@statistikzh/leu 0.28.1 → 0.28.3

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 (351) hide show
  1. package/dist/{Accordion-CwkI7sfx.js → Accordion-EwJ1WHFd.js} +1 -1
  2. package/dist/Accordion.js +2 -2
  3. package/dist/{Button-DcuvEVkC.d.ts → Button-BywuwtT2.d.ts} +0 -1
  4. package/dist/{Button-D1aYnunQ.js → Button-q4GeKj_3.js} +3 -4
  5. package/dist/Button.d.ts +1 -1
  6. package/dist/Button.js +4 -4
  7. package/dist/{ButtonGroup-CqThYjzX.js → ButtonGroup-BeU3Prei.js} +2 -2
  8. package/dist/ButtonGroup.js +5 -5
  9. package/dist/{ChartWrapper-BjVT4x-H.js → ChartWrapper-Bdb0_n2z.js} +2 -2
  10. package/dist/ChartWrapper.js +3 -3
  11. package/dist/{Checkbox-HxYqp2w4.js → Checkbox-BC0gAuaH.js} +2 -2
  12. package/dist/Checkbox.js +3 -3
  13. package/dist/{CheckboxGroup-DYws2rwt.js → CheckboxGroup-CiOgcwmo.js} +2 -2
  14. package/dist/CheckboxGroup.js +4 -4
  15. package/dist/{Chip-gKxD6IaZ.js → Chip-CYlPzmTG.js} +1 -1
  16. package/dist/Chip.js +2 -2
  17. package/dist/{ChipGroup-ZvBzX_wd.js → ChipGroup-3IMW_Mp7.js} +1 -1
  18. package/dist/ChipGroup.js +3 -3
  19. package/dist/ChipLink.js +2 -2
  20. package/dist/ChipRemovable.js +3 -3
  21. package/dist/ChipSelectable.js +2 -2
  22. package/dist/{Dialog-BYpzTprV.js → Dialog-DCl5qSXY.js} +3 -4
  23. package/dist/Dialog.js +3 -3
  24. package/dist/{Dropdown-C4CgE4E-.js → Dropdown-COmpmOev.js} +5 -5
  25. package/dist/Dropdown.d.ts +1 -1
  26. package/dist/Dropdown.js +8 -8
  27. package/dist/{FileInput-nsnSQCaU.js → FileInput-DXjoqKB4.js} +4 -4
  28. package/dist/FileInput.d.ts +1 -1
  29. package/dist/FileInput.js +6 -6
  30. package/dist/{Icon-D8HTPEFH.js → Icon-Bmk7lLWY.js} +1 -1
  31. package/dist/Icon.js +2 -2
  32. package/dist/{Input-OrILqlax.js → Input-B9FwAPKO.js} +2 -2
  33. package/dist/Input.js +3 -3
  34. package/dist/{LeuElement-C_lcHzQI.js → LeuElement-CQJQi8TB.js} +1 -1
  35. package/dist/{Menu-CFLCnI34.js → Menu-bWCAn0rT.js} +2 -2
  36. package/dist/Menu.js +4 -4
  37. package/dist/{MenuItem-ICjLCGim.js → MenuItem-CzCFZi8o.js} +2 -2
  38. package/dist/MenuItem.js +3 -3
  39. package/dist/{Message-Dw5D_0i1.js → Message-DMaM9ukF.js} +2 -2
  40. package/dist/Message.js +3 -3
  41. package/dist/{Pagination-D1tP5FrM.js → Pagination-870u3UgQ.js} +4 -4
  42. package/dist/{Pagination-9eZ8WMvR.d.ts → Pagination-B-mTHZiw.d.ts} +1 -1
  43. package/dist/Pagination.d.ts +1 -1
  44. package/dist/Pagination.js +6 -6
  45. package/dist/{Placeholder-CnGzCZ5-.js → Placeholder-DvvzGB1p.js} +1 -1
  46. package/dist/Placeholder.js +2 -2
  47. package/dist/{Popup-BiN_tZDN.js → Popup-BpG_7twr.js} +1 -1
  48. package/dist/Popup.js +2 -2
  49. package/dist/{ProgressBar-BfJo_KyU.js → ProgressBar-BkskTLWK.js} +1 -1
  50. package/dist/ProgressBar.js +2 -2
  51. package/dist/{Radio-CV7vuQUj.js → Radio-BS7UUhR3.js} +1 -1
  52. package/dist/Radio.js +2 -2
  53. package/dist/{RadioGroup-C3XWSScc.js → RadioGroup-Cpo9kAjB.js} +2 -2
  54. package/dist/RadioGroup.js +3 -3
  55. package/dist/{Range-C8RVrIM9.js → Range-Dh0p5UWA.js} +1 -1
  56. package/dist/Range.js +2 -2
  57. package/dist/{ScrollTop-B_TJ_k4m.js → ScrollTop-CtPidICZ.js} +3 -3
  58. package/dist/ScrollTop.d.ts +1 -1
  59. package/dist/ScrollTop.js +5 -5
  60. package/dist/{Select-CbPTrL3G.js → Select-W1KqDOgx.js} +7 -7
  61. package/dist/Select.d.ts +1 -1
  62. package/dist/Select.js +9 -9
  63. package/dist/{Spinner-ChKJQJTN.js → Spinner-CmAYIFws.js} +1 -1
  64. package/dist/Spinner.js +2 -2
  65. package/dist/{Tab-BJbzY1xd.js → Tab-7Cww5fSx.js} +1 -1
  66. package/dist/Tab.js +2 -2
  67. package/dist/{TabGroup-BIaCHrKR.js → TabGroup-tURfCrlw.js} +3 -3
  68. package/dist/TabGroup.js +4 -4
  69. package/dist/{TabPanel-CTyw410b.js → TabPanel-DIZcmcMV.js} +1 -1
  70. package/dist/TabPanel.js +2 -2
  71. package/dist/{Table-D3QmePJd.js → Table-BVYjYXP9.js} +3 -3
  72. package/dist/Table.d.ts +1 -1
  73. package/dist/Table.js +7 -7
  74. package/dist/{Tag-nUnWtHYy.js → Tag-x0KmEDEa.js} +1 -1
  75. package/dist/Tag.js +2 -2
  76. package/dist/{VisuallyHidden-DF2q9pTa.js → VisuallyHidden-CXRfGsaZ.js} +1 -1
  77. package/dist/VisuallyHidden.js +2 -2
  78. package/dist/custom-elements.json +6445 -0
  79. package/dist/index.d.ts +2 -2
  80. package/dist/index.js +30 -30
  81. package/dist/leu-accordion.js +2 -2
  82. package/dist/leu-button-group.js +5 -5
  83. package/dist/leu-button.d.ts +1 -1
  84. package/dist/leu-button.js +4 -4
  85. package/dist/leu-chart-wrapper.js +3 -3
  86. package/dist/leu-checkbox-group.js +4 -4
  87. package/dist/leu-checkbox.js +3 -3
  88. package/dist/leu-chip-group.js +3 -3
  89. package/dist/leu-chip-link.js +2 -2
  90. package/dist/leu-chip-removable.js +3 -3
  91. package/dist/leu-chip-selectable.js +2 -2
  92. package/dist/leu-dialog.js +3 -3
  93. package/dist/leu-dropdown.js +8 -8
  94. package/dist/leu-file-input.js +6 -6
  95. package/dist/leu-icon.js +2 -2
  96. package/dist/leu-input.js +3 -3
  97. package/dist/leu-menu-item.js +3 -3
  98. package/dist/leu-menu.js +4 -4
  99. package/dist/leu-message.js +3 -3
  100. package/dist/leu-pagination.d.ts +1 -1
  101. package/dist/leu-pagination.js +6 -6
  102. package/dist/leu-placeholder.js +2 -2
  103. package/dist/leu-popup.js +2 -2
  104. package/dist/leu-progress-bar.js +2 -2
  105. package/dist/leu-radio-group.js +3 -3
  106. package/dist/leu-radio.js +2 -2
  107. package/dist/leu-range.js +2 -2
  108. package/dist/leu-scroll-top.js +5 -5
  109. package/dist/leu-select.js +9 -9
  110. package/dist/leu-spinner.js +2 -2
  111. package/dist/leu-tab-group.js +4 -4
  112. package/dist/leu-tab-panel.js +2 -2
  113. package/dist/leu-tab.js +2 -2
  114. package/dist/leu-table.js +7 -7
  115. package/dist/leu-tag.js +2 -2
  116. package/dist/leu-visually-hidden.js +2 -2
  117. package/dist/vscode.html-custom-data.json +11 -11
  118. package/dist/vue/index.d.ts +20 -20
  119. package/dist/web-types.json +28 -28
  120. package/package.json +4 -1
  121. package/.editorconfig +0 -29
  122. package/.github/workflows/ci.yml +0 -81
  123. package/.github/workflows/deploy-github-pages.yaml +0 -34
  124. package/.github/workflows/publish.yml +0 -28
  125. package/.github/workflows/release-please.yml +0 -19
  126. package/.husky/commit-msg +0 -1
  127. package/.husky/pre-commit +0 -1
  128. package/.nvmrc +0 -1
  129. package/.prettierignore +0 -2
  130. package/.release-please-manifest.json +0 -3
  131. package/.storybook/main.ts +0 -34
  132. package/.storybook/manager-head.html +0 -1
  133. package/.storybook/manager.ts +0 -6
  134. package/.storybook/preview.ts +0 -96
  135. package/.storybook/static/fonts/Inter-Black.woff2 +0 -0
  136. package/.storybook/static/fonts/Inter-Regular.woff2 +0 -0
  137. package/.storybook/static/fonts.css +0 -11
  138. package/.storybook/static/global.css +0 -5
  139. package/.storybook/static/logo.svg +0 -19
  140. package/.storybook/theme.ts +0 -8
  141. package/AGENTS.md +0 -162
  142. package/CHANGELOG.md +0 -601
  143. package/CODE_OF_CONDUCT.md +0 -128
  144. package/CONTRIBUTING.md +0 -42
  145. package/commitlint.config.cjs +0 -1
  146. package/custom-elements-manifest.config.js +0 -46
  147. package/eslint.config.mjs +0 -79
  148. package/postcss.config.cjs +0 -16
  149. package/release-please-config.json +0 -9
  150. package/scripts/generate-component/generate.js +0 -167
  151. package/scripts/generate-component/templates/[Name].ts +0 -31
  152. package/scripts/generate-component/templates/[name].css +0 -6
  153. package/scripts/generate-component/templates/[namespace]-[name].ts +0 -11
  154. package/scripts/generate-component/templates/stories/[name].stories.ts +0 -26
  155. package/scripts/generate-component/templates/test/[name].test.ts +0 -23
  156. package/scripts/postcss-leu-font-styles.cjs +0 -154
  157. package/src/components/accordion/Accordion.ts +0 -108
  158. package/src/components/accordion/accordion.css +0 -150
  159. package/src/components/accordion/leu-accordion.ts +0 -11
  160. package/src/components/accordion/stories/accordion.stories.ts +0 -62
  161. package/src/components/accordion/test/accordion.test.ts +0 -118
  162. package/src/components/button/Button.ts +0 -286
  163. package/src/components/button/button.css +0 -317
  164. package/src/components/button/leu-button.ts +0 -11
  165. package/src/components/button/stories/button.stories.ts +0 -366
  166. package/src/components/button/test/button.test.ts +0 -417
  167. package/src/components/button-group/ButtonGroup.ts +0 -97
  168. package/src/components/button-group/button-group.css +0 -5
  169. package/src/components/button-group/leu-button-group.ts +0 -11
  170. package/src/components/button-group/stories/button-group.stories.ts +0 -54
  171. package/src/components/button-group/test/button-group.test.ts +0 -105
  172. package/src/components/chart-wrapper/ChartWrapper.ts +0 -78
  173. package/src/components/chart-wrapper/chart-wrapper.css +0 -87
  174. package/src/components/chart-wrapper/leu-chart-wrapper.ts +0 -11
  175. package/src/components/chart-wrapper/stories/chart-wrapper.stories.ts +0 -58
  176. package/src/components/chart-wrapper/test/chart-wrapper.test.ts +0 -77
  177. package/src/components/checkbox/Checkbox.ts +0 -129
  178. package/src/components/checkbox/CheckboxGroup.ts +0 -57
  179. package/src/components/checkbox/checkbox-group.css +0 -29
  180. package/src/components/checkbox/checkbox.css +0 -81
  181. package/src/components/checkbox/leu-checkbox-group.ts +0 -11
  182. package/src/components/checkbox/leu-checkbox.ts +0 -11
  183. package/src/components/checkbox/stories/checkbox-group.stories.ts +0 -59
  184. package/src/components/checkbox/stories/checkbox.stories.ts +0 -72
  185. package/src/components/checkbox/test/checkbox-group.test.ts +0 -109
  186. package/src/components/checkbox/test/checkbox.test.ts +0 -247
  187. package/src/components/chip/Chip.ts +0 -19
  188. package/src/components/chip/ChipGroup.ts +0 -122
  189. package/src/components/chip/ChipLink.ts +0 -24
  190. package/src/components/chip/ChipRemovable.ts +0 -45
  191. package/src/components/chip/ChipSelectable.ts +0 -80
  192. package/src/components/chip/chip-group.css +0 -15
  193. package/src/components/chip/chip.css +0 -139
  194. package/src/components/chip/exports.ts +0 -4
  195. package/src/components/chip/leu-chip-group.ts +0 -11
  196. package/src/components/chip/leu-chip-link.ts +0 -11
  197. package/src/components/chip/leu-chip-removable.ts +0 -11
  198. package/src/components/chip/leu-chip-selectable.ts +0 -11
  199. package/src/components/chip/stories/chip-group.stories.ts +0 -159
  200. package/src/components/chip/stories/chip-link.stories.ts +0 -45
  201. package/src/components/chip/stories/chip-removable.stories.ts +0 -42
  202. package/src/components/chip/stories/chip-selectable.stories.ts +0 -54
  203. package/src/components/chip/test/chip-group.test.ts +0 -171
  204. package/src/components/chip/test/chip-link.test.ts +0 -54
  205. package/src/components/chip/test/chip-removable.test.ts +0 -105
  206. package/src/components/chip/test/chip-selectable.test.ts +0 -101
  207. package/src/components/chip/test/chip.test.ts +0 -22
  208. package/src/components/dialog/Dialog.ts +0 -86
  209. package/src/components/dialog/dialog.css +0 -157
  210. package/src/components/dialog/leu-dialog.ts +0 -11
  211. package/src/components/dialog/stories/dialog.stories.ts +0 -142
  212. package/src/components/dialog/test/dialog.test.ts +0 -85
  213. package/src/components/dropdown/Dropdown.ts +0 -152
  214. package/src/components/dropdown/dropdown.css +0 -16
  215. package/src/components/dropdown/leu-dropdown.ts +0 -11
  216. package/src/components/dropdown/stories/dropdown.stories.ts +0 -58
  217. package/src/components/dropdown/test/dropdown.test.ts +0 -59
  218. package/src/components/file-input/FileInput.ts +0 -324
  219. package/src/components/file-input/file-input.css +0 -118
  220. package/src/components/file-input/leu-file-input.ts +0 -11
  221. package/src/components/file-input/stories/file-input.stories.ts +0 -45
  222. package/src/components/file-input/test/file-input.test.ts +0 -62
  223. package/src/components/icon/Icon.ts +0 -47
  224. package/src/components/icon/icon.css +0 -10
  225. package/src/components/icon/leu-icon.ts +0 -11
  226. package/src/components/icon/paths.ts +0 -219
  227. package/src/components/icon/stories/icon.stories.ts +0 -79
  228. package/src/components/icon/test/icon.test.ts +0 -50
  229. package/src/components/input/Input.ts +0 -469
  230. package/src/components/input/input.css +0 -238
  231. package/src/components/input/leu-input.ts +0 -11
  232. package/src/components/input/stories/input.stories.ts +0 -204
  233. package/src/components/input/test/input.test.ts +0 -603
  234. package/src/components/menu/Menu.ts +0 -149
  235. package/src/components/menu/MenuItem.ts +0 -168
  236. package/src/components/menu/leu-menu-item.ts +0 -11
  237. package/src/components/menu/leu-menu.ts +0 -11
  238. package/src/components/menu/menu-item.css +0 -77
  239. package/src/components/menu/menu.css +0 -19
  240. package/src/components/menu/stories/menu-item.stories.ts +0 -81
  241. package/src/components/menu/stories/menu.stories.ts +0 -54
  242. package/src/components/menu/test/menu-item.test.ts +0 -210
  243. package/src/components/menu/test/menu.test.ts +0 -125
  244. package/src/components/message/Message.ts +0 -118
  245. package/src/components/message/leu-message.ts +0 -11
  246. package/src/components/message/message.css +0 -163
  247. package/src/components/message/stories/message.mdx +0 -76
  248. package/src/components/message/stories/message.stories.ts +0 -149
  249. package/src/components/message/test/message.test.ts +0 -96
  250. package/src/components/pagination/Pagination.ts +0 -192
  251. package/src/components/pagination/leu-pagination.ts +0 -11
  252. package/src/components/pagination/pagination.css +0 -54
  253. package/src/components/pagination/stories/pagination.stories.ts +0 -115
  254. package/src/components/pagination/test/pagination.test.ts +0 -210
  255. package/src/components/placeholder/Placeholder.ts +0 -33
  256. package/src/components/placeholder/leu-placeholder.ts +0 -11
  257. package/src/components/placeholder/placeholder.css +0 -59
  258. package/src/components/placeholder/stories/placeholder.stories.ts +0 -34
  259. package/src/components/placeholder/test/placeholder.test.ts +0 -31
  260. package/src/components/popup/Popup.ts +0 -264
  261. package/src/components/popup/leu-popup.ts +0 -11
  262. package/src/components/popup/popup.css +0 -24
  263. package/src/components/popup/stories/popup.stories.ts +0 -117
  264. package/src/components/popup/test/popup.test.ts +0 -90
  265. package/src/components/progress-bar/ProgressBar.ts +0 -52
  266. package/src/components/progress-bar/leu-progress-bar.ts +0 -11
  267. package/src/components/progress-bar/progress-bar.css +0 -97
  268. package/src/components/progress-bar/stories/progress-bar.stories.ts +0 -39
  269. package/src/components/progress-bar/test/progress-bar.test.ts +0 -61
  270. package/src/components/radio/Radio.ts +0 -59
  271. package/src/components/radio/RadioGroup.ts +0 -181
  272. package/src/components/radio/leu-radio-group.ts +0 -11
  273. package/src/components/radio/leu-radio.ts +0 -11
  274. package/src/components/radio/radio-group.css +0 -29
  275. package/src/components/radio/radio.css +0 -76
  276. package/src/components/radio/stories/radio-group.stories.ts +0 -54
  277. package/src/components/radio/stories/radio.stories.ts +0 -55
  278. package/src/components/radio/test/radio-group.test.ts +0 -83
  279. package/src/components/radio/test/radio.test.ts +0 -119
  280. package/src/components/range/Range.ts +0 -400
  281. package/src/components/range/leu-range.ts +0 -11
  282. package/src/components/range/range.css +0 -227
  283. package/src/components/range/stories/range.stories.ts +0 -185
  284. package/src/components/range/test/range.test.ts +0 -228
  285. package/src/components/scroll-top/ScrollTop.ts +0 -91
  286. package/src/components/scroll-top/leu-scroll-top.ts +0 -11
  287. package/src/components/scroll-top/scroll-top.css +0 -50
  288. package/src/components/scroll-top/stories/scroll-top.stories.ts +0 -217
  289. package/src/components/scroll-top/test/scroll-top.test.ts +0 -22
  290. package/src/components/select/Select.ts +0 -570
  291. package/src/components/select/leu-select.ts +0 -11
  292. package/src/components/select/select.css +0 -222
  293. package/src/components/select/stories/select.stories.ts +0 -173
  294. package/src/components/select/test/fixtures.ts +0 -162
  295. package/src/components/select/test/select.test.ts +0 -937
  296. package/src/components/spinner/Spinner.ts +0 -31
  297. package/src/components/spinner/leu-spinner.ts +0 -11
  298. package/src/components/spinner/spinner.css +0 -20
  299. package/src/components/spinner/stories/spinner.stories.ts +0 -29
  300. package/src/components/spinner/test/spinner.test.ts +0 -30
  301. package/src/components/tab/Tab.ts +0 -72
  302. package/src/components/tab/TabGroup.ts +0 -267
  303. package/src/components/tab/TabPanel.ts +0 -59
  304. package/src/components/tab/leu-tab-group.ts +0 -11
  305. package/src/components/tab/leu-tab-panel.ts +0 -11
  306. package/src/components/tab/leu-tab.ts +0 -11
  307. package/src/components/tab/stories/tab.stories.ts +0 -97
  308. package/src/components/tab/tab-group.css +0 -63
  309. package/src/components/tab/tab-panel.css +0 -10
  310. package/src/components/tab/tab.css +0 -54
  311. package/src/components/tab/test/tab-group.test.ts +0 -426
  312. package/src/components/tab/test/tab-panel.test.ts +0 -102
  313. package/src/components/tab/test/tab.test.ts +0 -139
  314. package/src/components/table/Table.ts +0 -253
  315. package/src/components/table/leu-table.ts +0 -11
  316. package/src/components/table/stories/table.stories.ts +0 -131
  317. package/src/components/table/table.css +0 -112
  318. package/src/components/table/test/table.test.ts +0 -37
  319. package/src/components/tag/Tag.ts +0 -28
  320. package/src/components/tag/leu-tag.ts +0 -11
  321. package/src/components/tag/stories/tag.stories.ts +0 -107
  322. package/src/components/tag/tag.css +0 -42
  323. package/src/components/tag/test/tag.test.ts +0 -28
  324. package/src/components/visually-hidden/VisuallyHidden.ts +0 -16
  325. package/src/components/visually-hidden/leu-visually-hidden.ts +0 -11
  326. package/src/components/visually-hidden/stories/visually-hidden.stories.ts +0 -22
  327. package/src/components/visually-hidden/test/visually-hidden.test.ts +0 -34
  328. package/src/components/visually-hidden/visually-hidden.css +0 -10
  329. package/src/docs/contributing.mdx +0 -154
  330. package/src/docs/installation.mdx +0 -35
  331. package/src/docs/theme.mdx +0 -400
  332. package/src/docs/usage.mdx +0 -73
  333. package/src/global.d.ts +0 -11
  334. package/src/index.ts +0 -29
  335. package/src/lib/LeuElement.ts +0 -43
  336. package/src/lib/a11y.ts +0 -26
  337. package/src/lib/hasSlotController.ts +0 -74
  338. package/src/lib/mixins/FormAssociatedMixin.ts +0 -115
  339. package/src/lib/styleMap.ts +0 -139
  340. package/src/lib/utils.ts +0 -45
  341. package/src/styles/common-styles.css +0 -14
  342. package/src/styles/custom-media.css +0 -6
  343. package/src/styles/font-definitions.json +0 -210
  344. package/src/styles/style.stories.ts +0 -64
  345. package/src/styles/theme.css +0 -90
  346. package/stat_zh.png +0 -0
  347. package/stylelint.config.mjs +0 -23
  348. package/tsconfig.build.json +0 -24
  349. package/tsconfig.json +0 -14
  350. package/tsdown.config.ts +0 -35
  351. package/web-test-runner.config.mjs +0 -102
@@ -1,324 +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 async handleChange(event: Event & { target: HTMLInputElement }) {
96
- await this.updateComplete
97
- const customEvent = new CustomEvent(event.type, event)
98
- this.dispatchEvent(customEvent)
99
- }
100
-
101
- public formResetCallback() {
102
- this.files = []
103
- this.input.value = ""
104
- }
105
-
106
- protected setFormValue() {
107
- const formData = new FormData()
108
-
109
- const files = this.multiple ? this.files : this.files.slice(0, 1)
110
-
111
- files.forEach((file) => {
112
- formData.append(this.name, file)
113
- })
114
-
115
- this.internals.setFormValue(formData)
116
-
117
- if (this.required && files.length < 1) {
118
- // @todo i18n and/or custom validation message
119
- this.internals.setValidity(
120
- { valueMissing: true },
121
- "Bitte wählen Sie eine Datei.",
122
- this.input,
123
- )
124
- } else {
125
- this.internals.setValidity({})
126
- }
127
- }
128
-
129
- protected removeFile(fileToRemove: File) {
130
- this.files = this.files.filter((file) => file !== fileToRemove)
131
- this.dispatchChangeAndInputEvents()
132
- }
133
-
134
- protected async dispatchChangeAndInputEvents() {
135
- await this.updateComplete
136
- this.dispatchEvent(
137
- new CustomEvent("input", {
138
- composed: true,
139
- bubbles: true,
140
- }),
141
- )
142
- this.dispatchEvent(
143
- new CustomEvent("change", {
144
- composed: true,
145
- bubbles: true,
146
- }),
147
- )
148
- }
149
-
150
- /**
151
- * This implementation Uses base-10 (decimal) units:
152
- * 1 KB = 1_000 bytes
153
- * 1 MB = 1_000_000 bytes
154
- * 1 GB = 1_000_000_000 bytes
155
- *
156
- * To switch to base-2 (binary), use the following implementation:
157
- * // const KB = 1024
158
- * // const MB = 1024 * 1024
159
- * // const GB = 1024 * 1024 * 1024
160
- */
161
- protected static formatFileSize(size: number) {
162
- const KB = 1e3
163
- const MB = 1e6
164
- const GB = 1e9
165
-
166
- if (size >= GB) {
167
- return html`${(size / GB).toFixed(1)}&nbsp;GB`
168
- }
169
-
170
- if (size >= MB) {
171
- return html`${(size / MB).toFixed(1)}&nbsp;MB`
172
- }
173
-
174
- if (size >= KB) {
175
- return html`${(size / KB).toFixed(1)}&nbsp;KB`
176
- }
177
-
178
- return html`${size}&nbsp;bytes`
179
- }
180
-
181
- protected handleDragEnter = (event: DragEvent) => {
182
- if (this.disabled) return
183
-
184
- event.preventDefault()
185
- event.stopPropagation()
186
- this.isDragging = [...event.dataTransfer.items].some(
187
- (item) => item.kind === "file",
188
- )
189
- }
190
-
191
- protected handleDragOver = (event: DragEvent) => {
192
- if (this.disabled) return
193
-
194
- event.preventDefault()
195
- event.stopPropagation()
196
- }
197
-
198
- protected handleDragLeave = (event: DragEvent) => {
199
- if (this.disabled) return
200
-
201
- event.preventDefault()
202
- event.stopPropagation()
203
- this.isDragging = false
204
- }
205
-
206
- protected handleDrop = (event: DragEvent) => {
207
- this.isDragging = false
208
-
209
- if (this.disabled) return
210
-
211
- event.preventDefault()
212
- event.stopPropagation()
213
-
214
- const dt = event.dataTransfer
215
- const files = dt.files
216
- const acceptedFiles = [...files].filter((file) => this.isAcceptedFile(file))
217
-
218
- if (acceptedFiles.length < 1) {
219
- return
220
- }
221
-
222
- this.files = this.multiple
223
- ? this.files.concat(acceptedFiles)
224
- : acceptedFiles.slice(0, 1)
225
-
226
- this.dispatchChangeAndInputEvents()
227
- }
228
-
229
- isAcceptedFile(file: File): boolean {
230
- const acceptedTypes = this.accept.split(",").map((type) => type.trim())
231
- const mimeType = file.type
232
-
233
- for (const acceptedType of acceptedTypes) {
234
- // Handle file extensions (e.g. .jpg, .png)
235
- if (acceptedType.startsWith(".")) {
236
- const name = file.name.toLowerCase()
237
- const extension = acceptedType.toLowerCase()
238
-
239
- if (name.endsWith(extension)) {
240
- return true
241
- }
242
- // Handle wildcard types (e.g. image/*)
243
- } else if (/^\w+\/\*$/.test(acceptedType)) {
244
- if (mimeType.split("/")[0] === acceptedType.split("/")[0]) {
245
- return true
246
- }
247
- }
248
-
249
- if (mimeType === acceptedType) {
250
- return true
251
- }
252
- }
253
-
254
- return false
255
- }
256
-
257
- render() {
258
- const dropzoneClasses = {
259
- dropzone: true,
260
- "dropzone--dragging": this.isDragging,
261
- }
262
-
263
- return html`
264
- <div class="container">
265
- <label class="label" for="input">${this.label}</label>
266
- <leu-visually-hidden>
267
- <input
268
- id="input"
269
- type="file"
270
- ?multiple=${this.multiple}
271
- ?disabled=${this.disabled}
272
- ?required=${this.required}
273
- accept=${ifDefined(this.accept)}
274
- @input=${this.handleInput}
275
- @change=${this.handleChange}
276
- />
277
- </leu-visually-hidden>
278
- <div
279
- class=${classMap(dropzoneClasses)}
280
- @dragenter=${this.handleDragEnter}
281
- @dragover=${this.handleDragOver}
282
- @dragleave=${this.handleDragLeave}
283
- @drop=${this.handleDrop}
284
- >
285
- <slot class="dropzone__text"
286
- ><p>Zum Hochladen Dateien ziehen und hier ablegen.</p></slot
287
- >
288
- <leu-button
289
- variant="secondary"
290
- ?disabled=${this.disabled}
291
- @click=${() => this.input.click()}
292
- >
293
- Datei auswählen
294
- <leu-icon name="upload" slot="after"></leu-icon>
295
- </leu-button>
296
- </div>
297
- ${this.files.length > 0
298
- ? html`<ul class="file-list">
299
- ${this.files.map(
300
- (file) =>
301
- html`<li class="file">
302
- <strong class="file__name">${file.name}</strong>
303
- <p class="file__size">
304
- <span class="file__size-label">Grösse:</span>
305
- ${LeuFileInput.formatFileSize(file.size)}
306
- </p>
307
- <leu-button
308
- round
309
- class="file__button"
310
- label="Datei entfernen"
311
- size="small"
312
- variant="secondary"
313
- ?disabled=${this.disabled}
314
- @click=${() => this.removeFile(file)}
315
- ><leu-icon name="delete"></leu-icon
316
- ></leu-button>
317
- </li>`,
318
- )}
319
- </ul>`
320
- : nothing}
321
- </div>
322
- `
323
- }
324
- }
@@ -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,62 +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
-
39
- it("dispatches change after validity is updated", async () => {
40
- const el = await fixture<LeuFileInput>(html`
41
- <leu-file-input
42
- label="File upload"
43
- required
44
- accept="text/plain"
45
- ></leu-file-input>
46
- `)
47
- const dropzone = el.shadowRoot?.querySelector<HTMLDivElement>(".dropzone")
48
- const dataTransfer = new DataTransfer()
49
- const file = new File(["content"], "test.txt", { type: "text/plain" })
50
- dataTransfer.items.add(file)
51
- let validityAtChangeEvent: boolean | undefined
52
-
53
- el.addEventListener("change", () => {
54
- validityAtChangeEvent = el.checkValidity()
55
- })
56
-
57
- dropzone?.dispatchEvent(new DragEvent("drop", { dataTransfer }))
58
- await el.updateComplete
59
-
60
- expect(validityAtChangeEvent).to.be.true
61
- })
62
- })
@@ -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
- }