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 7/7] 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<TolariaCalloutKind, string> = {
+  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<RichEditorBlockTypeKey, PhosphorIcon> = {
@@ -131,6 +129,9 @@ const TOLARIA_SLASH_MENU_ICONS: Partial<Record<string, PhosphorIcon>> = {
   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)
-- 
2.50.1 (Apple Git-155)

