@kubex/zinc 1.1.185 → 2.0.0

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 (358) hide show
  1. package/.browserslistrc +2 -0
  2. package/.github/workflows/js_build_and_deploy.yaml +54 -1
  3. package/.github/workflows/test.yaml +27 -0
  4. package/dist/chunks/zn.UWJLIXDT.js +1 -0
  5. package/dist/custom-elements.json +9998 -2345
  6. package/dist/vscode.html-custom-data.json +1022 -67
  7. package/dist/web-types.json +2129 -177
  8. package/dist/zn.d.ts +2293 -416
  9. package/dist/zn.min.css +1 -1
  10. package/dist/zn.min.js +2310 -1637
  11. package/docs/_includes/default.njk +4 -1
  12. package/docs/assets/scripts/docs.js +22 -6
  13. package/docs/assets/styles/docs.css +9 -2
  14. package/docs/data/report-table-day-compare.json +380 -0
  15. package/docs/data/report-table.json +314 -0
  16. package/docs/pages/components/avatar-group.md +57 -0
  17. package/docs/pages/components/badge.md +67 -0
  18. package/docs/pages/components/button.md +41 -1
  19. package/docs/pages/components/chat-message.md +16 -0
  20. package/docs/pages/components/checkbox.md +1 -1
  21. package/docs/pages/components/chip.md +25 -13
  22. package/docs/pages/components/color-picker.md +37 -0
  23. package/docs/pages/components/copy-button.md +2 -2
  24. package/docs/pages/components/data-table-filter.md +33 -50
  25. package/docs/pages/components/data-table-search.md +4 -4
  26. package/docs/pages/components/data-table.md +27 -3
  27. package/docs/pages/components/date-range.md +116 -0
  28. package/docs/pages/components/dialog.md +29 -37
  29. package/docs/pages/components/diff-row.md +28 -0
  30. package/docs/pages/components/diff.md +46 -0
  31. package/docs/pages/components/editor.md +55 -0
  32. package/docs/pages/components/icon.md +46 -1
  33. package/docs/pages/components/input.md +30 -11
  34. package/docs/pages/components/item.md +35 -0
  35. package/docs/pages/components/key-value.md +25 -0
  36. package/docs/pages/components/menu.md +74 -7
  37. package/docs/pages/components/nav-item.md +15 -0
  38. package/docs/pages/components/nav-list.md +132 -0
  39. package/docs/pages/components/navbar.md +100 -1
  40. package/docs/pages/components/page.md +242 -74
  41. package/docs/pages/components/priority-list.md +43 -5
  42. package/docs/pages/components/query-builder.md +23 -0
  43. package/docs/pages/components/radio-group.md +33 -1
  44. package/docs/pages/components/radio.md +1 -1
  45. package/docs/pages/components/report-table.md +202 -0
  46. package/docs/pages/components/stat.md +30 -0
  47. package/docs/pages/components/tile.md +11 -0
  48. package/docs/pages/components/tooltip.md +1 -1
  49. package/docs/pages/components/translation-grid.md +86 -0
  50. package/docs/pages/components/vertical-stepper.md +108 -64
  51. package/package.json +2 -1
  52. package/scss/_global-spacing.scss +2 -2
  53. package/scss/_root.scss +11 -171
  54. package/scss/boot.scss +14 -0
  55. package/scss/mixins/_helper-mixins.scss +24 -2
  56. package/scss/mixins/_motion-mixins.scss +126 -0
  57. package/scss/mixins/_spacing-mixins.scss +4 -3
  58. package/scss/mixins/_tab-indicator-mixins.scss +12 -0
  59. package/scss/mixins/_typography-mixins.scss +1 -1
  60. package/scss/mixins/index.scss +14 -0
  61. package/scss/shared/_base.scss +32 -1
  62. package/scss/shared/_button-mixin.scss +7 -5
  63. package/scss/shared/_table.scss +35 -4
  64. package/scss/shared/nav.scss +4 -0
  65. package/scss/shared/shimmer.scss +1 -1
  66. package/scss/table-controls.scss +206 -0
  67. package/scss/themes/_dark.scss +1 -3
  68. package/scss/themes/_index.scss +1 -1
  69. package/scss/themes/_light.scss +46 -6
  70. package/scss/themes/_modes.scss +11 -11
  71. package/scss/themes/_openbyte.scss +944 -0
  72. package/scss/themes/_typography.scss +4 -2
  73. package/scss/variables/index.scss +0 -9
  74. package/src/components/alert/alert.component.ts +14 -4
  75. package/src/components/alert/alert.scss +55 -69
  76. package/src/components/alert/alert.test.ts +8 -0
  77. package/src/components/animated-button/animated-button.component.ts +3 -2
  78. package/src/components/animated-button/animated-button.scss +6 -23
  79. package/src/components/animated-button/animated-button.test.ts +4 -3
  80. package/src/components/avatar-group/avatar-group.component.ts +84 -0
  81. package/src/components/avatar-group/avatar-group.scss +54 -0
  82. package/src/components/avatar-group/avatar-group.test.ts +59 -0
  83. package/src/components/avatar-group/index.ts +12 -0
  84. package/src/components/badge/badge.component.ts +49 -0
  85. package/src/components/badge/badge.scss +80 -0
  86. package/src/components/badge/badge.test.ts +34 -0
  87. package/src/components/badge/index.ts +12 -0
  88. package/src/components/bulk-actions/bulk-actions.component.ts +14 -2
  89. package/src/components/button/button.component.ts +228 -8
  90. package/src/components/button/button.scss +115 -32
  91. package/src/components/button/button.test.ts +122 -0
  92. package/src/components/button-menu/button-menu.component.ts +32 -11
  93. package/src/components/button-menu/button-menu.scss +5 -1
  94. package/src/components/channel-tile/channel-tile.component.ts +34 -27
  95. package/src/components/channel-tile/channel-tile.scss +76 -43
  96. package/src/components/chart/builders.test.ts +46 -0
  97. package/src/components/chart/builders.ts +27 -3
  98. package/src/components/chart/chart-live.test.ts +4 -6
  99. package/src/components/chart/chart.component.ts +125 -5
  100. package/src/components/chart/chart.scss +121 -0
  101. package/src/components/chart/chart.test.ts +81 -0
  102. package/src/components/chat-message/chat-message.component.ts +21 -1
  103. package/src/components/chat-message/chat-message.scss +13 -2
  104. package/src/components/chat-message/chat-message.test.ts +9 -0
  105. package/src/components/checkbox/checkbox.component.ts +61 -27
  106. package/src/components/checkbox/checkbox.scss +58 -25
  107. package/src/components/checkbox-group/checkbox-group.component.ts +7 -1
  108. package/src/components/chip/chip.component.ts +11 -1
  109. package/src/components/chip/chip.scss +91 -26
  110. package/src/components/chip/chip.test.ts +17 -0
  111. package/src/components/collapsible/collapsible.component.ts +17 -3
  112. package/src/components/collapsible/collapsible.scss +19 -10
  113. package/src/components/color-picker/color-picker.component.ts +277 -0
  114. package/src/components/color-picker/color-picker.scss +141 -0
  115. package/src/components/color-picker/color-picker.test.ts +57 -0
  116. package/src/components/color-picker/index.ts +12 -0
  117. package/src/components/cols/cols.component.ts +10 -0
  118. package/src/components/cols/cols.test.ts +17 -0
  119. package/src/components/confirm/confirm.component.ts +20 -6
  120. package/src/components/confirm/confirm.test.ts +52 -0
  121. package/src/components/content-block/content-block.component.ts +38 -9
  122. package/src/components/content-block/content-block.scss +11 -5
  123. package/src/components/content-block/content-block.test.ts +26 -0
  124. package/src/components/copy-button/copy-button.component.ts +2 -2
  125. package/src/components/copy-button/copy-button.scss +17 -4
  126. package/src/components/data-select/data-select.component.ts +3 -1
  127. package/src/components/data-table/data-table.component.ts +362 -140
  128. package/src/components/data-table/data-table.scss +133 -60
  129. package/src/components/data-table/data-table.test.ts +356 -4
  130. package/src/components/data-table-filter/data-table-filter.component.ts +426 -406
  131. package/src/components/data-table-filter/data-table-filter.scss +176 -148
  132. package/src/components/data-table-filter/data-table-filter.test.ts +271 -273
  133. package/src/components/data-table-search/data-table-search.component.ts +4 -2
  134. package/src/components/data-table-search/data-table-search.scss +8 -1
  135. package/src/components/data-table-search/data-table-search.test.ts +29 -0
  136. package/src/components/date-range/date-range-math.test.ts +78 -0
  137. package/src/components/date-range/date-range-math.ts +105 -0
  138. package/src/components/date-range/date-range.component.ts +375 -0
  139. package/src/components/date-range/date-range.scss +272 -0
  140. package/src/components/date-range/date-range.test.ts +247 -0
  141. package/src/components/date-range/index.ts +12 -0
  142. package/src/components/datepicker/datepicker.component.ts +44 -7
  143. package/src/components/datepicker/datepicker.scss +9 -0
  144. package/src/components/datepicker/datepicker.test.ts +2 -2
  145. package/src/components/dialog/dialog.component.ts +38 -19
  146. package/src/components/dialog/dialog.scss +65 -36
  147. package/src/components/dialog/dialog.test.ts +14 -0
  148. package/src/components/diff/diff.component.ts +55 -0
  149. package/src/components/diff/diff.scss +46 -0
  150. package/src/components/diff/diff.test.ts +15 -0
  151. package/src/components/diff/index.ts +12 -0
  152. package/src/components/diff-row/diff-row.component.ts +75 -0
  153. package/src/components/diff-row/diff-row.scss +70 -0
  154. package/src/components/diff-row/diff-row.test.ts +37 -0
  155. package/src/components/diff-row/index.ts +12 -0
  156. package/src/components/dropdown/dropdown.component.ts +12 -10
  157. package/src/components/dropdown/dropdown.scss +2 -0
  158. package/src/components/editor/editor.component.ts +159 -11
  159. package/src/components/editor/editor.scss +250 -1
  160. package/src/components/editor/editor.test.ts +31 -3
  161. package/src/components/editor/modules/ai/panel/ai-panel.scss +0 -1
  162. package/src/components/editor/modules/attachment/attachment.ts +53 -31
  163. package/src/components/editor/modules/context-menu/context-menu.ts +17 -0
  164. package/src/components/editor/modules/dialog/dialog.component.ts +23 -1
  165. package/src/components/editor/modules/dialog/dialog.test.ts +28 -0
  166. package/src/components/editor/modules/emoji/emoji.ts +4 -5
  167. package/src/components/editor/modules/merge-field/merge-field.ts +83 -0
  168. package/src/components/editor/modules/toolbar/toolbar.component.ts +121 -68
  169. package/src/components/editor/modules/toolbar/toolbar.scss +38 -0
  170. package/src/components/editor/modules/toolbar/toolbar.ts +25 -1
  171. package/src/components/empty-state/empty-state.component.ts +6 -1
  172. package/src/components/empty-state/empty-state.scss +21 -4
  173. package/src/components/expanding-action/expanding-action.component.ts +22 -34
  174. package/src/components/expanding-action/expanding-action.scss +3 -45
  175. package/src/components/expanding-action/expanding-action.test.ts +2 -1
  176. package/src/components/file/file.component.ts +30 -2
  177. package/src/components/file/file.scss +6 -0
  178. package/src/components/flow-builder/flow-builder.component.ts +36 -3
  179. package/src/components/flow-builder/flow-builder.scss +0 -6
  180. package/src/components/flow-builder/modules/flow-canvas/flow-canvas.component.ts +8 -0
  181. package/src/components/flow-builder/modules/flow-canvas/flow-canvas.scss +10 -5
  182. package/src/components/flow-builder/modules/flow-node/flow-node.component.ts +17 -0
  183. package/src/components/flow-builder/modules/flow-node/flow-node.scss +10 -0
  184. package/src/components/form-actions/form-actions.component.ts +48 -2
  185. package/src/components/form-actions/form-actions.scss +1 -1
  186. package/src/components/form-group/form-group.component.ts +10 -3
  187. package/src/components/form-group/form-group.scss +37 -4
  188. package/src/components/form-group/form-group.test.ts +10 -0
  189. package/src/components/header/header.component.ts +11 -4
  190. package/src/components/header/header.scss +47 -5
  191. package/src/components/hover-container/hover-container.component.ts +4 -5
  192. package/src/components/icon/icon.component.ts +95 -9
  193. package/src/components/icon/icon.scss +70 -6
  194. package/src/components/icon/icon.test.ts +55 -0
  195. package/src/components/icon-picker/icon-picker.component.ts +35 -1
  196. package/src/components/inline-edit/inline-edit.component.ts +38 -8
  197. package/src/components/inline-edit/inline-edit.scss +128 -19
  198. package/src/components/input/input.component.ts +173 -297
  199. package/src/components/input/input.scss +65 -43
  200. package/src/components/input/input.test.ts +86 -4
  201. package/src/components/item/item.component.ts +12 -0
  202. package/src/components/item/item.scss +102 -3
  203. package/src/components/item/item.test.ts +23 -0
  204. package/src/components/key/key.component.ts +2 -2
  205. package/src/components/key/key.scss +11 -0
  206. package/src/components/key-value/index.ts +12 -0
  207. package/src/components/key-value/key-value.component.ts +160 -0
  208. package/src/components/key-value/key-value.scss +20 -0
  209. package/src/components/key-value/key-value.test.ts +22 -0
  210. package/src/components/markdown-editor/markdown-editor.component.ts +8 -1
  211. package/src/components/menu/menu.component.ts +21 -2
  212. package/src/components/menu/menu.scss +43 -23
  213. package/src/components/menu/menu.test.ts +33 -0
  214. package/src/components/menu-item/menu-item.component.ts +13 -2
  215. package/src/components/menu-item/menu-item.scss +56 -23
  216. package/src/components/menu-item/menu-item.test.ts +31 -0
  217. package/src/components/menu-item/submenu-controller.ts +25 -15
  218. package/src/components/menu-label/index.ts +12 -0
  219. package/src/components/menu-label/menu-label.component.ts +30 -0
  220. package/src/components/menu-label/menu-label.scss +18 -0
  221. package/src/components/nav-item/index.ts +12 -0
  222. package/src/components/nav-item/nav-item.component.ts +83 -0
  223. package/src/components/nav-item/nav-item.scss +128 -0
  224. package/src/components/nav-list/index.ts +12 -0
  225. package/src/components/nav-list/nav-list.component.ts +313 -0
  226. package/src/components/nav-list/nav-list.scss +87 -0
  227. package/src/components/nav-list/nav-list.test.ts +250 -0
  228. package/src/components/navbar/navbar.component.ts +235 -171
  229. package/src/components/navbar/navbar.scss +333 -169
  230. package/src/components/navbar/navbar.test.ts +63 -143
  231. package/src/components/page/page.component.ts +114 -29
  232. package/src/components/page/page.scss +223 -95
  233. package/src/components/page/page.test.ts +214 -3
  234. package/src/components/page-builder/page-builder.component.ts +51 -5
  235. package/src/components/page-builder/page-builder.scss +6 -1
  236. package/src/components/page-nav/page-nav.component.ts +25 -3
  237. package/src/components/page-nav/page-nav.scss +10 -2
  238. package/src/components/pagination/pagination.scss +1 -1
  239. package/src/components/panel/panel.component.ts +14 -13
  240. package/src/components/panel/panel.scss +14 -10
  241. package/src/components/panel/panel.test.ts +42 -0
  242. package/src/components/popup/popup.component.ts +20 -13
  243. package/src/components/popup/popup.test.ts +21 -1
  244. package/src/components/priority-list/priority-list.component.ts +157 -172
  245. package/src/components/priority-list/priority-list.scss +113 -17
  246. package/src/components/priority-list/priority-list.test.ts +301 -3
  247. package/src/components/progress-bar/progress-bar.component.ts +1 -1
  248. package/src/components/progress-bar/progress-bar.scss +16 -4
  249. package/src/components/progress-tile/progress-tile.scss +1 -1
  250. package/src/components/query-builder/query-builder.component.ts +85 -10
  251. package/src/components/query-builder/query-builder.scss +7 -1
  252. package/src/components/query-builder/query-builder.test.ts +40 -0
  253. package/src/components/radio/radio.component.ts +57 -18
  254. package/src/components/radio/radio.scss +101 -26
  255. package/src/components/radio-group/radio-group.component.ts +45 -7
  256. package/src/components/radio-group/radio-group.scss +17 -0
  257. package/src/components/radio-group/radio-group.test.ts +63 -2
  258. package/src/components/rating/rating.component.ts +23 -0
  259. package/src/components/rating/rating.scss +1 -1
  260. package/src/components/remarkd-editor/remarkd-editor.component.ts +60 -5
  261. package/src/components/remarkd-editor/remarkd-editor.scss +12 -4
  262. package/src/components/report-table/index.ts +12 -0
  263. package/src/components/report-table/report-format.test.ts +86 -0
  264. package/src/components/report-table/report-format.ts +72 -0
  265. package/src/components/report-table/report-math.test.ts +74 -0
  266. package/src/components/report-table/report-math.ts +252 -0
  267. package/src/components/report-table/report-table.component.ts +681 -0
  268. package/src/components/report-table/report-table.scss +328 -0
  269. package/src/components/report-table/report-table.test.ts +702 -0
  270. package/src/components/reveal/reveal.component.ts +15 -1
  271. package/src/components/reveal/reveal.scss +5 -0
  272. package/src/components/schedule-builder/schedule-builder.component.ts +23 -8
  273. package/src/components/scroll-container/scroll-container.component.ts +19 -1
  274. package/src/components/scroll-container/scroll-container.scss +6 -1
  275. package/src/components/select/select.component.ts +52 -36
  276. package/src/components/select/select.scss +42 -25
  277. package/src/components/select/select.test.ts +14 -2
  278. package/src/components/settings-container/settings-container.scss +18 -5
  279. package/src/components/sidebar/sidebar.component.ts +8 -1
  280. package/src/components/sidebar/sidebar.scss +6 -1
  281. package/src/components/skeleton/skeleton.component.ts +3 -3
  282. package/src/components/skeleton/skeleton.scss +6 -6
  283. package/src/components/skeleton/skeleton.test.ts +9 -0
  284. package/src/components/slash-menu/slash-menu.scss +1 -1
  285. package/src/components/slideout/slideout.component.ts +20 -3
  286. package/src/components/slideout/slideout.scss +13 -6
  287. package/src/components/slideout/slideout.test.ts +19 -0
  288. package/src/components/split-button/split-button.component.ts +1 -1
  289. package/src/components/split-pane/split-pane.component.ts +71 -8
  290. package/src/components/split-pane/split-pane.scss +145 -41
  291. package/src/components/split-pane/split-pane.test.ts +23 -3
  292. package/src/components/stat/stat.component.ts +209 -14
  293. package/src/components/stat/stat.scss +305 -5
  294. package/src/components/stat/stat.test.ts +143 -2
  295. package/src/components/status-indicator/status-indicator.scss +22 -21
  296. package/src/components/stepper/stepper.scss +3 -3
  297. package/src/components/tab/tab.component.ts +1 -0
  298. package/src/components/table/table.component.ts +12 -1
  299. package/src/components/table/table.scss +21 -13
  300. package/src/components/table/table.test.ts +17 -0
  301. package/src/components/tabs/tabs.component.ts +150 -37
  302. package/src/components/tabs/tabs.scss +48 -7
  303. package/src/components/tabs/tabs.test.ts +169 -0
  304. package/src/components/textarea/textarea.component.ts +25 -3
  305. package/src/components/textarea/textarea.scss +10 -0
  306. package/src/components/textarea/textarea.test.ts +8 -4
  307. package/src/components/theme-editor/theme-editor.scss +0 -6
  308. package/src/components/tile/tile.component.ts +32 -2
  309. package/src/components/tile/tile.scss +40 -7
  310. package/src/components/tile/tile.test.ts +10 -0
  311. package/src/components/toggle/toggle.component.ts +23 -7
  312. package/src/components/toggle/toggle.scss +36 -29
  313. package/src/components/toggle/toggle.test.ts +17 -0
  314. package/src/components/tooltip/tooltip.component.ts +3 -0
  315. package/src/components/tooltip/tooltip.scss +11 -6
  316. package/src/components/tooltip/tooltip.test.ts +12 -0
  317. package/src/components/translation-field/index.ts +12 -0
  318. package/src/components/translation-field/translation-field.component.ts +55 -0
  319. package/src/components/translation-field/translation-field.scss +101 -0
  320. package/src/components/translation-fields/index.ts +12 -0
  321. package/src/components/translation-fields/translation-fields.component.ts +80 -0
  322. package/src/components/translation-fields/translation-fields.scss +60 -0
  323. package/src/components/translation-grid/index.ts +12 -0
  324. package/src/components/translation-grid/translation-grid.component.ts +157 -0
  325. package/src/components/translation-grid/translation-grid.scss +138 -0
  326. package/src/components/translation-grid/translation-grid.test.ts +28 -0
  327. package/src/components/vertical-stepper/vertical-stepper.component.ts +35 -9
  328. package/src/components/vertical-stepper/vertical-stepper.scss +110 -39
  329. package/src/components/vertical-stepper/vertical-stepper.test.ts +35 -0
  330. package/src/components/well/well.scss +2 -2
  331. package/src/events/events.ts +2 -0
  332. package/src/events/zn-chart-click.ts +13 -0
  333. package/src/events/zn-report-change.ts +7 -0
  334. package/src/form-control.scss +36 -3
  335. package/src/internal/anchored-popover.ts +175 -0
  336. package/src/internal/animate.ts +19 -5
  337. package/src/internal/cosmic-border.ts +15 -0
  338. package/src/internal/form.ts +1 -1
  339. package/src/internal/hover-intent.ts +15 -0
  340. package/src/internal/input-modality.ts +15 -0
  341. package/src/internal/pointer-intent.ts +37 -0
  342. package/src/internal/reorder.ts +625 -0
  343. package/src/internal/scroll.ts +51 -3
  344. package/src/internal/selection-card.ts +1 -1
  345. package/src/internal/tab-indicator.ts +92 -0
  346. package/src/internal/table-sort.ts +25 -0
  347. package/src/internal/table-tabs.ts +108 -0
  348. package/src/internal/test-drag.ts +35 -0
  349. package/src/internal/theme-openbyte.test.ts +126 -0
  350. package/src/internal/theme.ts +4 -4
  351. package/src/internal/zinc-element.ts +2 -2
  352. package/src/selection-card.scss +25 -0
  353. package/src/types/web-test-runner-commands.d.ts +1 -0
  354. package/src/utilities/color.test.ts +43 -0
  355. package/src/utilities/color.ts +189 -0
  356. package/src/zinc.ts +14 -0
  357. package/.github/workflows/eleventy_build.yml +0 -42
  358. package/scss/themes/_aura.scss +0 -114
@@ -0,0 +1,202 @@
1
+ ---
2
+ meta:
3
+ title: Report Table
4
+ description: A grouped report that fetches its own rows, with group headings, gain and loss colouring and a total row.
5
+ layout: component
6
+ fullWidth: true
7
+ ---
8
+
9
+ ```html:preview
10
+ <zn-report-table caption="Day Compare" data-uri="/data/report-table.json" method="GET" locale="en-US"
11
+ from="2026-10-19" to="2026-10-20" group-by="affiliateFid"
12
+ types='[{"value":"compare","label":"Day Compare"},{"value":"summary","label":"Summary"}]'
13
+ group-bys='[
14
+ {"value":"affiliateFid","label":"Publisher","category":"Publisher"},
15
+ {"value":"publisherType","label":"Publisher Type","category":"Publisher"},
16
+ {"value":"subId1","label":"Sub ID 1","category":"Publisher"},
17
+ {"value":"campaignFid","label":"Campaign","category":"Campaign"},
18
+ {"value":"brand","label":"Brand","category":"Campaign"},
19
+ {"value":"media","label":"Media","category":"Campaign"},
20
+ {"value":"country","label":"Country","category":"Location"},
21
+ {"value":"city","label":"City","category":"Location"},
22
+ {"value":"device","label":"Device","category":"Location"}
23
+ ]'
24
+ filter-fields='[
25
+ {"id":"country","name":"Country","options":{"GB":"United Kingdom","US":"United States","DE":"Germany"}},
26
+ {"id":"device","name":"Device","options":{"desktop":"Desktop","mobile":"Mobile","tablet":"Tablet"}},
27
+ {"id":"campaign","name":"Campaign","operators":["eq","contains"]}
28
+ ]'></zn-report-table>
29
+ ```
30
+
31
+ `zn-report-table` shows a report: one row per value of a dimension (a publisher, a country, a campaign) over a date range, read column by column. Use it for reporting. For lists of records with paging, selection and row actions, use [Data Table](/components/data-table).
32
+
33
+ The table fetches its own data from `data-uri`, and fetches again whenever the report type, group by, date range or filter changes. The columns come back in the response, so the server decides what a report contains.
34
+
35
+ ## Examples
36
+
37
+ ### Groups and Columns
38
+
39
+ The response's `groups` give the heading row. Each group lists its `columns`, and a faint line marks the first column of each group. When a group has one column with the same label as the group, the column's own heading is left blank.
40
+
41
+ Each column has a `key`, a `label` and a `format`, and gets its value in one of three ways:
42
+
43
+ - `value`: a dotted path into the row's `values`, such as `d1.i.unique`.
44
+ - `formula`: arithmetic over `{dotted.path}` placeholders (see [Formulas and Totals](#formulas-and-totals)).
45
+ - Neither: the column's `key` is used as the path.
46
+
47
+ | Field | Values | Default | Meaning |
48
+ |---|---|---|---|
49
+ | `format` | `number`, `decimal`, `percent`, `currency`, `financial`, `text` | `number` | How the value is displayed. |
50
+ | `decimals` | integer | 0 for `number`, 2 otherwise | Decimal places. |
51
+ | `style` | `none`, `breakeven`, `ibreakeven`, `bold` | `none` | Colouring. |
52
+ | `threshold` | number | 0 | The breakeven point. |
53
+ | `summable` | bool | `true`, `false` for `text` | Whether the column gets a computed total. `false` shows `–`. |
54
+ | `currency` | ISO code | response `currency`, then the `currency` attribute, then `USD` | |
55
+
56
+ The formats:
57
+
58
+ - `number` and `decimal` use the locale's grouping.
59
+ - `percent` multiplies by 100 and adds `%`, since ratios are sent as fractions.
60
+ - `currency` shows negatives in brackets, such as `($1,396.73)`.
61
+ - `financial` is the same as `currency`, without the symbol.
62
+ - `text` shows the row's value as it is, for cells the server has already formatted.
63
+
64
+ With `breakeven`, a value above `threshold` is green and one below it is red. `ibreakeven` reverses that. Columns with no style are never coloured.
65
+
66
+ Each row has an `id`, a `label` for the first column and its `values`. A `uri` (and an optional `target`) turns the label into a link, which is how drill-down reports are linked. A row's `links` maps column keys to `{uri, target?}` and links those cells, for example a count to the records behind it. A `target` is rendered as `data-target`, so the console opens the link in that space, such as `slide`.
67
+
68
+ ### Formulas and Totals
69
+
70
+ A `formula` uses `+ - * /`, parentheses, numbers and unary minus over `{dotted.path}` placeholders, such as `{d2.total.revenue} - {d1.total.revenue}`. A leading `=` is ignored. Dividing by zero, a missing path or a value that isn't a number gives `0`. Formulas are parsed, never run as script.
71
+
72
+ The total row works the same way for every column. First, every numeric value is added up across the rows shown. Then each column's formula is read from those sums. That way a ratio such as Click / Acquisition is recalculated from the summed counts, not averaged.
73
+
74
+ When the response has `totals`, those are shown instead. Columns missing from `totals` show `–`. While the search box narrows the rows, the table goes back to computing totals from the rows on screen, so the total always matches what is shown.
75
+
76
+ ### Search and Sorting
77
+
78
+ The search box is a [Data Table Search](/components/data-table-search). It filters rows by their first column in the browser, a moment after typing stops, and its clear button shows every row again. The row count next to the caption reads `2 of 6 rows` while a search narrows the rows. The placeholder defaults to `Search` followed by the dimension's label, and `search-placeholder` replaces it.
79
+
80
+ Click a column heading to sort by it. The first click sorts descending, the second ascending, and the third goes back to the server's order. The first column sorts by text, and numbers inside it sort naturally, so `Sub ID 9` comes before `Sub ID 10`. The total row never moves. Search and sort are never sent to the server.
81
+
82
+ ### Report Type, Group By and Dates
83
+
84
+ - `types` is a JSON array of `{value, label}`. With two or more types, they show as tabs under the header, and `type` defaults to the first.
85
+ - `group-bys` is a JSON array of `{value, label, category?}` for the Group by menu. Options with a `category` are listed under its heading in a three-column grid. Without categories, the options are one list.
86
+ - `from` and `to` are ISO dates for the date range. `max-date` is the latest day that can be picked, and defaults to today. `presets` replaces the quick ranges, as on [Date Range](/components/date-range). `date-note` adds a short line under the calendar, such as "Day Compare sets the first day against the last."
87
+ - `filter-fields` gives the funnel its fields, in the same shape as Data Table's `filter-fields`. The funnel is a [Data Table Filter](/components/data-table-filter), and the rules that apply show as chips under the header. The funnel is hidden when there are no fields. The applied rules are sent as `filter`.
88
+
89
+ The response can send its own `groupBys` and `filterFields`, for a type whose options differ, and they replace the attributes. When the response's `groupBy` differs from the one requested, the table adopts it.
90
+
91
+ Each change sets the matching attribute and emits `zn-report-change` with `{type, groupBy, from, to, filter}`, then the table fetches again.
92
+
93
+ ```html:preview
94
+ <zn-report-table class="report-events" caption="Day Compare" data-uri="/data/report-table.json" method="GET"
95
+ locale="en-US" from="2026-10-19" to="2026-10-20" group-by="affiliateFid"
96
+ group-bys='[
97
+ {"value":"affiliateFid","label":"Publisher"},
98
+ {"value":"campaignFid","label":"Campaign"},
99
+ {"value":"country","label":"Country"},
100
+ {"value":"device","label":"Device"}
101
+ ]'></zn-report-table>
102
+ <pre class="report-events__log">Change the group by or dates to see zn-report-change.</pre>
103
+
104
+ <script type="module">
105
+ const table = document.querySelector('.report-events');
106
+ const log = document.querySelector('.report-events__log');
107
+ table.addEventListener('zn-report-change', event => {
108
+ log.textContent = JSON.stringify(event.detail, null, 2);
109
+ });
110
+ </script>
111
+ ```
112
+
113
+ ### Wide Reports
114
+
115
+ A report wider than its panel scrolls sideways. The first column stays in place and the other columns pass behind it, so each row's label stays in view. This Day Compare has a group per day, each with its own counts, ratios and spend.
116
+
117
+ ```html:preview
118
+ <zn-report-table caption="Day Compare" data-uri="/data/report-table-day-compare.json" method="GET" locale="en-US"
119
+ from="2026-10-19" to="2026-10-20" group-by="affiliateFid"
120
+ types='[{"value":"compare","label":"Day Compare"},{"value":"summary","label":"Summary"}]'
121
+ group-bys='[
122
+ {"value":"affiliateFid","label":"Publisher"},
123
+ {"value":"campaignFid","label":"Campaign"},
124
+ {"value":"country","label":"Country"}
125
+ ]'
126
+ filter-fields='[{"id":"country","name":"Country","options":{"GB":"United Kingdom","US":"United States"}}]'></zn-report-table>
127
+ ```
128
+
129
+ ### Sharable
130
+
131
+ Add `sharable` to keep the report's state in the URL's query string, so the view can be bookmarked or shared. The table writes `type`, `groupBy`, `from`, `to`, `filter` and `search` when they differ from the attributes it started with, and reads them back on load. Other query parameters are left alone.
132
+
133
+ ```html
134
+ <zn-report-table sharable data-uri="/reports/compare" caption="Day Compare"
135
+ from="2026-10-19" to="2026-10-20"></zn-report-table>
136
+ ```
137
+
138
+ A link such as `?type=summary&groupBy=country&from=2026-10-01&to=2026-10-07` opens the Summary type grouped by Country for that week.
139
+
140
+ ### Inputs and Empty State
141
+
142
+ Inputs in the `inputs` slot are sent with every request, which is useful for csrf tokens. Content in the `empty-state` slot replaces the default empty state, which is shown inside the panel when there are no rows.
143
+
144
+ ```html
145
+ <zn-report-table data-uri="/reports/compare">
146
+ <input slot="inputs" type="hidden" name="csrf" value="token">
147
+ <zn-empty-state slot="empty-state" caption="No traffic" icon="bar_chart"
148
+ description="Nothing ran in this range."></zn-empty-state>
149
+ </zn-report-table>
150
+ ```
151
+
152
+ ## Request and Response
153
+
154
+ The table sends JSON to `data-uri` with a `POST`, or a `GET` without a body when `method="GET"`. It sends the header `x-kx-fetch-style: zn-report-table`.
155
+
156
+ ```json
157
+ {
158
+ "type": "compare",
159
+ "groupBy": "affiliateFid",
160
+ "from": "2026-10-19",
161
+ "to": "2026-10-20",
162
+ "filter": "W3sia2V5IjoiY291bnRyeSIsImNvbXBhcmF0b3IiOiJlcSIsInZhbHVlIjoiR0IifV0="
163
+ }
164
+ ```
165
+
166
+ `filter` is `btoa(JSON.stringify(rules))` of `{key, comparator, value}` rules, as Data Table sends it, or `''` when no rules apply. The server decides what `from` and `to` mean for each type. A Day Compare compares the two days, and other types treat them as a span.
167
+
168
+ The response:
169
+
170
+ ```json
171
+ {
172
+ "dimension": {"label": "Publisher"},
173
+ "groups": [
174
+ {
175
+ "label": "Difference between 2026-10-19 and 2026-10-20",
176
+ "columns": [
177
+ {"key": "revenue", "label": "Revenue", "format": "currency", "style": "breakeven",
178
+ "formula": "{d2.total.revenue} - {d1.total.revenue}"}
179
+ ]
180
+ },
181
+ {
182
+ "label": "2026-10-19",
183
+ "columns": [{"key": "d1In", "label": "Inbound Actions", "format": "number", "value": "d1.i.unique"}]
184
+ }
185
+ ],
186
+ "rows": [
187
+ {"id": "AFF-1", "label": "NovaBeyond - Push/Display - Jake", "uri": "/reports/compare/campaignFid",
188
+ "values": {"d1": {"total": {"revenue": 2097.41}, "i": {"unique": 1298}}, "d2": {"total": {"revenue": 700.68}}}}
189
+ ],
190
+ "totals": {"revenue": -25736.81},
191
+ "currency": "USD",
192
+ "groupBy": "affiliateFid",
193
+ "groupBys": [{"value": "affiliateFid", "label": "Publisher", "category": "Publisher"}],
194
+ "filterFields": [{"id": "country", "name": "Country"}],
195
+ "error": {"text": "Results are limited to 1,000 rows", "level": "warning"}
196
+ }
197
+ ```
198
+
199
+ - `groups` and `rows` are required. `null` is read as an empty list.
200
+ - `totals` is optional. Without it, the table computes the totals.
201
+ - `groupBy`, `groupBys` and `filterFields` are optional and replace the attributes.
202
+ - `error` shows an alert inside the panel, above the table.
@@ -158,6 +158,36 @@ Use `delta-format="points"` with `show-delta` to show the difference between `am
158
158
  </zn-cols>
159
159
  ```
160
160
 
161
+ ### Tile
162
+
163
+ Use `layout="tile"` for a self-contained stat card: the caption, the amount, a footer with the delta and `description`, and an optional sparkline from comma-separated `spark` values. Colour the sparkline with `spark-color` (a tone such as `success` or `danger`, or any CSS colour). Set `invert-delta` where a rise is bad news.
164
+
165
+ ```html:preview
166
+ <zn-cols layout="1,1,1">
167
+ <zn-stat layout="tile" caption="Pending commission" amount="$2,941" show-delta previous="$2,875"
168
+ description="vs. 1,875" spark="4,6,5,8,7,10,9,13,12,15"></zn-stat>
169
+ <zn-stat layout="tile" caption="Unpaid paychecks" amount="$841" show-delta previous="$851"
170
+ description="vs. 902" spark="12,11,13,10,9,10,8,9,7,6" spark-color="danger"></zn-stat>
171
+ <zn-stat layout="tile" caption="Declined" amount="148" show-delta previous="140" invert-delta
172
+ description="3.4% of orders" spark="6,5,7,4,6,5,5,4,6,5,4,5,4,5,4" spark-color="danger"></zn-stat>
173
+ </zn-cols>
174
+ ```
175
+
176
+ ### Selectable Tiles
177
+
178
+ Add `selectable` to make a tile a toggle button, for tiles that filter the content below them, and `tone` for a coloured dot before the caption. `selected` sets the pressed state.
179
+
180
+ ```html:preview
181
+ <zn-cols layout="1,1,1">
182
+ <zn-stat layout="tile" selectable tone="info" caption="Capturing payment" amount="28"
183
+ description="Oldest 11 h" spark="0,0,1,0,2,1,0,3,2,4,3,5,8,12,28" spark-color="info"></zn-stat>
184
+ <zn-stat layout="tile" selectable selected tone="warning" caption="Awaiting approval" amount="203"
185
+ description="Oldest 29 days" spark="9,7,8,11,9,6,8,10,7,9,12,8,9,10,11" spark-color="warning"></zn-stat>
186
+ <zn-stat layout="tile" selectable tone="success" caption="Complete" amount="3,481" show-delta previous="3,513"
187
+ description="80% of orders" spark="120,128,119,124,118,131,127,122,126,130" spark-color="success"></zn-stat>
188
+ </zn-cols>
189
+ ```
190
+
161
191
  ### Icon
162
192
 
163
193
  Use `icon` to show an icon beside the amount. It takes the amount's color unless you set `icon-color`.
@@ -105,6 +105,17 @@ Use the `image` slot to add an image or icon to the left side of the tile. This
105
105
  </zn-tile>
106
106
  ```
107
107
 
108
+ ### Tile with Icon
109
+
110
+ Set `icon` to show an icon in a tinted square before the caption. `icon-color` picks the tint: `success`, `warning`,
111
+ `danger`, `info`, `ai` or `neutral` (the default).
112
+
113
+ ```html:preview
114
+ <zn-tile caption="Second chance" description="Offer · Default template" icon="tag@lu" icon-color="success"></zn-tile>
115
+ <zn-tile caption="Before you go" description="Message · Retention copy" icon="message-square@lu" icon-color="ai"></zn-tile>
116
+ <zn-tile caption="Archive" description="Kept for 90 days" icon="archive@lu"></zn-tile>
117
+ ```
118
+
108
119
  ### Clickable Tiles
109
120
 
110
121
  Add the `href` attribute to make a tile clickable. The tile will render as an anchor tag and display hover effects.
@@ -581,7 +581,7 @@ Customize the tooltip appearance with CSS custom properties.
581
581
  <zn-tooltip
582
582
  content="Error tooltip"
583
583
  style="
584
- --zn-tooltip-background-color: var(--zn-color-error-600);
584
+ --zn-tooltip-background-color: var(--zn-color-danger-600);
585
585
  --zn-tooltip-color: white;
586
586
  ">
587
587
  <zn-button color="error">Error Style</zn-button>
@@ -0,0 +1,86 @@
1
+ ---
2
+ meta:
3
+ title: Translation Grid
4
+ description: Shows how far each language's translation has got, with a column per language to choose and enable it.
5
+ layout: component
6
+ ---
7
+
8
+ Each language gets a column: its code links to that language's translation, the Enable row holds the control that
9
+ turns it on, and the Translation row shows its status. Pass the languages as a JSON array of
10
+ `{code, label, status, href}`, where `status` is `source`, `translated`, `outdated` or `missing`, and put each
11
+ language's Enable control in the `enable-{code}` slot.
12
+
13
+ ```html:preview
14
+ <zn-translation-grid
15
+ selected="es"
16
+ languages='[
17
+ {"code":"en","label":"English","status":"source"},
18
+ {"code":"fr","label":"French","status":"translated","href":"#fr"},
19
+ {"code":"de","label":"German","status":"outdated","href":"#de"},
20
+ {"code":"es","label":"Spanish","status":"missing","href":"#es"},
21
+ {"code":"it","label":"Italian","status":"missing","href":"#it"}
22
+ ]'>
23
+ <zn-checkbox slot="enable-en" checked disabled aria-label="English is always on"></zn-checkbox>
24
+ <zn-checkbox slot="enable-fr" checked aria-label="Enable French"></zn-checkbox>
25
+ <zn-checkbox slot="enable-de" aria-label="Enable German"></zn-checkbox>
26
+ <zn-checkbox slot="enable-es" disabled aria-label="Enable Spanish"></zn-checkbox>
27
+ <zn-checkbox slot="enable-it" disabled aria-label="Enable Italian"></zn-checkbox>
28
+ </zn-translation-grid>
29
+ ```
30
+
31
+ ## Examples
32
+
33
+ ### Enabling From A Form
34
+
35
+ Each Enable control can post on its own: put it in a form in the language's slot and give it `submit-on-click`, with
36
+ an `unchecked-value` so unticking posts too.
37
+
38
+ ```html:preview
39
+ <zn-translation-grid
40
+ selected="fr"
41
+ languages='[
42
+ {"code":"en","label":"English","status":"source"},
43
+ {"code":"fr","label":"French","status":"translated","href":"#fr"}
44
+ ]'>
45
+ <zn-checkbox slot="enable-en" checked disabled aria-label="English is always on"></zn-checkbox>
46
+ <form slot="enable-fr" method="post" action="/translations/fr/enable">
47
+ <zn-checkbox name="enabled" value="1" unchecked-value="0" submit-on-click aria-label="Enable French"></zn-checkbox>
48
+ </form>
49
+ </zn-translation-grid>
50
+ ```
51
+
52
+ ### Naming The Source
53
+
54
+ The legend calls an out-of-date translation "English changed". Set `source-label` when the source is another language.
55
+
56
+ ```html:preview
57
+ <zn-translation-grid
58
+ source-label="German"
59
+ languages='[
60
+ {"code":"de","label":"German","status":"source"},
61
+ {"code":"en","label":"English","status":"outdated","href":"#en"}
62
+ ]'>
63
+ </zn-translation-grid>
64
+ ```
65
+
66
+ ### A Row Per Field
67
+
68
+ When a record has several translated fields, pass them as `fields`, a JSON array of `{key, label, cells}` where
69
+ `cells` holds each language's `{status, href}` keyed by its code. Each field gets its own row, and `selected-field`
70
+ with `selected` rings the cell being edited. Leave out the `enable-{code}` slots to drop the Enable row.
71
+
72
+ ```html:preview
73
+ <zn-translation-grid
74
+ selected="de"
75
+ selected-field="content"
76
+ languages='[
77
+ {"code":"en","label":"English"},
78
+ {"code":"fr","label":"French","href":"#fr"},
79
+ {"code":"de","label":"German","href":"#de"}
80
+ ]'
81
+ fields='[
82
+ {"key":"name","label":"Display name","cells":{"en":{"status":"source"},"fr":{"status":"translated","href":"#name-fr"},"de":{"status":"missing","href":"#name-de"}}},
83
+ {"key":"content","label":"Content","cells":{"en":{"status":"source"},"fr":{"status":"outdated","href":"#content-fr"},"de":{"status":"missing","href":"#content-de"}}}
84
+ ]'>
85
+ </zn-translation-grid>
86
+ ```