@kubex/zinc 1.1.185 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. package/.browserslistrc +2 -0
  2. package/.github/workflows/js_build_and_deploy.yaml +54 -1
  3. package/.github/workflows/test.yaml +27 -0
  4. package/dist/chunks/zn.UWJLIXDT.js +1 -0
  5. package/dist/custom-elements.json +10319 -2666
  6. package/dist/vscode.html-custom-data.json +1012 -57
  7. package/dist/web-types.json +2097 -145
  8. package/dist/zn.d.ts +2294 -416
  9. package/dist/zn.min.css +1 -1
  10. package/dist/zn.min.js +2310 -1637
  11. package/docs/_includes/default.njk +4 -1
  12. package/docs/assets/scripts/docs.js +22 -6
  13. package/docs/assets/styles/docs.css +9 -2
  14. package/docs/data/report-table-day-compare.json +380 -0
  15. package/docs/data/report-table.json +314 -0
  16. package/docs/pages/components/avatar-group.md +57 -0
  17. package/docs/pages/components/badge.md +67 -0
  18. package/docs/pages/components/button.md +41 -1
  19. package/docs/pages/components/chat-message.md +16 -0
  20. package/docs/pages/components/checkbox.md +1 -1
  21. package/docs/pages/components/chip.md +25 -13
  22. package/docs/pages/components/color-picker.md +37 -0
  23. package/docs/pages/components/copy-button.md +2 -2
  24. package/docs/pages/components/data-table-filter.md +33 -50
  25. package/docs/pages/components/data-table-search.md +4 -4
  26. package/docs/pages/components/data-table.md +27 -3
  27. package/docs/pages/components/date-range.md +116 -0
  28. package/docs/pages/components/dialog.md +29 -37
  29. package/docs/pages/components/diff-row.md +28 -0
  30. package/docs/pages/components/diff.md +46 -0
  31. package/docs/pages/components/editor.md +55 -0
  32. package/docs/pages/components/icon.md +46 -1
  33. package/docs/pages/components/input.md +30 -11
  34. package/docs/pages/components/item.md +35 -0
  35. package/docs/pages/components/key-value.md +25 -0
  36. package/docs/pages/components/menu.md +74 -7
  37. package/docs/pages/components/nav-item.md +15 -0
  38. package/docs/pages/components/nav-list.md +132 -0
  39. package/docs/pages/components/navbar.md +100 -1
  40. package/docs/pages/components/page.md +242 -74
  41. package/docs/pages/components/priority-list.md +43 -5
  42. package/docs/pages/components/query-builder.md +23 -0
  43. package/docs/pages/components/radio-group.md +33 -1
  44. package/docs/pages/components/radio.md +1 -1
  45. package/docs/pages/components/report-table.md +202 -0
  46. package/docs/pages/components/stat.md +30 -0
  47. package/docs/pages/components/tile.md +11 -0
  48. package/docs/pages/components/tooltip.md +1 -1
  49. package/docs/pages/components/translation-grid.md +86 -0
  50. package/docs/pages/components/vertical-stepper.md +108 -64
  51. package/package.json +2 -1
  52. package/scss/_global-spacing.scss +2 -2
  53. package/scss/_root.scss +11 -171
  54. package/scss/boot.scss +14 -0
  55. package/scss/mixins/_helper-mixins.scss +24 -2
  56. package/scss/mixins/_motion-mixins.scss +126 -0
  57. package/scss/mixins/_spacing-mixins.scss +4 -3
  58. package/scss/mixins/_tab-indicator-mixins.scss +12 -0
  59. package/scss/mixins/_typography-mixins.scss +1 -1
  60. package/scss/mixins/index.scss +14 -0
  61. package/scss/shared/_base.scss +32 -1
  62. package/scss/shared/_button-mixin.scss +7 -5
  63. package/scss/shared/_table.scss +35 -4
  64. package/scss/shared/nav.scss +4 -0
  65. package/scss/shared/shimmer.scss +1 -1
  66. package/scss/table-controls.scss +206 -0
  67. package/scss/themes/_dark.scss +1 -3
  68. package/scss/themes/_index.scss +1 -1
  69. package/scss/themes/_light.scss +46 -6
  70. package/scss/themes/_modes.scss +11 -11
  71. package/scss/themes/_openbyte.scss +944 -0
  72. package/scss/themes/_typography.scss +4 -2
  73. package/scss/variables/index.scss +0 -9
  74. package/src/components/alert/alert.component.ts +14 -4
  75. package/src/components/alert/alert.scss +55 -69
  76. package/src/components/alert/alert.test.ts +8 -0
  77. package/src/components/animated-button/animated-button.component.ts +3 -2
  78. package/src/components/animated-button/animated-button.scss +6 -23
  79. package/src/components/animated-button/animated-button.test.ts +4 -3
  80. package/src/components/avatar-group/avatar-group.component.ts +84 -0
  81. package/src/components/avatar-group/avatar-group.scss +54 -0
  82. package/src/components/avatar-group/avatar-group.test.ts +59 -0
  83. package/src/components/avatar-group/index.ts +12 -0
  84. package/src/components/badge/badge.component.ts +49 -0
  85. package/src/components/badge/badge.scss +80 -0
  86. package/src/components/badge/badge.test.ts +34 -0
  87. package/src/components/badge/index.ts +12 -0
  88. package/src/components/bulk-actions/bulk-actions.component.ts +14 -2
  89. package/src/components/button/button.component.ts +228 -8
  90. package/src/components/button/button.scss +115 -32
  91. package/src/components/button/button.test.ts +122 -0
  92. package/src/components/button-menu/button-menu.component.ts +32 -11
  93. package/src/components/button-menu/button-menu.scss +5 -1
  94. package/src/components/channel-tile/channel-tile.component.ts +34 -27
  95. package/src/components/channel-tile/channel-tile.scss +76 -43
  96. package/src/components/chart/builders.test.ts +46 -0
  97. package/src/components/chart/builders.ts +27 -3
  98. package/src/components/chart/chart-live.test.ts +4 -6
  99. package/src/components/chart/chart.component.ts +125 -5
  100. package/src/components/chart/chart.scss +121 -0
  101. package/src/components/chart/chart.test.ts +81 -0
  102. package/src/components/chat-message/chat-message.component.ts +21 -1
  103. package/src/components/chat-message/chat-message.scss +13 -2
  104. package/src/components/chat-message/chat-message.test.ts +9 -0
  105. package/src/components/checkbox/checkbox.component.ts +61 -27
  106. package/src/components/checkbox/checkbox.scss +58 -25
  107. package/src/components/checkbox-group/checkbox-group.component.ts +7 -1
  108. package/src/components/chip/chip.component.ts +11 -1
  109. package/src/components/chip/chip.scss +91 -26
  110. package/src/components/chip/chip.test.ts +17 -0
  111. package/src/components/collapsible/collapsible.component.ts +17 -3
  112. package/src/components/collapsible/collapsible.scss +19 -10
  113. package/src/components/color-picker/color-picker.component.ts +277 -0
  114. package/src/components/color-picker/color-picker.scss +141 -0
  115. package/src/components/color-picker/color-picker.test.ts +57 -0
  116. package/src/components/color-picker/index.ts +12 -0
  117. package/src/components/cols/cols.component.ts +10 -0
  118. package/src/components/cols/cols.test.ts +17 -0
  119. package/src/components/confirm/confirm.component.ts +20 -6
  120. package/src/components/confirm/confirm.test.ts +52 -0
  121. package/src/components/content-block/content-block.component.ts +38 -9
  122. package/src/components/content-block/content-block.scss +11 -5
  123. package/src/components/content-block/content-block.test.ts +26 -0
  124. package/src/components/copy-button/copy-button.component.ts +2 -2
  125. package/src/components/copy-button/copy-button.scss +17 -4
  126. package/src/components/data-select/data-select.component.ts +3 -1
  127. package/src/components/data-table/data-table.component.ts +362 -140
  128. package/src/components/data-table/data-table.scss +136 -60
  129. package/src/components/data-table/data-table.test.ts +356 -4
  130. package/src/components/data-table-filter/data-table-filter.component.ts +426 -406
  131. package/src/components/data-table-filter/data-table-filter.scss +176 -148
  132. package/src/components/data-table-filter/data-table-filter.test.ts +271 -273
  133. package/src/components/data-table-search/data-table-search.component.ts +4 -2
  134. package/src/components/data-table-search/data-table-search.scss +8 -1
  135. package/src/components/data-table-search/data-table-search.test.ts +29 -0
  136. package/src/components/date-range/date-range-math.test.ts +78 -0
  137. package/src/components/date-range/date-range-math.ts +105 -0
  138. package/src/components/date-range/date-range.component.ts +375 -0
  139. package/src/components/date-range/date-range.scss +272 -0
  140. package/src/components/date-range/date-range.test.ts +247 -0
  141. package/src/components/date-range/index.ts +12 -0
  142. package/src/components/datepicker/datepicker.component.ts +44 -7
  143. package/src/components/datepicker/datepicker.scss +9 -0
  144. package/src/components/datepicker/datepicker.test.ts +2 -2
  145. package/src/components/dialog/dialog.component.ts +38 -19
  146. package/src/components/dialog/dialog.scss +65 -36
  147. package/src/components/dialog/dialog.test.ts +14 -0
  148. package/src/components/diff/diff.component.ts +55 -0
  149. package/src/components/diff/diff.scss +46 -0
  150. package/src/components/diff/diff.test.ts +15 -0
  151. package/src/components/diff/index.ts +12 -0
  152. package/src/components/diff-row/diff-row.component.ts +75 -0
  153. package/src/components/diff-row/diff-row.scss +70 -0
  154. package/src/components/diff-row/diff-row.test.ts +37 -0
  155. package/src/components/diff-row/index.ts +12 -0
  156. package/src/components/dropdown/dropdown.component.ts +12 -10
  157. package/src/components/dropdown/dropdown.scss +2 -0
  158. package/src/components/editor/editor.component.ts +159 -11
  159. package/src/components/editor/editor.scss +250 -1
  160. package/src/components/editor/editor.test.ts +31 -3
  161. package/src/components/editor/modules/ai/panel/ai-panel.scss +0 -1
  162. package/src/components/editor/modules/attachment/attachment.ts +53 -31
  163. package/src/components/editor/modules/context-menu/context-menu.ts +17 -0
  164. package/src/components/editor/modules/dialog/dialog.component.ts +23 -1
  165. package/src/components/editor/modules/dialog/dialog.test.ts +28 -0
  166. package/src/components/editor/modules/emoji/emoji.ts +4 -5
  167. package/src/components/editor/modules/merge-field/merge-field.ts +83 -0
  168. package/src/components/editor/modules/toolbar/toolbar.component.ts +121 -68
  169. package/src/components/editor/modules/toolbar/toolbar.scss +38 -0
  170. package/src/components/editor/modules/toolbar/toolbar.ts +25 -1
  171. package/src/components/empty-state/empty-state.component.ts +6 -1
  172. package/src/components/empty-state/empty-state.scss +21 -4
  173. package/src/components/expanding-action/expanding-action.component.ts +22 -34
  174. package/src/components/expanding-action/expanding-action.scss +3 -45
  175. package/src/components/expanding-action/expanding-action.test.ts +2 -1
  176. package/src/components/file/file.component.ts +30 -2
  177. package/src/components/file/file.scss +6 -0
  178. package/src/components/flow-builder/flow-builder.component.ts +36 -3
  179. package/src/components/flow-builder/flow-builder.scss +0 -6
  180. package/src/components/flow-builder/modules/flow-canvas/flow-canvas.component.ts +8 -0
  181. package/src/components/flow-builder/modules/flow-canvas/flow-canvas.scss +10 -5
  182. package/src/components/flow-builder/modules/flow-node/flow-node.component.ts +17 -0
  183. package/src/components/flow-builder/modules/flow-node/flow-node.scss +10 -0
  184. package/src/components/form-actions/form-actions.component.ts +48 -2
  185. package/src/components/form-actions/form-actions.scss +1 -1
  186. package/src/components/form-group/form-group.component.ts +10 -3
  187. package/src/components/form-group/form-group.scss +37 -4
  188. package/src/components/form-group/form-group.test.ts +10 -0
  189. package/src/components/header/header.component.ts +11 -4
  190. package/src/components/header/header.scss +47 -5
  191. package/src/components/hover-container/hover-container.component.ts +4 -5
  192. package/src/components/icon/icon.component.ts +95 -9
  193. package/src/components/icon/icon.scss +70 -6
  194. package/src/components/icon/icon.test.ts +55 -0
  195. package/src/components/icon-picker/icon-picker.component.ts +35 -1
  196. package/src/components/inline-edit/inline-edit.component.ts +38 -8
  197. package/src/components/inline-edit/inline-edit.scss +128 -19
  198. package/src/components/input/input.component.ts +173 -297
  199. package/src/components/input/input.scss +65 -43
  200. package/src/components/input/input.test.ts +86 -4
  201. package/src/components/item/item.component.ts +12 -0
  202. package/src/components/item/item.scss +102 -3
  203. package/src/components/item/item.test.ts +23 -0
  204. package/src/components/key/key.component.ts +2 -2
  205. package/src/components/key/key.scss +11 -0
  206. package/src/components/key-value/index.ts +12 -0
  207. package/src/components/key-value/key-value.component.ts +160 -0
  208. package/src/components/key-value/key-value.scss +20 -0
  209. package/src/components/key-value/key-value.test.ts +22 -0
  210. package/src/components/markdown-editor/markdown-editor.component.ts +8 -1
  211. package/src/components/menu/menu.component.ts +21 -2
  212. package/src/components/menu/menu.scss +43 -23
  213. package/src/components/menu/menu.test.ts +33 -0
  214. package/src/components/menu-item/menu-item.component.ts +13 -2
  215. package/src/components/menu-item/menu-item.scss +56 -23
  216. package/src/components/menu-item/menu-item.test.ts +31 -0
  217. package/src/components/menu-item/submenu-controller.ts +25 -15
  218. package/src/components/menu-label/index.ts +12 -0
  219. package/src/components/menu-label/menu-label.component.ts +30 -0
  220. package/src/components/menu-label/menu-label.scss +18 -0
  221. package/src/components/nav-item/index.ts +12 -0
  222. package/src/components/nav-item/nav-item.component.ts +83 -0
  223. package/src/components/nav-item/nav-item.scss +128 -0
  224. package/src/components/nav-list/index.ts +12 -0
  225. package/src/components/nav-list/nav-list.component.ts +313 -0
  226. package/src/components/nav-list/nav-list.scss +87 -0
  227. package/src/components/nav-list/nav-list.test.ts +250 -0
  228. package/src/components/navbar/navbar.component.ts +235 -171
  229. package/src/components/navbar/navbar.scss +333 -169
  230. package/src/components/navbar/navbar.test.ts +63 -143
  231. package/src/components/page/page.component.ts +114 -29
  232. package/src/components/page/page.scss +223 -95
  233. package/src/components/page/page.test.ts +214 -3
  234. package/src/components/page-builder/page-builder.component.ts +51 -5
  235. package/src/components/page-builder/page-builder.scss +6 -1
  236. package/src/components/page-nav/page-nav.component.ts +25 -3
  237. package/src/components/page-nav/page-nav.scss +10 -2
  238. package/src/components/pagination/pagination.scss +1 -1
  239. package/src/components/panel/panel.component.ts +14 -13
  240. package/src/components/panel/panel.scss +14 -10
  241. package/src/components/panel/panel.test.ts +42 -0
  242. package/src/components/popup/popup.component.ts +20 -13
  243. package/src/components/popup/popup.test.ts +21 -1
  244. package/src/components/priority-list/priority-list.component.ts +157 -172
  245. package/src/components/priority-list/priority-list.scss +113 -17
  246. package/src/components/priority-list/priority-list.test.ts +301 -3
  247. package/src/components/progress-bar/progress-bar.component.ts +1 -1
  248. package/src/components/progress-bar/progress-bar.scss +16 -4
  249. package/src/components/progress-tile/progress-tile.scss +1 -1
  250. package/src/components/query-builder/query-builder.component.ts +85 -10
  251. package/src/components/query-builder/query-builder.scss +7 -1
  252. package/src/components/query-builder/query-builder.test.ts +40 -0
  253. package/src/components/radio/radio.component.ts +57 -18
  254. package/src/components/radio/radio.scss +101 -26
  255. package/src/components/radio-group/radio-group.component.ts +45 -7
  256. package/src/components/radio-group/radio-group.scss +17 -0
  257. package/src/components/radio-group/radio-group.test.ts +63 -2
  258. package/src/components/rating/rating.component.ts +23 -0
  259. package/src/components/rating/rating.scss +1 -1
  260. package/src/components/remarkd-editor/remarkd-editor.component.ts +60 -5
  261. package/src/components/remarkd-editor/remarkd-editor.scss +12 -4
  262. package/src/components/report-table/index.ts +12 -0
  263. package/src/components/report-table/report-format.test.ts +86 -0
  264. package/src/components/report-table/report-format.ts +72 -0
  265. package/src/components/report-table/report-math.test.ts +74 -0
  266. package/src/components/report-table/report-math.ts +252 -0
  267. package/src/components/report-table/report-table.component.ts +681 -0
  268. package/src/components/report-table/report-table.scss +328 -0
  269. package/src/components/report-table/report-table.test.ts +702 -0
  270. package/src/components/reveal/reveal.component.ts +15 -1
  271. package/src/components/reveal/reveal.scss +5 -0
  272. package/src/components/schedule-builder/schedule-builder.component.ts +23 -8
  273. package/src/components/scroll-container/scroll-container.component.ts +19 -1
  274. package/src/components/scroll-container/scroll-container.scss +6 -1
  275. package/src/components/select/select.component.ts +52 -36
  276. package/src/components/select/select.scss +42 -25
  277. package/src/components/select/select.test.ts +14 -2
  278. package/src/components/settings-container/settings-container.scss +18 -5
  279. package/src/components/sidebar/sidebar.component.ts +8 -1
  280. package/src/components/sidebar/sidebar.scss +6 -1
  281. package/src/components/skeleton/skeleton.component.ts +3 -3
  282. package/src/components/skeleton/skeleton.scss +6 -6
  283. package/src/components/skeleton/skeleton.test.ts +9 -0
  284. package/src/components/slash-menu/slash-menu.scss +1 -1
  285. package/src/components/slideout/slideout.component.ts +20 -3
  286. package/src/components/slideout/slideout.scss +13 -6
  287. package/src/components/slideout/slideout.test.ts +19 -0
  288. package/src/components/split-button/split-button.component.ts +1 -1
  289. package/src/components/split-pane/split-pane.component.ts +71 -8
  290. package/src/components/split-pane/split-pane.scss +145 -41
  291. package/src/components/split-pane/split-pane.test.ts +23 -3
  292. package/src/components/stat/stat.component.ts +209 -14
  293. package/src/components/stat/stat.scss +305 -5
  294. package/src/components/stat/stat.test.ts +143 -2
  295. package/src/components/status-indicator/status-indicator.scss +22 -21
  296. package/src/components/stepper/stepper.scss +3 -3
  297. package/src/components/tab/tab.component.ts +1 -0
  298. package/src/components/table/table.component.ts +12 -1
  299. package/src/components/table/table.scss +21 -13
  300. package/src/components/table/table.test.ts +17 -0
  301. package/src/components/tabs/tabs.component.ts +150 -37
  302. package/src/components/tabs/tabs.scss +48 -7
  303. package/src/components/tabs/tabs.test.ts +169 -0
  304. package/src/components/textarea/textarea.component.ts +25 -3
  305. package/src/components/textarea/textarea.scss +10 -0
  306. package/src/components/textarea/textarea.test.ts +8 -4
  307. package/src/components/theme-editor/theme-editor.scss +0 -6
  308. package/src/components/tile/tile.component.ts +32 -2
  309. package/src/components/tile/tile.scss +40 -7
  310. package/src/components/tile/tile.test.ts +10 -0
  311. package/src/components/toggle/toggle.component.ts +23 -7
  312. package/src/components/toggle/toggle.scss +36 -29
  313. package/src/components/toggle/toggle.test.ts +17 -0
  314. package/src/components/tooltip/tooltip.component.ts +3 -0
  315. package/src/components/tooltip/tooltip.scss +11 -6
  316. package/src/components/tooltip/tooltip.test.ts +12 -0
  317. package/src/components/translation-field/index.ts +12 -0
  318. package/src/components/translation-field/translation-field.component.ts +55 -0
  319. package/src/components/translation-field/translation-field.scss +101 -0
  320. package/src/components/translation-fields/index.ts +12 -0
  321. package/src/components/translation-fields/translation-fields.component.ts +80 -0
  322. package/src/components/translation-fields/translation-fields.scss +60 -0
  323. package/src/components/translation-grid/index.ts +12 -0
  324. package/src/components/translation-grid/translation-grid.component.ts +157 -0
  325. package/src/components/translation-grid/translation-grid.scss +138 -0
  326. package/src/components/translation-grid/translation-grid.test.ts +28 -0
  327. package/src/components/vertical-stepper/vertical-stepper.component.ts +35 -9
  328. package/src/components/vertical-stepper/vertical-stepper.scss +110 -39
  329. package/src/components/vertical-stepper/vertical-stepper.test.ts +35 -0
  330. package/src/components/well/well.scss +2 -2
  331. package/src/events/events.ts +2 -0
  332. package/src/events/zn-chart-click.ts +13 -0
  333. package/src/events/zn-report-change.ts +7 -0
  334. package/src/form-control.scss +36 -3
  335. package/src/internal/anchored-popover.ts +175 -0
  336. package/src/internal/animate.ts +19 -5
  337. package/src/internal/cosmic-border.ts +15 -0
  338. package/src/internal/form.ts +1 -1
  339. package/src/internal/hover-intent.ts +15 -0
  340. package/src/internal/input-modality.ts +15 -0
  341. package/src/internal/pointer-intent.ts +37 -0
  342. package/src/internal/reorder.ts +632 -0
  343. package/src/internal/scroll.ts +51 -3
  344. package/src/internal/selection-card.ts +1 -1
  345. package/src/internal/tab-indicator.ts +92 -0
  346. package/src/internal/table-sort.ts +25 -0
  347. package/src/internal/table-tabs.ts +108 -0
  348. package/src/internal/test-drag.ts +35 -0
  349. package/src/internal/theme-openbyte.test.ts +126 -0
  350. package/src/internal/theme.ts +4 -4
  351. package/src/internal/zinc-element.ts +2 -2
  352. package/src/selection-card.scss +25 -0
  353. package/src/types/web-test-runner-commands.d.ts +1 -0
  354. package/src/utilities/color.test.ts +43 -0
  355. package/src/utilities/color.ts +189 -0
  356. package/src/zinc.ts +14 -0
  357. package/.github/workflows/eleventy_build.yml +0 -42
  358. package/scss/themes/_aura.scss +0 -114
@@ -1,5 +1,5 @@
1
1
  import {colorDataProvider} from "../../../data-select/providers/color-data-provider";
2
- import {type CSSResultGroup, html, type PropertyValues, unsafeCSS} from "lit";
2
+ import {type CSSResultGroup, html, nothing, type PropertyValues, unsafeCSS} from "lit";
3
3
  import {property, query, queryAll} from "lit/decorators.js";
4
4
  import {ResizeController} from '@lit-labs/observers/resize-controller.js';
5
5
  import ZincElement from "../../../../internal/zinc-element";
@@ -28,9 +28,18 @@ export default class ToolbarComponent extends ZincElement {
28
28
 
29
29
  private _featureConfig: EditorFeatureConfig = {};
30
30
  private _resizeId: number | null = null;
31
+ // Toolbar widths [min, max) over which the current split of visible and overflowed groups still holds
32
+ private _fitRange: [number, number] | null = null;
33
+ // Group widths from the last full measure, so a resize can re-split the groups without forcing a layout
34
+ private _measured: { groups: HTMLElement[]; widths: number[]; overflowWidth: number | null } | null = null;
31
35
 
36
+ // Dragging a pane resizes this every frame; re-measuring each time costs Safari a forced layout of the page
32
37
  private readonly _resizeObserver = new ResizeController(this, {
33
- callback: () => this.handleResize(),
38
+ callback: entries => {
39
+ const width = entries.find(entry => entry.target === this)?.borderBoxSize?.[0]?.inlineSize;
40
+ if (width !== undefined && this._fitRange && width >= this._fitRange[0] && width < this._fitRange[1]) return;
41
+ this.handleResize(width);
42
+ },
34
43
  });
35
44
 
36
45
  // Tracks DOM nodes (e.g. emoji/date pickers) temporarily moved into the overflow submenu so we can restore them
@@ -38,7 +47,6 @@ export default class ToolbarComponent extends ZincElement {
38
47
 
39
48
  connectedCallback() {
40
49
  super.connectedCallback();
41
- this.containerWidth = this.offsetWidth;
42
50
  if (this.parentElement) {
43
51
  this._resizeObserver.observe(this.parentElement);
44
52
  }
@@ -58,22 +66,33 @@ export default class ToolbarComponent extends ZincElement {
58
66
  protected firstUpdated(_changedProperties: PropertyValues) {
59
67
  super.firstUpdated(_changedProperties);
60
68
 
61
- this.containerWidth = this.getToolbarWidth();
62
69
  this.updateEmptyGroups();
63
70
 
64
71
  const slotElement = this.renderRoot?.querySelector('slot') as HTMLSlotElement | null;
65
- slotElement?.addEventListener('slotchange', () => this.calculateOverflow());
72
+ slotElement?.addEventListener('slotchange', () => this.handleResize());
66
73
 
67
- this.updateComplete.then(() => this.calculateOverflow());
74
+ this.handleResize();
68
75
  }
69
76
 
70
- handleResize = () => {
71
- this.containerWidth = this.getToolbarWidth();
77
+ // The resize controller re-renders on every observation, so only a real property change can alter the groups
78
+ protected updated(changedProperties: PropertyValues) {
79
+ super.updated(changedProperties);
80
+ if ([...changedProperties.keys()].some(key => key !== 'containerWidth')) {
81
+ this._measured = null;
82
+ }
83
+ }
84
+
85
+ // Measuring forces a synchronous layout (tens of ms in Safari on large pages), so batch it to once per frame.
86
+ // A width (from the resize observer) reuses the last measured group widths; no width measures again.
87
+ handleResize = (width?: number) => {
88
+ if (width === undefined) {
89
+ this._measured = null;
90
+ }
72
91
  if (this._resizeId !== null) {
73
92
  cancelAnimationFrame(this._resizeId);
74
93
  }
75
94
  this._resizeId = requestAnimationFrame(() => {
76
- this.calculateOverflow();
95
+ this.calculateOverflow(width);
77
96
  this._resizeId = null;
78
97
  });
79
98
  }
@@ -172,34 +191,27 @@ export default class ToolbarComponent extends ZincElement {
172
191
  });
173
192
  }
174
193
 
175
- private calculateOverflow() {
194
+ private calculateOverflow(width?: number) {
195
+ this._fitRange = null;
196
+ if (this._featureConfig.compact) return;
176
197
  const groups = Array.from(this._groups || []);
177
198
  if (!groups.length) return;
178
199
 
179
200
  this.restoreMovedContent();
180
- this.updateEmptyGroups();
181
-
182
- const nonOverflowGroups = groups.filter(group => !group.classList.contains('toolbar__group--overflow') && !group.classList.contains('toolbar__group--empty'));
183
-
184
- nonOverflowGroups.forEach(group => {
185
- group.style.display = 'flex';
186
- group.classList.remove('toolbar__group--hidden', 'toolbar__group--has-prev-visible');
187
- });
188
-
189
- if (this._overflowGroup) {
190
- this._overflowGroup.style.display = 'none';
191
- this._overflowGroup.classList.remove('toolbar__group--hidden', 'toolbar__group--has-prev-visible');
201
+ if (width === undefined || !this._measured) {
202
+ width = this.measureGroups(groups);
192
203
  }
204
+ this.containerWidth = width;
193
205
 
194
- const containerWidth = this.getToolbarWidth();
195
-
196
- if (!containerWidth || containerWidth <= 0) {
197
- nonOverflowGroups.forEach(group => (group.style.display = 'flex'));
206
+ if (!this._measured || width <= 0) {
207
+ groups.forEach(group => {
208
+ if (!group.classList.contains('toolbar__group--overflow') && !group.classList.contains('toolbar__group--empty')) {
209
+ group.style.display = 'flex';
210
+ }
211
+ });
198
212
  if (this._overflowGroup) {
199
213
  this._overflowGroup.style.display = 'none';
200
214
  }
201
-
202
- this.restoreMovedContent();
203
215
  if (this._overflowMenu) {
204
216
  this._overflowMenu.innerHTML = '';
205
217
  }
@@ -209,65 +221,74 @@ export default class ToolbarComponent extends ZincElement {
209
221
  return;
210
222
  }
211
223
 
212
- let used = 0;
213
- let visibleCount = 0;
224
+ this.layoutGroups(width);
225
+ }
214
226
 
215
- for (const group of nonOverflowGroups) {
216
- const width = group.offsetWidth;
217
- if (used + width <= containerWidth) {
218
- used += width;
219
- visibleCount++;
220
- } else {
221
- break;
222
- }
223
- }
227
+ /** Shows every group and records their widths. Returns the toolbar width. */
228
+ private measureGroups(groups: HTMLElement[]): number {
229
+ this._measured = null;
230
+ this.updateEmptyGroups();
224
231
 
225
- if (visibleCount >= nonOverflowGroups.length) {
226
- nonOverflowGroups.forEach(group => (group.style.display = 'flex'));
227
- if (this._overflowGroup) {
228
- this._overflowGroup.style.display = 'none';
229
- }
232
+ const visibleGroups = groups.filter(group => !group.classList.contains('toolbar__group--overflow') && !group.classList.contains('toolbar__group--empty'));
233
+ visibleGroups.forEach(group => {
234
+ group.style.display = 'flex';
235
+ group.classList.remove('toolbar__group--hidden', 'toolbar__group--has-prev-visible');
236
+ });
230
237
 
231
- this.restoreMovedContent();
232
- if (this._overflowMenu) {
233
- this._overflowMenu.innerHTML = '';
234
- }
238
+ if (this._overflowGroup) {
239
+ this._overflowGroup.style.display = 'none';
240
+ this._overflowGroup.classList.remove('toolbar__group--hidden', 'toolbar__group--has-prev-visible');
241
+ }
235
242
 
236
- this._updateDividerClasses();
237
- this._dispatchOverflowEvent();
238
- return;
243
+ const containerWidth = this.getToolbarWidth();
244
+ if (containerWidth > 0) {
245
+ this._measured = {groups: visibleGroups, widths: visibleGroups.map(group => group.offsetWidth), overflowWidth: null};
239
246
  }
247
+ return containerWidth;
248
+ }
240
249
 
241
- const overflowTriggerWidth = this.getOverflowGroupWidth();
242
- used = 0;
243
- visibleCount = 0;
244
- for (const group of nonOverflowGroups) {
245
- const width = group.offsetWidth;
246
- if (used + width + overflowTriggerWidth <= containerWidth) {
247
- used += width;
250
+ /** Shows the leading groups that fit `width` and moves the rest into the overflow menu. */
251
+ private layoutGroups(width: number) {
252
+ const measured = this._measured!;
253
+ const {groups, widths} = measured;
254
+ const total = widths.reduce((sum, groupWidth) => sum + groupWidth, 0);
255
+
256
+ let visibleCount = groups.length;
257
+ if (total > width) {
258
+ measured.overflowWidth ??= this.getOverflowGroupWidth();
259
+ const overflowWidth = measured.overflowWidth;
260
+ let used = 0;
261
+ visibleCount = 0;
262
+ for (const groupWidth of widths) {
263
+ if (used + groupWidth + overflowWidth > width) break;
264
+ used += groupWidth;
248
265
  visibleCount++;
249
- } else {
250
- break;
251
266
  }
267
+ this._fitRange = [
268
+ visibleCount ? used + overflowWidth : 0,
269
+ Math.min(total, used + widths[visibleCount] + overflowWidth),
270
+ ];
271
+ } else {
272
+ this._fitRange = [total, Infinity];
252
273
  }
253
274
 
254
- nonOverflowGroups.forEach((group, index) => {
255
- group.style.display = index < visibleCount ? 'flex' : 'none';
256
- });
257
-
258
- nonOverflowGroups.forEach((group, index) => {
275
+ groups.forEach((group, index) => {
259
276
  const hidden = index >= visibleCount;
277
+ group.style.display = hidden ? 'none' : 'flex';
260
278
  group.classList.toggle('toolbar__group--hidden', hidden);
261
279
  });
262
280
 
263
281
  if (this._overflowGroup) {
264
- this._overflowGroup.style.display = 'flex';
282
+ this._overflowGroup.style.display = visibleCount < groups.length ? 'flex' : 'none';
265
283
  }
266
284
 
267
285
  this._updateDividerClasses();
268
286
 
269
- const hiddenGroups = nonOverflowGroups.slice(visibleCount);
270
- this.populateOverflowMenu(hiddenGroups);
287
+ if (visibleCount < groups.length) {
288
+ this.populateOverflowMenu(groups.slice(visibleCount));
289
+ } else if (this._overflowMenu) {
290
+ this._overflowMenu.innerHTML = '';
291
+ }
271
292
 
272
293
  this._dispatchOverflowEvent();
273
294
  }
@@ -388,6 +409,7 @@ export default class ToolbarComponent extends ZincElement {
388
409
  return !isTrigger && !isMenu;
389
410
  });
390
411
 
412
+ submenu.classList.add('toolbar__submenu--picker');
391
413
  const wrapper = document.createElement('div');
392
414
  wrapper.className = 'toolbar__submenu-content';
393
415
  contentCandidates.forEach((element: HTMLElement) => this.moveContentTo(element, wrapper));
@@ -464,6 +486,10 @@ export default class ToolbarComponent extends ZincElement {
464
486
  }
465
487
 
466
488
  render() {
489
+ if (this._featureConfig.compact) {
490
+ return this._compactToolbar();
491
+ }
492
+
467
493
  const showInsertOptions = this._featureConfig.dividersEnabled ||
468
494
  this._featureConfig.linksEnabled ||
469
495
  this._featureConfig.attachmentsEnabled ||
@@ -543,6 +569,33 @@ export default class ToolbarComponent extends ZincElement {
543
569
  </zn-dropdown>`;
544
570
  }
545
571
 
572
+ private _compactToolbar() {
573
+ const button = (icon: string, label: string, format: string, type = '') => html`
574
+ <zn-button class="toolbar__format-button" icon-button="small" plain icon="${icon}" icon-size="16"
575
+ tooltip="${label}" data-format="${format}"
576
+ data-format-type="${type || nothing}"></zn-button>`;
577
+
578
+ return html`
579
+ <div class="toolbar toolbar--compact">
580
+ <div class="toolbar__group">
581
+ ${button('undo@lu', 'Undo', 'undo')}
582
+ ${button('redo@lu', 'Redo', 'redo')}
583
+ </div>
584
+ <div class="toolbar__group">
585
+ ${button('bold@lu', 'Bold', 'bold')}
586
+ ${button('italic@lu', 'Italic', 'italic')}
587
+ ${this._featureConfig.linksEnabled ? button('link@lu', 'Link', 'link') : ''}
588
+ ${this._featureConfig.linksEnabled ? button('unlink@lu', 'Unlink', 'unlink') : ''}
589
+ ${button('list@lu', 'Bulleted list', 'list', 'bullet')}
590
+ ${button('list-ordered@lu', 'Numbered list', 'list', 'ordered')}
591
+ ${this._featureConfig.codeBlocksEnabled ? button('square-code@lu', 'Code snippet', 'code-block') : ''}
592
+ </div>
593
+ <div class="toolbar__group">
594
+ <slot></slot>
595
+ </div>
596
+ </div>`;
597
+ }
598
+
546
599
  private _formatOptions() {
547
600
  return html`
548
601
  ${this._commonFormatOptions()}
@@ -70,3 +70,41 @@
70
70
  }
71
71
  }
72
72
  }
73
+
74
+ .toolbar--compact {
75
+ --zn-button-height: 24px;
76
+ gap: 2px;
77
+
78
+ zn-button::part(base) {
79
+ padding: 4px;
80
+ color: rgb(var(--zn-color-muted-text));
81
+ }
82
+
83
+ .toolbar__group {
84
+ gap: 2px;
85
+ }
86
+ }
87
+
88
+ // The pickers are wider than a menu's usual cap
89
+ zn-menu.toolbar__submenu--picker {
90
+ --zn-menu-max-width: none;
91
+ }
92
+
93
+ // The picker can cover the menu it opens from, which would show through the shell menu's translucent panel
94
+ zn-menu.toolbar__submenu--picker::part(base) {
95
+ background-color: rgb(var(--zn-color-navigation, 255, 255, 255));
96
+ backdrop-filter: none;
97
+ }
98
+
99
+ // In the overflow menu a picker sits in the submenu's panel, which already draws the frame
100
+ .toolbar__submenu-content {
101
+ em-emoji-picker {
102
+ --border-radius: 0;
103
+ --shadow: none;
104
+ }
105
+
106
+ .air-datepicker.-inline- {
107
+ border: 0;
108
+ border-radius: 0;
109
+ }
110
+ }
@@ -1,4 +1,5 @@
1
1
  import './toolbar.component';
2
+ import Link from "quill/formats/link";
2
3
  import Quill from "quill";
3
4
  import QuillToolbar from "quill/modules/toolbar";
4
5
  import type {EditorFeatureConfig} from "../../editor.component";
@@ -38,6 +39,9 @@ class Toolbar extends QuillToolbar {
38
39
  }
39
40
  this.addHandler('redo', () => quill.history.redo());
40
41
  this.addHandler('undo', () => quill.history.undo());
42
+ if (featureConfig?.linksEnabled) {
43
+ this.addHandler('unlink', () => this._unlink());
44
+ }
41
45
  this.addHandler('dialog', (value: string) => this._openDialog(value));
42
46
 
43
47
  this._quill = quill;
@@ -86,7 +90,10 @@ class Toolbar extends QuillToolbar {
86
90
  const range = this._quill.getSelection();
87
91
  const formats: Record<string, unknown> = range ? this._quill.getFormat(range) : {};
88
92
  const current = formats[key];
89
- const next: boolean | string | number = value !== undefined ? value as boolean | string | number : !(current as boolean);
93
+ let next: boolean | string | number = value !== undefined ? value as boolean | string | number : !(current as boolean);
94
+ if (key === 'list' && current === value) {
95
+ next = false;
96
+ }
90
97
  this._quill.format(key, next);
91
98
  }
92
99
 
@@ -194,6 +201,9 @@ class Toolbar extends QuillToolbar {
194
201
  this._syncButtonState('bold@lu', !!formats.bold);
195
202
  this._syncButtonState('italic@lu', !!formats.italic);
196
203
  this._syncButtonState('underline@lu', !!formats.underline);
204
+ this._syncButtonState('list@lu', formats.list === 'bullet');
205
+ this._syncButtonState('list-ordered@lu', formats.list === 'ordered');
206
+ this._syncButtonState('square-code@lu', Object.prototype.hasOwnProperty.call(formats, 'code-block'));
197
207
 
198
208
  this._updateHeadingFormatMenu(formats);
199
209
  this._updateListFormatMenu(formats);
@@ -304,6 +314,20 @@ class Toolbar extends QuillToolbar {
304
314
  }
305
315
  }
306
316
 
317
+ // With no selection, removes the whole link under the cursor
318
+ private _unlink() {
319
+ const range = this._quill.getSelection(true);
320
+ if (!range) return;
321
+ if (range.length > 0) {
322
+ this._quill.formatText(range, 'link', false, Quill.sources.USER);
323
+ return;
324
+ }
325
+ const [link, offset] = this._quill.scroll.descendant(Link, range.index);
326
+ if (link) {
327
+ this._quill.formatText(range.index - offset, link.length(), 'link', false, Quill.sources.USER);
328
+ }
329
+ }
330
+
307
331
  private _insertDivider() {
308
332
  if (!this._quill) return;
309
333
 
@@ -36,6 +36,9 @@ export default class ZnEmptyState extends ZincElement {
36
36
 
37
37
  @property({type: Boolean}) padded: boolean = false;
38
38
 
39
+ /** Draws the icon small inside a tinted, rounded tile rather than as a large glyph. */
40
+ @property({type: Boolean, reflect: true}) tile: boolean = false;
41
+
39
42
  private readonly hasSlotController = new HasSlotController(this, '[default]', 'caption', 'description');
40
43
 
41
44
  render() {
@@ -50,7 +53,9 @@ export default class ZnEmptyState extends ZincElement {
50
53
  <div class="empty-state__wrapper">
51
54
  ${this.icon || this.hasSlotController.test('icon')
52
55
  ? html`
53
- <zn-icon src="${this.icon}" size="48" color="${this.type ? this.type : 'primary'}"></zn-icon>`
56
+ ${this.tile
57
+ ? html`<span class="empty-state__tile"><zn-icon src="${this.icon}" size="20"></zn-icon></span>`
58
+ : html`<zn-icon src="${this.icon}" size="48" color="${this.type ? this.type : 'primary'}"></zn-icon>`}`
54
59
  : ''}
55
60
  ${this.caption || this.hasSlotController.test('caption')
56
61
  ? html`
@@ -21,7 +21,8 @@
21
21
  }
22
22
 
23
23
  .caption {
24
- font-weight: var(--zn-font-weight-semibold);
24
+ font-family: var(--zn-empty-state-caption-font-family, inherit);
25
+ font-weight: var(--zn-empty-state-caption-font-weight, var(--zn-font-weight-semibold));
25
26
  font-size: var(--zn-font-size-large);
26
27
  line-height: var(--zn-line-height-dense);
27
28
  color: rgb(var(--zn-text-heading));
@@ -29,12 +30,28 @@
29
30
  }
30
31
 
31
32
  .description {
33
+ max-width: var(--zn-empty-state-description-max-width, none);
32
34
  font-size: var(--zn-font-size-small);
33
- line-height: var(--zn-line-height-normal);
34
- color: rgb(var(--zn-text));
35
+ line-height: var(--zn-empty-state-description-line-height, var(--zn-line-height-normal));
36
+ color: var(--zn-empty-state-description-color, rgb(var(--zn-text)));
35
37
  text-align: center;
36
38
  }
37
39
 
40
+ &__tile {
41
+ display: grid;
42
+ place-content: center;
43
+ width: 44px;
44
+ height: 44px;
45
+ margin-bottom: var(--zn-spacing-2x-small);
46
+ border-radius: var(--zn-border-radius-large, 12px);
47
+ background: var(--zn-color-info-bg, rgba(var(--zn-primary), 0.1));
48
+ color: rgb(var(--zn-primary));
49
+
50
+ zn-icon {
51
+ --icon-color: currentColor;
52
+ }
53
+ }
54
+
38
55
  &__wrapper {
39
56
  height: 100%;
40
57
  width: 100%;
@@ -84,7 +101,7 @@
84
101
  }
85
102
 
86
103
  ::slotted(*), .caption, .description {
87
- color: rgb(var(--zn-primary));
104
+ color: var(--zn-color-primary-fg, rgb(var(--zn-primary)));
88
105
  }
89
106
  }
90
107
 
@@ -6,6 +6,7 @@ import {MutationController} from '@lit-labs/observers/mutation-controller.js';
6
6
  import {property} from 'lit/decorators.js';
7
7
  import {styleMap} from "lit/directives/style-map.js";
8
8
  import ZincElement from '../../internal/zinc-element';
9
+ import {onHoverIntent} from '../../internal/hover-intent';
9
10
 
10
11
  import styles from './expanding-action.scss';
11
12
 
@@ -56,7 +57,7 @@ export default class ZnExpandingAction extends ZincElement {
56
57
  private _actions: HTMLElement[] = [];
57
58
  private _preload = true;
58
59
  private _metaObserved = false;
59
- private _placementObserver?: MutationObserver;
60
+ private _fillHadFocus = false;
60
61
 
61
62
  private readonly _countObserver = new MutationController(this, {
62
63
  target: null,
@@ -148,7 +149,7 @@ export default class ZnExpandingAction extends ZincElement {
148
149
  this._actions.push(action);
149
150
 
150
151
  if (this._preload) {
151
- action.addEventListener('mouseover', this.fetchUri.bind(this, action));
152
+ onHoverIntent(action, () => this.fetchUri(action));
152
153
  }
153
154
 
154
155
  action.addEventListener('click', this._handleClick.bind(this));
@@ -242,40 +243,27 @@ export default class ZnExpandingAction extends ZincElement {
242
243
  this.open = false;
243
244
  }
244
245
 
245
- private _updateTriggerSide = () => {
246
- const trigger = this.shadowRoot?.querySelector('.expanding-action__dropdown zn-button[slot="trigger"]');
247
- const content = this.shadowRoot?.querySelector('#content');
248
- if (!trigger || !content) return;
249
-
250
- const triggerRect = trigger.getBoundingClientRect();
251
- const contentRect = content.getBoundingClientRect();
252
- if (contentRect.width === 0) return;
253
-
254
- const triggerCenter = (triggerRect.left + triggerRect.right) / 2;
255
- const contentCenter = (contentRect.left + contentRect.right) / 2;
256
- this.setAttribute('data-trigger-side', triggerCenter > contentCenter ? 'right' : 'left');
246
+ protected willUpdate(changed: PropertyValues<this>) {
247
+ super.willUpdate(changed);
248
+ if (changed.has('open') && !this.open) {
249
+ this._fillHadFocus = !!this.shadowRoot?.querySelector('.expanding-action--fill:focus-within');
250
+ }
257
251
  }
258
252
 
259
- private _observePlacement() {
260
- const dropdown = this.shadowRoot?.querySelector('.expanding-action__dropdown');
261
- const popup = dropdown?.shadowRoot?.querySelector('.dropdown');
262
- if (!popup) {
263
- requestAnimationFrame(() => this._observePlacement());
264
- return;
253
+ protected updated(changed: PropertyValues<this>) {
254
+ super.updated(changed);
255
+ if (this.method !== 'fill' || !changed.has('open') || changed.get('open') === undefined) return;
256
+ if (this.open) {
257
+ this.shadowRoot?.querySelector<HTMLElement>('#content')?.focus();
258
+ } else if (this._fillHadFocus) {
259
+ this.shadowRoot?.querySelector<HTMLElement>('.expanding-action__button')?.focus();
265
260
  }
266
-
267
- this._updateTriggerSide();
268
-
269
- if (this._placementObserver) return;
270
-
271
- this._placementObserver = new MutationObserver(this._updateTriggerSide);
272
- this._placementObserver.observe(popup, {attributes: true, attributeFilter: ['data-current-placement']});
273
261
  }
274
262
 
275
- disconnectedCallback() {
276
- super.disconnectedCallback();
277
- this._placementObserver?.disconnect();
278
- this._placementObserver = undefined;
263
+ private _handleFillKeyDown = (e: KeyboardEvent) => {
264
+ if (this.method !== 'fill' || e.key !== 'Escape' || !this.open) return;
265
+ e.stopPropagation();
266
+ this.open = false;
279
267
  }
280
268
 
281
269
  render() {
@@ -300,7 +288,8 @@ export default class ZnExpandingAction extends ZincElement {
300
288
  style=${styleMap({
301
289
  '--expanding-action-basis': this.method === "drop" && this.basis ? this.basis.replace('px', '') + 'px' : 'none',
302
290
  '--expanding-action-max-height': this.method === "drop" && this.maxHeight ? this.maxHeight.replace('px', '') + 'px' : null,
303
- })}>
291
+ })}
292
+ @keydown=${this._handleFillKeyDown}>
304
293
  ${this.method === 'drop' ? this.renderDropdown() : this.renderFill()}
305
294
  </div>`;
306
295
  }
@@ -312,7 +301,6 @@ export default class ZnExpandingAction extends ZincElement {
312
301
  @zn-show="${(e: Event) => {
313
302
  if (e.target !== e.currentTarget) return;
314
303
  this.open = true;
315
- this._observePlacement();
316
304
  }}"
317
305
  @zn-hide="${(e: Event) => {
318
306
  if (e.target !== e.currentTarget) return;
@@ -338,7 +326,7 @@ export default class ZnExpandingAction extends ZincElement {
338
326
  protected renderFill() {
339
327
  return html`
340
328
  <zn-icon src="${this.icon}" size="20"></zn-icon>
341
- <div id="content" class="expanding-action__content">
329
+ <div id="content" class="expanding-action__content" tabindex="-1">
342
330
  <slot></slot>
343
331
  </div>
344
332
  <zn-button slot="trigger"
@@ -43,7 +43,7 @@
43
43
 
44
44
  & > zn-icon {
45
45
  display: block;
46
- color: rgb(var(--zn-primary));
46
+ color: var(--zn-color-primary-fg, rgb(var(--zn-primary)));
47
47
  }
48
48
  }
49
49
 
@@ -75,8 +75,6 @@
75
75
  .expanding-action--drop .expanding-action__frame {
76
76
  @include wc.scrollbars;
77
77
 
78
- --expanding-action-trigger-width: 36px;
79
-
80
78
  position: relative;
81
79
  display: flex;
82
80
  flex-direction: column;
@@ -87,20 +85,9 @@
87
85
  background-color: rgb(var(--zn-panel));
88
86
  box-shadow: 0 8px 16px -6px rgba(33, 33, 33, 0.18);
89
87
  border: solid 1px rgb(var(--zn-border-color));
90
- border-radius: var(--zn-border-radius) 0 var(--zn-border-radius) var(--zn-border-radius);
88
+ border-radius: var(--zn-border-radius);
91
89
  padding: 0;
92
90
  height: 100%;
93
-
94
- &::before {
95
- content: "";
96
- position: absolute;
97
- top: -1px;
98
- left: calc(100% - var(--expanding-action-trigger-width) + 2px); // Works with width of trigger button and borders
99
- right: 0;
100
- z-index: 1;
101
- height: 2px;
102
- background: rgb(var(--zn-panel));
103
- }
104
91
  }
105
92
 
106
93
  .expanding-action--drop .expanding-action__content {
@@ -110,35 +97,6 @@
110
97
  border-radius: inherit;
111
98
  }
112
99
 
113
- :host([data-trigger-side="left"]) .expanding-action--drop .expanding-action__frame {
114
- border-radius: 0 var(--zn-border-radius) var(--zn-border-radius) var(--zn-border-radius);
115
-
116
- &::before {
117
- left: 0;
118
- right: calc(100% - var(--expanding-action-trigger-width) + 2px); // Works with width of trigger button and borders
119
- }
120
- }
121
-
122
- :host([open]) .expanding-action__dropdown zn-button[slot="trigger"] {
123
- position: relative;
124
- z-index: calc(var(--zn-z-index-dropdown) + 1);
125
-
126
- &::before {
127
- content: "";
128
- position: absolute;
129
- inset: 0;
130
- z-index: -1;
131
- height: 41px;
132
- background: rgb(var(--zn-panel));
133
- border: solid 1px rgb(var(--zn-border-color));
134
- border-bottom-color: rgb(var(--zn-panel));
135
- border-radius: var(--zn-border-radius) var(--zn-border-radius) 0 0;
136
- }
137
- }
138
-
139
100
  :host([open]) .expanding-action__dropdown zn-button[slot="trigger"]::part(base) {
140
- &:hover,
141
- &:active {
142
- background: transparent;
143
- }
101
+ background: var(--zn-button-plain-hover-background, rgb(var(--zn-color-tab)));
144
102
  }
@@ -47,7 +47,8 @@ describe('<zn-expanding-action>', () => {
47
47
  await openPanel(el);
48
48
 
49
49
  const frame = el.shadowRoot!.querySelector<HTMLElement>('.expanding-action__frame')!;
50
- expect(Math.round(frame.getBoundingClientRect().height)).to.equal(250);
50
+ // Layout height: the dropdown's open animation briefly scales the rendered box
51
+ expect(frame.offsetHeight).to.equal(250);
51
52
  });
52
53
  });
53
54
  });