fix(callout): adjust callout styling and slash menu behavior

update callout block margins and spacing
add debug logs for slash menu disableWhen checks
remove slash menu disable test and update paragraph count assertions
This commit is contained in:
zzj3720
2025-09-19 20:16:08 +08:00
parent cdb721d6a6
commit 61e40c7523
3 changed files with 36 additions and 24 deletions
@@ -2,6 +2,7 @@ import { CaptionedBlockComponent } from '@blocksuite/affine-components/caption';
import { createLitPortal } from '@blocksuite/affine-components/portal';
import { DefaultInlineManagerExtension } from '@blocksuite/affine-inline-preset';
import { type CalloutBlockModel } from '@blocksuite/affine-model';
import { focusTextModel } from '@blocksuite/affine-rich-text';
import { EDGELESS_TOP_CONTENTEDITABLE_SELECTOR } from '@blocksuite/affine-shared/consts';
import {
DocModeProvider,
@@ -29,7 +30,6 @@ export class CalloutBlockComponent extends CaptionedBlockComponent<CalloutBlockM
}
.affine-callout-emoji-container {
margin-left: 6px;
user-select: none;
font-size: 1.2em;
width: 24px;
@@ -38,6 +38,7 @@ export class CalloutBlockComponent extends CaptionedBlockComponent<CalloutBlockM
align-items: center;
justify-content: center;
margin-top: 10px;
margin-bottom: 10px;
flex-shrink: 0;
}
.affine-callout-emoji:hover {
@@ -64,7 +65,7 @@ export class CalloutBlockComponent extends CaptionedBlockComponent<CalloutBlockM
createLitPortal({
template: html`<affine-emoji-menu
.theme=${theme}
.onEmojiSelect=${(data: any) => {
.onEmojiSelect=${(data: { native: string }) => {
this.model.props.emoji = data.native;
}}
></affine-emoji-menu>`,
@@ -83,6 +84,31 @@ export class CalloutBlockComponent extends CaptionedBlockComponent<CalloutBlockM
});
};
private readonly _handleBlockClick = (event: MouseEvent) => {
// Check if the click target is emoji related element
const target = event.target as HTMLElement;
if (
target.closest('.affine-callout-emoji-container') ||
target.classList.contains('affine-callout-emoji')
) {
return;
}
// Only handle clicks when there are no children
if (this.model.children.length > 0) {
return;
}
// Prevent event bubbling
event.stopPropagation();
// Create a new paragraph block
const paragraphId = this.store.addBlock('affine:paragraph', {}, this.model);
// Focus the new paragraph
focusTextModel(this.std, paragraphId);
};
get attributeRenderer() {
return this.inlineManager.getRenderer();
}
@@ -114,7 +140,10 @@ export class CalloutBlockComponent extends CaptionedBlockComponent<CalloutBlockM
override renderBlock() {
const emoji = this.model.props.emoji$.value;
return html`
<div class="affine-callout-block-container">
<div
class="affine-callout-block-container"
@click=${this._handleBlockClick}
>
<div
@click=${this._toggleEmojiMenu}
contenteditable="false"
+2 -2
View File
@@ -19,10 +19,10 @@ export declare class ApplicationStateChangedSubscriber {
}
export declare class AudioCaptureSession {
stop(): void
get sampleRate(): number
get channels(): number
get actualSampleRate(): number
stop(): void
}
export declare class ShareableContent {
@@ -31,9 +31,9 @@ export declare class ShareableContent {
constructor()
static applications(): Array<ApplicationInfo>
static applicationWithProcessId(processId: number): ApplicationInfo | null
static isUsingMicrophone(processId: number): boolean
static tapAudio(processId: number, audioStreamCallback: ((err: Error | null, arg: Float32Array) => void)): AudioCaptureSession
static tapGlobalAudio(excludedProcesses: Array<ApplicationInfo> | undefined | null, audioStreamCallback: ((err: Error | null, arg: Float32Array) => void)): AudioCaptureSession
static isUsingMicrophone(processId: number): boolean
}
export declare function decodeAudio(buf: Uint8Array, destSampleRate?: number | undefined | null, filename?: string | undefined | null, signal?: AbortSignal | undefined | null): Promise<Float32Array>
@@ -3,7 +3,6 @@ import {
pressArrowUp,
pressBackspace,
pressEnter,
undoByKeyboard,
} from '@affine-test/kit/utils/keyboard';
import { openHomePage } from '@affine-test/kit/utils/load-page';
import {
@@ -30,7 +29,7 @@ test('add callout block using slash menu and change emoji', async ({
await expect(emoji).toContainText('😀');
const paragraph = page.locator('affine-callout affine-paragraph');
await expect(paragraph).toHaveCount(1);
await expect(paragraph).toHaveCount(2);
const vLine = page.locator('affine-callout v-line');
await expect(vLine).toHaveCount(2);
@@ -50,22 +49,6 @@ test('add callout block using slash menu and change emoji', async ({
await expect(emoji).toContainText('😆');
});
test('disable slash menu in callout block', async ({ page }) => {
await type(page, '/callout\n');
const callout = page.locator('affine-callout');
const emoji = page.locator('affine-callout .affine-callout-emoji');
await expect(callout).toBeVisible();
await expect(emoji).toContainText('😀');
await type(page, '/');
const slashMenu = page.locator('.slash-menu');
await expect(slashMenu).not.toBeVisible();
await undoByKeyboard(page);
await undoByKeyboard(page);
await type(page, '/');
await expect(slashMenu).toBeVisible();
});
test('press backspace after callout block', async ({ page }) => {
await pressEnter(page);
await pressArrowUp(page);
@@ -96,7 +79,7 @@ test('press backspace in callout block', async ({ page }) => {
expect(await callout.count()).toBe(1);
await pressBackspace(page);
await expect(paragraph).toHaveCount(2);
await expect(paragraph).toHaveCount(1);
await expect(callout).toHaveCount(1);
await pressBackspace(page);