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