@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,189 @@
1
+ export type ColorFormat = 'hex' | 'rgb' | 'hsl' | 'oklch';
2
+
3
+ /** Red, green and blue, each 0-255. */
4
+ export type Rgb = [number, number, number];
5
+
6
+ /** Hue 0-360, saturation and value 0-1. */
7
+ export type Hsv = [number, number, number];
8
+
9
+ const clamp = (n: number, min: number, max: number) => Math.min(max, Math.max(min, n));
10
+ const round1 = (n: number) => Math.round(n * 10) / 10;
11
+ const round3 = (n: number) => Math.round(n * 1000) / 1000;
12
+ const hexPair = (n: number) => Math.round(n).toString(16).padStart(2, '0').toUpperCase();
13
+
14
+ export function hsvToRgb(h: number, s: number, v: number): Rgb {
15
+ const f = (n: number) => {
16
+ const k = (n + h / 60) % 6;
17
+ return v - v * s * Math.max(0, Math.min(k, 4 - k, 1));
18
+ };
19
+ return [Math.round(f(5) * 255), Math.round(f(3) * 255), Math.round(f(1) * 255)];
20
+ }
21
+
22
+ export function rgbToHsv(r: number, g: number, b: number): Hsv {
23
+ r /= 255;
24
+ g /= 255;
25
+ b /= 255;
26
+ const max = Math.max(r, g, b);
27
+ const d = max - Math.min(r, g, b);
28
+ let h = 0;
29
+ if (d) {
30
+ h = max === r ? ((g - b) / d) % 6 : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
31
+ h *= 60;
32
+ if (h < 0) h += 360;
33
+ }
34
+ return [h, max ? d / max : 0, max];
35
+ }
36
+
37
+ /** Rounded to whole degrees and percentages. */
38
+ export function rgbToHsl(r: number, g: number, b: number): [number, number, number] {
39
+ r /= 255;
40
+ g /= 255;
41
+ b /= 255;
42
+ const max = Math.max(r, g, b);
43
+ const min = Math.min(r, g, b);
44
+ const d = max - min;
45
+ const l = (max + min) / 2;
46
+ const s = d ? d / (1 - Math.abs(2 * l - 1)) : 0;
47
+ let h = 0;
48
+ if (d) {
49
+ h = max === r ? ((g - b) / d) % 6 : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
50
+ h *= 60;
51
+ if (h < 0) h += 360;
52
+ }
53
+ return [Math.round(h), Math.round(s * 100), Math.round(l * 100)];
54
+ }
55
+
56
+ /** Saturation and lightness are percentages. */
57
+ export function hslToRgb(h: number, s: number, l: number): Rgb {
58
+ s /= 100;
59
+ l /= 100;
60
+ const a = s * Math.min(l, 1 - l);
61
+ const f = (n: number) => {
62
+ const k = (n + h / 30) % 12;
63
+ return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));
64
+ };
65
+ return [Math.round(f(0) * 255), Math.round(f(8) * 255), Math.round(f(4) * 255)];
66
+ }
67
+
68
+ const toLinear = (c: number) => {
69
+ c /= 255;
70
+ return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
71
+ };
72
+
73
+ const toGamma = (c: number) => {
74
+ c = clamp(c, 0, 1);
75
+ return Math.round(255 * (c <= 0.0031308 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055));
76
+ };
77
+
78
+ /** Lightness 0-1, chroma (about 0-0.4), hue in degrees. */
79
+ export function rgbToOklch(r: number, g: number, b: number): [number, number, number] {
80
+ r = toLinear(r);
81
+ g = toLinear(g);
82
+ b = toLinear(b);
83
+ const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
84
+ const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
85
+ const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
86
+ const L = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s;
87
+ const A = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;
88
+ const B = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;
89
+ const C = Math.sqrt(A * A + B * B);
90
+ let H = C < 0.0004 ? 0 : Math.atan2(B, A) * 180 / Math.PI;
91
+ if (H < 0) H += 360;
92
+ return [L, C, H];
93
+ }
94
+
95
+ /** Colours outside sRGB are clamped into it. */
96
+ export function oklchToRgb(L: number, C: number, H: number): Rgb {
97
+ const A = C * Math.cos(H * Math.PI / 180);
98
+ const B = C * Math.sin(H * Math.PI / 180);
99
+ const l = Math.pow(L + 0.3963377774 * A + 0.2158037573 * B, 3);
100
+ const m = Math.pow(L - 0.1055613458 * A - 0.0638541728 * B, 3);
101
+ const s = Math.pow(L - 0.0894841775 * A - 1.291485548 * B, 3);
102
+ return [
103
+ toGamma(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s),
104
+ toGamma(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s),
105
+ toGamma(-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s)
106
+ ];
107
+ }
108
+
109
+ /** OKLCH as shown to people: lightness as a percentage to 1dp, chroma to 3dp, hue to 1dp. */
110
+ export function oklchParts(rgb: Rgb): [number, number, number] {
111
+ const [l, c, h] = rgbToOklch(...rgb);
112
+ return [round1(l * 100), round3(c), round1(h)];
113
+ }
114
+
115
+ export const toHex = (rgb: Rgb) => `#${hexPair(rgb[0])}${hexPair(rgb[1])}${hexPair(rgb[2])}`;
116
+
117
+ /** The format a colour is written in, or null for a name, a token or anything that isn't a colour. */
118
+ export function detectColorFormat(value: string): ColorFormat | null {
119
+ const str = String(value ?? '').trim();
120
+ // A bare run of digits such as "123456" is ambiguous; only treat it as hex when it can't be anything else.
121
+ if (/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.test(str) && (str.startsWith('#') || /[a-f]/i.test(str) || str.length === 6)) {
122
+ return 'hex';
123
+ }
124
+ if (/^oklch\(/i.test(str)) return 'oklch';
125
+ if (/^hsla?\(/i.test(str)) return 'hsl';
126
+ if (/^(rgba?\(|\d{1,3}\s*[, ]\s*\d{1,3}\s*[, ]\s*\d{1,3}$)/i.test(str)) return 'rgb';
127
+ return null;
128
+ }
129
+
130
+ let probe: HTMLSpanElement | null = null;
131
+
132
+ /** Any CSS colour (hex, rgb(), hsl(), oklch(), a name or var(--token)) as RGB, or null when it isn't one. */
133
+ export function parseColor(value: string): Rgb | null {
134
+ const str = String(value ?? '').trim();
135
+ if (!str) return null;
136
+
137
+ let m = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(str);
138
+ if (m) {
139
+ const hex = m[1].length === 3 ? m[1].replace(/./g, '$&$&') : m[1];
140
+ return [parseInt(hex.slice(0, 2), 16), parseInt(hex.slice(2, 4), 16), parseInt(hex.slice(4, 6), 16)];
141
+ }
142
+
143
+ m = /^(?:rgb\()?\s*(\d{1,3})\s*[, ]\s*(\d{1,3})\s*[, ]\s*(\d{1,3})\s*\)?$/i.exec(str);
144
+ if (m && +m[1] < 256 && +m[2] < 256 && +m[3] < 256) return [+m[1], +m[2], +m[3]];
145
+
146
+ m = /^hsl\(\s*(\d{1,3})(?:deg)?\s*[, ]\s*(\d{1,3})%?\s*[, ]\s*(\d{1,3})%?\s*\)$/i.exec(str);
147
+ if (m && +m[1] <= 360 && +m[2] <= 100 && +m[3] <= 100) return hslToRgb(+m[1] % 360, +m[2], +m[3]);
148
+
149
+ m = /^oklch\(\s*([\d.]+)(%?)\s*[, ]\s*([\d.]+)(%?)\s*[, ]\s*([\d.]+)(?:deg)?\s*(?:\/\s*[\d.]+%?\s*)?\)$/i.exec(str);
150
+ if (m) {
151
+ const l = +m[1] / (m[2] ? 100 : 1);
152
+ const c = +m[3] * (m[4] ? 0.004 : 1);
153
+ const h = +m[5];
154
+ if (isNaN(l + c + h) || l > 1 || c > 0.5 || h > 360) return null;
155
+ return oklchToRgb(l, c, h % 360);
156
+ }
157
+
158
+ if (!/^[a-z-]+$|^var\(|^(rgb|hsl)a?\(/i.test(str) || typeof document === 'undefined') return null;
159
+
160
+ // Let the browser resolve names, tokens and other CSS syntax.
161
+ if (!probe) {
162
+ probe = document.createElement('span');
163
+ probe.style.display = 'none';
164
+ document.body.appendChild(probe);
165
+ }
166
+ probe.style.color = '';
167
+ probe.style.color = str;
168
+ if (!probe.style.color) return null;
169
+ const k = /rgba?\(\s*(\d+)[, ]+(\d+)[, ]+(\d+)/.exec(getComputedStyle(probe).color);
170
+ return k ? [+k[1], +k[2], +k[3]] : null;
171
+ }
172
+
173
+ /** Writes a colour out in the given format, e.g. `#085EFD`, `rgb(8, 94, 253)`, `hsl(219, 98%, 51%)` or `oklch(58.4% 0.226 262.5)`. */
174
+ export function formatColor(rgb: Rgb, format: ColorFormat): string {
175
+ switch (format) {
176
+ case 'rgb':
177
+ return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;
178
+ case 'hsl': {
179
+ const [h, s, l] = rgbToHsl(...rgb);
180
+ return `hsl(${h}, ${s}%, ${l}%)`;
181
+ }
182
+ case 'oklch': {
183
+ const [l, c, h] = oklchParts(rgb);
184
+ return `oklch(${l}% ${c} ${h})`;
185
+ }
186
+ default:
187
+ return toHex(rgb);
188
+ }
189
+ }
package/src/zinc.ts CHANGED
@@ -13,12 +13,14 @@ export { default as Chip } from './components/chip';
13
13
  export { default as Well } from './components/well';
14
14
  export { default as CopyButton } from './components/copy-button';
15
15
  export { default as DataTable } from './components/data-table';
16
+ export { default as ReportTable } from './components/report-table';
16
17
  export { default as Cols } from './components/cols';
17
18
  export { default as Confirm } from './components/confirm';
18
19
  export { default as Dialog } from './components/dialog';
19
20
  export { default as Dropdown } from './components/dropdown';
20
21
  export { default as Menu } from './components/menu';
21
22
  export { default as MenuItem } from './components/menu-item';
23
+ export { default as MenuLabel } from './components/menu-label';
22
24
  export { default as DefinedLabel } from './components/defined-label';
23
25
  export { default as EmptyState } from './components/empty-state';
24
26
  export { default as Note } from './components/note';
@@ -36,6 +38,8 @@ export { default as IconPicker } from './components/icon-picker';
36
38
  export { default as InlineEdit } from './components/inline-edit';
37
39
  export { default as Pagination } from './components/pagination';
38
40
  export { default as VerticalStepper } from './components/vertical-stepper';
41
+ export { default as Diff } from './components/diff';
42
+ export { default as DiffRow } from './components/diff-row';
39
43
  export { default as Timer } from './components/timer';
40
44
  export { default as Tabs } from './components/tabs';
41
45
  export { default as Panel } from './components/panel';
@@ -63,6 +67,7 @@ export { default as Option } from './components/option';
63
67
  export { default as Textarea } from './components/textarea';
64
68
  export { default as Checkbox } from './components/checkbox';
65
69
  export { default as Datepicker } from './components/datepicker';
70
+ export { default as DateRange } from './components/date-range';
66
71
  export { default as FormActions } from './components/form-actions';
67
72
  export { default as FormGroup } from './components/form-group';
68
73
  export { default as InputGroup } from './components/input-group';
@@ -99,6 +104,9 @@ export { default as Key } from './components/key';
99
104
  export { default as KeyContainer } from './components/key-container';
100
105
  export { default as AnimatedButton } from './components/animated-button';
101
106
  export { default as TranslationGroup } from './components/translation-group';
107
+ export { default as TranslationGrid } from './components/translation-grid';
108
+ export { default as TranslationField } from './components/translation-field';
109
+ export { default as TranslationFields } from './components/translation-fields';
102
110
  export { default as OptGroup } from './components/opt-group';
103
111
  export { default as PriorityList } from './components/priority-list';
104
112
  export { default as MarkdownEditor } from './components/markdown-editor';
@@ -119,6 +127,12 @@ export { default as ScheduleBuilder } from './components/schedule-builder';
119
127
  export { default as Thumbnail } from './components/thumbnail';
120
128
  export { default as ThumbnailGroup } from './components/thumbnail-group';
121
129
  export { default as Background } from './components/background';
130
+ export { default as NavList } from './components/nav-list';
131
+ export { default as NavItem } from './components/nav-item';
132
+ export { default as AvatarGroup } from './components/avatar-group';
133
+ export { default as Badge } from './components/badge';
134
+ export { default as ColorPicker } from './components/color-picker';
135
+ export { default as KeyValue } from './components/key-value';
122
136
  /* plop:component */
123
137
 
124
138
  // Base Component
@@ -1,42 +0,0 @@
1
- name: Eleventy Build
2
-
3
- on:
4
- push:
5
- branches:
6
- - master
7
-
8
- jobs:
9
- deploy:
10
- runs-on: ubuntu-latest
11
- permissions:
12
- contents: write
13
- concurrency:
14
- group: ${{ github.workflow }}-${{ github.ref }}
15
- steps:
16
- - uses: actions/checkout@v6 # Check out the repository
17
-
18
- - name: Setup Node
19
- uses: actions/setup-node@v6
20
- with:
21
- node-version: '24'
22
-
23
- - name: Cache npm
24
- uses: actions/cache@v5
25
- with:
26
- path: ~/.npm
27
- key: ${{ runner.os }}-node-${{ hashFiles('**/package.json') }}
28
-
29
- - run: npm ci # Install dependencies
30
-
31
- - run: npm run build -- --with-docs # Build the site (including docs)
32
-
33
- # Copy the dist/ folder into _site/dist
34
- - run: cp -r dist/ _site/dist
35
-
36
- - name: Deploy
37
- uses: peaceiris/actions-gh-pages@v4
38
- with:
39
- github_token: ${{ secrets.GITHUB_TOKEN }} # GitHub token automatically generated
40
- publish_dir: './_site' # Directory to deploy
41
- exclude_assets: '.github,**/.gitignore'
42
- cname: zinc.style
@@ -1,114 +0,0 @@
1
- // Aura — a soft violet identity drawn over either mode's primitives.
2
- //
3
- // Light inherits the light primitives (defined on :root) and only re-points the
4
- // primary ramp to a softer, more pastel violet so the whole UI takes on the
5
- // "aura" glow without redefining every token. Dark does the same over the dark
6
- // primitives, with the ramp inverted (50 darkest -> 900 lightest) the way
7
- // themes/_dark.scss inverts every other ramp.
8
- //
9
- // The selectors are root-qualified (`html[t="aura"]` / `body[t="aura"]`) and must
10
- // stay that way. ZincElement reflects `t`/`m` onto EVERY component, so a bare
11
- // `[t="aura"]` matched each of them individually and re-declared these tokens
12
- // with literal values, wiping out contextual overrides from an ancestor — that
13
- // is what painted the rubix aura header's buttons violet instead of white.
14
- // Worse, a consumer on an older ZincElement reflects `t` but not `m`: the bare
15
- // light block then matched it, poured light tokens over its whole subtree, and
16
- // anything in a shadow tree below could not recover (document stylesheets do not
17
- // match inside shadow roots), which is what painted shell dropdowns white in
18
- // aura dark. Root-qualified, non-root elements simply inherit.
19
- //
20
- // Only *source* tokens (--zn-color-*) and theme-owned leaf tokens belong here.
21
- // Never set a derived token (--zn-border-color, --zn-text*, --zn-panel,
22
- // --zn-body, --zn-input-bg) — those are mapped off the source tokens in
23
- // scss/_root.scss and will not follow if pinned here.
24
- html[t="aura"], body[t="aura"],
25
- html.theme-aura, body.theme-aura {
26
- color-scheme: light;
27
-
28
- /**************************************************************
29
- * Theme Tokens — soft violet primary
30
- *************************************************************/
31
-
32
- --zn-color-primary-50: hsl(258, 100%, 97%);
33
- --zn-color-primary-100: hsl(256, 95%, 94%);
34
- --zn-color-primary-200: hsl(255, 90%, 90%);
35
- --zn-color-primary-300: hsl(255, 88%, 83%);
36
- --zn-color-primary-400: hsl(256, 85%, 75%);
37
- --zn-color-primary-500: hsl(255, 82%, 68%);
38
- --zn-color-primary-600: hsl(256, 78%, 62%);
39
- --zn-color-primary-700: hsl(257, 70%, 54%);
40
- --zn-color-primary-800: hsl(258, 68%, 46%);
41
- --zn-color-primary-900: hsl(259, 66%, 38%);
42
-
43
- /* Soft, faintly violet-tinted elevations */
44
- --zn-shadow-x-small: 0 1px 4px rgba(60, 44, 110, 0.08);
45
- --zn-shadow-small: 0 3px 9px rgba(60, 44, 110, 0.12);
46
- --zn-shadow-medium: 0 6px 18px rgba(60, 44, 110, 0.12);
47
- --zn-shadow-large: 0 6px 20px rgba(60, 44, 110, 0.14);
48
- --zn-shadow-x-large: 0 6px 20px rgba(60, 44, 110, 0.22);
49
-
50
- /* Focus ring follows the softer primary */
51
- --zn-input-focus-ring-color: hsl(255 82% 68% / 40%);
52
- }
53
-
54
- // Aura dark — the same violet identity over the dark primitives.
55
- //
56
- // html[t="aura"][m="dark"] (0,2,1) outranks themes/_dark.scss's :root[m="dark"]
57
- // (0,2,0), but this block should still stay AFTER _dark.scss in themes/_index.scss
58
- // so the ordering reads the way it resolves. See the specificity note in
59
- // scss/_root.scss for why these are html/body rather than :root.
60
- html[t="aura"][m="dark"], body[t="aura"][m="dark"],
61
- html.theme-aura.theme-dark, body.theme-aura.theme-dark {
62
- color-scheme: dark;
63
-
64
- /**************************************************************
65
- * Theme Tokens — soft violet primary, inverted for dark
66
- *************************************************************/
67
-
68
- --zn-color-primary-50: hsl(257, 45%, 25%);
69
- --zn-color-primary-100: hsl(257, 50%, 34%);
70
- --zn-color-primary-200: hsl(257, 55%, 41%);
71
- --zn-color-primary-300: hsl(257, 62%, 50%);
72
- --zn-color-primary-400: hsl(256, 75%, 60%);
73
- --zn-color-primary-500: hsl(255, 88%, 68%);
74
- --zn-color-primary-600: hsl(253, 95%, 75%);
75
- --zn-color-primary-700: hsl(251, 100%, 83%);
76
- --zn-color-primary-800: hsl(249, 100%, 90%);
77
- --zn-color-primary-900: hsl(250, 100%, 94%);
78
-
79
- /* Elevations read as depth against the navy canvas, not violet haze */
80
- --zn-shadow-x-small: 0 1px 4px rgba(6, 10, 20, 0.30);
81
- --zn-shadow-small: 0 3px 9px rgba(6, 10, 20, 0.38);
82
- --zn-shadow-medium: 0 6px 18px rgba(6, 10, 20, 0.38);
83
- --zn-shadow-large: 0 6px 20px rgba(6, 10, 20, 0.42);
84
- --zn-shadow-x-large: 0 6px 20px rgba(6, 10, 20, 0.52);
85
-
86
- --zn-input-focus-ring-color: hsl(255 88% 68% / 45%);
87
-
88
- /* _dark.scss's gray-100 is a muddy violet-grey (hsl(262, 12%, 35%)) that reads
89
- brown over aura's navy canvas. It is the hover/secondary surface for a wide
90
- spread of components — every `--zn-color-neutral-100` consumer aliases it
91
- (zn-tile hover, zn-button hover, the markdown/remarkd editors,
92
- schedule-builder, the droparea checker) plus zn-alert directly — so
93
- re-pointing it here fixes them all at once. */
94
- --zn-color-gray-100: hsl(221.6, 41.21%, 27.22%);
95
-
96
- /* The neighbouring steps come along for the ride: _dark.scss aliases
97
- --zn-color-neutral-50/-200 onto these, so leaving them on the muddy violet
98
- ramp would put that colour back on `color="secondary"` button fills, input
99
- surfaces and every panel border. Values chosen to land on aura dark's
100
- existing navy tokens — 50 meets --zn-input-bg-accent (34,46,68) and 200
101
- meets --zn-color-border (64,82,113). */
102
- --zn-color-gray-50: hsl(220, 33%, 20%);
103
- --zn-color-gray-200: hsl(220, 28%, 35%);
104
-
105
- /* _dark.scss pins these to near-black literals, which read as holes punched
106
- in aura's navy canvas — re-point them to the navy family. */
107
- --zn-input-background-color-focus: rgb(35, 47, 70);
108
- --zn-input-background-color-disabled: rgb(33, 44, 65);
109
-
110
- --zn-tooltip-background-color: rgb(24, 33, 50);
111
-
112
- /* tables */
113
- --zn-table-header-background-color: 46, 61, 88;
114
- }