@statistikzh/leu 0.28.1 → 0.28.2

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 (348) hide show
  1. package/dist/{Accordion-CwkI7sfx.js → Accordion-CaDTUDJG.js} +1 -1
  2. package/dist/Accordion.js +2 -2
  3. package/dist/{Button-D1aYnunQ.js → Button-BF3_6xgs.js} +3 -3
  4. package/dist/Button.js +4 -4
  5. package/dist/{ButtonGroup-CqThYjzX.js → ButtonGroup-grJiWGHI.js} +2 -2
  6. package/dist/ButtonGroup.js +5 -5
  7. package/dist/{ChartWrapper-BjVT4x-H.js → ChartWrapper-CeolXijF.js} +2 -2
  8. package/dist/ChartWrapper.js +3 -3
  9. package/dist/{Checkbox-HxYqp2w4.js → Checkbox-DGUZ1XtB.js} +2 -2
  10. package/dist/Checkbox.js +3 -3
  11. package/dist/{CheckboxGroup-DYws2rwt.js → CheckboxGroup-CGdyk_RP.js} +2 -2
  12. package/dist/CheckboxGroup.js +4 -4
  13. package/dist/{Chip-gKxD6IaZ.js → Chip-BpKH3_Nk.js} +1 -1
  14. package/dist/Chip.js +2 -2
  15. package/dist/{ChipGroup-ZvBzX_wd.js → ChipGroup-dSAMpfy1.js} +1 -1
  16. package/dist/ChipGroup.js +3 -3
  17. package/dist/ChipLink.js +2 -2
  18. package/dist/ChipRemovable.js +3 -3
  19. package/dist/ChipSelectable.js +2 -2
  20. package/dist/{Dialog-BYpzTprV.js → Dialog-CC674l80.js} +2 -2
  21. package/dist/Dialog.js +3 -3
  22. package/dist/{Dropdown-C4CgE4E-.js → Dropdown-B9YTM5N_.js} +5 -5
  23. package/dist/Dropdown.d.ts +2 -2
  24. package/dist/Dropdown.js +8 -8
  25. package/dist/{FileInput-nsnSQCaU.js → FileInput-D4kyWFkL.js} +4 -4
  26. package/dist/FileInput.js +6 -6
  27. package/dist/{Icon-D8HTPEFH.js → Icon-DOcb_NlX.js} +1 -1
  28. package/dist/Icon.js +2 -2
  29. package/dist/{Input-OrILqlax.js → Input-6Xu1N2sA.js} +2 -2
  30. package/dist/Input.js +3 -3
  31. package/dist/{LeuElement-C_lcHzQI.js → LeuElement-C3HedxlQ.js} +1 -1
  32. package/dist/{Menu-CFLCnI34.js → Menu-CJtyuUvP.js} +2 -2
  33. package/dist/{Menu-Z2b7dsB5.d.ts → Menu-txbYINTW.d.ts} +1 -1
  34. package/dist/Menu.d.ts +1 -1
  35. package/dist/Menu.js +4 -4
  36. package/dist/{MenuItem-LY4TRIho.d.ts → MenuItem-9TTOrL0Z.d.ts} +1 -1
  37. package/dist/{MenuItem-ICjLCGim.js → MenuItem-ClSE3auh.js} +2 -2
  38. package/dist/MenuItem.d.ts +1 -1
  39. package/dist/MenuItem.js +3 -3
  40. package/dist/{Message-Dw5D_0i1.js → Message-C55ydBaU.js} +2 -2
  41. package/dist/Message.js +3 -3
  42. package/dist/{Pagination-D1tP5FrM.js → Pagination-BVwKLcd5.js} +4 -4
  43. package/dist/Pagination.js +6 -6
  44. package/dist/{Placeholder-CnGzCZ5-.js → Placeholder-DFNppiVf.js} +1 -1
  45. package/dist/Placeholder.js +2 -2
  46. package/dist/{Popup-BiN_tZDN.js → Popup-D91ZiFWh.js} +1 -1
  47. package/dist/Popup.js +2 -2
  48. package/dist/{ProgressBar-BfJo_KyU.js → ProgressBar-DQGO2we8.js} +1 -1
  49. package/dist/ProgressBar.js +2 -2
  50. package/dist/{Radio-CV7vuQUj.js → Radio-BetZNoUQ.js} +1 -1
  51. package/dist/Radio.js +2 -2
  52. package/dist/{RadioGroup-C3XWSScc.js → RadioGroup-DzW5z_SD.js} +2 -2
  53. package/dist/RadioGroup.js +3 -3
  54. package/dist/{Range-C8RVrIM9.js → Range-9ijUzrty.js} +1 -1
  55. package/dist/Range.js +2 -2
  56. package/dist/{ScrollTop-B_TJ_k4m.js → ScrollTop-uDL4K_C6.js} +3 -3
  57. package/dist/ScrollTop.js +5 -5
  58. package/dist/{Select-CbPTrL3G.js → Select-ClGNTYfp.js} +7 -7
  59. package/dist/Select.d.ts +2 -2
  60. package/dist/Select.js +9 -9
  61. package/dist/{Spinner-ChKJQJTN.js → Spinner-B7ikVfUZ.js} +1 -1
  62. package/dist/Spinner.js +2 -2
  63. package/dist/{Tab-BJbzY1xd.js → Tab-CSHR71IX.js} +1 -1
  64. package/dist/Tab.js +2 -2
  65. package/dist/{TabGroup-BIaCHrKR.js → TabGroup-D7YbKXm8.js} +3 -3
  66. package/dist/TabGroup.js +4 -4
  67. package/dist/{TabPanel-CTyw410b.js → TabPanel-D_RHF3lv.js} +1 -1
  68. package/dist/TabPanel.js +2 -2
  69. package/dist/{Table-D3QmePJd.js → Table-CdosaNFb.js} +3 -3
  70. package/dist/Table.js +7 -7
  71. package/dist/{Tag-nUnWtHYy.js → Tag-BQBgkkAs.js} +1 -1
  72. package/dist/Tag.js +2 -2
  73. package/dist/{VisuallyHidden-DF2q9pTa.js → VisuallyHidden-CEBTA6hv.js} +1 -1
  74. package/dist/VisuallyHidden.js +2 -2
  75. package/dist/custom-elements.json +6445 -0
  76. package/dist/index.d.ts +2 -2
  77. package/dist/index.js +30 -30
  78. package/dist/leu-accordion.js +2 -2
  79. package/dist/leu-button-group.js +5 -5
  80. package/dist/leu-button.js +4 -4
  81. package/dist/leu-chart-wrapper.js +3 -3
  82. package/dist/leu-checkbox-group.js +4 -4
  83. package/dist/leu-checkbox.js +3 -3
  84. package/dist/leu-chip-group.js +3 -3
  85. package/dist/leu-chip-link.js +2 -2
  86. package/dist/leu-chip-removable.js +3 -3
  87. package/dist/leu-chip-selectable.js +2 -2
  88. package/dist/leu-dialog.js +3 -3
  89. package/dist/leu-dropdown.js +8 -8
  90. package/dist/leu-file-input.js +6 -6
  91. package/dist/leu-icon.js +2 -2
  92. package/dist/leu-input.js +3 -3
  93. package/dist/leu-menu-item.d.ts +1 -1
  94. package/dist/leu-menu-item.js +3 -3
  95. package/dist/leu-menu.d.ts +1 -1
  96. package/dist/leu-menu.js +4 -4
  97. package/dist/leu-message.js +3 -3
  98. package/dist/leu-pagination.js +6 -6
  99. package/dist/leu-placeholder.js +2 -2
  100. package/dist/leu-popup.js +2 -2
  101. package/dist/leu-progress-bar.js +2 -2
  102. package/dist/leu-radio-group.js +3 -3
  103. package/dist/leu-radio.js +2 -2
  104. package/dist/leu-range.js +2 -2
  105. package/dist/leu-scroll-top.js +5 -5
  106. package/dist/leu-select.js +9 -9
  107. package/dist/leu-spinner.js +2 -2
  108. package/dist/leu-tab-group.js +4 -4
  109. package/dist/leu-tab-panel.js +2 -2
  110. package/dist/leu-tab.js +2 -2
  111. package/dist/leu-table.js +7 -7
  112. package/dist/leu-tag.js +2 -2
  113. package/dist/leu-visually-hidden.js +2 -2
  114. package/dist/vscode.html-custom-data.json +11 -11
  115. package/dist/vue/index.d.ts +20 -20
  116. package/dist/web-types.json +28 -28
  117. package/package.json +4 -1
  118. package/.editorconfig +0 -29
  119. package/.github/workflows/ci.yml +0 -81
  120. package/.github/workflows/deploy-github-pages.yaml +0 -34
  121. package/.github/workflows/publish.yml +0 -28
  122. package/.github/workflows/release-please.yml +0 -19
  123. package/.husky/commit-msg +0 -1
  124. package/.husky/pre-commit +0 -1
  125. package/.nvmrc +0 -1
  126. package/.prettierignore +0 -2
  127. package/.release-please-manifest.json +0 -3
  128. package/.storybook/main.ts +0 -34
  129. package/.storybook/manager-head.html +0 -1
  130. package/.storybook/manager.ts +0 -6
  131. package/.storybook/preview.ts +0 -96
  132. package/.storybook/static/fonts/Inter-Black.woff2 +0 -0
  133. package/.storybook/static/fonts/Inter-Regular.woff2 +0 -0
  134. package/.storybook/static/fonts.css +0 -11
  135. package/.storybook/static/global.css +0 -5
  136. package/.storybook/static/logo.svg +0 -19
  137. package/.storybook/theme.ts +0 -8
  138. package/AGENTS.md +0 -162
  139. package/CHANGELOG.md +0 -601
  140. package/CODE_OF_CONDUCT.md +0 -128
  141. package/CONTRIBUTING.md +0 -42
  142. package/commitlint.config.cjs +0 -1
  143. package/custom-elements-manifest.config.js +0 -46
  144. package/eslint.config.mjs +0 -79
  145. package/postcss.config.cjs +0 -16
  146. package/release-please-config.json +0 -9
  147. package/scripts/generate-component/generate.js +0 -167
  148. package/scripts/generate-component/templates/[Name].ts +0 -31
  149. package/scripts/generate-component/templates/[name].css +0 -6
  150. package/scripts/generate-component/templates/[namespace]-[name].ts +0 -11
  151. package/scripts/generate-component/templates/stories/[name].stories.ts +0 -26
  152. package/scripts/generate-component/templates/test/[name].test.ts +0 -23
  153. package/scripts/postcss-leu-font-styles.cjs +0 -154
  154. package/src/components/accordion/Accordion.ts +0 -108
  155. package/src/components/accordion/accordion.css +0 -150
  156. package/src/components/accordion/leu-accordion.ts +0 -11
  157. package/src/components/accordion/stories/accordion.stories.ts +0 -62
  158. package/src/components/accordion/test/accordion.test.ts +0 -118
  159. package/src/components/button/Button.ts +0 -286
  160. package/src/components/button/button.css +0 -317
  161. package/src/components/button/leu-button.ts +0 -11
  162. package/src/components/button/stories/button.stories.ts +0 -366
  163. package/src/components/button/test/button.test.ts +0 -417
  164. package/src/components/button-group/ButtonGroup.ts +0 -97
  165. package/src/components/button-group/button-group.css +0 -5
  166. package/src/components/button-group/leu-button-group.ts +0 -11
  167. package/src/components/button-group/stories/button-group.stories.ts +0 -54
  168. package/src/components/button-group/test/button-group.test.ts +0 -105
  169. package/src/components/chart-wrapper/ChartWrapper.ts +0 -78
  170. package/src/components/chart-wrapper/chart-wrapper.css +0 -87
  171. package/src/components/chart-wrapper/leu-chart-wrapper.ts +0 -11
  172. package/src/components/chart-wrapper/stories/chart-wrapper.stories.ts +0 -58
  173. package/src/components/chart-wrapper/test/chart-wrapper.test.ts +0 -77
  174. package/src/components/checkbox/Checkbox.ts +0 -129
  175. package/src/components/checkbox/CheckboxGroup.ts +0 -57
  176. package/src/components/checkbox/checkbox-group.css +0 -29
  177. package/src/components/checkbox/checkbox.css +0 -81
  178. package/src/components/checkbox/leu-checkbox-group.ts +0 -11
  179. package/src/components/checkbox/leu-checkbox.ts +0 -11
  180. package/src/components/checkbox/stories/checkbox-group.stories.ts +0 -59
  181. package/src/components/checkbox/stories/checkbox.stories.ts +0 -72
  182. package/src/components/checkbox/test/checkbox-group.test.ts +0 -109
  183. package/src/components/checkbox/test/checkbox.test.ts +0 -247
  184. package/src/components/chip/Chip.ts +0 -19
  185. package/src/components/chip/ChipGroup.ts +0 -122
  186. package/src/components/chip/ChipLink.ts +0 -24
  187. package/src/components/chip/ChipRemovable.ts +0 -45
  188. package/src/components/chip/ChipSelectable.ts +0 -80
  189. package/src/components/chip/chip-group.css +0 -15
  190. package/src/components/chip/chip.css +0 -139
  191. package/src/components/chip/exports.ts +0 -4
  192. package/src/components/chip/leu-chip-group.ts +0 -11
  193. package/src/components/chip/leu-chip-link.ts +0 -11
  194. package/src/components/chip/leu-chip-removable.ts +0 -11
  195. package/src/components/chip/leu-chip-selectable.ts +0 -11
  196. package/src/components/chip/stories/chip-group.stories.ts +0 -159
  197. package/src/components/chip/stories/chip-link.stories.ts +0 -45
  198. package/src/components/chip/stories/chip-removable.stories.ts +0 -42
  199. package/src/components/chip/stories/chip-selectable.stories.ts +0 -54
  200. package/src/components/chip/test/chip-group.test.ts +0 -171
  201. package/src/components/chip/test/chip-link.test.ts +0 -54
  202. package/src/components/chip/test/chip-removable.test.ts +0 -105
  203. package/src/components/chip/test/chip-selectable.test.ts +0 -101
  204. package/src/components/chip/test/chip.test.ts +0 -22
  205. package/src/components/dialog/Dialog.ts +0 -86
  206. package/src/components/dialog/dialog.css +0 -157
  207. package/src/components/dialog/leu-dialog.ts +0 -11
  208. package/src/components/dialog/stories/dialog.stories.ts +0 -142
  209. package/src/components/dialog/test/dialog.test.ts +0 -85
  210. package/src/components/dropdown/Dropdown.ts +0 -152
  211. package/src/components/dropdown/dropdown.css +0 -16
  212. package/src/components/dropdown/leu-dropdown.ts +0 -11
  213. package/src/components/dropdown/stories/dropdown.stories.ts +0 -58
  214. package/src/components/dropdown/test/dropdown.test.ts +0 -59
  215. package/src/components/file-input/FileInput.ts +0 -324
  216. package/src/components/file-input/file-input.css +0 -118
  217. package/src/components/file-input/leu-file-input.ts +0 -11
  218. package/src/components/file-input/stories/file-input.stories.ts +0 -45
  219. package/src/components/file-input/test/file-input.test.ts +0 -62
  220. package/src/components/icon/Icon.ts +0 -47
  221. package/src/components/icon/icon.css +0 -10
  222. package/src/components/icon/leu-icon.ts +0 -11
  223. package/src/components/icon/paths.ts +0 -219
  224. package/src/components/icon/stories/icon.stories.ts +0 -79
  225. package/src/components/icon/test/icon.test.ts +0 -50
  226. package/src/components/input/Input.ts +0 -469
  227. package/src/components/input/input.css +0 -238
  228. package/src/components/input/leu-input.ts +0 -11
  229. package/src/components/input/stories/input.stories.ts +0 -204
  230. package/src/components/input/test/input.test.ts +0 -603
  231. package/src/components/menu/Menu.ts +0 -149
  232. package/src/components/menu/MenuItem.ts +0 -168
  233. package/src/components/menu/leu-menu-item.ts +0 -11
  234. package/src/components/menu/leu-menu.ts +0 -11
  235. package/src/components/menu/menu-item.css +0 -77
  236. package/src/components/menu/menu.css +0 -19
  237. package/src/components/menu/stories/menu-item.stories.ts +0 -81
  238. package/src/components/menu/stories/menu.stories.ts +0 -54
  239. package/src/components/menu/test/menu-item.test.ts +0 -210
  240. package/src/components/menu/test/menu.test.ts +0 -125
  241. package/src/components/message/Message.ts +0 -118
  242. package/src/components/message/leu-message.ts +0 -11
  243. package/src/components/message/message.css +0 -163
  244. package/src/components/message/stories/message.mdx +0 -76
  245. package/src/components/message/stories/message.stories.ts +0 -149
  246. package/src/components/message/test/message.test.ts +0 -96
  247. package/src/components/pagination/Pagination.ts +0 -192
  248. package/src/components/pagination/leu-pagination.ts +0 -11
  249. package/src/components/pagination/pagination.css +0 -54
  250. package/src/components/pagination/stories/pagination.stories.ts +0 -115
  251. package/src/components/pagination/test/pagination.test.ts +0 -210
  252. package/src/components/placeholder/Placeholder.ts +0 -33
  253. package/src/components/placeholder/leu-placeholder.ts +0 -11
  254. package/src/components/placeholder/placeholder.css +0 -59
  255. package/src/components/placeholder/stories/placeholder.stories.ts +0 -34
  256. package/src/components/placeholder/test/placeholder.test.ts +0 -31
  257. package/src/components/popup/Popup.ts +0 -264
  258. package/src/components/popup/leu-popup.ts +0 -11
  259. package/src/components/popup/popup.css +0 -24
  260. package/src/components/popup/stories/popup.stories.ts +0 -117
  261. package/src/components/popup/test/popup.test.ts +0 -90
  262. package/src/components/progress-bar/ProgressBar.ts +0 -52
  263. package/src/components/progress-bar/leu-progress-bar.ts +0 -11
  264. package/src/components/progress-bar/progress-bar.css +0 -97
  265. package/src/components/progress-bar/stories/progress-bar.stories.ts +0 -39
  266. package/src/components/progress-bar/test/progress-bar.test.ts +0 -61
  267. package/src/components/radio/Radio.ts +0 -59
  268. package/src/components/radio/RadioGroup.ts +0 -181
  269. package/src/components/radio/leu-radio-group.ts +0 -11
  270. package/src/components/radio/leu-radio.ts +0 -11
  271. package/src/components/radio/radio-group.css +0 -29
  272. package/src/components/radio/radio.css +0 -76
  273. package/src/components/radio/stories/radio-group.stories.ts +0 -54
  274. package/src/components/radio/stories/radio.stories.ts +0 -55
  275. package/src/components/radio/test/radio-group.test.ts +0 -83
  276. package/src/components/radio/test/radio.test.ts +0 -119
  277. package/src/components/range/Range.ts +0 -400
  278. package/src/components/range/leu-range.ts +0 -11
  279. package/src/components/range/range.css +0 -227
  280. package/src/components/range/stories/range.stories.ts +0 -185
  281. package/src/components/range/test/range.test.ts +0 -228
  282. package/src/components/scroll-top/ScrollTop.ts +0 -91
  283. package/src/components/scroll-top/leu-scroll-top.ts +0 -11
  284. package/src/components/scroll-top/scroll-top.css +0 -50
  285. package/src/components/scroll-top/stories/scroll-top.stories.ts +0 -217
  286. package/src/components/scroll-top/test/scroll-top.test.ts +0 -22
  287. package/src/components/select/Select.ts +0 -570
  288. package/src/components/select/leu-select.ts +0 -11
  289. package/src/components/select/select.css +0 -222
  290. package/src/components/select/stories/select.stories.ts +0 -173
  291. package/src/components/select/test/fixtures.ts +0 -162
  292. package/src/components/select/test/select.test.ts +0 -937
  293. package/src/components/spinner/Spinner.ts +0 -31
  294. package/src/components/spinner/leu-spinner.ts +0 -11
  295. package/src/components/spinner/spinner.css +0 -20
  296. package/src/components/spinner/stories/spinner.stories.ts +0 -29
  297. package/src/components/spinner/test/spinner.test.ts +0 -30
  298. package/src/components/tab/Tab.ts +0 -72
  299. package/src/components/tab/TabGroup.ts +0 -267
  300. package/src/components/tab/TabPanel.ts +0 -59
  301. package/src/components/tab/leu-tab-group.ts +0 -11
  302. package/src/components/tab/leu-tab-panel.ts +0 -11
  303. package/src/components/tab/leu-tab.ts +0 -11
  304. package/src/components/tab/stories/tab.stories.ts +0 -97
  305. package/src/components/tab/tab-group.css +0 -63
  306. package/src/components/tab/tab-panel.css +0 -10
  307. package/src/components/tab/tab.css +0 -54
  308. package/src/components/tab/test/tab-group.test.ts +0 -426
  309. package/src/components/tab/test/tab-panel.test.ts +0 -102
  310. package/src/components/tab/test/tab.test.ts +0 -139
  311. package/src/components/table/Table.ts +0 -253
  312. package/src/components/table/leu-table.ts +0 -11
  313. package/src/components/table/stories/table.stories.ts +0 -131
  314. package/src/components/table/table.css +0 -112
  315. package/src/components/table/test/table.test.ts +0 -37
  316. package/src/components/tag/Tag.ts +0 -28
  317. package/src/components/tag/leu-tag.ts +0 -11
  318. package/src/components/tag/stories/tag.stories.ts +0 -107
  319. package/src/components/tag/tag.css +0 -42
  320. package/src/components/tag/test/tag.test.ts +0 -28
  321. package/src/components/visually-hidden/VisuallyHidden.ts +0 -16
  322. package/src/components/visually-hidden/leu-visually-hidden.ts +0 -11
  323. package/src/components/visually-hidden/stories/visually-hidden.stories.ts +0 -22
  324. package/src/components/visually-hidden/test/visually-hidden.test.ts +0 -34
  325. package/src/components/visually-hidden/visually-hidden.css +0 -10
  326. package/src/docs/contributing.mdx +0 -154
  327. package/src/docs/installation.mdx +0 -35
  328. package/src/docs/theme.mdx +0 -400
  329. package/src/docs/usage.mdx +0 -73
  330. package/src/global.d.ts +0 -11
  331. package/src/index.ts +0 -29
  332. package/src/lib/LeuElement.ts +0 -43
  333. package/src/lib/a11y.ts +0 -26
  334. package/src/lib/hasSlotController.ts +0 -74
  335. package/src/lib/mixins/FormAssociatedMixin.ts +0 -115
  336. package/src/lib/styleMap.ts +0 -139
  337. package/src/lib/utils.ts +0 -45
  338. package/src/styles/common-styles.css +0 -14
  339. package/src/styles/custom-media.css +0 -6
  340. package/src/styles/font-definitions.json +0 -210
  341. package/src/styles/style.stories.ts +0 -64
  342. package/src/styles/theme.css +0 -90
  343. package/stat_zh.png +0 -0
  344. package/stylelint.config.mjs +0 -23
  345. package/tsconfig.build.json +0 -24
  346. package/tsconfig.json +0 -14
  347. package/tsdown.config.ts +0 -35
  348. package/web-test-runner.config.mjs +0 -102
@@ -1,63 +0,0 @@
1
- @import url("../../styles/custom-media.css");
2
-
3
- :host {
4
- --tab-font-regular: var(--leu-font-family-regular);
5
- --tab-font-black: var(--leu-font-family-black);
6
-
7
- font-family: var(--tab-font-regular);
8
- }
9
-
10
- .container {
11
- position: relative;
12
- width: 100%;
13
- }
14
-
15
- .container::before,
16
- .container::after {
17
- content: "";
18
- position: absolute;
19
- top: 0;
20
- height: 100%;
21
- width: 0.375rem;
22
- pointer-events: none;
23
- visibility: hidden;
24
- opacity: 0;
25
- transition: 0.2s ease;
26
- transition-property: visibility, opacity;
27
- }
28
-
29
- .container::before {
30
- left: 0;
31
- background: linear-gradient(to right, rgb(0 0 0 / 20%), transparent);
32
- }
33
-
34
- .container::after {
35
- right: 0;
36
- background: linear-gradient(to left, rgb(0 0 0 / 20%), transparent);
37
- }
38
-
39
- .container--scrollable-left::before,
40
- .container--scrollable-right::after {
41
- visibility: visible;
42
- opacity: 1;
43
- }
44
-
45
- .tab-menu {
46
- display: flex;
47
- gap: 0.5rem;
48
- padding: 0.5rem 0;
49
- margin-bottom: 1.5rem;
50
- border-bottom: 1px solid var(--leu-color-black-transp-10);
51
-
52
- overflow: auto;
53
- scrollbar-width: thin;
54
-
55
- @media (--viewport-large) {
56
- margin-bottom: 2rem;
57
- }
58
-
59
- @media (--viewport-xlarge) {
60
- padding: 1rem 0;
61
- margin-bottom: 2.5rem;
62
- }
63
- }
@@ -1,10 +0,0 @@
1
- :host {
2
- --tab-panel-font-regular: var(--leu-font-family-regular);
3
- --tab-panel-font-black: var(--leu-font-family-black);
4
-
5
- font-family: var(--tab-panel-font-regular);
6
- }
7
-
8
- :host([aria-hidden="true"]) {
9
- display: none;
10
- }
@@ -1,54 +0,0 @@
1
- @import url("../../styles/custom-media.css");
2
-
3
- :host {
4
- --tab-button-font-regular: var(--leu-font-family-regular);
5
-
6
- --tab-button-active-background: var(--leu-color-black-100);
7
- --tab-button-active-color: var(--leu-color-black-0);
8
-
9
- --tab-button-inactive-background: var(--leu-color-black-transp-10);
10
- --tab-button-inactive-color: var(--leu-color-black-transp-60);
11
-
12
- --tab-button-hover-background: var(--leu-color-black-transp-20);
13
-
14
- display: flex;
15
- justify-content: center;
16
- align-items: center;
17
- font-family: var(--tab-button-font-regular);
18
- background: var(--tab-button-inactive-background);
19
- color: var(--tab-button-inactive-color);
20
- border: 0;
21
- border-radius: 0.25rem;
22
- padding: 0.5rem 0.75rem;
23
- cursor: pointer;
24
-
25
- white-space: nowrap;
26
-
27
- @media (--viewport-large) {
28
- padding-inline: 1rem;
29
- }
30
- }
31
-
32
- :host(:hover) {
33
- background: var(--tab-button-hover-background);
34
- }
35
-
36
- :host(:focus-visible) {
37
- outline: 2px solid var(--leu-color-func-cyan);
38
- outline-offset: 2px;
39
- }
40
-
41
- :host([active]) {
42
- background: var(--tab-button-active-background);
43
- color: var(--tab-button-active-color);
44
- }
45
-
46
- .label {
47
- font-size: 1rem;
48
- line-height: 1.5rem;
49
-
50
- @media (--viewport-large) {
51
- font-size: 1.125rem;
52
- line-height: 1.75rem;
53
- }
54
- }
@@ -1,426 +0,0 @@
1
- import { html } from "lit"
2
- import { ifDefined } from "lit/directives/if-defined.js"
3
- import { fixture, expect, oneEvent } from "@open-wc/testing"
4
- import { sendKeys } from "@web/test-runner-commands"
5
- import { spy } from "sinon"
6
-
7
- import "../leu-tab-group.js"
8
- import "../leu-tab.js"
9
- import "../leu-tab-panel.js"
10
- import type { LeuTabGroup } from "../TabGroup.js"
11
- import type { LeuTab } from "../Tab.js"
12
- import type { LeuTabPanel } from "../TabPanel.js"
13
-
14
- type TestArgs = {
15
- active?: string
16
- label?: string
17
- }
18
-
19
- async function defaultFixture(args: TestArgs = {}) {
20
- return fixture<LeuTabGroup>(html`
21
- <leu-tab-group
22
- active=${ifDefined(args.active)}
23
- label=${ifDefined(args.label)}
24
- >
25
- <leu-tab slot="tabs" name="online">Online</leu-tab>
26
- <leu-tab-panel slot="panels" name="online"><p>Online</p></leu-tab-panel>
27
-
28
- <leu-tab slot="tabs" name="vor-ort">Vor Ort</leu-tab>
29
- <leu-tab-panel slot="panels" name="vor-ort"><p>Vor Ort</p></leu-tab-panel>
30
-
31
- <leu-tab slot="tabs" name="per-post">Per Post</leu-tab>
32
- <leu-tab-panel slot="panels" name="per-post">
33
- <p>Per Post</p>
34
- </leu-tab-panel>
35
- </leu-tab-group>
36
- `)
37
- }
38
-
39
- function getTabs(el: LeuTabGroup): LeuTab[] {
40
- return Array.from(el.querySelectorAll<LeuTab>("leu-tab"))
41
- }
42
-
43
- function getPanels(el: LeuTabGroup): LeuTabPanel[] {
44
- return Array.from(el.querySelectorAll<LeuTabPanel>("leu-tab-panel"))
45
- }
46
-
47
- // ─── Element registration ─────────────────────────────────────────────────────
48
-
49
- describe("LeuTabGroup – element registration", () => {
50
- it("leu-tab-group is a defined element", () => {
51
- expect(customElements.get("leu-tab-group")).not.to.be.undefined
52
- })
53
- })
54
-
55
- // ─── Accessibility ────────────────────────────────────────────────────────────
56
-
57
- describe("LeuTabGroup – a11y", () => {
58
- it("passes the a11y audit", async () => {
59
- const el = await defaultFixture({ label: "Navigation" })
60
- await expect(el).shadowDom.to.be.accessible()
61
- })
62
-
63
- it("sets aria-label on the tablist from the label attribute", async () => {
64
- const el = await defaultFixture({ label: "Kanal wählen" })
65
- const tablist = el.shadowRoot!.querySelector("[role='tablist']")
66
- expect(tablist!.getAttribute("aria-label")).to.equal("Kanal wählen")
67
- })
68
- })
69
-
70
- // ─── Active fallback ─────────────────────────────────────────────────────────
71
-
72
- describe("LeuTabGroup – active fallback", () => {
73
- it("activates the first tab when no active prop is set", async () => {
74
- const el = await defaultFixture()
75
- expect(el.active).to.equal("online")
76
- })
77
-
78
- it("activates the first tab when the active prop doesn't match any tab", async () => {
79
- const el = await defaultFixture({ active: "nonexistent" })
80
- expect(el.active).to.equal("online")
81
- })
82
-
83
- it("preserves a valid pre-set active value", async () => {
84
- const el = await defaultFixture({ active: "vor-ort" })
85
- expect(el.active).to.equal("vor-ort")
86
- })
87
-
88
- it("the active tab and panel are in sync", async () => {
89
- const el = await defaultFixture()
90
- const panels = getPanels(el)
91
- const activePanel = panels.find((p) => p.active)
92
- expect(activePanel?.getAttribute("name") ?? activePanel?.name).to.equal(
93
- el.active,
94
- )
95
- })
96
- })
97
-
98
- // ─── Tab/panel state ──────────────────────────────────────────────────────────
99
-
100
- describe("LeuTabGroup – tab and panel state", () => {
101
- it("only one tab is active at a time", async () => {
102
- const el = await defaultFixture()
103
- const activeTabs = getTabs(el).filter((t) => t.active)
104
- expect(activeTabs).to.have.length(1)
105
- })
106
-
107
- it("only one panel is active at a time", async () => {
108
- const el = await defaultFixture()
109
- const activePanels = getPanels(el).filter((p) => p.active)
110
- expect(activePanels).to.have.length(1)
111
- })
112
-
113
- it("inactive tabs have ariaSelected=false", async () => {
114
- const el = await defaultFixture()
115
- const inactiveTabs = getTabs(el).filter((t) => !t.active)
116
- for (const tab of inactiveTabs) {
117
- expect(tab.ariaSelected).to.equal("false")
118
- }
119
- })
120
-
121
- it("the active tab has ariaSelected=true", async () => {
122
- const el = await defaultFixture()
123
- const activeTab = getTabs(el).find((t) => t.active)!
124
- expect(activeTab.ariaSelected).to.equal("true")
125
- })
126
- })
127
-
128
- // ─── Linking tabs and panels ──────────────────────────────────────────────────
129
-
130
- describe("LeuTabGroup – aria linking", () => {
131
- it("each tab's aria-controls points to its panel's id", async () => {
132
- const el = await defaultFixture()
133
- const tabs = getTabs(el)
134
- const panels = getPanels(el)
135
-
136
- for (const tab of tabs) {
137
- const panel = panels.find((p) => p.name === tab.name)!
138
- expect(tab.getAttribute("aria-controls")).to.equal(panel.id)
139
- }
140
- })
141
-
142
- it("each panel's aria-labelledby points to its tab's id", async () => {
143
- const el = await defaultFixture()
144
- const tabs = getTabs(el)
145
- const panels = getPanels(el)
146
-
147
- for (const panel of panels) {
148
- const tab = tabs.find((t) => t.name === panel.name)!
149
- expect(panel.getAttribute("aria-labelledby")).to.equal(tab.id)
150
- }
151
- })
152
-
153
- it("uses custom ids provided by the user for aria linking", async () => {
154
- const el = await fixture<LeuTabGroup>(html`
155
- <leu-tab-group>
156
- <leu-tab id="tab-custom" slot="tabs" name="a">A</leu-tab>
157
- <leu-tab-panel id="panel-custom" slot="panels" name="a"
158
- >A</leu-tab-panel
159
- >
160
- </leu-tab-group>
161
- `)
162
- const tab = el.querySelector<LeuTab>("leu-tab")!
163
- const panel = el.querySelector<LeuTabPanel>("leu-tab-panel")!
164
- expect(tab.getAttribute("aria-controls")).to.equal("panel-custom")
165
- expect(panel.getAttribute("aria-labelledby")).to.equal("tab-custom")
166
- })
167
-
168
- it("re-links tabs and panels when a tab's id changes", async () => {
169
- const el = await defaultFixture()
170
- const tab = getTabs(el)[0]
171
- const panel = getPanels(el)[0]
172
-
173
- // Simulate id being set (e.g., late server render)
174
- tab.id = "new-tab-id"
175
-
176
- // MutationObserver fires asynchronously
177
- await new Promise((r) => setTimeout(r, 0))
178
- await el.updateComplete
179
-
180
- expect(panel.getAttribute("aria-labelledby")).to.equal("new-tab-id")
181
- })
182
- })
183
-
184
- // ─── Click selection ──────────────────────────────────────────────────────────
185
-
186
- describe("LeuTabGroup – click selection", () => {
187
- it("clicking an inactive tab makes it the active tab", async () => {
188
- const el = await defaultFixture()
189
- const [, secondTab] = getTabs(el)
190
-
191
- secondTab.click()
192
- await el.updateComplete
193
-
194
- expect(el.active).to.equal("vor-ort")
195
- })
196
-
197
- it("clicking an inactive tab deactivates all other tabs", async () => {
198
- const el = await defaultFixture()
199
- const tabs = getTabs(el)
200
-
201
- tabs[1].click()
202
- await el.updateComplete
203
-
204
- const activeTabs = tabs.filter((t) => t.active)
205
- expect(activeTabs).to.have.length(1)
206
- expect(activeTabs[0].name).to.equal("vor-ort")
207
- })
208
-
209
- it("clicking an inactive tab activates the corresponding panel", async () => {
210
- const el = await defaultFixture()
211
- const tabs = getTabs(el)
212
- const panels = getPanels(el)
213
-
214
- tabs[2].click()
215
- await el.updateComplete
216
-
217
- const activePanel = panels.find((p) => p.active)!
218
- expect(activePanel.name).to.equal("per-post")
219
- })
220
-
221
- it("clicking an already-active tab has no effect", async () => {
222
- const el = await defaultFixture()
223
- const [firstTab] = getTabs(el)
224
- expect(el.active).to.equal("online")
225
-
226
- firstTab.click()
227
- await el.updateComplete
228
-
229
- expect(el.active).to.equal("online")
230
- expect(getTabs(el).filter((t) => t.active)).to.have.length(1)
231
- })
232
-
233
- it("programmatically setting active changes the active tab and panel", async () => {
234
- const el = await defaultFixture()
235
-
236
- el.active = "per-post"
237
- await el.updateComplete
238
-
239
- const activeTab = getTabs(el).find((t) => t.active)!
240
- const activePanel = getPanels(el).find((p) => p.active)!
241
- expect(activeTab.name).to.equal("per-post")
242
- expect(activePanel.name).to.equal("per-post")
243
- })
244
- })
245
-
246
- // ─── leu:show-tab-panel event ─────────────────────────────────────────────────
247
-
248
- describe("LeuTabGroup – leu:show-tab-panel event", () => {
249
- it("fires leu:show-tab-panel when clicking an inactive tab", async () => {
250
- const el = await defaultFixture()
251
- const [, secondTab] = getTabs(el)
252
-
253
- setTimeout(() => secondTab.click())
254
- const event = (await oneEvent(el, "leu:show-tab-panel")) as CustomEvent
255
-
256
- expect(event).to.exist
257
- expect(event.detail.name).to.equal("vor-ort")
258
- })
259
-
260
- it("fires leu:show-tab-panel when active is changed programmatically", async () => {
261
- const el = await defaultFixture()
262
-
263
- setTimeout(() => {
264
- el.active = "per-post"
265
- })
266
- const event = (await oneEvent(el, "leu:show-tab-panel")) as CustomEvent
267
-
268
- expect(event.detail.name).to.equal("per-post")
269
- })
270
-
271
- it("does NOT fire leu:show-tab-panel when clicking an already-active tab", async () => {
272
- const el = await defaultFixture()
273
- const [firstTab] = getTabs(el)
274
-
275
- let firedCount = 0
276
- el.addEventListener("leu:show-tab-panel", () => {
277
- firedCount++
278
- })
279
-
280
- firstTab.click()
281
- await el.updateComplete
282
-
283
- expect(firedCount).to.equal(0)
284
- })
285
-
286
- it("fires leu:show-tab-panel on initial render when active is not pre-set", async () => {
287
- const showSpy = spy()
288
-
289
- await fixture<HTMLDivElement>(html`
290
- <div @leu:show-tab-panel=${showSpy}>
291
- <leu-tab-group>
292
- <leu-tab slot="tabs" name="a">A</leu-tab>
293
- <leu-tab-panel slot="panels" name="a">A</leu-tab-panel>
294
- <leu-tab slot="tabs" name="b">B</leu-tab>
295
- <leu-tab-panel slot="panels" name="b">B</leu-tab-panel>
296
- </leu-tab-group>
297
- </div>
298
- `)
299
-
300
- expect(showSpy).to.be.calledOnce
301
- expect(showSpy.args[0][0].detail.name).to.equal("a")
302
- })
303
-
304
- it("fires leu:show-tab-panel on initial render when active is pre-set", async () => {
305
- const showSpy = spy()
306
-
307
- await fixture<HTMLDivElement>(html`
308
- <div @leu:show-tab-panel=${showSpy}>
309
- <leu-tab-group active="b">
310
- <leu-tab slot="tabs" name="a">A</leu-tab>
311
- <leu-tab-panel slot="panels" name="a">A</leu-tab-panel>
312
- <leu-tab slot="tabs" name="b">B</leu-tab>
313
- <leu-tab-panel slot="panels" name="b">B</leu-tab-panel>
314
- </leu-tab-group>
315
- </div>
316
- `)
317
-
318
- expect(showSpy).to.be.calledOnce
319
- expect(showSpy.args[0][0].detail.name).to.equal("b")
320
- })
321
- })
322
-
323
- // ─── Keyboard control ─────────────────────────────────────────────────────────
324
-
325
- describe("LeuTabGroup – keyboard control", () => {
326
- it("ArrowRight moves to the next tab", async () => {
327
- const el = await defaultFixture()
328
-
329
- await sendKeys({ press: "Tab" })
330
- await sendKeys({ press: "ArrowRight" })
331
- await el.updateComplete
332
-
333
- expect(el.active).to.equal("vor-ort")
334
- })
335
-
336
- it("ArrowLeft moves to the previous tab", async () => {
337
- const el = await defaultFixture({ active: "vor-ort" })
338
-
339
- await sendKeys({ press: "Tab" })
340
- await sendKeys({ press: "ArrowLeft" })
341
- await el.updateComplete
342
-
343
- expect(el.active).to.equal("online")
344
- })
345
-
346
- it("ArrowRight wraps from the last tab to the first", async () => {
347
- const el = await defaultFixture({ active: "per-post" })
348
-
349
- await sendKeys({ press: "Tab" })
350
- await sendKeys({ press: "ArrowRight" })
351
- await el.updateComplete
352
-
353
- expect(el.active).to.equal("online")
354
- })
355
-
356
- it("ArrowLeft wraps from the first tab to the last", async () => {
357
- const el = await defaultFixture()
358
-
359
- await sendKeys({ press: "Tab" })
360
- await sendKeys({ press: "ArrowLeft" })
361
- await el.updateComplete
362
-
363
- expect(el.active).to.equal("per-post")
364
- })
365
-
366
- it("Home key moves to the first tab", async () => {
367
- const el = await defaultFixture({ active: "per-post" })
368
-
369
- await sendKeys({ press: "Tab" })
370
- await sendKeys({ press: "Home" })
371
- await el.updateComplete
372
-
373
- expect(el.active).to.equal("online")
374
- })
375
-
376
- it("End key moves to the last tab", async () => {
377
- const el = await defaultFixture()
378
-
379
- await sendKeys({ press: "Tab" })
380
- await sendKeys({ press: "End" })
381
- await el.updateComplete
382
-
383
- expect(el.active).to.equal("per-post")
384
- })
385
-
386
- it("keyboard navigation moves focus to the newly active tab", async () => {
387
- const el = await defaultFixture()
388
- const tabs = getTabs(el)
389
-
390
- await sendKeys({ press: "Tab" })
391
- await sendKeys({ press: "ArrowRight" })
392
- await el.updateComplete
393
- await new Promise((r) => setTimeout(r, 0))
394
-
395
- expect(document.activeElement).to.equal(tabs[1])
396
- })
397
-
398
- it("non-navigation keys do not change the active tab", async () => {
399
- const el = await defaultFixture()
400
-
401
- await sendKeys({ press: "Tab" })
402
- for (const key of ["ArrowUp", "ArrowDown", "Enter", "Space"]) {
403
- await sendKeys({ press: key })
404
- }
405
- await el.updateComplete
406
-
407
- expect(el.active).to.equal("online")
408
- })
409
-
410
- it("keydown on an unfocused element does not trigger navigation", async () => {
411
- // A synthetic keydown dispatched on the host (not from a focused leu-tab)
412
- // must not reach the shadow-DOM tablist listener, so navigation must not occur.
413
- const el = await defaultFixture()
414
-
415
- el.dispatchEvent(
416
- new KeyboardEvent("keydown", {
417
- key: "ArrowRight",
418
- bubbles: true,
419
- composed: true,
420
- }),
421
- )
422
- await el.updateComplete
423
-
424
- expect(el.active).to.equal("online")
425
- })
426
- })
@@ -1,102 +0,0 @@
1
- import { html } from "lit"
2
- import { fixture, expect } from "@open-wc/testing"
3
-
4
- import "../leu-tab-panel.js"
5
- import type { LeuTabPanel } from "../TabPanel.js"
6
-
7
- async function defaultFixture() {
8
- return fixture<LeuTabPanel>(
9
- html`<leu-tab-panel name="test">Content</leu-tab-panel>`,
10
- )
11
- }
12
-
13
- async function activeFixture() {
14
- return fixture<LeuTabPanel>(
15
- html`<leu-tab-panel name="test" active>Content</leu-tab-panel>`,
16
- )
17
- }
18
-
19
- describe("LeuTabPanel", () => {
20
- it("is a defined element", () => {
21
- expect(customElements.get("leu-tab-panel")).not.to.be.undefined
22
- })
23
-
24
- it("passes the a11y audit in a proper tab context", async () => {
25
- const wrapper = await fixture(html`
26
- <div>
27
- <div role="tablist">
28
- <div id="panel-tab" role="tab" aria-selected="true" tabindex="0">
29
- Tab
30
- </div>
31
- </div>
32
- <leu-tab-panel aria-labelledby="panel-tab" name="test" active
33
- >Content</leu-tab-panel
34
- >
35
- </div>
36
- `)
37
- await expect(wrapper).to.be.accessible()
38
- })
39
-
40
- it("sets role=tabpanel on the host element", async () => {
41
- const el = await defaultFixture()
42
- expect(el.getAttribute("role")).to.equal("tabpanel")
43
- })
44
-
45
- it("sets tabIndex=0 on the host element", async () => {
46
- const el = await defaultFixture()
47
- expect(el.tabIndex).to.equal(0)
48
- })
49
-
50
- it("auto-generates an id when none is provided", async () => {
51
- const el = await defaultFixture()
52
- expect(el.id).to.match(/^leu-tab-panel-\d+$/)
53
- })
54
-
55
- it("keeps a user-provided id", async () => {
56
- const el = await fixture<LeuTabPanel>(
57
- html`<leu-tab-panel id="my-panel" name="test">Content</leu-tab-panel>`,
58
- )
59
- expect(el.id).to.equal("my-panel")
60
- })
61
-
62
- it("generates distinct ids for separate instances", async () => {
63
- const el1 = await fixture<LeuTabPanel>(
64
- html`<leu-tab-panel name="a">A</leu-tab-panel>`,
65
- )
66
- const el2 = await fixture<LeuTabPanel>(
67
- html`<leu-tab-panel name="b">B</leu-tab-panel>`,
68
- )
69
- expect(el1.id).not.to.equal(el2.id)
70
- })
71
-
72
- it("has ariaHidden=true when inactive (default)", async () => {
73
- const el = await defaultFixture()
74
- expect(el.ariaHidden).to.equal("true")
75
- })
76
-
77
- it("has ariaHidden=false when active", async () => {
78
- const el = await activeFixture()
79
- expect(el.ariaHidden).to.equal("false")
80
- })
81
-
82
- it("updates ariaHidden reactively when active changes", async () => {
83
- const el = await defaultFixture()
84
-
85
- el.active = true
86
- await el.updateComplete
87
- expect(el.ariaHidden).to.equal("false")
88
-
89
- el.active = false
90
- await el.updateComplete
91
- expect(el.ariaHidden).to.equal("true")
92
- })
93
-
94
- it("renders slotted content", async () => {
95
- const el = await fixture<LeuTabPanel>(
96
- html`<leu-tab-panel name="test" active
97
- ><p>Panel content</p></leu-tab-panel
98
- >`,
99
- )
100
- expect(el).to.have.text("Panel content")
101
- })
102
- })