@kubex/zinc 1.0.25 → 1.0.99

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 (199) hide show
  1. package/.claude/project.md +556 -0
  2. package/.github/workflows/js_build_and_deploy.yaml +9 -10
  3. package/dist/custom-elements.json +13575 -8856
  4. package/dist/vscode.html-custom-data.json +583 -48
  5. package/dist/web-types.json +1441 -181
  6. package/dist/zn.d.ts +1645 -660
  7. package/dist/zn.min.css +1 -1
  8. package/dist/zn.min.js +1412 -893
  9. package/docs/_utilities/code-previews.cjs +10 -1
  10. package/docs/assets/scripts/docs.js +42 -18
  11. package/docs/data/data-table.json +229 -66
  12. package/docs/data/empty.json +6 -0
  13. package/docs/data/products-table.json +41 -193
  14. package/docs/pages/components/action-bar.md +121 -6
  15. package/docs/pages/components/alert.md +118 -15
  16. package/docs/pages/components/animated-button.md +299 -0
  17. package/docs/pages/components/audio-select.md +534 -0
  18. package/docs/pages/components/bulk-actions.md +79 -5
  19. package/docs/pages/components/button-group.md +235 -27
  20. package/docs/pages/components/button.md +139 -1
  21. package/docs/pages/components/chart.md +365 -9
  22. package/docs/pages/components/checkbox.md +387 -58
  23. package/docs/pages/components/chip.md +253 -33
  24. package/docs/pages/components/collapsible.md +393 -46
  25. package/docs/pages/components/cols.md +152 -30
  26. package/docs/pages/components/confirm.md +182 -16
  27. package/docs/pages/components/copy-button.md +169 -6
  28. package/docs/pages/components/data-select.md +194 -15
  29. package/docs/pages/components/data-table-filter.md +96 -5
  30. package/docs/pages/components/data-table-search.md +451 -0
  31. package/docs/pages/components/data-table-sort.md +66 -5
  32. package/docs/pages/components/data-table.md +727 -66
  33. package/docs/pages/components/datepicker.md +402 -7
  34. package/docs/pages/components/defined-label.md +120 -5
  35. package/docs/pages/components/dialog.md +339 -59
  36. package/docs/pages/components/dropdown.md +366 -11
  37. package/docs/pages/components/editor.md +604 -7
  38. package/docs/pages/components/empty-state.md +315 -16
  39. package/docs/pages/components/expanding-action.md +212 -28
  40. package/docs/pages/components/file.md +421 -12
  41. package/docs/pages/components/filter-container.md +158 -5
  42. package/docs/pages/components/filter-wrapper.md +167 -6
  43. package/docs/pages/components/form-group.md +383 -6
  44. package/docs/pages/components/hover-container.md +237 -6
  45. package/docs/pages/components/icon-picker.md +121 -0
  46. package/docs/pages/components/icon.md +454 -48
  47. package/docs/pages/components/inline-edit.md +787 -19
  48. package/docs/pages/components/input-group.md +207 -13
  49. package/docs/pages/components/input.md +194 -0
  50. package/docs/pages/components/item.md +18 -0
  51. package/docs/pages/components/key-container.md +115 -0
  52. package/docs/pages/components/key.md +101 -0
  53. package/docs/pages/components/menu.md +512 -6
  54. package/docs/pages/components/note.md +239 -36
  55. package/docs/pages/components/opt-group.md +107 -0
  56. package/docs/pages/components/pagination.md +332 -6
  57. package/docs/pages/components/pane.md +222 -6
  58. package/docs/pages/components/panel.md +213 -26
  59. package/docs/pages/components/popup.md +1354 -6
  60. package/docs/pages/components/priority-list.md +233 -0
  61. package/docs/pages/components/progress-bar.md +387 -6
  62. package/docs/pages/components/radio-group.md +242 -5
  63. package/docs/pages/components/radio.md +474 -6
  64. package/docs/pages/components/rating.md +331 -7
  65. package/docs/pages/components/reveal.md +524 -6
  66. package/docs/pages/components/scroll-container.md +552 -6
  67. package/docs/pages/components/select.md +762 -160
  68. package/docs/pages/components/skeleton.md +473 -30
  69. package/docs/pages/components/slideout.md +261 -5
  70. package/docs/pages/components/sp.md +99 -41
  71. package/docs/pages/components/split-button.md +347 -9
  72. package/docs/pages/components/split-pane.md +445 -6
  73. package/docs/pages/components/stat.md +549 -9
  74. package/docs/pages/components/status-indicator.md +230 -1
  75. package/docs/pages/components/stepper.md +563 -6
  76. package/docs/pages/components/tabs.md +439 -13
  77. package/docs/pages/components/textarea.md +415 -17
  78. package/docs/pages/components/tile.md +385 -26
  79. package/docs/pages/components/toggle.md +424 -6
  80. package/docs/pages/components/tooltip.md +367 -0
  81. package/docs/pages/components/translation-group.md +210 -0
  82. package/docs/pages/components/translations.md +319 -19
  83. package/docs/pages/components/vertical-stepper.md +401 -8
  84. package/docs/pages/components/well.md +300 -3
  85. package/docs/pages/getting-started/form-controls.md +162 -0
  86. package/docs/pages/index.md +116 -15
  87. package/package.json +5 -6
  88. package/scss/_global-spacing.scss +4 -0
  89. package/scss/_root.scss +2 -2
  90. package/scss/boot.scss +19 -0
  91. package/scss/shared/layout.scss +5 -0
  92. package/scss/themes/_light.scss +3 -3
  93. package/src/components/alert/alert.scss +1 -0
  94. package/src/components/animated-button/README.md +306 -0
  95. package/src/components/animated-button/animated-button.component.ts +229 -0
  96. package/src/components/animated-button/animated-button.scss +228 -0
  97. package/src/components/animated-button/animated-button.test.ts +143 -0
  98. package/src/components/animated-button/index.ts +12 -0
  99. package/src/components/button/button.component.ts +5 -0
  100. package/src/components/button-group/button-group.component.ts +25 -13
  101. package/src/components/button-group/button-group.scss +6 -0
  102. package/src/components/checkbox/checkbox.component.ts +4 -0
  103. package/src/components/checkbox/checkbox.scss +7 -4
  104. package/src/components/checkbox-group/checkbox-group.scss +7 -0
  105. package/src/components/chip/chip.component.ts +7 -2
  106. package/src/components/chip/chip.scss +16 -2
  107. package/src/components/collapsible/collapsible.component.ts +27 -20
  108. package/src/components/cols/cols.component.ts +14 -2
  109. package/src/components/cols/cols.scss +6 -12
  110. package/src/components/confirm/confirm.component.ts +7 -0
  111. package/src/components/copy-button/copy-button.component.ts +12 -11
  112. package/src/components/data-select/data-select.component.ts +215 -44
  113. package/src/components/data-select/data-select.scss +66 -6
  114. package/src/components/data-select/providers/currency-data-provider.ts +20 -6
  115. package/src/components/data-select/providers/provider.ts +1 -0
  116. package/src/components/data-select/providers/us-state-data-provider.ts +68 -0
  117. package/src/components/data-table/data-table.component.ts +81 -22
  118. package/src/components/data-table-search/data-table-search.component.ts +184 -0
  119. package/src/components/data-table-search/data-table-search.scss +17 -0
  120. package/src/components/data-table-search/data-table-search.test.ts +11 -0
  121. package/src/components/data-table-search/index.ts +12 -0
  122. package/src/components/datepicker/datepicker.component.ts +347 -13
  123. package/src/components/dialog/dialog.component.ts +1 -1
  124. package/src/components/empty-state/empty-state.scss +6 -1
  125. package/src/components/header/header.scss +3 -3
  126. package/src/components/icon/icon.component.ts +23 -1
  127. package/src/components/icon/icon.scss +23 -0
  128. package/src/components/icon-picker/brand-icons.ts +24 -0
  129. package/src/components/icon-picker/icon-picker.component.ts +407 -0
  130. package/src/components/icon-picker/icon-picker.scss +205 -0
  131. package/src/components/icon-picker/index.ts +12 -0
  132. package/src/components/icon-picker/line-icons.ts +612 -0
  133. package/src/components/icon-picker/material-icons.ts +14543 -0
  134. package/src/components/inline-edit/inline-edit.component.ts +190 -46
  135. package/src/components/inline-edit/inline-edit.scss +29 -0
  136. package/src/components/inline-edit/inline-edit.test.ts +314 -1
  137. package/src/components/input/input.component.ts +324 -5
  138. package/src/components/input/input.scss +87 -0
  139. package/src/components/input-group/input-group.component.ts +28 -7
  140. package/src/components/input-group/input-group.scss +48 -10
  141. package/src/components/item/item.component.ts +24 -3
  142. package/src/components/item/item.scss +18 -0
  143. package/src/components/key/index.ts +12 -0
  144. package/src/components/key/key.component.ts +47 -0
  145. package/src/components/key/key.scss +38 -0
  146. package/src/components/key-container/index.ts +12 -0
  147. package/src/components/key-container/key-container.component.ts +142 -0
  148. package/src/components/key-container/key-container.scss +33 -0
  149. package/src/components/menu-item/menu-item.component.ts +20 -0
  150. package/src/components/menu-item/menu-item.scss +69 -2
  151. package/src/components/navbar/navbar.component.ts +103 -11
  152. package/src/components/navbar/navbar.scss +6 -1
  153. package/src/components/opt-group/index.ts +12 -0
  154. package/src/components/opt-group/opt-group.component.ts +74 -0
  155. package/src/components/opt-group/opt-group.scss +37 -0
  156. package/src/components/opt-group/opt-group.test.ts +27 -0
  157. package/src/components/option/option.component.ts +1 -16
  158. package/src/components/option/option.scss +4 -0
  159. package/src/components/panel/panel.component.ts +10 -8
  160. package/src/components/panel/panel.scss +20 -0
  161. package/src/components/priority-list/index.ts +12 -0
  162. package/src/components/priority-list/priority-list.component.ts +611 -0
  163. package/src/components/priority-list/priority-list.scss +185 -0
  164. package/src/components/priority-list/priority-list.test.ts +139 -0
  165. package/src/components/progress-bar/progress-bar.component.ts +22 -16
  166. package/src/components/radio/radio.scss +10 -3
  167. package/src/components/select/select.component.ts +812 -72
  168. package/src/components/select/select.scss +108 -2
  169. package/src/components/select/select.test.ts +147 -2
  170. package/src/components/settings-container/settings-container.component.ts +44 -19
  171. package/src/components/settings-container/settings-container.scss +1 -1
  172. package/src/components/skeleton/skeleton.component.ts +6 -1
  173. package/src/components/slideout/slideout.scss +8 -3
  174. package/src/components/sp/sp.component.ts +3 -1
  175. package/src/components/sp/sp.scss +19 -0
  176. package/src/components/stepper/stepper.component.ts +16 -10
  177. package/src/components/textarea/textarea.scss +0 -4
  178. package/src/components/tile/tile.component.ts +12 -3
  179. package/src/components/tile/tile.scss +1 -1
  180. package/src/components/timer/timer.component.ts +15 -2
  181. package/src/components/toggle/toggle.component.ts +29 -26
  182. package/src/components/toggle/toggle.scss +13 -1
  183. package/src/components/translation-group/index.ts +12 -0
  184. package/src/components/translation-group/translation-group.component.ts +207 -0
  185. package/src/components/translation-group/translation-group.scss +8 -0
  186. package/src/components/translations/translations.component.ts +90 -44
  187. package/src/components/translations/translations.scss +4 -0
  188. package/src/components/vertical-stepper/vertical-stepper.component.ts +14 -9
  189. package/src/events/events.ts +12 -7
  190. package/src/events/zn-language-change.ts +7 -0
  191. package/src/events/zn-purchase.ts +11 -0
  192. package/src/events/zn-redirect.ts +7 -0
  193. package/src/events/zn-reorder.ts +7 -0
  194. package/src/events/zn-search-change.ts +11 -0
  195. package/src/events/zn-submit.ts +1 -1
  196. package/src/form-control.scss +4 -0
  197. package/src/internal/form-navigation.ts +510 -0
  198. package/src/internal/form.ts +6 -0
  199. package/src/zinc.ts +91 -83
@@ -1,24 +1,621 @@
1
1
  ---
2
2
  meta:
3
3
  title: Editor
4
- description:
4
+ description: A rich text editor component powered by Quill for composing formatted content with support for text formatting, lists, images, attachments, emojis, dates, and more.
5
5
  layout: component
6
6
  ---
7
7
 
8
- ```html:preview
8
+ The Editor is a powerful rich text editing component built on top of Quill. It provides a customizable toolbar with formatting options, supports file attachments and uploads, includes emoji and date pickers, and offers AI-assisted writing capabilities.
9
9
 
10
- <zn-editor style="height: 400px">
10
+ ```html:preview
11
+ <zn-editor
12
+ name="content"
13
+ value=""
14
+ code-blocks
15
+ dividers
16
+ links
17
+ images
18
+ emojis
19
+ style="height: 400px">
11
20
  </zn-editor>
12
21
  ```
13
22
 
23
+ :::tip
24
+ This component works with standard `<form>` elements. Please refer to the section on [form controls](/getting-started/form-controls) to learn more about form submission and client-side validation.
25
+ :::
26
+
14
27
  ## Examples
15
28
 
16
- ### First Example
29
+ ### Basic Editor
30
+
31
+ A basic editor with default formatting options (headings, bold, italic, underline, colors, lists, etc.).
32
+
33
+ ```html:preview
34
+ <zn-editor
35
+ name="description"
36
+ style="height: 300px">
37
+ </zn-editor>
38
+ ```
39
+
40
+ ### Editor with Initial Value
41
+
42
+ Set initial HTML content using the `value` attribute.
43
+
44
+ ```html:preview
45
+ <zn-editor
46
+ name="content"
47
+ value="<h2>Welcome</h2><p>This editor has <strong>initial content</strong> with formatting.</p>"
48
+ style="height: 300px">
49
+ </zn-editor>
50
+ ```
51
+
52
+ ### Interaction Types
53
+
54
+ The editor supports two interaction types: `chat` and `ticket`. In chat mode, pressing Enter submits the form if there is content. In ticket mode (default), Enter creates a new line.
55
+
56
+ #### Chat Mode
57
+
58
+ In chat mode, pressing Enter will submit the form automatically if the editor has content.
59
+
60
+ ```html:preview
61
+ <form class="chat-form">
62
+ <zn-editor
63
+ name="message"
64
+ interaction-type="chat"
65
+ style="height: 200px">
66
+ </zn-editor>
67
+ <div style="margin-top: 1rem; padding: 1rem; background: var(--zn-color-neutral-100); border-radius: 4px; font-size: 0.875rem;">
68
+ <strong>Messages:</strong>
69
+ <div id="chat-messages"></div>
70
+ </div>
71
+ </form>
72
+
73
+ <script type="module">
74
+ const form = document.querySelector('.chat-form');
75
+ const messagesDiv = document.getElementById('chat-messages');
76
+
77
+ await customElements.whenDefined('zn-editor');
78
+
79
+ form.addEventListener('submit', (e) => {
80
+ e.preventDefault();
81
+ const formData = new FormData(form);
82
+ const message = formData.get('message');
83
+ if (message) {
84
+ const time = new Date().toLocaleTimeString();
85
+ messagesDiv.innerHTML += `<div style="margin-top: 0.5rem;">[${time}] ${message}</div>`;
86
+ }
87
+ });
88
+ </script>
89
+ ```
90
+
91
+ #### Ticket Mode
92
+
93
+ In ticket mode (default), Enter creates new lines. Forms must be submitted using a submit button.
94
+
95
+ ```html:preview
96
+ <form class="ticket-form">
97
+ <zn-editor
98
+ name="ticket-content"
99
+ interaction-type="ticket"
100
+ style="height: 250px">
101
+ </zn-editor>
102
+ <br />
103
+ <zn-button type="submit" color="success">Submit Ticket</zn-button>
104
+ </form>
105
+
106
+ <script type="module">
107
+ const form = document.querySelector('.ticket-form');
108
+
109
+ await Promise.all([
110
+ customElements.whenDefined('zn-editor'),
111
+ customElements.whenDefined('zn-button')
112
+ ]);
113
+
114
+ form.addEventListener('submit', (e) => {
115
+ e.preventDefault();
116
+ const formData = new FormData(form);
117
+ alert('Ticket submitted!\n\n' + formData.get('ticket-content'));
118
+ });
119
+ </script>
120
+ ```
121
+
122
+ ### Enabling Features
123
+
124
+ The editor has many optional features that can be enabled with boolean attributes.
125
+
126
+ #### Code Blocks
127
+
128
+ Enable code block insertion with the `code-blocks` attribute.
129
+
130
+ ```html:preview
131
+ <zn-editor
132
+ name="content"
133
+ code-blocks
134
+ style="height: 300px">
135
+ </zn-editor>
136
+ ```
137
+
138
+ #### Inline Code
139
+
140
+ Enable inline code formatting with the `code` attribute.
141
+
142
+ ```html:preview
143
+ <zn-editor
144
+ name="content"
145
+ code
146
+ value="<p>Use inline code for commands like <code>npm install</code></p>"
147
+ style="height: 300px">
148
+ </zn-editor>
149
+ ```
150
+
151
+ #### Dividers
152
+
153
+ Enable horizontal rule insertion with the `dividers` attribute.
154
+
155
+ ```html:preview
156
+ <zn-editor
157
+ name="content"
158
+ dividers
159
+ value="<p>Section 1</p><hr class='ql-hr'><p>Section 2</p>"
160
+ style="height: 300px">
161
+ </zn-editor>
162
+ ```
163
+
164
+ #### Links
165
+
166
+ Enable link insertion and editing with the `links` attribute.
167
+
168
+ ```html:preview
169
+ <zn-editor
170
+ name="content"
171
+ links
172
+ value="<p>Visit <a href='https://zinc.style'>our website</a> for more info.</p>"
173
+ style="height: 300px">
174
+ </zn-editor>
175
+ ```
176
+
177
+ #### Images
178
+
179
+ Enable image insertion with the `images` attribute.
180
+
181
+ ```html:preview
182
+ <zn-editor
183
+ name="content"
184
+ images
185
+ style="height: 300px">
186
+ </zn-editor>
187
+ ```
188
+
189
+ #### Videos
190
+
191
+ Enable video embedding with the `videos` attribute.
192
+
193
+ ```html:preview
194
+ <zn-editor
195
+ name="content"
196
+ videos
197
+ style="height: 300px">
198
+ </zn-editor>
199
+ ```
200
+
201
+ #### Emojis
202
+
203
+ Enable emoji picker with the `emojis` attribute. Users can type `:` to trigger autocomplete or use the emoji picker from the toolbar.
204
+
205
+ ```html:preview
206
+ <zn-editor
207
+ name="content"
208
+ emojis
209
+ value="<p>Express yourself! 😀 🎉 ❤️</p>"
210
+ style="height: 300px">
211
+ </zn-editor>
212
+ ```
213
+
214
+ #### Dates
215
+
216
+ Enable date picker with the `dates` attribute.
217
+
218
+ ```html:preview
219
+ <zn-editor
220
+ name="content"
221
+ dates
222
+ style="height: 300px">
223
+ </zn-editor>
224
+ ```
225
+
226
+ #### All Features Combined
227
+
228
+ Enable all features together for a fully-featured editor.
229
+
230
+ ```html:preview
231
+ <zn-editor
232
+ name="content"
233
+ code-blocks
234
+ code
235
+ dividers
236
+ links
237
+ images
238
+ videos
239
+ dates
240
+ emojis
241
+ style="height: 400px">
242
+ </zn-editor>
243
+ ```
244
+
245
+ ### File Attachments
246
+
247
+ Enable file attachments with the `attachments` attribute. You must also provide an `attachment-url` for uploading files.
248
+
249
+ ```html:preview
250
+ <form class="attachment-form">
251
+ <zn-editor
252
+ name="message"
253
+ attachments
254
+ attachment-url="/api/upload"
255
+ style="height: 300px">
256
+ </zn-editor>
257
+ <input type="hidden" name="attachments" />
258
+ <br />
259
+ <zn-button type="submit" color="success">Submit</zn-button>
260
+ </form>
261
+
262
+ <script type="module">
263
+ const form = document.querySelector('.attachment-form');
264
+
265
+ await Promise.all([
266
+ customElements.whenDefined('zn-editor'),
267
+ customElements.whenDefined('zn-button')
268
+ ]);
17
269
 
18
- TODO
270
+ form.addEventListener('submit', (e) => {
271
+ e.preventDefault();
272
+ alert('Form submitted! In a real application, attachments would be uploaded to the server.');
273
+ });
274
+ </script>
275
+ ```
276
+
277
+ :::warning
278
+ **Note:** The attachment feature requires a server endpoint that accepts POST requests with file data and returns JSON with `uploadPath`, `uploadUrl`, and `originalFilename` properties.
279
+ :::
280
+
281
+ ### Custom Toolbar Tools
282
+
283
+ Add custom tools to the editor toolbar using the `zn-editor-tool` component in the `tools` slot.
284
+
285
+ ```html:preview
286
+ <zn-editor
287
+ name="content"
288
+ style="height: 300px">
289
+ <zn-editor-tool
290
+ slot="tools"
291
+ icon="lightbulb"
292
+ label="Insert Tip"
293
+ handler="dialog"
294
+ uri="/custom/tip"
295
+ key="tip">
296
+ </zn-editor-tool>
297
+ </zn-editor>
298
+ ```
299
+
300
+ ### Context Menu Quick Actions
301
+
302
+ Add custom quick actions to the context menu using the `zn-editor-quick-action` component in the `context-items` slot.
303
+
304
+ ```html:preview
305
+ <zn-editor
306
+ name="content"
307
+ value="<p>Select this text to see custom quick actions in the context menu</p>"
308
+ style="height: 300px">
309
+ <zn-editor-quick-action
310
+ slot="context-items"
311
+ icon="translate"
312
+ label="Translate"
313
+ uri="/api/translate"
314
+ key="translate"
315
+ order="1">
316
+ </zn-editor-quick-action>
317
+ <zn-editor-quick-action
318
+ slot="context-items"
319
+ icon="auto_fix_high"
320
+ label="Improve"
321
+ uri="/api/improve"
322
+ key="improve"
323
+ order="2">
324
+ </zn-editor-quick-action>
325
+ </zn-editor>
326
+ ```
327
+
328
+ ### AI-Assisted Editing
329
+
330
+ Enable AI features with the `ai` attribute and provide an `ai-path` for the AI service endpoint.
331
+
332
+ ```html:preview
333
+ <zn-editor
334
+ name="content"
335
+ ai
336
+ ai-path="/api/ai"
337
+ style="height: 350px">
338
+ </zn-editor>
339
+ ```
340
+
341
+ :::warning
342
+ **Note:** The AI feature requires a server endpoint that accepts POST requests and returns AI-generated content. The AI module is experimental.
343
+ :::
344
+
345
+ ### Custom Actions Slot
346
+
347
+ Add custom action buttons below the editor using the `actions` slot.
348
+
349
+ ```html:preview
350
+ <zn-editor
351
+ name="content"
352
+ style="height: 300px">
353
+ <div slot="actions" style="display: flex; gap: 0.5rem;">
354
+ <zn-button color="success" type="button" id="save-draft">Save Draft</zn-button>
355
+ <zn-button color="primary" type="submit">Publish</zn-button>
356
+ </div>
357
+ </zn-editor>
358
+
359
+ <script type="module">
360
+ await customElements.whenDefined('zn-button');
361
+
362
+ document.getElementById('save-draft').addEventListener('click', () => {
363
+ alert('Draft saved!');
364
+ });
365
+ </script>
366
+ ```
367
+
368
+ ### Programmatic Content Insertion
369
+
370
+ You can programmatically insert or replace content in the editor using special data attributes on clickable elements.
371
+
372
+ #### Insert Mode
373
+
374
+ Insert text at the current cursor position using `editor-mode="insert"`.
375
+
376
+ ```html:preview
377
+ <div style="margin-bottom: 1rem;">
378
+ <zn-button
379
+ editor-id="demo-editor"
380
+ editor-mode="insert"
381
+ editor-content-id="insert-content">
382
+ Insert Template
383
+ </zn-button>
384
+ <input type="hidden" id="insert-content" value="[Inserted template text]">
385
+ </div>
386
+
387
+ <zn-editor
388
+ id="demo-editor"
389
+ name="content"
390
+ value="<p>Click the button to insert text at cursor position.</p>"
391
+ style="height: 250px">
392
+ </zn-editor>
393
+ ```
394
+
395
+ #### Replace Mode
396
+
397
+ Replace selected text or entire content using `editor-mode="replace"`.
398
+
399
+ ```html:preview
400
+ <div style="margin-bottom: 1rem;">
401
+ <zn-button
402
+ editor-id="replace-editor"
403
+ editor-mode="replace"
404
+ editor-content-id="replace-content">
405
+ Replace with Template
406
+ </zn-button>
407
+ <input type="hidden" id="replace-content" value="This is replacement text">
408
+ </div>
409
+
410
+ <zn-editor
411
+ id="replace-editor"
412
+ name="content"
413
+ value="<p>Select some text and click the button, or click with no selection to replace all.</p>"
414
+ style="height: 250px">
415
+ </zn-editor>
416
+ ```
417
+
418
+ ### Events
419
+
420
+ Listen to editor events to respond to user interactions.
19
421
 
20
- ### Second Example
422
+ ```html:preview
423
+ <zn-editor
424
+ id="event-demo"
425
+ name="content"
426
+ interaction-type="chat"
427
+ style="height: 200px">
428
+ </zn-editor>
429
+
430
+ <div id="event-log" style="margin-top: 1rem; padding: 1rem; background: var(--zn-color-neutral-100); border-radius: 4px; font-family: monospace; font-size: 0.875rem; max-height: 200px; overflow-y: auto;">
431
+ Events will appear here...
432
+ </div>
433
+
434
+ <script type="module">
435
+ const editor = document.getElementById('event-demo');
436
+ const eventLog = document.getElementById('event-log');
437
+
438
+ await customElements.whenDefined('zn-editor');
439
+
440
+ function logEvent(eventName, detail = '') {
441
+ const time = new Date().toLocaleTimeString();
442
+ const message = `[${time}] ${eventName}${detail ? ': ' + JSON.stringify(detail).substring(0, 50) : ''}`;
443
+ eventLog.innerHTML = message + '<br>' + eventLog.innerHTML;
444
+ }
445
+
446
+ editor.addEventListener('zn-change', (e) => {
447
+ logEvent('zn-change', 'content updated');
448
+ });
449
+
450
+ editor.addEventListener('zn-submit', (e) => {
451
+ logEvent('zn-submit', {value: e.detail.value.substring(0, 30) + '...'});
452
+ });
453
+
454
+ editor.addEventListener('zn-element-added', (e) => {
455
+ logEvent('zn-element-added', 'editor initialized');
456
+ });
457
+ </script>
458
+ ```
459
+
460
+ ### Form Validation
461
+
462
+ The editor integrates with HTML5 form validation.
463
+
464
+ ```html:preview
465
+ <form class="editor-validation-form">
466
+ <zn-editor
467
+ id="validation-editor"
468
+ name="description"
469
+ style="height: 250px">
470
+ </zn-editor>
471
+ <br />
472
+ <zn-button type="submit" color="success">Submit</zn-button>
473
+ </form>
474
+
475
+ <script type="module">
476
+ const form = document.querySelector('.editor-validation-form');
477
+ const editor = document.getElementById('validation-editor');
478
+
479
+ await Promise.all([
480
+ customElements.whenDefined('zn-editor'),
481
+ customElements.whenDefined('zn-button')
482
+ ]);
483
+
484
+ // Custom validation: require at least 10 characters
485
+ editor.addEventListener('zn-change', () => {
486
+ const text = editor.value.replace(/<[^>]*>/g, '').trim();
487
+ if (text.length < 10 && text.length > 0) {
488
+ editor.setCustomValidity('Content must be at least 10 characters long');
489
+ } else if (text.length === 0) {
490
+ editor.setCustomValidity('Content is required');
491
+ } else {
492
+ editor.setCustomValidity('');
493
+ }
494
+ });
495
+
496
+ form.addEventListener('submit', (e) => {
497
+ e.preventDefault();
498
+ if (form.checkValidity()) {
499
+ alert('Form submitted successfully!');
500
+ } else {
501
+ editor.reportValidity();
502
+ }
503
+ });
504
+ </script>
505
+ ```
506
+
507
+ ### Responsive Toolbar
508
+
509
+ The toolbar automatically adapts to available space, moving tools into an overflow menu on smaller screens.
510
+
511
+ ```html:preview
512
+ <div style="resize: horizontal; overflow: auto; border: 2px dashed var(--zn-color-neutral-300); padding: 1rem; min-width: 300px; max-width: 100%;">
513
+ <p style="font-size: 0.875rem; color: var(--zn-color-neutral-600); margin-bottom: 0.5rem;">Resize this container to see the toolbar adapt</p>
514
+ <zn-editor
515
+ name="content"
516
+ code-blocks
517
+ dividers
518
+ links
519
+ images
520
+ emojis
521
+ dates
522
+ style="height: 300px">
523
+ </zn-editor>
524
+ </div>
525
+ ```
526
+
527
+ ### Time Tracking Integration
528
+
529
+ The editor can integrate with hidden time tracking inputs in the form for tracking editing time.
530
+
531
+ ```html:preview
532
+ <form class="time-tracking-form">
533
+ <input type="hidden" name="startTime" id="startTime" />
534
+ <input type="hidden" name="openTime" id="openTime" />
535
+
536
+ <zn-editor
537
+ name="content"
538
+ style="height: 250px">
539
+ </zn-editor>
540
+ <br />
541
+ <zn-button type="submit" color="success">Submit</zn-button>
542
+
543
+ <div style="margin-top: 1rem; font-size: 0.875rem; color: var(--zn-color-neutral-600);">
544
+ Time tracking is active. Check form data on submit.
545
+ </div>
546
+ </form>
547
+
548
+ <script type="module">
549
+ const form = document.querySelector('.time-tracking-form');
550
+
551
+ await Promise.all([
552
+ customElements.whenDefined('zn-editor'),
553
+ customElements.whenDefined('zn-button')
554
+ ]);
555
+
556
+ form.addEventListener('submit', (e) => {
557
+ e.preventDefault();
558
+ const formData = new FormData(form);
559
+ const data = Object.fromEntries(formData);
560
+ alert('Form with time tracking:\n\n' + JSON.stringify(data, null, 2));
561
+ });
562
+ </script>
563
+ ```
564
+
565
+ ### Advanced: Accessing Quill Instance
566
+
567
+ For advanced use cases, you can access the underlying Quill instance after the editor is initialized.
568
+
569
+ ```html:preview
570
+ <zn-editor
571
+ id="quill-access"
572
+ name="content"
573
+ value="<p>This editor demonstrates direct Quill API access.</p>"
574
+ style="height: 250px">
575
+ </zn-editor>
576
+
577
+ <div style="margin-top: 1rem; display: flex; gap: 0.5rem;">
578
+ <zn-button id="get-length">Get Text Length</zn-button>
579
+ <zn-button id="insert-text">Insert Text</zn-button>
580
+ <zn-button id="format-bold">Toggle Bold</zn-button>
581
+ </div>
582
+
583
+ <script type="module">
584
+ const editor = document.getElementById('quill-access');
585
+
586
+ await Promise.all([
587
+ customElements.whenDefined('zn-editor'),
588
+ customElements.whenDefined('zn-button')
589
+ ]);
590
+
591
+ // Wait for editor to be fully initialized
592
+ editor.addEventListener('zn-element-added', () => {
593
+ const quill = editor.quillElement;
594
+
595
+ document.getElementById('get-length').addEventListener('click', () => {
596
+ const length = quill.getLength();
597
+ alert(`Text length: ${length} characters`);
598
+ });
599
+
600
+ document.getElementById('insert-text').addEventListener('click', () => {
601
+ const range = quill.getSelection();
602
+ const index = range ? range.index : 0;
603
+ quill.insertText(index, ' [Inserted via API] ');
604
+ });
605
+
606
+ document.getElementById('format-bold').addEventListener('click', () => {
607
+ const range = quill.getSelection();
608
+ if (range) {
609
+ const format = quill.getFormat(range);
610
+ quill.format('bold', !format.bold);
611
+ }
612
+ });
613
+ });
614
+ </script>
615
+ ```
21
616
 
22
- TODO
617
+ :::warning
618
+ **Note:** Direct access to the Quill instance should be used with caution. Always prefer using the editor's public API when possible. The `quillElement` property is available but not officially documented and may change in future versions.
619
+ :::
23
620
 
24
621