kc-plate-editor 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +261 -62
  2. package/dist/components/configurator/CodeDrawer.d.ts +10 -0
  3. package/dist/components/configurator/ConfiguratorTab.d.ts +1 -0
  4. package/dist/components/configurator/EditorPreview.d.ts +9 -0
  5. package/dist/components/configurator/ExamplesDrawer.d.ts +6 -0
  6. package/dist/components/configurator/FeatureSelector.d.ts +10 -0
  7. package/dist/components/editor/plate-editor.d.ts +58 -10
  8. package/dist/components/editor/plugins/configurable-toolbar-kit.d.ts +17 -1
  9. package/dist/components/editor/standalone-toolbar.d.ts +52 -0
  10. package/dist/components/editor/table-of-contents.d.ts +21 -0
  11. package/dist/components/{ui → editor/toolbars}/configurable-toolbar.d.ts +1 -1
  12. package/dist/components/editor/toolbars/export-button.d.ts +6 -0
  13. package/dist/components/editor/toolbars/find-replace-button.d.ts +1 -0
  14. package/dist/components/ui/button.d.ts +5 -2
  15. package/dist/components/ui/fixed-toolbar-buttons.d.ts +2 -1
  16. package/dist/components/ui/floating-toolbar-buttons.d.ts +2 -1
  17. package/dist/{index-BEIMyJvn.js → index-B9jFBuVJ.cjs} +1 -1
  18. package/dist/{index-DXE99mkF.js → index-Bh8w1JAM.cjs} +339 -320
  19. package/dist/{index-Drawy4im.mjs → index-BqmOwSZO.js} +30842 -30671
  20. package/dist/{index-CKsqR2Kp.mjs → index-CI-um7kw.js} +1 -1
  21. package/dist/{index-CQ9MhVRi.mjs → index-D5R9tPIM.js} +2 -2
  22. package/dist/{index-Cjpf2atD.js → index-hCIdZ_Vi.cjs} +1 -1
  23. package/dist/index.cjs +1 -1
  24. package/dist/index.d.ts +34 -6
  25. package/dist/index.mjs +109 -72
  26. package/dist/lib/config-provider.d.ts +11 -1
  27. package/dist/lib/toc.d.ts +14 -0
  28. package/dist/lib/toolbar-presets.d.ts +15 -15
  29. package/dist/locales/en-US.d.ts +28 -2
  30. package/dist/locales/index.d.ts +71 -4
  31. package/dist/locales/zh-CN.d.ts +43 -2
  32. package/dist/{react-CZcIaMtb.mjs → react-Bc9tMIHF.js} +2 -2
  33. package/dist/{react-CYElXqmt.mjs → react-LIndOFtY.js} +2 -2
  34. package/dist/react-U07OTDVt.cjs +16 -0
  35. package/dist/react-tGwRm5U-.cjs +11 -0
  36. package/dist/stores/editor-store.d.ts +28 -2
  37. package/dist/style.css +1 -1
  38. package/dist/types/editor-types.d.ts +34 -0
  39. package/dist/types/toolbar-config.d.ts +15 -3
  40. package/package.json +28 -10
  41. package/dist/components/ui/fullscreen-toolbar-button.d.ts +0 -3
  42. package/dist/lib/fullscreen.d.ts +0 -5
  43. package/dist/pages/ApiDemo.d.ts +0 -1
  44. package/dist/pages/Configurator.d.ts +0 -1
  45. package/dist/pages/Editor.d.ts +0 -1
  46. package/dist/pages/Examples.d.ts +0 -1
  47. package/dist/pages/FeatureShowcase.d.ts +0 -1
  48. package/dist/pages/Home.d.ts +0 -1
  49. package/dist/react-C-6r15yv.js +0 -16
  50. package/dist/react-hxgauqI7.js +0 -11
  51. /package/dist/{Preview-BGDe7OsV.js → Preview-BGDe7OsV.cjs} +0 -0
  52. /package/dist/{Preview-ckip2XGc.mjs → Preview-ckip2XGc.js} +0 -0
  53. /package/dist/{custom-media-element-B4vskoi6.mjs → custom-media-element-B4vskoi6.js} +0 -0
  54. /package/dist/{custom-media-element-CiqdUTcd.js → custom-media-element-CiqdUTcd.cjs} +0 -0
  55. /package/dist/{dash.all.min-VODXcrvW.js → dash.all.min-VODXcrvW.cjs} +0 -0
  56. /package/dist/{dash.all.min-mZ3IpU_5.mjs → dash.all.min-mZ3IpU_5.js} +0 -0
  57. /package/dist/{hls-C54ON8N6.js → hls-C54ON8N6.cjs} +0 -0
  58. /package/dist/{hls-Cn4MnxsU.mjs → hls-Cn4MnxsU.js} +0 -0
  59. /package/dist/{html2canvas-pro.esm-B7aTk6co.js → html2canvas-pro.esm-B7aTk6co.cjs} +0 -0
  60. /package/dist/{html2canvas-pro.esm-CQOXKWpT.mjs → html2canvas-pro.esm-CQOXKWpT.js} +0 -0
  61. /package/dist/{react-0OewwyjJ.mjs → react-0OewwyjJ.js} +0 -0
  62. /package/dist/{react-1jldl5V6.js → react-1jldl5V6.cjs} +0 -0
  63. /package/dist/{react-4oo9GGvM.js → react-4oo9GGvM.cjs} +0 -0
  64. /package/dist/{react-B6p7WDog.mjs → react-B6p7WDog.js} +0 -0
  65. /package/dist/{react-BB71DO7H.js → react-BB71DO7H.cjs} +0 -0
  66. /package/dist/{react-BhxJwm-d.js → react-BhxJwm-d.cjs} +0 -0
  67. /package/dist/{react-Bv-bWJKt.mjs → react-Bv-bWJKt.js} +0 -0
  68. /package/dist/{react-C-QUBeUY.js → react-C-QUBeUY.cjs} +0 -0
  69. /package/dist/{react-CbduCSo9.mjs → react-CbduCSo9.js} +0 -0
  70. /package/dist/{react-D2Xlskb3.mjs → react-D2Xlskb3.js} +0 -0
  71. /package/dist/{react-DE-5wXKn.mjs → react-DE-5wXKn.js} +0 -0
  72. /package/dist/{react-DGu3YNSU.js → react-DGu3YNSU.cjs} +0 -0
  73. /package/dist/{server.browser-BzSRCBp5.js → server.browser-BzSRCBp5.cjs} +0 -0
  74. /package/dist/{server.browser-DNro-WMz.mjs → server.browser-DNro-WMz.js} +0 -0
package/README.md CHANGED
@@ -20,19 +20,21 @@ A powerful and customizable rich text editor built on [Plate](https://platejs.or
20
20
  - 🔧 **Granular Control**: Fine-grained control over individual toolbar features
21
21
 
22
22
  ### 扩展功能
23
- - 🔍 **Find & Replace**: Built-in text search and replace functionality
24
- - 📊 **Word Count**: Real-time word, character, and paragraph counting
23
+ - 🔍 **Find & Replace API**: Powerful find and replace API for building custom search functionality
24
+ - 📊 **Word Count**: Real-time word, character, and paragraph counting with Chinese/English mixed text support
25
25
  - 📑 **Outline Navigation**: Automatic document outline generation
26
- - 📤 **Export**: Export to HTML, Markdown, PDF, and Image formats
26
+ - 📤 **Export**: Export to HTML, Markdown, PDF (multi-page support), and Image formats with progress indicators
27
27
  - 🖥️ **Fullscreen Mode**: Distraction-free fullscreen editing
28
+ - 🔧 **Extensible Toolbar**: Add custom buttons to the toolbar with `customToolbarButtons` prop
28
29
 
29
30
  ### 开发体验
30
31
  - 🔌 **Extended API**: Comprehensive API with 30+ methods for content manipulation
31
- - 🛡️ **Error Handling**: Unified error handling with error boundaries
32
- - 📦 **TypeScript**: Full TypeScript support with comprehensive type definitions
33
- - 🚀 **Performance**: Optimized rendering with React.memo and useMemo
32
+ - 🛡️ **Error Handling**: Unified error handling with error boundaries and detailed error logging
33
+ - 📦 **TypeScript**: Full TypeScript support with comprehensive type definitions and strict type safety
34
+ - 🚀 **Performance**: Optimized rendering with debouncing, max match limits, and efficient algorithms
34
35
  - 🔧 **Plugin System**: Flexible plugin architecture with helper utilities
35
36
  - ⚡ **Modern Stack**: Built with React 19, Vite, and Tailwind CSS
37
+ - 💾 **Config Persistence**: Automatic configuration persistence to localStorage
36
38
 
37
39
  ## Installation
38
40
 
@@ -93,7 +95,47 @@ const editorConfig = {
93
95
 
94
96
  function App() {
95
97
  return (
96
- <ConfigProvider config={editorConfig}>
98
+ <ConfigProvider
99
+ config={editorConfig}
100
+ persistKey="my-editor-config" // Custom localStorage key
101
+ enablePersist={true} // Enable auto-save to localStorage
102
+ >
103
+ <PlateEditor />
104
+ </ConfigProvider>
105
+ );
106
+ }
107
+ ```
108
+
109
+ ### Configuration Persistence
110
+
111
+ The editor automatically saves configuration to localStorage:
112
+
113
+ ```tsx
114
+ import { PlateEditor, ConfigProvider, useEditorConfig } from 'kc-plate-editor';
115
+
116
+ function EditorSettings() {
117
+ const { config, updateConfig, resetConfig } = useEditorConfig();
118
+
119
+ return (
120
+ <div>
121
+ <h3>Settings</h3>
122
+ <select
123
+ value={config.locale}
124
+ onChange={(e) => updateConfig({ locale: e.target.value as 'zh-CN' | 'en-US' })}
125
+ >
126
+ <option value="zh-CN">中文</option>
127
+ <option value="en-US">English</option>
128
+ </select>
129
+
130
+ <button onClick={resetConfig}>Reset to Default</button>
131
+ </div>
132
+ );
133
+ }
134
+
135
+ function App() {
136
+ return (
137
+ <ConfigProvider enablePersist={true}>
138
+ <EditorSettings />
97
139
  <PlateEditor />
98
140
  </ConfigProvider>
99
141
  );
@@ -109,11 +151,8 @@ import {
109
151
  PlateEditor,
110
152
  MINIMAL_TOOLBAR,
111
153
  BASIC_TOOLBAR,
112
- RICH_TEXT_TOOLBAR,
113
- MARKDOWN_TOOLBAR,
114
- BLOG_TOOLBAR,
115
154
  DOCUMENT_TOOLBAR,
116
- COMMENT_TOOLBAR,
155
+ FULL_TOOLBAR,
117
156
  getToolbarPreset,
118
157
  } from 'kc-plate-editor';
119
158
  import type { ToolbarConfig } from 'kc-plate-editor';
@@ -122,26 +161,17 @@ function App() {
122
161
  // Use preset configurations
123
162
  return (
124
163
  <>
125
- {/* Minimal editor */}
164
+ {/* Minimal editor - for simple text input */}
126
165
  <PlateEditor toolbarConfig={MINIMAL_TOOLBAR} />
127
166
 
128
- {/* Basic editor */}
167
+ {/* Basic editor - for general editing */}
129
168
  <PlateEditor toolbarConfig={BASIC_TOOLBAR} />
130
169
 
131
- {/* Rich text editor */}
132
- <PlateEditor toolbarConfig={RICH_TEXT_TOOLBAR} />
133
-
134
- {/* Markdown editor */}
135
- <PlateEditor toolbarConfig={MARKDOWN_TOOLBAR} />
136
-
137
- {/* Blog editor */}
138
- <PlateEditor toolbarConfig={BLOG_TOOLBAR} />
139
-
140
- {/* Document editor */}
170
+ {/* Document editor - for rich documents */}
141
171
  <PlateEditor toolbarConfig={DOCUMENT_TOOLBAR} />
142
172
 
143
- {/* Comment editor */}
144
- <PlateEditor toolbarConfig={COMMENT_TOOLBAR} />
173
+ {/* Full editor - all features */}
174
+ <PlateEditor toolbarConfig={FULL_TOOLBAR} />
145
175
 
146
176
  {/* Or use getToolbarPreset */}
147
177
  <PlateEditor toolbarConfig={getToolbarPreset('minimal')} />
@@ -182,6 +212,51 @@ Available feature groups:
182
212
  - **extraFormat**: Superscript, Subscript, Keyboard
183
213
  - **blockOps**: Indent, Outdent, Toggle
184
214
 
215
+ ### Custom Toolbar Buttons
216
+
217
+ Extend the editor toolbar with your own custom buttons:
218
+
219
+ ```tsx
220
+ import { useRef } from 'react';
221
+ import { PlateEditor, type PlateEditorRef, type CustomToolbarButtons } from 'kc-plate-editor';
222
+
223
+ function CustomButton({ editorRef }: { editorRef: React.RefObject<PlateEditorRef> }) {
224
+ const handleClick = () => {
225
+ if (!editorRef.current) return;
226
+
227
+ // Use editor API
228
+ const text = editorRef.current.getText();
229
+ alert(`Editor has ${text.length} characters`);
230
+ };
231
+
232
+ return (
233
+ <button onClick={handleClick} className="h-8 px-2 hover:bg-muted rounded-md">
234
+ Custom
235
+ </button>
236
+ );
237
+ }
238
+
239
+ function App() {
240
+ const editorRef = useRef<PlateEditorRef>(null);
241
+
242
+ const customButtons: CustomToolbarButtons = {
243
+ before: <CustomButton editorRef={editorRef} />, // Add to toolbar start
244
+ after: <CustomButton editorRef={editorRef} />, // Add to toolbar end
245
+ };
246
+
247
+ return (
248
+ <PlateEditor
249
+ ref={editorRef}
250
+ customToolbarButtons={customButtons}
251
+ />
252
+ );
253
+ }
254
+ ```
255
+
256
+ **Examples:**
257
+ - 📁 [Custom Find & Replace Example](src/pages/CustomFindReplaceExample.tsx) - Complete example with UI
258
+ - 📖 See the `/examples` route in the playground for more interactive examples
259
+
185
260
  ### Controlled Mode
186
261
 
187
262
  ```tsx
@@ -197,9 +272,9 @@ function App() {
197
272
  ]);
198
273
 
199
274
  return (
200
- <PlateEditor
201
- value={content}
202
- onChange={setContent}
275
+ <PlateEditor
276
+ value={content}
277
+ onChange={setContent}
203
278
  />
204
279
  );
205
280
  }
@@ -215,6 +290,7 @@ function App() {
215
290
  | onChange | (value: Value) => void | - | Content change callback |
216
291
  | plugins | EditorPluginKit | - | Custom plugin list |
217
292
  | toolbarConfig | ToolbarConfig | - | Toolbar configuration (see below) |
293
+ | customToolbarButtons | CustomToolbarButtons | - | Custom toolbar buttons (see below) |
218
294
  | className | string | - | Custom CSS class |
219
295
  | disabled | boolean | false | Disable editor |
220
296
  | readOnly | boolean | false | Read-only mode |
@@ -222,8 +298,8 @@ function App() {
222
298
  | showToolbar | boolean | true | Show/hide toolbar |
223
299
  | toolbarSticky | boolean | true | Make toolbar sticky |
224
300
  | mode | 'edit' \| 'view' \| 'suggestion' | 'edit' | Editor mode |
301
+ | showSettings | boolean | true | Show/hide settings button |
225
302
  | onModifiedChange | (isModified: boolean) => void | - | Modified state callback |
226
- | onFullscreenChange | (isFullscreen: boolean) => void | - | Fullscreen state callback |
227
303
 
228
304
  ### ToolbarConfig
229
305
 
@@ -243,18 +319,36 @@ interface ToolbarConfig {
243
319
  }
244
320
  ```
245
321
 
322
+ ### CustomToolbarButtons
323
+
324
+ ```typescript
325
+ interface CustomToolbarButtons {
326
+ before?: React.ReactNode; // Buttons to insert at the start of the toolbar
327
+ after?: React.ReactNode; // Buttons to insert at the end of the toolbar
328
+ }
329
+ ```
330
+
331
+ **Example:**
332
+
333
+ ```tsx
334
+ const customButtons: CustomToolbarButtons = {
335
+ before: <MyCustomButton />, // Appears at the start
336
+ after: <AnotherButton />, // Appears at the end
337
+ };
338
+
339
+ <PlateEditor customToolbarButtons={customButtons} />
340
+ ```
341
+
342
+ See [Custom Toolbar Buttons](#custom-toolbar-buttons) section for complete examples.
343
+
246
344
  **Toolbar Presets:**
247
345
 
248
346
  | Preset | Description | Use Case |
249
347
  |--------|-------------|----------|
250
- | `FULL_TOOLBAR` | All features enabled | Full-featured editor |
251
- | `BASIC_TOOLBAR` | Common text editing features | General purpose editing |
252
- | `MINIMAL_TOOLBAR` | Minimal feature set | Simple text input |
253
- | `RICH_TEXT_TOOLBAR` | Rich formatting features | Document editing |
254
- | `MARKDOWN_TOOLBAR` | Markdown-focused features | Markdown editing |
255
- | `BLOG_TOOLBAR` | Blog post editing features | Blog/article writing |
256
- | `DOCUMENT_TOOLBAR` | Formal document features | Professional documents |
257
- | `COMMENT_TOOLBAR` | Comment/annotation features | Comments and notes |
348
+ | `FULL_TOOLBAR` | All features enabled | Full-featured editor with all capabilities |
349
+ | `BASIC_TOOLBAR` | Common text editing features | General purpose editing and content creation |
350
+ | `MINIMAL_TOOLBAR` | Minimal feature set | Simple text input, comments, and notes |
351
+ | `DOCUMENT_TOOLBAR` | Rich document features | Professional documents and formal writing |
258
352
 
259
353
  **Examples:**
260
354
 
@@ -354,6 +448,20 @@ interface EditorConfig {
354
448
  authorization?: string; // Authorization header
355
449
  baseURL?: string; // Base URL for API calls
356
450
  }
451
+
452
+ interface ConfigProviderProps {
453
+ children: ReactNode;
454
+ config?: EditorConfig;
455
+ persistKey?: string; // localStorage key for persistence (default: 'kc-plate-editor-config')
456
+ enablePersist?: boolean; // Enable config persistence (default: true)
457
+ }
458
+
459
+ // Config context methods
460
+ interface ConfigContextType {
461
+ config: EditorConfig;
462
+ updateConfig: (newConfig: Partial<EditorConfig>) => void; // Update config
463
+ resetConfig: () => void; // Reset to default
464
+ }
357
465
  ```
358
466
 
359
467
  ### Exported Types
@@ -507,12 +615,34 @@ configureErrorHandler({
507
615
  });
508
616
  ```
509
617
 
510
- ### Find & Replace
618
+ ### Find & Replace API
619
+
620
+ The editor provides powerful find and replace APIs that you can use to build custom search functionality.
621
+
622
+ **Core APIs:**
623
+
624
+ ```tsx
625
+ // Find text and return match positions
626
+ const matches = editorRef.current?.find('search text', {
627
+ caseSensitive: false, // Optional: case-sensitive search (default: false)
628
+ });
629
+
630
+ // Replace text and return replacement count
631
+ const count = editorRef.current?.replace(
632
+ 'old text',
633
+ 'new text',
634
+ {
635
+ replaceAll: true, // Optional: replace all matches (default: false)
636
+ caseSensitive: false, // Optional: case-sensitive search (default: false)
637
+ }
638
+ );
639
+ ```
640
+
641
+ **Basic Example:**
511
642
 
512
643
  ```tsx
513
644
  import { useRef } from 'react';
514
- import { PlateEditor } from 'kc-plate-editor';
515
- import type { PlateEditorRef } from 'kc-plate-editor';
645
+ import { PlateEditor, type PlateEditorRef } from 'kc-plate-editor';
516
646
 
517
647
  function App() {
518
648
  const editorRef = useRef<PlateEditorRef>(null);
@@ -543,6 +673,38 @@ function App() {
543
673
  }
544
674
  ```
545
675
 
676
+ **Custom Find & Replace UI Example:**
677
+
678
+ For a complete example of building a custom find & replace UI with match highlighting, navigation, and more, see:
679
+ - 📁 [Custom Find Replace Example](src/pages/CustomFindReplaceExample.tsx)
680
+ - 🎮 Run the playground (`pnpm dev`) and visit the examples page
681
+
682
+ **API Reference:**
683
+
684
+ | Method | Parameters | Returns | Description |
685
+ |--------|-----------|---------|-------------|
686
+ | `find()` | `searchText: string`<br/>`options?: FindOptions` | `MatchPosition[]` | Find all matches in the editor |
687
+ | `replace()` | `searchText: string`<br/>`replaceText: string`<br/>`options?: ReplaceOptions` | `number` | Replace text and return count |
688
+
689
+ **Types:**
690
+
691
+ ```typescript
692
+ interface FindOptions {
693
+ caseSensitive?: boolean; // Default: false
694
+ }
695
+
696
+ interface ReplaceOptions {
697
+ caseSensitive?: boolean; // Default: false
698
+ replaceAll?: boolean; // Default: false
699
+ }
700
+
701
+ interface MatchPosition {
702
+ path: number[]; // Node path in the editor
703
+ offset: number; // Character offset
704
+ length: number; // Match length
705
+ }
706
+ ```
707
+
546
708
  ### Word Count & Outline
547
709
 
548
710
  ```tsx
@@ -595,6 +757,36 @@ function App() {
595
757
 
596
758
  ### Export Functions
597
759
 
760
+ The editor provides comprehensive export functionality with the following improvements:
761
+
762
+ **HTML Export:**
763
+ - ✅ Complete styling with Tailwind CSS and KaTeX
764
+ - ✅ Embedded fonts (Inter, JetBrains Mono)
765
+ - ✅ Responsive design
766
+ - ✅ Error handling with user feedback
767
+
768
+ **PDF Export:**
769
+ - ✅ **Multi-page support**: Automatically splits long documents into multiple pages
770
+ - ✅ **A4 page size**: Standard A4 format (595 x 842 points)
771
+ - ✅ **Page margins**: 40pt margins on all sides
772
+ - ✅ **High quality**: 2x scale for crisp text and images
773
+ - ✅ **Auto-scaling**: Content automatically scaled to fit page width
774
+
775
+ **Image Export:**
776
+ - ✅ **High resolution**: 2x scale for better quality
777
+ - ✅ **PNG format**: Lossless compression
778
+ - ✅ **Full content**: Captures entire editor content
779
+
780
+ **Markdown Export:**
781
+ - ✅ Uses Plate.js native serialization
782
+ - ✅ Preserves formatting and structure
783
+
784
+ **All exports include:**
785
+ - ⏳ **Loading indicators**: Shows "Exporting..." during export
786
+ - ❌ **Error handling**: Displays error messages if export fails
787
+ - 📝 **Console logging**: Detailed error logs for debugging
788
+ - 🔒 **Type safety**: Full TypeScript support
789
+
598
790
  ```tsx
599
791
  import { useRef } from 'react';
600
792
  import { PlateEditor } from 'kc-plate-editor';
@@ -604,19 +796,26 @@ function App() {
604
796
  const editorRef = useRef<PlateEditorRef>(null);
605
797
 
606
798
  const handleExport = async (format: 'html' | 'markdown' | 'pdf' | 'image') => {
607
- switch (format) {
608
- case 'html':
609
- await editorRef.current?.exportAsHtml('document.html');
610
- break;
611
- case 'markdown':
612
- await editorRef.current?.exportAsMarkdown('document.md');
613
- break;
614
- case 'pdf':
615
- await editorRef.current?.exportAsPdf('document.pdf');
616
- break;
617
- case 'image':
618
- await editorRef.current?.exportAsImage('document.png');
619
- break;
799
+ try {
800
+ switch (format) {
801
+ case 'html':
802
+ await editorRef.current?.exportAsHtml('document.html');
803
+ break;
804
+ case 'markdown':
805
+ await editorRef.current?.exportAsMarkdown('document.md');
806
+ break;
807
+ case 'pdf':
808
+ // Now supports multi-page PDF export!
809
+ await editorRef.current?.exportAsPdf('document.pdf');
810
+ break;
811
+ case 'image':
812
+ // High-quality 2x resolution
813
+ await editorRef.current?.exportAsImage('document.png');
814
+ break;
815
+ }
816
+ console.log(`${format.toUpperCase()} export successful!`);
817
+ } catch (error) {
818
+ console.error(`${format.toUpperCase()} export failed:`, error);
620
819
  }
621
820
  };
622
821
 
@@ -624,8 +823,8 @@ function App() {
624
823
  <>
625
824
  <button onClick={() => handleExport('html')}>Export HTML</button>
626
825
  <button onClick={() => handleExport('markdown')}>Export Markdown</button>
627
- <button onClick={() => handleExport('pdf')}>Export PDF</button>
628
- <button onClick={() => handleExport('image')}>Export Image</button>
826
+ <button onClick={() => handleExport('pdf')}>Export PDF (Multi-page)</button>
827
+ <button onClick={() => handleExport('image')}>Export Image (2x)</button>
629
828
  <PlateEditor ref={editorRef} />
630
829
  </>
631
830
  );
@@ -792,17 +991,17 @@ Built with [Plate](https://platejs.org/) - a plugin framework for building rich
792
991
 
793
992
  ### Usage Guides
794
993
 
795
- - 📖 [中文使用手册](./docs/USAGE_GUIDE_CN.md) - 完整的中文使用指南
796
- - 📖 [English Usage Guide](./docs/USAGE_GUIDE_EN.md) - Complete English usage guide
797
- - 🔧 [API 实现指南](./docs/API_IMPLEMENTATION_GUIDE.md) - Backend API implementation guide
798
- - 🔌 [后端 API 文档](./docs/BACKEND_API.md) - Backend API documentation
994
+ - 📖 [使用手册](./docs/使用手册.md) - 完整的使用指南
995
+ - 📦 [发包指南](./docs/发包指南.md) - NPM 发布指南
996
+ - 🔧 [后端接口实现指南](./docs/后端接口实现指南.md) - Backend API implementation guide
997
+ - 🔌 [后端接口描述](./docs/后端接口描述.md) - Backend API documentation
799
998
 
800
999
  ### Examples
801
1000
 
802
1001
  For complete examples, check out:
803
- - `/examples` - Playground examples with various use cases
804
- - `FEATURES.md` - Detailed feature documentation
805
- - `CHANGELOG.md` - Version history and updates
1002
+ - Run the playground with `pnpm dev` and explore the examples page
1003
+ - Check `src/pages/` directory for example implementations
1004
+ - See the documentation in `docs/` directory
806
1005
 
807
1006
  ## Support
808
1007
 
@@ -0,0 +1,10 @@
1
+ type CodeFormat = 'typescript' | 'javascript' | 'json';
2
+ interface CodeDrawerProps {
3
+ isOpen: boolean;
4
+ onClose: () => void;
5
+ code: string;
6
+ codeFormat: CodeFormat;
7
+ onCodeFormatChange: (format: CodeFormat) => void;
8
+ }
9
+ export declare function CodeDrawer({ isOpen, onClose, code, codeFormat, onCodeFormatChange, }: CodeDrawerProps): import("react/jsx-runtime").JSX.Element | null;
10
+ export {};
@@ -0,0 +1 @@
1
+ export declare function ConfiguratorTab(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { ToolbarConfig } from '../../types/toolbar-config';
2
+ import { Locale } from '../../locales';
3
+ interface EditorPreviewProps {
4
+ config: ToolbarConfig;
5
+ locale: Locale;
6
+ editorKey: string;
7
+ }
8
+ export declare function EditorPreview({ config, locale, editorKey }: EditorPreviewProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,6 @@
1
+ interface ExamplesDrawerProps {
2
+ isOpen: boolean;
3
+ onClose: () => void;
4
+ }
5
+ export declare function ExamplesDrawer({ isOpen, onClose }: ExamplesDrawerProps): import("react/jsx-runtime").JSX.Element | null;
6
+ export {};
@@ -0,0 +1,10 @@
1
+ interface FeatureSelectorProps {
2
+ selectedFeatures: Set<string>;
3
+ onToggleFeature: (featureId: string) => void;
4
+ onToggleGroupFeatures: (groupId: string) => void;
5
+ onSelectAll: () => void;
6
+ expandedGroups: Set<string>;
7
+ onToggleGroup: (groupId: string) => void;
8
+ }
9
+ export declare function FeatureSelector({ selectedFeatures, onToggleFeature, onToggleGroupFeatures, onSelectAll, expandedGroups, onToggleGroup, }: FeatureSelectorProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -1,9 +1,29 @@
1
1
  import { Value } from 'platejs';
2
2
  import { TPlateEditor } from 'platejs/react';
3
3
  import { EditorPluginKit } from '../../types/plugin-types';
4
- import { ToolbarConfig } from '../../types/toolbar-config';
4
+ import { ToolbarConfig, ToolbarAlign } from '../../types/toolbar-config';
5
5
  import { EditorMode, WordCountResult, OutlineItem, FindOptions, ReplaceOptions, MatchPosition } from '../../types/editor-types';
6
6
  import * as React from 'react';
7
+ /**
8
+ * 自定义工具栏按钮配置
9
+ */
10
+ export interface CustomToolbarButtons {
11
+ /** 在工具栏开始位置插入的按钮 */
12
+ before?: React.ReactNode;
13
+ /** 在工具栏末尾插入的按钮 */
14
+ after?: React.ReactNode;
15
+ }
16
+ /**
17
+ * 工具栏引用接口
18
+ */
19
+ export interface ToolbarRef {
20
+ /** 获取工具栏容器元素 */
21
+ getElement: () => HTMLDivElement | null;
22
+ /** 设置工具栏可见性 */
23
+ setVisible: (visible: boolean) => void;
24
+ /** 获取工具栏可见性 */
25
+ isVisible: () => boolean;
26
+ }
7
27
  /**
8
28
  * PlateEditor 组件属性
9
29
  */
@@ -30,16 +50,50 @@ export interface PlateEditorProps {
30
50
  toolbarSticky?: boolean;
31
51
  /** 编辑器模式:'edit' | 'view' | 'suggestion' */
32
52
  mode?: EditorMode;
53
+ /** 是否显示右侧设置按钮,默认 true */
54
+ showSettings?: boolean;
33
55
  /** 修改状态变化回调 */
34
56
  onModifiedChange?: (isModified: boolean) => void;
35
- /** 全屏状态变化回调 */
36
- onFullscreenChange?: (isFullscreen: boolean) => void;
57
+ /** 自定义工具栏按钮 */
58
+ customToolbarButtons?: CustomToolbarButtons;
59
+ /** 工具栏按钮对齐方式:left | center | right,默认 left */
60
+ toolbarAlign?: ToolbarAlign;
61
+ /** 工具栏是否占据全宽(不受内容区域宽度限制),默认 false */
62
+ toolbarFullWidth?: boolean;
63
+ /** 自定义工具栏的 CSS 类名 */
64
+ toolbarClassName?: string;
65
+ /** 自定义工具栏的内联样式对象 */
66
+ toolbarStyle?: React.CSSProperties;
67
+ /** 自定义渲染工具栏的函数 */
68
+ renderToolbar?: (toolbar: React.ReactNode) => React.ReactNode;
69
+ /** 编辑器内容区域的最大宽度 */
70
+ contentMaxWidth?: string | number;
71
+ /** 是否显示目录,默认 false */
72
+ showToc?: boolean;
73
+ /** 目录位置,默认 'left' */
74
+ tocPosition?: import('../../types/editor-types').TocPosition;
75
+ /** 目录宽度(当位置为 left/right 时),默认 '240px' */
76
+ tocWidth?: string | number;
77
+ /** 自定义目录的 CSS 类名 */
78
+ tocClassName?: string;
79
+ /** 自定义目录的内联样式对象 */
80
+ tocStyle?: React.CSSProperties;
81
+ /** 自定义渲染目录的函数 */
82
+ renderToc?: (toc: React.ReactNode) => React.ReactNode;
37
83
  }
38
84
  /**
39
85
  * PlateEditor 组件引用接口
40
86
  * 提供编辑器的所有操作方法
41
87
  */
42
88
  export interface PlateEditorRef {
89
+ /** 获取工具栏实例或引用 */
90
+ getToolbar: () => ToolbarRef | null;
91
+ /** 设置工具栏的显示/隐藏状态 */
92
+ setToolbarVisible: (visible: boolean) => void;
93
+ /** 获取目录实例或引用 */
94
+ getToc: () => import('../../types/editor-types').TocRef | null;
95
+ /** 设置目录的显示/隐藏状态 */
96
+ setTocVisible: (visible: boolean) => void;
43
97
  /** 获取编辑器内容(JSON 格式) */
44
98
  getContent: () => Value;
45
99
  /** 设置编辑器内容 */
@@ -52,7 +106,7 @@ export interface PlateEditorRef {
52
106
  getMarkdown: () => string;
53
107
  /** 从 Markdown 加载内容 */
54
108
  setMarkdown: (markdown: string) => void;
55
- /** 导出为 HTML 格式 */
109
+ /** 导出为 HTML 文件 */
56
110
  getHtml: () => Promise<string>;
57
111
  /** 从 HTML 加载内容 */
58
112
  setHtml: (html: string) => void;
@@ -98,11 +152,5 @@ export interface PlateEditorRef {
98
152
  getOutline: () => OutlineItem[];
99
153
  /** 获取字数统计 */
100
154
  getWordCount: () => WordCountResult;
101
- /** 进入全屏模式 */
102
- enterFullscreen: () => Promise<void>;
103
- /** 退出全屏模式 */
104
- exitFullscreen: () => Promise<void>;
105
- /** 检查是否处于全屏模式 */
106
- isFullscreen: () => boolean;
107
155
  }
108
156
  export declare const PlateEditor: React.ForwardRefExoticComponent<PlateEditorProps & React.RefAttributes<PlateEditorRef>>;
@@ -1,8 +1,24 @@
1
- import { ToolbarConfig } from '../../../types/toolbar-config';
1
+ import { ToolbarConfig, ToolbarAlign } from '../../../types/toolbar-config';
2
+ import { default as React } from 'react';
2
3
  export interface ConfigurableToolbarKitOptions {
3
4
  /** 是否显示工具栏,默认 true */
4
5
  showToolbar?: boolean;
5
6
  /** 工具栏是否吸顶,默认 true */
6
7
  toolbarSticky?: boolean;
8
+ /** 工具栏对齐方式(可选,当前仅预留,不影响渲染) */
9
+ toolbarAlign?: ToolbarAlign;
10
+ /** 是否全宽(可选,当前仅预留,不影响渲染) */
11
+ toolbarFullWidth?: boolean;
12
+ /** 自定义类名(可选) */
13
+ toolbarClassName?: string;
14
+ /** 内联样式(可选) */
15
+ toolbarStyle?: React.CSSProperties;
16
+ /** 自定义渲染函数(可选) */
17
+ renderToolbar?: (toolbar: React.ReactNode) => React.ReactNode;
18
+ /** 自定义按钮插槽(可选,当前仅预留,不影响渲染) */
19
+ customButtons?: {
20
+ before?: React.ReactNode;
21
+ after?: React.ReactNode;
22
+ };
7
23
  }
8
24
  export declare function createConfigurableToolbarKit(config: ToolbarConfig, options?: ConfigurableToolbarKitOptions): any[];
@@ -0,0 +1,52 @@
1
+ import { ToolbarConfig, ToolbarAlign } from '../../types/toolbar-config';
2
+ import { CustomToolbarButtons } from './plate-editor';
3
+ import { EditorPluginKit } from '../../types/plugin-types';
4
+ import * as React from 'react';
5
+ /**
6
+ * 独立工具栏组件的属性
7
+ */
8
+ export interface StandaloneToolbarProps {
9
+ /** 工具栏配置 */
10
+ config: ToolbarConfig;
11
+ /** 编辑器实例(可选,如果不提供则创建一个内部实例) */
12
+ editor?: any;
13
+ /** 自定义插件列表(可选) */
14
+ plugins?: EditorPluginKit;
15
+ /** 是否显示工具栏,默认 true */
16
+ showToolbar?: boolean;
17
+ /** 工具栏是否吸顶,默认 true */
18
+ sticky?: boolean;
19
+ /** 工具栏按钮对齐方式,默认 left */
20
+ align?: ToolbarAlign;
21
+ /** 工具栏是否占据全宽,默认 false */
22
+ fullWidth?: boolean;
23
+ /** 自定义工具栏的 CSS 类名 */
24
+ className?: string;
25
+ /** 自定义工具栏的内联样式对象 */
26
+ style?: React.CSSProperties;
27
+ /** 自定义工具栏按钮 */
28
+ customButtons?: CustomToolbarButtons;
29
+ }
30
+ /**
31
+ * 独立工具栏组件
32
+ * 可以在编辑器组件外部独立使用,提供完整的工具栏功能
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * // 基础使用
37
+ * <StandaloneToolbar config={FULL_TOOLBAR} />
38
+ *
39
+ * // 自定义样式和对齐
40
+ * <StandaloneToolbar
41
+ * config={BASIC_TOOLBAR}
42
+ * align="center"
43
+ * className="my-custom-toolbar"
44
+ * style={{ backgroundColor: '#f0f0f0' }}
45
+ * />
46
+ *
47
+ * // 与编辑器实例关联
48
+ * const editor = usePlateEditor({ plugins: EditorKit });
49
+ * <StandaloneToolbar config={FULL_TOOLBAR} editor={editor} />
50
+ * ```
51
+ */
52
+ export declare const StandaloneToolbar: React.ForwardRefExoticComponent<StandaloneToolbarProps & React.RefAttributes<HTMLDivElement>>;