@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
@@ -14,14 +14,16 @@
14
14
  * --zn-text-<role>-transform
15
15
  * --zn-text-<role>-letter-spacing
16
16
  *
17
- * All roles use the sans family (--zn-font-sans). Apply a role
18
- * in a component with the text-style() mixin from scss/mixins.
17
+ * Roles use the sans family (--zn-font-sans) unless a theme sets
18
+ * --zn-text-<role>-font-family. Apply a role in a component with
19
+ * the text-style() mixin from scss/mixins.
19
20
  *************************************************************/
20
21
 
21
22
  $text-styles: (
22
23
  "paragraph": ("size": 14px, "line": 21px, "spacing": 21px, "weight": normal, "color": default, "transform": none),
23
24
  "table-content": ("size": 14px, "line": 16px, "spacing": 15px, "weight": normal, "color": default, "transform": none),
24
25
  "chat": ("size": 16px, "line": 24px, "spacing": 15px, "weight": normal, "color": default, "transform": none),
26
+ "page-title": ("size": 16px, "line": 16px, "spacing": 18px, "weight": semibold, "color": default, "transform": none),
25
27
  "h1": ("size": 16px, "line": 16px, "spacing": 18px, "weight": semibold, "color": default, "transform": none),
26
28
  "h2": ("size": 14px, "line": 16px, "spacing": 15px, "weight": semibold, "color": default, "transform": none),
27
29
  "h3": ("size": 11px, "line": 16px, "spacing": 15px, "weight": semibold, "color": default, "transform": none),
@@ -1,10 +1 @@
1
1
  @forward "spacing";
2
-
3
- @keyframes rotate-gradient {
4
- from {
5
- --rotate: 0deg;
6
- }
7
- to {
8
- --rotate: 360deg;
9
- }
10
- }
@@ -1,6 +1,7 @@
1
1
  import {classMap} from "lit/directives/class-map.js";
2
2
  import {type CSSResultGroup, html, unsafeCSS} from 'lit';
3
3
  import {property} from 'lit/decorators.js';
4
+ import {registerCosmicBorder} from "../../internal/cosmic-border";
4
5
  import ZincElement from '../../internal/zinc-element';
5
6
 
6
7
  import styles from './alert.scss';
@@ -26,24 +27,33 @@ export default class ZnAlert extends ZincElement {
26
27
  static styles: CSSResultGroup = unsafeCSS(styles);
27
28
 
28
29
  @property({type: String}) icon: string = '';
30
+ /** The status icon's size in pixels. */
31
+ @property({attribute: 'icon-size', type: Number}) iconSize = 24;
29
32
  @property({type: String}) caption: string = '';
30
33
  @property({type: Boolean}) collapse: boolean = false;
31
34
  @property({type: String, reflect: true}) appearance: 'transparent' | 'solid' = 'transparent';
32
- @property({type: String}) level: 'primary' | 'error' | 'info' | 'success' | 'warning' | 'note' | 'cosmic' = 'info';
35
+ /** `ai` marks AI-generated content only. */
36
+ @property({type: String}) level: 'primary' | 'error' | 'info' | 'success' | 'warning' | 'note' | 'cosmic' | 'ai' = 'info';
33
37
  @property({type: Boolean, reflect: true}) center: boolean = false;
34
38
  @property({type: String}) size: 'small' | 'medium' | 'large' = 'medium';
35
39
 
40
+ connectedCallback() {
41
+ super.connectedCallback();
42
+ registerCosmicBorder();
43
+ }
44
+
36
45
  render() {
37
46
  let icon;
38
47
 
39
48
  if (this.icon) {
40
49
  if (this.collapse) {
41
50
  icon = this.icon ? html`
42
- <zn-icon class="alert-icon" src="${this.icon}" id="xy2" @click="${this.hideAlert}"
43
- style="cursor: pointer"></zn-icon>` : "";
51
+ <button type="button" class="alert-dismiss" aria-label="Dismiss" @click="${this.hideAlert}">
52
+ <zn-icon class="alert-icon" src="${this.icon}" size="${this.iconSize}" id="xy2"></zn-icon>
53
+ </button>` : "";
44
54
  } else {
45
55
  icon = this.icon ? html`
46
- <zn-icon class="alert-icon" src="${this.icon}" id="xy2"></zn-icon>` : '';
56
+ <zn-icon class="alert-icon" src="${this.icon}" size="${this.iconSize}" id="xy2"></zn-icon>` : '';
47
57
  }
48
58
  }
49
59
 
@@ -5,19 +5,39 @@
5
5
  display: flex;
6
6
  justify-content: flex-start;
7
7
  align-items: center;
8
- border-radius: 10px;
8
+ border-radius: var(--zn-alert-border-radius, 10px);
9
9
  }
10
10
 
11
11
  :host {
12
- background-color: rgba(var(--zn-panel), 0.8);
12
+ background-color: var(--zn-alert-background, rgba(var(--zn-panel), 0.8));
13
13
  }
14
14
 
15
15
  :host([appearance="solid"]) {
16
- background-color: rgb(var(--zn-panel));
16
+ background-color: var(--zn-alert-solid-background, rgb(var(--zn-panel)));
17
+ }
18
+
19
+ .alert-dismiss {
20
+ display: inline-flex;
21
+ padding: 0;
22
+ border: 0;
23
+ background: none;
24
+ color: inherit;
25
+ cursor: pointer;
26
+
27
+ &:focus-visible {
28
+ outline: var(--zn-focus-ring);
29
+ border-radius: var(--zn-border-radius-small);
30
+ }
17
31
  }
18
32
 
19
33
  .alert-icon {
20
- padding: var(--zn-spacing-2x-small) var(--zn-spacing-x-small);
34
+ padding: var(--zn-alert-icon-padding, var(--zn-spacing-2x-small) var(--zn-spacing-x-small));
35
+ margin-top: var(--zn-alert-icon-offset, 0);
36
+ }
37
+
38
+ // zn-icon draws lucide icons at its own stroke; a theme can lighten the status icon's
39
+ .alert-icon::part(icon) {
40
+ stroke-width: var(--zn-alert-icon-stroke-width, 2.1);
21
41
  }
22
42
 
23
43
  p {
@@ -35,6 +55,8 @@ p {
35
55
  // which is not where alerts sit.
36
56
  .wrapper {
37
57
  position: relative;
58
+ align-items: var(--zn-alert-align-items, center);
59
+ gap: var(--zn-alert-gap, 0);
38
60
  border: 1px solid rgb(var(--zn-border-color)) !important;
39
61
  width: 100%;
40
62
  height: 100%;
@@ -55,7 +77,8 @@ p {
55
77
  flex-grow: 1;
56
78
  align-self: start;
57
79
  text-align: left;
58
- padding: 8px;
80
+ padding: var(--zn-alert-content-padding, 8px);
81
+ color: var(--zn-alert-body-color, inherit);
59
82
 
60
83
  > h6 {
61
84
  font-size: inherit;
@@ -81,78 +104,41 @@ p {
81
104
  background: rgba(var(--zn-panel), .05);
82
105
  }
83
106
 
84
- :host([level="primary"]) .wrapper {
85
- h6 {
86
- color: rgb(var(--zn-primary));
87
- }
88
-
89
- border-color: rgb(var(--zn-primary)) !important;
90
- background: rgba(var(--zn-primary), .05);
91
-
92
- zn-icon {
93
- --icon-color: rgb(var(--zn-primary));
94
- }
95
- }
96
-
97
- :host([level="error"]) .wrapper {
98
- h6 {
99
- color: rgb(var(--zn-color-error));
100
- }
101
-
102
- border-color: rgb(var(--zn-color-error)) !important;
103
- background: rgba(var(--zn-color-error), .05);
104
-
105
- zn-icon {
106
- --icon-color: rgb(var(--zn-color-error));
107
- }
108
- }
109
-
110
- :host([level="info"]) .wrapper {
111
- h6 {
112
- color: rgb(var(--zn-color-info));
113
- }
107
+ // Each level paints from one RGB triplet: the title and border in the colour,
108
+ // the wrapper a light tint of it. A theme can soften the border and deepen the
109
+ // tint through the alpha tokens, or give titles a neutral colour.
110
+ @each $level, $rgb, $role in (
111
+ (primary, var(--zn-primary), primary),
112
+ (error, var(--zn-color-error), danger),
113
+ (info, var(--zn-color-info), info),
114
+ (warning, var(--zn-color-warning), warning),
115
+ (success, var(--zn-color-success), success),
116
+ (ai, var(--zn-color-ai), ai)
117
+ ) {
118
+ :host([level="#{$level}"]) .wrapper {
119
+ h6 {
120
+ color: var(--zn-alert-title-color, rgb(#{$rgb}));
121
+ }
114
122
 
115
- border-color: rgb(var(--zn-color-info)) !important;
116
- background: rgba(var(--zn-color-info), .05);
123
+ border-color: rgba(#{$rgb}, var(--zn-alert-border-alpha, 1)) !important;
124
+ background: rgba(#{$rgb}, var(--zn-alert-tint-alpha, .05));
117
125
 
118
- zn-icon {
119
- --icon-color: rgb(var(--zn-color-info));
126
+ zn-icon {
127
+ @if $role == primary {
128
+ --icon-color: rgb(#{$rgb});
129
+ } @else {
130
+ --icon-color: var(--zn-color-#{$role}-fg);
131
+ }
132
+ }
120
133
  }
121
134
  }
122
135
 
123
- :host([level="warning"]) .wrapper {
124
- h6 {
125
- color: rgb(var(--zn-color-warning));
126
- }
127
-
128
- border-color: rgb(var(--zn-color-warning)) !important;
129
- background: rgba(var(--zn-color-warning), .05);
130
-
131
- zn-icon {
132
- --icon-color: rgb(var(--zn-color-warning));
133
- }
134
- }
135
-
136
- :host([level="success"]) .wrapper {
137
- h6 {
138
- color: rgb(var(--zn-color-success));
139
- }
140
-
141
- border-color: rgb(var(--zn-color-success)) !important;
142
- background: rgba(var(--zn-color-success), .05);
143
-
144
- zn-icon {
145
- --icon-color: rgb(var(--zn-color-success));
146
- }
147
- }
148
-
149
-
150
136
  :host([level="note"]) .wrapper {
151
137
  h6 {
152
- color: var(--zn-color-gray-800);
138
+ color: var(--zn-alert-title-color, var(--zn-color-gray-800));
153
139
  }
154
140
 
155
- border-color: var(--zn-color-gray-500) !important;
141
+ border-color: var(--zn-alert-note-border-color, var(--zn-color-gray-500)) !important;
156
142
  background: var(--zn-color-gray-100);
157
143
 
158
144
  zn-icon {
@@ -167,7 +153,7 @@ p {
167
153
  }
168
154
 
169
155
  &--medium {
170
- padding: var(--zn-spacing-x-small) var(--zn-spacing-small);
156
+ padding: var(--zn-alert-padding, var(--zn-spacing-x-small) var(--zn-spacing-small));
171
157
  font-size: 100%;
172
158
  }
173
159
 
@@ -7,4 +7,12 @@ describe('<zn-alert>', () => {
7
7
 
8
8
  expect(el).to.exist;
9
9
  });
10
+
11
+ it('tints an ai alert from the ai colour', async () => {
12
+ const el = await fixture<HTMLElement>(html`
13
+ <zn-alert level="ai" caption="Suggested" style="--zn-color-ai: 1, 2, 3">Drafted for you.</zn-alert>`);
14
+ const wrapper = el.shadowRoot!.querySelector('.wrapper')!;
15
+
16
+ expect(getComputedStyle(wrapper).borderTopColor).to.equal('rgb(1, 2, 3)');
17
+ });
10
18
  });
@@ -142,7 +142,7 @@ export default class ZnAnimatedButton extends ZincElement {
142
142
  }
143
143
 
144
144
  protected render() {
145
- const isDisabled = this.disabled || this.currentState !== 'idle';
145
+ const isBusy = this.currentState !== 'idle';
146
146
  const showSpinner = this.currentState === 'processing';
147
147
  const showSuccess = this.currentState === 'success';
148
148
  const showFailure = this.currentState === 'failure';
@@ -163,7 +163,8 @@ export default class ZnAnimatedButton extends ZincElement {
163
163
  return html`
164
164
  <button
165
165
  class=${classMap(classes)}
166
- ?disabled=${isDisabled}
166
+ ?disabled=${this.disabled}
167
+ aria-disabled=${isBusy ? 'true' : 'false'}
167
168
  @click=${this.handleClick}
168
169
  type="button"
169
170
  aria-live="polite"
@@ -1,4 +1,5 @@
1
1
  @use "../../../scss/shared/button-mixin" as shared;
2
+ @use "../../wc";
2
3
 
3
4
  :host {
4
5
  display: inline-block;
@@ -24,11 +25,11 @@
24
25
  font-family: inherit;
25
26
  cursor: pointer;
26
27
 
27
- &:hover:not(:disabled) {
28
+ &:hover:not(:disabled, [aria-disabled='true']) {
28
29
  opacity: 0.9;
29
30
  }
30
31
 
31
- &:active:not(:disabled) {
32
+ &:active:not(:disabled, [aria-disabled='true']) {
32
33
  transform: scale(0.98);
33
34
  }
34
35
 
@@ -64,23 +65,14 @@
64
65
  .animated-button__spinner {
65
66
  display: inline-flex;
66
67
  flex-shrink: 0;
67
- animation: spin 1s linear infinite;
68
- }
69
-
70
- @keyframes spin {
71
- from {
72
- transform: rotate(0deg);
73
- }
74
- to {
75
- transform: rotate(360deg);
76
- }
68
+ @include wc.spin;
77
69
  }
78
70
 
79
71
  // Shimmer animation for processing state
80
72
  .animated-button__shimmer {
81
73
  position: absolute;
82
74
  top: 0;
83
- left: -100%;
75
+ left: 0;
84
76
  width: 100%;
85
77
  height: 100%;
86
78
  background: linear-gradient(
@@ -89,16 +81,7 @@
89
81
  rgba(255, 255, 255, 0.3) 50%,
90
82
  rgba(255, 255, 255, 0) 100%
91
83
  );
92
- animation: shimmer 1.5s infinite;
93
- }
94
-
95
- @keyframes shimmer {
96
- 0% {
97
- left: -100%;
98
- }
99
- 100% {
100
- left: 100%;
101
- }
84
+ @include wc.sweep(1.5s, $easing: ease);
102
85
  }
103
86
 
104
87
  // State: Idle (default blue)
@@ -22,16 +22,17 @@ describe('<zn-animated-button>', () => {
22
22
  expect(button?.textContent?.trim()).to.equal('Buy Now');
23
23
  });
24
24
 
25
- it('should be disabled when processing', async () => {
25
+ it('should be aria-disabled but focusable when processing', async () => {
26
26
  const el = await fixture<ZnAnimatedButton>(html`<zn-animated-button></zn-animated-button>`);
27
27
  const button = el.shadowRoot?.querySelector('button') as HTMLButtonElement;
28
28
 
29
- expect(button.disabled).to.be.false;
29
+ expect(button.getAttribute('aria-disabled')).to.not.equal('true');
30
30
 
31
31
  button.click();
32
32
  await el.updateComplete;
33
33
 
34
- expect(button.disabled).to.be.true;
34
+ expect(button.getAttribute('aria-disabled')).to.equal('true');
35
+ expect(button.disabled).to.be.false;
35
36
  });
36
37
 
37
38
  it('should emit zn-purchase event when clicked', async () => {
@@ -0,0 +1,84 @@
1
+ import {type CSSResultGroup, html, unsafeCSS} from 'lit';
2
+ import {MutationController} from '@lit-labs/observers/mutation-controller.js';
3
+ import {property, state} from 'lit/decorators.js';
4
+ import ZincElement from '../../internal/zinc-element';
5
+ import ZnTooltip from '../tooltip';
6
+
7
+ import styles from './avatar-group.scss';
8
+
9
+ /**
10
+ * @summary Overlapping avatars that show each person's name on hover, collapsing any past `max` into a "+N" count.
11
+ * @documentation https://zinc.style/components/avatar-group
12
+ * @status experimental
13
+ * @since 1.0
14
+ *
15
+ * @dependency zn-tooltip
16
+ *
17
+ * @slot - `zn-icon` avatars. Each one's tooltip shows its `alt`, or its `src` when it has none.
18
+ *
19
+ * @csspart base - The component's base wrapper.
20
+ * @csspart overflow - The "+N" count standing in for the avatars past `max`.
21
+ *
22
+ * @cssproperty --zn-avatar-ring-color - The ring that separates overlapping avatars; defaults to the panel surface.
23
+ */
24
+ export default class ZnAvatarGroup extends ZincElement {
25
+ static styles: CSSResultGroup = unsafeCSS(styles);
26
+ static dependencies = {
27
+ 'zn-tooltip': ZnTooltip,
28
+ };
29
+
30
+ /** The most avatars to show; the rest are counted in a "+N" avatar whose tooltip lists them. 0 shows them all. */
31
+ @property({type: Number}) max = 0;
32
+
33
+ @state() private _avatars: HTMLElement[] = [];
34
+
35
+ constructor() {
36
+ super();
37
+ // eslint-disable-next-line no-new
38
+ new MutationController(this, {
39
+ config: {childList: true, subtree: true, attributes: true, attributeFilter: ['src', 'alt', 'size']},
40
+ callback: () => this._syncAvatars(),
41
+ });
42
+ }
43
+
44
+ connectedCallback() {
45
+ super.connectedCallback();
46
+ this._syncAvatars();
47
+ }
48
+
49
+ // Each avatar is routed to its own slot so it can sit inside a tooltip of its own
50
+ private _syncAvatars() {
51
+ this._avatars = [...this.children].filter((el): el is HTMLElement => el instanceof HTMLElement);
52
+ this._avatars.forEach((avatar, i) => {
53
+ const slot = `avatar-${i}`;
54
+ if (avatar.slot !== slot) avatar.slot = slot;
55
+ // The ring and overlap are circular, so a square avatar would show its corners outside them
56
+ if (!avatar.hasAttribute('round')) avatar.setAttribute('round', '');
57
+ });
58
+ }
59
+
60
+ private _name(avatar: HTMLElement) {
61
+ return avatar.getAttribute('alt') || avatar.getAttribute('src') || avatar.textContent?.trim() || '';
62
+ }
63
+
64
+ render() {
65
+ const shown = this.max > 0 && this._avatars.length > this.max ? this._avatars.slice(0, this.max) : this._avatars;
66
+ const hidden = this._avatars.slice(shown.length);
67
+ const hiddenNames = hidden.map(avatar => this._name(avatar)).filter(Boolean).join(', ');
68
+ const size = (shown[0] as HTMLElement & { size?: number })?.size;
69
+
70
+ return html`
71
+ <div part="base" class="avatar-group" role="group">
72
+ ${shown.map((avatar, i) => html`
73
+ <zn-tooltip content="${this._name(avatar)}">
74
+ <slot name="avatar-${i}"></slot>
75
+ </zn-tooltip>`)}
76
+ ${hidden.length > 0 ? html`
77
+ <zn-tooltip content="${hiddenNames}">
78
+ <span part="overflow" class="avatar-group__overflow" tabindex="0" role="img"
79
+ aria-label="${hidden.length} more: ${hiddenNames}"
80
+ style="${size ? `--avatar-size: ${size}px` : ''}">+${hidden.length}</span>
81
+ </zn-tooltip>` : ''}
82
+ </div>`;
83
+ }
84
+ }
@@ -0,0 +1,54 @@
1
+ @use "../../wc";
2
+
3
+ :host {
4
+ display: inline-flex;
5
+ vertical-align: middle;
6
+ }
7
+
8
+ .avatar-group {
9
+ display: inline-flex;
10
+ align-items: center;
11
+ }
12
+
13
+ ::slotted(zn-icon),
14
+ .avatar-group__overflow {
15
+ border-radius: 50%;
16
+ // A ring in the surface colour separates each avatar from the one it overlaps
17
+ box-shadow: 0 0 0 2px var(--zn-avatar-ring-color, rgb(var(--zn-panel)));
18
+ }
19
+
20
+ ::slotted(zn-icon:not([slot="avatar-0"])),
21
+ .avatar-group__overflow {
22
+ margin-inline-start: -0.4rem;
23
+ }
24
+
25
+ // Lifted over its neighbours so the whole avatar shows while its tooltip is open
26
+ ::slotted(zn-icon:hover) {
27
+ position: relative;
28
+ z-index: 1;
29
+ }
30
+
31
+ // Matches a solid zn-icon avatar in the text colour
32
+ .avatar-group__overflow {
33
+ --avatar-size: 28px;
34
+
35
+ display: inline-flex;
36
+ flex: none;
37
+ align-items: center;
38
+ justify-content: center;
39
+ width: var(--avatar-size);
40
+ height: var(--avatar-size);
41
+ background-color: rgb(var(--zn-text));
42
+ color: rgb(var(--zn-panel));
43
+ font-size: calc(var(--avatar-size) * var(--zn-avatar-font-scale, 0.4167));
44
+ font-weight: var(--zn-avatar-font-weight, var(--zn-font-weight-semibold));
45
+ line-height: 1;
46
+ letter-spacing: .02em;
47
+ cursor: default;
48
+ user-select: none;
49
+
50
+ &:focus-visible {
51
+ outline: 2px solid rgb(var(--zn-primary));
52
+ outline-offset: 2px;
53
+ }
54
+ }
@@ -0,0 +1,59 @@
1
+ import '../../../dist/zn.min.js';
2
+ import {expect, fixture, html} from '@open-wc/testing';
3
+ import type ZnAvatarGroup from './avatar-group.component';
4
+
5
+ describe('<zn-avatar-group>', () => {
6
+ it('should wrap each avatar in a tooltip with its name', async () => {
7
+ const el = await fixture<ZnAvatarGroup>(html`
8
+ <zn-avatar-group>
9
+ <zn-icon src="Ben Brooks" library="avatar"></zn-icon>
10
+ <zn-icon src="JE" alt="Jade Ellis" library="avatar"></zn-icon>
11
+ </zn-avatar-group>
12
+ `);
13
+ await el.updateComplete;
14
+
15
+ const tooltips = [...el.shadowRoot!.querySelectorAll('zn-tooltip')];
16
+ expect(tooltips.map(tooltip => tooltip.getAttribute('content'))).to.deep.equal(['Ben Brooks', 'Jade Ellis']);
17
+ expect(tooltips[0].querySelector('slot')!.assignedElements()[0]).to.equal(el.children[0]);
18
+ });
19
+
20
+ it('should make its avatars round', async () => {
21
+ const el = await fixture<ZnAvatarGroup>(html`
22
+ <zn-avatar-group><zn-icon src="Ben Brooks" library="avatar"></zn-icon></zn-avatar-group>
23
+ `);
24
+ expect(el.children[0].hasAttribute('round')).to.be.true;
25
+ });
26
+
27
+ it('should count the avatars past max and list them in the overflow tooltip', async () => {
28
+ const el = await fixture<ZnAvatarGroup>(html`
29
+ <zn-avatar-group max="2">
30
+ <zn-icon src="Ben Brooks" library="avatar" size="lg"></zn-icon>
31
+ <zn-icon src="Jade Ellis" library="avatar" size="lg"></zn-icon>
32
+ <zn-icon src="Kai Walsh" library="avatar" size="lg"></zn-icon>
33
+ <zn-icon src="Ann Isaacs" library="avatar" size="lg"></zn-icon>
34
+ </zn-avatar-group>
35
+ `);
36
+ await el.updateComplete;
37
+
38
+ const overflow = el.shadowRoot!.querySelector<HTMLElement>('[part="overflow"]')!;
39
+ expect(overflow.textContent!.trim()).to.equal('+2');
40
+ expect(overflow.closest('zn-tooltip')!.getAttribute('content')).to.equal('Kai Walsh, Ann Isaacs');
41
+ expect(overflow.getBoundingClientRect().width).to.equal(40);
42
+ expect((el.children[2] as HTMLElement).getBoundingClientRect().width).to.equal(0);
43
+ });
44
+
45
+ it('should update when avatars are added', async () => {
46
+ const el = await fixture<ZnAvatarGroup>(html`
47
+ <zn-avatar-group><zn-icon src="Ben Brooks" library="avatar"></zn-icon></zn-avatar-group>
48
+ `);
49
+ const added = document.createElement('zn-icon');
50
+ added.setAttribute('src', 'Jade Ellis');
51
+ added.setAttribute('library', 'avatar');
52
+ el.append(added);
53
+ await new Promise(resolve => setTimeout(resolve, 0));
54
+ await el.updateComplete;
55
+
56
+ expect(el.shadowRoot!.querySelectorAll('zn-tooltip')).to.have.length(2);
57
+ expect(added.slot).to.equal('avatar-1');
58
+ });
59
+ });
@@ -0,0 +1,12 @@
1
+ import ZnAvatarGroup from './avatar-group.component';
2
+
3
+ export * from './avatar-group.component';
4
+ export default ZnAvatarGroup;
5
+
6
+ ZnAvatarGroup.define('zn-avatar-group');
7
+
8
+ declare global {
9
+ interface HTMLElementTagNameMap {
10
+ 'zn-avatar-group': ZnAvatarGroup;
11
+ }
12
+ }
@@ -0,0 +1,49 @@
1
+ import {classMap} from "lit/directives/class-map.js";
2
+ import {type CSSResultGroup, html, unsafeCSS} from 'lit';
3
+ import {property} from 'lit/decorators.js';
4
+ import ZincElement from '../../internal/zinc-element';
5
+
6
+ import styles from './badge.scss';
7
+
8
+ /**
9
+ * @summary Badges label the status or category of a record, such as "Active" or "Past due".
10
+ * @documentation https://zinc.style/components/badge
11
+ * @status experimental
12
+ * @since 1.0
13
+ *
14
+ * @dependency zn-icon
15
+ *
16
+ * @slot - The badge's label.
17
+ *
18
+ * @csspart base - The component's base wrapper.
19
+ */
20
+ export default class ZnBadge extends ZincElement {
21
+ static styles: CSSResultGroup = unsafeCSS(styles);
22
+
23
+ /** `ai` marks AI-generated content only. */
24
+ @property({reflect: true}) type: 'neutral' | 'success' | 'warning' | 'danger' | 'info' | 'ai' = 'neutral';
25
+
26
+ @property({reflect: true}) size: 'medium' | 'large' = 'medium';
27
+
28
+ /** Fills the badge with its type colour. */
29
+ @property({type: Boolean, reflect: true}) solid = false;
30
+
31
+ /** Leads the label with a dot in the type colour. */
32
+ @property({type: Boolean, reflect: true}) dot = false;
33
+
34
+ render() {
35
+ return html`
36
+ <span part="base" class="${classMap({
37
+ 'badge': true,
38
+ [`badge--${this.type}`]: true,
39
+ 'badge--large': this.size === 'large',
40
+ 'badge--solid': this.solid,
41
+ 'badge--dot': this.dot,
42
+ })}">
43
+ ${this.type === 'ai' ? html`
44
+ <zn-icon class="badge__icon" src="sparkle" library="lucide" size="14"></zn-icon>` : ''}
45
+ <slot></slot>
46
+ </span>
47
+ `;
48
+ }
49
+ }