@kubex/zinc 1.0.25 → 1.0.98

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 (198) 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 +13431 -8728
  4. package/dist/vscode.html-custom-data.json +571 -37
  5. package/dist/web-types.json +1439 -181
  6. package/dist/zn.d.ts +1642 -661
  7. package/dist/zn.min.css +1 -1
  8. package/dist/zn.min.js +1406 -891
  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/key-container.md +115 -0
  51. package/docs/pages/components/key.md +101 -0
  52. package/docs/pages/components/menu.md +512 -6
  53. package/docs/pages/components/note.md +239 -36
  54. package/docs/pages/components/opt-group.md +107 -0
  55. package/docs/pages/components/pagination.md +332 -6
  56. package/docs/pages/components/pane.md +222 -6
  57. package/docs/pages/components/panel.md +213 -26
  58. package/docs/pages/components/popup.md +1354 -6
  59. package/docs/pages/components/priority-list.md +233 -0
  60. package/docs/pages/components/progress-bar.md +387 -6
  61. package/docs/pages/components/radio-group.md +242 -5
  62. package/docs/pages/components/radio.md +474 -6
  63. package/docs/pages/components/rating.md +331 -7
  64. package/docs/pages/components/reveal.md +524 -6
  65. package/docs/pages/components/scroll-container.md +552 -6
  66. package/docs/pages/components/select.md +762 -160
  67. package/docs/pages/components/skeleton.md +473 -30
  68. package/docs/pages/components/slideout.md +261 -5
  69. package/docs/pages/components/sp.md +99 -41
  70. package/docs/pages/components/split-button.md +347 -9
  71. package/docs/pages/components/split-pane.md +445 -6
  72. package/docs/pages/components/stat.md +549 -9
  73. package/docs/pages/components/status-indicator.md +230 -1
  74. package/docs/pages/components/stepper.md +563 -6
  75. package/docs/pages/components/tabs.md +439 -13
  76. package/docs/pages/components/textarea.md +415 -17
  77. package/docs/pages/components/tile.md +385 -26
  78. package/docs/pages/components/toggle.md +424 -6
  79. package/docs/pages/components/tooltip.md +367 -0
  80. package/docs/pages/components/translation-group.md +210 -0
  81. package/docs/pages/components/translations.md +319 -19
  82. package/docs/pages/components/vertical-stepper.md +401 -8
  83. package/docs/pages/components/well.md +300 -3
  84. package/docs/pages/getting-started/form-controls.md +162 -0
  85. package/docs/pages/index.md +116 -15
  86. package/package.json +5 -6
  87. package/scss/_global-spacing.scss +4 -0
  88. package/scss/_root.scss +2 -2
  89. package/scss/boot.scss +19 -0
  90. package/scss/shared/layout.scss +5 -0
  91. package/scss/themes/_light.scss +3 -3
  92. package/src/components/alert/alert.scss +1 -0
  93. package/src/components/animated-button/README.md +306 -0
  94. package/src/components/animated-button/animated-button.component.ts +229 -0
  95. package/src/components/animated-button/animated-button.scss +228 -0
  96. package/src/components/animated-button/animated-button.test.ts +143 -0
  97. package/src/components/animated-button/index.ts +12 -0
  98. package/src/components/button/button.component.ts +5 -0
  99. package/src/components/button-group/button-group.component.ts +25 -13
  100. package/src/components/button-group/button-group.scss +6 -0
  101. package/src/components/checkbox/checkbox.component.ts +4 -0
  102. package/src/components/checkbox/checkbox.scss +7 -4
  103. package/src/components/checkbox-group/checkbox-group.scss +7 -0
  104. package/src/components/chip/chip.component.ts +7 -2
  105. package/src/components/chip/chip.scss +16 -2
  106. package/src/components/collapsible/collapsible.component.ts +27 -20
  107. package/src/components/cols/cols.component.ts +14 -2
  108. package/src/components/cols/cols.scss +6 -12
  109. package/src/components/confirm/confirm.component.ts +7 -0
  110. package/src/components/copy-button/copy-button.component.ts +12 -11
  111. package/src/components/data-select/data-select.component.ts +215 -44
  112. package/src/components/data-select/data-select.scss +66 -6
  113. package/src/components/data-select/providers/currency-data-provider.ts +20 -6
  114. package/src/components/data-select/providers/provider.ts +1 -0
  115. package/src/components/data-select/providers/us-state-data-provider.ts +68 -0
  116. package/src/components/data-table/data-table.component.ts +81 -22
  117. package/src/components/data-table-search/data-table-search.component.ts +184 -0
  118. package/src/components/data-table-search/data-table-search.scss +17 -0
  119. package/src/components/data-table-search/data-table-search.test.ts +11 -0
  120. package/src/components/data-table-search/index.ts +12 -0
  121. package/src/components/datepicker/datepicker.component.ts +347 -13
  122. package/src/components/dialog/dialog.component.ts +1 -1
  123. package/src/components/empty-state/empty-state.scss +6 -1
  124. package/src/components/header/header.scss +3 -3
  125. package/src/components/icon/icon.component.ts +23 -1
  126. package/src/components/icon/icon.scss +23 -0
  127. package/src/components/icon-picker/brand-icons.ts +24 -0
  128. package/src/components/icon-picker/icon-picker.component.ts +407 -0
  129. package/src/components/icon-picker/icon-picker.scss +205 -0
  130. package/src/components/icon-picker/index.ts +12 -0
  131. package/src/components/icon-picker/line-icons.ts +612 -0
  132. package/src/components/icon-picker/material-icons.ts +14543 -0
  133. package/src/components/inline-edit/inline-edit.component.ts +190 -46
  134. package/src/components/inline-edit/inline-edit.scss +29 -0
  135. package/src/components/inline-edit/inline-edit.test.ts +314 -1
  136. package/src/components/input/input.component.ts +324 -5
  137. package/src/components/input/input.scss +87 -0
  138. package/src/components/input-group/input-group.component.ts +28 -7
  139. package/src/components/input-group/input-group.scss +48 -10
  140. package/src/components/item/item.component.ts +11 -2
  141. package/src/components/item/item.scss +7 -0
  142. package/src/components/key/index.ts +12 -0
  143. package/src/components/key/key.component.ts +47 -0
  144. package/src/components/key/key.scss +38 -0
  145. package/src/components/key-container/index.ts +12 -0
  146. package/src/components/key-container/key-container.component.ts +142 -0
  147. package/src/components/key-container/key-container.scss +33 -0
  148. package/src/components/menu-item/menu-item.component.ts +20 -0
  149. package/src/components/menu-item/menu-item.scss +69 -2
  150. package/src/components/navbar/navbar.component.ts +103 -11
  151. package/src/components/navbar/navbar.scss +6 -1
  152. package/src/components/opt-group/index.ts +12 -0
  153. package/src/components/opt-group/opt-group.component.ts +74 -0
  154. package/src/components/opt-group/opt-group.scss +37 -0
  155. package/src/components/opt-group/opt-group.test.ts +27 -0
  156. package/src/components/option/option.component.ts +1 -16
  157. package/src/components/option/option.scss +4 -0
  158. package/src/components/panel/panel.component.ts +10 -8
  159. package/src/components/panel/panel.scss +20 -0
  160. package/src/components/priority-list/index.ts +12 -0
  161. package/src/components/priority-list/priority-list.component.ts +611 -0
  162. package/src/components/priority-list/priority-list.scss +185 -0
  163. package/src/components/priority-list/priority-list.test.ts +139 -0
  164. package/src/components/progress-bar/progress-bar.component.ts +22 -16
  165. package/src/components/radio/radio.scss +10 -3
  166. package/src/components/select/select.component.ts +812 -72
  167. package/src/components/select/select.scss +108 -2
  168. package/src/components/select/select.test.ts +147 -2
  169. package/src/components/settings-container/settings-container.component.ts +44 -19
  170. package/src/components/settings-container/settings-container.scss +1 -1
  171. package/src/components/skeleton/skeleton.component.ts +6 -1
  172. package/src/components/slideout/slideout.scss +8 -3
  173. package/src/components/sp/sp.component.ts +3 -1
  174. package/src/components/sp/sp.scss +19 -0
  175. package/src/components/stepper/stepper.component.ts +16 -10
  176. package/src/components/textarea/textarea.scss +0 -4
  177. package/src/components/tile/tile.component.ts +12 -3
  178. package/src/components/tile/tile.scss +1 -1
  179. package/src/components/timer/timer.component.ts +15 -2
  180. package/src/components/toggle/toggle.component.ts +29 -26
  181. package/src/components/toggle/toggle.scss +13 -1
  182. package/src/components/translation-group/index.ts +12 -0
  183. package/src/components/translation-group/translation-group.component.ts +207 -0
  184. package/src/components/translation-group/translation-group.scss +8 -0
  185. package/src/components/translations/translations.component.ts +90 -44
  186. package/src/components/translations/translations.scss +4 -0
  187. package/src/components/vertical-stepper/vertical-stepper.component.ts +14 -9
  188. package/src/events/events.ts +12 -7
  189. package/src/events/zn-language-change.ts +7 -0
  190. package/src/events/zn-purchase.ts +11 -0
  191. package/src/events/zn-redirect.ts +7 -0
  192. package/src/events/zn-reorder.ts +7 -0
  193. package/src/events/zn-search-change.ts +11 -0
  194. package/src/events/zn-submit.ts +1 -1
  195. package/src/form-control.scss +4 -0
  196. package/src/internal/form-navigation.ts +510 -0
  197. package/src/internal/form.ts +6 -0
  198. package/src/zinc.ts +91 -83
@@ -0,0 +1,101 @@
1
+ ---
2
+ meta:
3
+ title: Key
4
+ description: A legend key item, typically used alongside charts to label and toggle visibility of data series by category.
5
+ layout: component
6
+ ---
7
+
8
+ ```html:preview
9
+ <div style="display: flex; flex-direction: column; gap: 8px;">
10
+ <zn-key icon="circle" color="primary" active>Primary active</zn-key>
11
+ <zn-key icon="circle" color="success">Success inactive</zn-key>
12
+ <zn-key icon="circle" color="warning" active>Warning active</zn-key>
13
+ </div>
14
+ ```
15
+
16
+ ## Examples
17
+
18
+ ### Basic Key
19
+
20
+ A key displays a chip alongside a description. Clicking it toggles the active state.
21
+
22
+ ```html:preview
23
+ <zn-key icon="circle" color="primary">Sales</zn-key>
24
+ ```
25
+
26
+ ### Active State
27
+
28
+ Use the `active` attribute to set the key as active by default. When active, the chip displays the assigned color; when inactive, it appears transparent.
29
+
30
+ ```html:preview
31
+ <zn-key icon="circle" color="primary" active>Active key</zn-key>
32
+ <zn-key icon="circle" color="primary">Inactive key</zn-key>
33
+ ```
34
+
35
+ ### Colors
36
+
37
+ Use the `color` attribute to set the semantic color of the key chip. Available colors are `primary`, `success`, `warning`, `error`, `info`, and `neutral`.
38
+
39
+ ```html:preview
40
+ <div style="display: flex; flex-direction: column; gap: 8px;">
41
+ <zn-key icon="circle" color="primary" active>Primary</zn-key>
42
+ <zn-key icon="circle" color="success" active>Success</zn-key>
43
+ <zn-key icon="circle" color="warning" active>Warning</zn-key>
44
+ <zn-key icon="circle" color="error" active>Error</zn-key>
45
+ <zn-key icon="circle" color="info" active>Info</zn-key>
46
+ <zn-key icon="circle" color="neutral" active>Neutral</zn-key>
47
+ </div>
48
+ ```
49
+
50
+ ### Icons
51
+
52
+ Use the `icon` attribute to set the icon displayed in the chip.
53
+
54
+ ```html:preview
55
+ <div style="display: flex; flex-direction: column; gap: 8px;">
56
+ <zn-key icon="payments" color="success" active>Revenue</zn-key>
57
+ <zn-key icon="shopping_cart" color="primary" active>Orders</zn-key>
58
+ <zn-key icon="person" color="info" active>Customers</zn-key>
59
+ </div>
60
+ ```
61
+
62
+ ### Icon Size
63
+
64
+ Use the `icon-size` attribute to control the size of the icon within the chip.
65
+
66
+ ```html:preview
67
+ <div style="display: flex; flex-direction: column; gap: 8px;">
68
+ <zn-key icon="circle" color="primary" icon-size="14" active>Small icon</zn-key>
69
+ <zn-key icon="circle" color="primary" active>Default icon (24)</zn-key>
70
+ <zn-key icon="circle" color="primary" icon-size="32" active>Large icon</zn-key>
71
+ </div>
72
+ ```
73
+
74
+ ### Filtering Attributes
75
+
76
+ Use the `attribute` and `value` attributes to define what content this key filters. These are used by `zn-key-container` to match items.
77
+
78
+ ```html:preview
79
+ <zn-key icon="circle" color="primary" attribute="data-type" value="sale" active>Sales</zn-key>
80
+ <zn-key icon="circle" color="error" attribute="data-type" value="refund" active>Refunds</zn-key>
81
+ ```
82
+
83
+ ### Events
84
+
85
+ Keys emit a `zn-change` event when toggled.
86
+
87
+ ```html:preview
88
+ <zn-key id="event-key" icon="circle" color="primary" active>Click me</zn-key>
89
+ <div id="key-output" style="margin-top: 1rem; padding: 0.75rem; background: #f5f5f5; border-radius: 4px;">
90
+ Click the key to toggle it
91
+ </div>
92
+
93
+ <script type="module">
94
+ const key = document.querySelector('#event-key');
95
+ const output = document.querySelector('#key-output');
96
+
97
+ key.addEventListener('zn-change', () => {
98
+ output.textContent = `Key is now: ${key.active ? 'active' : 'inactive'}`;
99
+ });
100
+ </script>
101
+ ```
@@ -1,12 +1,11 @@
1
1
  ---
2
2
  meta:
3
3
  title: Menu
4
- description:
4
+ description: Menus provide a list of options for the user to choose from.
5
5
  layout: component
6
6
  ---
7
7
 
8
8
  ```html:preview
9
-
10
9
  <zn-menu>
11
10
  <zn-menu-item>Menu Item 1</zn-menu-item>
12
11
  <zn-menu-item>Menu Item 2</zn-menu-item>
@@ -23,14 +22,521 @@ layout: component
23
22
  </zn-menu>
24
23
  ```
25
24
 
25
+ Menus are typically used in combination with dropdowns to display a list of actions or options. They support keyboard navigation, submenus, icons, checkboxes, disabled items, and more.
26
+
26
27
  ## Examples
27
28
 
28
- ### First Example
29
+ ### Basic Menu
30
+
31
+ A basic menu with simple text items.
32
+
33
+ ```html:preview
34
+ <zn-menu>
35
+ <zn-menu-item>Cut</zn-menu-item>
36
+ <zn-menu-item>Copy</zn-menu-item>
37
+ <zn-menu-item>Paste</zn-menu-item>
38
+ </zn-menu>
39
+ ```
40
+
41
+ ### Menu with Dropdown
42
+
43
+ Menus are commonly used inside dropdowns to create action menus or context menus.
44
+
45
+ ```html:preview
46
+ <zn-dropdown placement="bottom-start">
47
+ <zn-button slot="trigger" caret>Actions</zn-button>
48
+ <zn-menu>
49
+ <zn-menu-item>Edit</zn-menu-item>
50
+ <zn-menu-item>Duplicate</zn-menu-item>
51
+ <zn-menu-item>Archive</zn-menu-item>
52
+ <zn-menu-item>Delete</zn-menu-item>
53
+ </zn-menu>
54
+ </zn-dropdown>
55
+ ```
56
+
57
+ ### Menu Items with Icons
58
+
59
+ Use the `prefix` slot to add icons to menu items.
60
+
61
+ ```html:preview
62
+ <zn-menu>
63
+ <zn-menu-item>
64
+ <zn-icon slot="prefix" src="edit" size="20"></zn-icon>
65
+ Edit
66
+ </zn-menu-item>
67
+ <zn-menu-item>
68
+ <zn-icon slot="prefix" src="content_copy" size="20"></zn-icon>
69
+ Copy
70
+ </zn-menu-item>
71
+ <zn-menu-item>
72
+ <zn-icon slot="prefix" src="content_paste" size="20"></zn-icon>
73
+ Paste
74
+ </zn-menu-item>
75
+ <zn-menu-item>
76
+ <zn-icon slot="prefix" src="delete" size="20"></zn-icon>
77
+ Delete
78
+ </zn-menu-item>
79
+ </zn-menu>
80
+ ```
81
+
82
+ ### Menu Items with Value
83
+
84
+ Use the `value` attribute to associate a value with each menu item. This is useful for identifying which item was selected.
85
+
86
+ ```html:preview
87
+ <zn-dropdown placement="bottom-start">
88
+ <zn-button slot="trigger" caret>Select Action</zn-button>
89
+ <zn-menu id="value-menu">
90
+ <zn-menu-item value="edit">Edit</zn-menu-item>
91
+ <zn-menu-item value="copy">Copy</zn-menu-item>
92
+ <zn-menu-item value="delete">Delete</zn-menu-item>
93
+ </zn-menu>
94
+ </zn-dropdown>
95
+
96
+ <div id="value-output" style="margin-top: 1rem; padding: 1rem; background: #f5f5f5; border-radius: 4px;">
97
+ <strong>Last selected:</strong> <span id="selected-value">None</span>
98
+ </div>
99
+
100
+ <script type="module">
101
+ const menu = document.querySelector('#value-menu');
102
+ const output = document.querySelector('#selected-value');
103
+
104
+ menu.addEventListener('zn-select', (event) => {
105
+ output.textContent = event.detail.item.value;
106
+ });
107
+ </script>
108
+ ```
109
+
110
+ ### Disabled Menu Items
111
+
112
+ Use the `disabled` attribute to disable menu items.
113
+
114
+ ```html:preview
115
+ <zn-menu>
116
+ <zn-menu-item>Enabled Item</zn-menu-item>
117
+ <zn-menu-item disabled>Disabled Item</zn-menu-item>
118
+ <zn-menu-item>Another Enabled Item</zn-menu-item>
119
+ <zn-menu-item disabled>Another Disabled Item</zn-menu-item>
120
+ </zn-menu>
121
+ ```
122
+
123
+ ### Checkbox Menu Items
124
+
125
+ Use `type="checkbox"` to create checkbox menu items. Use the `checked` attribute to set the initial state.
126
+
127
+ ```html:preview
128
+ <zn-menu id="checkbox-menu">
129
+ <zn-menu-item type="checkbox" checked>Bold</zn-menu-item>
130
+ <zn-menu-item type="checkbox">Italic</zn-menu-item>
131
+ <zn-menu-item type="checkbox">Underline</zn-menu-item>
132
+ <zn-menu-item type="checkbox" checked>Strikethrough</zn-menu-item>
133
+ </zn-menu>
134
+
135
+ <script type="module">
136
+ const menu = document.querySelector('#checkbox-menu');
137
+
138
+ menu.addEventListener('zn-select', (event) => {
139
+ const item = event.detail.item;
140
+ console.log(`${item.getTextLabel()}: ${item.checked ? 'checked' : 'unchecked'}`);
141
+ });
142
+ </script>
143
+ ```
144
+
145
+ ### Checkbox Position
146
+
147
+ Use the `checked-position` attribute to control where the checkbox icon appears. The default is `left`, but you can set it to `right`.
148
+
149
+ ```html:preview
150
+ <zn-menu>
151
+ <zn-menu-item type="checkbox" checked checked-position="left">Left Position (default)</zn-menu-item>
152
+ <zn-menu-item type="checkbox" checked checked-position="right">Right Position</zn-menu-item>
153
+ </zn-menu>
154
+ ```
155
+
156
+ ### Menu Items with Links
157
+
158
+ Menu items can function as links by using the `href` attribute. Use `target` to control where the link opens.
159
+
160
+ ```html:preview
161
+ <zn-menu>
162
+ <zn-menu-item href="https://example.com">
163
+ <zn-icon slot="prefix" src="link" size="20"></zn-icon>
164
+ Open Example
165
+ </zn-menu-item>
166
+ <zn-menu-item href="https://github.com" target="_blank">
167
+ <zn-icon slot="prefix" src="open_in_new" size="20"></zn-icon>
168
+ Open in New Tab
169
+ </zn-menu-item>
170
+ </zn-menu>
171
+ ```
172
+
173
+ ### Submenus
174
+
175
+ Menu items can contain submenus. Hover over or navigate to a menu item with a submenu to expand it. Submenus support the same features as regular menus.
176
+
177
+ ```html:preview
178
+ <zn-menu>
179
+ <zn-menu-item>New File</zn-menu-item>
180
+ <zn-menu-item>Open File</zn-menu-item>
181
+ <zn-menu-item>
182
+ Recent Files
183
+ <zn-menu slot="submenu">
184
+ <zn-menu-item>document1.txt</zn-menu-item>
185
+ <zn-menu-item>document2.txt</zn-menu-item>
186
+ <zn-menu-item>document3.txt</zn-menu-item>
187
+ </zn-menu>
188
+ </zn-menu-item>
189
+ <zn-menu-item>Save File</zn-menu-item>
190
+ </zn-menu>
191
+ ```
192
+
193
+ ### Nested Submenus
194
+
195
+ Submenus can be nested multiple levels deep.
196
+
197
+ ```html:preview
198
+ <zn-menu>
199
+ <zn-menu-item>File</zn-menu-item>
200
+ <zn-menu-item>
201
+ Edit
202
+ <zn-menu slot="submenu">
203
+ <zn-menu-item>Undo</zn-menu-item>
204
+ <zn-menu-item>Redo</zn-menu-item>
205
+ <zn-menu-item>
206
+ Find
207
+ <zn-menu slot="submenu">
208
+ <zn-menu-item>Find in File</zn-menu-item>
209
+ <zn-menu-item>Find in Project</zn-menu-item>
210
+ <zn-menu-item>
211
+ Replace
212
+ <zn-menu slot="submenu">
213
+ <zn-menu-item>Replace in File</zn-menu-item>
214
+ <zn-menu-item>Replace in Project</zn-menu-item>
215
+ </zn-menu>
216
+ </zn-menu-item>
217
+ </zn-menu>
218
+ </zn-menu-item>
219
+ </zn-menu>
220
+ </zn-menu-item>
221
+ <zn-menu-item>View</zn-menu-item>
222
+ </zn-menu>
223
+ ```
224
+
225
+ ### Loading State
226
+
227
+ Use the `loading` attribute to show a loading state on menu items.
228
+
229
+ ```html:preview
230
+ <zn-menu>
231
+ <zn-menu-item>Regular Item</zn-menu-item>
232
+ <zn-menu-item loading>Loading Item</zn-menu-item>
233
+ <zn-menu-item>Another Item</zn-menu-item>
234
+ </zn-menu>
235
+ ```
236
+
237
+ ### Menu Item Colors
238
+
239
+ Use the `color` attribute to apply semantic colors to menu items.
29
240
 
30
- TODO
241
+ ```html:preview
242
+ <zn-menu>
243
+ <zn-menu-item>Default</zn-menu-item>
244
+ <zn-menu-item color="primary">Primary</zn-menu-item>
245
+ <zn-menu-item color="secondary">Secondary</zn-menu-item>
246
+ <zn-menu-item color="info">Info</zn-menu-item>
247
+ <zn-menu-item color="success">Success</zn-menu-item>
248
+ <zn-menu-item color="warning">Warning</zn-menu-item>
249
+ <zn-menu-item color="error">Error</zn-menu-item>
250
+ </zn-menu>
251
+ ```
252
+
253
+ ### Keyboard Navigation
254
+
255
+ Menus support full keyboard navigation:
256
+
257
+ - **Arrow Up/Down** - Navigate between menu items
258
+ - **Home/End** - Jump to first/last menu item
259
+ - **Enter/Space** - Select the current menu item
260
+ - **Arrow Right** - Open a submenu
261
+ - **Arrow Left** - Close a submenu and return to parent
262
+ - **Escape** - Close the menu
263
+
264
+ ```html:preview
265
+ <zn-dropdown placement="bottom-start">
266
+ <zn-button slot="trigger" caret>Navigate with Keyboard</zn-button>
267
+ <zn-menu>
268
+ <zn-menu-item>
269
+ <zn-icon slot="prefix" src="edit" size="20"></zn-icon>
270
+ Edit
271
+ </zn-menu-item>
272
+ <zn-menu-item>
273
+ <zn-icon slot="prefix" src="content_copy" size="20"></zn-icon>
274
+ Copy
275
+ </zn-menu-item>
276
+ <zn-menu-item>
277
+ More Options
278
+ <zn-menu slot="submenu">
279
+ <zn-menu-item>Option 1</zn-menu-item>
280
+ <zn-menu-item>Option 2</zn-menu-item>
281
+ <zn-menu-item>Option 3</zn-menu-item>
282
+ </zn-menu>
283
+ </zn-menu-item>
284
+ <zn-menu-item disabled>Disabled Item</zn-menu-item>
285
+ <zn-menu-item>
286
+ <zn-icon slot="prefix" src="delete" size="20"></zn-icon>
287
+ Delete
288
+ </zn-menu-item>
289
+ </zn-menu>
290
+ </zn-dropdown>
291
+ ```
292
+
293
+ ### Dividers
294
+
295
+ You can add visual separators between menu items using HTML elements with `role="separator"`.
296
+
297
+ ```html:preview
298
+ <zn-menu>
299
+ <zn-menu-item>Cut</zn-menu-item>
300
+ <zn-menu-item>Copy</zn-menu-item>
301
+ <zn-menu-item>Paste</zn-menu-item>
302
+ <hr style="margin: 0; border: none; border-top: 1px solid rgba(0,0,0,0.1);">
303
+ <zn-menu-item>Select All</zn-menu-item>
304
+ <hr style="margin: 0; border: none; border-top: 1px solid rgba(0,0,0,0.1);">
305
+ <zn-menu-item color="error">Delete</zn-menu-item>
306
+ </zn-menu>
307
+ ```
308
+
309
+ ### Complex Menu with Multiple Features
310
+
311
+ A comprehensive example showing various menu features together.
312
+
313
+ ```html:preview
314
+ <zn-dropdown placement="bottom-start">
315
+ <zn-button slot="trigger" caret>File Options</zn-button>
316
+ <zn-menu id="complex-menu">
317
+ <zn-menu-item value="new">
318
+ <zn-icon slot="prefix" src="add" size="20"></zn-icon>
319
+ New File
320
+ </zn-menu-item>
321
+ <zn-menu-item value="open">
322
+ <zn-icon slot="prefix" src="folder_open" size="20"></zn-icon>
323
+ Open File
324
+ </zn-menu-item>
325
+ <zn-menu-item value="recent">
326
+ Recent Files
327
+ <zn-menu slot="submenu">
328
+ <zn-menu-item value="doc1">document1.txt</zn-menu-item>
329
+ <zn-menu-item value="doc2">document2.txt</zn-menu-item>
330
+ <zn-menu-item value="doc3">document3.txt</zn-menu-item>
331
+ </zn-menu>
332
+ </zn-menu-item>
333
+ <hr style="margin: 0; border: none; border-top: 1px solid rgba(0,0,0,0.1);">
334
+ <zn-menu-item value="save">
335
+ <zn-icon slot="prefix" src="save" size="20"></zn-icon>
336
+ Save
337
+ </zn-menu-item>
338
+ <zn-menu-item value="save-as" disabled>
339
+ <zn-icon slot="prefix" src="save_as" size="20"></zn-icon>
340
+ Save As...
341
+ </zn-menu-item>
342
+ <hr style="margin: 0; border: none; border-top: 1px solid rgba(0,0,0,0.1);">
343
+ <zn-menu-item type="checkbox" value="auto-save" checked>
344
+ Auto Save
345
+ </zn-menu-item>
346
+ <zn-menu-item type="checkbox" value="show-line-numbers">
347
+ Show Line Numbers
348
+ </zn-menu-item>
349
+ <hr style="margin: 0; border: none; border-top: 1px solid rgba(0,0,0,0.1);">
350
+ <zn-menu-item value="export">
351
+ Export
352
+ <zn-menu slot="submenu">
353
+ <zn-menu-item value="pdf">
354
+ <zn-icon slot="prefix" src="picture_as_pdf" size="20"></zn-icon>
355
+ Export as PDF
356
+ </zn-menu-item>
357
+ <zn-menu-item value="html">
358
+ <zn-icon slot="prefix" src="code" size="20"></zn-icon>
359
+ Export as HTML
360
+ </zn-menu-item>
361
+ </zn-menu>
362
+ </zn-menu-item>
363
+ <hr style="margin: 0; border: none; border-top: 1px solid rgba(0,0,0,0.1);">
364
+ <zn-menu-item value="close" color="error">
365
+ <zn-icon slot="prefix" src="close" size="20"></zn-icon>
366
+ Close File
367
+ </zn-menu-item>
368
+ </zn-menu>
369
+ </zn-dropdown>
370
+
371
+ <div id="complex-output" style="margin-top: 1rem; padding: 1rem; background: #f5f5f5; border-radius: 4px;">
372
+ <strong>Last action:</strong> <span id="complex-action">None</span>
373
+ </div>
374
+
375
+ <script type="module">
376
+ const menu = document.querySelector('#complex-menu');
377
+ const output = document.querySelector('#complex-action');
378
+
379
+ menu.addEventListener('zn-select', (event) => {
380
+ const item = event.detail.item;
381
+ output.textContent = `${item.value || 'No value'} - ${item.type === 'checkbox' ? (item.checked ? 'checked' : 'unchecked') : 'selected'}`;
382
+ });
383
+ </script>
384
+ ```
385
+
386
+ ### Events
387
+
388
+ Menus emit the following events:
389
+
390
+ - `zn-select` - Emitted when a menu item is selected. The event detail includes the selected item.
391
+ - `zn-menu-ready` - Emitted when the menu's items have been slotted and the roving tab index is initialized.
392
+
393
+ ```html:preview
394
+ <zn-dropdown placement="bottom-start">
395
+ <zn-button slot="trigger" caret>Actions</zn-button>
396
+ <zn-menu id="event-menu">
397
+ <zn-menu-item value="action1">Action 1</zn-menu-item>
398
+ <zn-menu-item value="action2">Action 2</zn-menu-item>
399
+ <zn-menu-item value="action3">Action 3</zn-menu-item>
400
+ </zn-menu>
401
+ </zn-dropdown>
31
402
 
32
- ### Second Example
403
+ <div id="menu-event-output" style="margin-top: 1rem; padding: 1rem; background: #f5f5f5; border-radius: 4px;">
404
+ <strong>Events:</strong>
405
+ <ul id="menu-event-list" style="margin: 0.5rem 0 0 0; padding-left: 1.5rem;"></ul>
406
+ </div>
33
407
 
34
- TODO
408
+ <script type="module">
409
+ const menu = document.querySelector('#event-menu');
410
+ const eventList = document.querySelector('#menu-event-list');
411
+
412
+ function logEvent(eventName, detail = '') {
413
+ const li = document.createElement('li');
414
+ li.textContent = `${eventName}${detail ? ': ' + detail : ''}`;
415
+ eventList.insertBefore(li, eventList.firstChild);
416
+
417
+ // Keep only last 5 events
418
+ while (eventList.children.length > 5) {
419
+ eventList.removeChild(eventList.lastChild);
420
+ }
421
+ }
422
+
423
+ menu.addEventListener('zn-select', (e) => {
424
+ logEvent('zn-select', `value = ${e.detail.item.value}`);
425
+ });
426
+
427
+ menu.addEventListener('zn-menu-ready', () => {
428
+ logEvent('zn-menu-ready');
429
+ });
430
+ </script>
431
+ ```
432
+
433
+ ### Menu Item Events
434
+
435
+ Individual menu items emit their own events:
436
+
437
+ - `zn-menu-select` - Emitted when the menu item is selected. The event detail includes the item's value and element.
438
+
439
+ ```html:preview
440
+ <zn-dropdown placement="bottom-start">
441
+ <zn-button slot="trigger" caret>Select Item</zn-button>
442
+ <zn-menu>
443
+ <zn-menu-item id="item1" value="first">First Item</zn-menu-item>
444
+ <zn-menu-item id="item2" value="second">Second Item</zn-menu-item>
445
+ <zn-menu-item id="item3" value="third">Third Item</zn-menu-item>
446
+ </zn-menu>
447
+ </zn-dropdown>
448
+
449
+ <div id="item-event-output" style="margin-top: 1rem; padding: 1rem; background: #f5f5f5; border-radius: 4px;">
450
+ <strong>Menu item events:</strong>
451
+ <ul id="item-event-list" style="margin: 0.5rem 0 0 0; padding-left: 1.5rem;"></ul>
452
+ </div>
453
+
454
+ <script type="module">
455
+ const items = document.querySelectorAll('#item1, #item2, #item3');
456
+ const eventList = document.querySelector('#item-event-list');
457
+
458
+ function logEvent(eventName, detail = '') {
459
+ const li = document.createElement('li');
460
+ li.textContent = `${eventName}${detail ? ': ' + detail : ''}`;
461
+ eventList.insertBefore(li, eventList.firstChild);
462
+
463
+ // Keep only last 5 events
464
+ while (eventList.children.length > 5) {
465
+ eventList.removeChild(eventList.lastChild);
466
+ }
467
+ }
468
+
469
+ items.forEach(item => {
470
+ item.addEventListener('zn-menu-select', (e) => {
471
+ logEvent('zn-menu-select', `${item.id}: value = ${e.detail.value}`);
472
+ });
473
+ });
474
+ </script>
475
+ ```
476
+
477
+ ### Suffix Slot
478
+
479
+ Use the `suffix` slot to add content to the right side of menu items, such as keyboard shortcuts or badges.
480
+
481
+ ```html:preview
482
+ <zn-menu>
483
+ <zn-menu-item>
484
+ <zn-icon slot="prefix" src="content_copy" size="20"></zn-icon>
485
+ Copy
486
+ <span slot="suffix" style="opacity: 0.6; font-size: 0.875rem;">Ctrl+C</span>
487
+ </zn-menu-item>
488
+ <zn-menu-item>
489
+ <zn-icon slot="prefix" src="content_cut" size="20"></zn-icon>
490
+ Cut
491
+ <span slot="suffix" style="opacity: 0.6; font-size: 0.875rem;">Ctrl+X</span>
492
+ </zn-menu-item>
493
+ <zn-menu-item>
494
+ <zn-icon slot="prefix" src="content_paste" size="20"></zn-icon>
495
+ Paste
496
+ <span slot="suffix" style="opacity: 0.6; font-size: 0.875rem;">Ctrl+V</span>
497
+ </zn-menu-item>
498
+ </zn-menu>
499
+ ```
500
+
501
+ ### Programmatic Control
502
+
503
+ You can programmatically control menu items using their methods.
504
+
505
+ ```html:preview
506
+ <zn-menu>
507
+ <zn-menu-item id="prog-item1">Item 1</zn-menu-item>
508
+ <zn-menu-item id="prog-item2">Item 2</zn-menu-item>
509
+ <zn-menu-item id="prog-item3">Item 3</zn-menu-item>
510
+ </zn-menu>
511
+
512
+ <div style="margin-top: 1rem;">
513
+ <zn-button id="focus-item2" size="small">Focus Item 2</zn-button>
514
+ <zn-button id="click-item3" size="small" color="info">Click Item 3</zn-button>
515
+ </div>
516
+
517
+ <div id="prog-output" style="margin-top: 1rem; padding: 1rem; background: #f5f5f5; border-radius: 4px;">
518
+ <strong>Status:</strong> <span id="prog-status">Ready</span>
519
+ </div>
520
+
521
+ <script type="module">
522
+ const item2 = document.querySelector('#prog-item2');
523
+ const item3 = document.querySelector('#prog-item3');
524
+ const status = document.querySelector('#prog-status');
525
+
526
+ document.querySelector('#focus-item2').addEventListener('click', () => {
527
+ item2.focus();
528
+ status.textContent = 'Focused Item 2';
529
+ });
530
+
531
+ document.querySelector('#click-item3').addEventListener('click', () => {
532
+ item3.click();
533
+ status.textContent = 'Clicked Item 3';
534
+ });
535
+
536
+ item3.addEventListener('zn-menu-select', () => {
537
+ status.textContent = 'Item 3 was selected';
538
+ });
539
+ </script>
540
+ ```
35
541
 
36
542