From 2b57543d7855487e75d52fce12714501811fb650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 17 Jul 2026 10:30:04 +0800 Subject: [PATCH] feat: complete portable page block set --- src/components/Editor.css | 16 +++++++++++ src/components/editorSchema.tsx | 3 +++ .../tolariaEditorFormatting.test.tsx | 12 ++++++++- .../tolariaEditorFormattingConfig.ts | 27 ++++++++++++++++--- src/utils/blockNoteDirectMarkdown.test.ts | 9 +++++++ src/utils/calloutMarkdown.ts | 12 +++++++-- 6 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/components/Editor.css b/src/components/Editor.css index 5db3fe1..11a0813 100644 --- a/src/components/Editor.css +++ b/src/components/Editor.css @@ -109,6 +109,22 @@ --tolaria-callout-bg: color-mix(in srgb, #dc2626 10%, var(--bg-primary)); } +.tolaria-callout[data-kind="annotation"] { + --tolaria-callout-accent: #8b5cf6; + --tolaria-callout-bg: color-mix(in srgb, #8b5cf6 11%, var(--bg-primary)); +} + +.tolaria-callout[data-kind="relationship"] { + --tolaria-callout-accent: #0f9f8f; + --tolaria-callout-bg: color-mix(in srgb, #0f9f8f 11%, var(--bg-primary)); +} + +.tolaria-callout[data-kind="path"] { + --tolaria-callout-accent: #4f7ecb; + --tolaria-callout-bg: color-mix(in srgb, #4f7ecb 11%, var(--bg-primary)); + border-style: dashed; +} + .tolaria-callout__marker { width: 4px; min-height: 100%; diff --git a/src/components/editorSchema.tsx b/src/components/editorSchema.tsx index 7d62518..75ceddf 100644 --- a/src/components/editorSchema.tsx +++ b/src/components/editorSchema.tsx @@ -356,8 +356,11 @@ const GuanghuPortalBlock = createReactBlockSpec( ) const CALLOUT_LABELS: Record = { + annotation: '批注', danger: 'Danger', info: 'Info', + path: '路径', + relationship: '关系', success: 'Success', warning: 'Warning', } diff --git a/src/components/tolariaEditorFormatting.test.tsx b/src/components/tolariaEditorFormatting.test.tsx index 7bd06c2..b32ebb7 100644 --- a/src/components/tolariaEditorFormatting.test.tsx +++ b/src/components/tolariaEditorFormatting.test.tsx @@ -60,7 +60,7 @@ describe('tolariaEditorFormatting', () => { ]) }) - it('filters unsupported toggle slash-menu variants and removes command descriptions', () => { + it('keeps Notion-style toggles, filters oversized headings, and removes command descriptions', () => { type TolariaSlashMenuTestItem = { key: string title: string @@ -82,6 +82,8 @@ describe('tolariaEditorFormatting', () => { ] satisfies TolariaSlashMenuTestItem[]) expect(items.map((item) => item.key)).toEqual([ + 'toggle_heading', + 'toggle_list', 'heading', 'heading_4', 'bullet_list', @@ -94,6 +96,8 @@ describe('tolariaEditorFormatting', () => { undefined, undefined, undefined, + undefined, + undefined, ]) }) @@ -280,6 +284,12 @@ describe('tolariaEditorFormatting', () => { styles: {}, }], }]) + + expect(items.map(item => item.key)).toEqual(expect.arrayContaining([ + 'tolaria_callout_annotation', + 'tolaria_callout_relationship', + 'tolaria_callout_path', + ])) }) it('creates a math slash command with a default display equation', () => { diff --git a/src/components/tolariaEditorFormattingConfig.ts b/src/components/tolariaEditorFormattingConfig.ts index 614cbf5..41d9225 100644 --- a/src/components/tolariaEditorFormattingConfig.ts +++ b/src/components/tolariaEditorFormattingConfig.ts @@ -9,6 +9,7 @@ import { CheckCircle, File, FlowArrow, + GitBranch, ImageSquare, Info, ListBullets, @@ -21,6 +22,7 @@ import { ScribbleLoop, Smiley, SpeakerHigh, + Tag, Table, TextHOne, TextHTwo, @@ -90,10 +92,6 @@ const UNSUPPORTED_FORMATTING_TOOLBAR_KEYS = new Set([ const UNSUPPORTED_SLASH_MENU_KEYS = new Set([ 'heading_5', 'heading_6', - 'toggle_heading', - 'toggle_heading_2', - 'toggle_heading_3', - 'toggle_list', ]) const TOLARIA_BLOCK_TYPE_SELECT_ICONS: Record = { @@ -131,6 +129,9 @@ const TOLARIA_SLASH_MENU_ICONS: Partial> = { quote: Quotes, tolaria_callout_danger: XCircle, tolaria_callout_info: Info, + tolaria_callout_annotation: Tag, + tolaria_callout_path: FlowArrow, + tolaria_callout_relationship: GitBranch, tolaria_callout_success: CheckCircle, tolaria_callout_warning: Warning, table: Table, @@ -237,6 +238,24 @@ export function createCalloutSlashMenuItems( aliases: ['callout', 'danger', 'risk', 'error', '风险', '危险'], kind: 'danger', }), + createCalloutSlashMenuItem(editor, { + key: 'tolaria_callout_annotation', + title: '批注 / Annotation', + aliases: ['annotation', 'comment', 'note', '批注', '注释'], + kind: 'annotation', + }), + createCalloutSlashMenuItem(editor, { + key: 'tolaria_callout_relationship', + title: '关系卡 / Relationship', + aliases: ['relationship', 'relation', 'wikilink', '关系', '关联'], + kind: 'relationship', + }), + createCalloutSlashMenuItem(editor, { + key: 'tolaria_callout_path', + title: '路径包 / Path map', + aliases: ['path', 'breadcrumb', 'route', 'map', '路径', '面包屑', '导航'], + kind: 'path', + }), ] } diff --git a/src/utils/blockNoteDirectMarkdown.test.ts b/src/utils/blockNoteDirectMarkdown.test.ts index cabba60..358df27 100644 --- a/src/utils/blockNoteDirectMarkdown.test.ts +++ b/src/utils/blockNoteDirectMarkdown.test.ts @@ -127,6 +127,15 @@ describe('BlockNote direct Markdown serialization', () => { children: [], }, ]).markdown).toBe('> [!success] Package is ready') + + expect(blocksToMarkdownDirect([ + { + type: TOLARIA_CALLOUT_BLOCK_TYPE, + props: { kind: 'relationship' }, + content: [{ type: 'text', text: '[[TCS]] → [[HoloLake]]', styles: {} }], + children: [], + }, + ]).markdown).toBe('> [!relationship] [[TCS]] → [[HoloLake]]') }) it('caches unchanged block objects across rich-editor body serialization', () => { diff --git a/src/utils/calloutMarkdown.ts b/src/utils/calloutMarkdown.ts index b6881b6..2fa2449 100644 --- a/src/utils/calloutMarkdown.ts +++ b/src/utils/calloutMarkdown.ts @@ -2,11 +2,19 @@ import type { BlockLike } from './durableMarkdownBlocks' export const TOLARIA_CALLOUT_BLOCK_TYPE = 'tolariaCallout' -export const TOLARIA_CALLOUT_KINDS = ['info', 'success', 'warning', 'danger'] as const +export const TOLARIA_CALLOUT_KINDS = [ + 'info', + 'success', + 'warning', + 'danger', + 'annotation', + 'relationship', + 'path', +] as const export type TolariaCalloutKind = typeof TOLARIA_CALLOUT_KINDS[number] -const CALLOUT_MARKER_RE = /^\[!(info|success|warning|danger)\]\s*(.*)$/iu +const CALLOUT_MARKER_RE = /^\[!(info|success|warning|danger|annotation|relationship|path)\]\s*(.*)$/iu function isCalloutKind(value: unknown): value is TolariaCalloutKind { return typeof value === 'string' && TOLARIA_CALLOUT_KINDS.includes(value as TolariaCalloutKind)