From 3c7461a5ce9b9ce9a2e3a8d5e007bba05e2bc283 Mon Sep 17 00:00:00 2001 From: 3720 Date: Thu, 9 Oct 2025 17:04:14 +0800 Subject: [PATCH] fix(editor): adjust callout emoji spacing based on first child block type (#13712) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove fixed marginTop from emoji container style - Dynamically calculate emoji marginTop based on first child block type (h1-h6) - Use model signal to reactively update spacing when children change - Default to 10px for non-heading blocks ## Summary by CodeRabbit - Style - Improved emoji alignment in callout blocks. The emoji now adjusts its top spacing based on the first line’s heading level, ensuring better vertical alignment with headings (H1–H6) and more consistent visual balance across different callout contents. - Maintains existing margins and layout behavior otherwise, resulting in a cleaner, more polished appearance without affecting functionality. --- .../callout/src/callout-block-styles.ts | 2 +- .../blocks/callout/src/callout-block.ts | 37 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/blocksuite/affine/blocks/callout/src/callout-block-styles.ts b/blocksuite/affine/blocks/callout/src/callout-block-styles.ts index 631ce0e7bb..d91eb467cd 100644 --- a/blocksuite/affine/blocks/callout/src/callout-block-styles.ts +++ b/blocksuite/affine/blocks/callout/src/callout-block-styles.ts @@ -20,7 +20,7 @@ export const calloutEmojiContainerStyles = css({ display: 'flex', alignItems: 'center', justifyContent: 'center', - marginTop: '10px', + // marginTop is dynamically set by JavaScript based on first child's height marginBottom: '10px', flexShrink: 0, position: 'relative', diff --git a/blocksuite/affine/blocks/callout/src/callout-block.ts b/blocksuite/affine/blocks/callout/src/callout-block.ts index 7819bbe775..1b753a3125 100644 --- a/blocksuite/affine/blocks/callout/src/callout-block.ts +++ b/blocksuite/affine/blocks/callout/src/callout-block.ts @@ -4,7 +4,10 @@ import { popupTargetFromElement, } from '@blocksuite/affine-components/context-menu'; import { DefaultInlineManagerExtension } from '@blocksuite/affine-inline-preset'; -import { type CalloutBlockModel } from '@blocksuite/affine-model'; +import { + type CalloutBlockModel, + ParagraphBlockModel, +} from '@blocksuite/affine-model'; import { focusTextModel } from '@blocksuite/affine-rich-text'; import { EDGELESS_TOP_CONTENTEDITABLE_SELECTOR } from '@blocksuite/affine-shared/consts'; import { @@ -69,6 +72,35 @@ export class CalloutBlockComponent extends CaptionedBlockComponent = { + 'affine:paragraph:h1': '23px', + 'affine:paragraph:h2': '20px', + 'affine:paragraph:h3': '16px', + 'affine:paragraph:h4': '15px', + 'affine:paragraph:h5': '14px', + 'affine:paragraph:h6': '13px', + }; + + // For heading blocks, use the type to determine margin + if (flavour === 'affine:paragraph') { + const paragraph = firstChild as ParagraphBlockModel; + const type = paragraph.props.type$.value; + const key = `${flavour}:${type}`; + return marginTopMap[key] || '10px'; + } + + // Default for all other block types + return '10px'; + } + private _closeIconPicker() { if (this._popupCloseHandler) { this._popupCloseHandler(); @@ -204,6 +236,9 @@ export class CalloutBlockComponent extends CaptionedBlockComponent ${iconContent}