From d4c5b402844cb98591c8757ef3f94e095fe6fd4b Mon Sep 17 00:00:00 2001 From: Flrande <1978616327@qq.com> Date: Wed, 28 May 2025 10:38:23 +0000 Subject: [PATCH] fix(editor): code block ui issues (#12609) Close BS-3423 Close BS-3505 ## Summary by CodeRabbit - **Style** - Updated toolbar button background color and adjusted layout spacing for toolbar and preview buttons to improve visual consistency. - **Refactor** - Reorganized toolbar menu groups for better clarity, separating toggle and clipboard actions within the code block toolbar. - **Bug Fixes** - Improved UI interaction in code block tests to ensure menus behave as expected without closing prematurely. --- .../code-toolbar/components/code-toolbar.ts | 6 +- .../code-toolbar/components/preview-button.ts | 4 ++ .../blocks/code/src/code-toolbar/config.ts | 20 +++--- .../code-toolbar/setup-code-toolbar.ts | 61 ++++++++++--------- tests/blocksuite/e2e/code/crud.spec.ts | 12 +++- 5 files changed, 59 insertions(+), 44 deletions(-) diff --git a/blocksuite/affine/blocks/code/src/code-toolbar/components/code-toolbar.ts b/blocksuite/affine/blocks/code/src/code-toolbar/components/code-toolbar.ts index 83d14c1ed7..4ee4c0869f 100644 --- a/blocksuite/affine/blocks/code/src/code-toolbar/components/code-toolbar.ts +++ b/blocksuite/affine/blocks/code/src/code-toolbar/components/code-toolbar.ts @@ -35,14 +35,10 @@ export class AffineCodeToolbar extends WithDisposable(LitElement) { .code-toolbar-button { color: ${unsafeCSSVarV2('icon/primary')}; - background-color: ${unsafeCSSVarV2('segment/background')}; + background-color: ${unsafeCSSVarV2('button/secondary')}; box-shadow: var(--affine-shadow-1); border-radius: 4px; } - - .copy-code { - margin-left: auto; - } `; private _currentOpenMenu: AbortController | null = null; diff --git a/blocksuite/affine/blocks/code/src/code-toolbar/components/preview-button.ts b/blocksuite/affine/blocks/code/src/code-toolbar/components/preview-button.ts index a320dee965..060e97fe8c 100644 --- a/blocksuite/affine/blocks/code/src/code-toolbar/components/preview-button.ts +++ b/blocksuite/affine/blocks/code/src/code-toolbar/components/preview-button.ts @@ -13,6 +13,10 @@ import { CodeBlockPreviewIdentifier } from '../../code-preview-extension'; export class PreviewButton extends WithDisposable(SignalWatcher(LitElement)) { static override styles = css` + :host { + margin-right: auto; + } + .preview-toggle-container { display: flex; padding: 2px; diff --git a/blocksuite/affine/blocks/code/src/code-toolbar/config.ts b/blocksuite/affine/blocks/code/src/code-toolbar/config.ts index e96ddfaff0..4d0fd79971 100644 --- a/blocksuite/affine/blocks/code/src/code-toolbar/config.ts +++ b/blocksuite/affine/blocks/code/src/code-toolbar/config.ts @@ -117,13 +117,12 @@ export const PRIMARY_GROUPS: MenuItemGroup[] = [ }, ]; -// Clipboard Group -export const clipboardGroup: MenuItemGroup = { - type: 'clipboard', +export const toggleGroup: MenuItemGroup = { + type: 'toggle', items: [ { type: 'wrap', - generate: ({ blockComponent, close }) => { + generate: ({ blockComponent }) => { return { action: () => {}, render: () => { @@ -134,7 +133,6 @@ export const clipboardGroup: MenuItemGroup = { { blockComponent.setWrap(!wrapped); - close(); }} aria-label=${label} > @@ -155,7 +153,7 @@ export const clipboardGroup: MenuItemGroup = { when: ({ std }) => std.getOptional(CodeBlockConfigExtension.identifier)?.showLineNumbers ?? true, - generate: ({ blockComponent, close }) => { + generate: ({ blockComponent }) => { return { action: () => {}, render: () => { @@ -167,8 +165,6 @@ export const clipboardGroup: MenuItemGroup = { blockComponent.store.updateBlock(blockComponent.model, { lineNumber: !lineNumber, }); - - close(); }} aria-label=${label} > @@ -184,6 +180,13 @@ export const clipboardGroup: MenuItemGroup = { }; }, }, + ], +}; + +// Clipboard Group +export const clipboardGroup: MenuItemGroup = { + type: 'clipboard', + items: [ { type: 'duplicate', label: 'Duplicate', @@ -233,6 +236,7 @@ export const deleteGroup: MenuItemGroup = { }; export const MORE_GROUPS: MenuItemGroup[] = [ + toggleGroup, clipboardGroup, deleteGroup, ]; diff --git a/packages/frontend/core/src/blocksuite/ai/entries/code-toolbar/setup-code-toolbar.ts b/packages/frontend/core/src/blocksuite/ai/entries/code-toolbar/setup-code-toolbar.ts index b600d1a998..7d64eaf1d0 100644 --- a/packages/frontend/core/src/blocksuite/ai/entries/code-toolbar/setup-code-toolbar.ts +++ b/packages/frontend/core/src/blocksuite/ai/entries/code-toolbar/setup-code-toolbar.ts @@ -15,34 +15,37 @@ import { buildAICodeItemGroups } from '../../_common/config'; import type { AskAIButtonOptions } from '../../components/ask-ai-button'; export function setupCodeToolbarAIEntry(codeToolbar: AffineCodeToolbarWidget) { - codeToolbar.addPrimaryItems([ - { - type: 'ask-ai', - when: ({ doc }) => !doc.readonly, - generate: ({ host, blockComponent }) => { - return { - action: () => { - const { selection } = host; - selection.setGroup('note', [ - selection.create(BlockSelection, { - blockId: blockComponent.blockId, - }), - ]); - }, - render: item => - html` { - e.stopPropagation(); - item.action(); - }} - >`, - }; + codeToolbar.addPrimaryItems( + [ + { + type: 'ask-ai', + when: ({ doc }) => !doc.readonly, + generate: ({ host, blockComponent }) => { + return { + action: () => { + const { selection } = host; + selection.setGroup('note', [ + selection.create(BlockSelection, { + blockId: blockComponent.blockId, + }), + ]); + }, + render: item => + html` { + e.stopPropagation(); + item.action(); + }} + >`, + }; + }, }, - }, - ]); + ], + 2 + ); } diff --git a/tests/blocksuite/e2e/code/crud.spec.ts b/tests/blocksuite/e2e/code/crud.spec.ts index 203c75b10a..a73ee2e820 100644 --- a/tests/blocksuite/e2e/code/crud.spec.ts +++ b/tests/blocksuite/e2e/code/crud.spec.ts @@ -219,6 +219,8 @@ test('duplicate code block', async ({ page }, testInfo) => { await codeBlockController.codeBlock.hover(); await (await codeBlockController.openMore()).wrapButton.click(); + await page.mouse.click(300, 300); + // duplicate await codeBlockController.codeBlock.hover(); await (await codeBlockController.openMore()).duplicateButton.click(); @@ -270,6 +272,8 @@ test('toggle code block wrap can work', async ({ page }, testInfo) => { await codeBlockController.codeBlock.hover(); await (await codeBlockController.openMore()).wrapButton.click(); + await page.mouse.click(300, 300); + expect(await getPageSnapshot(page, true)).toMatchSnapshot( `${testInfo.title}_2.json` ); @@ -335,6 +339,8 @@ test('toggle code block line number can work', async ({ page }) => { await codeBlockController.codeBlock.hover(); await (await codeBlockController.openMore()).cancelLineNumberButton.click(); + await page.mouse.click(300, 300); + await expect(lineNumber).toBeHidden(); await undoByKeyboard(page); @@ -389,7 +395,9 @@ test('should tab works in code block', async ({ page }) => { await assertRichTexts(page, ['const a = 10;\n \nconst b = "NothingToSay"']); }); -test('should open more menu and close on selecting', async ({ page }) => { +test('should open more menu and do not close after selecting', async ({ + page, +}) => { await enterPlaygroundRoom(page); await initEmptyCodeBlockState(page); await focusRichText(page); @@ -401,7 +409,7 @@ test('should open more menu and close on selecting', async ({ page }) => { await expect(moreMenu.menu).toBeVisible(); await moreMenu.wrapButton.click(); - await expect(moreMenu.menu).toBeHidden(); + await expect(moreMenu.menu).toBeVisible(); }); test('should code block lang input supports alias', async ({ page }) => {