@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,937 +0,0 @@
1
- import { html } from "lit"
2
- import { ifDefined } from "lit/directives/if-defined.js"
3
- import { fixture, expect, elementUpdated } from "@open-wc/testing"
4
- import { sendKeys } from "@web/test-runner-commands"
5
-
6
- import type { LeuSelect } from "../Select.js"
7
- import "../leu-select.js"
8
- import "../../menu/leu-menu-item.js"
9
- import { MUNICIPALITIES } from "./fixtures.js"
10
-
11
- async function defaultFixture(
12
- args: {
13
- options?: ReadonlyArray<string>
14
- label?: string
15
- value?: ReadonlyArray<string>
16
- clearable?: boolean
17
- disabled?: boolean
18
- filterable?: boolean
19
- multiple?: boolean
20
- } = {},
21
- ) {
22
- const el = await fixture<LeuSelect>(
23
- html`<leu-select
24
- label=${ifDefined(args.label)}
25
- value=${ifDefined(args.value?.join(","))}
26
- ?clearable=${args.clearable ?? false}
27
- ?disabled=${args.disabled ?? false}
28
- ?filterable=${args.filterable ?? false}
29
- ?multiple=${args.multiple ?? false}
30
- >
31
- ${(args.options ?? []).map(
32
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
33
- )}
34
- </leu-select> `,
35
- )
36
-
37
- return el
38
- }
39
-
40
- describe("LeuSelect", () => {
41
- it("is a defined element", async () => {
42
- const el = customElements.get("leu-select")
43
-
44
- expect(el).not.to.be.undefined
45
- })
46
-
47
- it("passes the a11y audit", async () => {
48
- const el = await defaultFixture({
49
- options: MUNICIPALITIES,
50
- label: "Gemeinde",
51
- })
52
-
53
- await expect(el).shadowDom.to.be.accessible()
54
- })
55
-
56
- it("passes the a11y audit in the open state", async () => {
57
- const el = await defaultFixture({
58
- options: MUNICIPALITIES,
59
- label: "Gemeinde",
60
- })
61
-
62
- el.click()
63
- await elementUpdated(el)
64
-
65
- await expect(el).shadowDom.to.be.accessible()
66
- })
67
-
68
- it("passes the a11y audit when a value is set", async () => {
69
- const el = await defaultFixture({
70
- options: MUNICIPALITIES,
71
- label: "Gemeinde",
72
- value: ["Affoltern am Albis"],
73
- clearable: true,
74
- })
75
-
76
- await expect(el).shadowDom.to.be.accessible()
77
- })
78
-
79
- it("renders a label", async () => {
80
- const el = await defaultFixture({
81
- options: MUNICIPALITIES,
82
- label: "Gemeinde",
83
- })
84
-
85
- const toggleButton =
86
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
87
-
88
- expect(toggleButton).to.have.trimmed.text("Gemeinde")
89
- })
90
-
91
- it("doesn't display the popup in the default state", async () => {
92
- const el = await defaultFixture({
93
- options: MUNICIPALITIES,
94
- label: "Gemeinde",
95
- })
96
-
97
- const popup = el.shadowRoot.querySelector("leu-popup")
98
- expect(popup).to.not.have.attribute("active")
99
- })
100
-
101
- it("opens the list of options when the toggle button is clicked", async () => {
102
- const el = await defaultFixture({
103
- options: MUNICIPALITIES,
104
- label: "Gemeinde",
105
- })
106
-
107
- const toggleButton =
108
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
109
- toggleButton.click()
110
-
111
- const popup = el.shadowRoot.querySelector("leu-popup")
112
- await elementUpdated(el)
113
-
114
- expect(popup).to.have.attribute("active")
115
- })
116
-
117
- it("has a default value of an empty array", async () => {
118
- const el = await defaultFixture({
119
- options: MUNICIPALITIES,
120
- label: "Gemeinde",
121
- })
122
-
123
- expect(el.value).to.deep.equal([])
124
- })
125
-
126
- it("marks the menu item as selected if the value is set", async () => {
127
- const el = await defaultFixture({
128
- options: MUNICIPALITIES,
129
- label: "Gemeinde",
130
- value: ["Affoltern am Albis"],
131
- })
132
-
133
- await elementUpdated(el)
134
-
135
- const menuItems = Array.from(el.querySelectorAll("leu-menu-item"))
136
-
137
- const menuItem = menuItems.find(
138
- (item) => item.textContent === "Affoltern am Albis",
139
- )
140
-
141
- expect(menuItem).to.have.attribute("active")
142
-
143
- el.value = ["Affoltern a.A."] // This name doesn't match the name in the options
144
- await elementUpdated(el)
145
-
146
- // The value doesn't match any of the options
147
- expect(menuItems.every((item) => !item.active)).to.be.true
148
- })
149
-
150
- it("converts the value to an array if it is a string", async () => {
151
- const el = await defaultFixture({
152
- options: ["Option 1", "Option 2", "Option 3"],
153
- label: "Options",
154
- })
155
-
156
- el.setAttribute("value", "Option 1, Option 2")
157
- expect(el.value).to.deep.equal(["Option 1", "Option 2"])
158
-
159
- el.setAttribute("value", "Option 3")
160
- expect(el.value).to.deep.equal(["Option 3"])
161
-
162
- el.setAttribute("value", "Option 1 Option 2")
163
- expect(el.value).to.deep.equal(["Option 1 Option 2"])
164
- })
165
-
166
- it("renders the label of the selected option", async () => {
167
- const el = await defaultFixture({
168
- options: MUNICIPALITIES,
169
- label: "Gemeinde",
170
- value: ["Affoltern am Albis"],
171
- })
172
-
173
- const toggleButton = el.shadowRoot.querySelector(".select-toggle .value")
174
- expect(toggleButton).to.have.trimmed.text("Affoltern am Albis")
175
-
176
- el.multiple = true
177
- await elementUpdated(el)
178
-
179
- expect(toggleButton).to.have.trimmed.text("1 gewählt")
180
-
181
- el.value = ["Affoltern am Albis", "Maur"]
182
- await elementUpdated(el)
183
- expect(toggleButton).to.have.trimmed.text("2 gewählt")
184
- })
185
-
186
- it("shows the clear button when a value is set", async () => {
187
- const el = await defaultFixture({
188
- options: MUNICIPALITIES,
189
- label: "Gemeinde",
190
- value: ["Affoltern am Albis"],
191
- clearable: true,
192
- })
193
-
194
- const clearButton = el.shadowRoot.querySelector(".clear-button")
195
-
196
- expect(clearButton).to.exist
197
- })
198
-
199
- it("renders a input field to filter the options", async () => {
200
- const el = await defaultFixture({
201
- options: MUNICIPALITIES,
202
- label: "Gemeinde",
203
- filterable: true,
204
- })
205
-
206
- const filterInput =
207
- el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
208
-
209
- expect(filterInput).to.exist
210
- })
211
-
212
- it("filters the options when the filter input is changed", async () => {
213
- const el = await defaultFixture({
214
- options: MUNICIPALITIES,
215
- label: "Gemeinde",
216
- filterable: true,
217
- })
218
-
219
- const toggleButton =
220
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
221
- toggleButton.click()
222
-
223
- const filterInput =
224
- el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
225
- filterInput.focus()
226
-
227
- await sendKeys({ type: "am albis" })
228
-
229
- const menuItems = el.querySelectorAll("leu-menu-item")
230
- const visibleMenuItems = Array.from(menuItems).filter(
231
- (menuItem) => !menuItem.hidden,
232
- )
233
- expect(visibleMenuItems.length).to.equal(6)
234
- })
235
-
236
- it("resets the filter when the filter input is cleared", async () => {
237
- const el = await defaultFixture({
238
- options: MUNICIPALITIES,
239
- label: "Gemeinde",
240
- filterable: true,
241
- })
242
-
243
- const toggleButton =
244
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
245
- toggleButton.click()
246
-
247
- const filterInput =
248
- el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
249
- filterInput.focus()
250
-
251
- await sendKeys({ type: "am albis" })
252
-
253
- const clearFilterButton =
254
- filterInput.shadowRoot.querySelector<HTMLButtonElement>(".clear-button")
255
- clearFilterButton.click()
256
- await elementUpdated(el)
257
-
258
- const menuItems = el.querySelectorAll("leu-menu-item")
259
- const visibleMenuItems = Array.from(menuItems).filter(
260
- (menuItem) => !menuItem.hidden,
261
- )
262
-
263
- expect(visibleMenuItems.length).to.equal(MUNICIPALITIES.length)
264
- })
265
-
266
- it("renders a message when no options are available after filtering", async () => {
267
- const el = await defaultFixture({
268
- options: MUNICIPALITIES,
269
- label: "Gemeinde",
270
- filterable: true,
271
- })
272
-
273
- const toggleButton =
274
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
275
- toggleButton.click()
276
-
277
- const filterInput =
278
- el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
279
- filterInput.focus()
280
-
281
- await sendKeys({ type: "am albissss" })
282
- await elementUpdated(el)
283
-
284
- const emptyMessage = el.shadowRoot.querySelector(".filter-message-empty")
285
- expect(emptyMessage).to.exist
286
- expect(emptyMessage).to.have.attribute("aria-live", "polite")
287
- expect(emptyMessage).to.have.trimmed.text("Keine Resultate")
288
- })
289
-
290
- it("doesn't render a message when no options are available and no filter is set", async () => {
291
- const el = await defaultFixture({
292
- options: [],
293
- label: "Gemeinde",
294
- filterable: true,
295
- })
296
-
297
- const toggleButton =
298
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
299
- toggleButton.click()
300
-
301
- const emptyMessage = el.shadowRoot.querySelector(".filter-message-empty")
302
- expect(emptyMessage).not.to.exist
303
- })
304
-
305
- it("syncs the state to the menu items when they're updated lazily", async () => {
306
- const el = await defaultFixture({
307
- options: [],
308
- label: "Gemeinde",
309
- value: ["Affoltern am Albis"],
310
- filterable: true,
311
- })
312
-
313
- const toggleButton =
314
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
315
- toggleButton.click()
316
-
317
- const filterInput =
318
- el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
319
- filterInput.focus()
320
-
321
- await sendKeys({ type: "am albis" })
322
- await elementUpdated(el)
323
-
324
- let emptyMessage = el.shadowRoot.querySelector(".filter-message-empty")
325
- expect(emptyMessage).to.exist
326
-
327
- const fragment = document.createDocumentFragment()
328
- MUNICIPALITIES.forEach((option) => {
329
- const menuItem = document.createElement("leu-menu-item")
330
- menuItem.textContent = option
331
- fragment.appendChild(menuItem)
332
- })
333
-
334
- el.appendChild(fragment)
335
-
336
- // Two calls to elementUpdated are needed because the _hasFilterResults
337
- // property is set during the updated lifecycle
338
- await elementUpdated(el)
339
- await elementUpdated(el)
340
- emptyMessage = el.shadowRoot.querySelector(".filter-message-empty")
341
- expect(emptyMessage).to.be.null
342
-
343
- const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
344
- (item) => item.textContent === "Affoltern am Albis",
345
- )
346
- expect(menuItem).to.have.attribute("active")
347
- })
348
-
349
- it("renders a apply button when multiple selection is allowed", async () => {
350
- const el = await defaultFixture({
351
- options: MUNICIPALITIES,
352
- label: "Gemeinde",
353
- multiple: true,
354
- })
355
-
356
- const applyButton = el.shadowRoot.querySelector(".apply-button")
357
- expect(applyButton).to.exist
358
- })
359
-
360
- it("closes the popup when the apply button is clicked", async () => {
361
- const el = await defaultFixture({
362
- options: MUNICIPALITIES,
363
- label: "Gemeinde",
364
- multiple: true,
365
- })
366
-
367
- const toggleButton =
368
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
369
- toggleButton.click()
370
-
371
- const applyButton = el.shadowRoot.querySelector(".apply-button")
372
- applyButton.click()
373
-
374
- const popup = el.shadowRoot.querySelector("leu-popup")
375
- expect(popup).to.not.have.attribute("active")
376
- })
377
-
378
- it("updates the value when an option is selected", async () => {
379
- const el = await defaultFixture({
380
- options: MUNICIPALITIES,
381
- label: "Gemeinde",
382
- })
383
-
384
- const toggleButton =
385
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
386
- toggleButton.click()
387
-
388
- const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
389
- (item) => item.textContent === "Maur",
390
- )
391
- menuItem.click()
392
-
393
- expect(el.value).to.deep.equal(["Maur"])
394
- })
395
-
396
- it("doesn't allow unselecting the value", async () => {
397
- const el = await defaultFixture({
398
- options: MUNICIPALITIES,
399
- label: "Gemeinde",
400
- value: ["Maur"],
401
- })
402
- const toggleButton =
403
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
404
- toggleButton.click()
405
-
406
- const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
407
- (item) => item.textContent === "Maur",
408
- )
409
-
410
- menuItem.click()
411
- expect(el.value).to.deep.equal(["Maur"])
412
- })
413
-
414
- it("allows unselecting the value when clearable is set", async () => {
415
- const el = await defaultFixture({
416
- options: MUNICIPALITIES,
417
- label: "Gemeinde",
418
- value: ["Maur"],
419
- clearable: true,
420
- })
421
- const toggleButton =
422
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
423
- toggleButton.click()
424
-
425
- const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
426
- (item) => item.textContent === "Maur",
427
- )
428
-
429
- menuItem.click()
430
- expect(el.value).to.deep.equal([])
431
- })
432
-
433
- it("allows a value with multiple values", async () => {
434
- const el = await defaultFixture({
435
- options: MUNICIPALITIES,
436
- label: "Gemeinde",
437
- multiple: true,
438
- })
439
-
440
- const toggleButton =
441
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
442
- toggleButton.click()
443
-
444
- const menuItems = Array.from(el.querySelectorAll("leu-menu-item"))
445
-
446
- menuItems.find((item) => item.textContent === "Maur").click()
447
- menuItems.find((item) => item.textContent === "Zollikon").click()
448
-
449
- expect(el.value).to.deep.equal(["Maur", "Zollikon"])
450
- })
451
-
452
- it("closes the popup when an item is selected", async () => {
453
- const el = await defaultFixture({
454
- options: MUNICIPALITIES,
455
- label: "Gemeinde",
456
- })
457
-
458
- const toggleButton =
459
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
460
- toggleButton.click()
461
-
462
- const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
463
- (item) => item.textContent === "Hedingen",
464
- )
465
- menuItem.click()
466
-
467
- const popup = el.shadowRoot.querySelector("leu-popup")
468
- expect(popup).to.not.have.attribute("active")
469
- })
470
-
471
- it("keeps the popup open after selecting an item when multiple selection is allowed", async () => {
472
- const el = await defaultFixture({
473
- options: MUNICIPALITIES,
474
- label: "Gemeinde",
475
- multiple: true,
476
- })
477
-
478
- const toggleButton =
479
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
480
- toggleButton.click()
481
-
482
- const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
483
- (item) => item.textContent === "Hedingen",
484
- )
485
- menuItem.click()
486
-
487
- const popup = el.shadowRoot.querySelector("leu-popup")
488
- expect(popup).to.not.have.attribute("active")
489
- })
490
-
491
- it("focuses the filter input when the popup is opened", async () => {
492
- const el = await defaultFixture({
493
- options: MUNICIPALITIES,
494
- label: "Gemeinde",
495
- filterable: true,
496
- })
497
-
498
- const toggleButton =
499
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
500
- toggleButton.click()
501
-
502
- await elementUpdated(el)
503
-
504
- const filterInput =
505
- el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
506
- expect(filterInput).to.equal(el.shadowRoot.activeElement)
507
- })
508
-
509
- it("focuses the first menu item when the popup is opened", async () => {
510
- const el = await defaultFixture({
511
- options: MUNICIPALITIES,
512
- label: "Gemeinde",
513
- })
514
-
515
- const toggleButton =
516
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
517
- toggleButton.click()
518
-
519
- await elementUpdated(el)
520
-
521
- const menuItems = el.querySelectorAll("leu-menu-item")
522
- const firstMenuItem = menuItems[0]
523
- expect(firstMenuItem).to.equal(document.activeElement)
524
- })
525
-
526
- it("closes the popup when the escape key is pressed", async () => {
527
- const el = await defaultFixture({
528
- options: MUNICIPALITIES,
529
- label: "Gemeinde",
530
- })
531
-
532
- const toggleButton =
533
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
534
- toggleButton.click()
535
-
536
- await sendKeys({ press: "Escape" })
537
-
538
- const popup = el.shadowRoot.querySelector("leu-popup")
539
- expect(popup.active).to.not.be.true
540
- })
541
-
542
- it("sets the multipleSelection property on the menu items when multiple selection is allowed", async () => {
543
- const el = await defaultFixture({
544
- options: MUNICIPALITIES,
545
- label: "Gemeinde",
546
- multiple: true,
547
- })
548
-
549
- const menuItems = Array.from(el.querySelectorAll("leu-menu-item"))
550
- expect(menuItems.every((item) => item.multipleSelection)).to.be.true
551
-
552
- el.multiple = false
553
- await elementUpdated(el)
554
-
555
- expect(menuItems.every((item) => !item.multipleSelection)).to.be.true
556
- })
557
-
558
- it("closes the popup when the document is clicked outside the component", async () => {
559
- const el = await defaultFixture({
560
- options: MUNICIPALITIES,
561
- label: "Gemeinde",
562
- })
563
-
564
- const toggleButton =
565
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
566
- toggleButton.click()
567
-
568
- document.body.click()
569
-
570
- const popup = el.shadowRoot.querySelector("leu-popup")
571
- expect(popup.active).to.not.be.true
572
- })
573
-
574
- describe("Form association", () => {
575
- it("submits the selected value in a form", async () => {
576
- const form = await fixture<HTMLFormElement>(html`
577
- <form>
578
- <leu-select name="city" label="Gemeinde">
579
- ${MUNICIPALITIES.map(
580
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
581
- )}
582
- </leu-select>
583
- </form>
584
- `)
585
-
586
- const el = form.querySelector("leu-select")
587
- el.value = ["Maur"]
588
- await elementUpdated(el)
589
-
590
- const formData = new FormData(form)
591
- expect(formData.get("city")).to.equal("Maur")
592
- })
593
-
594
- it("submits multiple selected values as separate form entries", async () => {
595
- const form = await fixture<HTMLFormElement>(html`
596
- <form>
597
- <leu-select name="city" label="Gemeinde" ?multiple=${true}>
598
- ${MUNICIPALITIES.map(
599
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
600
- )}
601
- </leu-select>
602
- </form>
603
- `)
604
-
605
- const el = form.querySelector("leu-select")
606
- el.value = ["Maur", "Zollikon"]
607
- await elementUpdated(el)
608
-
609
- const formData = new FormData(form)
610
- expect(formData.getAll("city")).to.deep.equal(["Maur", "Zollikon"])
611
- })
612
-
613
- it("submits null when no value is selected", async () => {
614
- const form = await fixture<HTMLFormElement>(html`
615
- <form>
616
- <leu-select name="city" label="Gemeinde">
617
- ${MUNICIPALITIES.map(
618
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
619
- )}
620
- </leu-select>
621
- </form>
622
- `)
623
-
624
- const formData = new FormData(form)
625
- expect(formData.get("city")).to.be.null
626
- })
627
-
628
- it("uses the defaultValue as initial form value", async () => {
629
- const form = await fixture<HTMLFormElement>(html`
630
- <form>
631
- <leu-select name="city" value="Maur" label="Gemeinde">
632
- ${MUNICIPALITIES.map(
633
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
634
- )}
635
- </leu-select>
636
- </form>
637
- `)
638
-
639
- const el = form.querySelector("leu-select")
640
- await elementUpdated(el)
641
-
642
- expect(el.defaultValue).to.deep.equal(["Maur"])
643
- expect(el.value).to.deep.equal(["Maur"])
644
-
645
- const formData = new FormData(form)
646
- expect(formData.get("city")).to.equal("Maur")
647
- })
648
-
649
- it("resets to the defaultValue when the form is reset", async () => {
650
- const form = await fixture<HTMLFormElement>(html`
651
- <form>
652
- <leu-select name="city" value="Maur" label="Gemeinde">
653
- ${MUNICIPALITIES.map(
654
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
655
- )}
656
- </leu-select>
657
- </form>
658
- `)
659
-
660
- const el = form.querySelector("leu-select")
661
- el.value = ["Zollikon"]
662
- await elementUpdated(el)
663
-
664
- expect(el.value).to.deep.equal(["Zollikon"])
665
-
666
- form.reset()
667
- await elementUpdated(el)
668
-
669
- expect(el.value).to.deep.equal(["Maur"])
670
- })
671
-
672
- it("resets to an empty value when no defaultValue is set", async () => {
673
- const form = await fixture<HTMLFormElement>(html`
674
- <form>
675
- <leu-select name="city" label="Gemeinde">
676
- ${MUNICIPALITIES.map(
677
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
678
- )}
679
- </leu-select>
680
- </form>
681
- `)
682
-
683
- const el = form.querySelector("leu-select")
684
- el.value = ["Maur"]
685
- await elementUpdated(el)
686
-
687
- form.reset()
688
- await elementUpdated(el)
689
-
690
- expect(el.value).to.deep.equal([])
691
- })
692
-
693
- it("updates the form data when the defaultValue changes before any interaction", async () => {
694
- const form = await fixture<HTMLFormElement>(html`
695
- <form>
696
- <leu-select name="city" value="Maur" label="Gemeinde">
697
- ${MUNICIPALITIES.map(
698
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
699
- )}
700
- </leu-select>
701
- </form>
702
- `)
703
-
704
- const el = form.querySelector("leu-select")
705
-
706
- let formData = new FormData(form)
707
- expect(formData.get("city")).to.equal("Maur")
708
-
709
- el.defaultValue = ["Zollikon"]
710
- await elementUpdated(el)
711
-
712
- formData = new FormData(form)
713
- expect(formData.get("city")).to.equal("Zollikon")
714
- })
715
-
716
- it("does not override the value when defaultValue changes after interaction", async () => {
717
- const form = await fixture<HTMLFormElement>(html`
718
- <form>
719
- <leu-select name="city" label="Gemeinde">
720
- ${MUNICIPALITIES.map(
721
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
722
- )}
723
- </leu-select>
724
- </form>
725
- `)
726
-
727
- const el = form.querySelector("leu-select")
728
- // Simulate user interaction
729
- const toggleButton =
730
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
731
- toggleButton.click()
732
- const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
733
- (item) => item.textContent === "Maur",
734
- )
735
- menuItem.click()
736
- await elementUpdated(el)
737
-
738
- expect(el.value).to.deep.equal(["Maur"])
739
-
740
- el.defaultValue = ["Zollikon"]
741
- await elementUpdated(el)
742
-
743
- // User interaction has occurred, defaultValue change should NOT override value
744
- expect(el.value).to.deep.equal(["Maur"])
745
- })
746
-
747
- it("is disabled by the form when the fieldset is disabled", async () => {
748
- const form = await fixture<HTMLFormElement>(html`
749
- <form>
750
- <fieldset disabled>
751
- <leu-select name="city" label="Gemeinde">
752
- ${MUNICIPALITIES.map(
753
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
754
- )}
755
- </leu-select>
756
- </fieldset>
757
- </form>
758
- `)
759
-
760
- const el = form.querySelector("leu-select")
761
- await elementUpdated(el)
762
-
763
- expect(el.disabled).to.be.true
764
- })
765
- })
766
-
767
- describe("Validity", () => {
768
- it("is valid by default", async () => {
769
- const el = await defaultFixture({
770
- options: MUNICIPALITIES,
771
- label: "Gemeinde",
772
- })
773
- expect(el.checkValidity()).to.be.true
774
- expect(el.validity.valid).to.be.true
775
- })
776
-
777
- it("is always valid when not required", async () => {
778
- const el = await defaultFixture({
779
- options: MUNICIPALITIES,
780
- label: "Gemeinde",
781
- })
782
- expect(el.checkValidity()).to.be.true
783
-
784
- el.value = []
785
- await elementUpdated(el)
786
- expect(el.checkValidity()).to.be.true
787
- })
788
-
789
- it("is invalid when required and no value is selected", async () => {
790
- const form = await fixture<HTMLFormElement>(html`
791
- <form>
792
- <leu-select name="city" label="Gemeinde" ?required=${true}>
793
- ${MUNICIPALITIES.map(
794
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
795
- )}
796
- </leu-select>
797
- </form>
798
- `)
799
-
800
- const el = form.querySelector<LeuSelect>("leu-select")
801
- await elementUpdated(el)
802
-
803
- expect(el.checkValidity()).to.be.false
804
- expect(el.validity.valueMissing).to.be.true
805
- })
806
-
807
- it("is valid when required and a value is selected", async () => {
808
- const form = await fixture<HTMLFormElement>(html`
809
- <form>
810
- <leu-select name="city" label="Gemeinde" ?required=${true}>
811
- ${MUNICIPALITIES.map(
812
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
813
- )}
814
- </leu-select>
815
- </form>
816
- `)
817
-
818
- const el = form.querySelector<LeuSelect>("leu-select")
819
- el.value = ["Maur"]
820
- await elementUpdated(el)
821
-
822
- expect(el.checkValidity()).to.be.true
823
- expect(el.validity.valid).to.be.true
824
- })
825
-
826
- it("becomes invalid when required is set after a value exists and is then cleared", async () => {
827
- const el = await defaultFixture({
828
- options: MUNICIPALITIES,
829
- label: "Gemeinde",
830
- value: ["Maur"],
831
- })
832
-
833
- el.required = true
834
- await elementUpdated(el)
835
- expect(el.checkValidity()).to.be.true
836
-
837
- el.value = []
838
- await elementUpdated(el)
839
- expect(el.checkValidity()).to.be.false
840
- expect(el.validity.valueMissing).to.be.true
841
- })
842
-
843
- it("becomes valid when a value is selected after being required and empty", async () => {
844
- const form = await fixture<HTMLFormElement>(html`
845
- <form>
846
- <leu-select name="city" label="Gemeinde" ?required=${true}>
847
- ${MUNICIPALITIES.map(
848
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
849
- )}
850
- </leu-select>
851
- </form>
852
- `)
853
-
854
- const el = form.querySelector<LeuSelect>("leu-select")
855
- await elementUpdated(el)
856
- expect(el.checkValidity()).to.be.false
857
-
858
- const toggleButton =
859
- el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
860
- toggleButton.click()
861
- const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
862
- (item) => item.textContent === "Maur",
863
- )
864
- menuItem.click()
865
- await elementUpdated(el)
866
-
867
- expect(el.checkValidity()).to.be.true
868
- })
869
-
870
- it("sets a validation message when required and empty", async () => {
871
- const form = await fixture<HTMLFormElement>(html`
872
- <form>
873
- <leu-select name="city" label="Gemeinde" ?required=${true}>
874
- ${MUNICIPALITIES.map(
875
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
876
- )}
877
- </leu-select>
878
- </form>
879
- `)
880
-
881
- const el = form.querySelector<LeuSelect>("leu-select")
882
- await elementUpdated(el)
883
-
884
- expect(el.validationMessage).to.be.a("string").and.not.be.empty
885
- })
886
-
887
- it("has no validation message when valid", async () => {
888
- const el = await defaultFixture({
889
- options: MUNICIPALITIES,
890
- label: "Gemeinde",
891
- value: ["Maur"],
892
- })
893
- expect(el.validationMessage).to.equal("")
894
- })
895
-
896
- it("willValidate is true when not disabled", async () => {
897
- const el = await defaultFixture({
898
- options: MUNICIPALITIES,
899
- label: "Gemeinde",
900
- })
901
- expect(el.willValidate).to.be.true
902
- })
903
-
904
- it("willValidate is false when disabled", async () => {
905
- const el = await defaultFixture({
906
- options: MUNICIPALITIES,
907
- label: "Gemeinde",
908
- disabled: true,
909
- })
910
- expect(el.willValidate).to.be.false
911
- })
912
-
913
- it("resets validity on form reset", async () => {
914
- const form = await fixture<HTMLFormElement>(html`
915
- <form>
916
- <leu-select name="city" label="Gemeinde" ?required=${true}>
917
- ${MUNICIPALITIES.map(
918
- (o) => html`<leu-menu-item>${o}</leu-menu-item>`,
919
- )}
920
- </leu-select>
921
- </form>
922
- `)
923
-
924
- const el = form.querySelector<LeuSelect>("leu-select")
925
- el.value = ["Maur"]
926
- await elementUpdated(el)
927
- expect(el.checkValidity()).to.be.true
928
-
929
- form.reset()
930
- await elementUpdated(el)
931
-
932
- // After reset value is empty again, so required makes it invalid
933
- expect(el.checkValidity()).to.be.false
934
- expect(el.validity.valueMissing).to.be.true
935
- })
936
- })
937
- })