mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-10 05:29:08 +08:00
feat(editor): create gfx mindmap package (#11100)
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
"@blocksuite/affine-fragment-frame-panel": "workspace:*",
|
||||
"@blocksuite/affine-fragment-outline": "workspace:*",
|
||||
"@blocksuite/affine-gfx-connector": "workspace:*",
|
||||
"@blocksuite/affine-gfx-mindmap": "workspace:*",
|
||||
"@blocksuite/affine-gfx-note": "workspace:*",
|
||||
"@blocksuite/affine-gfx-shape": "workspace:*",
|
||||
"@blocksuite/affine-gfx-text": "workspace:*",
|
||||
@@ -119,6 +120,7 @@
|
||||
"./gfx/text": "./src/gfx/text.ts",
|
||||
"./gfx/shape": "./src/gfx/shape.ts",
|
||||
"./gfx/note": "./src/gfx/note.ts",
|
||||
"./gfx/mindmap": "./src/gfx/mindmap.ts",
|
||||
"./gfx/connector": "./src/gfx/connector.ts",
|
||||
"./gfx/turbo-renderer": "./src/gfx/turbo-renderer.ts",
|
||||
"./components/block-selection": "./src/components/block-selection.ts",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-gfx-mindmap';
|
||||
@@ -31,6 +31,7 @@
|
||||
{ "path": "../fragments/fragment-frame-panel" },
|
||||
{ "path": "../fragments/fragment-outline" },
|
||||
{ "path": "../gfx/connector" },
|
||||
{ "path": "../gfx/mindmap" },
|
||||
{ "path": "../gfx/note" },
|
||||
{ "path": "../gfx/shape" },
|
||||
{ "path": "../gfx/text" },
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { EdgelessTextBlockModel } from '@blocksuite/affine-model';
|
||||
import { type ToolbarModuleConfig } from '@blocksuite/affine-shared/services';
|
||||
import {
|
||||
type ToolbarModuleConfig,
|
||||
ToolbarModuleExtension,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { createTextActions } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { BlockFlavourIdentifier } from '@blocksuite/block-std';
|
||||
|
||||
export const edgelessTextToolbarConfig = {
|
||||
// No need to adjust element bounds, which updates itself using ResizeObserver
|
||||
@@ -8,3 +12,8 @@ export const edgelessTextToolbarConfig = {
|
||||
|
||||
when: ctx => ctx.getSurfaceModelsByType(EdgelessTextBlockModel).length > 0,
|
||||
} as const satisfies ToolbarModuleConfig;
|
||||
|
||||
export const edgelessTextToolbarExtension = ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:edgeless-text'),
|
||||
config: edgelessTextToolbarConfig,
|
||||
});
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-fragment-doc-title": "workspace:*",
|
||||
"@blocksuite/affine-gfx-connector": "workspace:*",
|
||||
"@blocksuite/affine-gfx-mindmap": "workspace:*",
|
||||
"@blocksuite/affine-gfx-note": "workspace:*",
|
||||
"@blocksuite/affine-gfx-shape": "workspace:*",
|
||||
"@blocksuite/affine-gfx-text": "workspace:*",
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { edgelessTextToolbarConfig } from '@blocksuite/affine-block-edgeless-text';
|
||||
import { edgelessTextToolbarExtension } from '@blocksuite/affine-block-edgeless-text';
|
||||
import { frameToolbarExtension } from '@blocksuite/affine-block-frame';
|
||||
import { connectorToolbarConfig } from '@blocksuite/affine-gfx-connector';
|
||||
import { textToolbarConfig } from '@blocksuite/affine-gfx-text';
|
||||
import { connectorToolbarExtension } from '@blocksuite/affine-gfx-connector';
|
||||
import { mindmapToolbarExtension } from '@blocksuite/affine-gfx-mindmap';
|
||||
import { shapeToolbarExtension } from '@blocksuite/affine-gfx-shape';
|
||||
import { textToolbarExtension } from '@blocksuite/affine-gfx-text';
|
||||
import { ToolbarModuleExtension } from '@blocksuite/affine-shared/services';
|
||||
import { BlockFlavourIdentifier } from '@blocksuite/block-std';
|
||||
import type { ExtensionType } from '@blocksuite/store';
|
||||
|
||||
import { builtinBrushToolbarConfig } from './brush';
|
||||
import { builtinGroupToolbarConfig } from './group';
|
||||
import { builtinMindmapToolbarConfig } from './mindmap';
|
||||
import { builtinLockedToolbarConfig, builtinMiscToolbarConfig } from './misc';
|
||||
import { builtinShapeToolbarConfig } from './shape';
|
||||
|
||||
export const EdgelessElementToolbarExtension: ExtensionType[] = [
|
||||
frameToolbarExtension,
|
||||
@@ -25,30 +25,15 @@ export const EdgelessElementToolbarExtension: ExtensionType[] = [
|
||||
config: builtinBrushToolbarConfig,
|
||||
}),
|
||||
|
||||
ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:connector'),
|
||||
config: connectorToolbarConfig,
|
||||
}),
|
||||
connectorToolbarExtension,
|
||||
|
||||
ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:mindmap'),
|
||||
config: builtinMindmapToolbarConfig,
|
||||
}),
|
||||
mindmapToolbarExtension,
|
||||
|
||||
ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:text'),
|
||||
config: textToolbarConfig,
|
||||
}),
|
||||
textToolbarExtension,
|
||||
|
||||
ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:edgeless-text'),
|
||||
config: edgelessTextToolbarConfig,
|
||||
}),
|
||||
edgelessTextToolbarExtension,
|
||||
|
||||
ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:shape'),
|
||||
config: builtinShapeToolbarConfig,
|
||||
}),
|
||||
shapeToolbarExtension,
|
||||
|
||||
ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:*'),
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
import { shapeToolbarConfig } from '@blocksuite/affine-gfx-shape';
|
||||
import {
|
||||
MindmapElementModel,
|
||||
ShapeElementModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import type { ToolbarActions } from '@blocksuite/affine-shared/services';
|
||||
|
||||
import {
|
||||
createMindmapLayoutActionMenu,
|
||||
createMindmapStyleActionMenu,
|
||||
} from './mindmap';
|
||||
|
||||
const mindmapActions = [
|
||||
{
|
||||
id: 'a.mindmap-style',
|
||||
when(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
return models.some(hasGrouped);
|
||||
},
|
||||
content(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
if (!models.length) return null;
|
||||
|
||||
let mindmaps = models
|
||||
.map(model => model.group)
|
||||
.filter(model => ctx.matchModel(model, MindmapElementModel));
|
||||
if (!mindmaps.length) return null;
|
||||
|
||||
// Not displayed when there is both a normal shape and a mindmap shape.
|
||||
if (models.length !== mindmaps.length) return null;
|
||||
|
||||
mindmaps = Array.from(new Set(mindmaps));
|
||||
|
||||
return createMindmapStyleActionMenu(ctx, mindmaps);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'b.mindmap-layout',
|
||||
when(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
return models.some(hasGrouped);
|
||||
},
|
||||
content(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
if (!models.length) return null;
|
||||
|
||||
let mindmaps = models
|
||||
.map(model => model.group)
|
||||
.filter(model => ctx.matchModel(model, MindmapElementModel));
|
||||
if (!mindmaps.length) return null;
|
||||
|
||||
// Not displayed when there is both a normal shape and a mindmap shape.
|
||||
if (models.length !== mindmaps.length) return null;
|
||||
|
||||
mindmaps = Array.from(new Set(mindmaps));
|
||||
|
||||
// It's a sub node.
|
||||
if (models.length === 1 && mindmaps[0].tree.element !== models[0])
|
||||
return null;
|
||||
|
||||
return createMindmapLayoutActionMenu(ctx, mindmaps);
|
||||
},
|
||||
},
|
||||
] as const satisfies ToolbarActions;
|
||||
|
||||
export const builtinShapeToolbarConfig = {
|
||||
...shapeToolbarConfig,
|
||||
actions: [...mindmapActions, ...shapeToolbarConfig.actions],
|
||||
};
|
||||
|
||||
function hasGrouped(model: ShapeElementModel) {
|
||||
return model.group instanceof MindmapElementModel;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { effects as gfxConnectorEffects } from '@blocksuite/affine-gfx-connector/effects';
|
||||
import { effects as gfxMindmapEffects } from '@blocksuite/affine-gfx-mindmap/effects';
|
||||
import { effects as gfxNoteEffects } from '@blocksuite/affine-gfx-note/effects';
|
||||
import { effects as gfxShapeEffects } from '@blocksuite/affine-gfx-shape/effects';
|
||||
import { effects as gfxCanvasTextEffects } from '@blocksuite/affine-gfx-text/effects';
|
||||
@@ -32,9 +33,6 @@ import { EdgelessDefaultToolButton } from './edgeless/components/toolbar/default
|
||||
import { EdgelessEraserToolButton } from './edgeless/components/toolbar/eraser/eraser-tool-button.js';
|
||||
import { EdgelessLassoToolButton } from './edgeless/components/toolbar/lasso/lasso-tool-button.js';
|
||||
import { EdgelessLinkToolButton } from './edgeless/components/toolbar/link/link-tool-button.js';
|
||||
import { MindMapPlaceholder } from './edgeless/components/toolbar/mindmap/mindmap-importing-placeholder.js';
|
||||
import { EdgelessMindmapMenu } from './edgeless/components/toolbar/mindmap/mindmap-menu.js';
|
||||
import { EdgelessMindmapToolButton } from './edgeless/components/toolbar/mindmap/mindmap-tool-button.js';
|
||||
import { OverlayScrollbar } from './edgeless/components/toolbar/template/overlay-scrollbar.js';
|
||||
import { AffineTemplateLoading } from './edgeless/components/toolbar/template/template-loading.js';
|
||||
import { EdgelessTemplatePanel } from './edgeless/components/toolbar/template/template-panel.js';
|
||||
@@ -108,6 +106,7 @@ function registerGfxEffects() {
|
||||
gfxShapeEffects();
|
||||
gfxNoteEffects();
|
||||
gfxConnectorEffects();
|
||||
gfxMindmapEffects();
|
||||
}
|
||||
|
||||
function registerWidgets() {
|
||||
@@ -141,15 +140,10 @@ function registerEdgelessToolbarComponents() {
|
||||
);
|
||||
customElements.define('edgeless-link-tool-button', EdgelessLinkToolButton);
|
||||
customElements.define('edgeless-lasso-tool-button', EdgelessLassoToolButton);
|
||||
customElements.define(
|
||||
'edgeless-mindmap-tool-button',
|
||||
EdgelessMindmapToolButton
|
||||
);
|
||||
customElements.define('edgeless-template-button', EdgelessTemplateButton);
|
||||
|
||||
// Menus
|
||||
customElements.define('edgeless-brush-menu', EdgelessBrushMenu);
|
||||
customElements.define('edgeless-mindmap-menu', EdgelessMindmapMenu);
|
||||
customElements.define('edgeless-slide-menu', EdgelessSlideMenu);
|
||||
|
||||
// Toolbar components
|
||||
@@ -214,9 +208,6 @@ function registerMiscComponents() {
|
||||
EDGELESS_SELECTED_RECT_WIDGET,
|
||||
EdgelessSelectedRectWidget
|
||||
);
|
||||
|
||||
// Mindmap components
|
||||
customElements.define('mindmap-import-placeholder', MindMapPlaceholder);
|
||||
}
|
||||
|
||||
declare global {
|
||||
@@ -243,9 +234,6 @@ declare global {
|
||||
'edgeless-eraser-tool-button': EdgelessEraserToolButton;
|
||||
'edgeless-lasso-tool-button': EdgelessLassoToolButton;
|
||||
'edgeless-link-tool-button': EdgelessLinkToolButton;
|
||||
'mindmap-import-placeholder': MindMapPlaceholder;
|
||||
'edgeless-mindmap-menu': EdgelessMindmapMenu;
|
||||
'edgeless-mindmap-tool-button': EdgelessMindmapToolButton;
|
||||
'overlay-scrollbar': OverlayScrollbar;
|
||||
'affine-template-loading': AffineTemplateLoading;
|
||||
'edgeless-templates-panel': EdgelessTemplatePanel;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../../fragments/fragment-doc-title" },
|
||||
{ "path": "../../gfx/connector" },
|
||||
{ "path": "../../gfx/mindmap" },
|
||||
{ "path": "../../gfx/note" },
|
||||
{ "path": "../../gfx/shape" },
|
||||
{ "path": "../../gfx/text" },
|
||||
|
||||
@@ -21,10 +21,11 @@ import {
|
||||
resolveColor,
|
||||
StrokeStyle,
|
||||
} from '@blocksuite/affine-model';
|
||||
import type {
|
||||
ToolbarContext,
|
||||
ToolbarGenericAction,
|
||||
ToolbarModuleConfig,
|
||||
import {
|
||||
type ToolbarContext,
|
||||
type ToolbarGenericAction,
|
||||
type ToolbarModuleConfig,
|
||||
ToolbarModuleExtension,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import {
|
||||
getMostCommonResolvedValue,
|
||||
@@ -37,6 +38,7 @@ import {
|
||||
LINE_STYLE_LIST,
|
||||
renderMenu,
|
||||
} from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { BlockFlavourIdentifier } from '@blocksuite/block-std';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import {
|
||||
AddTextIcon,
|
||||
@@ -417,3 +419,8 @@ function updateModelsWith<
|
||||
.updateElement(model.id, { [field]: value });
|
||||
}
|
||||
}
|
||||
|
||||
export const connectorToolbarExtension = ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:connector'),
|
||||
config: connectorToolbarConfig,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "@blocksuite/affine-gfx-mindmap",
|
||||
"description": "Gfx mindmap for BlockSuite.",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsc"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"keywords": [],
|
||||
"author": "toeverything",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-attachment": "workspace:*",
|
||||
"@blocksuite/affine-block-edgeless-text": "workspace:*",
|
||||
"@blocksuite/affine-block-image": "workspace:*",
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-gfx-text": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-rich-text": "workspace:*",
|
||||
"@blocksuite/affine-shared": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-toolbar": "workspace:*",
|
||||
"@blocksuite/block-std": "workspace:*",
|
||||
"@blocksuite/global": "workspace:*",
|
||||
"@blocksuite/icons": "^2.2.6",
|
||||
"@blocksuite/store": "workspace:*",
|
||||
"@lit/context": "^1.1.2",
|
||||
"@preact/signals-core": "^1.8.0",
|
||||
"@toeverything/theme": "^1.1.12",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"lit": "^3.2.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"minimatch": "^10.0.1",
|
||||
"rxjs": "^7.8.1",
|
||||
"simple-xml-to-json": "^1.2.2",
|
||||
"yjs": "^13.6.21",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./effects": "./src/effects.ts"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"dist",
|
||||
"!src/__tests__",
|
||||
"!dist/__tests__"
|
||||
],
|
||||
"version": "0.20.0"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { MindMapPlaceholder } from './toolbar/mindmap-importing-placeholder';
|
||||
import { EdgelessMindmapMenu } from './toolbar/mindmap-menu';
|
||||
import { EdgelessMindmapToolButton } from './toolbar/mindmap-tool-button';
|
||||
|
||||
export function effects() {
|
||||
customElements.define(
|
||||
'edgeless-mindmap-tool-button',
|
||||
EdgelessMindmapToolButton
|
||||
);
|
||||
customElements.define('edgeless-mindmap-menu', EdgelessMindmapMenu);
|
||||
customElements.define('mindmap-import-placeholder', MindMapPlaceholder);
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'edgeless-mindmap-tool-button': EdgelessMindmapToolButton;
|
||||
'edgeless-mindmap-menu': EdgelessMindmapMenu;
|
||||
'mindmap-import-placeholder': MindMapPlaceholder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './toolbar/config';
|
||||
+11
-4
@@ -9,15 +9,17 @@ import {
|
||||
MindmapElementModel,
|
||||
MindmapStyle,
|
||||
} from '@blocksuite/affine-model';
|
||||
import type {
|
||||
ToolbarContext,
|
||||
ToolbarModuleConfig,
|
||||
import {
|
||||
type ToolbarContext,
|
||||
type ToolbarModuleConfig,
|
||||
ToolbarModuleExtension,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { getMostCommonValue } from '@blocksuite/affine-shared/utils';
|
||||
import {
|
||||
type MenuItem,
|
||||
renderMenu,
|
||||
} from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { BlockFlavourIdentifier } from '@blocksuite/block-std';
|
||||
import { RadiantIcon, RightLayoutIcon, StyleIcon } from '@blocksuite/icons/lit';
|
||||
|
||||
const MINDMAP_STYLE_LIST = [
|
||||
@@ -102,7 +104,7 @@ export const createMindmapLayoutActionMenu = (
|
||||
});
|
||||
};
|
||||
|
||||
export const builtinMindmapToolbarConfig = {
|
||||
export const mindmapToolbarConfig = {
|
||||
actions: [
|
||||
{
|
||||
id: 'a.style',
|
||||
@@ -126,3 +128,8 @@ export const builtinMindmapToolbarConfig = {
|
||||
|
||||
when: ctx => ctx.getSurfaceModelsByType(MindmapElementModel).length > 0,
|
||||
} as const satisfies ToolbarModuleConfig;
|
||||
|
||||
export const mindmapToolbarExtension = ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:mindmap'),
|
||||
config: mindmapToolbarConfig,
|
||||
});
|
||||
+6
-10
@@ -21,7 +21,6 @@ import { css, html, LitElement, nothing, type TemplateResult } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
|
||||
import type { EdgelessRootBlockComponent } from '../../../index.js';
|
||||
import { getMindMaps, type ToolbarMindmapItem } from './assets.js';
|
||||
import { mediaRender, textRender } from './basket-elements.js';
|
||||
import { importMindMapIcon, mindmapMenuMediaIcon, textIcon } from './icons.js';
|
||||
@@ -124,12 +123,9 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
||||
ToolbarMindmapItem | TextItem | ImportItem | MediaItem
|
||||
>;
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
override type = 'empty' as const;
|
||||
|
||||
private get _rootBlock(): EdgelessRootBlockComponent {
|
||||
return this.std.view.getBlock(this.model.id) as EdgelessRootBlockComponent;
|
||||
}
|
||||
|
||||
get mindMaps() {
|
||||
return getMindMaps(this.theme);
|
||||
}
|
||||
@@ -164,7 +160,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
||||
}}
|
||||
@click=${() => {
|
||||
this.draggableController.cancel();
|
||||
const viewportBound = this._rootBlock.service.viewport.viewportBounds;
|
||||
const viewportBound = this.gfx.viewport.viewportBounds;
|
||||
|
||||
viewportBound.x += viewportBound.w / 2;
|
||||
viewportBound.y += viewportBound.h / 2;
|
||||
@@ -183,16 +179,13 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
||||
}
|
||||
|
||||
private _onImportMindMap(bound: Bound) {
|
||||
const edgelessBlock = this._rootBlock;
|
||||
if (!edgelessBlock) return;
|
||||
|
||||
const placeholder = new MindMapPlaceholder();
|
||||
|
||||
placeholder.style.position = 'absolute';
|
||||
placeholder.style.left = `${bound.x}px`;
|
||||
placeholder.style.top = `${bound.y}px`;
|
||||
|
||||
edgelessBlock.gfxViewportElm.append(placeholder);
|
||||
this.gfx.viewport.element?.append(placeholder);
|
||||
|
||||
this.onImportMindMap?.(bound)
|
||||
.then(() => {
|
||||
@@ -230,6 +223,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
||||
this.onActiveStyleChange?.(element.data.style);
|
||||
}
|
||||
// a workaround to active mindmap, so that menu cannot be closed by `Escape`
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'empty' });
|
||||
},
|
||||
onDrop: (element, bound) => {
|
||||
@@ -240,6 +234,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
||||
if (!id) return;
|
||||
if (element.data.type === 'mindmap') {
|
||||
this.onActiveStyleChange?.(element.data.style);
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
this.gfx.selection.set({
|
||||
elements: [id],
|
||||
@@ -249,6 +244,7 @@ export class EdgelessMindmapMenu extends EdgelessToolbarToolMixin(
|
||||
element.data.type === 'text' ||
|
||||
element.data.type === 'media'
|
||||
) {
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
}
|
||||
})
|
||||
+6
@@ -150,6 +150,7 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
||||
|
||||
override enableActiveBackground = true;
|
||||
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
override type: GfxToolsFullOptionValue['type'][] = ['empty', 'text'];
|
||||
|
||||
get draggableTools(): DraggableTool[] {
|
||||
@@ -191,6 +192,7 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
||||
|
||||
private _toggleMenu() {
|
||||
if (this.tryDisposePopper()) return;
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
|
||||
const menu = this.createPopper('edgeless-mindmap-menu', this);
|
||||
@@ -211,6 +213,7 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
||||
const element = this.crud.getElementById(id) as MindmapElementModel;
|
||||
|
||||
this.tryDisposePopper();
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
this.gfx.selection.set({
|
||||
elements: [element.tree.id],
|
||||
@@ -271,12 +274,14 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
||||
if (!id) return;
|
||||
this.readyToDrop = false;
|
||||
if (el.data.name === 'mindmap') {
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
this.gfx.selection.set({
|
||||
elements: [id],
|
||||
editing: false,
|
||||
});
|
||||
} else if (el.data.name === 'text') {
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'default' });
|
||||
}
|
||||
})
|
||||
@@ -309,6 +314,7 @@ export class EdgelessMindmapToolButton extends EdgelessToolbarToolMixin(
|
||||
});
|
||||
return;
|
||||
}
|
||||
// @ts-expect-error FIXME: resolve after gfx tool refactor
|
||||
this.setEdgelessTool({ type: 'empty' });
|
||||
const icon = this.mindmapElement;
|
||||
const { x, y } = gfx.tool.lastMousePos$.peek();
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo"
|
||||
},
|
||||
"include": ["./src"],
|
||||
"references": [
|
||||
{ "path": "../../blocks/block-attachment" },
|
||||
{ "path": "../../blocks/block-edgeless-text" },
|
||||
{ "path": "../../blocks/block-image" },
|
||||
{ "path": "../../blocks/block-surface" },
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../text" },
|
||||
{ "path": "../../model" },
|
||||
{ "path": "../../rich-text" },
|
||||
{ "path": "../../shared" },
|
||||
{ "path": "../../widgets/widget-edgeless-toolbar" },
|
||||
{ "path": "../../../framework/block-std" },
|
||||
{ "path": "../../../framework/global" },
|
||||
{ "path": "../../../framework/store" }
|
||||
]
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-gfx-mindmap": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-rich-text": "workspace:*",
|
||||
"@blocksuite/affine-shared": "workspace:*",
|
||||
|
||||
@@ -7,6 +7,10 @@ import {
|
||||
type PickColorEvent,
|
||||
} from '@blocksuite/affine-components/color-picker';
|
||||
import type { LineDetailType } from '@blocksuite/affine-components/edgeless-line-styles-panel';
|
||||
import {
|
||||
createMindmapLayoutActionMenu,
|
||||
createMindmapStyleActionMenu,
|
||||
} from '@blocksuite/affine-gfx-mindmap';
|
||||
import {
|
||||
type Color,
|
||||
DefaultTheme,
|
||||
@@ -24,9 +28,10 @@ import {
|
||||
ShapeType,
|
||||
StrokeStyle,
|
||||
} from '@blocksuite/affine-model';
|
||||
import type {
|
||||
ToolbarGenericAction,
|
||||
ToolbarModuleConfig,
|
||||
import {
|
||||
type ToolbarGenericAction,
|
||||
type ToolbarModuleConfig,
|
||||
ToolbarModuleExtension,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { getMostCommonValue } from '@blocksuite/affine-shared/utils';
|
||||
import {
|
||||
@@ -35,6 +40,7 @@ import {
|
||||
LINE_STYLE_LIST,
|
||||
renderMenu,
|
||||
} from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { BlockFlavourIdentifier } from '@blocksuite/block-std';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import { AddTextIcon, ShapeIcon } from '@blocksuite/icons/lit';
|
||||
import { html } from 'lit';
|
||||
@@ -46,6 +52,56 @@ import { ShapeComponentConfig } from './shape-menu-config';
|
||||
|
||||
export const shapeToolbarConfig = {
|
||||
actions: [
|
||||
{
|
||||
id: 'a.mindmap-style',
|
||||
when(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
return models.some(hasGrouped);
|
||||
},
|
||||
content(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
if (!models.length) return null;
|
||||
|
||||
let mindmaps = models
|
||||
.map(model => model.group)
|
||||
.filter(model => ctx.matchModel(model, MindmapElementModel));
|
||||
if (!mindmaps.length) return null;
|
||||
|
||||
// Not displayed when there is both a normal shape and a mindmap shape.
|
||||
if (models.length !== mindmaps.length) return null;
|
||||
|
||||
mindmaps = Array.from(new Set(mindmaps));
|
||||
|
||||
return createMindmapStyleActionMenu(ctx, mindmaps);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'b.mindmap-layout',
|
||||
when(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
return models.some(hasGrouped);
|
||||
},
|
||||
content(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
if (!models.length) return null;
|
||||
|
||||
let mindmaps = models
|
||||
.map(model => model.group)
|
||||
.filter(model => ctx.matchModel(model, MindmapElementModel));
|
||||
if (!mindmaps.length) return null;
|
||||
|
||||
// Not displayed when there is both a normal shape and a mindmap shape.
|
||||
if (models.length !== mindmaps.length) return null;
|
||||
|
||||
mindmaps = Array.from(new Set(mindmaps));
|
||||
|
||||
// It's a sub node.
|
||||
if (models.length === 1 && mindmaps[0].tree.element !== models[0])
|
||||
return null;
|
||||
|
||||
return createMindmapLayoutActionMenu(ctx, mindmaps);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'c.switch-type',
|
||||
when(ctx) {
|
||||
@@ -326,3 +382,8 @@ function getTextColor(fillColor: Color, isNotTransparent = false) {
|
||||
function hasGrouped(model: ShapeElementModel) {
|
||||
return model.group instanceof MindmapElementModel;
|
||||
}
|
||||
|
||||
export const shapeToolbarExtension = ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:shape'),
|
||||
config: shapeToolbarConfig,
|
||||
});
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"references": [
|
||||
{ "path": "../../blocks/block-surface" },
|
||||
{ "path": "../../components" },
|
||||
{ "path": "../mindmap" },
|
||||
{ "path": "../../model" },
|
||||
{ "path": "../../rich-text" },
|
||||
{ "path": "../../shared" },
|
||||
|
||||
@@ -3,8 +3,12 @@ import {
|
||||
TextUtils,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { TextElementModel } from '@blocksuite/affine-model';
|
||||
import { type ToolbarModuleConfig } from '@blocksuite/affine-shared/services';
|
||||
import {
|
||||
type ToolbarModuleConfig,
|
||||
ToolbarModuleExtension,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { createTextActions } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { BlockFlavourIdentifier } from '@blocksuite/block-std';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
|
||||
export const textToolbarConfig = {
|
||||
@@ -46,3 +50,8 @@ export const textToolbarConfig = {
|
||||
|
||||
when: ctx => ctx.getSurfaceModelsByType(TextElementModel).length > 0,
|
||||
} as const satisfies ToolbarModuleConfig;
|
||||
|
||||
export const textToolbarExtension = ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:text'),
|
||||
config: textToolbarConfig,
|
||||
});
|
||||
|
||||
@@ -29,6 +29,7 @@ export const PackageList = [
|
||||
'blocksuite/affine/fragments/fragment-frame-panel',
|
||||
'blocksuite/affine/fragments/fragment-outline',
|
||||
'blocksuite/affine/gfx/connector',
|
||||
'blocksuite/affine/gfx/mindmap',
|
||||
'blocksuite/affine/gfx/note',
|
||||
'blocksuite/affine/gfx/shape',
|
||||
'blocksuite/affine/gfx/text',
|
||||
@@ -310,6 +311,7 @@ export const PackageList = [
|
||||
'blocksuite/affine/components',
|
||||
'blocksuite/affine/fragments/fragment-doc-title',
|
||||
'blocksuite/affine/gfx/connector',
|
||||
'blocksuite/affine/gfx/mindmap',
|
||||
'blocksuite/affine/gfx/note',
|
||||
'blocksuite/affine/gfx/shape',
|
||||
'blocksuite/affine/gfx/text',
|
||||
@@ -460,6 +462,25 @@ export const PackageList = [
|
||||
'blocksuite/framework/store',
|
||||
],
|
||||
},
|
||||
{
|
||||
location: 'blocksuite/affine/gfx/mindmap',
|
||||
name: '@blocksuite/affine-gfx-mindmap',
|
||||
workspaceDependencies: [
|
||||
'blocksuite/affine/blocks/block-attachment',
|
||||
'blocksuite/affine/blocks/block-edgeless-text',
|
||||
'blocksuite/affine/blocks/block-image',
|
||||
'blocksuite/affine/blocks/block-surface',
|
||||
'blocksuite/affine/components',
|
||||
'blocksuite/affine/gfx/text',
|
||||
'blocksuite/affine/model',
|
||||
'blocksuite/affine/rich-text',
|
||||
'blocksuite/affine/shared',
|
||||
'blocksuite/affine/widgets/widget-edgeless-toolbar',
|
||||
'blocksuite/framework/block-std',
|
||||
'blocksuite/framework/global',
|
||||
'blocksuite/framework/store',
|
||||
],
|
||||
},
|
||||
{
|
||||
location: 'blocksuite/affine/gfx/note',
|
||||
name: '@blocksuite/affine-gfx-note',
|
||||
@@ -484,6 +505,7 @@ export const PackageList = [
|
||||
workspaceDependencies: [
|
||||
'blocksuite/affine/blocks/block-surface',
|
||||
'blocksuite/affine/components',
|
||||
'blocksuite/affine/gfx/mindmap',
|
||||
'blocksuite/affine/model',
|
||||
'blocksuite/affine/rich-text',
|
||||
'blocksuite/affine/shared',
|
||||
@@ -1093,6 +1115,7 @@ export type PackageName =
|
||||
| '@blocksuite/affine-fragment-frame-panel'
|
||||
| '@blocksuite/affine-fragment-outline'
|
||||
| '@blocksuite/affine-gfx-connector'
|
||||
| '@blocksuite/affine-gfx-mindmap'
|
||||
| '@blocksuite/affine-gfx-note'
|
||||
| '@blocksuite/affine-gfx-shape'
|
||||
| '@blocksuite/affine-gfx-text'
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
{ "path": "./blocksuite/affine/fragments/fragment-frame-panel" },
|
||||
{ "path": "./blocksuite/affine/fragments/fragment-outline" },
|
||||
{ "path": "./blocksuite/affine/gfx/connector" },
|
||||
{ "path": "./blocksuite/affine/gfx/mindmap" },
|
||||
{ "path": "./blocksuite/affine/gfx/note" },
|
||||
{ "path": "./blocksuite/affine/gfx/shape" },
|
||||
{ "path": "./blocksuite/affine/gfx/text" },
|
||||
|
||||
@@ -2734,6 +2734,7 @@ __metadata:
|
||||
"@blocksuite/affine-components": "workspace:*"
|
||||
"@blocksuite/affine-fragment-doc-title": "workspace:*"
|
||||
"@blocksuite/affine-gfx-connector": "workspace:*"
|
||||
"@blocksuite/affine-gfx-mindmap": "workspace:*"
|
||||
"@blocksuite/affine-gfx-note": "workspace:*"
|
||||
"@blocksuite/affine-gfx-shape": "workspace:*"
|
||||
"@blocksuite/affine-gfx-text": "workspace:*"
|
||||
@@ -2997,6 +2998,38 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@blocksuite/affine-gfx-mindmap@workspace:*, @blocksuite/affine-gfx-mindmap@workspace:blocksuite/affine/gfx/mindmap":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@blocksuite/affine-gfx-mindmap@workspace:blocksuite/affine/gfx/mindmap"
|
||||
dependencies:
|
||||
"@blocksuite/affine-block-attachment": "workspace:*"
|
||||
"@blocksuite/affine-block-edgeless-text": "workspace:*"
|
||||
"@blocksuite/affine-block-image": "workspace:*"
|
||||
"@blocksuite/affine-block-surface": "workspace:*"
|
||||
"@blocksuite/affine-components": "workspace:*"
|
||||
"@blocksuite/affine-gfx-text": "workspace:*"
|
||||
"@blocksuite/affine-model": "workspace:*"
|
||||
"@blocksuite/affine-rich-text": "workspace:*"
|
||||
"@blocksuite/affine-shared": "workspace:*"
|
||||
"@blocksuite/affine-widget-edgeless-toolbar": "workspace:*"
|
||||
"@blocksuite/block-std": "workspace:*"
|
||||
"@blocksuite/global": "workspace:*"
|
||||
"@blocksuite/icons": "npm:^2.2.6"
|
||||
"@blocksuite/store": "workspace:*"
|
||||
"@lit/context": "npm:^1.1.2"
|
||||
"@preact/signals-core": "npm:^1.8.0"
|
||||
"@toeverything/theme": "npm:^1.1.12"
|
||||
"@types/lodash-es": "npm:^4.17.12"
|
||||
lit: "npm:^3.2.0"
|
||||
lodash-es: "npm:^4.17.21"
|
||||
minimatch: "npm:^10.0.1"
|
||||
rxjs: "npm:^7.8.1"
|
||||
simple-xml-to-json: "npm:^1.2.2"
|
||||
yjs: "npm:^13.6.21"
|
||||
zod: "npm:^3.23.8"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@blocksuite/affine-gfx-note@workspace:*, @blocksuite/affine-gfx-note@workspace:blocksuite/affine/gfx/note":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@blocksuite/affine-gfx-note@workspace:blocksuite/affine/gfx/note"
|
||||
@@ -3033,6 +3066,7 @@ __metadata:
|
||||
dependencies:
|
||||
"@blocksuite/affine-block-surface": "workspace:*"
|
||||
"@blocksuite/affine-components": "workspace:*"
|
||||
"@blocksuite/affine-gfx-mindmap": "workspace:*"
|
||||
"@blocksuite/affine-model": "workspace:*"
|
||||
"@blocksuite/affine-rich-text": "workspace:*"
|
||||
"@blocksuite/affine-shared": "workspace:*"
|
||||
@@ -3540,6 +3574,7 @@ __metadata:
|
||||
"@blocksuite/affine-fragment-frame-panel": "workspace:*"
|
||||
"@blocksuite/affine-fragment-outline": "workspace:*"
|
||||
"@blocksuite/affine-gfx-connector": "workspace:*"
|
||||
"@blocksuite/affine-gfx-mindmap": "workspace:*"
|
||||
"@blocksuite/affine-gfx-note": "workspace:*"
|
||||
"@blocksuite/affine-gfx-shape": "workspace:*"
|
||||
"@blocksuite/affine-gfx-text": "workspace:*"
|
||||
|
||||
Reference in New Issue
Block a user