@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
@@ -239,4 +239,371 @@ Tooltips will be clipped if they're inside a container that has `overflow: auto|
239
239
  padding: var(--zn-spacing-medium);
240
240
  }
241
241
  </style>
242
+ ```
243
+
244
+ ### Distance and Skidding
245
+
246
+ Use the `distance` and `skidding` attributes to fine-tune the tooltip's position. The `distance` attribute controls how far the tooltip is from the anchor element, while `skidding` offsets the tooltip along the anchor element.
247
+
248
+ ```html:preview
249
+ <div style="display: flex; gap: 2rem; margin: 2rem 0;">
250
+ <zn-tooltip content="Distance: 8px" distance="8">
251
+ <zn-button>Distance 8</zn-button>
252
+ </zn-tooltip>
253
+
254
+ <zn-tooltip content="Distance: 16px" distance="16">
255
+ <zn-button>Distance 16</zn-button>
256
+ </zn-tooltip>
257
+
258
+ <zn-tooltip content="Skidding: 20px" skidding="20">
259
+ <zn-button>Skidding 20</zn-button>
260
+ </zn-tooltip>
261
+
262
+ <zn-tooltip content="Distance: 12, Skidding: 15" distance="12" skidding="15">
263
+ <zn-button>Both</zn-button>
264
+ </zn-tooltip>
265
+ </div>
266
+ ```
267
+
268
+ ### Disabled Tooltips
269
+
270
+ Use the `disabled` attribute to disable a tooltip. The tooltip will not show when disabled.
271
+
272
+ ```html:preview
273
+ <zn-tooltip content="This tooltip is disabled" disabled>
274
+ <zn-button>Disabled Tooltip</zn-button>
275
+ </zn-tooltip>
276
+
277
+ <zn-tooltip content="This tooltip is enabled">
278
+ <zn-button>Enabled Tooltip</zn-button>
279
+ </zn-tooltip>
280
+
281
+ <script>
282
+ const disabledTooltip = document.querySelector('zn-tooltip[disabled]');
283
+ const toggleButton = document.createElement('zn-button');
284
+ toggleButton.textContent = 'Toggle Disabled';
285
+ toggleButton.style.marginLeft = '1rem';
286
+ toggleButton.addEventListener('click', () => {
287
+ disabledTooltip.disabled = !disabledTooltip.disabled;
288
+ });
289
+ disabledTooltip.parentElement.appendChild(toggleButton);
290
+ </script>
291
+ ```
292
+
293
+ ### Focus Trigger
294
+
295
+ Use the `trigger` attribute with value `focus` to show the tooltip only when the anchor element receives focus.
296
+
297
+ ```html:preview
298
+ <zn-tooltip content="Focus on the input to see this" trigger="focus">
299
+ <zn-input placeholder="Focus me"></zn-input>
300
+ </zn-tooltip>
301
+ ```
302
+
303
+ ### Hover and Focus Trigger
304
+
305
+ The default trigger is `hover focus`, which shows the tooltip on both hover and focus events.
306
+
307
+ ```html:preview
308
+ <zn-tooltip content="Hover or focus to see this" trigger="hover focus">
309
+ <zn-button>Hover or Focus</zn-button>
310
+ </zn-tooltip>
311
+ ```
312
+
313
+ ### Multiple Trigger Types
314
+
315
+ You can combine multiple trigger types by separating them with spaces.
316
+
317
+ ```html:preview
318
+ <div style="display: flex; gap: 1rem;">
319
+ <zn-tooltip content="Hover only" trigger="hover">
320
+ <zn-button>Hover</zn-button>
321
+ </zn-tooltip>
322
+
323
+ <zn-tooltip content="Click only" trigger="click">
324
+ <zn-button>Click</zn-button>
325
+ </zn-tooltip>
326
+
327
+ <zn-tooltip content="Focus only" trigger="focus">
328
+ <zn-button>Focus</zn-button>
329
+ </zn-tooltip>
330
+
331
+ <zn-tooltip content="Hover and click" trigger="hover click">
332
+ <zn-button>Hover & Click</zn-button>
333
+ </zn-tooltip>
334
+ </div>
335
+ ```
336
+
337
+ ## Events
338
+
339
+ Tooltips emit events when they show and hide, allowing you to respond to these state changes.
340
+
341
+ ### Show and Hide Events
342
+
343
+ The `zn-show` event is emitted when the tooltip begins to show, and `zn-hide` is emitted when it begins to hide.
344
+
345
+ ```html:preview
346
+ <div class="tooltip-events">
347
+ <zn-tooltip content="Hover me to trigger events">
348
+ <zn-button>Event Demo</zn-button>
349
+ </zn-tooltip>
350
+
351
+ <div class="event-log">
352
+ <strong>Event Log:</strong>
353
+ <ul id="event-list"></ul>
354
+ </div>
355
+ </div>
356
+
357
+ <script>
358
+ const tooltip = document.querySelector('.tooltip-events zn-tooltip');
359
+ const eventList = document.getElementById('event-list');
360
+
361
+ ['zn-show', 'zn-after-show', 'zn-hide', 'zn-after-hide'].forEach(eventName => {
362
+ tooltip.addEventListener(eventName, () => {
363
+ const li = document.createElement('li');
364
+ li.textContent = `${eventName} - ${new Date().toLocaleTimeString()}`;
365
+ eventList.insertBefore(li, eventList.firstChild);
366
+
367
+ // Keep only last 5 events
368
+ if (eventList.children.length > 5) {
369
+ eventList.removeChild(eventList.lastChild);
370
+ }
371
+ });
372
+ });
373
+ </script>
374
+
375
+ <style>
376
+ .tooltip-events {
377
+ display: flex;
378
+ gap: 2rem;
379
+ align-items: start;
380
+ }
381
+
382
+ .event-log {
383
+ background: var(--zn-color-neutral-50);
384
+ padding: 1rem;
385
+ border-radius: 4px;
386
+ min-width: 300px;
387
+ }
388
+
389
+ .event-log ul {
390
+ list-style: none;
391
+ padding: 0;
392
+ margin: 0.5rem 0 0 0;
393
+ font-size: 0.875rem;
394
+ }
395
+
396
+ .event-log li {
397
+ padding: 0.25rem 0;
398
+ border-bottom: 1px solid var(--zn-color-neutral-200);
399
+ }
400
+
401
+ .event-log li:last-child {
402
+ border-bottom: none;
403
+ }
404
+ </style>
405
+ ```
406
+
407
+ ### After Show and After Hide Events
408
+
409
+ The `zn-after-show` event is emitted after the tooltip is fully shown, and `zn-after-hide` is emitted after it is fully hidden.
410
+
411
+ ```html:preview
412
+ <zn-tooltip content="Open and close events">
413
+ <zn-button id="after-events-btn">After Events Demo</zn-button>
414
+ </zn-tooltip>
415
+
416
+ <div id="after-events-status" style="margin-top: 1rem; padding: 0.5rem; background: var(--zn-color-neutral-100); border-radius: 4px;">
417
+ Status: <span id="status-text">Ready</span>
418
+ </div>
419
+
420
+ <script>
421
+ const afterTooltip = document.querySelector('#after-events-btn').parentElement;
422
+ const statusText = document.getElementById('status-text');
423
+
424
+ afterTooltip.addEventListener('zn-after-show', () => {
425
+ statusText.textContent = 'Tooltip fully shown';
426
+ statusText.style.color = 'var(--zn-color-success-600)';
427
+ });
428
+
429
+ afterTooltip.addEventListener('zn-after-hide', () => {
430
+ statusText.textContent = 'Tooltip fully hidden';
431
+ statusText.style.color = 'var(--zn-color-neutral-600)';
432
+ });
433
+ </script>
434
+ ```
435
+
436
+ ## Methods
437
+
438
+ Tooltips provide methods to programmatically control their visibility.
439
+
440
+ ### Show Method
441
+
442
+ Call the `show()` method to display the tooltip programmatically. This method returns a promise that resolves after the `zn-after-show` event is emitted.
443
+
444
+ ```html:preview
445
+ <zn-button id="show-method-btn">Show Tooltip Programmatically</zn-button>
446
+
447
+ <zn-tooltip content="Programmatically shown!" trigger="manual" class="show-method-tooltip">
448
+ <zn-icon src="info" size="24"></zn-icon>
449
+ </zn-tooltip>
450
+
451
+ <script>
452
+ const showBtn = document.getElementById('show-method-btn');
453
+ const showTooltip = document.querySelector('.show-method-tooltip');
454
+
455
+ showBtn.addEventListener('click', async () => {
456
+ await showTooltip.show();
457
+ console.log('Tooltip is now visible');
458
+
459
+ // Automatically hide after 3 seconds
460
+ setTimeout(() => {
461
+ showTooltip.hide();
462
+ }, 3000);
463
+ });
464
+ </script>
465
+ ```
466
+
467
+ ### Hide Method
468
+
469
+ Call the `hide()` method to hide the tooltip programmatically.
470
+
471
+ ```html:preview
472
+ <div style="display: flex; gap: 1rem; align-items: center;">
473
+ <zn-button id="toggle-show-btn">Show</zn-button>
474
+ <zn-button id="toggle-hide-btn" color="error">Hide</zn-button>
475
+
476
+ <zn-tooltip content="Control me with buttons!" trigger="manual" class="hide-method-tooltip">
477
+ <zn-icon src="star" size="32"></zn-icon>
478
+ </zn-tooltip>
479
+ </div>
480
+
481
+ <script>
482
+ const hideTooltip = document.querySelector('.hide-method-tooltip');
483
+ const showMethodBtn = document.getElementById('toggle-show-btn');
484
+ const hideMethodBtn = document.getElementById('toggle-hide-btn');
485
+
486
+ showMethodBtn.addEventListener('click', () => {
487
+ hideTooltip.show();
488
+ });
489
+
490
+ hideMethodBtn.addEventListener('click', () => {
491
+ hideTooltip.hide();
492
+ });
493
+ </script>
494
+ ```
495
+
496
+ ## Slots
497
+
498
+ Tooltips provide slots for customizing content and defining the anchor element.
499
+
500
+ ### Default Slot (Content)
501
+
502
+ The default slot or the `content` slot can be used to add content to the tooltip. Use the slot for HTML content and the `content` attribute for simple text.
503
+
504
+ ```html:preview
505
+ <zn-tooltip>
506
+ <div slot="content">
507
+ <strong>Rich Content</strong>
508
+ <p style="margin: 0.25rem 0 0 0;">This tooltip contains <em>formatted</em> text!</p>
509
+ </div>
510
+ <zn-button>Rich Tooltip</zn-button>
511
+ </zn-tooltip>
512
+ ```
513
+
514
+ ### Anchor Slot
515
+
516
+ The anchor slot (default unnamed slot) defines the element that triggers the tooltip. This should be a single element.
517
+
518
+ ```html:preview
519
+ <zn-tooltip content="I'm anchored to this icon">
520
+ <zn-icon src="help_outline" size="32"></zn-icon>
521
+ </zn-tooltip>
522
+
523
+ <zn-tooltip content="I'm anchored to this input" style="margin-left: 2rem;">
524
+ <zn-input placeholder="Hover over me"></zn-input>
525
+ </zn-tooltip>
526
+ ```
527
+
528
+ ### Complex Anchor
529
+
530
+ When you need multiple elements as the anchor, wrap them in a container.
531
+
532
+ ```html:preview
533
+ <zn-tooltip content="This tooltip anchors to the entire group">
534
+ <div style="display: flex; gap: 0.5rem; align-items: center;">
535
+ <zn-icon src="account_circle" size="24"></zn-icon>
536
+ <span>John Doe</span>
537
+ <zn-icon src="verified" size="20"></zn-icon>
538
+ </div>
539
+ </zn-tooltip>
540
+ ```
541
+
542
+ ## CSS Custom Properties
543
+
544
+ Tooltips can be customized using CSS custom properties.
545
+
546
+ ### Arrow Size
547
+
548
+ Control the size of the tooltip arrow using the `--zn-tooltip-arrow-size` custom property.
549
+
550
+ ```html:preview
551
+ <div style="display: flex; gap: 1rem;">
552
+ <zn-tooltip content="Default arrow">
553
+ <zn-button>Default</zn-button>
554
+ </zn-tooltip>
555
+
556
+ <zn-tooltip content="Large arrow" style="--zn-tooltip-arrow-size: 12px;">
557
+ <zn-button>Large Arrow</zn-button>
558
+ </zn-tooltip>
559
+
560
+ <zn-tooltip content="Extra large arrow" style="--zn-tooltip-arrow-size: 16px;">
561
+ <zn-button>XL Arrow</zn-button>
562
+ </zn-tooltip>
563
+ </div>
564
+ ```
565
+
566
+ ### Background and Text Color
567
+
568
+ Customize the tooltip appearance with CSS custom properties.
569
+
570
+ ```html:preview
571
+ <div style="display: flex; gap: 1rem;">
572
+ <zn-tooltip
573
+ content="Custom styled tooltip"
574
+ style="
575
+ --zn-tooltip-background-color: var(--zn-color-success-600);
576
+ --zn-tooltip-color: white;
577
+ ">
578
+ <zn-button color="success">Success Style</zn-button>
579
+ </zn-tooltip>
580
+
581
+ <zn-tooltip
582
+ content="Error tooltip"
583
+ style="
584
+ --zn-tooltip-background-color: var(--zn-color-error-600);
585
+ --zn-tooltip-color: white;
586
+ ">
587
+ <zn-button color="error">Error Style</zn-button>
588
+ </zn-tooltip>
589
+ </div>
590
+ ```
591
+
592
+ ## Accessibility
593
+
594
+ Tooltips are built with accessibility in mind:
595
+
596
+ - The tooltip uses `role="tooltip"` for proper semantics
597
+ - The tooltip content has `aria-live="polite"` when open to announce changes to screen readers
598
+ - Keyboard navigation is supported with Escape key to dismiss
599
+ - Focus management works with the `focus` trigger option
600
+
601
+ ### Keyboard Support
602
+
603
+ When a tooltip is open, you can press the `Escape` key to hide it.
604
+
605
+ ```html:preview
606
+ <zn-tooltip content="Press Escape to close" trigger="click">
607
+ <zn-button>Click me, then press Escape</zn-button>
608
+ </zn-tooltip>
242
609
  ```
@@ -0,0 +1,210 @@
1
+ ---
2
+ meta:
3
+ title: Translation Group
4
+ description: A panel-styled container that provides a shared language toggle for multiple translation inputs.
5
+ layout: component
6
+ ---
7
+
8
+ The Translation Group component wraps multiple `zn-translations` components in a panel-styled container with a shared
9
+ language toggle. A button group in the top right lets users switch between languages, controlling all child translation
10
+ inputs simultaneously.
11
+
12
+ ```html:preview
13
+ <zn-translation-group
14
+ label="Product Content"
15
+ languages='{"en":"English","fr":"French","de":"German"}'>
16
+ <zn-translations
17
+ label="Name"
18
+ name="name"
19
+ values='{"en":"Wireless Headphones","fr":"Écouteurs sans fil","de":"Kabellose Kopfhörer"}'
20
+ ></zn-translations>
21
+ <zn-translations
22
+ label="Description"
23
+ name="description"
24
+ values='{"en":"Premium noise-cancelling headphones","fr":"Écouteurs antibruit premium","de":"Premium-Kopfhörer mit Geräuschunterdrückung"}'
25
+ ></zn-translations>
26
+ </zn-translation-group>
27
+ ```
28
+
29
+ ## Examples
30
+
31
+ ### Basic Usage
32
+
33
+ A translation group with two translation inputs sharing one language button group.
34
+
35
+ ```html:preview
36
+ <zn-translation-group languages='{"en":"English","fr":"French"}'>
37
+ <zn-translations label="Title" name="title"></zn-translations>
38
+ <zn-translations label="Subtitle" name="subtitle"></zn-translations>
39
+ </zn-translation-group>
40
+ ```
41
+
42
+ ### With Label
43
+
44
+ Use the `label` attribute to add a descriptive label in the panel header, displayed on the left side alongside the language toggle.
45
+
46
+ ```html:preview
47
+ <zn-translation-group
48
+ label="Page Translations"
49
+ languages='{"en":"English","fr":"French","es":"Spanish"}'>
50
+ <zn-translations label="Heading" name="heading"></zn-translations>
51
+ <zn-translations label="Body" name="body"></zn-translations>
52
+ </zn-translation-group>
53
+ ```
54
+
55
+ ### Pre-filled Values
56
+
57
+ Set initial translations on each child. The group automatically collects all language codes from children and displays
58
+ them as buttons in the toggle group.
59
+
60
+ ```html:preview
61
+ <zn-translation-group
62
+ label="Notification Templates"
63
+ languages='{"en":"English","fr":"French","de":"German","es":"Spanish"}'>
64
+ <zn-translations
65
+ label="Subject"
66
+ name="subject"
67
+ values='{"en":"Welcome aboard!","fr":"Bienvenue !","de":"Willkommen!","es":"Bienvenido!"}'
68
+ ></zn-translations>
69
+ <zn-translations
70
+ label="Preview Text"
71
+ name="preview"
72
+ values='{"en":"Get started with your account","fr":"Commencez avec votre compte","de":"Starten Sie mit Ihrem Konto","es":"Comience con su cuenta"}'
73
+ ></zn-translations>
74
+ </zn-translation-group>
75
+ ```
76
+
77
+ ### Many Fields
78
+
79
+ The group scales well with multiple translation inputs under a single toggle.
80
+
81
+ ```html:preview
82
+ <zn-translation-group
83
+ label="SEO Metadata"
84
+ languages='{"en":"English","fr":"French","de":"German"}'>
85
+ <zn-translations label="Page Title" name="seo-title"></zn-translations>
86
+ <zn-translations label="Meta Description" name="seo-description"></zn-translations>
87
+ <zn-translations label="Open Graph Title" name="og-title"></zn-translations>
88
+ <zn-translations label="Open Graph Description" name="og-description"></zn-translations>
89
+ </zn-translation-group>
90
+ ```
91
+
92
+ ### Flush Layout
93
+
94
+ Remove body padding for a more compact appearance using the `flush` attribute.
95
+
96
+ ```html:preview
97
+ <zn-translation-group
98
+ flush
99
+ label="Compact Translations"
100
+ languages='{"en":"English","fr":"French"}'>
101
+ <zn-translations label="Label" name="label"></zn-translations>
102
+ <zn-translations label="Placeholder" name="placeholder"></zn-translations>
103
+ </zn-translation-group>
104
+ ```
105
+
106
+ ### Listening to Language Changes
107
+
108
+ The group emits a `zn-language-change` event when the active language changes.
109
+
110
+ ```html:preview
111
+ <zn-translation-group
112
+ id="group-events"
113
+ label="Event Demo"
114
+ languages='{"en":"English","fr":"French","de":"German"}'>
115
+ <zn-translations label="Title" name="title"></zn-translations>
116
+ <zn-translations label="Description" name="description"></zn-translations>
117
+ </zn-translation-group>
118
+
119
+ <div style="margin-top: 1rem; padding: 1rem; background: var(--zn-color-neutral-50); border-radius: 4px;">
120
+ <strong>Active Language:</strong>
121
+ <span id="active-lang" style="font-family: monospace;">en</span>
122
+ </div>
123
+
124
+ <script type="module">
125
+ const group = document.getElementById('group-events');
126
+ const display = document.getElementById('active-lang');
127
+
128
+ group.addEventListener('zn-language-change', (event) => {
129
+ display.textContent = event.detail.language;
130
+ });
131
+ </script>
132
+ ```
133
+
134
+ ### Real-World Use Case: Product Content Management
135
+
136
+ A complete example showing how the translation group simplifies a product editing form.
137
+
138
+ ```html:preview
139
+ <div style="max-width: 800px;">
140
+ <zn-panel caption="Product Details" icon="inventory_2">
141
+ <div style="display: flex; flex-direction: column; gap: 1rem;">
142
+ <zn-input
143
+ label="Product SKU"
144
+ value="PROD-12345"
145
+ readonly
146
+ ></zn-input>
147
+
148
+ <zn-translation-group
149
+ label="Translatable Content"
150
+ languages='{"en":"English","fr":"French","de":"German","es":"Spanish"}'>
151
+ <zn-translations
152
+ name="name"
153
+ label="Product Name"
154
+ values='{"en":"Premium Wireless Headphones","fr":"Écouteurs sans fil premium","de":"Premium kabellose Kopfhörer","es":"Auriculares inalámbricos premium"}'
155
+ ></zn-translations>
156
+ <zn-translations
157
+ name="short-description"
158
+ label="Short Description"
159
+ values='{"en":"High-quality wireless audio","fr":"Audio sans fil haute qualité","de":"Hochwertiges kabelloses Audio","es":"Audio inalámbrico de alta calidad"}'
160
+ ></zn-translations>
161
+ <zn-translations
162
+ name="description"
163
+ label="Full Description"
164
+ values='{"en":"Experience premium sound with active noise cancellation","fr":"Découvrez un son premium avec suppression active du bruit","de":"Erleben Sie Premium-Sound mit aktiver Geräuschunterdrückung","es":"Experimente sonido premium con cancelación activa de ruido"}'
165
+ ></zn-translations>
166
+ </zn-translation-group>
167
+
168
+ <zn-input
169
+ label="Price"
170
+ type="currency"
171
+ value="299.99"
172
+ ></zn-input>
173
+ </div>
174
+
175
+ <div slot="footer" style="display: flex; gap: 0.5rem; justify-content: flex-end;">
176
+ <zn-button color="secondary">Cancel</zn-button>
177
+ <zn-button color="success">Save Product</zn-button>
178
+ </div>
179
+ </zn-panel>
180
+ </div>
181
+ ```
182
+
183
+ ## Properties
184
+
185
+ | Property | Type | Default | Description |
186
+ |-------------|--------------------------|--------------|--------------------------------------------------------|
187
+ | `label` | `string` | `''` | Label displayed in the panel header |
188
+ | `languages` | `Record<string, string>` | `{en: "EN"}` | Object mapping language codes to display names |
189
+ | `flush` | `boolean` | `false` | Removes body padding for compact layout |
190
+
191
+ ## Events
192
+
193
+ | Event | Description | Event Detail |
194
+ |----------------------|------------------------------------------|------------------------|
195
+ | `zn-language-change` | Emitted when the active language changes | `{ language: string }` |
196
+
197
+ ## Slots
198
+
199
+ | Slot | Description |
200
+ |-----------|------------------------------------------------------------|
201
+ | (default) | Place `<zn-translations>` elements here |
202
+ | `label` | Alternative to the `label` attribute for rich HTML content |
203
+
204
+ ## CSS Parts
205
+
206
+ | Part | Description |
207
+ |----------------|---------------------------------------------------------|
208
+ | `base` | The outer panel wrapper |
209
+ | `header` | The header area containing the label and language toggle |
210
+ | `translations` | The body container wrapping the slotted children |