@vizel/react 0.0.1-alpha.1

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.
@@ -0,0 +1,965 @@
1
+ import { ComponentProps } from 'react';
2
+ import { CustomIconMap } from '@vizel/core';
3
+ import { default as default_2 } from 'react';
4
+ import { Editor } from '@vizel/core';
5
+ import { Icon } from '@iconify/react';
6
+ import { JSONContent } from '@vizel/core';
7
+ import { JSX } from 'react/jsx-runtime';
8
+ import { ReactNode } from 'react';
9
+ import { Ref } from 'react';
10
+ import { SuggestionOptions } from '@vizel/core';
11
+ import { VizelAutoSaveOptions } from '@vizel/core';
12
+ import { VizelColorDefinition } from '@vizel/core';
13
+ import { VizelCreateEditorOptions } from '@vizel/core';
14
+ import { VizelEditorState } from '@vizel/core';
15
+ import { VizelEmbedData } from '@vizel/core';
16
+ import { VizelFeatureOptions } from '@vizel/core';
17
+ import { VizelIconContextValue } from '@vizel/core';
18
+ import { VizelIconName } from '@vizel/core';
19
+ import { VizelMarkdownSyncOptions } from '@vizel/core';
20
+ import { VizelNodeTypeOption } from '@vizel/core';
21
+ import { VizelPortalLayer } from '@vizel/core';
22
+ import { VizelSaveStatus } from '@vizel/core';
23
+ import { VizelSlashCommandItem } from '@vizel/core';
24
+ import { VizelSlashMenuRendererOptions } from '@vizel/core';
25
+ import { VizelThemeProviderOptions } from '@vizel/core';
26
+ import { VizelThemeState } from '@vizel/core';
27
+
28
+ /**
29
+ * Creates a suggestion render configuration for the SlashCommand extension.
30
+ * This handles the popup positioning and React component lifecycle.
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * import { VizelSlashCommand } from '@vizel/core';
35
+ * import { createVizelSlashMenuRenderer } from '@vizel/react';
36
+ *
37
+ * const editor = useEditor({
38
+ * extensions: [
39
+ * VizelSlashCommand.configure({
40
+ * suggestion: createVizelSlashMenuRenderer(),
41
+ * }),
42
+ * ],
43
+ * });
44
+ * ```
45
+ */
46
+ export declare function createVizelSlashMenuRenderer(options?: VizelSlashMenuRendererOptions): Partial<SuggestionOptions<VizelSlashCommandItem>>;
47
+
48
+ /**
49
+ * Hook for auto-saving editor content with debouncing.
50
+ *
51
+ * @param getEditor - Function that returns the editor instance
52
+ * @param options - Auto-save configuration options
53
+ * @returns Auto-save state and controls
54
+ *
55
+ * @example
56
+ * ```tsx
57
+ * function Editor() {
58
+ * const editor = useVizelEditor({ ... });
59
+ * const { status, lastSaved, save } = useVizelAutoSave(() => editor, {
60
+ * debounceMs: 2000,
61
+ * storage: 'localStorage',
62
+ * key: 'my-document',
63
+ * });
64
+ *
65
+ * return (
66
+ * <div>
67
+ * <EditorContent editor={editor} />
68
+ * <SaveIndicator status={status} lastSaved={lastSaved} />
69
+ * </div>
70
+ * );
71
+ * }
72
+ * ```
73
+ */
74
+ export declare function useVizelAutoSave(getEditor: () => Editor | null | undefined, options?: VizelAutoSaveOptions): UseVizelAutoSaveResult;
75
+
76
+ /**
77
+ * Auto-save hook result
78
+ */
79
+ export declare interface UseVizelAutoSaveResult {
80
+ /** Current save status */
81
+ status: VizelSaveStatus;
82
+ /** Whether there are unsaved changes */
83
+ hasUnsavedChanges: boolean;
84
+ /** Timestamp of last successful save */
85
+ lastSaved: Date | null;
86
+ /** Last error that occurred */
87
+ error: Error | null;
88
+ /** Manually trigger save */
89
+ save: () => Promise<void>;
90
+ /** Restore content from storage */
91
+ restore: () => Promise<JSONContent | null>;
92
+ }
93
+
94
+ /**
95
+ * Hook to access the editor instance from context.
96
+ *
97
+ * @throws Error if used outside of VizelProvider
98
+ *
99
+ * @example
100
+ * ```tsx
101
+ * function BoldButton() {
102
+ * const { editor } = useVizelContext();
103
+ * if (!editor) return null;
104
+ *
105
+ * return (
106
+ * <button onClick={() => editor.chain().focus().toggleBold().run()}>
107
+ * Bold
108
+ * </button>
109
+ * );
110
+ * }
111
+ * ```
112
+ */
113
+ export declare function useVizelContext(): VizelContextValue;
114
+
115
+ /**
116
+ * Hook to access the editor instance from context.
117
+ * Returns null if used outside of VizelProvider (does not throw).
118
+ */
119
+ export declare function useVizelContextSafe(): VizelContextValue | null;
120
+
121
+ /**
122
+ * React hook to create and manage a Vizel editor instance.
123
+ *
124
+ * @example
125
+ * ```tsx
126
+ * const editor = useVizelEditor({
127
+ * placeholder: "Start typing...",
128
+ * onUpdate: ({ editor }) => {
129
+ * console.log(editor.getJSON());
130
+ * },
131
+ * });
132
+ *
133
+ * return <EditorContent editor={editor} />;
134
+ * ```
135
+ *
136
+ * @example
137
+ * ```tsx
138
+ * // With initial markdown content
139
+ * const editor = useVizelEditor({
140
+ * initialMarkdown: "# Hello World\n\nThis is **bold** text.",
141
+ * });
142
+ * ```
143
+ */
144
+ export declare function useVizelEditor(options?: UseVizelEditorOptions): Editor | null;
145
+
146
+ /**
147
+ * Options for useVizelEditor hook.
148
+ * @see VizelCreateEditorOptions for available options.
149
+ */
150
+ export declare type UseVizelEditorOptions = VizelCreateEditorOptions;
151
+
152
+ /**
153
+ * Hook that returns the current editor state and re-renders on state changes.
154
+ * This is a convenience hook that combines `useVizelState` (for reactivity)
155
+ * and `getVizelEditorState` (for state extraction).
156
+ *
157
+ * @param getEditor - A function that returns the editor instance to observe
158
+ * @returns The current editor state including focus, empty status, undo/redo, and character/word counts
159
+ *
160
+ * @example
161
+ * ```tsx
162
+ * function StatusBar({ editor }: { editor: Editor | null }) {
163
+ * const { characterCount, wordCount, canUndo, canRedo } = useVizelEditorState(() => editor);
164
+ *
165
+ * return (
166
+ * <div className="status-bar">
167
+ * <span>{characterCount} characters</span>
168
+ * <span>{wordCount} words</span>
169
+ * <button disabled={!canUndo}>Undo</button>
170
+ * <button disabled={!canRedo}>Redo</button>
171
+ * </div>
172
+ * );
173
+ * }
174
+ * ```
175
+ */
176
+ export declare function useVizelEditorState(getEditor: () => Editor | null | undefined): VizelEditorState;
177
+
178
+ /**
179
+ * Hook to access custom icon mappings from VizelIconProvider.
180
+ * Returns undefined if no VizelIconProvider is present (falls back to defaults).
181
+ */
182
+ export declare function useVizelIconContext(): VizelIconContextValue;
183
+
184
+ /**
185
+ * React hook for bidirectional Markdown synchronization with the editor.
186
+ *
187
+ * @param getEditor - Function to get the editor instance
188
+ * @param options - Sync options
189
+ * @returns Markdown state and control functions
190
+ *
191
+ * @example
192
+ * ```tsx
193
+ * import { useVizelEditor, useVizelMarkdown } from '@vizel/react';
194
+ *
195
+ * function App() {
196
+ * const editor = useVizelEditor();
197
+ * const { markdown, setMarkdown, isPending } = useVizelMarkdown(() => editor, {
198
+ * debounceMs: 300,
199
+ * });
200
+ *
201
+ * return (
202
+ * <div>
203
+ * <VizelEditor editor={editor} />
204
+ * <textarea
205
+ * value={markdown}
206
+ * onChange={(e) => setMarkdown(e.target.value)}
207
+ * />
208
+ * {isPending && <span>Syncing...</span>}
209
+ * </div>
210
+ * );
211
+ * }
212
+ * ```
213
+ *
214
+ * @example
215
+ * ```tsx
216
+ * // With initial markdown value
217
+ * const { markdown, setMarkdown } = useVizelMarkdown(() => editor, {
218
+ * initialValue: "# Hello World",
219
+ * transformDiagrams: true,
220
+ * });
221
+ * ```
222
+ */
223
+ export declare function useVizelMarkdown(getEditor: () => Editor | null | undefined, options?: UseVizelMarkdownOptions): UseVizelMarkdownResult;
224
+
225
+ export declare interface UseVizelMarkdownOptions extends VizelMarkdownSyncOptions {
226
+ /**
227
+ * Initial markdown value. If provided, this will be set to the editor on mount.
228
+ */
229
+ initialValue?: string;
230
+ }
231
+
232
+ export declare interface UseVizelMarkdownResult {
233
+ /**
234
+ * Current markdown content (reactive).
235
+ * Updates with debounce when editor content changes.
236
+ */
237
+ markdown: string;
238
+ /**
239
+ * Set markdown content to the editor.
240
+ * Automatically transforms diagram code blocks if transformDiagrams is enabled.
241
+ */
242
+ setMarkdown: (markdown: string) => void;
243
+ /**
244
+ * Whether markdown export is currently pending (debounced).
245
+ */
246
+ isPending: boolean;
247
+ /**
248
+ * Force immediate export (flush pending debounced export).
249
+ */
250
+ flush: () => void;
251
+ }
252
+
253
+ /**
254
+ * Hook that forces a re-render whenever the editor's state changes.
255
+ * This is useful for components that need to reflect the current editor state
256
+ * (e.g., formatting buttons that show active state).
257
+ *
258
+ * @param getEditor - A function that returns the editor instance
259
+ * @returns A number that changes on each editor state update (can be ignored)
260
+ *
261
+ * @example
262
+ * ```tsx
263
+ * function FormattingButtons({ editor }: { editor: Editor }) {
264
+ * useVizelState(() => editor);
265
+ * // Now editor.isActive() will be re-evaluated on each state change
266
+ * return (
267
+ * <button className={editor.isActive("bold") ? "active" : ""}>
268
+ * Bold
269
+ * </button>
270
+ * );
271
+ * }
272
+ * ```
273
+ */
274
+ export declare function useVizelState(getEditor: () => Editor | null | undefined): number;
275
+
276
+ /**
277
+ * Hook to access theme state and controls
278
+ *
279
+ * Must be used within a VizelThemeProvider
280
+ *
281
+ * @example
282
+ * ```tsx
283
+ * const { theme, setTheme, resolvedTheme } = useVizelTheme();
284
+ *
285
+ * return (
286
+ * <button onClick={() => setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')}>
287
+ * Toggle theme
288
+ * </button>
289
+ * );
290
+ * ```
291
+ */
292
+ export declare function useVizelTheme(): VizelThemeState;
293
+
294
+ /**
295
+ * Hook to access theme state safely (returns null if not in provider)
296
+ */
297
+ export declare function useVizelThemeSafe(): VizelThemeState | null;
298
+
299
+ /**
300
+ * Vizel - All-in-one editor component
301
+ *
302
+ * A complete editor component that includes VizelEditor and VizelBubbleMenu.
303
+ * This is the recommended way to use Vizel for most use cases.
304
+ *
305
+ * @example
306
+ * ```tsx
307
+ * import { Vizel } from '@vizel/react';
308
+ *
309
+ * function App() {
310
+ * return <Vizel placeholder="Type '/' for commands..." />;
311
+ * }
312
+ * ```
313
+ *
314
+ * @example
315
+ * ```tsx
316
+ * import { Vizel, type VizelRef } from '@vizel/react';
317
+ * import { useRef } from 'react';
318
+ *
319
+ * function App() {
320
+ * const vizelRef = useRef<VizelRef>(null);
321
+ *
322
+ * const handleSave = () => {
323
+ * const content = vizelRef.current?.editor?.getJSON();
324
+ * console.log(content);
325
+ * };
326
+ *
327
+ * return (
328
+ * <>
329
+ * <Vizel ref={vizelRef} onUpdate={({ editor }) => console.log(editor.getJSON())} />
330
+ * <button onClick={handleSave}>Save</button>
331
+ * </>
332
+ * );
333
+ * }
334
+ * ```
335
+ */
336
+ export declare function Vizel({ ref, initialContent, initialMarkdown, transformDiagramsOnImport, placeholder, editable, autofocus, features, className, showBubbleMenu, enableEmbed, bubbleMenuContent, children, onUpdate, onCreate, onDestroy, onSelectionUpdate, onFocus, onBlur, }: VizelProps): ReactNode;
337
+
338
+ /**
339
+ * A floating menu that appears when text is selected.
340
+ * Provides formatting options like bold, italic, strike, code, and link.
341
+ *
342
+ * @example
343
+ * ```tsx
344
+ * // Basic usage with default menu
345
+ * <VizelProvider editor={editor}>
346
+ * <VizelEditor />
347
+ * <VizelBubbleMenu />
348
+ * </VizelProvider>
349
+ *
350
+ * // With custom items using sub-components
351
+ * <VizelBubbleMenu>
352
+ * <VizelBubbleMenuButton
353
+ * onClick={() => editor.chain().toggleBold().run()}
354
+ * isActive={editor.isActive("bold")}
355
+ * >
356
+ * Bold
357
+ * </VizelBubbleMenuButton>
358
+ * <VizelBubbleMenuDivider />
359
+ * <VizelBubbleMenuButton onClick={() => setShowLinkEditor(true)}>
360
+ * Link
361
+ * </VizelBubbleMenuButton>
362
+ * </VizelBubbleMenu>
363
+ * ```
364
+ */
365
+ export declare function VizelBubbleMenu({ editor: editorProp, className, children, showDefaultMenu, pluginKey, updateDelay, shouldShow, enableEmbed, }: VizelBubbleMenuProps): JSX.Element | null;
366
+
367
+ /**
368
+ * A button component for use in the VizelBubbleMenu.
369
+ *
370
+ * @example
371
+ * ```tsx
372
+ * <VizelBubbleMenuButton
373
+ * onClick={() => editor.chain().focus().toggleBold().run()}
374
+ * isActive={editor.isActive("bold")}
375
+ * title="Bold (Cmd+B)"
376
+ * >
377
+ * <strong>B</strong>
378
+ * </VizelBubbleMenuButton>
379
+ * ```
380
+ */
381
+ export declare function VizelBubbleMenuButton({ onClick, isActive, disabled, children, title, className, action, }: VizelBubbleMenuButtonProps): JSX.Element;
382
+
383
+ export declare interface VizelBubbleMenuButtonProps {
384
+ /** Click handler. Optional when disabled is true. */
385
+ onClick?: () => void;
386
+ isActive?: boolean;
387
+ disabled?: boolean;
388
+ children: ReactNode;
389
+ title?: string;
390
+ className?: string;
391
+ /** Action identifier for testing */
392
+ action?: string;
393
+ }
394
+
395
+ /**
396
+ * A color picker component for the VizelBubbleMenu.
397
+ * Supports text color and highlight color selection with custom colors and recent colors.
398
+ */
399
+ export declare function VizelBubbleMenuColorPicker({ editor, type, colors, className, allowCustomColor, showRecentColors, }: VizelBubbleMenuColorPickerProps): JSX.Element;
400
+
401
+ export declare interface VizelBubbleMenuColorPickerProps {
402
+ editor: Editor;
403
+ /** Color picker type */
404
+ type: "textColor" | "highlight";
405
+ /** Custom color palette */
406
+ colors?: VizelColorDefinition[];
407
+ /** Custom class name */
408
+ className?: string;
409
+ /** Enable custom color input (default: true) */
410
+ allowCustomColor?: boolean;
411
+ /** Enable recent colors (default: true) */
412
+ showRecentColors?: boolean;
413
+ }
414
+
415
+ /**
416
+ * The default menu content for VizelBubbleMenu.
417
+ * Provides formatting buttons for bold, italic, strikethrough, code, and link.
418
+ *
419
+ * @example
420
+ * ```tsx
421
+ * <VizelBubbleMenu>
422
+ * <VizelBubbleMenuDefault editor={editor} />
423
+ * </VizelBubbleMenu>
424
+ * ```
425
+ */
426
+ export declare function VizelBubbleMenuDefault({ editor, className, enableEmbed, }: VizelBubbleMenuDefaultProps): JSX.Element;
427
+
428
+ export declare interface VizelBubbleMenuDefaultProps {
429
+ editor: Editor;
430
+ className?: string;
431
+ /** Enable embed option in link editor (requires Embed extension) */
432
+ enableEmbed?: boolean;
433
+ }
434
+
435
+ /**
436
+ * A divider component for separating groups of buttons in the VizelBubbleMenu.
437
+ *
438
+ * @example
439
+ * ```tsx
440
+ * <VizelBubbleMenu>
441
+ * <VizelBubbleMenuButton>B</VizelBubbleMenuButton>
442
+ * <VizelBubbleMenuButton>I</VizelBubbleMenuButton>
443
+ * <VizelBubbleMenuDivider />
444
+ * <VizelBubbleMenuButton>Link</VizelBubbleMenuButton>
445
+ * </VizelBubbleMenu>
446
+ * ```
447
+ */
448
+ export declare function VizelBubbleMenuDivider({ className }: VizelBubbleMenuDividerProps): JSX.Element;
449
+
450
+ export declare interface VizelBubbleMenuDividerProps {
451
+ className?: string;
452
+ }
453
+
454
+ export declare interface VizelBubbleMenuProps {
455
+ /** Override the editor from context */
456
+ editor?: Editor | null;
457
+ /** Custom class name for the menu container */
458
+ className?: string;
459
+ /** Custom menu items (overrides default menu) */
460
+ children?: ReactNode;
461
+ /** Whether to show the default formatting menu */
462
+ showDefaultMenu?: boolean;
463
+ /** Plugin key for the bubble menu */
464
+ pluginKey?: string;
465
+ /** Delay in ms before updating the menu position */
466
+ updateDelay?: number;
467
+ /** Custom shouldShow function */
468
+ shouldShow?: (props: {
469
+ editor: Editor;
470
+ from: number;
471
+ to: number;
472
+ }) => boolean;
473
+ /** Enable embed option in link editor (requires Embed extension) */
474
+ enableEmbed?: boolean;
475
+ }
476
+
477
+ /**
478
+ * A reusable color picker component with keyboard navigation and accessibility support.
479
+ */
480
+ export declare function VizelColorPicker({ colors, value, onChange, label, className, allowCustomColor, recentColors, showRecentColors, noneValues, }: VizelColorPickerProps): JSX.Element;
481
+
482
+ export declare interface VizelColorPickerProps {
483
+ /** Color palette to display */
484
+ colors: VizelColorDefinition[];
485
+ /** Currently selected color */
486
+ value?: string | undefined;
487
+ /** Callback when color is selected */
488
+ onChange: (color: string) => void;
489
+ /** Label for accessibility */
490
+ label?: string;
491
+ /** Custom class name */
492
+ className?: string;
493
+ /** Enable custom HEX input (default: true) */
494
+ allowCustomColor?: boolean;
495
+ /** Recent colors to display */
496
+ recentColors?: string[];
497
+ /** Show recent colors section (default: true) */
498
+ showRecentColors?: boolean;
499
+ /** "None" option color values (e.g., ["transparent", "inherit"]) */
500
+ noneValues?: string[];
501
+ }
502
+
503
+ declare interface VizelContextValue {
504
+ editor: Editor | null;
505
+ }
506
+
507
+ /**
508
+ * Renders the editable content area of the Vizel editor.
509
+ *
510
+ * Can be used within an VizelProvider (no editor prop needed), or standalone with editor prop.
511
+ *
512
+ * @example
513
+ * ```tsx
514
+ * // With VizelProvider
515
+ * <VizelProvider editor={editor}>
516
+ * <VizelEditor className="prose" />
517
+ * </VizelProvider>
518
+ *
519
+ * // Or directly with editor prop
520
+ * <VizelEditor editor={editor} className="prose" />
521
+ *
522
+ * // With ref to access container DOM
523
+ * const editorRef = useRef<VizelExposed>(null);
524
+ * <VizelEditor ref={editorRef} editor={editor} />
525
+ * // editorRef.current?.container gives you the container element
526
+ * ```
527
+ */
528
+ export declare function VizelEditor({ ref, editor: editorProp, className }: VizelEditorProps): ReactNode;
529
+
530
+ export declare interface VizelEditorProps {
531
+ /** Ref to access editor container */
532
+ ref?: Ref<VizelExposed>;
533
+ /** Override the editor from context */
534
+ editor?: Editor | null;
535
+ /** Optional className for the editor container */
536
+ className?: string;
537
+ }
538
+
539
+ /**
540
+ * Renders an embed based on its type.
541
+ * Supports oEmbed (rich), OGP (card), title (link with text), and plain link.
542
+ */
543
+ export declare function VizelEmbedView({ data, className, selected }: VizelEmbedViewProps): default_2.JSX.Element;
544
+
545
+ export declare interface VizelEmbedViewProps {
546
+ /** Embed data */
547
+ data: VizelEmbedData;
548
+ /** Additional class name */
549
+ className?: string;
550
+ /** Whether the embed is selected */
551
+ selected?: boolean;
552
+ }
553
+
554
+ export declare interface VizelExposed {
555
+ /** The container DOM element */
556
+ container: HTMLDivElement | null;
557
+ }
558
+
559
+ /**
560
+ * Icon component that renders Iconify icons based on semantic icon names.
561
+ * Uses Lucide icons by default, but can be customized via:
562
+ * 1. customIcons prop (highest priority)
563
+ * 2. VizelIconProvider context
564
+ * 3. Default Lucide icons (fallback)
565
+ *
566
+ * @example
567
+ * ```tsx
568
+ * // Using default Lucide icons
569
+ * <VizelIcon name="heading1" />
570
+ *
571
+ * // With custom icon override (prop takes precedence)
572
+ * <VizelIcon name="heading1" customIcons={{ heading1: "mdi:format-header-1" }} />
573
+ *
574
+ * // With VizelIconProvider context
575
+ * <VizelIconProvider icons={{ heading1: "ph:text-h-one" }}>
576
+ * <VizelIcon name="heading1" /> {/* Uses Phosphor icon *\/}
577
+ * </VizelIconProvider>
578
+ *
579
+ * // With size and color
580
+ * <VizelIcon name="check" width={24} height={24} color="green" />
581
+ * ```
582
+ */
583
+ export declare function VizelIcon({ name, customIcons, style, ...props }: VizelIconProps): JSX.Element;
584
+
585
+ export declare interface VizelIconProps extends Omit<ComponentProps<typeof Icon>, "icon"> {
586
+ /**
587
+ * The semantic icon name from Vizel's icon system.
588
+ */
589
+ name: VizelIconName;
590
+ /**
591
+ * Custom icon mappings to override default Iconify icon IDs.
592
+ * If provided, will take precedence over context icons.
593
+ */
594
+ customIcons?: CustomIconMap;
595
+ }
596
+
597
+ /**
598
+ * Provider component for customizing icons throughout the application.
599
+ * Wrap your application or editor with this provider to use custom icon sets.
600
+ *
601
+ * @example
602
+ * ```tsx
603
+ * import { VizelIconProvider } from "@vizel/react";
604
+ *
605
+ * // Use Phosphor icons
606
+ * const phosphorIcons = {
607
+ * heading1: "ph:text-h-one",
608
+ * heading2: "ph:text-h-two",
609
+ * bold: "ph:text-b-bold",
610
+ * italic: "ph:text-italic",
611
+ * // ... more icons
612
+ * };
613
+ *
614
+ * function App() {
615
+ * return (
616
+ * <VizelIconProvider icons={phosphorIcons}>
617
+ * <VizelEditor />
618
+ * </VizelIconProvider>
619
+ * );
620
+ * }
621
+ * ```
622
+ */
623
+ export declare function VizelIconProvider({ icons, children }: VizelIconProviderProps): JSX.Element;
624
+
625
+ export declare interface VizelIconProviderProps {
626
+ /**
627
+ * Custom icon mappings to override default Lucide icons.
628
+ * Any icon not specified will fall back to the default Lucide icon.
629
+ *
630
+ * @example
631
+ * ```tsx
632
+ * // Use Material Design Icons for some icons
633
+ * <VizelIconProvider icons={{ bold: "mdi:format-bold", italic: "mdi:format-italic" }}>
634
+ * <App />
635
+ * </VizelIconProvider>
636
+ *
637
+ * // Use Heroicons
638
+ * <VizelIconProvider icons={{ check: "heroicons:check", warning: "heroicons:exclamation-triangle" }}>
639
+ * <App />
640
+ * </VizelIconProvider>
641
+ * ```
642
+ */
643
+ icons?: CustomIconMap;
644
+ children: ReactNode;
645
+ }
646
+
647
+ /**
648
+ * A link editor component for editing hyperlinks in the VizelBubbleMenu.
649
+ * Provides an input field for URL entry and buttons to apply or remove the link.
650
+ * Optionally supports converting links to embeds when the Embed extension is loaded.
651
+ *
652
+ * @example
653
+ * ```tsx
654
+ * const [showLinkEditor, setShowLinkEditor] = useState(false);
655
+ *
656
+ * {showLinkEditor ? (
657
+ * <VizelLinkEditor
658
+ * editor={editor}
659
+ * onClose={() => setShowLinkEditor(false)}
660
+ * enableEmbed
661
+ * />
662
+ * ) : (
663
+ * <VizelBubbleMenuButton onClick={() => setShowLinkEditor(true)}>
664
+ * Link
665
+ * </VizelBubbleMenuButton>
666
+ * )}
667
+ * ```
668
+ */
669
+ export declare function VizelLinkEditor({ editor, onClose, className, enableEmbed, }: VizelLinkEditorProps): JSX.Element;
670
+
671
+ export declare interface VizelLinkEditorProps {
672
+ editor: Editor;
673
+ onClose: () => void;
674
+ className?: string;
675
+ /** Enable embed option (requires Embed extension) */
676
+ enableEmbed?: boolean;
677
+ }
678
+
679
+ /**
680
+ * A dropdown selector for changing block node types.
681
+ * Displays the current node type and allows transformation to other types.
682
+ *
683
+ * @example
684
+ * ```tsx
685
+ * <VizelNodeSelector editor={editor} />
686
+ * ```
687
+ */
688
+ export declare function VizelNodeSelector({ editor, nodeTypes, className, }: VizelNodeSelectorProps): JSX.Element;
689
+
690
+ export declare interface VizelNodeSelectorProps {
691
+ /** The editor instance */
692
+ editor: Editor;
693
+ /** Custom node types (defaults to vizelDefaultNodeTypes) */
694
+ nodeTypes?: VizelNodeTypeOption[];
695
+ /** Custom class name */
696
+ className?: string;
697
+ }
698
+
699
+ /**
700
+ * Portal component for rendering content outside the DOM hierarchy.
701
+ *
702
+ * Renders children into a portal container at the document body level,
703
+ * ensuring proper z-index stacking for floating UI elements.
704
+ *
705
+ * @example
706
+ * ```tsx
707
+ * <VizelPortal layer="dropdown">
708
+ * <DropdownMenu />
709
+ * </VizelPortal>
710
+ * ```
711
+ *
712
+ * @example Disabled portal (renders in place)
713
+ * ```tsx
714
+ * <VizelPortal disabled>
715
+ * <Content />
716
+ * </VizelPortal>
717
+ * ```
718
+ */
719
+ export declare function VizelPortal({ children, layer, className, disabled, }: VizelPortalProps): ReactNode;
720
+
721
+ export declare namespace VizelPortal {
722
+ var displayName: string;
723
+ }
724
+
725
+ /**
726
+ * Props for the VizelPortal component.
727
+ */
728
+ export declare interface VizelPortalProps {
729
+ /** Content to render in the portal */
730
+ children: ReactNode;
731
+ /** Z-index layer for the portal content */
732
+ layer?: VizelPortalLayer;
733
+ /** Additional CSS class name */
734
+ className?: string;
735
+ /** Whether the portal is disabled (renders children in place) */
736
+ disabled?: boolean;
737
+ }
738
+
739
+ export declare interface VizelProps {
740
+ /** Ref to access editor instance */
741
+ ref?: Ref<VizelRef>;
742
+ /** Initial content in JSON format */
743
+ initialContent?: JSONContent;
744
+ /**
745
+ * Initial content in Markdown format.
746
+ * If both initialContent and initialMarkdown are provided, initialMarkdown takes precedence.
747
+ * @example
748
+ * ```tsx
749
+ * <Vizel initialMarkdown="# Hello World\n\nThis is **bold** text." />
750
+ * ```
751
+ */
752
+ initialMarkdown?: string;
753
+ /**
754
+ * Automatically transform diagram code blocks (mermaid, graphviz) to diagram nodes
755
+ * when importing markdown content. Only applies when initialMarkdown is provided.
756
+ * @default true
757
+ */
758
+ transformDiagramsOnImport?: boolean;
759
+ /** Placeholder text when editor is empty */
760
+ placeholder?: string;
761
+ /** Whether the editor is editable (default: true) */
762
+ editable?: boolean;
763
+ /** Auto focus on mount */
764
+ autofocus?: boolean | "start" | "end" | "all" | number;
765
+ /** Feature configuration */
766
+ features?: VizelFeatureOptions;
767
+ /** Custom class name for the editor container */
768
+ className?: string;
769
+ /** Whether to show the bubble menu (default: true) */
770
+ showBubbleMenu?: boolean;
771
+ /** Enable embed option in bubble menu link editor (requires Embed extension) */
772
+ enableEmbed?: boolean;
773
+ /** Custom bubble menu content */
774
+ bubbleMenuContent?: ReactNode;
775
+ /** Additional children to render inside the editor root */
776
+ children?: ReactNode;
777
+ /** Callback when content changes */
778
+ onUpdate?: (props: {
779
+ editor: Editor;
780
+ }) => void;
781
+ /** Callback when editor is created */
782
+ onCreate?: (props: {
783
+ editor: Editor;
784
+ }) => void;
785
+ /** Callback when editor is destroyed */
786
+ onDestroy?: () => void;
787
+ /** Callback when selection changes */
788
+ onSelectionUpdate?: (props: {
789
+ editor: Editor;
790
+ }) => void;
791
+ /** Callback when editor gets focus */
792
+ onFocus?: (props: {
793
+ editor: Editor;
794
+ }) => void;
795
+ /** Callback when editor loses focus */
796
+ onBlur?: (props: {
797
+ editor: Editor;
798
+ }) => void;
799
+ }
800
+
801
+ /**
802
+ * Provider component for the Vizel editor.
803
+ * Provides editor context to all child components.
804
+ *
805
+ * @example
806
+ * ```tsx
807
+ * const editor = useVizelEditor();
808
+ *
809
+ * return (
810
+ * <VizelProvider editor={editor}>
811
+ * <VizelEditor />
812
+ * <VizelBubbleMenu />
813
+ * </VizelProvider>
814
+ * );
815
+ * ```
816
+ */
817
+ export declare function VizelProvider({ editor, children, className }: VizelProviderProps): JSX.Element;
818
+
819
+ export declare interface VizelProviderProps {
820
+ /** The editor instance from useVizelEditor */
821
+ editor: Editor | null;
822
+ /** Child components (VizelEditor, VizelBubbleMenu, etc.) */
823
+ children: ReactNode;
824
+ /** Optional className for the root container */
825
+ className?: string;
826
+ }
827
+
828
+ export declare interface VizelRef {
829
+ /** The underlying Tiptap editor instance */
830
+ editor: Editor | null;
831
+ }
832
+
833
+ /**
834
+ * Visual indicator for the current save state of the editor.
835
+ *
836
+ * @example
837
+ * ```tsx
838
+ * <VizelSaveIndicator
839
+ * status={status}
840
+ * lastSaved={lastSaved}
841
+ * showTimestamp
842
+ * />
843
+ * ```
844
+ */
845
+ export declare function VizelSaveIndicator({ status, lastSaved, showTimestamp, className, }: VizelSaveIndicatorProps): JSX.Element;
846
+
847
+ export declare interface VizelSaveIndicatorProps {
848
+ /** Current save status */
849
+ status: VizelSaveStatus;
850
+ /** Timestamp of last successful save */
851
+ lastSaved?: Date | null;
852
+ /** Show relative timestamp (default: true) */
853
+ showTimestamp?: boolean;
854
+ /** Custom class name */
855
+ className?: string;
856
+ }
857
+
858
+ /**
859
+ * Slash command menu component for displaying command suggestions.
860
+ * Supports grouping, keyboard navigation, and fuzzy search highlighting.
861
+ *
862
+ * @example
863
+ * ```tsx
864
+ * // Basic usage via createVizelSlashMenuRenderer
865
+ * import { SlashCommand, createVizelSlashMenuRenderer } from '@vizel/react';
866
+ *
867
+ * const editor = useEditor({
868
+ * extensions: [
869
+ * SlashCommand.configure({
870
+ * suggestion: createVizelSlashMenuRenderer(),
871
+ * }),
872
+ * ],
873
+ * });
874
+ * ```
875
+ */
876
+ export declare function VizelSlashMenu({ ref, items, command, className, showGroups, renderItem, renderEmpty, groupOrder, }: VizelSlashMenuProps): ReactNode;
877
+
878
+ /**
879
+ * An empty state component for the VizelSlashMenu when no results are found.
880
+ *
881
+ * @example
882
+ * ```tsx
883
+ * {items.length === 0 && (
884
+ * <VizelSlashMenuEmpty>No commands found</VizelSlashMenuEmpty>
885
+ * )}
886
+ * ```
887
+ */
888
+ export declare function VizelSlashMenuEmpty({ children, className }: VizelSlashMenuEmptyProps): JSX.Element;
889
+
890
+ export declare interface VizelSlashMenuEmptyProps {
891
+ children?: ReactNode;
892
+ className?: string;
893
+ }
894
+
895
+ /**
896
+ * A menu item component for the VizelSlashMenu.
897
+ * Displays the command icon, title, description, and optional keyboard shortcut.
898
+ *
899
+ * @example
900
+ * ```tsx
901
+ * <VizelSlashMenuItem
902
+ * item={{ title: "Heading 1", icon: "H1", description: "Large heading", shortcut: "⌘⌥1" }}
903
+ * isSelected={selectedIndex === 0}
904
+ * onClick={() => command(item)}
905
+ * />
906
+ * ```
907
+ */
908
+ export declare function VizelSlashMenuItem({ item, isSelected, onClick, className, titleMatches, }: VizelSlashMenuItemProps): JSX.Element;
909
+
910
+ export declare interface VizelSlashMenuItemProps {
911
+ item: VizelSlashCommandItem;
912
+ isSelected?: boolean;
913
+ onClick: () => void;
914
+ className?: string;
915
+ /** Match indices for highlighting (from fuzzy search) */
916
+ titleMatches?: [number, number][];
917
+ }
918
+
919
+ export declare interface VizelSlashMenuProps {
920
+ /** Ref to access menu methods */
921
+ ref?: Ref<VizelSlashMenuRef>;
922
+ items: VizelSlashCommandItem[];
923
+ command: (item: VizelSlashCommandItem) => void;
924
+ /** Custom class name for the menu container */
925
+ className?: string;
926
+ /** Whether to show items grouped by category (default: true when not searching) */
927
+ showGroups?: boolean;
928
+ /** Custom render function for items */
929
+ renderItem?: (props: {
930
+ item: VizelSlashCommandItem;
931
+ isSelected: boolean;
932
+ onClick: () => void;
933
+ }) => ReactNode;
934
+ /** Custom empty state component */
935
+ renderEmpty?: () => ReactNode;
936
+ /** Custom group order */
937
+ groupOrder?: string[];
938
+ }
939
+
940
+ export declare interface VizelSlashMenuRef {
941
+ onKeyDown: (props: {
942
+ event: KeyboardEvent;
943
+ }) => boolean;
944
+ }
945
+
946
+ export { VizelSlashMenuRendererOptions }
947
+
948
+ /**
949
+ * Theme provider component for managing dark mode
950
+ *
951
+ * @example
952
+ * ```tsx
953
+ * <VizelThemeProvider defaultTheme="system">
954
+ * <App />
955
+ * </VizelThemeProvider>
956
+ * ```
957
+ */
958
+ export declare function VizelThemeProvider({ children, defaultTheme, storageKey, targetSelector, disableTransitionOnChange, }: VizelThemeProviderProps): JSX.Element;
959
+
960
+ export declare interface VizelThemeProviderProps extends VizelThemeProviderOptions {
961
+ /** Children to render */
962
+ children: ReactNode;
963
+ }
964
+
965
+ export { }