diff --git a/blocksuite/affine/block-note/src/note-edgeless-block.ts b/blocksuite/affine/block-note/src/note-edgeless-block.ts index 1f86633aa3..bb7252f294 100644 --- a/blocksuite/affine/block-note/src/note-edgeless-block.ts +++ b/blocksuite/affine/block-note/src/note-edgeless-block.ts @@ -26,12 +26,13 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent( return ( this.model.edgeless.collapse && this.gfx.selection.has(this.model.id) && + !this._dragging && (this._isResizing || this._isHover) ); } - get _zoom() { - return this.gfx.viewport.zoom; + private get _dragging() { + return this._isHover && this.gfx.tool.dragging$.value; } private _collapsedContent() { @@ -236,6 +237,7 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent( >
{ }); }); }); + +test.describe('note block rendering', () => { + test('collapsed content rendering', async ({ page }) => { + await createEdgelessNoteBlock(page, [50, 50]); + + await type(page, 'paragraph 1'); + for (let i = 0; i < 5; i++) { + await pressEnter(page); + } + await type(page, 'paragraph 2'); + await pressEscape(page, 3); + await clickView(page, [50, 50]); + await resizeElementByHandle(page, [0, -50], 'bottom-right'); + const xywh = await getSelectedXYWH(page); + const center: IVec = [xywh[0] + xywh[2] / 2, xywh[1] + xywh[3] / 2]; + + const note = page + .locator('affine-edgeless-note') + .getByTestId('edgeless-note-clip-container') + .nth(1); + + await expect(note, 'should hide collapsed content').toHaveCSS( + 'overflow-y', + 'clip' + ); + await moveToView(page, center); + await expect(note, 'should show collapsed content when hover').toHaveCSS( + 'overflow-y', + 'visible' + ); + + const [x1, y1] = await toViewCoord(page, center); + const [x2, y2] = await toViewCoord(page, [center[0], center[1] + 25]); + const [x3, y3] = await toViewCoord(page, [center[0], center[1] + 50]); + await page.mouse.move(x1, y1); + await page.mouse.down(); + + await page.mouse.move(x2, y2, { steps: 10 }); + await expect( + note, + 'should hide collapsed content during dragging' + ).toHaveCSS('overflow-y', 'clip'); + await page.mouse.move(x3, y3, { steps: 10 }); + await page.mouse.up(); + await page.mouse.move(x3, y3); + await expect( + note, + 'should show collapsed content when dragging is finished' + ).toHaveCSS('overflow-y', 'visible'); + }); +}); diff --git a/tests/kit/src/utils/editor.ts b/tests/kit/src/utils/editor.ts index b68354ec9c..b68bbfc3cb 100644 --- a/tests/kit/src/utils/editor.ts +++ b/tests/kit/src/utils/editor.ts @@ -82,6 +82,22 @@ export async function getEdgelessSelectedIds(page: Page, editorIndex = 0) { }); } +export async function getSelectedXYWH( + page: Page, + index = 0, + editorIndex = 0 +): Promise<[number, number, number, number]> { + const container = locateEditorContainer(page, editorIndex); + return container.evaluate((container, index) => { + const root = container.querySelector('affine-edgeless-root'); + if (!root) { + throw new Error('Edgeless root not found'); + } + const selected = root.service.selection.selectedElements[index]; + return selected.elementBound.toXYWH(); + }, index); +} + export async function getViewportCenter(page: Page, editorIndex = 0) { const container = locateEditorContainer(page, editorIndex); return container.evaluate((container: AffineEditorContainer) => { @@ -108,6 +124,17 @@ export async function setViewportCenter( }, center); } +export async function setViewportZoom(page: Page, zoom = 1, editorIndex = 0) { + const container = locateEditorContainer(page, editorIndex); + return container.evaluate((container: AffineEditorContainer, zoom) => { + const root = container.querySelector('affine-edgeless-root'); + if (!root) { + throw new Error('Edgeless root not found'); + } + root.gfx.viewport.setZoom(zoom); + }, zoom); +} + /** * Convert a canvas point to view coordinate * @param point the coordinate on the canvas @@ -119,10 +146,36 @@ export async function toViewCoord(page: Page, point: IVec, editorIndex = 0) { if (!root) { throw new Error('Edgeless root not found'); } - return root.gfx.viewport.toViewCoord(point[0], point[1]); + const coord = root.gfx.viewport.toViewCoord(point[0], point[1]); + coord[0] += root.gfx.viewport.left; + coord[1] += root.gfx.viewport.top; + return coord; }, point); } +/** + * Convert a view coordinate to canvas point + * @param point the coordinate on the view + */ +export async function toModelCoord(page: Page, point: IVec, editorIndex = 0) { + const container = locateEditorContainer(page, editorIndex); + return container.evaluate((container: AffineEditorContainer, point) => { + const root = container.querySelector('affine-edgeless-root'); + if (!root) { + throw new Error('Edgeless root not found'); + } + return root.gfx.viewport.toModelCoordFromClientCoord(point); + }, point); +} + +/** + * Move to a point on the canvas + */ +export async function moveToView(page: Page, point: IVec, editorIndex = 0) { + const [x, y] = await toViewCoord(page, point, editorIndex); + await page.mouse.move(x, y); +} + /** * Click a point on the canvas * @param point the coordinate on the canvas @@ -331,6 +384,28 @@ export async function setEdgelessTool( } } +export async function resizeElementByHandle( + page: Page, + delta: IVec, + corner: + | 'top-left' + | 'top-right' + | 'bottom-right' + | 'bottom-left' = 'top-left', + editorIndex = 0 +) { + const handle = page.locator(`.handle[aria-label="${corner}"] .resize`); + const box = await handle.boundingBox(); + if (box === null) throw new Error(); + const from = await toModelCoord( + page, + [box.x + box.width / 2, box.y + box.height / 2], + editorIndex + ); + const to: IVec = [from[0] + delta[0], from[1] + delta[1]]; + await dragView(page, from, to, editorIndex); +} + export function locateElementToolbar(page: Page, editorIndex = 0) { return locateEditorContainer(page, editorIndex).locator( EDGELESS_ELEMENT_TOOLBAR_WIDGET