@vizel/svelte 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.
Files changed (101) hide show
  1. package/README.md +83 -0
  2. package/dist/components/Vizel.svelte +158 -0
  3. package/dist/components/Vizel.svelte.d.ts +82 -0
  4. package/dist/components/Vizel.svelte.d.ts.map +1 -0
  5. package/dist/components/VizelBubbleMenu.svelte +96 -0
  6. package/dist/components/VizelBubbleMenu.svelte.d.ts +28 -0
  7. package/dist/components/VizelBubbleMenu.svelte.d.ts.map +1 -0
  8. package/dist/components/VizelBubbleMenuButton.svelte +45 -0
  9. package/dist/components/VizelBubbleMenuButton.svelte.d.ts +21 -0
  10. package/dist/components/VizelBubbleMenuButton.svelte.d.ts.map +1 -0
  11. package/dist/components/VizelBubbleMenuColorPicker.svelte +135 -0
  12. package/dist/components/VizelBubbleMenuColorPicker.svelte.d.ts +19 -0
  13. package/dist/components/VizelBubbleMenuColorPicker.svelte.d.ts.map +1 -0
  14. package/dist/components/VizelBubbleMenuDefault.svelte +111 -0
  15. package/dist/components/VizelBubbleMenuDefault.svelte.d.ts +13 -0
  16. package/dist/components/VizelBubbleMenuDefault.svelte.d.ts.map +1 -0
  17. package/dist/components/VizelBubbleMenuDivider.svelte +12 -0
  18. package/dist/components/VizelBubbleMenuDivider.svelte.d.ts +8 -0
  19. package/dist/components/VizelBubbleMenuDivider.svelte.d.ts.map +1 -0
  20. package/dist/components/VizelColorPicker.svelte +269 -0
  21. package/dist/components/VizelColorPicker.svelte.d.ts +25 -0
  22. package/dist/components/VizelColorPicker.svelte.d.ts.map +1 -0
  23. package/dist/components/VizelContext.d.ts +27 -0
  24. package/dist/components/VizelContext.d.ts.map +1 -0
  25. package/dist/components/VizelContext.js +34 -0
  26. package/dist/components/VizelEditor.svelte +61 -0
  27. package/dist/components/VizelEditor.svelte.d.ts +17 -0
  28. package/dist/components/VizelEditor.svelte.d.ts.map +1 -0
  29. package/dist/components/VizelEmbedView.svelte +162 -0
  30. package/dist/components/VizelEmbedView.svelte.d.ts +13 -0
  31. package/dist/components/VizelEmbedView.svelte.d.ts.map +1 -0
  32. package/dist/components/VizelIcon.svelte +54 -0
  33. package/dist/components/VizelIcon.svelte.d.ts +32 -0
  34. package/dist/components/VizelIcon.svelte.d.ts.map +1 -0
  35. package/dist/components/VizelIconContext.d.ts +27 -0
  36. package/dist/components/VizelIconContext.d.ts.map +1 -0
  37. package/dist/components/VizelIconContext.js +31 -0
  38. package/dist/components/VizelIconProvider.svelte +43 -0
  39. package/dist/components/VizelIconProvider.svelte.d.ts +31 -0
  40. package/dist/components/VizelIconProvider.svelte.d.ts.map +1 -0
  41. package/dist/components/VizelLinkEditor.svelte +143 -0
  42. package/dist/components/VizelLinkEditor.svelte.d.ts +15 -0
  43. package/dist/components/VizelLinkEditor.svelte.d.ts.map +1 -0
  44. package/dist/components/VizelNodeSelector.svelte +172 -0
  45. package/dist/components/VizelNodeSelector.svelte.d.ts +13 -0
  46. package/dist/components/VizelNodeSelector.svelte.d.ts.map +1 -0
  47. package/dist/components/VizelPortal.svelte +70 -0
  48. package/dist/components/VizelPortal.svelte.d.ts +19 -0
  49. package/dist/components/VizelPortal.svelte.d.ts.map +1 -0
  50. package/dist/components/VizelProvider.svelte +26 -0
  51. package/dist/components/VizelProvider.svelte.d.ts +14 -0
  52. package/dist/components/VizelProvider.svelte.d.ts.map +1 -0
  53. package/dist/components/VizelSaveIndicator.svelte +94 -0
  54. package/dist/components/VizelSaveIndicator.svelte.d.ts +15 -0
  55. package/dist/components/VizelSaveIndicator.svelte.d.ts.map +1 -0
  56. package/dist/components/VizelSlashMenu.svelte +211 -0
  57. package/dist/components/VizelSlashMenu.svelte.d.ts +31 -0
  58. package/dist/components/VizelSlashMenu.svelte.d.ts.map +1 -0
  59. package/dist/components/VizelSlashMenuEmpty.svelte +22 -0
  60. package/dist/components/VizelSlashMenuEmpty.svelte.d.ts +11 -0
  61. package/dist/components/VizelSlashMenuEmpty.svelte.d.ts.map +1 -0
  62. package/dist/components/VizelSlashMenuItem.svelte +57 -0
  63. package/dist/components/VizelSlashMenuItem.svelte.d.ts +17 -0
  64. package/dist/components/VizelSlashMenuItem.svelte.d.ts.map +1 -0
  65. package/dist/components/VizelThemeProvider.svelte +79 -0
  66. package/dist/components/VizelThemeProvider.svelte.d.ts +11 -0
  67. package/dist/components/VizelThemeProvider.svelte.d.ts.map +1 -0
  68. package/dist/components/index.d.ts +23 -0
  69. package/dist/components/index.d.ts.map +1 -0
  70. package/dist/components/index.js +64 -0
  71. package/dist/iconRenderer.d.ts +6 -0
  72. package/dist/iconRenderer.d.ts.map +1 -0
  73. package/dist/iconRenderer.js +7 -0
  74. package/dist/index.d.ts +9 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +31 -0
  77. package/dist/runes/createVizelAutoSave.svelte.d.ts +44 -0
  78. package/dist/runes/createVizelAutoSave.svelte.d.ts.map +1 -0
  79. package/dist/runes/createVizelAutoSave.svelte.js +91 -0
  80. package/dist/runes/createVizelEditor.svelte.d.ts +43 -0
  81. package/dist/runes/createVizelEditor.svelte.d.ts.map +1 -0
  82. package/dist/runes/createVizelEditor.svelte.js +65 -0
  83. package/dist/runes/createVizelEditorState.svelte.d.ts +27 -0
  84. package/dist/runes/createVizelEditorState.svelte.d.ts.map +1 -0
  85. package/dist/runes/createVizelEditorState.svelte.js +35 -0
  86. package/dist/runes/createVizelMarkdown.svelte.d.ts +68 -0
  87. package/dist/runes/createVizelMarkdown.svelte.d.ts.map +1 -0
  88. package/dist/runes/createVizelMarkdown.svelte.js +123 -0
  89. package/dist/runes/createVizelSlashMenuRenderer.d.ts +22 -0
  90. package/dist/runes/createVizelSlashMenuRenderer.d.ts.map +1 -0
  91. package/dist/runes/createVizelSlashMenuRenderer.js +84 -0
  92. package/dist/runes/createVizelState.svelte.d.ts +22 -0
  93. package/dist/runes/createVizelState.svelte.d.ts.map +1 -0
  94. package/dist/runes/createVizelState.svelte.js +50 -0
  95. package/dist/runes/getVizelTheme.svelte.d.ts +23 -0
  96. package/dist/runes/getVizelTheme.svelte.d.ts.map +1 -0
  97. package/dist/runes/getVizelTheme.svelte.js +31 -0
  98. package/dist/runes/index.d.ts +8 -0
  99. package/dist/runes/index.d.ts.map +1 -0
  100. package/dist/runes/index.js +7 -0
  101. package/package.json +64 -0
@@ -0,0 +1,111 @@
1
+ <script lang="ts" module>
2
+ import type { Editor } from "@vizel/core";
3
+
4
+ export interface VizelBubbleMenuDefaultProps {
5
+ /** The editor instance */
6
+ editor: Editor;
7
+ /** Custom class name */
8
+ class?: string;
9
+ /** Enable embed option in link editor (requires Embed extension) */
10
+ enableEmbed?: boolean;
11
+ }
12
+ </script>
13
+
14
+ <script lang="ts">
15
+ import { createVizelState } from "../runes/createVizelState.svelte.ts";
16
+ import VizelBubbleMenuButton from "./VizelBubbleMenuButton.svelte";
17
+ import VizelBubbleMenuColorPicker from "./VizelBubbleMenuColorPicker.svelte";
18
+ import VizelLinkEditor from "./VizelLinkEditor.svelte";
19
+ import VizelIcon from "./VizelIcon.svelte";
20
+ import VizelNodeSelector from "./VizelNodeSelector.svelte";
21
+
22
+ let { editor, class: className, enableEmbed }: VizelBubbleMenuDefaultProps = $props();
23
+ let showLinkEditor = $state(false);
24
+
25
+ // Subscribe to editor state changes to update active states
26
+ const editorState = createVizelState(() => editor);
27
+
28
+ // Create derived values that depend on editorState.current to trigger re-renders
29
+ const isBoldActive = $derived.by(() => {
30
+ void editorState.current; // Trigger reactivity
31
+ return editor.isActive("bold");
32
+ });
33
+ const isItalicActive = $derived.by(() => {
34
+ void editorState.current;
35
+ return editor.isActive("italic");
36
+ });
37
+ const isStrikeActive = $derived.by(() => {
38
+ void editorState.current;
39
+ return editor.isActive("strike");
40
+ });
41
+ const isUnderlineActive = $derived.by(() => {
42
+ void editorState.current;
43
+ return editor.isActive("underline");
44
+ });
45
+ const isCodeActive = $derived.by(() => {
46
+ void editorState.current;
47
+ return editor.isActive("code");
48
+ });
49
+ const isLinkActive = $derived.by(() => {
50
+ void editorState.current;
51
+ return editor.isActive("link");
52
+ });
53
+ </script>
54
+
55
+ {#if showLinkEditor}
56
+ <VizelLinkEditor {editor} {...(enableEmbed ? { enableEmbed } : {})} onclose={() => (showLinkEditor = false)} />
57
+ {:else}
58
+ <div class="vizel-bubble-menu-toolbar {className ?? ''}">
59
+ <VizelNodeSelector {editor} />
60
+ <VizelBubbleMenuButton
61
+ action="bold"
62
+ isActive={isBoldActive}
63
+ title="Bold (Cmd+B)"
64
+ onclick={() => editor.chain().focus().toggleBold().run()}
65
+ >
66
+ <VizelIcon name="bold" />
67
+ </VizelBubbleMenuButton>
68
+ <VizelBubbleMenuButton
69
+ action="italic"
70
+ isActive={isItalicActive}
71
+ title="Italic (Cmd+I)"
72
+ onclick={() => editor.chain().focus().toggleItalic().run()}
73
+ >
74
+ <VizelIcon name="italic" />
75
+ </VizelBubbleMenuButton>
76
+ <VizelBubbleMenuButton
77
+ action="strike"
78
+ isActive={isStrikeActive}
79
+ title="Strikethrough"
80
+ onclick={() => editor.chain().focus().toggleStrike().run()}
81
+ >
82
+ <VizelIcon name="strikethrough" />
83
+ </VizelBubbleMenuButton>
84
+ <VizelBubbleMenuButton
85
+ action="underline"
86
+ isActive={isUnderlineActive}
87
+ title="Underline (Cmd+U)"
88
+ onclick={() => editor.chain().focus().toggleUnderline().run()}
89
+ >
90
+ <VizelIcon name="underline" />
91
+ </VizelBubbleMenuButton>
92
+ <VizelBubbleMenuButton
93
+ action="code"
94
+ isActive={isCodeActive}
95
+ title="Code (Cmd+E)"
96
+ onclick={() => editor.chain().focus().toggleCode().run()}
97
+ >
98
+ <VizelIcon name="code" />
99
+ </VizelBubbleMenuButton>
100
+ <VizelBubbleMenuButton
101
+ action="link"
102
+ isActive={isLinkActive}
103
+ title="Link (Cmd+K)"
104
+ onclick={() => (showLinkEditor = true)}
105
+ >
106
+ <VizelIcon name="link" />
107
+ </VizelBubbleMenuButton>
108
+ <VizelBubbleMenuColorPicker {editor} type="textColor" />
109
+ <VizelBubbleMenuColorPicker {editor} type="highlight" />
110
+ </div>
111
+ {/if}
@@ -0,0 +1,13 @@
1
+ import type { Editor } from "@vizel/core";
2
+ export interface VizelBubbleMenuDefaultProps {
3
+ /** The editor instance */
4
+ editor: Editor;
5
+ /** Custom class name */
6
+ class?: string;
7
+ /** Enable embed option in link editor (requires Embed extension) */
8
+ enableEmbed?: boolean;
9
+ }
10
+ declare const VizelBubbleMenuDefault: import("svelte").Component<VizelBubbleMenuDefaultProps, {}, "">;
11
+ type VizelBubbleMenuDefault = ReturnType<typeof VizelBubbleMenuDefault>;
12
+ export default VizelBubbleMenuDefault;
13
+ //# sourceMappingURL=VizelBubbleMenuDefault.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VizelBubbleMenuDefault.svelte.d.ts","sourceRoot":"","sources":["../../src/components/VizelBubbleMenuDefault.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,2BAA2B;IAC1C,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAmFD,QAAA,MAAM,sBAAsB,iEAAwC,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,12 @@
1
+ <script lang="ts" module>
2
+ export interface VizelBubbleMenuDividerProps {
3
+ /** Custom class name */
4
+ class?: string;
5
+ }
6
+ </script>
7
+
8
+ <script lang="ts">
9
+ let { class: className }: VizelBubbleMenuDividerProps = $props();
10
+ </script>
11
+
12
+ <span class="vizel-bubble-menu-divider {className ?? ''}"></span>
@@ -0,0 +1,8 @@
1
+ export interface VizelBubbleMenuDividerProps {
2
+ /** Custom class name */
3
+ class?: string;
4
+ }
5
+ declare const VizelBubbleMenuDivider: import("svelte").Component<VizelBubbleMenuDividerProps, {}, "">;
6
+ type VizelBubbleMenuDivider = ReturnType<typeof VizelBubbleMenuDivider>;
7
+ export default VizelBubbleMenuDivider;
8
+ //# sourceMappingURL=VizelBubbleMenuDivider.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VizelBubbleMenuDivider.svelte.d.ts","sourceRoot":"","sources":["../../src/components/VizelBubbleMenuDivider.svelte.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,2BAA2B;IAC1C,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAYD,QAAA,MAAM,sBAAsB,iEAAwC,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,269 @@
1
+ <script lang="ts" module>
2
+ import type { VizelColorDefinition } from "@vizel/core";
3
+
4
+ export interface VizelColorPickerProps {
5
+ /** Color palette to display */
6
+ colors: VizelColorDefinition[];
7
+ /** Currently selected color */
8
+ value?: string;
9
+ /** Callback when color is selected */
10
+ onchange: (color: string) => void;
11
+ /** Label for accessibility */
12
+ label?: string;
13
+ /** Custom class name */
14
+ class?: string;
15
+ /** Enable custom HEX input (default: true) */
16
+ allowCustomColor?: boolean;
17
+ /** Recent colors to display */
18
+ recentColors?: string[];
19
+ /** Show recent colors section (default: true) */
20
+ showRecentColors?: boolean;
21
+ /** "None" option color values (e.g., ["transparent", "inherit"]) */
22
+ noneValues?: string[];
23
+ }
24
+ </script>
25
+
26
+ <script lang="ts">
27
+ import { isVizelValidHexColor, normalizeVizelHexColor } from "@vizel/core";
28
+ import VizelIcon from "./VizelIcon.svelte";
29
+
30
+ const GRID_COLUMNS = 4;
31
+
32
+ let {
33
+ colors,
34
+ value,
35
+ onchange,
36
+ label = "Color palette",
37
+ class: className,
38
+ allowCustomColor = true,
39
+ recentColors = [],
40
+ showRecentColors = true,
41
+ noneValues = ["transparent", "inherit"],
42
+ }: VizelColorPickerProps = $props();
43
+
44
+ let inputValue = $state("");
45
+ let focusedIndex = $state(-1);
46
+ let swatchRefs: (HTMLButtonElement | null)[] = $state([]);
47
+ let inputRef: HTMLInputElement | null = $state(null);
48
+
49
+ // Clean up swatchRefs when colors decrease
50
+ $effect(() => {
51
+ const length = allColors.length;
52
+ if (swatchRefs.length > length) {
53
+ swatchRefs.length = length;
54
+ }
55
+ });
56
+
57
+ // Build flat list of all selectable colors for keyboard navigation
58
+ const allColors = $derived([
59
+ ...(showRecentColors ? recentColors : []),
60
+ ...colors.map((c) => c.color),
61
+ ]);
62
+
63
+ // Calculate the offset for color palette indices (after recent colors)
64
+ const paletteOffset = $derived(showRecentColors ? recentColors.length : 0);
65
+
66
+ // Find color definition by color value
67
+ function findColorDef(color: string): VizelColorDefinition | undefined {
68
+ return colors.find((c) => c.color === color);
69
+ }
70
+
71
+ // Get display name for a color
72
+ function getColorName(color: string): string {
73
+ const def = findColorDef(color);
74
+ return def?.name ?? color;
75
+ }
76
+
77
+ // Check if a color is a "none" value
78
+ function isNoneValue(color: string): boolean {
79
+ return noneValues.includes(color);
80
+ }
81
+
82
+ // Handle swatch selection
83
+ function handleSelect(color: string) {
84
+ onchange(color);
85
+ inputValue = "";
86
+ }
87
+
88
+ // Handle custom color input submit
89
+ function handleInputSubmit() {
90
+ const normalized = normalizeVizelHexColor(inputValue);
91
+ if (isVizelValidHexColor(normalized)) {
92
+ onchange(normalized);
93
+ inputValue = "";
94
+ }
95
+ }
96
+
97
+ // Handle input keydown
98
+ function handleInputKeyDown(e: KeyboardEvent) {
99
+ if (e.key === "Enter") {
100
+ e.preventDefault();
101
+ handleInputSubmit();
102
+ }
103
+ }
104
+
105
+ // Keyboard navigation handler
106
+ function handleKeyDown(e: KeyboardEvent, currentIndex: number) {
107
+ const totalColors = allColors.length;
108
+ if (totalColors === 0) return;
109
+
110
+ let newIndex = currentIndex;
111
+ let handled = false;
112
+
113
+ switch (e.key) {
114
+ case "ArrowRight":
115
+ newIndex = (currentIndex + 1) % totalColors;
116
+ handled = true;
117
+ break;
118
+ case "ArrowLeft":
119
+ newIndex = (currentIndex - 1 + totalColors) % totalColors;
120
+ handled = true;
121
+ break;
122
+ case "ArrowDown":
123
+ newIndex = Math.min(currentIndex + GRID_COLUMNS, totalColors - 1);
124
+ handled = true;
125
+ break;
126
+ case "ArrowUp":
127
+ newIndex = Math.max(currentIndex - GRID_COLUMNS, 0);
128
+ handled = true;
129
+ break;
130
+ case "Home":
131
+ newIndex = 0;
132
+ handled = true;
133
+ break;
134
+ case "End":
135
+ newIndex = totalColors - 1;
136
+ handled = true;
137
+ break;
138
+ case "Enter":
139
+ case " ": {
140
+ e.preventDefault();
141
+ const selectedColor = allColors[currentIndex];
142
+ if (selectedColor) {
143
+ handleSelect(selectedColor);
144
+ }
145
+ return;
146
+ }
147
+ }
148
+
149
+ if (handled) {
150
+ e.preventDefault();
151
+ focusedIndex = newIndex;
152
+ swatchRefs[newIndex]?.focus();
153
+ }
154
+ }
155
+
156
+ // Update input value when value prop changes
157
+ $effect(() => {
158
+ if (value && !isNoneValue(value)) {
159
+ inputValue = value;
160
+ } else {
161
+ inputValue = "";
162
+ }
163
+ });
164
+
165
+ // Focus first swatch or current value on mount (run only once)
166
+ $effect(() => {
167
+ const currentIndex = value ? allColors.indexOf(value) : -1;
168
+ if (currentIndex >= 0) {
169
+ focusedIndex = currentIndex;
170
+ } else if (allColors.length > 0) {
171
+ focusedIndex = 0;
172
+ }
173
+ });
174
+
175
+ const isInputValid = $derived(isVizelValidHexColor(normalizeVizelHexColor(inputValue)));
176
+ const previewColor = $derived(isInputValid ? normalizeVizelHexColor(inputValue) : undefined);
177
+ </script>
178
+
179
+ <div
180
+ class="vizel-color-picker-content {className ?? ''}"
181
+ role="listbox"
182
+ aria-label={label}
183
+ >
184
+ <!-- Recent colors -->
185
+ {#if showRecentColors && recentColors.length > 0}
186
+ <div class="vizel-color-picker-section">
187
+ <div class="vizel-color-picker-label">Recent</div>
188
+ <div class="vizel-color-picker-recent">
189
+ {#each recentColors as color, idx}
190
+ <button
191
+ bind:this={swatchRefs[idx]}
192
+ type="button"
193
+ role="option"
194
+ aria-selected={value === color}
195
+ aria-label={color}
196
+ tabindex={focusedIndex === idx ? 0 : -1}
197
+ class="vizel-color-picker-swatch {value === color ? 'is-active' : ''}"
198
+ style="background-color: {isNoneValue(color) ? 'transparent' : color}"
199
+ data-color={color}
200
+ onclick={() => handleSelect(color)}
201
+ onkeydown={(e) => handleKeyDown(e, idx)}
202
+ >
203
+ {#if isNoneValue(color)}
204
+ <span class="vizel-color-picker-none"><VizelIcon name="x" /></span>
205
+ {/if}
206
+ </button>
207
+ {/each}
208
+ </div>
209
+ </div>
210
+ {/if}
211
+
212
+ <!-- Color palette -->
213
+ <div class="vizel-color-picker-section">
214
+ <div class="vizel-color-picker-grid">
215
+ {#each colors as colorDef, i}
216
+ {@const idx = paletteOffset + i}
217
+ <button
218
+ bind:this={swatchRefs[idx]}
219
+ type="button"
220
+ role="option"
221
+ aria-selected={value === colorDef.color}
222
+ aria-label={colorDef.name}
223
+ tabindex={focusedIndex === idx ? 0 : -1}
224
+ class="vizel-color-picker-swatch {value === colorDef.color ? 'is-active' : ''}"
225
+ style="background-color: {isNoneValue(colorDef.color) ? 'transparent' : colorDef.color}"
226
+ data-color={colorDef.color}
227
+ onclick={() => handleSelect(colorDef.color)}
228
+ onkeydown={(e) => handleKeyDown(e, idx)}
229
+ >
230
+ {#if isNoneValue(colorDef.color)}
231
+ <span class="vizel-color-picker-none"><VizelIcon name="x" /></span>
232
+ {/if}
233
+ </button>
234
+ {/each}
235
+ </div>
236
+ </div>
237
+
238
+ <!-- HEX input with preview -->
239
+ {#if allowCustomColor}
240
+ <div class="vizel-color-picker-input-row">
241
+ <span
242
+ class="vizel-color-picker-preview"
243
+ style="background-color: {previewColor || 'transparent'}"
244
+ aria-hidden="true"
245
+ ></span>
246
+ <input
247
+ bind:this={inputRef}
248
+ type="text"
249
+ class="vizel-color-picker-input"
250
+ placeholder="#000000"
251
+ value={inputValue}
252
+ maxlength={7}
253
+ aria-label="Custom color hex value"
254
+ oninput={(e) => (inputValue = (e.target as HTMLInputElement).value)}
255
+ onkeydown={handleInputKeyDown}
256
+ />
257
+ <button
258
+ type="button"
259
+ class="vizel-color-picker-apply"
260
+ disabled={!isInputValid}
261
+ title="Apply"
262
+ aria-label="Apply custom color"
263
+ onclick={handleInputSubmit}
264
+ >
265
+ <VizelIcon name="check" />
266
+ </button>
267
+ </div>
268
+ {/if}
269
+ </div>
@@ -0,0 +1,25 @@
1
+ import type { VizelColorDefinition } from "@vizel/core";
2
+ export interface VizelColorPickerProps {
3
+ /** Color palette to display */
4
+ colors: VizelColorDefinition[];
5
+ /** Currently selected color */
6
+ value?: string;
7
+ /** Callback when color is selected */
8
+ onchange: (color: string) => void;
9
+ /** Label for accessibility */
10
+ label?: string;
11
+ /** Custom class name */
12
+ class?: string;
13
+ /** Enable custom HEX input (default: true) */
14
+ allowCustomColor?: boolean;
15
+ /** Recent colors to display */
16
+ recentColors?: string[];
17
+ /** Show recent colors section (default: true) */
18
+ showRecentColors?: boolean;
19
+ /** "None" option color values (e.g., ["transparent", "inherit"]) */
20
+ noneValues?: string[];
21
+ }
22
+ declare const VizelColorPicker: import("svelte").Component<VizelColorPickerProps, {}, "">;
23
+ type VizelColorPicker = ReturnType<typeof VizelColorPicker>;
24
+ export default VizelColorPicker;
25
+ //# sourceMappingURL=VizelColorPicker.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VizelColorPicker.svelte.d.ts","sourceRoot":"","sources":["../../src/components/VizelColorPicker.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,WAAW,qBAAqB;IACpC,+BAA+B;IAC/B,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AA8MD,QAAA,MAAM,gBAAgB,2DAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { Editor } from "@vizel/core";
2
+ export declare const VIZEL_CONTEXT_KEY: unique symbol;
3
+ /**
4
+ * Get the editor instance from VizelProvider context.
5
+ *
6
+ * @throws Error if used outside of VizelProvider
7
+ *
8
+ * @example
9
+ * ```svelte
10
+ * <script lang="ts">
11
+ * import { getVizelContext } from '@vizel/svelte';
12
+ *
13
+ * const getEditor = getVizelContext();
14
+ * </script>
15
+ *
16
+ * <button onclick={() => getEditor()?.chain().focus().toggleBold().run()}>
17
+ * Bold
18
+ * </button>
19
+ * ```
20
+ */
21
+ export declare function getVizelContext(): () => Editor | null;
22
+ /**
23
+ * Get the editor instance from context.
24
+ * Returns undefined if used outside of VizelProvider (does not throw).
25
+ */
26
+ export declare function getVizelContextSafe(): (() => Editor | null) | undefined;
27
+ //# sourceMappingURL=VizelContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VizelContext.d.ts","sourceRoot":"","sources":["../../src/components/VizelContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,eAAO,MAAM,iBAAiB,eAAyB,CAAC;AAExD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,IAAI,MAAM,MAAM,GAAG,IAAI,CAMrD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,SAAS,CAEvE"}
@@ -0,0 +1,34 @@
1
+ import { getContext } from "svelte";
2
+ export const VIZEL_CONTEXT_KEY = Symbol("vizel-editor");
3
+ /**
4
+ * Get the editor instance from VizelProvider context.
5
+ *
6
+ * @throws Error if used outside of VizelProvider
7
+ *
8
+ * @example
9
+ * ```svelte
10
+ * <script lang="ts">
11
+ * import { getVizelContext } from '@vizel/svelte';
12
+ *
13
+ * const getEditor = getVizelContext();
14
+ * </script>
15
+ *
16
+ * <button onclick={() => getEditor()?.chain().focus().toggleBold().run()}>
17
+ * Bold
18
+ * </button>
19
+ * ```
20
+ */
21
+ export function getVizelContext() {
22
+ const getEditor = getContext(VIZEL_CONTEXT_KEY);
23
+ if (!getEditor) {
24
+ throw new Error("getVizelContext must be used within a VizelProvider");
25
+ }
26
+ return getEditor;
27
+ }
28
+ /**
29
+ * Get the editor instance from context.
30
+ * Returns undefined if used outside of VizelProvider (does not throw).
31
+ */
32
+ export function getVizelContextSafe() {
33
+ return getContext(VIZEL_CONTEXT_KEY);
34
+ }
@@ -0,0 +1,61 @@
1
+ <script lang="ts" module>
2
+ import type { Editor } from "@vizel/core";
3
+
4
+ export interface VizelEditorProps {
5
+ /** Override the editor from context */
6
+ editor?: Editor | null;
7
+ /** Custom class name */
8
+ class?: string;
9
+ }
10
+
11
+ export interface VizelExposed {
12
+ /** The container DOM element */
13
+ container: HTMLDivElement | null;
14
+ }
15
+ </script>
16
+
17
+ <script lang="ts">
18
+ import { getVizelContextSafe } from "./VizelContext.ts";
19
+
20
+ let { editor: editorProp, class: className }: VizelEditorProps = $props();
21
+
22
+ const contextEditor = getVizelContextSafe();
23
+ const editor = $derived(editorProp ?? contextEditor?.());
24
+
25
+ let element: HTMLDivElement | null = $state(null);
26
+
27
+ // Expose container element to parent component
28
+ export function getExposed(): VizelExposed {
29
+ return {
30
+ get container() {
31
+ return element;
32
+ },
33
+ };
34
+ }
35
+
36
+ $effect(() => {
37
+ if (!editor || !element) {
38
+ return;
39
+ }
40
+
41
+ const currentEditor = editor;
42
+ const currentElement = element;
43
+
44
+ // Mount the editor's DOM view to the container element
45
+ currentElement.appendChild(currentEditor.view.dom);
46
+
47
+ // Update editable state
48
+ currentEditor.view.setProps({
49
+ editable: () => currentEditor?.isEditable ?? false,
50
+ });
51
+
52
+ // Cleanup: remove DOM element when editor changes or unmounts
53
+ return () => {
54
+ if (currentEditor.view.dom.parentNode === currentElement) {
55
+ currentElement.removeChild(currentEditor.view.dom);
56
+ }
57
+ };
58
+ });
59
+ </script>
60
+
61
+ <div bind:this={element} class={className} data-vizel-content></div>
@@ -0,0 +1,17 @@
1
+ import type { Editor } from "@vizel/core";
2
+ export interface VizelEditorProps {
3
+ /** Override the editor from context */
4
+ editor?: Editor | null;
5
+ /** Custom class name */
6
+ class?: string;
7
+ }
8
+ export interface VizelExposed {
9
+ /** The container DOM element */
10
+ container: HTMLDivElement | null;
11
+ }
12
+ declare const VizelEditor: import("svelte").Component<VizelEditorProps, {
13
+ getExposed: () => VizelExposed;
14
+ }, "">;
15
+ type VizelEditor = ReturnType<typeof VizelEditor>;
16
+ export default VizelEditor;
17
+ //# sourceMappingURL=VizelEditor.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VizelEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/components/VizelEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,SAAS,EAAE,cAAc,GAAG,IAAI,CAAC;CAClC;AAuDD,QAAA,MAAM,WAAW;sBAvCO,YAAY;MAuCqB,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}