diff --git a/blocksuite/affine/block-surface/src/index.ts b/blocksuite/affine/block-surface/src/index.ts index cf62cb7fee..a73cec0145 100644 --- a/blocksuite/affine/block-surface/src/index.ts +++ b/blocksuite/affine/block-surface/src/index.ts @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/triple-slash-reference +// oxlint-disable-next-line @typescript-eslint/triple-slash-reference /// export { type IModelCoord, ZOOM_MAX, ZOOM_MIN, ZOOM_STEP } from './consts.js'; export { GRID_GAP_MAX, GRID_GAP_MIN } from './consts.js'; @@ -29,6 +29,7 @@ export { export { fitContent } from './renderer/elements/shape/utils.js'; export * from './renderer/elements/type.js'; export { Overlay, OverlayIdentifier } from './renderer/overlay.js'; +export { MindMapView } from './view/mindmap.js'; import { getCursorByCoord, getLineHeight, diff --git a/blocksuite/blocks/src/surface-block/mini-mindmap/spec.ts b/blocksuite/blocks/src/surface-block/mini-mindmap/spec.ts index aa8b42c4f4..62371946e3 100644 --- a/blocksuite/blocks/src/surface-block/mini-mindmap/spec.ts +++ b/blocksuite/blocks/src/surface-block/mini-mindmap/spec.ts @@ -1,4 +1,7 @@ -import { SurfaceBlockSchema } from '@blocksuite/affine-block-surface'; +import { + MindMapView, + SurfaceBlockSchema, +} from '@blocksuite/affine-block-surface'; import { RootBlockSchema } from '@blocksuite/affine-model'; import { DocModeService, @@ -23,6 +26,7 @@ export const MiniMindmapSpecs: ExtensionType[] = [ MindmapService, BlockViewExtension('affine:page', literal`mini-mindmap-root-block`), FlavourExtension('affine:surface'), + MindMapView, MindmapSurfaceBlockService, BlockViewExtension('affine:surface', literal`mini-mindmap-surface-block`), ]; diff --git a/blocksuite/presets/src/__tests__/edgeless/mini-mindmap.spec.ts b/blocksuite/presets/src/__tests__/edgeless/mini-mindmap.spec.ts index 5afcb10182..6f41084262 100644 --- a/blocksuite/presets/src/__tests__/edgeless/mini-mindmap.spec.ts +++ b/blocksuite/presets/src/__tests__/edgeless/mini-mindmap.spec.ts @@ -12,9 +12,26 @@ import { wait } from '../utils/common.js'; import { getDocRootBlock } from '../utils/edgeless.js'; import { setupEditor } from '../utils/setup.js'; -describe('mind map', () => { +describe('mini mindmap preview', () => { let edgeless!: EdgelessRootBlockComponent; + const createPreview = (host: EditorHost, answer: string) => { + const mindmapPreview = new MiniMindmapPreview(); + + mindmapPreview.answer = answer; + mindmapPreview.host = host; + mindmapPreview.ctx = { + get() { + return {}; + }, + set() {}, + }; + + document.body.append(mindmapPreview); + + return mindmapPreview; + }; + beforeEach(async () => { const cleanup = await setupEditor('edgeless'); @@ -25,7 +42,7 @@ describe('mind map', () => { return cleanup; }); - test('mind map preview', async () => { + test('mini mindmap basic', async () => { const mindmapAnswer = ` - Mindmap - Node 1 @@ -36,74 +53,65 @@ describe('mind map', () => { - Node 2.2 `; - const createPreview = ( - host: EditorHost, - answer: string = mindmapAnswer - ) => { - const mindmapPreview = new MiniMindmapPreview(); - - mindmapPreview.answer = answer; - mindmapPreview.host = host; - mindmapPreview.ctx = { - get() { - return {}; - }, - set() {}, - }; - - document.body.append(mindmapPreview); - - return mindmapPreview; - }; - - const miniMindMapPreview = createPreview(window.editor.host!); + const miniMindMapPreview = createPreview( + window.editor.host!, + mindmapAnswer + ); await wait(50); const miniMindMapSurface = miniMindMapPreview.renderRoot.querySelector( 'mini-mindmap-surface-block' ) as MindmapSurfaceBlock; - expect(miniMindMapSurface).not.toBeNull(); + // model-related properties + expect(miniMindMapPreview.mindmapId).toBeDefined(); + expect(miniMindMapPreview.portalHost).toBeDefined(); + expect(miniMindMapPreview.doc).toBeDefined(); + expect(miniMindMapPreview.surface).toBeDefined(); + expect(miniMindMapPreview.surface!.elementModels.length).toBe(8); + + // renderer expect(miniMindMapSurface.renderer).toBeDefined(); expect(miniMindMapSurface.renderer?.canvas.isConnected).toBe(true); expect(miniMindMapSurface.renderer?.canvas.width).toBeGreaterThan(0); expect(miniMindMapSurface.renderer?.canvas.height).toBeGreaterThan(0); - expect(miniMindMapSurface.model.elementModels.length).toBe(8); - return () => { miniMindMapPreview.remove(); }; }); - test('new mind map should layout automatically', async () => { - const gfx = editor.std.get(GfxControllerIdentifier); - const mindmapId = gfx.surface!.addElement({ - type: 'mindmap', - children: { - text: 'Main node', - children: [ - { - text: 'Child node', - }, - { - text: 'Second child node', - }, - { - text: 'Third child node', - }, - ], - }, - }); - const mindmap = gfx.getElementById(mindmapId) as MindmapElementModel; - await wait(0); - const [child1, child2, child3] = mindmap.tree.children; + test('mini mindmap should layout automatically', async () => { + const mindmapAnswer = ` + - Main node + - Child node + - Second child node + - Third child node + `; - expect(mindmapId).not.toBeUndefined(); - expect(mindmap.tree.children.length).toBe(3); - expect(mindmap.tree.element.x).toBeLessThan(child1.element.x); + const miniMindMapPreview = createPreview( + window.editor.host!, + mindmapAnswer + ); + + await wait(50); + const gfx = miniMindMapPreview.portalHost.std.get(GfxControllerIdentifier); + const mindmap = gfx.surface!.elementModels.filter( + model => model.type === 'mindmap' + )[0] as MindmapElementModel; + const [child1, child2, child3] = mindmap.tree.children; + const root = mindmap.tree; + + expect(mindmap).not.toBeUndefined(); + + expect(root.children.length).toBe(3); + expect(root.element.x).toBeLessThan(child1.element.x); + + // children should be aligned horizontally expect(child1.element.x).toBe(child2.element.x); expect(child2.element.x).toBe(child3.element.x); - expect(child1.element.y).toBeLessThan(child2.element.y); - expect(child2.element.y).toBeLessThan(child3.element.y); + + // children + expect(child1.element.y + child1.element.h).toBeLessThan(child2.element.y); + expect(child2.element.y + child2.element.h).toBeLessThan(child3.element.y); }); });