From 2732b96d00f268537f5ab90a26ba20b5c3cfb957 Mon Sep 17 00:00:00 2001 From: L-Sun Date: Wed, 26 Feb 2025 09:33:57 +0000 Subject: [PATCH] fix(editor): overflow of embed github card in edgeless note (#10442) This PR fixes the overflow of the `embed-github-card` inside edgeless notes. https://github.com/user-attachments/assets/21775d0f-e4c8-4fcc-86d8-aafb27033358 --- .../src/common/embed-block-element.ts | 11 +++++- .../src/embed-github-block/styles.ts | 11 ++++++ .../e2e/blocksuite/edgeless/embed.spec.ts | 24 +++++++++++-- tests/kit/src/utils/utils.ts | 36 ++++++++++++++++++- 4 files changed, 77 insertions(+), 5 deletions(-) diff --git a/blocksuite/affine/block-embed/src/common/embed-block-element.ts b/blocksuite/affine/block-embed/src/common/embed-block-element.ts index b208269acc..52ad84755c 100644 --- a/blocksuite/affine/block-embed/src/common/embed-block-element.ts +++ b/blocksuite/affine/block-embed/src/common/embed-block-element.ts @@ -9,6 +9,7 @@ import { EMBED_CARD_WIDTH, } from '@blocksuite/affine-shared/consts'; import { DocModeProvider } from '@blocksuite/affine-shared/services'; +import { findAncestorModel } from '@blocksuite/affine-shared/utils'; import type { BlockService } from '@blocksuite/block-std'; import type { GfxCompatibleProps } from '@blocksuite/block-std/gfx'; import type { BlockModel } from '@blocksuite/store'; @@ -57,7 +58,15 @@ export class EmbedBlockComponent< ) { this.style.display = 'block'; - if (this.std.get(DocModeProvider).getEditorMode() === 'edgeless') { + const insideNote = findAncestorModel( + this.model, + m => m.flavour === 'affine:note' + ); + + if ( + !insideNote && + this.std.get(DocModeProvider).getEditorMode() === 'edgeless' + ) { this.style.minWidth = `${EMBED_CARD_MIN_WIDTH}px`; } } diff --git a/blocksuite/affine/block-embed/src/embed-github-block/styles.ts b/blocksuite/affine/block-embed/src/embed-github-block/styles.ts index f5c63f5b2e..55bcd7e80f 100644 --- a/blocksuite/affine/block-embed/src/embed-github-block/styles.ts +++ b/blocksuite/affine/block-embed/src/embed-github-block/styles.ts @@ -2,6 +2,7 @@ import { css, html } from 'lit'; export const styles = css` .affine-embed-github-block { + container: affine-embed-github-block / inline-size; box-sizing: border-box; display: flex; width: 100%; @@ -24,6 +25,7 @@ export const styles = css` padding: 12px; border-radius: var(--1, 0px); opacity: var(--add, 1); + overflow: hidden; } .affine-embed-github-content-title { @@ -376,6 +378,15 @@ export const styles = css` display: none; } } + + @container affine-embed-github-block (width < 375px) { + .affine-embed-github-content { + width: 100%; + } + .affine-embed-github-banner { + display: none; + } + } `; export const GithubIcon = html` { await openHomePage(page); await waitForEditorLoad(page); - await clickNewPageButton(page, title); + await clickNewPageButton(page); await clickEdgelessModeButton(page); const container = locateEditorContainer(page); await container.click(); @@ -40,3 +41,20 @@ test('should close embed editing modal when editor switching to page mode by sho await waitForEditorLoad(page); expect(editingModal).toBeHidden(); }); + +test('embed card should not overflow the edgeless note', async ({ page }) => { + const note = page.locator('affine-edgeless-note'); + await note.dblclick(); + await type(page, '/github'); + await pressEnter(page); + await page + .locator('.embed-card-modal-input') + .fill('https://github.com/toeverything/AFFiNE/pull/10442'); + await pressEnter(page); + + const embedCard = page.locator('affine-embed-github-block'); + await embedCard + .locator('.affine-embed-github-block:not(.loading)') + .waitFor({ state: 'visible' }); + expect(await isContainedInBoundingBox(note, embedCard, true)).toBe(true); +}); diff --git a/tests/kit/src/utils/utils.ts b/tests/kit/src/utils/utils.ts index ee787eee8c..e1433da830 100644 --- a/tests/kit/src/utils/utils.ts +++ b/tests/kit/src/utils/utils.ts @@ -1,6 +1,6 @@ import { setTimeout } from 'node:timers/promises'; -import type { Page } from '@playwright/test'; +import type { Locator, Page } from '@playwright/test'; import fs from 'fs-extra'; export async function waitForLogMessage( @@ -36,3 +36,37 @@ export async function removeWithRetry( // Add a return statement here to ensure that a value is always returned return false; } + +export async function isContainedInBoundingBox( + container: Locator, + element: Locator, + includeDescendant = false +) { + const containerBox = await container.boundingBox(); + if (!containerBox) { + throw new Error('Container bounding box not found'); + } + const { x: cx, y: cy, width: cw, height: ch } = containerBox; + + const inside = async (el: Locator): Promise => { + const elBox = await el.boundingBox(); + if (!elBox) { + throw new Error('Element bounding box not found'); + } + const { x, y, width, height } = elBox; + + return x >= cx && x + width <= cx + cw && y >= cy && y + height <= cy + ch; + }; + + let isInside = await inside(element); + if (!isInside) return false; + + if (includeDescendant) { + const children = await element.locator('*:visible').all(); + for (const child of children) { + isInside = await inside(child); + if (!isInside) return false; + } + } + return true; +}