@kubex/zinc 1.1.185 → 2.0.1

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 +10319 -2666
  6. package/dist/vscode.html-custom-data.json +1012 -57
  7. package/dist/web-types.json +2097 -145
  8. package/dist/zn.d.ts +2294 -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 +136 -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 +632 -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,7 @@
1
+ export type ZnReportChangeEvent = CustomEvent<{type: string; groupBy: string; from: string; to: string; filter: string}>;
2
+
3
+ declare global {
4
+ interface GlobalEventHandlersEventMap {
5
+ 'zn-report-change': ZnReportChangeEvent;
6
+ }
7
+ }
@@ -1,5 +1,5 @@
1
1
  .form-control-input {
2
- margin: var(--zn-spacing-2x-small) 3px 3px 0;
2
+ margin: var(--zn-form-control-input-margin, var(--zn-spacing-2x-small) 3px 3px 0);
3
3
  }
4
4
 
5
5
  .form-control-input--flush {
@@ -15,12 +15,13 @@
15
15
  }
16
16
 
17
17
  /* Label */
18
+ // Inline-block sits in the inherited line box, which can be taller than the label; block sizes it to its own line.
18
19
  .form-control--has-label .form-control__label {
19
- display: inline-block;
20
+ display: var(--zn-input-label-display, inline-block);
20
21
  color: var(--zn-input-label-color);
21
22
  font-weight: var(--zn-input-label-font-weight);
22
23
  line-height: var(--zn-input-label-line-height);
23
- margin-bottom: var(--zn-spacing-x-small);
24
+ margin-bottom: var(--zn-input-label-spacing, var(--zn-spacing-x-small));
24
25
  }
25
26
 
26
27
  .form-control--has-label.form-control--medium .form-control__label {
@@ -37,6 +38,28 @@
37
38
  color: var(--zn-input-required-content-color);
38
39
  }
39
40
 
41
+ .form-control__label-note {
42
+ margin-inline-start: var(--zn-input-label-note-offset, var(--zn-spacing-2x-small));
43
+ color: var(--zn-input-help-text-color);
44
+ font-weight: var(--zn-font-weight-normal, 400);
45
+ }
46
+
47
+ .form-control--has-label-tooltip .form-control__label-note {
48
+ margin-inline-start: 0;
49
+ }
50
+
51
+ .form-control--small .form-control__label-note {
52
+ font-size: var(--zn-input-help-text-font-size-small);
53
+ }
54
+
55
+ .form-control--medium .form-control__label-note {
56
+ font-size: var(--zn-input-help-text-font-size-medium);
57
+ }
58
+
59
+ .form-control--large .form-control__label-note {
60
+ font-size: var(--zn-input-help-text-font-size-large);
61
+ }
62
+
40
63
  .form-control--has-label.form-control--radio-group .form-control__label,
41
64
  .form-control--has-label.form-control--checkbox-group .form-control__label {
42
65
  margin-bottom: 0;
@@ -60,6 +83,11 @@
60
83
  zn-icon {
61
84
  --icon-color: var(--zn-color-neutral-700);
62
85
  --icon-size: var(--zn-font-size-small);
86
+
87
+ &:focus-visible {
88
+ outline: var(--zn-focus-ring);
89
+ border-radius: var(--zn-border-radius-small);
90
+ }
63
91
  }
64
92
  }
65
93
 
@@ -100,6 +128,11 @@
100
128
  margin-top: var(--zn-spacing-small);
101
129
  }
102
130
 
131
+ // Unset, the declaration is invalid at computed time and the line height inherits as before.
132
+ .form-control--has-help-text .form-control__help-text {
133
+ line-height: var(--zn-input-help-text-line-height);
134
+ }
135
+
103
136
  .form-control--has-help-text.form-control--small .form-control__help-text {
104
137
  font-size: var(--zn-input-help-text-font-size-small);
105
138
  }
@@ -0,0 +1,175 @@
1
+ import type {ReactiveController, ReactiveControllerHost} from 'lit';
2
+
3
+ export type PopoverHideReason = 'escape' | 'outside' | 'api';
4
+
5
+ interface AnchoredPopoverOptions {
6
+ /** Selector, in the host's shadow root, of the element the popover hangs from. */
7
+ trigger: string;
8
+ /** Selector, in the host's shadow root, of the popover. */
9
+ popover: string;
10
+ /** The popover's rendered width in px, used to keep it on screen. */
11
+ width: () => number;
12
+ /** Which trigger edge the popover lines up with; it flips when that would run off screen. */
13
+ align: 'start' | 'end';
14
+ /** Called whenever the popover closes, with how it was closed. */
15
+ onHide?: (reason: PopoverHideReason) => void;
16
+ /**
17
+ * Selectors, in the popover, tried in order for the element to focus once it opens. When set, focus goes back to the
18
+ * trigger as it closes, unless it has already moved somewhere else.
19
+ */
20
+ focus?: string[];
21
+ }
22
+
23
+ /**
24
+ * A fixed-position popover anchored under a trigger in the host's shadow root, closed by Escape or a click outside
25
+ * both. Fixed so a panel's overflow can't clip it.
26
+ */
27
+ export class AnchoredPopoverController implements ReactiveController {
28
+ open = false;
29
+ position = {top: 0, left: 0};
30
+ private readonly host: ReactiveControllerHost & HTMLElement;
31
+ private readonly opts: AnchoredPopoverOptions;
32
+ private observed: HTMLElement | null = null;
33
+ // Children such as zn-input render after the host, so the height settles later; refitting inside the callback
34
+ // itself trips WebKit's ResizeObserver loop error
35
+ private readonly resizes = new ResizeObserver(() => requestAnimationFrame(() => this.refit()));
36
+
37
+ constructor(host: ReactiveControllerHost & HTMLElement, opts: AnchoredPopoverOptions) {
38
+ this.host = host;
39
+ this.opts = opts;
40
+ host.addController(this);
41
+ }
42
+
43
+ hostConnected() {
44
+ this.host.addEventListener('keydown', this.keydown);
45
+ document.addEventListener('keydown', this.keydown);
46
+ document.addEventListener('click', this.outsideClick);
47
+ window.addEventListener('resize', this.reposition);
48
+ window.addEventListener('scroll', this.reposition, true);
49
+ }
50
+
51
+ hostDisconnected() {
52
+ this.host.removeEventListener('keydown', this.keydown);
53
+ document.removeEventListener('keydown', this.keydown);
54
+ document.removeEventListener('click', this.outsideClick);
55
+ window.removeEventListener('resize', this.reposition);
56
+ window.removeEventListener('scroll', this.reposition, true);
57
+ this.resizes.disconnect();
58
+ this.observed = null;
59
+ }
60
+
61
+ // The height is only known once rendered; a fixed popover running off the bottom can't be scrolled to
62
+ hostUpdated() {
63
+ const pop = this.open ? this.popover() : null;
64
+ if (pop !== this.observed) {
65
+ this.resizes.disconnect();
66
+ if (pop) this.resizes.observe(pop);
67
+ this.observed = pop;
68
+ }
69
+ this.refit();
70
+ }
71
+
72
+ private refit() {
73
+ if (!this.open) return;
74
+ const top = this.position.top;
75
+ this.place();
76
+ if (this.position.top !== top) {
77
+ this.host.requestUpdate();
78
+ }
79
+ }
80
+
81
+ get style(): string {
82
+ return `top: ${this.position.top}px; left: ${this.position.left}px`;
83
+ }
84
+
85
+ show() {
86
+ this.place();
87
+ this.open = true;
88
+ this.host.requestUpdate();
89
+ const selectors = this.opts.focus;
90
+ if (selectors) {
91
+ void this.host.updateComplete.then(() => {
92
+ const pop = this.popover();
93
+ selectors.map(selector => pop?.querySelector<HTMLElement>(selector)).find(Boolean)?.focus();
94
+ });
95
+ }
96
+ }
97
+
98
+ hide(reason: PopoverHideReason = 'api') {
99
+ if (!this.open) return;
100
+ if (this.opts.focus && this.focusIsLost()) {
101
+ this.focusTrigger();
102
+ }
103
+ this.open = false;
104
+ this.host.requestUpdate();
105
+ this.opts.onHide?.(reason);
106
+ }
107
+
108
+ trigger(): HTMLElement | null {
109
+ return this.host.shadowRoot?.querySelector<HTMLElement>(this.opts.trigger) ?? null;
110
+ }
111
+
112
+ private popover(): HTMLElement | null {
113
+ return this.host.shadowRoot?.querySelector<HTMLElement>(this.opts.popover) ?? null;
114
+ }
115
+
116
+ private focusIsLost(): boolean {
117
+ const active = this.host.shadowRoot?.activeElement;
118
+ if (active) return !!this.popover()?.contains(active);
119
+ return !document.activeElement || document.activeElement === document.body;
120
+ }
121
+
122
+ private focusTrigger() {
123
+ const trigger = this.trigger();
124
+ (trigger?.shadowRoot?.querySelector<HTMLElement>('button, a') ?? trigger)?.focus();
125
+ }
126
+
127
+ private place() {
128
+ const trigger = this.trigger();
129
+ if (!trigger) return;
130
+ const rect = trigger.getBoundingClientRect();
131
+ const width = this.opts.width();
132
+ const start = rect.left;
133
+ const end = rect.right - width;
134
+ const fitsStart = start + width <= window.innerWidth - 8;
135
+ const fitsEnd = end >= 8;
136
+ const left = this.opts.align === 'start'
137
+ ? (fitsStart || !fitsEnd ? start : end)
138
+ : (fitsEnd || !fitsStart ? end : start);
139
+ const height = this.popover()?.offsetHeight ?? 0;
140
+ const below = rect.bottom + 4;
141
+ const above = rect.top - 4 - height;
142
+ let top = below;
143
+ if (below + height > window.innerHeight - 8) {
144
+ top = above >= 8 ? above : Math.max(8, window.innerHeight - height - 8);
145
+ }
146
+ this.position = {
147
+ top,
148
+ left: Math.max(8, Math.min(left, window.innerWidth - width - 8)),
149
+ };
150
+ }
151
+
152
+ private outsideClick = (e: MouseEvent) => {
153
+ if (!this.open) return;
154
+ const path = e.composedPath();
155
+ const pop = this.popover();
156
+ const trigger = this.trigger();
157
+ if ((pop && path.includes(pop)) || (trigger && path.includes(trigger))) return;
158
+ this.hide('outside');
159
+ };
160
+
161
+ // Also bound on the host so it runs before an enclosing dialog's own Escape handling
162
+ private keydown = (e: KeyboardEvent) => {
163
+ if (e.key !== 'Escape' || !this.open) return;
164
+ e.stopPropagation();
165
+ e.preventDefault();
166
+ this.hide('escape');
167
+ };
168
+
169
+ private reposition = () => {
170
+ if (this.open) {
171
+ this.place();
172
+ this.host.requestUpdate();
173
+ }
174
+ };
175
+ }
@@ -1,22 +1,36 @@
1
+ // Keep in sync with --zn-ease-* in scss/themes/_light.scss; WAAPI easing can't read var().
2
+ export const EASE_OUT = 'cubic-bezier(0.23, 1, 0.32, 1)';
3
+ export const EASE_DRAWER = 'cubic-bezier(0.32, 0.72, 0, 1)';
4
+
1
5
  /**
2
6
  * Animates an element using keyframes. Returns a promise that resolves after the animation completes or gets canceled.
3
7
  */
4
- export function animateTo(el: HTMLElement, keyframes: Keyframe[], options?: KeyframeAnimationOptions) {
8
+ export function animateTo(el: Element, keyframes: Keyframe[], options?: KeyframeAnimationOptions) {
5
9
  return new Promise(resolve => {
6
10
  if (options?.duration === Infinity) {
7
11
  throw new Error('Promise-based animations must be finite.');
8
12
  }
9
13
 
10
- const animation = el.animate(keyframes, {
11
- ...options,
12
- duration: prefersReducedMotion() ? 0 : options!.duration
13
- });
14
+ let animation: Animation;
15
+ if (prefersReducedMotion()) {
16
+ const fade = reduceKeyframes(keyframes);
17
+ const fades = fade.some(keyframe => 'opacity' in keyframe);
18
+ animation = el.animate(fade, {...options, duration: fades ? Math.min(Number(options?.duration ?? 0), 150) : 0});
19
+ } else {
20
+ animation = el.animate(keyframes, options);
21
+ }
14
22
 
15
23
  animation.addEventListener('cancel', resolve, {once: true});
16
24
  animation.addEventListener('finish', resolve, {once: true});
17
25
  });
18
26
  }
19
27
 
28
+ /** Keeps only the opacity of each keyframe: fades still aid comprehension under reduced motion, movement doesn't. */
29
+ function reduceKeyframes(keyframes: Keyframe[]): Keyframe[] {
30
+ const kept = ['offset', 'easing', 'composite', 'opacity'];
31
+ return keyframes.map(keyframe => Object.fromEntries(Object.entries(keyframe).filter(([key]) => kept.includes(key))));
32
+ }
33
+
20
34
  /** Parses a CSS duration and returns the number of milliseconds. */
21
35
  export function parseDuration(delay: number | string) {
22
36
  delay = delay.toString().toLowerCase();
@@ -0,0 +1,15 @@
1
+ let registered = false;
2
+
3
+ /** Registers `--rotate` so the cosmic border's gradient can animate; `@property` rules inside a shadow root are ignored. */
4
+ export function registerCosmicBorder() {
5
+ if (registered || !window.CSS.registerProperty) {
6
+ return;
7
+ }
8
+
9
+ registered = true;
10
+ try {
11
+ window.CSS.registerProperty({name: '--rotate', syntax: '<angle>', inherits: false, initialValue: '0deg'});
12
+ } catch {
13
+ // Already registered by another copy of zinc on the page
14
+ }
15
+ }
@@ -442,7 +442,7 @@ export class FormControlController implements ReactiveController {
442
442
  this.host.isConnected &&
443
443
  !disabled &&
444
444
  !isButton &&
445
- name.length > 0 &&
445
+ !!name &&
446
446
  typeof value !== 'undefined'
447
447
  ) {
448
448
  const isPassword = (this.host as HTMLElement & { type?: string }).type === 'password';
@@ -0,0 +1,15 @@
1
+ /** How long the pointer must rest on an element before hover preloading starts. */
2
+ export const HOVER_INTENT_DELAY = 150;
3
+
4
+ /**
5
+ * Calls `callback` once the pointer has rested on `element` for `delay` ms. Preloads hang off this
6
+ * so sweeping across a row of tabs doesn't fetch and render every panel on the way past.
7
+ */
8
+ export function onHoverIntent(element: HTMLElement, callback: () => void, delay = HOVER_INTENT_DELAY): void {
9
+ let timer = 0;
10
+ element.addEventListener('mouseenter', () => {
11
+ clearTimeout(timer);
12
+ timer = window.setTimeout(callback, delay);
13
+ });
14
+ element.addEventListener('mouseleave', () => clearTimeout(timer));
15
+ }
@@ -0,0 +1,15 @@
1
+ let lastPointerAt = -Infinity;
2
+ let lastPointerPath: EventTarget[] = [];
3
+ let lastKeyAt = -Infinity;
4
+
5
+ // Capture phase, so a component that stops propagation can't hide the input.
6
+ document.addEventListener('pointerdown', (e) => {
7
+ lastPointerAt = performance.now();
8
+ lastPointerPath = e.composedPath();
9
+ }, {capture: true, passive: true});
10
+ document.addEventListener('keydown', () => (lastKeyAt = performance.now()), {capture: true, passive: true});
11
+
12
+ /** Whether the latest user input was a pointer press inside `within`, made within the last `withinMs`. */
13
+ export function pointerInitiated(within: Element, withinMs = 300): boolean {
14
+ return lastPointerAt > lastKeyAt && performance.now() - lastPointerAt < withinMs && lastPointerPath.includes(within);
15
+ }
@@ -0,0 +1,37 @@
1
+ import type {ReactiveController, ReactiveControllerHost} from 'lit';
2
+
3
+ /**
4
+ * Tells a control whether its latest state change came from a pointer press, so keyboard and
5
+ * programmatic changes (arrow keys, select-all, value sync) can skip their animation.
6
+ */
7
+ export class PointerIntentController implements ReactiveController {
8
+ private host: ReactiveControllerHost & HTMLElement;
9
+ private pressed = false;
10
+ private readonly handlePointerDown = () => (this.pressed = true);
11
+ private readonly handleKeyDown = () => (this.pressed = false);
12
+ // A press that changed nothing (dragged off, disabled) mustn't leak into the next change
13
+ private readonly handleClick = () => setTimeout(() => (this.pressed = false));
14
+
15
+ constructor(host: ReactiveControllerHost & HTMLElement) {
16
+ (this.host = host).addController(this);
17
+ }
18
+
19
+ hostConnected() {
20
+ this.host.addEventListener('pointerdown', this.handlePointerDown);
21
+ this.host.addEventListener('keydown', this.handleKeyDown);
22
+ this.host.addEventListener('click', this.handleClick);
23
+ }
24
+
25
+ hostDisconnected() {
26
+ this.host.removeEventListener('pointerdown', this.handlePointerDown);
27
+ this.host.removeEventListener('keydown', this.handleKeyDown);
28
+ this.host.removeEventListener('click', this.handleClick);
29
+ }
30
+
31
+ /** Whether the change being handled now was pointer-initiated. Call synchronously from the state-change handler. */
32
+ consume() {
33
+ const pressed = this.pressed;
34
+ this.pressed = false;
35
+ return pressed;
36
+ }
37
+ }