@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
@@ -23,6 +23,8 @@
23
23
  // component-level override.
24
24
  --btn-color: var(--zn-primary);
25
25
  --btn-ink: var(--zn-color-on-primary, 255, 255, 255);
26
+ // The button colour as text on a surface (outline and text buttons).
27
+ --btn-surface-fg: var(--zn-color-primary-fg, rgb(var(--btn-color)));
26
28
  --notification-color: rgb(var(--zn-color-error));
27
29
 
28
30
  border-width: var(--zn-button-border-width, 1px);
@@ -33,27 +35,54 @@
33
35
  border-color: var(--zn-button-border-color, transparent);
34
36
  display: inline-flex;
35
37
  position: relative;
38
+ transition: background-color var(--zn-transition-fast, 150ms) ease,
39
+ border-color var(--zn-transition-fast, 150ms) ease,
40
+ color var(--zn-transition-fast, 150ms) ease,
41
+ transform 160ms var(--zn-ease-out, cubic-bezier(0.23, 1, 0.32, 1));
42
+
43
+ &:active:not([disabled]) {
44
+ transform: scale(0.97);
45
+ }
36
46
 
37
47
  &.button--info {
48
+ --btn-surface-fg: var(--zn-color-info-fg);
38
49
  --btn-color: var(--zn-color-info);
39
50
  --btn-ink: var(--zn-color-on-info, 255, 255, 255);
40
51
  }
41
52
 
42
53
  &.button--error {
54
+ --btn-surface-fg: var(--zn-color-danger-fg);
43
55
  --btn-color: var(--zn-color-error);
44
56
  --btn-ink: var(--zn-color-on-error, 255, 255, 255);
45
57
  }
46
58
 
47
59
  &.button--warning {
60
+ --btn-surface-fg: var(--zn-color-warning-fg);
48
61
  --btn-color: var(--zn-color-warning);
49
62
  --btn-ink: var(--zn-color-on-warning, 255, 255, 255);
50
63
  }
51
64
 
52
65
  &.button--success {
66
+ --btn-surface-fg: var(--zn-color-success-fg);
53
67
  --btn-color: var(--zn-color-success);
54
68
  --btn-ink: var(--zn-color-on-success, 255, 255, 255);
55
69
  }
56
70
 
71
+ &.button--ai {
72
+ --btn-surface-fg: var(--zn-color-ai-fg);
73
+ --btn-color: var(--zn-color-ai);
74
+ --btn-ink: var(--zn-color-on-ai, 255, 255, 255);
75
+ }
76
+
77
+ &.button--small {
78
+ --zn-button-height: var(--zn-button-height-small, 30px);
79
+ font-size: var(--zn-button-font-size-small, var(--zn-text-button-label-font-size));
80
+ }
81
+
82
+ &.button--large {
83
+ --zn-button-height: var(--zn-button-height-large, 40px);
84
+ }
85
+
57
86
  &__label--hidden {
58
87
  visibility: hidden;
59
88
  }
@@ -129,30 +158,41 @@
129
158
 
130
159
  .button--standard {
131
160
  &.button--secondary {
132
- background-color: var(--zn-color-neutral-50);
133
- border-color: var(--zn-button-border-color, var(--zn-color-neutral-50));
134
- color: rgb(var(--zn-primary));
161
+ background-color: var(--zn-button-secondary-background, var(--zn-color-neutral-50));
162
+ border-color: var(--zn-button-border-color, var(--zn-button-secondary-border, var(--zn-color-neutral-50)));
163
+ color: var(--zn-button-secondary-color, rgb(var(--zn-primary)));
135
164
 
136
165
  &:hover:not([disabled]) {
137
- background-color: var(--zn-color-neutral-100)
166
+ background-color: var(--zn-button-secondary-hover-background, var(--zn-color-neutral-100));
138
167
  }
139
168
 
140
169
  &:active:not([disabled]) {
141
- background-color: var(--zn-color-neutral-100)
170
+ background-color: var(--zn-button-secondary-active-background, var(--zn-color-neutral-100));
142
171
  }
143
172
  }
144
173
 
174
+ &.button--ai {
175
+ background-color: var(--zn-color-ai-bg);
176
+ border-color: var(--zn-button-border-color, var(--zn-color-ai-line));
177
+ color: var(--zn-color-ai-fg);
178
+ box-shadow: none;
179
+
180
+ &:hover:not([disabled]), &:active:not([disabled]) {
181
+ background-color: color-mix(in srgb, var(--zn-color-ai-bg), var(--zn-color-ai-line));
182
+ }
183
+ }
145
184
 
146
185
  background-color: rgba(var(--btn-color));
147
186
  border-color: var(--zn-button-border-color, rgb(var(--btn-color)));
148
187
  color: rgba(var(--btn-ink), 0.9);
188
+ box-shadow: var(--zn-button-shadow, none);
149
189
 
150
190
  &:hover:not([disabled]) {
151
- background-color: rgba(var(--btn-color), 0.8);
191
+ background-color: color-mix(in srgb, rgb(var(--btn-color)) var(--zn-button-hover-mix, 80%), var(--zn-button-mix-color, transparent));
152
192
  }
153
193
 
154
194
  &:active:not([disabled]) {
155
- background-color: rgba(var(--btn-color));
195
+ background-color: color-mix(in srgb, rgb(var(--btn-color)) var(--zn-button-active-mix, 100%), var(--zn-button-mix-color, transparent));
156
196
  }
157
197
  }
158
198
 
@@ -163,12 +203,14 @@
163
203
  border-right-width: var(--zn-button-border-right-width, var(--zn-button-border-width, 1px));
164
204
  border-bottom-width: var(--zn-button-border-bottom-width, var(--zn-button-border-width, 1px));
165
205
  border-left-width: var(--zn-button-border-left-width, var(--zn-button-border-width, 1px));
166
- border-color: var(--zn-button-border-color, rgb(var(--btn-color)));
167
- color: rgb(var(--btn-color));
206
+ border-color: var(--zn-button-border-color, rgba(var(--btn-color), var(--zn-button-outline-border-alpha, 1)));
207
+ color: var(--btn-surface-fg);
168
208
 
209
+ // A theme can swap the solid hover for a tint by lowering the alpha and
210
+ // keeping the ink on the button colour (ink mix 0%).
169
211
  &:hover:not([disabled]), &:active:not([disabled]) {
170
- background-color: rgb(var(--btn-color));
171
- color: rgb(var(--btn-ink));
212
+ background-color: rgba(var(--btn-color), var(--zn-button-outline-hover-alpha, 1));
213
+ color: color-mix(in srgb, rgb(var(--btn-ink)) var(--zn-button-outline-hover-ink-mix, 100%), var(--btn-surface-fg));
172
214
  }
173
215
 
174
216
  &.button--secondary {
@@ -184,7 +226,7 @@
184
226
 
185
227
  .button--text {
186
228
  background: none;
187
- color: rgb(var(--btn-color));
229
+ color: var(--btn-surface-fg);
188
230
 
189
231
  &:hover:not([disabled]), &:active:not([disabled]) {
190
232
  background-color: rgba(var(--btn-color), 0.1);
@@ -192,6 +234,12 @@
192
234
 
193
235
  &.button--secondary {
194
236
  font-weight: normal;
237
+ color: var(--zn-button-ghost-color, rgb(var(--btn-color)));
238
+
239
+ &:hover:not([disabled]), &:active:not([disabled]) {
240
+ background-color: var(--zn-button-ghost-hover-background, rgba(var(--btn-color), 0.1));
241
+ color: var(--zn-button-ghost-hover-color, rgb(var(--btn-color)));
242
+ }
195
243
  }
196
244
  }
197
245
 
@@ -227,6 +275,7 @@
227
275
 
228
276
  .button--transparent {
229
277
  background-color: transparent;
278
+ box-shadow: none;
230
279
  border-color: var(--zn-button-border-color, transparent) !important;
231
280
  color: inherit;
232
281
 
@@ -241,6 +290,7 @@
241
290
 
242
291
  .button--star {
243
292
  --btn-color: var(--zn-orange);
293
+ --btn-surface-fg: rgb(var(--btn-color));
244
294
  --btn-ink: var(--zn-color-on-warning, 255, 255, 255);
245
295
  background-color: rgb(var(--btn-color));
246
296
  border-color: var(--zn-button-border-color, rgb(var(--btn-color)));
@@ -281,15 +331,16 @@
281
331
  --icon-button-color: rgb(var(--zn-text));
282
332
  --icon-button-hover-color: rgb(var(--zn-primary));
283
333
 
284
- width: 40px;
285
- min-width: 40px;
286
- height: 36px;
287
- min-height: 36px;
288
- max-height: 36px;
334
+ width: var(--zn-button-icon-width, 40px);
335
+ min-width: var(--zn-button-icon-width, 40px);
336
+ height: var(--zn-button-height, 36px);
337
+ min-height: var(--zn-button-height, 36px);
338
+ max-height: var(--zn-button-height, 36px);
289
339
  padding: 6px;
340
+ box-shadow: var(--zn-button-icon-shadow, none);
290
341
  margin: 0;
291
342
  background: rgb(var(--zn-panel));
292
- border-color: var(--zn-button-border-color, rgb(var(--zn-border-color))) !important;
343
+ border-color: var(--zn-button-border-color, var(--zn-button-icon-border, rgb(var(--zn-border-color)))) !important;
293
344
  border-radius: var(--zn-border-radius);
294
345
  color: var(--icon-button-color);
295
346
  font-weight: inherit;
@@ -309,18 +360,19 @@
309
360
  }
310
361
 
311
362
  &.button--icon-button-small {
312
- width: 36px;
313
- min-width: 36px;
363
+ width: var(--zn-button-height, 36px);
364
+ min-width: var(--zn-button-height, 36px);
314
365
  }
315
366
 
316
367
  // Round: 36x36 circle on the tab tint, muted icon by default
317
368
  &.button--icon-button-round {
318
- width: 36px;
319
- min-width: 36px;
369
+ width: var(--zn-button-height, 36px);
370
+ min-width: var(--zn-button-height, 36px);
320
371
  padding: 8px;
321
372
  background: rgb(var(--zn-color-tab));
322
373
  border-color: var(--zn-button-border-color, transparent) !important;
323
374
  border-radius: var(--zn-border-radius-circle);
375
+ box-shadow: none;
324
376
 
325
377
  &:hover:not([disabled]), &:active:not([disabled]) {
326
378
  background: rgb(var(--zn-color-border));
@@ -330,9 +382,10 @@
330
382
  &.button--plain {
331
383
  background: transparent;
332
384
  border-color: var(--zn-button-border-color, transparent) !important;
385
+ box-shadow: none;
333
386
 
334
387
  &:hover:not([disabled]), &:active:not([disabled]) {
335
- background: rgb(var(--zn-color-tab));
388
+ background: var(--zn-button-plain-hover-background, rgb(var(--zn-color-tab)));
336
389
  }
337
390
  }
338
391
 
@@ -436,19 +489,13 @@
436
489
  border: 2px solid currentColor;
437
490
  border-right-color: transparent;
438
491
  border-radius: 50%;
439
- animation: button-spin .7s linear infinite;
492
+ @include wc.spin(.7s);
440
493
  }
441
494
 
442
495
  .button__label--replaced {
443
496
  display: none;
444
497
  }
445
498
 
446
- @keyframes button-spin {
447
- to {
448
- transform: rotate(360deg);
449
- }
450
- }
451
-
452
499
  .button--relative-wrapper {
453
500
  position: relative;
454
501
  display: inline-flex;
@@ -531,8 +578,10 @@
531
578
  .button.button--pill {
532
579
  border-radius: var(--zn-border-radius-pill);
533
580
  padding: 0 var(--zn-spacing-small);
534
- height: 32px;
535
- min-height: 32px;
581
+ height: var(--zn-button-pill-height, 32px);
582
+ min-height: var(--zn-button-pill-height, 32px);
583
+ max-height: var(--zn-button-pill-height, 32px);
584
+ box-shadow: none;
536
585
  font-weight: var(--zn-font-weight-normal);
537
586
  text-transform: none;
538
587
  white-space: nowrap;
@@ -567,3 +616,37 @@
567
616
  :host([data-zn-button-group__button--panel-bg]) .button:not(.button--icon-button) {
568
617
  @include panel-bg;
569
618
  }
619
+
620
+ @media (prefers-reduced-motion: reduce) {
621
+ .button {
622
+ transition: background-color var(--zn-transition-fast, 150ms) ease,
623
+ border-color var(--zn-transition-fast, 150ms) ease,
624
+ color var(--zn-transition-fast, 150ms) ease;
625
+
626
+ &:active:not([disabled]) {
627
+ transform: none;
628
+ }
629
+ }
630
+ }
631
+
632
+ // Long press menu: the dropdown sits over the button so its panel anchors to the button's box, and lets
633
+ // presses through to the button underneath.
634
+ .button__menu {
635
+ position: absolute;
636
+ inset: 0;
637
+ pointer-events: none;
638
+ }
639
+
640
+ .button__menu-anchor {
641
+ display: block;
642
+ width: 100%;
643
+ height: 100%;
644
+ }
645
+
646
+ .button__menu-panel {
647
+ pointer-events: auto;
648
+ }
649
+
650
+ .button--has-menu {
651
+ -webkit-touch-callout: none;
652
+ }
@@ -39,4 +39,126 @@ describe('<zn-button>', () => {
39
39
  expect(base.getAttribute('aria-pressed')).to.equal('false');
40
40
  });
41
41
 
42
+ it('forwards aria-expanded and aria-haspopup to the inner button', async () => {
43
+ const el = await fixture<ZnButton>(html`<zn-button aria-haspopup="dialog" aria-expanded="false">Menu</zn-button>`);
44
+ const base = el.shadowRoot!.querySelector('[part~="base"]')!;
45
+ expect(base.getAttribute('aria-haspopup')).to.equal('dialog');
46
+ expect(base.getAttribute('aria-expanded')).to.equal('false');
47
+
48
+ el.setAttribute('aria-expanded', 'true');
49
+ await el.updateComplete;
50
+ expect(base.getAttribute('aria-expanded')).to.equal('true');
51
+
52
+ const plain = await fixture<ZnButton>(html`<zn-button>Plain</zn-button>`);
53
+ const plainBase = plain.shadowRoot!.querySelector('[part~="base"]')!;
54
+ expect(plainBase.hasAttribute('aria-expanded')).to.be.false;
55
+ expect(plainBase.hasAttribute('aria-haspopup')).to.be.false;
56
+ });
57
+
58
+ it('applies size classes', async () => {
59
+ const el = await fixture<ZnButton>(html`<zn-button size="small">Small</zn-button>`);
60
+ const base = el.shadowRoot!.querySelector('[part~="base"]')!;
61
+ expect(base.classList.contains('button--small')).to.be.true;
62
+
63
+ el.size = 'large';
64
+ await el.updateComplete;
65
+ expect(base.classList.contains('button--small')).to.be.false;
66
+ expect(base.classList.contains('button--large')).to.be.true;
67
+ });
68
+
69
+ it('applies the ai color', async () => {
70
+ const el = await fixture<ZnButton>(html`<zn-button color="ai">Summarise</zn-button>`);
71
+ const base = el.shadowRoot!.querySelector('[part~="base"]')!;
72
+ expect(base.classList.contains('button--ai')).to.be.true;
73
+ await expect(el).to.be.accessible();
74
+ });
75
+
76
+
77
+ it('submits to its formaction, with its name and value', async () => {
78
+ const form = await fixture<HTMLFormElement>(html`
79
+ <form action="/default">
80
+ <zn-button type="submit" formaction="/add" name="intent" value="add">Add</zn-button>
81
+ </form>
82
+ `);
83
+ const button = form.querySelector('zn-button')! as HTMLElement & {updateComplete: Promise<unknown>};
84
+ await button.updateComplete;
85
+
86
+ let action = '';
87
+ let intent: FormDataEntryValue | null = null;
88
+ form.addEventListener('submit', (e: SubmitEvent) => {
89
+ e.preventDefault();
90
+ action = e.submitter!.getAttribute('formaction') ?? '';
91
+ intent = new FormData(form, e.submitter).get('intent');
92
+ });
93
+ button.click();
94
+
95
+ expect(action).to.equal('/add');
96
+ expect(intent).to.equal('add');
97
+ });
98
+
99
+ describe('long press menu', () => {
100
+ const menuFixture = () => fixture<ZnButton>(html`
101
+ <zn-button long-press-delay="50">
102
+ Send
103
+ <zn-menu slot="menu">
104
+ <zn-menu-item value="draft">Save as draft</zn-menu-item>
105
+ </zn-menu>
106
+ </zn-button>
107
+ `);
108
+
109
+ const press = (base: Element, type: string) =>
110
+ base.dispatchEvent(new PointerEvent(type, {bubbles: true, composed: true, button: 0, clientX: 5, clientY: 5}));
111
+
112
+ it('announces the menu on the inner button', async () => {
113
+ const el = await menuFixture();
114
+ const base = el.shadowRoot!.querySelector('[part~="base"]')!;
115
+ expect(base.getAttribute('aria-haspopup')).to.equal('menu');
116
+ expect(base.getAttribute('aria-expanded')).to.equal('false');
117
+ });
118
+
119
+ it('runs the click action on a short press', async () => {
120
+ const el = await menuFixture();
121
+ const base = el.shadowRoot!.querySelector('[part~="base"]')! as HTMLElement;
122
+ let clicks = 0;
123
+ el.addEventListener('click', () => clicks++);
124
+
125
+ press(base, 'pointerdown');
126
+ press(document.body, 'pointerup');
127
+ base.click();
128
+
129
+ expect(clicks).to.equal(1);
130
+ expect(el.menuDropdown.open).to.be.false;
131
+ });
132
+
133
+ it('opens the menu on a long press and swallows the click that ends it', async () => {
134
+ const el = await menuFixture();
135
+ const base = el.shadowRoot!.querySelector('[part~="base"]')! as HTMLElement;
136
+ let clicks = 0;
137
+ el.addEventListener('click', () => clicks++);
138
+
139
+ press(base, 'pointerdown');
140
+ await new Promise(resolve => setTimeout(resolve, 100));
141
+ press(document.body, 'pointerup');
142
+ base.click();
143
+
144
+ expect(el.menuDropdown.open).to.be.true;
145
+ expect(clicks).to.equal(0);
146
+ expect(base.getAttribute('aria-expanded')).to.equal('true');
147
+ });
148
+
149
+ it('opens the menu with ArrowDown', async () => {
150
+ const el = await menuFixture();
151
+ const base = el.shadowRoot!.querySelector('[part~="base"]')!;
152
+
153
+ base.dispatchEvent(new KeyboardEvent('keydown', {key: 'ArrowDown', bubbles: true, composed: true}));
154
+ await el.menuDropdown.updateComplete;
155
+
156
+ expect(el.menuDropdown.open).to.be.true;
157
+ });
158
+
159
+ it('renders no dropdown without a menu', async () => {
160
+ const el = await fixture<ZnButton>(html`<zn-button>Plain</zn-button>`);
161
+ expect(el.shadowRoot!.querySelector('zn-dropdown')).to.be.null;
162
+ });
163
+ });
42
164
  });
@@ -23,6 +23,8 @@ interface CustomButtonWidths {
23
23
  * @since 1.0
24
24
  *
25
25
  * @slot - The default slot.
26
+ * @slot prefix - Controls shown just before the inline buttons, such as a segmented toggle. Their width is kept
27
+ * free when working out which buttons fit.
26
28
  *
27
29
  */
28
30
  export default class ZnButtonMenu extends ZincElement {
@@ -40,7 +42,7 @@ export default class ZnButtonMenu extends ZincElement {
40
42
  @property({type: Number, attribute: 'max-level'})
41
43
  public maxLevel: number = 2; // primary = 1, secondary = 2, transparent = 3
42
44
 
43
- @property({type: Number, attribute: 'icon-size', reflect: true}) iconSize: number = 20;
45
+ @property({type: Number, attribute: 'icon-size', reflect: true}) iconSize: number = 16;
44
46
 
45
47
  @property({type: Boolean, attribute: 'no-gap'}) public noGap: boolean;
46
48
 
@@ -51,6 +53,9 @@ export default class ZnButtonMenu extends ZincElement {
51
53
  private _originalButtons: CustomButtonWidths[] = [];
52
54
 
53
55
  private _resizeRafId = 0;
56
+ // What the last rebuild laid out, so a resize that keeps the same split leaves the DOM alone
57
+ private _shownCount = -1;
58
+ private _shownTotal = -1;
54
59
 
55
60
  private readonly resizeObserver = new ResizeController(this, {
56
61
  target: null,
@@ -96,20 +101,20 @@ export default class ZnButtonMenu extends ZincElement {
96
101
  if (this.maxWidth) {
97
102
  this.containerWidth = Math.min(this.containerWidth, this.maxWidth);
98
103
  }
99
- this.calculateVisibleButtons();
104
+ this.calculateVisibleButtons(true);
100
105
  }
101
106
 
102
107
  connectedCallback() {
103
108
  super.connectedCallback();
104
- this.containerWidth = this.offsetWidth;
105
109
 
106
110
  if (this.parentNode) {
107
111
  this.resizeObserver.observe(this.parentNode as HTMLElement);
108
112
  }
109
113
  }
110
114
 
111
- calculateVisibleButtons() {
115
+ calculateVisibleButtons(onlyIfChanged = false) {
112
116
  const containerWidth = this.containerWidth;
117
+ const focused = this.shadowRoot?.activeElement as ZnButton | null;
113
118
 
114
119
  let primaryButtons = 0;
115
120
  let secondaryButtons = 0;
@@ -119,6 +124,7 @@ export default class ZnButtonMenu extends ZincElement {
119
124
  let remainingWidth = containerWidth;
120
125
  this._buttons = [...this._originalButtons];
121
126
  remainingWidth -= 50; // Allow for more-vert button
127
+ remainingWidth -= this.getPrefixWidth();
122
128
 
123
129
  // Sort the buttons
124
130
  this._buttons.sort((a, b) => {
@@ -156,6 +162,12 @@ export default class ZnButtonMenu extends ZincElement {
156
162
  visibleButtons = Math.min(visibleButtons, this.limit);
157
163
  }
158
164
 
165
+ if (onlyIfChanged && visibleButtons === this._shownCount && totalButtons === this._shownTotal) {
166
+ return;
167
+ }
168
+ this._shownCount = visibleButtons;
169
+ this._shownTotal = totalButtons;
170
+
159
171
  // Remove all buttons from the ui and menu
160
172
  const container = this.shadowRoot?.querySelector('.button-menu__container');
161
173
  if (container) {
@@ -167,18 +179,18 @@ export default class ZnButtonMenu extends ZincElement {
167
179
  menu.innerHTML = '';
168
180
  }
169
181
 
170
- // Add colors to the buttons depending on type
171
182
  this._buttons.forEach((button: CustomButtonWidths, index: number) => {
172
183
  if (index < visibleButtons) {
173
184
  this.shadowRoot?.querySelector('.button-menu__container')?.appendChild(button.button);
174
-
175
- if (button.button.hasAttribute('primary') || button.button.hasAttribute('secondary')) {
176
- button.button.setAttribute('text', "");
177
- }
178
185
  }
179
186
  });
180
187
 
181
188
  this.calculateMenuButtons(totalButtons, visibleButtons, this._buttons);
189
+
190
+ if (focused && this.shadowRoot?.activeElement !== focused) {
191
+ const target = focused.isConnected ? focused : this.shadowRoot?.querySelector<ZnButton>('zn-button[slot="trigger"]');
192
+ target?.button?.focus();
193
+ }
182
194
  }
183
195
 
184
196
  calculateMenuButtons(totalButtons: number, visibleButtons: number, buttons: CustomButtonWidths[]) {
@@ -216,7 +228,7 @@ export default class ZnButtonMenu extends ZincElement {
216
228
  if (iconLibrary) {
217
229
  iconElement.setAttribute('library', iconLibrary);
218
230
  }
219
- iconElement.setAttribute('size', '18');
231
+ iconElement.setAttribute('size', '16');
220
232
  iconElement.setAttribute('slot', 'prefix');
221
233
  menuItem.appendChild(iconElement);
222
234
  }
@@ -268,6 +280,12 @@ export default class ZnButtonMenu extends ZincElement {
268
280
  })
269
281
  }
270
282
 
283
+ private getPrefixWidth(): number {
284
+ const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot[name="prefix"]');
285
+ const gap = parseFloat(getComputedStyle(this).getPropertyValue('--menu-gap')) || 0;
286
+ return (slot?.assignedElements() ?? []).reduce((width, el) => width + (el as HTMLElement).offsetWidth + gap, 0);
287
+ }
288
+
271
289
  private getButtonLabel(button: ZnButton) {
272
290
  const labelSlot = button.shadowRoot?.querySelector<HTMLSlotElement>('slot[part="label"]');
273
291
  const slottedLabel = labelSlot ? [...labelSlot.assignedNodes({flatten: true})]
@@ -297,13 +315,16 @@ export default class ZnButtonMenu extends ZincElement {
297
315
  'button-menu--no-padding': this.noPadding,
298
316
  'button-menu--no-gap': this.noGap,
299
317
  })}">
318
+ <slot name="prefix" @slotchange="${() => this.calculateVisibleButtons()}"></slot>
300
319
  <div class="button-menu__container"></div>
301
320
  <zn-dropdown placement="bottom-end">
302
321
  <zn-button slot="trigger"
303
322
  icon="ellipsis"
304
323
  icon-library="lucide"
305
324
  icon-size="${this.iconSize}"
306
- icon-button="small"></zn-button>
325
+ icon-button="small"
326
+ plain
327
+ label="More actions"></zn-button>
307
328
  <zn-menu></zn-menu>
308
329
  </zn-dropdown>
309
330
  <slot></slot>
@@ -44,7 +44,11 @@
44
44
  }
45
45
 
46
46
  zn-button {
47
- min-width: 34px;
47
+ min-width: var(--zn-button-icon-width, 34px);
48
48
  flex-shrink: 0;
49
49
  }
50
50
  }
51
+
52
+ slot[name="prefix"]::slotted(*) {
53
+ align-self: center;
54
+ }
@@ -197,6 +197,13 @@ export default class ZnChannelTile extends ZincElement {
197
197
  this._accept();
198
198
  };
199
199
 
200
+ // A click, so listeners on the host see keyboard activation too
201
+ private _handleKeyDown = (e: KeyboardEvent) => {
202
+ if (e.target !== e.currentTarget || (e.key !== 'Enter' && e.key !== ' ')) return;
203
+ e.preventDefault();
204
+ (e.currentTarget as HTMLElement).click();
205
+ };
206
+
200
207
  protected render(): unknown {
201
208
  const title = this.title || (this.available ? 'Available' : '');
202
209
  const countdown = this._isCountingDown() ? this._countdownPercent() : null;
@@ -214,7 +221,8 @@ export default class ZnChannelTile extends ZincElement {
214
221
  })}
215
222
  role="button"
216
223
  tabindex="0"
217
- @click=${this._handleClick}>
224
+ @click=${this._handleClick}
225
+ @keydown=${this._handleKeyDown}>
218
226
  <div class="channel-tile__header">${this.header ? html`<h3>${this.header}</h3>` : ''}</div>
219
227
  ${countdown !== null
220
228
  ? html`
@@ -261,14 +269,9 @@ export default class ZnChannelTile extends ZincElement {
261
269
  <slot name="leading">
262
270
  ${this.icon
263
271
  ? html`
264
- <zn-button icon=${this.icon}
265
- icon-size="20"
266
- icon-button="round"
267
- color=${this.color}
268
- class="${classMap({
269
- [`channel-tile--${this.color}`]: true,
270
- })}"
271
- no-hover></zn-button>`
272
+ <span class="channel-tile__lead">
273
+ <zn-icon src=${this.icon} size="16"></zn-icon>
274
+ </span>`
272
275
  : ''}
273
276
  </slot>`;
274
277
  }
@@ -276,32 +279,36 @@ export default class ZnChannelTile extends ZincElement {
276
279
  private _renderAvailableAction() {
277
280
  if (this.incoming && this.rejectable) {
278
281
  return html`
279
- <button class="channel-tile__reject" type="button" aria-label=${this.rejectLabel}
282
+ <button class="channel-tile__lead channel-tile__reject" type="button" aria-label=${this.rejectLabel}
280
283
  @click=${this._handleReject}>
281
- <zn-icon src=${this.rejectIcon} size="22"></zn-icon>
284
+ <zn-icon src=${this.rejectIcon} size="16"></zn-icon>
282
285
  </button>`;
283
286
  }
284
287
 
285
288
  if (this.acceptUri) {
286
289
  return html`
287
- <zn-button href=${this.acceptUri}
288
- icon=${this.acceptIcon}
289
- icon-size="20"
290
- icon-button="round"
291
- gaid=${this.acceptGaid}
292
- loading-text="Accepting"
293
- no-hover>
294
- </zn-button>`;
290
+ <span class="channel-tile__lead">
291
+ <zn-button href=${this.acceptUri}
292
+ icon=${this.acceptIcon}
293
+ icon-size="16"
294
+ icon-button="round"
295
+ gaid=${this.acceptGaid}
296
+ loading-text="Accepting"
297
+ plain>
298
+ </zn-button>
299
+ </span>`;
295
300
  }
296
301
 
297
302
  return html`
298
- <slot name="action">
299
- <zn-button icon=${this.acceptIcon}
300
- icon-size="20"
301
- icon-button="round"
302
- gaid=${this.acceptGaid}
303
- no-hover>
304
- </zn-button>
305
- </slot>`;
303
+ <span class="channel-tile__lead">
304
+ <slot name="action">
305
+ <zn-button icon=${this.acceptIcon}
306
+ icon-size="16"
307
+ icon-button="round"
308
+ gaid=${this.acceptGaid}
309
+ plain>
310
+ </zn-button>
311
+ </slot>
312
+ </span>`;
306
313
  }
307
314
  }