@statistikzh/leu 0.25.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +28 -0
- package/CONTRIBUTING.md +19 -8
- package/dist/{Accordion-CDNyrB8d.js → Accordion-DLsqXcK8.js} +1 -1
- package/dist/Accordion.js +2 -2
- package/dist/{Button-EdS9xr2J.js → Button-BSyDL_cV.js} +57 -17
- package/dist/{Button-DSGPIcjm.d.ts → Button-BgNUxmo_.d.ts} +6 -0
- package/dist/Button.d.ts +1 -1
- package/dist/Button.js +5 -4
- package/dist/{ButtonGroup-BQqf8o_d.js → ButtonGroup-BmSvl-Oc.js} +2 -2
- package/dist/ButtonGroup.js +6 -5
- package/dist/{ChartWrapper-LiNHTNRw.js → ChartWrapper-CvDvQsd5.js} +3 -3
- package/dist/ChartWrapper.d.ts +2 -2
- package/dist/ChartWrapper.js +3 -3
- package/dist/{Checkbox-BtDWmPab.js → Checkbox-Cl_X6gBJ.js} +3 -3
- package/dist/Checkbox.js +4 -4
- package/dist/{CheckboxGroup-C8MbwW9u.js → CheckboxGroup-BKhOmZYX.js} +2 -2
- package/dist/CheckboxGroup.js +5 -5
- package/dist/{Chip-Ch09jjYi.js → Chip-McVP3N_x.js} +1 -1
- package/dist/Chip.js +2 -2
- package/dist/{ChipGroup-PvqVW-tm.js → ChipGroup-DUGavZeU.js} +1 -1
- package/dist/ChipGroup.js +3 -3
- package/dist/ChipLink.js +2 -2
- package/dist/ChipRemovable.js +3 -3
- package/dist/ChipSelectable.js +2 -2
- package/dist/{Dialog-CV1JTkCn.js → Dialog-BlDd4T2u.js} +3 -3
- package/dist/Dialog.d.ts +1 -1
- package/dist/Dialog.js +3 -3
- package/dist/{Dropdown-DpFdFbA1.js → Dropdown-BLxSIe6p.js} +6 -6
- package/dist/Dropdown.d.ts +2 -2
- package/dist/Dropdown.js +9 -8
- package/dist/{FileInput-5apX17JT.js → FileInput-DntYrpZ-.js} +23 -8
- package/dist/FileInput.d.ts +12 -1
- package/dist/FileInput.js +7 -6
- package/dist/{Icon-DhAvH0XM.js → Icon-CbZXpyHU.js} +1 -1
- package/dist/Icon.js +2 -2
- package/dist/{Input-D2THgo7c.d.ts → Input-CeaAOB4p.d.ts} +6 -2
- package/dist/{Input-CnEz-2dK.js → Input-DBXX7ev8.js} +33 -12
- package/dist/Input.d.ts +1 -1
- package/dist/Input.js +4 -4
- package/dist/{LeuElement-B7NJzWwP.js → LeuElement-k4RjIeoG.js} +1 -1
- package/dist/{Menu-DpiheIPk.js → Menu-Cu8eIF1T.js} +2 -2
- package/dist/Menu.js +4 -4
- package/dist/{MenuItem-CZTqGg5R.js → MenuItem-Cs3KFhJm.js} +2 -2
- package/dist/MenuItem.js +3 -3
- package/dist/{Message-J4Kj7yHE.js → Message-C6Zlk_2p.js} +3 -3
- package/dist/Message.js +3 -3
- package/dist/{Pagination-CWqgusWZ.js → Pagination-CB2eVlXk.js} +4 -4
- package/dist/{Pagination-Be8TcBoC.d.ts → Pagination-CqkHh-Vd.d.ts} +1 -1
- package/dist/Pagination.d.ts +1 -1
- package/dist/Pagination.js +7 -6
- package/dist/{Placeholder-DMN6sMbp.js → Placeholder-DHMexMhK.js} +1 -1
- package/dist/Placeholder.js +2 -2
- package/dist/{Popup-JQjuj26v.js → Popup-8jhVy8gB.js} +1 -1
- package/dist/Popup.js +2 -2
- package/dist/{ProgressBar-CzN3fqiH.js → ProgressBar-CG0_lHfS.js} +1 -1
- package/dist/ProgressBar.js +2 -2
- package/dist/{Radio-CX8aCsff.js → Radio-DG3xqP3s.js} +1 -1
- package/dist/Radio.js +2 -2
- package/dist/{RadioGroup-CgEWQnC4.js → RadioGroup-BKCp9ICX.js} +2 -2
- package/dist/RadioGroup.js +3 -3
- package/dist/{Range-DoW_ZdKm.js → Range-7LrESv4K.js} +1 -1
- package/dist/Range.js +2 -2
- package/dist/{ScrollTop-DxChetWq.js → ScrollTop-CJJsfniA.js} +20 -20
- package/dist/ScrollTop.d.ts +6 -6
- package/dist/ScrollTop.js +6 -5
- package/dist/{Select-BCx79gOH.js → Select-CxEDXIBn.js} +154 -134
- package/dist/Select.d.ts +75 -73
- package/dist/Select.js +10 -9
- package/dist/{Spinner-DJR4gv3Y.js → Spinner-VhKfzI3Q.js} +1 -1
- package/dist/Spinner.d.ts +1 -1
- package/dist/Spinner.js +2 -2
- package/dist/{Table-DZz1ic3j.js → Table-rg_JCtsA.js} +3 -3
- package/dist/Table.d.ts +1 -1
- package/dist/Table.js +8 -7
- package/dist/{Tag-DsZS_8pl.js → Tag-BROUaDAZ.js} +1 -1
- package/dist/Tag.js +2 -2
- package/dist/{VisuallyHidden-BkllVjlz.js → VisuallyHidden-Co_txzxB.js} +1 -1
- package/dist/VisuallyHidden.js +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +31 -31
- package/dist/leu-accordion.js +2 -2
- package/dist/leu-button-group.js +6 -5
- package/dist/leu-button.d.ts +1 -1
- package/dist/leu-button.js +5 -4
- package/dist/leu-chart-wrapper.js +3 -3
- package/dist/leu-checkbox-group.js +5 -5
- package/dist/leu-checkbox.js +4 -4
- package/dist/leu-chip-group.js +3 -3
- package/dist/leu-chip-link.js +2 -2
- package/dist/leu-chip-removable.js +3 -3
- package/dist/leu-chip-selectable.js +2 -2
- package/dist/leu-dialog.js +3 -3
- package/dist/leu-dropdown.js +9 -8
- package/dist/leu-file-input.js +7 -6
- package/dist/leu-icon.js +2 -2
- package/dist/leu-input.d.ts +1 -1
- package/dist/leu-input.js +4 -4
- package/dist/leu-menu-item.js +3 -3
- package/dist/leu-menu.js +4 -4
- package/dist/leu-message.js +3 -3
- package/dist/leu-pagination.d.ts +1 -1
- package/dist/leu-pagination.js +7 -6
- package/dist/leu-placeholder.js +2 -2
- package/dist/leu-popup.js +2 -2
- package/dist/leu-progress-bar.js +2 -2
- package/dist/leu-radio-group.js +3 -3
- package/dist/leu-radio.js +2 -2
- package/dist/leu-range.js +2 -2
- package/dist/leu-scroll-top.js +6 -5
- package/dist/leu-select.js +10 -9
- package/dist/leu-spinner.d.ts +1 -1
- package/dist/leu-spinner.js +2 -2
- package/dist/leu-table.js +8 -7
- package/dist/leu-tag.js +2 -2
- package/dist/leu-visually-hidden.js +2 -2
- package/dist/vscode.html-custom-data.json +19 -27
- package/dist/vue/index.d.ts +18 -24
- package/dist/web-types.json +51 -60
- package/package.json +1 -1
- package/src/components/button/Button.ts +15 -3
- package/src/components/button/button.css +37 -9
- package/src/components/button/stories/button.stories.ts +23 -0
- package/src/components/button/test/button.test.ts +30 -3
- package/src/components/file-input/FileInput.ts +24 -5
- package/src/components/input/Input.ts +43 -8
- package/src/components/input/test/input.test.ts +106 -1
- package/src/components/scroll-top/ScrollTop.ts +18 -16
- package/src/components/select/Select.ts +198 -124
- package/src/components/select/select.css +4 -0
- package/src/components/select/stories/select.stories.ts +10 -0
- package/src/components/select/test/select.test.ts +440 -35
- /package/dist/{FormAssociatedMixin-BbFlza53.js → FormAssociatedMixin-DLPvFtbT.js} +0 -0
- /package/dist/{Spinner-CMo_o6Fy.d.ts → Spinner-CrM1enM0.d.ts} +0 -0
- /package/dist/{hasSlotController-DjdfnOQp.js → hasSlotController-DSBCVzPD.js} +0 -0
- /package/dist/{hasSlotController-BLtZurRh.d.ts → hasSlotController-DWPyZ52b.d.ts} +0 -0
|
@@ -3,30 +3,45 @@ import { ifDefined } from "lit/directives/if-defined.js"
|
|
|
3
3
|
import { fixture, expect, elementUpdated } from "@open-wc/testing"
|
|
4
4
|
import { sendKeys } from "@web/test-runner-commands"
|
|
5
5
|
|
|
6
|
+
import type { LeuSelect } from "../Select.js"
|
|
6
7
|
import "../leu-select.js"
|
|
7
8
|
import "../../menu/leu-menu-item.js"
|
|
8
9
|
import { MUNICIPALITIES } from "./fixtures.js"
|
|
9
10
|
|
|
10
|
-
async function defaultFixture(
|
|
11
|
-
|
|
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>(
|
|
12
23
|
html`<leu-select
|
|
13
24
|
label=${ifDefined(args.label)}
|
|
14
|
-
|
|
15
|
-
?clearable=${args.clearable}
|
|
16
|
-
?disabled=${args.disabled}
|
|
17
|
-
?filterable=${args.filterable}
|
|
18
|
-
?multiple=${args.multiple}
|
|
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}
|
|
19
30
|
>
|
|
20
|
-
${args.options.map(
|
|
31
|
+
${(args.options ?? []).map(
|
|
32
|
+
(o) => html`<leu-menu-item>${o}</leu-menu-item>`,
|
|
33
|
+
)}
|
|
21
34
|
</leu-select> `,
|
|
22
35
|
)
|
|
36
|
+
|
|
37
|
+
return el
|
|
23
38
|
}
|
|
24
39
|
|
|
25
40
|
describe("LeuSelect", () => {
|
|
26
41
|
it("is a defined element", async () => {
|
|
27
42
|
const el = customElements.get("leu-select")
|
|
28
43
|
|
|
29
|
-
|
|
44
|
+
expect(el).not.to.be.undefined
|
|
30
45
|
})
|
|
31
46
|
|
|
32
47
|
it("passes the a11y audit", async () => {
|
|
@@ -42,9 +57,11 @@ describe("LeuSelect", () => {
|
|
|
42
57
|
const el = await defaultFixture({
|
|
43
58
|
options: MUNICIPALITIES,
|
|
44
59
|
label: "Gemeinde",
|
|
45
|
-
open: true,
|
|
46
60
|
})
|
|
47
61
|
|
|
62
|
+
el.click()
|
|
63
|
+
await elementUpdated(el)
|
|
64
|
+
|
|
48
65
|
await expect(el).shadowDom.to.be.accessible()
|
|
49
66
|
})
|
|
50
67
|
|
|
@@ -65,7 +82,8 @@ describe("LeuSelect", () => {
|
|
|
65
82
|
label: "Gemeinde",
|
|
66
83
|
})
|
|
67
84
|
|
|
68
|
-
const toggleButton =
|
|
85
|
+
const toggleButton =
|
|
86
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
69
87
|
|
|
70
88
|
expect(toggleButton).to.have.trimmed.text("Gemeinde")
|
|
71
89
|
})
|
|
@@ -86,7 +104,8 @@ describe("LeuSelect", () => {
|
|
|
86
104
|
label: "Gemeinde",
|
|
87
105
|
})
|
|
88
106
|
|
|
89
|
-
const toggleButton =
|
|
107
|
+
const toggleButton =
|
|
108
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
90
109
|
toggleButton.click()
|
|
91
110
|
|
|
92
111
|
const popup = el.shadowRoot.querySelector("leu-popup")
|
|
@@ -184,7 +203,8 @@ describe("LeuSelect", () => {
|
|
|
184
203
|
filterable: true,
|
|
185
204
|
})
|
|
186
205
|
|
|
187
|
-
const filterInput =
|
|
206
|
+
const filterInput =
|
|
207
|
+
el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
|
|
188
208
|
|
|
189
209
|
expect(filterInput).to.exist
|
|
190
210
|
})
|
|
@@ -196,10 +216,12 @@ describe("LeuSelect", () => {
|
|
|
196
216
|
filterable: true,
|
|
197
217
|
})
|
|
198
218
|
|
|
199
|
-
const toggleButton =
|
|
219
|
+
const toggleButton =
|
|
220
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
200
221
|
toggleButton.click()
|
|
201
222
|
|
|
202
|
-
const filterInput =
|
|
223
|
+
const filterInput =
|
|
224
|
+
el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
|
|
203
225
|
filterInput.focus()
|
|
204
226
|
|
|
205
227
|
await sendKeys({ type: "am albis" })
|
|
@@ -218,16 +240,18 @@ describe("LeuSelect", () => {
|
|
|
218
240
|
filterable: true,
|
|
219
241
|
})
|
|
220
242
|
|
|
221
|
-
const toggleButton =
|
|
243
|
+
const toggleButton =
|
|
244
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
222
245
|
toggleButton.click()
|
|
223
246
|
|
|
224
|
-
const filterInput =
|
|
247
|
+
const filterInput =
|
|
248
|
+
el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
|
|
225
249
|
filterInput.focus()
|
|
226
250
|
|
|
227
251
|
await sendKeys({ type: "am albis" })
|
|
228
252
|
|
|
229
253
|
const clearFilterButton =
|
|
230
|
-
filterInput.shadowRoot.querySelector(".clear-button")
|
|
254
|
+
filterInput.shadowRoot.querySelector<HTMLButtonElement>(".clear-button")
|
|
231
255
|
clearFilterButton.click()
|
|
232
256
|
await elementUpdated(el)
|
|
233
257
|
|
|
@@ -246,10 +270,12 @@ describe("LeuSelect", () => {
|
|
|
246
270
|
filterable: true,
|
|
247
271
|
})
|
|
248
272
|
|
|
249
|
-
const toggleButton =
|
|
273
|
+
const toggleButton =
|
|
274
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
250
275
|
toggleButton.click()
|
|
251
276
|
|
|
252
|
-
const filterInput =
|
|
277
|
+
const filterInput =
|
|
278
|
+
el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
|
|
253
279
|
filterInput.focus()
|
|
254
280
|
|
|
255
281
|
await sendKeys({ type: "am albissss" })
|
|
@@ -268,7 +294,8 @@ describe("LeuSelect", () => {
|
|
|
268
294
|
filterable: true,
|
|
269
295
|
})
|
|
270
296
|
|
|
271
|
-
const toggleButton =
|
|
297
|
+
const toggleButton =
|
|
298
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
272
299
|
toggleButton.click()
|
|
273
300
|
|
|
274
301
|
const emptyMessage = el.shadowRoot.querySelector(".filter-message-empty")
|
|
@@ -283,10 +310,12 @@ describe("LeuSelect", () => {
|
|
|
283
310
|
filterable: true,
|
|
284
311
|
})
|
|
285
312
|
|
|
286
|
-
const toggleButton =
|
|
313
|
+
const toggleButton =
|
|
314
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
287
315
|
toggleButton.click()
|
|
288
316
|
|
|
289
|
-
const filterInput =
|
|
317
|
+
const filterInput =
|
|
318
|
+
el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
|
|
290
319
|
filterInput.focus()
|
|
291
320
|
|
|
292
321
|
await sendKeys({ type: "am albis" })
|
|
@@ -335,7 +364,8 @@ describe("LeuSelect", () => {
|
|
|
335
364
|
multiple: true,
|
|
336
365
|
})
|
|
337
366
|
|
|
338
|
-
const toggleButton =
|
|
367
|
+
const toggleButton =
|
|
368
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
339
369
|
toggleButton.click()
|
|
340
370
|
|
|
341
371
|
const applyButton = el.shadowRoot.querySelector(".apply-button")
|
|
@@ -351,7 +381,8 @@ describe("LeuSelect", () => {
|
|
|
351
381
|
label: "Gemeinde",
|
|
352
382
|
})
|
|
353
383
|
|
|
354
|
-
const toggleButton =
|
|
384
|
+
const toggleButton =
|
|
385
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
355
386
|
toggleButton.click()
|
|
356
387
|
|
|
357
388
|
const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
|
|
@@ -368,7 +399,8 @@ describe("LeuSelect", () => {
|
|
|
368
399
|
label: "Gemeinde",
|
|
369
400
|
value: ["Maur"],
|
|
370
401
|
})
|
|
371
|
-
const toggleButton =
|
|
402
|
+
const toggleButton =
|
|
403
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
372
404
|
toggleButton.click()
|
|
373
405
|
|
|
374
406
|
const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
|
|
@@ -386,7 +418,8 @@ describe("LeuSelect", () => {
|
|
|
386
418
|
value: ["Maur"],
|
|
387
419
|
clearable: true,
|
|
388
420
|
})
|
|
389
|
-
const toggleButton =
|
|
421
|
+
const toggleButton =
|
|
422
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
390
423
|
toggleButton.click()
|
|
391
424
|
|
|
392
425
|
const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
|
|
@@ -404,7 +437,8 @@ describe("LeuSelect", () => {
|
|
|
404
437
|
multiple: true,
|
|
405
438
|
})
|
|
406
439
|
|
|
407
|
-
const toggleButton =
|
|
440
|
+
const toggleButton =
|
|
441
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
408
442
|
toggleButton.click()
|
|
409
443
|
|
|
410
444
|
const menuItems = Array.from(el.querySelectorAll("leu-menu-item"))
|
|
@@ -421,7 +455,8 @@ describe("LeuSelect", () => {
|
|
|
421
455
|
label: "Gemeinde",
|
|
422
456
|
})
|
|
423
457
|
|
|
424
|
-
const toggleButton =
|
|
458
|
+
const toggleButton =
|
|
459
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
425
460
|
toggleButton.click()
|
|
426
461
|
|
|
427
462
|
const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
|
|
@@ -440,7 +475,8 @@ describe("LeuSelect", () => {
|
|
|
440
475
|
multiple: true,
|
|
441
476
|
})
|
|
442
477
|
|
|
443
|
-
const toggleButton =
|
|
478
|
+
const toggleButton =
|
|
479
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
444
480
|
toggleButton.click()
|
|
445
481
|
|
|
446
482
|
const menuItem = Array.from(el.querySelectorAll("leu-menu-item")).find(
|
|
@@ -459,12 +495,14 @@ describe("LeuSelect", () => {
|
|
|
459
495
|
filterable: true,
|
|
460
496
|
})
|
|
461
497
|
|
|
462
|
-
const toggleButton =
|
|
498
|
+
const toggleButton =
|
|
499
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
463
500
|
toggleButton.click()
|
|
464
501
|
|
|
465
502
|
await elementUpdated(el)
|
|
466
503
|
|
|
467
|
-
const filterInput =
|
|
504
|
+
const filterInput =
|
|
505
|
+
el.shadowRoot.querySelector<HTMLInputElement>(".select-search")
|
|
468
506
|
expect(filterInput).to.equal(el.shadowRoot.activeElement)
|
|
469
507
|
})
|
|
470
508
|
|
|
@@ -474,7 +512,8 @@ describe("LeuSelect", () => {
|
|
|
474
512
|
label: "Gemeinde",
|
|
475
513
|
})
|
|
476
514
|
|
|
477
|
-
const toggleButton =
|
|
515
|
+
const toggleButton =
|
|
516
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
478
517
|
toggleButton.click()
|
|
479
518
|
|
|
480
519
|
await elementUpdated(el)
|
|
@@ -490,7 +529,8 @@ describe("LeuSelect", () => {
|
|
|
490
529
|
label: "Gemeinde",
|
|
491
530
|
})
|
|
492
531
|
|
|
493
|
-
const toggleButton =
|
|
532
|
+
const toggleButton =
|
|
533
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
494
534
|
toggleButton.click()
|
|
495
535
|
|
|
496
536
|
await sendKeys({ press: "Escape" })
|
|
@@ -521,7 +561,8 @@ describe("LeuSelect", () => {
|
|
|
521
561
|
label: "Gemeinde",
|
|
522
562
|
})
|
|
523
563
|
|
|
524
|
-
const toggleButton =
|
|
564
|
+
const toggleButton =
|
|
565
|
+
el.shadowRoot.querySelector<HTMLButtonElement>(".select-toggle")
|
|
525
566
|
toggleButton.click()
|
|
526
567
|
|
|
527
568
|
document.body.click()
|
|
@@ -529,4 +570,368 @@ describe("LeuSelect", () => {
|
|
|
529
570
|
const popup = el.shadowRoot.querySelector("leu-popup")
|
|
530
571
|
expect(popup.active).to.not.be.true
|
|
531
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
|
+
})
|
|
532
937
|
})
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|