@statistikzh/leu 0.28.0 → 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 (346) hide show
  1. package/dist/{Accordion-D9kLsiBW.js → Accordion-CaDTUDJG.js} +1 -1
  2. package/dist/Accordion.js +2 -2
  3. package/dist/{Button-DyNVOHCd.js → Button-BF3_6xgs.js} +3 -3
  4. package/dist/Button.js +4 -4
  5. package/dist/{ButtonGroup-MEh4vb5a.js → ButtonGroup-grJiWGHI.js} +2 -2
  6. package/dist/ButtonGroup.js +5 -5
  7. package/dist/{ChartWrapper-DAl91BIN.js → ChartWrapper-CeolXijF.js} +2 -2
  8. package/dist/ChartWrapper.js +3 -3
  9. package/dist/{Checkbox-CGGyUW9U.js → Checkbox-DGUZ1XtB.js} +2 -2
  10. package/dist/Checkbox.js +3 -3
  11. package/dist/{CheckboxGroup-DXt5iMdj.js → CheckboxGroup-CGdyk_RP.js} +2 -2
  12. package/dist/CheckboxGroup.js +4 -4
  13. package/dist/{Chip-BGs71WGH.js → Chip-BpKH3_Nk.js} +1 -1
  14. package/dist/Chip.js +2 -2
  15. package/dist/{ChipGroup-BcGyusP-.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-BzuyL1U3.js → Dialog-CC674l80.js} +2 -2
  21. package/dist/Dialog.js +3 -3
  22. package/dist/{Dropdown-plyBTM15.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-BT3Fe-0J.js → FileInput-D4kyWFkL.js} +8 -6
  26. package/dist/FileInput.d.ts +1 -1
  27. package/dist/FileInput.js +6 -6
  28. package/dist/{Icon-D83qesg5.js → Icon-DOcb_NlX.js} +1 -1
  29. package/dist/Icon.js +2 -2
  30. package/dist/{Input-D7zS50oz.js → Input-6Xu1N2sA.js} +2 -2
  31. package/dist/Input.js +3 -3
  32. package/dist/{LeuElement-DQI8cqZV.js → LeuElement-C3HedxlQ.js} +1 -1
  33. package/dist/{Menu-DRU1LiMM.js → Menu-CJtyuUvP.js} +2 -2
  34. package/dist/{Menu-Z2b7dsB5.d.ts → Menu-txbYINTW.d.ts} +1 -1
  35. package/dist/Menu.d.ts +1 -1
  36. package/dist/Menu.js +4 -4
  37. package/dist/{MenuItem-LY4TRIho.d.ts → MenuItem-9TTOrL0Z.d.ts} +1 -1
  38. package/dist/{MenuItem-DCttylRO.js → MenuItem-ClSE3auh.js} +2 -2
  39. package/dist/MenuItem.d.ts +1 -1
  40. package/dist/MenuItem.js +3 -3
  41. package/dist/{Message-0NxnKEqw.js → Message-C55ydBaU.js} +2 -2
  42. package/dist/Message.js +3 -3
  43. package/dist/{Pagination-CIy7YvWE.js → Pagination-BVwKLcd5.js} +4 -4
  44. package/dist/Pagination.js +6 -6
  45. package/dist/{Placeholder-Dol_X5Hp.js → Placeholder-DFNppiVf.js} +1 -1
  46. package/dist/Placeholder.js +2 -2
  47. package/dist/{Popup-nJrJHGSy.js → Popup-D91ZiFWh.js} +1 -1
  48. package/dist/Popup.js +2 -2
  49. package/dist/{ProgressBar-Dmq9veqU.js → ProgressBar-DQGO2we8.js} +1 -1
  50. package/dist/ProgressBar.js +2 -2
  51. package/dist/{Radio-W5ck_IJI.js → Radio-BetZNoUQ.js} +1 -1
  52. package/dist/Radio.js +2 -2
  53. package/dist/{RadioGroup-De5x2YCO.js → RadioGroup-DzW5z_SD.js} +2 -2
  54. package/dist/RadioGroup.js +3 -3
  55. package/dist/{Range-NCdfDkeD.js → Range-9ijUzrty.js} +1 -1
  56. package/dist/Range.js +2 -2
  57. package/dist/{ScrollTop-DwcNIKmN.js → ScrollTop-uDL4K_C6.js} +3 -3
  58. package/dist/ScrollTop.js +5 -5
  59. package/dist/{Select-Bpicra9q.js → Select-ClGNTYfp.js} +7 -7
  60. package/dist/Select.d.ts +2 -2
  61. package/dist/Select.js +9 -9
  62. package/dist/{Spinner-BBiVZxFH.js → Spinner-B7ikVfUZ.js} +1 -1
  63. package/dist/Spinner.js +2 -2
  64. package/dist/{Tab-Ce9nrDok.js → Tab-CSHR71IX.js} +1 -1
  65. package/dist/Tab.js +2 -2
  66. package/dist/{TabGroup-C-cd4Wcx.js → TabGroup-D7YbKXm8.js} +3 -3
  67. package/dist/TabGroup.js +4 -4
  68. package/dist/{TabPanel-BW1ydVBT.js → TabPanel-D_RHF3lv.js} +1 -1
  69. package/dist/TabPanel.js +2 -2
  70. package/dist/{Table-DiYqIzBu.js → Table-CdosaNFb.js} +3 -3
  71. package/dist/Table.js +7 -7
  72. package/dist/{Tag-Ct8Hhv7W.js → Tag-BQBgkkAs.js} +1 -1
  73. package/dist/Tag.js +2 -2
  74. package/dist/{VisuallyHidden-CpYXyuC7.js → VisuallyHidden-CEBTA6hv.js} +1 -1
  75. package/dist/VisuallyHidden.js +2 -2
  76. package/dist/custom-elements.json +6445 -0
  77. package/dist/index.d.ts +2 -2
  78. package/dist/index.js +30 -30
  79. package/dist/leu-accordion.js +2 -2
  80. package/dist/leu-button-group.js +5 -5
  81. package/dist/leu-button.js +4 -4
  82. package/dist/leu-chart-wrapper.js +3 -3
  83. package/dist/leu-checkbox-group.js +4 -4
  84. package/dist/leu-checkbox.js +3 -3
  85. package/dist/leu-chip-group.js +3 -3
  86. package/dist/leu-chip-link.js +2 -2
  87. package/dist/leu-chip-removable.js +3 -3
  88. package/dist/leu-chip-selectable.js +2 -2
  89. package/dist/leu-dialog.js +3 -3
  90. package/dist/leu-dropdown.js +8 -8
  91. package/dist/leu-file-input.js +6 -6
  92. package/dist/leu-icon.js +2 -2
  93. package/dist/leu-input.js +3 -3
  94. package/dist/leu-menu-item.d.ts +1 -1
  95. package/dist/leu-menu-item.js +3 -3
  96. package/dist/leu-menu.d.ts +1 -1
  97. package/dist/leu-menu.js +4 -4
  98. package/dist/leu-message.js +3 -3
  99. package/dist/leu-pagination.js +6 -6
  100. package/dist/leu-placeholder.js +2 -2
  101. package/dist/leu-popup.js +2 -2
  102. package/dist/leu-progress-bar.js +2 -2
  103. package/dist/leu-radio-group.js +3 -3
  104. package/dist/leu-radio.js +2 -2
  105. package/dist/leu-range.js +2 -2
  106. package/dist/leu-scroll-top.js +5 -5
  107. package/dist/leu-select.js +9 -9
  108. package/dist/leu-spinner.js +2 -2
  109. package/dist/leu-tab-group.js +4 -4
  110. package/dist/leu-tab-panel.js +2 -2
  111. package/dist/leu-tab.js +2 -2
  112. package/dist/leu-table.js +7 -7
  113. package/dist/leu-tag.js +2 -2
  114. package/dist/leu-visually-hidden.js +2 -2
  115. package/dist/web-types.json +1 -1
  116. package/package.json +9 -4
  117. package/.editorconfig +0 -29
  118. package/.github/workflows/ci.yml +0 -81
  119. package/.github/workflows/deploy-github-pages.yaml +0 -34
  120. package/.github/workflows/publish.yml +0 -30
  121. package/.github/workflows/release-please.yml +0 -19
  122. package/.husky/commit-msg +0 -1
  123. package/.husky/pre-commit +0 -1
  124. package/.nvmrc +0 -1
  125. package/.prettierignore +0 -2
  126. package/.release-please-manifest.json +0 -3
  127. package/.storybook/main.ts +0 -34
  128. package/.storybook/manager-head.html +0 -1
  129. package/.storybook/manager.ts +0 -6
  130. package/.storybook/preview.ts +0 -96
  131. package/.storybook/static/fonts/Inter-Black.woff2 +0 -0
  132. package/.storybook/static/fonts/Inter-Regular.woff2 +0 -0
  133. package/.storybook/static/fonts.css +0 -11
  134. package/.storybook/static/global.css +0 -5
  135. package/.storybook/static/logo.svg +0 -19
  136. package/.storybook/theme.ts +0 -8
  137. package/CHANGELOG.md +0 -594
  138. package/CODE_OF_CONDUCT.md +0 -128
  139. package/CONTRIBUTING.md +0 -42
  140. package/commitlint.config.cjs +0 -1
  141. package/custom-elements-manifest.config.js +0 -46
  142. package/eslint.config.mjs +0 -79
  143. package/postcss.config.cjs +0 -16
  144. package/release-please-config.json +0 -9
  145. package/scripts/generate-component/generate.js +0 -167
  146. package/scripts/generate-component/templates/[Name].ts +0 -31
  147. package/scripts/generate-component/templates/[name].css +0 -6
  148. package/scripts/generate-component/templates/[namespace]-[name].ts +0 -11
  149. package/scripts/generate-component/templates/stories/[name].stories.ts +0 -26
  150. package/scripts/generate-component/templates/test/[name].test.ts +0 -23
  151. package/scripts/postcss-leu-font-styles.cjs +0 -154
  152. package/src/components/accordion/Accordion.ts +0 -108
  153. package/src/components/accordion/accordion.css +0 -150
  154. package/src/components/accordion/leu-accordion.ts +0 -11
  155. package/src/components/accordion/stories/accordion.stories.ts +0 -62
  156. package/src/components/accordion/test/accordion.test.ts +0 -118
  157. package/src/components/button/Button.ts +0 -286
  158. package/src/components/button/button.css +0 -317
  159. package/src/components/button/leu-button.ts +0 -11
  160. package/src/components/button/stories/button.stories.ts +0 -366
  161. package/src/components/button/test/button.test.ts +0 -417
  162. package/src/components/button-group/ButtonGroup.ts +0 -97
  163. package/src/components/button-group/button-group.css +0 -5
  164. package/src/components/button-group/leu-button-group.ts +0 -11
  165. package/src/components/button-group/stories/button-group.stories.ts +0 -54
  166. package/src/components/button-group/test/button-group.test.ts +0 -105
  167. package/src/components/chart-wrapper/ChartWrapper.ts +0 -78
  168. package/src/components/chart-wrapper/chart-wrapper.css +0 -87
  169. package/src/components/chart-wrapper/leu-chart-wrapper.ts +0 -11
  170. package/src/components/chart-wrapper/stories/chart-wrapper.stories.ts +0 -58
  171. package/src/components/chart-wrapper/test/chart-wrapper.test.ts +0 -77
  172. package/src/components/checkbox/Checkbox.ts +0 -129
  173. package/src/components/checkbox/CheckboxGroup.ts +0 -57
  174. package/src/components/checkbox/checkbox-group.css +0 -29
  175. package/src/components/checkbox/checkbox.css +0 -81
  176. package/src/components/checkbox/leu-checkbox-group.ts +0 -11
  177. package/src/components/checkbox/leu-checkbox.ts +0 -11
  178. package/src/components/checkbox/stories/checkbox-group.stories.ts +0 -59
  179. package/src/components/checkbox/stories/checkbox.stories.ts +0 -72
  180. package/src/components/checkbox/test/checkbox-group.test.ts +0 -109
  181. package/src/components/checkbox/test/checkbox.test.ts +0 -247
  182. package/src/components/chip/Chip.ts +0 -19
  183. package/src/components/chip/ChipGroup.ts +0 -122
  184. package/src/components/chip/ChipLink.ts +0 -24
  185. package/src/components/chip/ChipRemovable.ts +0 -45
  186. package/src/components/chip/ChipSelectable.ts +0 -80
  187. package/src/components/chip/chip-group.css +0 -15
  188. package/src/components/chip/chip.css +0 -139
  189. package/src/components/chip/exports.ts +0 -4
  190. package/src/components/chip/leu-chip-group.ts +0 -11
  191. package/src/components/chip/leu-chip-link.ts +0 -11
  192. package/src/components/chip/leu-chip-removable.ts +0 -11
  193. package/src/components/chip/leu-chip-selectable.ts +0 -11
  194. package/src/components/chip/stories/chip-group.stories.ts +0 -159
  195. package/src/components/chip/stories/chip-link.stories.ts +0 -45
  196. package/src/components/chip/stories/chip-removable.stories.ts +0 -42
  197. package/src/components/chip/stories/chip-selectable.stories.ts +0 -54
  198. package/src/components/chip/test/chip-group.test.ts +0 -171
  199. package/src/components/chip/test/chip-link.test.ts +0 -54
  200. package/src/components/chip/test/chip-removable.test.ts +0 -105
  201. package/src/components/chip/test/chip-selectable.test.ts +0 -101
  202. package/src/components/chip/test/chip.test.ts +0 -22
  203. package/src/components/dialog/Dialog.ts +0 -86
  204. package/src/components/dialog/dialog.css +0 -157
  205. package/src/components/dialog/leu-dialog.ts +0 -11
  206. package/src/components/dialog/stories/dialog.stories.ts +0 -142
  207. package/src/components/dialog/test/dialog.test.ts +0 -85
  208. package/src/components/dropdown/Dropdown.ts +0 -152
  209. package/src/components/dropdown/dropdown.css +0 -16
  210. package/src/components/dropdown/leu-dropdown.ts +0 -11
  211. package/src/components/dropdown/stories/dropdown.stories.ts +0 -58
  212. package/src/components/dropdown/test/dropdown.test.ts +0 -59
  213. package/src/components/file-input/FileInput.ts +0 -322
  214. package/src/components/file-input/file-input.css +0 -118
  215. package/src/components/file-input/leu-file-input.ts +0 -11
  216. package/src/components/file-input/stories/file-input.stories.ts +0 -45
  217. package/src/components/file-input/test/file-input.test.ts +0 -38
  218. package/src/components/icon/Icon.ts +0 -47
  219. package/src/components/icon/icon.css +0 -10
  220. package/src/components/icon/leu-icon.ts +0 -11
  221. package/src/components/icon/paths.ts +0 -219
  222. package/src/components/icon/stories/icon.stories.ts +0 -79
  223. package/src/components/icon/test/icon.test.ts +0 -50
  224. package/src/components/input/Input.ts +0 -469
  225. package/src/components/input/input.css +0 -238
  226. package/src/components/input/leu-input.ts +0 -11
  227. package/src/components/input/stories/input.stories.ts +0 -204
  228. package/src/components/input/test/input.test.ts +0 -603
  229. package/src/components/menu/Menu.ts +0 -149
  230. package/src/components/menu/MenuItem.ts +0 -168
  231. package/src/components/menu/leu-menu-item.ts +0 -11
  232. package/src/components/menu/leu-menu.ts +0 -11
  233. package/src/components/menu/menu-item.css +0 -77
  234. package/src/components/menu/menu.css +0 -19
  235. package/src/components/menu/stories/menu-item.stories.ts +0 -81
  236. package/src/components/menu/stories/menu.stories.ts +0 -54
  237. package/src/components/menu/test/menu-item.test.ts +0 -210
  238. package/src/components/menu/test/menu.test.ts +0 -125
  239. package/src/components/message/Message.ts +0 -118
  240. package/src/components/message/leu-message.ts +0 -11
  241. package/src/components/message/message.css +0 -163
  242. package/src/components/message/stories/message.mdx +0 -76
  243. package/src/components/message/stories/message.stories.ts +0 -149
  244. package/src/components/message/test/message.test.ts +0 -96
  245. package/src/components/pagination/Pagination.ts +0 -192
  246. package/src/components/pagination/leu-pagination.ts +0 -11
  247. package/src/components/pagination/pagination.css +0 -54
  248. package/src/components/pagination/stories/pagination.stories.ts +0 -115
  249. package/src/components/pagination/test/pagination.test.ts +0 -210
  250. package/src/components/placeholder/Placeholder.ts +0 -33
  251. package/src/components/placeholder/leu-placeholder.ts +0 -11
  252. package/src/components/placeholder/placeholder.css +0 -59
  253. package/src/components/placeholder/stories/placeholder.stories.ts +0 -34
  254. package/src/components/placeholder/test/placeholder.test.ts +0 -31
  255. package/src/components/popup/Popup.ts +0 -264
  256. package/src/components/popup/leu-popup.ts +0 -11
  257. package/src/components/popup/popup.css +0 -24
  258. package/src/components/popup/stories/popup.stories.ts +0 -117
  259. package/src/components/popup/test/popup.test.ts +0 -90
  260. package/src/components/progress-bar/ProgressBar.ts +0 -52
  261. package/src/components/progress-bar/leu-progress-bar.ts +0 -11
  262. package/src/components/progress-bar/progress-bar.css +0 -97
  263. package/src/components/progress-bar/stories/progress-bar.stories.ts +0 -39
  264. package/src/components/progress-bar/test/progress-bar.test.ts +0 -61
  265. package/src/components/radio/Radio.ts +0 -59
  266. package/src/components/radio/RadioGroup.ts +0 -181
  267. package/src/components/radio/leu-radio-group.ts +0 -11
  268. package/src/components/radio/leu-radio.ts +0 -11
  269. package/src/components/radio/radio-group.css +0 -29
  270. package/src/components/radio/radio.css +0 -76
  271. package/src/components/radio/stories/radio-group.stories.ts +0 -54
  272. package/src/components/radio/stories/radio.stories.ts +0 -55
  273. package/src/components/radio/test/radio-group.test.ts +0 -83
  274. package/src/components/radio/test/radio.test.ts +0 -119
  275. package/src/components/range/Range.ts +0 -400
  276. package/src/components/range/leu-range.ts +0 -11
  277. package/src/components/range/range.css +0 -227
  278. package/src/components/range/stories/range.stories.ts +0 -185
  279. package/src/components/range/test/range.test.ts +0 -228
  280. package/src/components/scroll-top/ScrollTop.ts +0 -91
  281. package/src/components/scroll-top/leu-scroll-top.ts +0 -11
  282. package/src/components/scroll-top/scroll-top.css +0 -50
  283. package/src/components/scroll-top/stories/scroll-top.stories.ts +0 -217
  284. package/src/components/scroll-top/test/scroll-top.test.ts +0 -22
  285. package/src/components/select/Select.ts +0 -570
  286. package/src/components/select/leu-select.ts +0 -11
  287. package/src/components/select/select.css +0 -222
  288. package/src/components/select/stories/select.stories.ts +0 -173
  289. package/src/components/select/test/fixtures.ts +0 -162
  290. package/src/components/select/test/select.test.ts +0 -937
  291. package/src/components/spinner/Spinner.ts +0 -31
  292. package/src/components/spinner/leu-spinner.ts +0 -11
  293. package/src/components/spinner/spinner.css +0 -20
  294. package/src/components/spinner/stories/spinner.stories.ts +0 -29
  295. package/src/components/spinner/test/spinner.test.ts +0 -30
  296. package/src/components/tab/Tab.ts +0 -72
  297. package/src/components/tab/TabGroup.ts +0 -267
  298. package/src/components/tab/TabPanel.ts +0 -59
  299. package/src/components/tab/leu-tab-group.ts +0 -11
  300. package/src/components/tab/leu-tab-panel.ts +0 -11
  301. package/src/components/tab/leu-tab.ts +0 -11
  302. package/src/components/tab/stories/tab.stories.ts +0 -97
  303. package/src/components/tab/tab-group.css +0 -63
  304. package/src/components/tab/tab-panel.css +0 -10
  305. package/src/components/tab/tab.css +0 -54
  306. package/src/components/tab/test/tab-group.test.ts +0 -426
  307. package/src/components/tab/test/tab-panel.test.ts +0 -102
  308. package/src/components/tab/test/tab.test.ts +0 -139
  309. package/src/components/table/Table.ts +0 -253
  310. package/src/components/table/leu-table.ts +0 -11
  311. package/src/components/table/stories/table.stories.ts +0 -131
  312. package/src/components/table/table.css +0 -112
  313. package/src/components/table/test/table.test.ts +0 -37
  314. package/src/components/tag/Tag.ts +0 -28
  315. package/src/components/tag/leu-tag.ts +0 -11
  316. package/src/components/tag/stories/tag.stories.ts +0 -107
  317. package/src/components/tag/tag.css +0 -42
  318. package/src/components/tag/test/tag.test.ts +0 -28
  319. package/src/components/visually-hidden/VisuallyHidden.ts +0 -16
  320. package/src/components/visually-hidden/leu-visually-hidden.ts +0 -11
  321. package/src/components/visually-hidden/stories/visually-hidden.stories.ts +0 -22
  322. package/src/components/visually-hidden/test/visually-hidden.test.ts +0 -34
  323. package/src/components/visually-hidden/visually-hidden.css +0 -10
  324. package/src/docs/contributing.mdx +0 -154
  325. package/src/docs/installation.mdx +0 -35
  326. package/src/docs/theme.mdx +0 -400
  327. package/src/docs/usage.mdx +0 -73
  328. package/src/global.d.ts +0 -11
  329. package/src/index.ts +0 -29
  330. package/src/lib/LeuElement.ts +0 -43
  331. package/src/lib/a11y.ts +0 -26
  332. package/src/lib/hasSlotController.ts +0 -74
  333. package/src/lib/mixins/FormAssociatedMixin.ts +0 -115
  334. package/src/lib/styleMap.ts +0 -139
  335. package/src/lib/utils.ts +0 -45
  336. package/src/styles/common-styles.css +0 -14
  337. package/src/styles/custom-media.css +0 -6
  338. package/src/styles/font-definitions.json +0 -210
  339. package/src/styles/style.stories.ts +0 -64
  340. package/src/styles/theme.css +0 -90
  341. package/stat_zh.png +0 -0
  342. package/stylelint.config.mjs +0 -23
  343. package/tsconfig.build.json +0 -24
  344. package/tsconfig.json +0 -14
  345. package/tsdown.config.ts +0 -35
  346. package/web-test-runner.config.mjs +0 -102
@@ -1,322 +0,0 @@
1
- import { html, nothing, PropertyValues } from "lit"
2
- import { property, query, state } from "lit/decorators.js"
3
- import { ifDefined } from "lit/directives/if-defined.js"
4
- import { classMap } from "lit/directives/class-map.js"
5
-
6
- import { LeuElement } from "../../lib/LeuElement.js"
7
-
8
- import styles from "./file-input.css?inline"
9
- import { LeuButton } from "../button/Button.js"
10
- import { LeuIcon } from "../icon/Icon.js"
11
- import { LeuVisuallyHidden } from "../visually-hidden/VisuallyHidden.js"
12
- import { FormAssociatedMixin } from "../../lib/mixins/FormAssociatedMixin.js"
13
-
14
- /**
15
- * @todo Pluralize text when multiple files are allowed
16
- * @todo Hide dropzone when not multiple and already filled
17
- */
18
-
19
- /**
20
- * @tagname leu-file-input
21
- */
22
- export class LeuFileInput extends FormAssociatedMixin(LeuElement) {
23
- static dependencies = {
24
- "leu-icon": LeuIcon,
25
- "leu-button": LeuButton,
26
- "leu-visually-hidden": LeuVisuallyHidden,
27
- }
28
-
29
- static styles = [LeuElement.styles, styles]
30
-
31
- static shadowRootOptions = {
32
- ...LeuElement.shadowRootOptions,
33
- delegatesFocus: true,
34
- }
35
-
36
- static formAssociated = true
37
-
38
- protected internals: ElementInternals
39
-
40
- @property({ type: String })
41
- label: string = ""
42
-
43
- /** A list of acceptable file types. Must be a comma-separated list of [unique file type specifiers](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers). */
44
- @property({ type: String })
45
- accept: string = ""
46
-
47
- /** Whether the file input is disabled. */
48
- @property({ type: Boolean, reflect: true })
49
- disabled: boolean = false
50
-
51
- /** Whether the file input allows multiple files. */
52
- @property({ type: Boolean, reflect: true })
53
- multiple: boolean = false
54
-
55
- /** Whether the file input is required. */
56
- @property({ type: Boolean, reflect: true })
57
- required: boolean = false
58
-
59
- /** The variant of the file list item. `filled` renders a gray background. */
60
- @property({ type: String, reflect: true })
61
- variant: "filled" | "transparent" = "filled"
62
-
63
- @state()
64
- public files: File[] = []
65
-
66
- @state()
67
- private isDragging: boolean = false
68
-
69
- @query('input[type="file"]')
70
- input: HTMLInputElement
71
-
72
- updated(changedProperties: PropertyValues<this>) {
73
- if (
74
- changedProperties.has("files") ||
75
- changedProperties.has("disabled") ||
76
- changedProperties.has("multiple")
77
- ) {
78
- this.setFormValue()
79
- }
80
- }
81
-
82
- protected handleInput() {
83
- // Append selected files
84
- if (this.input.files) {
85
- const acceptableFiles = [...this.input.files].filter((file) =>
86
- this.isAcceptedFile(file),
87
- )
88
-
89
- this.files = this.multiple
90
- ? this.files.concat(acceptableFiles)
91
- : acceptableFiles.slice(0, 1)
92
- }
93
- }
94
-
95
- private handleChange(event: Event & { target: HTMLInputElement }) {
96
- const customEvent = new CustomEvent(event.type, event)
97
- this.dispatchEvent(customEvent)
98
- }
99
-
100
- public formResetCallback() {
101
- this.files = []
102
- this.input.value = ""
103
- }
104
-
105
- protected setFormValue() {
106
- const formData = new FormData()
107
-
108
- const files = this.multiple ? this.files : this.files.slice(0, 1)
109
-
110
- files.forEach((file) => {
111
- formData.append(this.name, file)
112
- })
113
-
114
- this.internals.setFormValue(formData)
115
-
116
- if (this.required && files.length < 1) {
117
- // @todo i18n and/or custom validation message
118
- this.internals.setValidity(
119
- { valueMissing: true },
120
- "Bitte wählen Sie eine Datei.",
121
- this.input,
122
- )
123
- } else {
124
- this.internals.setValidity({})
125
- }
126
- }
127
-
128
- protected removeFile(fileToRemove: File) {
129
- this.files = this.files.filter((file) => file !== fileToRemove)
130
- this.dispatchChangeAndInputEvents()
131
- }
132
-
133
- protected dispatchChangeAndInputEvents() {
134
- this.dispatchEvent(
135
- new CustomEvent("input", {
136
- composed: true,
137
- bubbles: true,
138
- }),
139
- )
140
- this.dispatchEvent(
141
- new CustomEvent("change", {
142
- composed: true,
143
- bubbles: true,
144
- }),
145
- )
146
- }
147
-
148
- /**
149
- * This implementation Uses base-10 (decimal) units:
150
- * 1 KB = 1_000 bytes
151
- * 1 MB = 1_000_000 bytes
152
- * 1 GB = 1_000_000_000 bytes
153
- *
154
- * To switch to base-2 (binary), use the following implementation:
155
- * // const KB = 1024
156
- * // const MB = 1024 * 1024
157
- * // const GB = 1024 * 1024 * 1024
158
- */
159
- protected static formatFileSize(size: number) {
160
- const KB = 1e3
161
- const MB = 1e6
162
- const GB = 1e9
163
-
164
- if (size >= GB) {
165
- return html`${(size / GB).toFixed(1)}&nbsp;GB`
166
- }
167
-
168
- if (size >= MB) {
169
- return html`${(size / MB).toFixed(1)}&nbsp;MB`
170
- }
171
-
172
- if (size >= KB) {
173
- return html`${(size / KB).toFixed(1)}&nbsp;KB`
174
- }
175
-
176
- return html`${size}&nbsp;bytes`
177
- }
178
-
179
- protected handleDragEnter = (event: DragEvent) => {
180
- if (this.disabled) return
181
-
182
- event.preventDefault()
183
- event.stopPropagation()
184
- this.isDragging = [...event.dataTransfer.items].some(
185
- (item) => item.kind === "file",
186
- )
187
- }
188
-
189
- protected handleDragOver = (event: DragEvent) => {
190
- if (this.disabled) return
191
-
192
- event.preventDefault()
193
- event.stopPropagation()
194
- }
195
-
196
- protected handleDragLeave = (event: DragEvent) => {
197
- if (this.disabled) return
198
-
199
- event.preventDefault()
200
- event.stopPropagation()
201
- this.isDragging = false
202
- }
203
-
204
- protected handleDrop = (event: DragEvent) => {
205
- this.isDragging = false
206
-
207
- if (this.disabled) return
208
-
209
- event.preventDefault()
210
- event.stopPropagation()
211
-
212
- const dt = event.dataTransfer
213
- const files = dt.files
214
- const acceptedFiles = [...files].filter((file) => this.isAcceptedFile(file))
215
-
216
- if (acceptedFiles.length < 1) {
217
- return
218
- }
219
-
220
- this.files = this.multiple
221
- ? this.files.concat(acceptedFiles)
222
- : acceptedFiles.slice(0, 1)
223
-
224
- this.dispatchChangeAndInputEvents()
225
- }
226
-
227
- isAcceptedFile(file: File): boolean {
228
- const acceptedTypes = this.accept.split(",").map((type) => type.trim())
229
- const mimeType = file.type
230
-
231
- for (const acceptedType of acceptedTypes) {
232
- // Handle file extensions (e.g. .jpg, .png)
233
- if (acceptedType.startsWith(".")) {
234
- const name = file.name.toLowerCase()
235
- const extension = acceptedType.toLowerCase()
236
-
237
- if (name.endsWith(extension)) {
238
- return true
239
- }
240
- // Handle wildcard types (e.g. image/*)
241
- } else if (/^\w+\/\*$/.test(acceptedType)) {
242
- if (mimeType.split("/")[0] === acceptedType.split("/")[0]) {
243
- return true
244
- }
245
- }
246
-
247
- if (mimeType === acceptedType) {
248
- return true
249
- }
250
- }
251
-
252
- return false
253
- }
254
-
255
- render() {
256
- const dropzoneClasses = {
257
- dropzone: true,
258
- "dropzone--dragging": this.isDragging,
259
- }
260
-
261
- return html`
262
- <div class="container">
263
- <label class="label" for="input">${this.label}</label>
264
- <leu-visually-hidden>
265
- <input
266
- id="input"
267
- type="file"
268
- ?multiple=${this.multiple}
269
- ?disabled=${this.disabled}
270
- ?required=${this.required}
271
- accept=${ifDefined(this.accept)}
272
- @input=${this.handleInput}
273
- @change=${this.handleChange}
274
- />
275
- </leu-visually-hidden>
276
- <div
277
- class=${classMap(dropzoneClasses)}
278
- @dragenter=${this.handleDragEnter}
279
- @dragover=${this.handleDragOver}
280
- @dragleave=${this.handleDragLeave}
281
- @drop=${this.handleDrop}
282
- >
283
- <slot class="dropzone__text"
284
- ><p>Zum Hochladen Dateien ziehen und hier ablegen.</p></slot
285
- >
286
- <leu-button
287
- variant="secondary"
288
- ?disabled=${this.disabled}
289
- @click=${() => this.input.click()}
290
- >
291
- Datei auswählen
292
- <leu-icon name="upload" slot="after"></leu-icon>
293
- </leu-button>
294
- </div>
295
- ${this.files.length > 0
296
- ? html`<ul class="file-list">
297
- ${this.files.map(
298
- (file) =>
299
- html`<li class="file">
300
- <strong class="file__name">${file.name}</strong>
301
- <p class="file__size">
302
- <span class="file__size-label">Grösse:</span>
303
- ${LeuFileInput.formatFileSize(file.size)}
304
- </p>
305
- <leu-button
306
- round
307
- class="file__button"
308
- label="Datei entfernen"
309
- size="small"
310
- variant="secondary"
311
- ?disabled=${this.disabled}
312
- @click=${() => this.removeFile(file)}
313
- ><leu-icon name="delete"></leu-icon
314
- ></leu-button>
315
- </li>`,
316
- )}
317
- </ul>`
318
- : nothing}
319
- </div>
320
- `
321
- }
322
- }
@@ -1,118 +0,0 @@
1
- @import url("../../styles/custom-media.css");
2
-
3
- :host {
4
- --file-input-font-regular: var(--leu-font-family-regular);
5
- --file-input-font-black: var(--leu-font-family-black);
6
-
7
- font-family: var(--file-input-font-regular);
8
- }
9
-
10
- .label {
11
- display: block;
12
- margin-bottom: 0.5rem;
13
- font: var(--leu-t-curve-regular-black-font);
14
- }
15
-
16
- :host([required]) .label::after {
17
- content: "*";
18
- }
19
-
20
- .dropzone {
21
- display: flex;
22
- flex-direction: column;
23
- align-items: center;
24
- text-align: center;
25
-
26
- border: 2px dashed var(--leu-color-black-20);
27
- border-radius: 0.25rem;
28
-
29
- padding: 2rem 1.5rem;
30
-
31
- @media (--viewport-regular) {
32
- padding: 2.5rem 2rem;
33
- }
34
-
35
- @media (--viewport-xlarge) {
36
- padding: 3.5rem 2.5rem;
37
- }
38
- }
39
-
40
- .dropzone--dragging {
41
- border-color: var(--leu-color-black-60);
42
- background-color: var(--leu-color-black-transp-5);
43
- cursor: copy;
44
- }
45
-
46
- .dropzone__text {
47
- font: var(--leu-t-curve-small-regular-font);
48
- color: var(--leu-color-black-60);
49
-
50
- margin-bottom: 0.75rem;
51
-
52
- @media (--viewport-small) {
53
- margin-bottom: 2rem;
54
- }
55
-
56
- @media (--viewport-regular) {
57
- margin-bottom: 1.25rem;
58
- }
59
-
60
- @media (--viewport-xlarge) {
61
- margin-bottom: 1.5rem;
62
- }
63
- }
64
-
65
- .file-list {
66
- list-style: none;
67
- padding: 0;
68
-
69
- display: flex;
70
- flex-direction: column;
71
- gap: 0.125rem;
72
- }
73
-
74
- .file {
75
- display: grid;
76
- grid-template-columns: minmax(0, 1fr) min-content;
77
- gap: 0.25rem 0.5rem;
78
-
79
- place-items: start;
80
-
81
- background-color: var(--leu-color-black-10);
82
- padding: 0.75rem 1.25rem;
83
-
84
- @media (--viewport-regular) {
85
- column-gap: 0.75rem;
86
- }
87
-
88
- @media (--viewport-large) {
89
- column-gap: 1rem;
90
- padding: 1.5rem 1rem;
91
- }
92
- }
93
-
94
- .file__name {
95
- grid-column: 1 / 2;
96
- font: var(--leu-t-regular-black-font);
97
- text-overflow: ellipsis;
98
- overflow: hidden;
99
- max-width: 100%;
100
- }
101
-
102
- .file__size {
103
- grid-column: 1 / 2;
104
- display: flex;
105
- gap: 0.25rem;
106
- margin: 0;
107
- font: var(--leu-t-tiny-regular-font);
108
- }
109
-
110
- .file__size-label {
111
- color: var(--leu-color-black-60);
112
- }
113
-
114
- .file__button {
115
- grid-column: 2 / 3;
116
- grid-row: 1 / 3;
117
- align-self: center;
118
- }
@@ -1,11 +0,0 @@
1
- import { LeuFileInput } from "./FileInput.js"
2
-
3
- export { LeuFileInput }
4
-
5
- LeuFileInput.define("leu-file-input")
6
-
7
- declare global {
8
- interface HTMLElementTagNameMap {
9
- "leu-file-input": LeuFileInput
10
- }
11
- }
@@ -1,45 +0,0 @@
1
- import { Meta, StoryObj } from "@storybook/web-components-vite"
2
- import { action } from "storybook/actions"
3
- import { html } from "lit"
4
- import { ifDefined } from "lit/directives/if-defined.js"
5
-
6
- import "../leu-file-input.js"
7
- import { LeuFileInput } from "../FileInput.js"
8
-
9
- type StoryArgs = LeuFileInput
10
- type Story = StoryObj<StoryArgs>
11
-
12
- export default {
13
- title: "Components/FileInput",
14
- component: "leu-file-input",
15
- args: {
16
- oninput: action("input"),
17
- onchange: action("change"),
18
- },
19
- } satisfies Meta<StoryArgs>
20
-
21
- const Template: Story = {
22
- render: (args: StoryArgs) => html`
23
- <leu-file-input
24
- name="file"
25
- label=${ifDefined(args.label)}
26
- accept=${ifDefined(args.accept)}
27
- ?disabled=${args.disabled}
28
- ?multiple=${args.multiple}
29
- ?required=${args.required}
30
- @input=${args.oninput}
31
- @change=${args.onchange}
32
- ></leu-file-input>
33
- `,
34
- }
35
-
36
- export const Regular = {
37
- ...Template,
38
- args: {
39
- accept: "image/*",
40
- disabled: false,
41
- multiple: false,
42
- label: "Dokumente hochladen",
43
- // Add default args here
44
- },
45
- }
@@ -1,38 +0,0 @@
1
- import { html } from "lit"
2
- import { fixture, expect } from "@open-wc/testing"
3
-
4
- import "../leu-file-input.js"
5
- import { LeuFileInput } from "../FileInput.js"
6
-
7
- async function defaultFixture() {
8
- return fixture<LeuFileInput>(
9
- html`<leu-file-input label="File upload"></leu-file-input>`,
10
- )
11
- }
12
-
13
- describe("LeuFileInput", () => {
14
- it("is a defined element", async () => {
15
- const el = customElements.get("leu-file-input")
16
-
17
- expect(el).not.to.be.undefined
18
- })
19
-
20
- it("passes the a11y audit", async () => {
21
- const el = await defaultFixture()
22
-
23
- await expect(el).shadowDom.to.be.accessible()
24
- })
25
-
26
- it("is not valid when required and no file is selected", async () => {
27
- const form = await fixture<HTMLFormElement>(html`
28
- <form>
29
- <leu-file-input label="File upload" required></leu-file-input>
30
- </form>
31
- `)
32
- const fileInput = form.querySelector<LeuFileInput>("leu-file-input")
33
-
34
- expect(fileInput.validity.valid).to.be.false
35
- expect(fileInput.validity.valueMissing).to.be.true
36
- expect(form.checkValidity()).to.be.false
37
- })
38
- })
@@ -1,47 +0,0 @@
1
- import { html, svg } from "lit"
2
- import { property } from "lit/decorators.js"
3
-
4
- import { LeuElement } from "../../lib/LeuElement.js"
5
-
6
- import styles from "./icon.css?inline"
7
- import { paths, IconPathName } from "./paths.js"
8
-
9
- /**
10
- * A component to render all defined zhWeb icons.
11
- * The `fill` of the icon is set to `currentColor` and
12
- * can be overriden by setting the css `color` property.
13
- * If the icon name is not found, a placeholder will be displayed.
14
- *
15
- * @tagname leu-icon
16
- * @cssprop --leu-icon-size - The size of the icon.
17
- */
18
- export class LeuIcon extends LeuElement {
19
- static styles = [LeuElement.styles, styles]
20
-
21
- /**
22
- * The name of the icon to display.
23
- */
24
- @property({ type: String, reflect: true })
25
- name: IconPathName | "" = ""
26
-
27
- render() {
28
- if (!paths[this.name]) {
29
- return html`<div class="placeholder"></div>`
30
- }
31
-
32
- const iconPath = paths[this.name]
33
-
34
- return html`
35
- <svg
36
- width="24"
37
- height="24"
38
- fill="currentColor"
39
- viewBox="0 0 24 24"
40
- fill-rule="evenodd"
41
- role="presentation"
42
- >
43
- ${svg`<path d=${iconPath} />`}
44
- </svg>
45
- `
46
- }
47
- }
@@ -1,10 +0,0 @@
1
- :host {
2
- display: contents;
3
- }
4
-
5
- svg,
6
- .placeholder {
7
- display: block;
8
- width: var(--leu-icon-size, 1.5rem);
9
- height: var(--leu-icon-size, 1.5rem);
10
- }
@@ -1,11 +0,0 @@
1
- import { LeuIcon } from "./Icon.js"
2
-
3
- export { LeuIcon }
4
-
5
- LeuIcon.define("leu-icon")
6
-
7
- declare global {
8
- interface HTMLElementTagNameMap {
9
- "leu-icon": LeuIcon
10
- }
11
- }