@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
@@ -3,7 +3,8 @@ import {type CSSResultGroup, html, type PropertyValues, unsafeCSS} from 'lit';
3
3
  import {HasSlotController} from "../../internal/slot";
4
4
  import {idSelector} from "../../utilities/query";
5
5
  import {ifDefined} from "lit/directives/if-defined.js";
6
- import {property, query} from 'lit/decorators.js';
6
+ import {property, query, state} from 'lit/decorators.js';
7
+ import {registerCosmicBorder} from "../../internal/cosmic-border";
7
8
  import {unlockBodyScrolling} from "../../internal/scroll";
8
9
  import ZincElement from '../../internal/zinc-element';
9
10
  import ZnButton from "../button";
@@ -11,14 +12,14 @@ import ZnButton from "../button";
11
12
  import styles from './dialog.scss';
12
13
 
13
14
  /**
14
- * @summary Short summary of the component's intended use.
15
+ * @summary A modal that appears above the page for a decision that blocks the flow.
15
16
  * @documentation https://zinc.style/components/dialog
16
17
  * @status experimental
17
18
  * @since 1.0
18
19
  *
19
20
  * @dependency zn-button
20
21
  *
21
- * @event zn-show - Emitted when the dialog is opens.
22
+ * @event zn-show - Emitted when the dialog opens.
22
23
  * @event zn-close - Emitted when the dialog is closed.
23
24
  * @event {{ source: 'close-button' | 'keyboard' | 'overlay' }} zn-request-close - Emitted when the user attempts to
24
25
  * close the dialog by clicking the close button, clicking the overlay, or pressing escape. Calling
@@ -29,7 +30,7 @@ import styles from './dialog.scss';
29
30
  * @slot label - The dialog's label. Alternatively you can use the `label` attribute.
30
31
  * @slot header-icon - Optional icon to add to the left of the dialog's label (title). A color will be applied
31
32
  * to the icon depending on the dialog variant.
32
- * @slot announcement-intro - Optional Intro text to display below the icon, when using the variant `announcement`.
33
+ * @slot announcement-intro - Optional intro text to display below the icon, when using the variant `announcement`.
33
34
  * @slot header-actions - Optional actions to add to the header. Works best with `<zn-button>` elements.
34
35
  * @slot footer - The dialog's footer. This is typically used for buttons representing various options.
35
36
  * @slot footer-text - Optional text to include below the footer buttons, when using the variant `announcement`.
@@ -39,14 +40,23 @@ import styles from './dialog.scss';
39
40
  * @csspart header-actions - Optional actions to add to the header. Works best with `<zn-button>` elements.
40
41
  * @csspart title - The dialog's title.
41
42
  * @csspart close-button - The dialog's close button.
42
- * @csspart close-button__base - The close buttons exported `base` part.
43
+ * @csspart close-button__base - The close button's exported `base` part.
43
44
  * @csspart body - The dialog's body.
44
45
  * @csspart footer - The dialog's footer.
45
46
  *
46
- * @cssproperty --width - The preferred width of the dialog. Note the dialog will shrink to accommodate smaller screens.
47
+ * @cssproperty --width - The preferred width of a `size="custom"` dialog. The dialog shrinks to fit smaller screens.
47
48
  * @cssproperty --header-spacing - The amount of padding to use for the header.
48
49
  * @cssproperty --body-spacing - The amount of padding to use for the body.
49
50
  * @cssproperty --footer-spacing - The amount of padding to use for the footer.
51
+ * @cssproperty --zn-dialog-width-small - Theme token: the width of `size="small"`.
52
+ * @cssproperty --zn-dialog-width-medium - Theme token: the width of `size="medium"`.
53
+ * @cssproperty --zn-dialog-width-large - Theme token: the width of `size="large"`.
54
+ * @cssproperty --zn-dialog-border-radius - Theme token: the dialog's corner radius.
55
+ * @cssproperty --zn-dialog-backdrop - Theme token: the backdrop behind the dialog.
56
+ * @cssproperty --zn-dialog-body-color - Theme token: the body text colour.
57
+ * @cssproperty --zn-dialog-icon-background - Theme token: the fill behind a default or warning header icon.
58
+ * @cssproperty --zn-dialog-close-color - Theme token: the close button's icon colour.
59
+ * @cssproperty --zn-dialog-close-icon-size - Theme token: the close button's icon size, read when the dialog opens.
50
60
  */
51
61
  export default class ZnDialog extends ZincElement {
52
62
  static styles: CSSResultGroup = unsafeCSS(styles);
@@ -92,6 +102,9 @@ export default class ZnDialog extends ZincElement {
92
102
  */
93
103
  @property({type: String, reflect: true}) trigger: string;
94
104
 
105
+ /** Read from `--zn-dialog-close-icon-size` on open, as zn-icon takes its size as an attribute. */
106
+ @state() private closeIconSize = 24;
107
+
95
108
  protected firstUpdated(_changedProperties: PropertyValues) {
96
109
  super.firstUpdated(_changedProperties);
97
110
  if (this.open) {
@@ -111,18 +124,7 @@ export default class ZnDialog extends ZincElement {
111
124
  trigger.addEventListener('click', () => this.show());
112
125
  }
113
126
  }
114
- if (window.CSS.registerProperty) {
115
- try {
116
- window.CSS.registerProperty({
117
- inherits: false,
118
- initialValue: '0deg',
119
- name: '--rotate',
120
- syntax: '<angle>',
121
- });
122
- } catch (e) {
123
- // do nothing
124
- }
125
- }
127
+ registerCosmicBorder();
126
128
  }
127
129
 
128
130
  disconnectedCallback() {
@@ -153,6 +155,19 @@ export default class ZnDialog extends ZincElement {
153
155
  this.hide();
154
156
  }
155
157
 
158
+ // Escape on a native modal dialog closes it directly, bypassing zn-request-close
159
+ private handleCancel = (event: Event) => {
160
+ event.preventDefault();
161
+ this.requestClose('keyboard');
162
+ };
163
+
164
+ // The browser can refuse to cancel a repeated Escape, closing the dialog anyway
165
+ private handleNativeClose = () => {
166
+ if (this.open) {
167
+ this.hide();
168
+ }
169
+ };
170
+
156
171
  private addOpenListeners() {
157
172
  if ('CloseWatcher' in window) {
158
173
  this.closeWatcher?.destroy();
@@ -167,6 +182,8 @@ export default class ZnDialog extends ZincElement {
167
182
 
168
183
  /** Shows the dialog. */
169
184
  show() {
185
+ const closeIconSize = parseFloat(getComputedStyle(this).getPropertyValue('--zn-dialog-close-icon-size'));
186
+ this.closeIconSize = closeIconSize > 0 ? closeIconSize : 24;
170
187
  this.emit('zn-show');
171
188
  this.addOpenListeners();
172
189
  this.open = true;
@@ -207,6 +224,8 @@ export default class ZnDialog extends ZincElement {
207
224
  return html`
208
225
  <dialog
209
226
  part="base"
227
+ @cancel=${this.handleCancel}
228
+ @close=${this.handleNativeClose}
210
229
  role="alertdialog"
211
230
  aria-modal="true"
212
231
  aria-label=${ifDefined(this.noHeader ? this.label : undefined)}
@@ -246,7 +265,7 @@ export default class ZnDialog extends ZincElement {
246
265
  exportparts="base:close-button__base"
247
266
  class="dialog__close"
248
267
  icon="x@lu"
249
- icon-size="24"
268
+ icon-size="${this.closeIconSize}"
250
269
  icon-button="small"
251
270
  plain
252
271
  @click="${() => this.requestClose('close-button')}"
@@ -2,9 +2,9 @@
2
2
 
3
3
  :host {
4
4
  --width: 30rem;
5
- --header-spacing: var(--zn-spacing-large) var(--zn-spacing-large) var(--zn-spacing-medium);
6
- --body-spacing: var(--zn-spacing-x-small) var(--zn-spacing-large);
7
- --footer-spacing: var(--zn-spacing-large);
5
+ --header-spacing: var(--zn-dialog-header-spacing, var(--zn-spacing-large) var(--zn-spacing-large) var(--zn-spacing-medium));
6
+ --body-spacing: var(--zn-dialog-body-spacing, var(--zn-spacing-x-small) var(--zn-spacing-large));
7
+ --footer-spacing: var(--zn-dialog-footer-spacing, var(--zn-spacing-large));
8
8
  --icon-background-color: var(--zn-color-primary-200);
9
9
  --icon-color: var(--zn-color-primary-600);
10
10
  --caption-color: var(--zn-color-primary-600);
@@ -17,7 +17,7 @@
17
17
  flex: 1 1 auto;
18
18
  flex-direction: column;
19
19
  min-height: 0;
20
- border-radius: var(--zn-border-radius);
20
+ border-radius: var(--zn-dialog-border-radius, var(--zn-border-radius));
21
21
  background-color: var(--zn-panel-background-color);
22
22
  margin: 2px;
23
23
  overflow: hidden;
@@ -28,6 +28,10 @@
28
28
  }
29
29
 
30
30
  .dialog {
31
+ // Back to the theme's sizes: a dialog inherits from wherever it is placed, e.g. a chip that shrinks its buttons
32
+ --zn-button-height: var(--zn-density-control-height, 36px);
33
+ --zn-button-icon-width: var(--zn-density-control-height, 40px);
34
+
31
35
  flex-direction: column;
32
36
  z-index: 2;
33
37
  width: calc(var(--width) + 1px);
@@ -35,7 +39,7 @@
35
39
  max-width: calc(100% - var(--zn-spacing-2x-large));
36
40
  max-height: calc(100% - 20vh);
37
41
  background-color: var(--zn-panel-background-color);
38
- border-radius: var(--zn-border-radius);
42
+ border-radius: var(--zn-dialog-border-radius, var(--zn-border-radius));
39
43
  box-shadow: var(--zn-shadow-x-large);
40
44
  padding: 0;
41
45
  margin: 10vh auto;
@@ -44,6 +48,12 @@
44
48
  display: flex;
45
49
  }
46
50
 
51
+ // The fallback is the browser's own dialog backdrop.
52
+ &::backdrop {
53
+ background: var(--zn-dialog-backdrop, rgba(0, 0, 0, 0.1));
54
+ backdrop-filter: var(--zn-overlay-backdrop-filter, none);
55
+ }
56
+
47
57
  &__header {
48
58
  flex: 0 0 auto;
49
59
  display: flex;
@@ -77,6 +87,16 @@
77
87
  }
78
88
  }
79
89
 
90
+ &__close::part(base) {
91
+ width: var(--zn-dialog-close-size, var(--zn-button-height, 36px));
92
+ min-width: var(--zn-dialog-close-size, var(--zn-button-height, 36px));
93
+ height: var(--zn-dialog-close-size, var(--zn-button-height, 36px));
94
+ min-height: var(--zn-dialog-close-size, var(--zn-button-height, 36px));
95
+ max-height: var(--zn-dialog-close-size, var(--zn-button-height, 36px));
96
+ padding: var(--zn-dialog-close-padding, 6px);
97
+ color: var(--zn-dialog-close-color, rgb(var(--zn-text)));
98
+ }
99
+
80
100
  &__label {
81
101
  overflow: hidden;
82
102
  word-break: break-word;
@@ -90,17 +110,24 @@
90
110
  padding: var(--body-spacing);
91
111
  overflow: auto;
92
112
  -webkit-overflow-scrolling: touch;
93
- color: var(--zn-color-text-default);
94
- font-size: var(--zn-font-size-medium);
113
+ color: var(--zn-dialog-body-color, var(--zn-color-text-default));
114
+ font-size: var(--zn-dialog-body-font-size, var(--zn-font-size-medium));
95
115
  font-weight: var(--zn-font-weight-normal);
96
116
  letter-spacing: var(--zn-tracking-normal);
97
- line-height: var(--zn-line-height-dense);
117
+ line-height: var(--zn-dialog-body-line-height, var(--zn-line-height-dense));
118
+
119
+ // Safari opens the dialog by focusing this tabindex="-1" body, and it isn't a control worth a ring
120
+ &:focus {
121
+ outline: none;
122
+ }
98
123
  }
99
124
 
100
125
  &__footer {
101
126
  flex: 0 0 auto;
102
127
  text-align: right;
103
128
  padding: var(--footer-spacing);
129
+ border-top: var(--zn-dialog-footer-divider, none);
130
+ background: var(--zn-dialog-footer-background, transparent);
104
131
 
105
132
  ::slotted(zn-button:not(:first-of-type)) {
106
133
  margin-inline-start: var(--zn-spacing-x-small);
@@ -111,10 +138,11 @@
111
138
  &--default &__title,
112
139
  &--warning &__title {
113
140
  color: rgb(var(--zn-text-panel-title));
114
- font-size: var(--zn-font-size-x-large);
115
- font-weight: var(--zn-font-weight-semibold);
141
+ font-family: var(--zn-dialog-title-font-family, inherit);
142
+ font-size: var(--zn-dialog-title-font-size, var(--zn-font-size-x-large));
143
+ font-weight: var(--zn-dialog-title-font-weight, var(--zn-font-weight-semibold));
116
144
  letter-spacing: var(--zn-letter-spacing-normal);
117
- line-height: var(--zn-line-height-dense);
145
+ line-height: var(--zn-dialog-title-line-height, var(--zn-line-height-dense));
118
146
  padding: var(--header-spacing);
119
147
  }
120
148
 
@@ -124,11 +152,12 @@
124
152
  flex-direction: column;
125
153
  justify-content: center;
126
154
  align-content: center;
127
- color: var(--caption-color);
128
- font-size: var(--zn-font-size-x-large);
129
- font-weight: var(--zn-font-weight-semibold);
155
+ color: var(--zn-dialog-announcement-title-color, var(--caption-color));
156
+ font-family: var(--zn-dialog-announcement-title-font-family, inherit);
157
+ font-size: var(--zn-dialog-announcement-title-font-size, var(--zn-font-size-x-large));
158
+ font-weight: var(--zn-dialog-announcement-title-font-weight, var(--zn-font-weight-semibold));
130
159
  letter-spacing: var(--zn-letter-spacing-normal);
131
- line-height: var(--zn-line-height-dense);
160
+ line-height: var(--zn-dialog-announcement-title-line-height, var(--zn-line-height-dense));
132
161
  padding: var(--header-spacing);
133
162
  margin: 0;
134
163
  }
@@ -136,19 +165,20 @@
136
165
  &--default &__title ::slotted(zn-icon),
137
166
  &--warning &__title ::slotted(zn-icon) {
138
167
  border-radius: var(--zn-border-radius-pill);
139
- padding: var(--zn-spacing-2x-small);
140
- margin-right: var(--zn-spacing-small);
168
+ padding: var(--zn-dialog-icon-padding, var(--zn-spacing-2x-small));
169
+ margin-right: var(--zn-dialog-icon-gap, var(--zn-spacing-small));
141
170
  }
142
171
 
143
172
  &--announcement &__title ::slotted(zn-icon) {
144
- --icon-size: var(--zn-font-size-3x-large);
145
- border-radius: var(--zn-border-radius-pill);
146
- padding: var(--zn-spacing-medium);
147
- margin-bottom: var(--zn-spacing-medium);
173
+ --icon-size: var(--zn-dialog-announcement-icon-size, var(--zn-font-size-3x-large));
174
+ border-radius: var(--zn-dialog-announcement-icon-radius, var(--zn-border-radius-pill));
175
+ padding: var(--zn-dialog-announcement-icon-padding, var(--zn-spacing-medium));
176
+ margin-bottom: var(--zn-dialog-announcement-icon-gap, var(--zn-spacing-medium));
177
+ background-color: var(--icon-background-color);
148
178
  }
149
179
 
150
180
  &__title ::slotted(zn-icon) {
151
- background-color: var(--icon-background-color);
181
+ background-color: var(--zn-dialog-icon-background, var(--icon-background-color));
152
182
  color: var(--icon-color);
153
183
  }
154
184
 
@@ -158,10 +188,12 @@
158
188
  }
159
189
 
160
190
  &--announcement &__title ::slotted([slot='announcement-intro']) {
161
- color: var(--zn-color-neutral-800);
162
- font-size: var(--zn-font-size-large);
191
+ color: var(--zn-dialog-announcement-intro-color, var(--zn-color-neutral-800));
192
+ font-size: var(--zn-dialog-announcement-intro-font-size, var(--zn-font-size-large));
163
193
  font-weight: var(--zn-font-weight-semibold);
164
- padding: var(--zn-spacing-medium) 0;
194
+ letter-spacing: var(--zn-dialog-announcement-intro-letter-spacing, normal);
195
+ text-transform: var(--zn-dialog-announcement-intro-transform, none);
196
+ padding: var(--zn-dialog-announcement-intro-spacing, var(--zn-spacing-medium) 0);
165
197
  }
166
198
 
167
199
  &--announcement &__header-actions {
@@ -169,7 +201,7 @@
169
201
  }
170
202
 
171
203
  &--announcement &__body {
172
- padding: var(--zn-spacing-x-small) var(--zn-spacing-2x-large);
204
+ padding: var(--zn-dialog-announcement-body-spacing, var(--zn-spacing-x-small) var(--zn-spacing-2x-large));
173
205
  }
174
206
 
175
207
  &--announcement &__title,
@@ -179,27 +211,28 @@
179
211
  }
180
212
 
181
213
  &--announcement &__footer ::slotted([slot='footer-text']) {
182
- color: var(--zn-color-neutral-700);
183
- font-size: var(--zn-font-size-small);
214
+ color: var(--zn-dialog-announcement-footer-text-color, var(--zn-color-neutral-700));
215
+ font-size: var(--zn-dialog-announcement-footer-text-font-size, var(--zn-font-size-small));
184
216
  font-weight: var(--zn-font-weight-normal);
217
+ padding: var(--zn-dialog-announcement-footer-text-spacing, var(--zn-spacing-large));
185
218
  }
186
219
 
187
220
  /** Sizes */
188
221
  &--small {
189
- --width: 25rem;
222
+ --width: var(--zn-dialog-width-small, 25rem);
190
223
 
191
224
  .dialog__body {
192
- color: rgb(var(--zn-text));
225
+ color: var(--zn-dialog-body-color, rgb(var(--zn-text)));
193
226
  padding: var(--body-spacing);
194
227
  }
195
228
  }
196
229
 
197
230
  &--medium {
198
- --width: 30rem;
231
+ --width: var(--zn-dialog-width-medium, 30rem);
199
232
  }
200
233
 
201
234
  &--large {
202
- --width: 37.5rem;
235
+ --width: var(--zn-dialog-width-large, 37.5rem);
203
236
  }
204
237
 
205
238
  /** Modifiers **/
@@ -208,10 +241,6 @@
208
241
  // padding: var(--zn-spacing-x-small) var(--zn-spacing-large) var(--zn-spacing-3x-large);
209
242
  //}
210
243
 
211
- &--announcement &__footer ::slotted([slot='footer-text']) {
212
- padding: var(--zn-spacing-large);
213
- }
214
-
215
244
  &__footer ::slotted(zn-button:not(:first-of-type)) {
216
245
  margin-inline-start: var(--zn-spacing-x-small);
217
246
  }
@@ -7,4 +7,18 @@ describe('<zn-dialog>', () => {
7
7
 
8
8
  expect(el).to.exist;
9
9
  });
10
+
11
+ it('draws the footer divider and radius from the dialog tokens', async () => {
12
+ const el = await fixture<HTMLElement>(html`
13
+ <zn-dialog label="Refund" style="--zn-dialog-footer-divider: 1px solid rgb(1, 2, 3); --zn-dialog-border-radius: 9px">
14
+ <p>Body</p>
15
+ <button slot="footer">OK</button>
16
+ </zn-dialog>`);
17
+ await (el as HTMLElement & {updateComplete: Promise<boolean>}).updateComplete;
18
+ const footer = el.shadowRoot!.querySelector('.dialog__footer')!;
19
+ const dialog = el.shadowRoot!.querySelector('.dialog')!;
20
+
21
+ expect(getComputedStyle(footer).borderTopColor).to.equal('rgb(1, 2, 3)');
22
+ expect(getComputedStyle(dialog).borderTopLeftRadius).to.equal('9px');
23
+ });
10
24
  });
@@ -0,0 +1,55 @@
1
+ import { type CSSResultGroup, html, unsafeCSS } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import ZincElement from '../../internal/zinc-element';
4
+
5
+ import styles from './diff.scss';
6
+
7
+ /**
8
+ * @summary A side-by-side comparison of two versions of something, one column each, built from `zn-diff-row`s.
9
+ * @documentation https://zinc.style/components/diff
10
+ * @status experimental
11
+ * @since 1.1
12
+ *
13
+ * @property {string} beforeCaption - The left column's heading, such as the older version.
14
+ * @property {string} beforeDescription - A line under the left heading.
15
+ * @property {string} afterCaption - The right column's heading, such as the newer version.
16
+ * @property {string} afterDescription - A line under the right heading.
17
+ *
18
+ * @slot - The `zn-diff-row`s.
19
+ * @slot before - Inline content after the left heading, such as a status badge.
20
+ * @slot after - Inline content after the right heading, such as a status badge.
21
+ *
22
+ * @csspart base - The table.
23
+ * @csspart head - The sticky row of column headings.
24
+ *
25
+ * @cssproperty --zn-diff-head-background - The heading row's background.
26
+ * @cssproperty --zn-diff-sticky-top - How far from the top of its scroll container the heading row sticks.
27
+ */
28
+ export default class ZnDiff extends ZincElement {
29
+ static styles: CSSResultGroup = unsafeCSS(styles);
30
+
31
+ @property({ attribute: 'before-caption' }) beforeCaption = '';
32
+ @property({ attribute: 'before-description' }) beforeDescription = '';
33
+ @property({ attribute: 'after-caption' }) afterCaption = '';
34
+ @property({ attribute: 'after-description' }) afterDescription = '';
35
+
36
+ render() {
37
+ return html`
38
+ <div class="diff" part="base" role="table">
39
+ <div class="diff__head" part="head" role="row">
40
+ <div class="diff__column" role="columnheader">
41
+ <span class="diff__caption">${this.beforeCaption}<slot name="before"></slot></span>
42
+ ${this.beforeDescription ? html`<span class="diff__description">${this.beforeDescription}</span>` : ''}
43
+ </div>
44
+ <div class="diff__column" role="columnheader">
45
+ <span class="diff__caption">${this.afterCaption}<slot name="after"></slot></span>
46
+ ${this.afterDescription ? html`<span class="diff__description">${this.afterDescription}</span>` : ''}
47
+ </div>
48
+ </div>
49
+ <div role="rowgroup">
50
+ <slot></slot>
51
+ </div>
52
+ </div>
53
+ `;
54
+ }
55
+ }
@@ -0,0 +1,46 @@
1
+ @use "../../wc";
2
+
3
+ :host {
4
+ display: block;
5
+ }
6
+
7
+ .diff__head {
8
+ position: sticky;
9
+ top: var(--zn-diff-sticky-top, 0);
10
+ z-index: 1;
11
+ display: grid;
12
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
13
+ border-bottom: 1px solid rgb(var(--zn-border-color));
14
+ background: var(--zn-diff-head-background, rgb(var(--zn-panel)));
15
+ }
16
+
17
+ .diff__column {
18
+ display: flex;
19
+ flex-direction: column;
20
+ gap: 2px;
21
+ min-width: 0;
22
+ padding: var(--zn-spacing-small) var(--zn-spacing-medium);
23
+
24
+ & + & {
25
+ border-inline-start: 1px solid rgb(var(--zn-border-color));
26
+ }
27
+ }
28
+
29
+ .diff__caption {
30
+ display: flex;
31
+ flex-wrap: wrap;
32
+ align-items: center;
33
+ gap: var(--zn-spacing-x-small);
34
+ font-size: var(--zn-font-size-small);
35
+ font-weight: var(--zn-font-weight-semibold);
36
+ color: rgb(var(--zn-text-heading));
37
+ }
38
+
39
+ .diff__description {
40
+ font-size: var(--zn-font-size-x-small);
41
+ color: rgb(var(--zn-color-muted-text));
42
+ }
43
+
44
+ ::slotted(:last-child) {
45
+ --zn-diff-row-border: 0;
46
+ }
@@ -0,0 +1,15 @@
1
+ import '../../../dist/zn.min.js';
2
+ import { expect, fixture, html } from '@open-wc/testing';
3
+
4
+ describe('<zn-diff>', () => {
5
+ it('renders both column headings', async () => {
6
+ const el = await fixture(html`
7
+ <zn-diff before-caption="Version 2" after-caption="Version 3" after-description="Live"></zn-diff>`);
8
+
9
+ const headings = el.shadowRoot!.querySelectorAll('[role="columnheader"]');
10
+ expect(headings).to.have.length(2);
11
+ expect(headings[0].textContent).to.contain('Version 2');
12
+ expect(headings[1].textContent).to.contain('Version 3');
13
+ expect(headings[1].textContent).to.contain('Live');
14
+ });
15
+ });
@@ -0,0 +1,12 @@
1
+ import ZnDiff from './diff.component';
2
+
3
+ export * from './diff.component';
4
+ export default ZnDiff;
5
+
6
+ ZnDiff.define('zn-diff');
7
+
8
+ declare global {
9
+ interface HTMLElementTagNameMap {
10
+ 'zn-diff': ZnDiff;
11
+ }
12
+ }
@@ -0,0 +1,75 @@
1
+ import { type CSSResultGroup, html, unsafeCSS } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import ZincElement from '../../internal/zinc-element';
4
+ import ZnBadge from '../badge';
5
+
6
+ import styles from './diff-row.scss';
7
+
8
+ const changeLabels = { changed: 'Changed', added: 'Added', removed: 'Removed' } as const;
9
+
10
+ /**
11
+ * @summary One aligned row of a `zn-diff`: the same item in both versions, tinted by how it changed.
12
+ * @documentation https://zinc.style/components/diff-row
13
+ * @status experimental
14
+ * @since 1.1
15
+ *
16
+ * @dependency zn-badge
17
+ *
18
+ * @property {string} caption - The item's name, shown in both columns.
19
+ * @property {string} change - How the item changed: `changed`, `added` or `removed`. Unchanged when empty.
20
+ * @property {boolean} heading - When true, the row is a heading spanning both columns, such as a section name.
21
+ * @property {string} beforePlaceholder - Shown in the left column when the item was added.
22
+ * @property {string} afterPlaceholder - Shown in the right column when the item was removed.
23
+ *
24
+ * @slot before - The item's details in the older version.
25
+ * @slot after - The item's details in the newer version.
26
+ *
27
+ * @csspart row - The row.
28
+ * @csspart before - The left cell.
29
+ * @csspart after - The right cell.
30
+ *
31
+ * @cssproperty --zn-diff-row-border - The line below the row.
32
+ */
33
+ export default class ZnDiffRow extends ZincElement {
34
+ static styles: CSSResultGroup = unsafeCSS(styles);
35
+ static dependencies = {
36
+ 'zn-badge': ZnBadge,
37
+ };
38
+
39
+ @property() caption = '';
40
+ @property({ reflect: true }) change: '' | 'changed' | 'added' | 'removed' = '';
41
+ @property({ type: Boolean, reflect: true }) heading = false;
42
+ @property({ attribute: 'before-placeholder' }) beforePlaceholder = 'Not in this version';
43
+ @property({ attribute: 'after-placeholder' }) afterPlaceholder = 'Not in this version';
44
+
45
+ private renderCell(side: 'before' | 'after') {
46
+ const absent = side === 'before' ? this.change === 'added' : this.change === 'removed';
47
+ if (absent) {
48
+ return html`
49
+ <div class="row__cell row__cell--absent" part="${side}" role="cell">
50
+ ${side === 'before' ? this.beforePlaceholder : this.afterPlaceholder}
51
+ </div>`;
52
+ }
53
+ const label = this.change ? changeLabels[this.change] : '';
54
+ const badgeType = this.change === 'added' ? 'success' : this.change === 'removed' ? 'danger' : 'info';
55
+ return html`
56
+ <div class="row__cell" part="${side}" role="cell">
57
+ <span class="row__caption">
58
+ ${this.caption}
59
+ ${side === 'after' && label ? html`<zn-badge type="${badgeType}">${label}</zn-badge>` : ''}
60
+ </span>
61
+ <span class="row__details"><slot name="${side}"></slot></span>
62
+ </div>`;
63
+ }
64
+
65
+ render() {
66
+ if (this.heading) {
67
+ return html`<div class="row row--heading" part="row" role="row"><span role="rowheader">${this.caption}</span></div>`;
68
+ }
69
+ return html`
70
+ <div class="row" part="row" role="row">
71
+ ${this.renderCell('before')}
72
+ ${this.renderCell('after')}
73
+ </div>`;
74
+ }
75
+ }
@@ -0,0 +1,70 @@
1
+ @use "../../wc";
2
+
3
+ :host {
4
+ display: block;
5
+ }
6
+
7
+ .row {
8
+ display: grid;
9
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
10
+ border-bottom: var(--zn-diff-row-border, 1px solid rgb(var(--zn-border-color)));
11
+ }
12
+
13
+ .row--heading {
14
+ display: block;
15
+ padding: var(--zn-spacing-small) var(--zn-spacing-medium) var(--zn-spacing-x-small);
16
+ background: rgba(var(--zn-color-text), 0.02);
17
+ font-size: var(--zn-font-size-x-small);
18
+ font-weight: var(--zn-font-weight-semibold);
19
+ letter-spacing: 0.06em;
20
+ text-transform: uppercase;
21
+ color: rgb(var(--zn-color-muted-text));
22
+ }
23
+
24
+ .row__cell {
25
+ display: flex;
26
+ flex-direction: column;
27
+ gap: 2px;
28
+ min-width: 0;
29
+ padding: var(--zn-spacing-small) var(--zn-spacing-medium);
30
+ font-size: var(--zn-font-size-small);
31
+ line-height: 1.45;
32
+
33
+ & + & {
34
+ border-inline-start: 1px solid rgb(var(--zn-border-color));
35
+ }
36
+ }
37
+
38
+ .row__caption {
39
+ display: flex;
40
+ flex-wrap: wrap;
41
+ align-items: center;
42
+ gap: var(--zn-spacing-x-small);
43
+ font-weight: var(--zn-font-weight-semibold);
44
+ color: rgb(var(--zn-text-heading));
45
+ }
46
+
47
+ .row__details {
48
+ color: rgb(var(--zn-color-muted-text));
49
+ overflow-wrap: anywhere;
50
+ }
51
+
52
+ // The absent side of an added or removed item: hatched so it reads as empty rather than blank.
53
+ .row__cell--absent {
54
+ justify-content: center;
55
+ background: repeating-linear-gradient(135deg, transparent 0 6px, rgba(var(--zn-border-color), 0.25) 6px 12px);
56
+ font-size: var(--zn-font-size-x-small);
57
+ color: rgb(var(--zn-color-muted-text));
58
+ }
59
+
60
+ :host([change="changed"]) .row__cell {
61
+ background-color: var(--zn-color-info-bg);
62
+ }
63
+
64
+ :host([change="added"]) .row__cell:not(.row__cell--absent) {
65
+ background-color: var(--zn-color-success-bg);
66
+ }
67
+
68
+ :host([change="removed"]) .row__cell:not(.row__cell--absent) {
69
+ background-color: var(--zn-color-danger-bg);
70
+ }