@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,115 +1,468 @@
1
1
  ---
2
2
  meta:
3
3
  title: Data Table
4
- description:
4
+ description: Data tables display large sets of tabular data with sorting, filtering, pagination, and row selection capabilities.
5
5
  layout: component
6
6
  fullWidth: true
7
7
  ---
8
8
 
9
9
  ```html:preview
10
+ <zn-data-table
11
+ data-uri="/data/data-table.json"
12
+ method="GET"
13
+ empty-state-caption="No records found"
14
+ empty-state-icon="data_alert"
15
+ headers='[
16
+ {"key":"id","label":"ID", "required":true, "default": true},
17
+ {"key":"name","label":"Name", "required":true, "default": true, "sortable":true},
18
+ {"key":"email","label":"Email", "sortable":true},
19
+ {"key":"status","label":"Status", "sortable":true},
20
+ {"key":"date","label":"Date Joined", "sortable":true}
21
+ ]'>
10
22
 
11
- <zn-data-table empty-state-caption="No customers found" empty-state-icon="person_off" data-uri="/data/data-table.json"
12
- method="GET"
13
- headers="[{&quot;key&quot;:&quot;label&quot,&quot;label&quot;:&quot;ID&quot;, &quot;required&quot;:true, &quot;default&quot;: true},
14
- {&quot;key&quot;:&quot;One&quot;,&quot;label&quot;:&quot;Name&quot;, &quot;required&quot;:true, &quot;default&quot;: true, &quot;sortable&quot;:true, &quot;filterable&quot;:true},
15
- {&quot;key&quot;:&quot;Two&quot;,&quot;label&quot;:&quot;Name&quot;, &quot;required&quot;:true, &quot;default&quot;: true, &quot;sortable&quot;:true, &quot;filterable&quot;:true},
16
- {&quot;key&quot;:&quot;Three&quot;,&quot;label&quot;:&quot;Name&quot;, &quot;required&quot;:true, &quot;default&quot;: true, &quot;sortable&quot;:true, &quot;filterable&quot;:true},
17
- {&quot;key&quot;:&quot;Four&quot;,&quot;label&quot;:&quot;Name&quot;, &quot;required&quot;:true, &quot;default&quot;: true, &quot;sortable&quot;:true, &quot;filterable&quot;:true}]">
18
-
19
- <zn-data-table-sort slot="sort">
20
- <!-- Need to configure default, and available sort columns
21
- Future enhancement: allow multi-column sort !-->
22
- </zn-data-table-sort>
23
-
24
- <zn-data-table-filter auto-submit="true" debounce="1000" slot="filter">
25
- <zn-input name="search" placeholder="Search customers..." icon="search" debounce="300" clearable></zn-input>
26
- </zn-data-table-filter>
23
+ <zn-data-table-search slot="search" placeholder="Search records..."></zn-data-table-search>
27
24
 
28
25
  </zn-data-table>
29
26
  ```
30
27
 
31
28
  ## Examples
32
29
 
33
- ### Grouping Split Tables
30
+ ### Basic Data Table
34
31
 
35
- Splits table into groups based on a specified column. (Will request all data upfront)
32
+ The simplest data table fetches data from a URI and displays it with defined column headers. The `headers` property defines the columns to display.
36
33
 
37
34
  ```html:preview
35
+ <zn-data-table
36
+ data-uri="/data/data-table.json"
37
+ method="GET"
38
+ headers='[
39
+ {"key":"id","label":"ID"},
40
+ {"key":"name","label":"Name"},
41
+ {"key":"email","label":"Email"},
42
+ {"key":"status","label":"Status"}
43
+ ]'>
44
+ </zn-data-table>
45
+ ```
38
46
 
39
- <zn-data-table data-uri="/data/products-table.json" method="GET" group="category"
40
- headers="[{&quot;key&quot;:&quot;name&quot;,&quot;label&quot;:&quot;Name&quot;},
41
- {&quot;key&quot;:&quot;category&quot;,&quot;label&quot;:&quot;Category&quot;},
42
- {&quot;key&quot;:&quot;price&quot;,&quot;label&quot;:&quot;Price&quot;},
43
- {&quot;key&quot;:&quot;discountPercentage&quot;,&quot;label&quot;:&quot;Discount %&quot;},
44
- {&quot;key&quot;:&quot;stock&quot;,&quot;label&quot;:&quot;Stock&quot;},
45
- {&quot;key&quot;:&quot;rating&quot;,&quot;label&quot;:&quot;Rating&quot;}]">
47
+ ### With Search
46
48
 
47
- <zn-empty-state slot="empty-state" icon="inventory_2" caption="No products found">
48
- <p>Use the filters to search for products</p>
49
- </zn-empty-state>
49
+ Add a search component to filter table data. The search component emits debounced search events that trigger data reloading.
50
+
51
+ :::tip
52
+ In this preview, search sends a `search` parameter with each request but the static data file always returns the same results. With a real server endpoint, results would be filtered based on the search term.
53
+ :::
54
+
55
+ ```html:preview
56
+ <zn-data-table
57
+ data-uri="/data/data-table.json"
58
+ method="GET"
59
+ headers='[
60
+ {"key":"id","label":"ID"},
61
+ {"key":"name","label":"Name"},
62
+ {"key":"email","label":"Email"},
63
+ {"key":"status","label":"Status"}
64
+ ]'>
65
+
66
+ <zn-data-table-search
67
+ slot="search"
68
+ placeholder="Search by name or email..."
69
+ debounce-delay="350">
70
+ </zn-data-table-search>
50
71
 
51
72
  </zn-data-table>
52
73
  ```
53
74
 
54
- ### Filter-top Slot
75
+ ### With Sorting
76
+
77
+ Enable column sorting by marking headers as sortable. Click column headers to sort data ascending or descending.
55
78
 
56
- Add complex filtering options to the top of the table using the `filter-top` slot.
79
+ :::tip
80
+ Server-side sorting sends `sortColumn` and `sortDirection` parameters with each request. In this preview, the static data file returns results in the same order regardless. Use `local-sort` (shown below) to see sorting in action without a server.
81
+ :::
57
82
 
58
83
  ```html:preview
84
+ <zn-data-table
85
+ data-uri="/data/data-table.json"
86
+ method="GET"
87
+ sort-column="name"
88
+ sort-direction="asc"
89
+ headers='[
90
+ {"key":"id","label":"ID"},
91
+ {"key":"name","label":"Name", "sortable":true},
92
+ {"key":"email","label":"Email", "sortable":true},
93
+ {"key":"status","label":"Status", "sortable":true},
94
+ {"key":"date","label":"Date", "sortable":true}
95
+ ]'>
96
+ </zn-data-table>
97
+ ```
59
98
 
60
- <zn-data-table data-uri="/data/products-table.json" method="GET"
61
- no-initial-load
62
- headers="[{&quot;key&quot;:&quot;name&quot;,&quot;label&quot;:&quot;Name&quot;},
63
- {&quot;key&quot;:&quot;category&quot;,&quot;label&quot;:&quot;Category&quot;},
64
- {&quot;key&quot;:&quot;price&quot;,&quot;label&quot;:&quot;Price&quot;},
65
- {&quot;key&quot;:&quot;discountPercentage&quot;,&quot;label&quot;:&quot;Discount %&quot;},
66
- {&quot;key&quot;:&quot;stock&quot;,&quot;label&quot;:&quot;Stock&quot;},
67
- {&quot;key&quot;:&quot;rating&quot;,&quot;label&quot;:&quot;Rating&quot;}]">
99
+ ### Local Sorting
68
100
 
69
- <zn-empty-state slot="empty-state" icon="inventory_2" caption="No products found">
70
- <p>Use the filters to search for products</p>
101
+ Use `local-sort` to sort data client-side without making server requests. Best for small datasets.
102
+
103
+ ```html:preview
104
+ <zn-data-table
105
+ data-uri="/data/data-table.json"
106
+ method="GET"
107
+ local-sort
108
+ sort-column="name"
109
+ sort-direction="asc"
110
+ headers='[
111
+ {"key":"id","label":"ID"},
112
+ {"key":"name","label":"Name", "sortable":true},
113
+ {"key":"email","label":"Email", "sortable":true},
114
+ {"key":"status","label":"Status", "sortable":true}
115
+ ]'>
116
+ </zn-data-table>
117
+ ```
118
+
119
+ ### Pagination
120
+
121
+ Data tables automatically display pagination controls when the total number of records exceeds the per-page limit. Users can navigate between pages and adjust rows per page.
122
+
123
+ :::tip
124
+ Pagination controls appear based on the `total` and `perPage` values in the response. In this preview, changing pages re-fetches the same static data. With a real server, each page request would return the corresponding slice of data.
125
+ :::
126
+
127
+ ```html:preview
128
+ <zn-data-table
129
+ data-uri="/data/data-table.json"
130
+ method="GET"
131
+ headers='[
132
+ {"key":"id","label":"ID"},
133
+ {"key":"name","label":"Name"},
134
+ {"key":"email","label":"Email"},
135
+ {"key":"status","label":"Status"}
136
+ ]'>
137
+ </zn-data-table>
138
+ ```
139
+
140
+ ### Hide Pagination
141
+
142
+ Use `hide-pagination` to hide pagination controls even when multiple pages are available.
143
+
144
+ ```html:preview
145
+ <zn-data-table
146
+ data-uri="/data/data-table.json"
147
+ method="GET"
148
+ hide-pagination
149
+ headers='[
150
+ {"key":"id","label":"ID"},
151
+ {"key":"name","label":"Name"},
152
+ {"key":"email","label":"Email"}
153
+ ]'>
154
+ </zn-data-table>
155
+ ```
156
+
157
+ ### Row Selection
158
+
159
+ By default, rows can be selected by clicking. Selected rows are tracked and can be used with bulk actions.
160
+
161
+ ```html:preview
162
+ <zn-data-table
163
+ data-uri="/data/data-table.json"
164
+ method="GET"
165
+ headers='[
166
+ {"key":"id","label":"ID"},
167
+ {"key":"name","label":"Name"},
168
+ {"key":"email","label":"Email"},
169
+ {"key":"status","label":"Status"}
170
+ ]'>
171
+
172
+ <zn-button slot="delete-action" color="error" icon="delete" size="x-small">
173
+ Delete Selected
174
+ </zn-button>
175
+
176
+ </zn-data-table>
177
+ ```
178
+
179
+ ### Hide Checkboxes
180
+
181
+ Use `hide-checkboxes` to disable row selection functionality.
182
+
183
+ ```html:preview
184
+ <zn-data-table
185
+ data-uri="/data/data-table.json"
186
+ method="GET"
187
+ hide-checkboxes
188
+ headers='[
189
+ {"key":"id","label":"ID"},
190
+ {"key":"name","label":"Name"},
191
+ {"key":"email","label":"Email"}
192
+ ]'>
193
+ </zn-data-table>
194
+ ```
195
+
196
+ ### Bulk Actions
197
+
198
+ Add action buttons to the table header for performing operations on selected rows. Use the `delete-action`, `modify-action`, and `create-action` slots.
199
+
200
+ ```html:preview
201
+ <zn-data-table
202
+ data-uri="/data/data-table.json"
203
+ method="GET"
204
+ headers='[
205
+ {"key":"id","label":"ID"},
206
+ {"key":"name","label":"Name"},
207
+ {"key":"email","label":"Email"},
208
+ {"key":"status","label":"Status"}
209
+ ]'>
210
+
211
+ <zn-button slot="delete-action" color="error" icon="delete" size="x-small">
212
+ Delete Selected
213
+ </zn-button>
214
+
215
+ <zn-button slot="modify-action" color="info" icon="edit" size="x-small">
216
+ Edit Selected
217
+ </zn-button>
218
+
219
+ <zn-button slot="create-action" color="success" icon="add" size="x-small">
220
+ Create New
221
+ </zn-button>
222
+
223
+ </zn-data-table>
224
+ ```
225
+
226
+ ### Secondary Columns
227
+
228
+ Mark columns as secondary to hide them by default. Users can expand rows to view secondary data.
229
+
230
+ ```html:preview
231
+ <zn-data-table
232
+ data-uri="/data/data-table.json"
233
+ method="GET"
234
+ headers='[
235
+ {"key":"id","label":"ID"},
236
+ {"key":"name","label":"Name"},
237
+ {"key":"email","label":"Email"},
238
+ {"key":"phone","label":"Phone", "secondary":true},
239
+ {"key":"address","label":"Address", "secondary":true},
240
+ {"key":"notes","label":"Notes", "secondary":true}
241
+ ]'>
242
+ </zn-data-table>
243
+ ```
244
+
245
+ ### Hide Columns
246
+
247
+ Use `hide-columns` to completely hide specific columns from the table.
248
+
249
+ ```html:preview
250
+ <zn-data-table
251
+ data-uri="/data/data-table.json"
252
+ method="GET"
253
+ hide-columns='["id", "internal_id"]'
254
+ headers='[
255
+ {"key":"id","label":"ID"},
256
+ {"key":"internal_id","label":"Internal ID"},
257
+ {"key":"name","label":"Name"},
258
+ {"key":"email","label":"Email"}
259
+ ]'>
260
+ </zn-data-table>
261
+ ```
262
+
263
+ ### Hide Headers
264
+
265
+ Use `hide-headers` to hide column header text while keeping the column content visible.
266
+
267
+ ```html:preview
268
+ <zn-data-table
269
+ data-uri="/data/data-table.json"
270
+ method="GET"
271
+ hide-headers='["actions"]'
272
+ headers='[
273
+ {"key":"name","label":"Name"},
274
+ {"key":"email","label":"Email"},
275
+ {"key":"actions","label":"Actions"}
276
+ ]'>
277
+ </zn-data-table>
278
+ ```
279
+
280
+ ### Unsortable Columns
281
+
282
+ Disable sorting on specific columns using `unsortable-headers`, or disable sorting entirely with `unsortable`.
283
+
284
+ ```html:preview
285
+ <zn-data-table
286
+ data-uri="/data/data-table.json"
287
+ method="GET"
288
+ unsortable-headers='["actions", "status"]'
289
+ headers='[
290
+ {"key":"name","label":"Name", "sortable":true},
291
+ {"key":"email","label":"Email", "sortable":true},
292
+ {"key":"status","label":"Status"},
293
+ {"key":"actions","label":"Actions"}
294
+ ]'>
295
+ </zn-data-table>
296
+ ```
297
+
298
+ Make the entire table unsortable:
299
+
300
+ ```html:preview
301
+ <zn-data-table
302
+ data-uri="/data/data-table.json"
303
+ method="GET"
304
+ unsortable
305
+ headers='[
306
+ {"key":"name","label":"Name"},
307
+ {"key":"email","label":"Email"},
308
+ {"key":"status","label":"Status"}
309
+ ]'>
310
+ </zn-data-table>
311
+ ```
312
+
313
+ ### Wide Columns
314
+
315
+ Use `wide-column` to specify which column should expand to fill available space.
316
+
317
+ ```html:preview
318
+ <zn-data-table
319
+ data-uri="/data/data-table.json"
320
+ method="GET"
321
+ wide-column="description"
322
+ headers='[
323
+ {"key":"id","label":"ID"},
324
+ {"key":"name","label":"Name"},
325
+ {"key":"description","label":"Description"},
326
+ {"key":"status","label":"Status"}
327
+ ]'>
328
+ </zn-data-table>
329
+ ```
330
+
331
+ ### Custom Empty State
332
+
333
+ Customize the empty state shown when no data is available using the `empty-state` slot or caption attributes.
334
+
335
+ ```html:preview
336
+ <zn-data-table
337
+ data-uri="/data/empty.json"
338
+ method="GET"
339
+ headers='[{"key":"id","label":"ID"},{"key":"name","label":"Name"}]'>
340
+
341
+ <zn-empty-state
342
+ slot="empty-state"
343
+ icon="inbox"
344
+ caption="No records found">
345
+ <p>Try adjusting your search or filter criteria</p>
346
+ <zn-button color="success" icon="add">Create First Record</zn-button>
71
347
  </zn-empty-state>
72
348
 
73
- <zn-filter-wrapper slot="filter-top" button="Submit">
349
+ </zn-data-table>
350
+ ```
351
+
352
+ Or use the built-in empty state with custom text:
353
+
354
+ ```html:preview
355
+ <zn-data-table
356
+ data-uri="/data/empty.json"
357
+ method="GET"
358
+ empty-state-caption="No customers found"
359
+ empty-state-icon="person_off"
360
+ caption="Customers"
361
+ headers='[{"key":"id","label":"ID"},{"key":"name","label":"Name"}]'>
362
+ </zn-data-table>
363
+ ```
364
+
365
+ ### Filtering
366
+
367
+ Add advanced filtering with the `zn-data-table-filter` component. The filter opens a slideout with a query builder.
368
+
369
+ :::tip
370
+ In this preview, filter parameters are sent with the request but the static data file returns the same results regardless. With a real server endpoint, results would be filtered based on the applied criteria.
371
+ :::
372
+
373
+ ```html:preview
374
+ <zn-data-table
375
+ data-uri="/data/data-table.json"
376
+ method="GET"
377
+ headers='[
378
+ {"key":"name","label":"Name", "filterable":true},
379
+ {"key":"email","label":"Email", "filterable":true},
380
+ {"key":"status","label":"Status", "filterable":true}
381
+ ]'>
382
+
383
+ <zn-data-table-search slot="search" placeholder="Search..."></zn-data-table-search>
384
+
385
+ <zn-data-table-filter
386
+ slot="filter"
387
+ filters='[
388
+ {"id":"name","name":"Name","operators":["eq","contains"]},
389
+ {"id":"status","name":"Status","options":{"active":"Active","inactive":"Inactive"},"operators":["eq"]}
390
+ ]'>
391
+ </zn-data-table-filter>
392
+
393
+ </zn-data-table>
394
+ ```
395
+
396
+ ### Filter Top Slot
397
+
398
+ Add complex filtering options above the table using the `filter-top` slot. Perfect for search forms and advanced filters.
399
+
400
+ :::tip
401
+ This example uses `no-initial-load` so the table starts empty. Submitting the filter form triggers a data load, but the static data file returns the same results regardless of filter values. With a real server, results would be filtered accordingly.
402
+ :::
403
+
404
+ ```html:preview
405
+ <zn-data-table
406
+ data-uri="/data/products-table.json"
407
+ method="GET"
408
+ no-initial-load
409
+ headers='[
410
+ {"key":"name","label":"Name"},
411
+ {"key":"category","label":"Category"},
412
+ {"key":"price","label":"Price"},
413
+ {"key":"stock","label":"Stock"}
414
+ ]'>
415
+
416
+ <zn-filter-wrapper slot="filter-top">
74
417
  <div class="form-spacing">
75
- <zn-input type="price" name="price" label="Price" span="3"></zn-input>
418
+ <zn-input type="text" name="name" label="Product Name" span="4"></zn-input>
419
+ <zn-input type="currency" name="price" label="Max Price" span="3"></zn-input>
76
420
  <zn-select name="category" span="3" label="Category" clearable>
77
421
  <zn-option value="beauty">Beauty</zn-option>
422
+ <zn-option value="electronics">Electronics</zn-option>
78
423
  </zn-select>
79
- <zn-button type="primary" submit>Search</zn-button>
424
+ <zn-button color="success" submit>Search</zn-button>
80
425
  </div>
81
426
  </zn-filter-wrapper>
427
+
428
+ <zn-empty-state slot="empty-state" icon="inventory_2" caption="No products found">
429
+ <p>Use the filters above to search for products</p>
430
+ </zn-empty-state>
431
+
82
432
  </zn-data-table>
83
433
  ```
84
434
 
85
- ### Filter-top Slot with Tabs
435
+ ### Filter Top with Tabs
86
436
 
87
- Add complex filtering options to the top of the table using the `filter-top` slot.
437
+ Combine the `filter-top` slot with tabs for multiple filtering interfaces.
88
438
 
89
- ```html:preview
439
+ :::tip
440
+ In this preview, filter and search parameters are sent with each request but the static data file returns the same results. With a real server endpoint, each tab's filters would produce different results.
441
+ :::
90
442
 
91
- <zn-data-table data-uri="/data/products-table.json" method="GET"
92
- headers="[{&quot;key&quot;:&quot;name&quot;,&quot;label&quot;:&quot;Name&quot;},
93
- {&quot;key&quot;:&quot;category&quot;,&quot;label&quot;:&quot;Category&quot;},
94
- {&quot;key&quot;:&quot;price&quot;,&quot;label&quot;:&quot;Price&quot;},
95
- {&quot;key&quot;:&quot;discountPercentage&quot;,&quot;label&quot;:&quot;Discount %&quot;},
96
- {&quot;key&quot;:&quot;stock&quot;,&quot;label&quot;:&quot;Stock&quot;},
97
- {&quot;key&quot;:&quot;rating&quot;,&quot;label&quot;:&quot;Rating&quot;}]">
443
+ ```html:preview
444
+ <zn-data-table
445
+ data-uri="/data/products-table.json"
446
+ method="GET"
447
+ headers='[
448
+ {"key":"name","label":"Name"},
449
+ {"key":"category","label":"Category"},
450
+ {"key":"price","label":"Price"},
451
+ {"key":"stock","label":"Stock"}
452
+ ]'>
98
453
 
99
454
  <zn-panel flush-x slot="filter-top">
100
455
  <zn-tabs>
101
456
  <zn-navbar slot="top">
102
457
  <li tab>Quick Search</li>
103
- <li tab="product">Product Search</li>
458
+ <li tab="advanced">Advanced Search</li>
104
459
  </zn-navbar>
105
460
 
106
461
  <zn-sp gap="sm">
107
462
  <zn-filter-wrapper with-submit>
108
- <zn-form-group
109
- label="Quick Search"
110
- label-tooltip="Quickly filter results in the table"
111
- help-text="Use the fields to filter results in the table, then click Search">
112
- <zn-input type="price" name="price" label="Price" span="3"></zn-input>
463
+ <zn-form-group label="Quick Search" help-text="Search by common fields">
464
+ <zn-input type="text" name="search" label="Keyword" span="6"></zn-input>
465
+ <zn-input type="currency" name="price" label="Max Price" span="3"></zn-input>
113
466
  <zn-select name="category" span="3" label="Category" clearable>
114
467
  <zn-option value="beauty">Beauty</zn-option>
115
468
  </zn-select>
@@ -117,18 +470,326 @@ Add complex filtering options to the top of the table using the `filter-top` slo
117
470
  </zn-filter-wrapper>
118
471
  </zn-sp>
119
472
 
120
- <zn-sp id="product" flush-y>
473
+ <zn-sp id="advanced" flush-y>
121
474
  <zn-filter-wrapper with-submit>
122
- <zn-filter-builder
123
- filters="[{&quot;id&quot;:&quot;title&quot;,&quot;name&quot;:&quot;Title&quot;,&quot;operators&quot;: [&quot;eq&quot;]},
124
- {&quot;id&quot;:&quot;category&quot;,&quot;name&quot;:&quot;Category&quot;,&quot;options&quot;:{&quot;beauty&quot;:&quot;Beauty&quot;},&quot;operators&quot;:[&quot;eq&quot;]}]"
475
+ <zn-query-builder
476
+ filters='[
477
+ {"id":"name","name":"Name","operators":["eq","contains"]},
478
+ {"id":"category","name":"Category","options":{"beauty":"Beauty"},"operators":["eq"]}
479
+ ]'
125
480
  name="query">
126
- </zn-filter-builder>
481
+ </zn-query-builder>
127
482
  </zn-filter-wrapper>
128
483
  </zn-sp>
129
484
  </zn-tabs>
130
485
  </zn-panel>
131
486
 
487
+ </zn-data-table>
488
+ ```
489
+
490
+ ### Additional Input Parameters
491
+
492
+ Use the `inputs` slot to include additional form inputs that get sent with every data request.
493
+
494
+ :::tip
495
+ In this preview, the input values are sent as parameters with each request but the static data file returns the same results. With a real server, these additional parameters would filter or modify the response data.
496
+ :::
497
+
498
+ ```html:preview
499
+ <zn-data-table
500
+ data-uri="/data/data-table.json"
501
+ method="GET"
502
+ headers='[
503
+ {"key":"name","label":"Name"},
504
+ {"key":"status","label":"Status"}
505
+ ]'>
506
+
507
+ <zn-select slot="inputs" name="filter_type" value="active">
508
+ <zn-option value="active">Active Only</zn-option>
509
+ <zn-option value="all">All Records</zn-option>
510
+ </zn-select>
132
511
 
512
+ <input slot="inputs" name="user_id" value="123" type="hidden">
513
+
514
+ </zn-data-table>
515
+ ```
516
+
517
+ ### Grouping Data
518
+
519
+ Group rows by a specific column using the `group-by` property. This loads all data and splits it into separate tables.
520
+
521
+ ```html:preview
522
+ <zn-data-table
523
+ data-uri="/data/products-table.json"
524
+ method="GET"
525
+ group-by="category"
526
+ headers='[
527
+ {"key":"name","label":"Name"},
528
+ {"key":"category","label":"Category"},
529
+ {"key":"price","label":"Price"},
530
+ {"key":"stock","label":"Stock"},
531
+ {"key":"rating","label":"Rating"}
532
+ ]'>
533
+
534
+ <zn-empty-state slot="empty-state" icon="inventory_2" caption="No products found">
535
+ <p>No products match your criteria</p>
536
+ </zn-empty-state>
537
+
538
+ </zn-data-table>
539
+ ```
540
+
541
+ ### Specific Groups
542
+
543
+ When using grouping, control which groups to show with the `groups` property.
544
+
545
+ ```html:preview
546
+ <zn-data-table
547
+ data-uri="/data/products-table.json"
548
+ method="GET"
549
+ group-by="category"
550
+ groups="Beauty, Electronics, *"
551
+ headers='[
552
+ {"key":"name","label":"Name"},
553
+ {"key":"category","label":"Category"},
554
+ {"key":"price","label":"Price"}
555
+ ]'>
133
556
  </zn-data-table>
134
- ```
557
+ ```
558
+
559
+ Use `*` as a wildcard to include all other groups not explicitly listed.
560
+
561
+ ### No Initial Load
562
+
563
+ Prevent automatic data loading on mount with `no-initial-load`. Call the `refresh()` method to manually trigger loading.
564
+
565
+ ```html:preview
566
+ <zn-data-table
567
+ id="manual-table"
568
+ data-uri="/data/data-table.json"
569
+ method="GET"
570
+ no-initial-load
571
+ headers='[
572
+ {"key":"name","label":"Name"},
573
+ {"key":"email","label":"Email"}
574
+ ]'>
575
+
576
+ <zn-filter-wrapper slot="filter-top">
577
+ <zn-input name="search" label="Search" span="6"></zn-input>
578
+ <zn-button color="success" submit>Load Data</zn-button>
579
+ </zn-filter-wrapper>
580
+
581
+ </zn-data-table>
582
+
583
+ <script type="module">
584
+ const table = document.querySelector('#manual-table');
585
+ const form = table.querySelector('zn-filter-wrapper');
586
+
587
+ form.addEventListener('submit', (e) => {
588
+ e.preventDefault();
589
+ table.refresh();
590
+ });
591
+ </script>
592
+ ```
593
+
594
+ ### Standalone Mode
595
+
596
+ Use `standalone` to render the table without a container wrapper, useful for embedding in other components.
597
+
598
+ ```html:preview
599
+ <zn-data-table
600
+ data-uri="/data/data-table.json"
601
+ method="GET"
602
+ standalone
603
+ headers='[
604
+ {"key":"name","label":"Name"},
605
+ {"key":"email","label":"Email"}
606
+ ]'>
607
+ </zn-data-table>
608
+ ```
609
+
610
+ ### Request Method
611
+
612
+ Choose between GET and POST requests using the `method` property. POST is default and sends parameters in the request body.
613
+
614
+ :::tip
615
+ This preview uses GET against a static file. In production, POST requests send pagination, sorting, and filter parameters in the request body rather than as query string parameters.
616
+ :::
617
+
618
+ ```html:preview
619
+ <zn-data-table
620
+ data-uri="/data/data-table.json"
621
+ method="GET"
622
+ headers='[
623
+ {"key":"name","label":"Name"},
624
+ {"key":"email","label":"Email"}
625
+ ]'>
626
+ </zn-data-table>
627
+ ```
628
+
629
+ ### Cell Styling
630
+
631
+ Cells support various styling options through the data response format. Each cell can have colors, icons, links, chips, and hover content.
632
+
633
+ ```json
634
+ {
635
+ "rows": [
636
+ {
637
+ "id": "1",
638
+ "cells": [
639
+ {"text": "John Doe", "column": "name", "style": "bold"},
640
+ {"text": "Active", "column": "status", "chipColor": "success"},
641
+ {"text": "admin@example.com", "column": "email", "copyable": true},
642
+ {"text": "View", "column": "action", "uri": "/users/1", "color": "info"}
643
+ ]
644
+ }
645
+ ],
646
+ "page": 1,
647
+ "perPage": 10,
648
+ "total": 100
649
+ }
650
+ ```
651
+
652
+ Available cell properties:
653
+ - `text`: The display text
654
+ - `column`: Column key this cell belongs to
655
+ - `style`: Comma-separated styles (bold, italic, mono, code, border, center)
656
+ - `color`: Text color
657
+ - `chipColor`: Renders as a chip with specified color
658
+ - `uri`: Makes cell content a link
659
+ - `target`: Link target attribute
660
+ - `copyable`: Adds a copy button
661
+ - `iconSrc`: Icon to display with text
662
+ - `iconColor`: Icon color
663
+ - `hoverContent`: HTML content shown on hover
664
+ - `hoverPlacement`: Hover tooltip placement
665
+ - `sortValue`: Value to use for sorting (overrides text)
666
+ - `gaid`: Google Analytics ID for tracking
667
+
668
+ ### Row Actions
669
+
670
+ Rows can have contextual actions that appear in a dropdown menu.
671
+
672
+ ```json
673
+ {
674
+ "rows": [
675
+ {
676
+ "id": "1",
677
+ "uri": "/users/1",
678
+ "actions": [
679
+ {
680
+ "text": "Edit",
681
+ "uri": "/users/1/edit",
682
+ "icon": "edit",
683
+ "gaid": "edit-user"
684
+ },
685
+ {
686
+ "text": "Delete",
687
+ "uri": "/users/1/delete",
688
+ "icon": "delete",
689
+ "confirmType": "error",
690
+ "confirmTitle": "Delete User",
691
+ "confirmContent": "Are you sure you want to delete this user?"
692
+ }
693
+ ],
694
+ "cells": [...]
695
+ }
696
+ ]
697
+ }
698
+ ```
699
+
700
+ ### Caption
701
+
702
+ Add a caption to describe the table data.
703
+
704
+ ```html:preview
705
+ <zn-data-table
706
+ data-uri="/data/data-table.json"
707
+ method="GET"
708
+ caption="Customer Records"
709
+ headers='[
710
+ {"key":"name","label":"Name"},
711
+ {"key":"email","label":"Email"}
712
+ ]'>
713
+ </zn-data-table>
714
+ ```
715
+
716
+ ### Programmatic Control
717
+
718
+ Access table methods programmatically to control behavior.
719
+
720
+ ```html:preview
721
+ <zn-data-table
722
+ id="controlled-table"
723
+ data-uri="/data/data-table.json"
724
+ method="GET"
725
+ headers='[
726
+ {"key":"name","label":"Name"},
727
+ {"key":"email","label":"Email"},
728
+ {"key":"status","label":"Status"}
729
+ ]'>
730
+ </zn-data-table>
731
+
732
+ <br />
733
+
734
+ <zn-button id="refresh-btn" icon="refresh">Refresh Data</zn-button>
735
+ <zn-button id="select-all-btn" icon="check_box">Select All</zn-button>
736
+
737
+ <script type="module">
738
+ const table = document.querySelector('#controlled-table');
739
+
740
+ document.querySelector('#refresh-btn').addEventListener('click', () => {
741
+ table.refresh();
742
+ });
743
+
744
+ document.querySelector('#select-all-btn').addEventListener('click', () => {
745
+ table.selectAll(new Event('click'));
746
+ });
747
+ </script>
748
+ ```
749
+
750
+ ## Data Format
751
+
752
+ The data table expects responses in the following format:
753
+
754
+ ```json
755
+ {
756
+ "rows": [
757
+ {
758
+ "id": "unique-row-id",
759
+ "uri": "/path/to/resource",
760
+ "target": "_blank",
761
+ "actions": [],
762
+ "cells": [
763
+ {
764
+ "text": "Display Value",
765
+ "column": "column_key",
766
+ "color": "success",
767
+ "style": "bold,mono",
768
+ "uri": "/link",
769
+ "copyable": true
770
+ }
771
+ ]
772
+ }
773
+ ],
774
+ "page": 1,
775
+ "perPage": 10,
776
+ "total": 100
777
+ }
778
+ ```
779
+
780
+ ## Request Format
781
+
782
+ For POST requests, the table sends:
783
+
784
+ ```json
785
+ {
786
+ "page": 1,
787
+ "perPage": 10,
788
+ "sortColumn": "name",
789
+ "sortDirection": "asc",
790
+ "filter": "",
791
+ "search": "search term"
792
+ }
793
+ ```
794
+
795
+ Additional parameters from the `inputs` slot are merged into the request.