@statistikzh/leu 0.5.1 → 0.7.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/.husky/commit-msg +0 -3
- package/.husky/pre-commit +0 -3
- package/CHANGELOG.md +54 -0
- package/dist/Accordion.d.ts +10 -9
- package/dist/Accordion.d.ts.map +1 -1
- package/dist/Accordion.js +12 -11
- package/dist/Breadcrumb.d.ts +4 -4
- package/dist/Breadcrumb.d.ts.map +1 -1
- package/dist/Breadcrumb.js +28 -24
- package/dist/{Button-5326c982.d.ts → Button-7370f901.d.ts} +10 -11
- package/dist/Button-7370f901.d.ts.map +1 -0
- package/dist/{Button-5326c982.js → Button-7370f901.js} +57 -67
- package/dist/Button.d.ts +1 -1
- package/dist/Button.js +3 -3
- package/dist/ButtonGroup.d.ts +2 -2
- package/dist/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup.js +3 -3
- package/dist/Checkbox.d.ts +4 -3
- package/dist/Checkbox.d.ts.map +1 -1
- package/dist/Checkbox.js +14 -17
- package/dist/CheckboxGroup.d.ts +2 -2
- package/dist/CheckboxGroup.d.ts.map +1 -1
- package/dist/CheckboxGroup.js +4 -4
- package/dist/Chip.d.ts +2 -2
- package/dist/Chip.d.ts.map +1 -1
- package/dist/Chip.js +23 -28
- package/dist/ChipGroup.d.ts +16 -8
- package/dist/ChipGroup.d.ts.map +1 -1
- package/dist/ChipGroup.js +39 -9
- package/dist/ChipLink.d.ts +2 -1
- package/dist/ChipLink.d.ts.map +1 -1
- package/dist/ChipLink.js +4 -7
- package/dist/ChipRemovable.d.ts +0 -2
- package/dist/ChipRemovable.d.ts.map +1 -1
- package/dist/ChipRemovable.js +8 -11
- package/dist/ChipSelectable.d.ts +12 -2
- package/dist/ChipSelectable.d.ts.map +1 -1
- package/dist/ChipSelectable.js +24 -26
- package/dist/Dropdown.d.ts +9 -5
- package/dist/Dropdown.d.ts.map +1 -1
- package/dist/Dropdown.js +68 -32
- package/dist/Icon.d.ts +116 -0
- package/dist/Icon.d.ts.map +1 -0
- package/dist/{icon-03e86700.js → Icon.js} +61 -32
- package/dist/Input.d.ts +13 -17
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +33 -24
- package/dist/LeuElement-ba5ea33d.d.ts +7 -0
- package/dist/LeuElement-ba5ea33d.d.ts.map +1 -0
- package/dist/{_rollupPluginBabelHelpers-20f659f4.js → LeuElement-ba5ea33d.js} +20 -1
- package/dist/Menu.d.ts +24 -2
- package/dist/Menu.d.ts.map +1 -1
- package/dist/Menu.js +120 -3
- package/dist/MenuItem.d.ts +28 -11
- package/dist/MenuItem.d.ts.map +1 -1
- package/dist/MenuItem.js +110 -63
- package/dist/Pagination.d.ts +10 -3
- package/dist/Pagination.d.ts.map +1 -1
- package/dist/Pagination.js +24 -21
- package/dist/Popup.d.ts +21 -3
- package/dist/Popup.d.ts.map +1 -1
- package/dist/Popup.js +44 -17
- package/dist/Radio.d.ts +4 -2
- package/dist/Radio.d.ts.map +1 -1
- package/dist/Radio.js +9 -14
- package/dist/RadioGroup.d.ts +2 -2
- package/dist/RadioGroup.d.ts.map +1 -1
- package/dist/RadioGroup.js +20 -11
- package/dist/ScrollTop.d.ts +2 -2
- package/dist/ScrollTop.d.ts.map +1 -1
- package/dist/ScrollTop.js +10 -8
- package/dist/Select.d.ts +75 -37
- package/dist/Select.d.ts.map +1 -1
- package/dist/Select.js +279 -181
- package/dist/Table.d.ts +2 -6
- package/dist/Table.d.ts.map +1 -1
- package/dist/Table.js +16 -16
- package/dist/VisuallyHidden.d.ts +2 -2
- package/dist/VisuallyHidden.d.ts.map +1 -1
- package/dist/VisuallyHidden.js +3 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -14
- package/dist/leu-accordion.d.ts.map +1 -1
- package/dist/leu-accordion.js +2 -3
- package/dist/leu-breadcrumb.d.ts.map +1 -1
- package/dist/leu-breadcrumb.js +4 -10
- package/dist/leu-button-group.d.ts.map +1 -1
- package/dist/leu-button-group.js +2 -3
- package/dist/leu-button.d.ts +1 -1
- package/dist/leu-button.d.ts.map +1 -1
- package/dist/leu-button.js +4 -5
- package/dist/leu-checkbox-group.d.ts.map +1 -1
- package/dist/leu-checkbox-group.js +2 -3
- package/dist/leu-checkbox.d.ts.map +1 -1
- package/dist/leu-checkbox.js +3 -4
- package/dist/leu-chip-group.d.ts.map +1 -1
- package/dist/leu-chip-group.js +2 -3
- package/dist/leu-chip-link.d.ts.map +1 -1
- package/dist/leu-chip-link.js +2 -3
- package/dist/leu-chip-removable.d.ts.map +1 -1
- package/dist/leu-chip-removable.js +3 -4
- package/dist/leu-chip-selectable.d.ts.map +1 -1
- package/dist/leu-chip-selectable.js +2 -3
- package/dist/leu-dropdown.d.ts.map +1 -1
- package/dist/leu-dropdown.js +5 -10
- package/dist/leu-icon.d.ts +3 -0
- package/dist/leu-icon.d.ts.map +1 -0
- package/dist/leu-icon.js +7 -0
- package/dist/leu-input.d.ts.map +1 -1
- package/dist/leu-input.js +3 -4
- package/dist/leu-menu-item.d.ts.map +1 -1
- package/dist/leu-menu-item.js +3 -5
- package/dist/leu-menu.d.ts.map +1 -1
- package/dist/leu-menu.js +5 -3
- package/dist/leu-pagination.d.ts.map +1 -1
- package/dist/leu-pagination.js +4 -7
- package/dist/leu-popup.d.ts.map +1 -1
- package/dist/leu-popup.js +2 -3
- package/dist/leu-radio-group.d.ts.map +1 -1
- package/dist/leu-radio-group.js +2 -3
- package/dist/leu-radio.d.ts.map +1 -1
- package/dist/leu-radio.js +2 -3
- package/dist/leu-scroll-top.d.ts.map +1 -1
- package/dist/leu-scroll-top.js +4 -6
- package/dist/leu-select.d.ts.map +1 -1
- package/dist/leu-select.js +5 -13
- package/dist/leu-table.d.ts.map +1 -1
- package/dist/leu-table.js +4 -8
- package/dist/leu-visually-hidden.d.ts.map +1 -1
- package/dist/leu-visually-hidden.js +2 -3
- package/dist/theme.css +2 -0
- package/dist/vscode.html-custom-data.json +124 -74
- package/dist/vue/index.d.ts +83 -67
- package/dist/web-types.json +256 -142
- package/package.json +9 -12
- package/scripts/generate-component/templates/[Name].js +6 -3
- package/scripts/generate-component/templates/test/[name].test.js +1 -1
- package/src/components/accordion/Accordion.js +13 -10
- package/src/components/accordion/leu-accordion.js +1 -2
- package/src/components/breadcrumb/Breadcrumb.js +31 -18
- package/src/components/breadcrumb/leu-breadcrumb.js +1 -2
- package/src/components/button/Button.js +45 -71
- package/src/components/button/button.css +11 -9
- package/src/components/button/leu-button.js +1 -2
- package/src/components/button/stories/button.stories.js +60 -19
- package/src/components/button/test/button.test.js +26 -63
- package/src/components/button-group/ButtonGroup.js +4 -2
- package/src/components/button-group/leu-button-group.js +1 -2
- package/src/components/checkbox/Checkbox.js +17 -11
- package/src/components/checkbox/CheckboxGroup.js +6 -3
- package/src/components/checkbox/leu-checkbox-group.js +1 -2
- package/src/components/checkbox/leu-checkbox.js +1 -2
- package/src/components/checkbox/stories/checkbox-group.stories.js +10 -26
- package/src/components/checkbox/stories/checkbox.stories.js +2 -7
- package/src/components/checkbox/test/checkbox-group.test.js +6 -21
- package/src/components/checkbox/test/checkbox.test.js +1 -12
- package/src/components/chip/Chip.js +5 -4
- package/src/components/chip/ChipGroup.js +38 -8
- package/src/components/chip/ChipLink.js +3 -7
- package/src/components/chip/ChipRemovable.js +8 -11
- package/src/components/chip/ChipSelectable.js +23 -27
- package/src/components/chip/chip.css +19 -20
- package/src/components/chip/leu-chip-group.js +1 -2
- package/src/components/chip/leu-chip-link.js +1 -2
- package/src/components/chip/leu-chip-removable.js +1 -2
- package/src/components/chip/leu-chip-selectable.js +1 -2
- package/src/components/chip/stories/chip-group.stories.js +6 -9
- package/src/components/chip/stories/chip-link.stories.js +3 -5
- package/src/components/chip/stories/chip-removable.stories.js +3 -4
- package/src/components/chip/stories/chip-selectable.stories.js +3 -3
- package/src/components/chip/test/chip-group.test.js +82 -30
- package/src/components/chip/test/chip-link.test.js +2 -6
- package/src/components/chip/test/chip-removable.test.js +4 -10
- package/src/components/chip/test/chip-selectable.test.js +10 -12
- package/src/components/dropdown/Dropdown.js +79 -26
- package/src/components/dropdown/leu-dropdown.js +1 -2
- package/src/components/dropdown/stories/dropdown.stories.js +30 -7
- package/src/components/dropdown/test/dropdown.test.js +5 -5
- package/src/components/icon/Icon.js +55 -0
- package/src/components/icon/icon.css +6 -0
- package/src/components/icon/leu-icon.js +5 -0
- package/src/components/icon/{icon.js → paths.js} +4 -37
- package/src/components/icon/stories/icon.stories.js +47 -0
- package/src/components/icon/test/icon.test.js +23 -40
- package/src/components/input/Input.js +31 -20
- package/src/components/input/input.css +4 -2
- package/src/components/input/leu-input.js +1 -2
- package/src/components/input/stories/input.stories.js +5 -5
- package/src/components/input/test/input.test.js +22 -0
- package/src/components/menu/Menu.js +143 -2
- package/src/components/menu/MenuItem.js +104 -52
- package/src/components/menu/leu-menu-item.js +1 -2
- package/src/components/menu/leu-menu.js +1 -2
- package/src/components/menu/menu-item.css +11 -4
- package/src/components/menu/stories/menu-item.stories.js +15 -4
- package/src/components/menu/stories/menu.stories.js +34 -7
- package/src/components/menu/test/menu-item.test.js +88 -82
- package/src/components/menu/test/menu.test.js +101 -8
- package/src/components/pagination/Pagination.js +27 -18
- package/src/components/pagination/leu-pagination.js +1 -2
- package/src/components/popup/Popup.js +39 -16
- package/src/components/popup/leu-popup.js +1 -2
- package/src/components/popup/popup.css +1 -0
- package/src/components/radio/Radio.js +12 -7
- package/src/components/radio/RadioGroup.js +18 -12
- package/src/components/radio/leu-radio-group.js +1 -2
- package/src/components/radio/leu-radio.js +1 -2
- package/src/components/radio/stories/radio-group.stories.js +5 -19
- package/src/components/radio/stories/radio.stories.js +2 -7
- package/src/components/radio/test/radio-group.test.js +6 -9
- package/src/components/radio/test/radio.test.js +3 -13
- package/src/components/scroll-top/ScrollTop.js +15 -5
- package/src/components/scroll-top/leu-scroll-top.js +1 -2
- package/src/components/select/Select.js +279 -175
- package/src/components/select/leu-select.js +1 -2
- package/src/components/select/select.css +20 -12
- package/src/components/select/stories/select.stories.js +16 -2
- package/src/components/select/test/select.test.js +191 -37
- package/src/components/table/Table.js +15 -9
- package/src/components/table/leu-table.js +1 -2
- package/src/components/table/table.css +3 -1
- package/src/components/visually-hidden/VisuallyHidden.js +6 -2
- package/src/components/visually-hidden/leu-visually-hidden.js +1 -2
- package/src/lib/LeuElement.js +23 -0
- package/src/lib/a11y.js +26 -0
- package/src/styles/custom-properties.css +2 -0
- package/web-test-runner.config.mjs +2 -0
- package/dist/Button-5326c982.d.ts.map +0 -1
- package/dist/_rollupPluginBabelHelpers-20f659f4.d.ts +0 -3
- package/dist/_rollupPluginBabelHelpers-20f659f4.d.ts.map +0 -1
- package/dist/defineElement-40372b4b.d.ts +0 -9
- package/dist/defineElement-40372b4b.d.ts.map +0 -1
- package/dist/defineElement-40372b4b.js +0 -15
- package/dist/icon-03e86700.d.ts +0 -11
- package/dist/icon-03e86700.d.ts.map +0 -1
- package/src/lib/defineElement.js +0 -13
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { html } from "lit"
|
|
2
2
|
import "../leu-menu.js"
|
|
3
3
|
import "../leu-menu-item.js"
|
|
4
|
+
import "../../icon/leu-icon.js"
|
|
5
|
+
import { ifDefined } from "lit/directives/if-defined.js"
|
|
4
6
|
|
|
5
7
|
export default {
|
|
6
8
|
title: "Menu",
|
|
@@ -11,16 +13,41 @@ export default {
|
|
|
11
13
|
url: "https://www.figma.com/file/d6Pv21UVUbnBs3AdcZijHmbN/KTZH-Design-System?type=design&node-id=17340-82208&mode=design&t=lzVrtq8lxYVJU5TB-11",
|
|
12
14
|
},
|
|
13
15
|
},
|
|
16
|
+
argTypes: {
|
|
17
|
+
selects: {
|
|
18
|
+
control: "select",
|
|
19
|
+
options: ["single", "multiple"],
|
|
20
|
+
},
|
|
21
|
+
role: {
|
|
22
|
+
control: "select",
|
|
23
|
+
options: ["menu", "listbox"],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
14
26
|
}
|
|
15
27
|
|
|
16
|
-
function Template() {
|
|
17
|
-
return html` <leu-menu
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
28
|
+
function Template(args) {
|
|
29
|
+
return html` <leu-menu
|
|
30
|
+
role=${ifDefined(args.role)}
|
|
31
|
+
selects=${ifDefined(args.selects)}
|
|
32
|
+
>
|
|
33
|
+
<leu-menu-item
|
|
34
|
+
><leu-icon slot="before"></leu-icon>Menu Item 1</leu-menu-item
|
|
35
|
+
>
|
|
36
|
+
<leu-menu-item active
|
|
37
|
+
><leu-icon slot="before" name="check"></leu-icon>Menu Item
|
|
38
|
+
2</leu-menu-item
|
|
39
|
+
>
|
|
40
|
+
<leu-menu-item
|
|
41
|
+
><leu-icon slot="before"></leu-icon>Menu Item 3</leu-menu-item
|
|
42
|
+
>
|
|
21
43
|
<hr />
|
|
22
|
-
<leu-menu-item
|
|
23
|
-
|
|
44
|
+
<leu-menu-item
|
|
45
|
+
><leu-icon slot="before" name="pin"></leu-icon>Menu Item 3<span
|
|
46
|
+
slot="after"
|
|
47
|
+
>CH</span
|
|
48
|
+
></leu-menu-item
|
|
49
|
+
>
|
|
50
|
+
<leu-menu-item>Menu Item 4</leu-menu-item>
|
|
24
51
|
</leu-menu>`
|
|
25
52
|
}
|
|
26
53
|
|
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
import { html } from "lit"
|
|
2
|
-
import { fixture, expect, oneEvent } from "@open-wc/testing"
|
|
2
|
+
import { fixture, expect, oneEvent, elementUpdated } from "@open-wc/testing"
|
|
3
3
|
import { ifDefined } from "lit/directives/if-defined.js"
|
|
4
4
|
import { spy } from "sinon"
|
|
5
5
|
|
|
6
|
+
import "../leu-menu.js"
|
|
6
7
|
import "../leu-menu-item.js"
|
|
7
8
|
|
|
8
9
|
async function defaultFixture(args = {}) {
|
|
9
10
|
return fixture(html`
|
|
10
11
|
<leu-menu-item
|
|
11
|
-
label=${args.label}
|
|
12
|
-
before=${ifDefined(args.before)}
|
|
13
|
-
after=${ifDefined(args.after)}
|
|
14
12
|
href=${ifDefined(args.href)}
|
|
13
|
+
componentRole=${ifDefined(args.componentRole)}
|
|
14
|
+
value=${ifDefined(args.value)}
|
|
15
15
|
?active=${args.active}
|
|
16
16
|
?disabled=${args.disabled}
|
|
17
|
-
|
|
17
|
+
?tabbable=${args.tabbable}
|
|
18
|
+
>
|
|
19
|
+
${args.label}
|
|
20
|
+
</leu-menu-item>
|
|
21
|
+
`)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function wrappedFixture(args = {}) {
|
|
25
|
+
return fixture(html`
|
|
26
|
+
<leu-menu role=${ifDefined(args.menuRole)}>
|
|
27
|
+
${await defaultFixture(args)}
|
|
28
|
+
</leu-menu>
|
|
18
29
|
`)
|
|
19
30
|
}
|
|
20
31
|
|
|
@@ -26,26 +37,25 @@ describe("LeuMenuItem", () => {
|
|
|
26
37
|
})
|
|
27
38
|
|
|
28
39
|
it("passes the a11y audit", async () => {
|
|
29
|
-
const el = await
|
|
40
|
+
const el = await wrappedFixture({ label: "Download" })
|
|
30
41
|
|
|
31
|
-
await expect(el).
|
|
42
|
+
await expect(el).dom.to.be.accessible()
|
|
32
43
|
})
|
|
33
44
|
|
|
34
45
|
it("passes the a11y audit with a link", async () => {
|
|
35
|
-
const el = await
|
|
46
|
+
const el = await wrappedFixture({
|
|
36
47
|
label: "Download",
|
|
37
48
|
href: "https://zh.ch",
|
|
49
|
+
menuRole: "none",
|
|
38
50
|
})
|
|
39
51
|
|
|
40
|
-
await expect(el).
|
|
52
|
+
await expect(el).dom.to.be.accessible()
|
|
41
53
|
})
|
|
42
54
|
|
|
43
55
|
it("renders a label", async () => {
|
|
44
56
|
const el = await defaultFixture({ label: "Download" })
|
|
45
57
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
expect(button).to.have.trimmed.text("Download")
|
|
58
|
+
expect(el).to.have.trimmed.text("Download")
|
|
49
59
|
})
|
|
50
60
|
|
|
51
61
|
it("renders a button", async () => {
|
|
@@ -66,90 +76,61 @@ describe("LeuMenuItem", () => {
|
|
|
66
76
|
|
|
67
77
|
expect(link).to.exist
|
|
68
78
|
expect(link).to.have.attribute("href", "https://zh.ch")
|
|
69
|
-
expect(
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it("renders a before icon", async () => {
|
|
73
|
-
const el = await defaultFixture({ label: "Download", before: "download" })
|
|
74
|
-
|
|
75
|
-
const before = el.shadowRoot.querySelector(".before")
|
|
76
|
-
expect(before).to.exist
|
|
77
|
-
|
|
78
|
-
expect(el).shadowDom.to.equal(
|
|
79
|
-
"<button class='button'><span class='before'></span><span class='label'>Download</span></button>"
|
|
80
|
-
)
|
|
79
|
+
expect(el).to.have.trimmed.text("Kanton Zürich")
|
|
81
80
|
})
|
|
82
81
|
|
|
83
|
-
it("
|
|
84
|
-
const el = await defaultFixture({ label: "Download",
|
|
85
|
-
|
|
86
|
-
const before = el.shadowRoot.querySelector(".before")
|
|
87
|
-
expect(before).to.exist
|
|
88
|
-
expect(before).to.have.trimmed.text("DE")
|
|
89
|
-
|
|
90
|
-
expect(el).shadowDom.to.equal(
|
|
91
|
-
"<button class='button'><span class='before'>DE</span><span class='label'>Download</span></button>"
|
|
92
|
-
)
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
it("renders a before placeholder", async () => {
|
|
96
|
-
const el = await defaultFixture({ label: "Download", before: "EMPTY" })
|
|
97
|
-
|
|
98
|
-
const before = el.shadowRoot.querySelector(".before")
|
|
99
|
-
expect(before).to.exist
|
|
100
|
-
expect(before).to.not.have.trimmed.text()
|
|
101
|
-
|
|
102
|
-
const iconPlaceholder = before.querySelector(".icon-placeholder")
|
|
103
|
-
expect(iconPlaceholder).to.exist
|
|
104
|
-
|
|
105
|
-
expect(el).shadowDom.to.equal(
|
|
106
|
-
"<button class='button'><span class='before'><div class='icon-placeholder'></div></span><span class='label'>Download</span></button>"
|
|
107
|
-
)
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it("renders a after icon", async () => {
|
|
111
|
-
const el = await defaultFixture({ label: "Download", after: "download" })
|
|
112
|
-
|
|
113
|
-
const after = el.shadowRoot.querySelector(".after")
|
|
114
|
-
expect(after).to.exist
|
|
82
|
+
it("sets the aria-disabled attribute to the button", async () => {
|
|
83
|
+
const el = await defaultFixture({ label: "Download", disabled: true })
|
|
115
84
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
)
|
|
85
|
+
const button = el.shadowRoot.querySelector("button")
|
|
86
|
+
expect(button).to.have.attribute("aria-disabled", "true")
|
|
119
87
|
})
|
|
120
88
|
|
|
121
|
-
it("
|
|
122
|
-
const el = await defaultFixture({
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
expect(after).to.exist
|
|
126
|
-
expect(after).to.have.trimmed.text("DE")
|
|
89
|
+
it("sets the defined role on the button", async () => {
|
|
90
|
+
const el = await defaultFixture({
|
|
91
|
+
label: "Download",
|
|
92
|
+
})
|
|
127
93
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
)
|
|
131
|
-
})
|
|
94
|
+
const button = el.shadowRoot.querySelector("button")
|
|
95
|
+
expect(button).to.have.attribute("role", "menuitem")
|
|
132
96
|
|
|
133
|
-
|
|
134
|
-
|
|
97
|
+
el.componentRole = "menuitemcheckbox"
|
|
98
|
+
await elementUpdated(el)
|
|
99
|
+
expect(button).to.have.attribute("role", "menuitemcheckbox")
|
|
135
100
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
expect(
|
|
101
|
+
el.componentRole = "menuitemradio"
|
|
102
|
+
await elementUpdated(el)
|
|
103
|
+
expect(button).to.have.attribute("role", "menuitemradio")
|
|
139
104
|
|
|
140
|
-
|
|
141
|
-
|
|
105
|
+
el.componentRole = "option"
|
|
106
|
+
await elementUpdated(el)
|
|
107
|
+
expect(button).to.have.attribute("role", "option")
|
|
142
108
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
)
|
|
109
|
+
el.componentRole = "none"
|
|
110
|
+
await elementUpdated(el)
|
|
111
|
+
expect(button).to.not.have.attribute("role")
|
|
146
112
|
})
|
|
147
113
|
|
|
148
|
-
it("
|
|
149
|
-
const el = await defaultFixture({
|
|
114
|
+
it("adds either the aria-checked or aria-selected attribute to the button when the item is active", async () => {
|
|
115
|
+
const el = await defaultFixture({
|
|
116
|
+
label: "Download",
|
|
117
|
+
componentRole: "option",
|
|
118
|
+
active: true,
|
|
119
|
+
})
|
|
150
120
|
|
|
151
121
|
const button = el.shadowRoot.querySelector("button")
|
|
152
|
-
expect(button).to.have.attribute("
|
|
122
|
+
expect(button).to.have.attribute("aria-selected", "true")
|
|
123
|
+
expect(button).not.to.have.attribute("aria-checked")
|
|
124
|
+
|
|
125
|
+
el.componentRole = "menuitemcheckbox"
|
|
126
|
+
await elementUpdated(el)
|
|
127
|
+
expect(button).to.have.attribute("aria-checked", "true")
|
|
128
|
+
expect(button).not.to.have.attribute("aria-selected")
|
|
129
|
+
|
|
130
|
+
el.componentRole = "menuitemradio"
|
|
131
|
+
await elementUpdated(el)
|
|
132
|
+
expect(button).to.have.attribute("aria-checked", "true")
|
|
133
|
+
expect(button).not.to.have.attribute("aria-selected")
|
|
153
134
|
})
|
|
154
135
|
|
|
155
136
|
it("lets the click event bubble up", async () => {
|
|
@@ -177,4 +158,29 @@ describe("LeuMenuItem", () => {
|
|
|
177
158
|
|
|
178
159
|
expect(clickSpy).to.have.not.been.called
|
|
179
160
|
})
|
|
161
|
+
|
|
162
|
+
it("reflects the tabbable property as tabindex to the button", async () => {
|
|
163
|
+
const el = await defaultFixture({ label: "Download", tabbable: true })
|
|
164
|
+
|
|
165
|
+
const button = el.shadowRoot.querySelector("button")
|
|
166
|
+
expect(button).to.have.attribute("tabindex", "0")
|
|
167
|
+
|
|
168
|
+
el.tabbable = false
|
|
169
|
+
await elementUpdated(el)
|
|
170
|
+
expect(button).to.have.attribute("tabindex", "-1")
|
|
171
|
+
|
|
172
|
+
el.tabbable = undefined
|
|
173
|
+
await elementUpdated(el)
|
|
174
|
+
expect(button).to.not.have.attribute("tabindex")
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
it("returns the value or label when getValue is called", async () => {
|
|
178
|
+
const el = await defaultFixture({ label: "Download " })
|
|
179
|
+
|
|
180
|
+
expect(el.getValue()).to.equal("Download")
|
|
181
|
+
|
|
182
|
+
el.value = "download-01"
|
|
183
|
+
|
|
184
|
+
expect(el.getValue()).to.equal("download-01")
|
|
185
|
+
})
|
|
180
186
|
})
|
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
import { html } from "lit"
|
|
2
|
+
import { ifDefined } from "lit/directives/if-defined.js"
|
|
2
3
|
import { fixture, expect } from "@open-wc/testing"
|
|
4
|
+
import { sendKeys } from "@web/test-runner-commands"
|
|
3
5
|
|
|
4
6
|
import "../leu-menu.js"
|
|
5
7
|
import "../leu-menu-item.js"
|
|
8
|
+
import "../../icon/leu-icon.js"
|
|
6
9
|
|
|
7
|
-
async function defaultFixture() {
|
|
8
|
-
return fixture(html` <leu-menu
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
async function defaultFixture(args = {}) {
|
|
11
|
+
return fixture(html` <leu-menu
|
|
12
|
+
role=${ifDefined(args.role)}
|
|
13
|
+
selects=${ifDefined(args.selects)}
|
|
14
|
+
>
|
|
15
|
+
<leu-menu-item
|
|
16
|
+
><leu-icon slot="before"></leu-icon>Menu Item 1</leu-menu-item
|
|
17
|
+
>
|
|
18
|
+
<leu-menu-item active
|
|
19
|
+
><leu-icon slot="before" name="check"></leu-icon>Menu Item
|
|
20
|
+
2</leu-menu-item
|
|
21
|
+
>
|
|
22
|
+
<leu-menu-item
|
|
23
|
+
><leu-icon slot="before"></leu-icon>Menu Item 3</leu-menu-item
|
|
24
|
+
>
|
|
12
25
|
<hr />
|
|
13
|
-
<leu-menu-item
|
|
14
|
-
|
|
26
|
+
<leu-menu-item
|
|
27
|
+
><leu-icon name="pin" slot="before"></leu-icon>Menu Item 3<slot
|
|
28
|
+
name="after"
|
|
29
|
+
>CH</slot
|
|
30
|
+
></leu-menu-item
|
|
31
|
+
>
|
|
32
|
+
<leu-menu-item>Menu Item 4</leu-menu-item>
|
|
15
33
|
</leu-menu>`)
|
|
16
34
|
}
|
|
17
35
|
|
|
@@ -25,6 +43,81 @@ describe("LeuMenu", () => {
|
|
|
25
43
|
it("passes the a11y audit", async () => {
|
|
26
44
|
const el = await defaultFixture()
|
|
27
45
|
|
|
28
|
-
await expect(el).
|
|
46
|
+
await expect(el).dom.to.be.accessible()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it("sets 'menu' as the default role", async () => {
|
|
50
|
+
const el = await defaultFixture()
|
|
51
|
+
|
|
52
|
+
expect(el.getAttribute("role")).to.equal("menu")
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it("sets 'menuitem' as the default role for menu items", async () => {
|
|
56
|
+
const el = await defaultFixture()
|
|
57
|
+
|
|
58
|
+
const menuItems = el.querySelectorAll("leu-menu-item")
|
|
59
|
+
|
|
60
|
+
menuItems.forEach((menuItem) => {
|
|
61
|
+
expect(menuItem.componentRole).to.equal("menuitem")
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it("sets 'menuitemradio' as the role for menu items when only one item can be selected", async () => {
|
|
66
|
+
const el = await defaultFixture({ selects: "single" })
|
|
67
|
+
|
|
68
|
+
const menuItems = el.querySelectorAll("leu-menu-item")
|
|
69
|
+
|
|
70
|
+
menuItems.forEach((menuItem) => {
|
|
71
|
+
expect(menuItem.componentRole).to.equal("menuitemradio")
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it("sets 'menuitemcheckbox' as the role for menu items when multiple items can be selected", async () => {
|
|
76
|
+
const el = await defaultFixture({ selects: "multiple" })
|
|
77
|
+
|
|
78
|
+
const menuItems = el.querySelectorAll("leu-menu-item")
|
|
79
|
+
|
|
80
|
+
menuItems.forEach((menuItem) => {
|
|
81
|
+
expect(menuItem.componentRole).to.equal("menuitemcheckbox")
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it("sets 'option' as the role for menu items when the menu role is 'listbox'", async () => {
|
|
86
|
+
const el = await defaultFixture({ role: "listbox" })
|
|
87
|
+
|
|
88
|
+
const menuItems = el.querySelectorAll("leu-menu-item")
|
|
89
|
+
|
|
90
|
+
menuItems.forEach((menuItem) => {
|
|
91
|
+
expect(menuItem.componentRole).to.equal("option")
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it("moves the focus when the arrow keys are pressed", async () => {
|
|
96
|
+
const el = await defaultFixture()
|
|
97
|
+
|
|
98
|
+
const menuItems = Array.from(el.querySelectorAll("leu-menu-item"))
|
|
99
|
+
|
|
100
|
+
await sendKeys({ press: "Tab" })
|
|
101
|
+
expect(document.activeElement).to.equal(menuItems[0])
|
|
102
|
+
|
|
103
|
+
await sendKeys({ press: "ArrowDown" })
|
|
104
|
+
await sendKeys({ press: "ArrowDown" })
|
|
105
|
+
|
|
106
|
+
expect(document.activeElement).to.equal(menuItems[2])
|
|
107
|
+
|
|
108
|
+
await sendKeys({ press: "ArrowUp" })
|
|
109
|
+
await sendKeys({ press: "ArrowUp" })
|
|
110
|
+
await sendKeys({ press: "ArrowUp" })
|
|
111
|
+
|
|
112
|
+
expect(document.activeElement).to.equal(menuItems.at(-1))
|
|
113
|
+
|
|
114
|
+
await sendKeys({ press: "Home" })
|
|
115
|
+
expect(document.activeElement).to.equal(menuItems[0])
|
|
116
|
+
|
|
117
|
+
await sendKeys({ press: "End" })
|
|
118
|
+
expect(document.activeElement).to.equal(menuItems.at(-1))
|
|
119
|
+
|
|
120
|
+
await sendKeys({ press: "ArrowDown" })
|
|
121
|
+
expect(document.activeElement).to.equal(menuItems[0])
|
|
29
122
|
})
|
|
30
123
|
})
|
|
@@ -1,24 +1,33 @@
|
|
|
1
|
-
import { html
|
|
1
|
+
import { html } from "lit"
|
|
2
2
|
import { live } from "lit/directives/live.js"
|
|
3
3
|
|
|
4
|
-
import "
|
|
5
|
-
import
|
|
4
|
+
import { LeuElement } from "../../lib/LeuElement.js"
|
|
5
|
+
import { LeuButton } from "../button/Button.js"
|
|
6
|
+
import { LeuVisuallyHidden } from "../visually-hidden/VisuallyHidden.js"
|
|
7
|
+
import { LeuIcon } from "../icon/Icon.js"
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
import styles from "./pagination.css"
|
|
8
11
|
|
|
9
12
|
const MIN_PAGE = 1
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* @tagname leu-pagination
|
|
13
16
|
*/
|
|
14
|
-
export class LeuPagination extends
|
|
17
|
+
export class LeuPagination extends LeuElement {
|
|
18
|
+
static dependencies = {
|
|
19
|
+
"leu-button": LeuButton,
|
|
20
|
+
"leu-icon": LeuIcon,
|
|
21
|
+
"leu-visually-hidden": LeuVisuallyHidden,
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
static styles = styles
|
|
16
25
|
|
|
17
26
|
/**
|
|
18
27
|
* @internal
|
|
19
28
|
*/
|
|
20
29
|
static shadowRootOptions = {
|
|
21
|
-
...
|
|
30
|
+
...LeuElement.shadowRootOptions,
|
|
22
31
|
delegatesFocus: true,
|
|
23
32
|
}
|
|
24
33
|
|
|
@@ -26,15 +35,6 @@ export class LeuPagination extends LitElement {
|
|
|
26
35
|
defaultPage: { type: Number, reflect: true },
|
|
27
36
|
itemsPerPage: { type: Number, reflect: true },
|
|
28
37
|
numOfItems: { type: Number, reflect: true },
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Internal page state that contains an
|
|
32
|
-
* already clamped page number. Should only
|
|
33
|
-
* be accessed through the `page` getter and
|
|
34
|
-
* setter.
|
|
35
|
-
* @type {Number}
|
|
36
|
-
* @internal
|
|
37
|
-
*/
|
|
38
38
|
_page: { state: true },
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -43,9 +43,18 @@ export class LeuPagination extends LitElement {
|
|
|
43
43
|
|
|
44
44
|
/** @type {Number} */
|
|
45
45
|
this.numOfItems = 1
|
|
46
|
+
|
|
46
47
|
/** @type {Number} */
|
|
47
48
|
this.itemsPerPage = 1
|
|
48
|
-
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Internal page state that contains an
|
|
52
|
+
* already clamped page number. Should only
|
|
53
|
+
* be accessed through the `page` getter and
|
|
54
|
+
* setter.
|
|
55
|
+
* @type {Number}
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
49
58
|
this._page = 1
|
|
50
59
|
}
|
|
51
60
|
|
|
@@ -148,22 +157,22 @@ export class LeuPagination extends LitElement {
|
|
|
148
157
|
<div class="label">von ${this._maxPage}</div>
|
|
149
158
|
<div class="button-group">
|
|
150
159
|
<leu-button
|
|
151
|
-
icon="angleLeft"
|
|
152
160
|
variant="secondary"
|
|
153
161
|
label="Vorherige Seite"
|
|
154
162
|
@click=${(_) => {
|
|
155
163
|
this._updatePage(this.page - 1)
|
|
156
164
|
}}
|
|
157
165
|
?disabled=${this._isFirstPage()}
|
|
166
|
+
><leu-icon name="angleLeft"></leu-icon
|
|
158
167
|
></leu-button>
|
|
159
168
|
<leu-button
|
|
160
|
-
icon="angleRight"
|
|
161
169
|
variant="secondary"
|
|
162
170
|
label="Nächste Seite"
|
|
163
171
|
@click=${(_) => {
|
|
164
172
|
this._updatePage(this.page + 1)
|
|
165
173
|
}}
|
|
166
174
|
?disabled=${this._isLastPage()}
|
|
175
|
+
><leu-icon name="angleRight"></leu-icon
|
|
167
176
|
></leu-button>
|
|
168
177
|
</div>
|
|
169
178
|
`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { html
|
|
1
|
+
import { html } from "lit"
|
|
2
2
|
import {
|
|
3
3
|
autoUpdate,
|
|
4
4
|
computePosition,
|
|
@@ -6,34 +6,37 @@ import {
|
|
|
6
6
|
shift,
|
|
7
7
|
size,
|
|
8
8
|
} from "@floating-ui/dom"
|
|
9
|
+
|
|
10
|
+
import { LeuElement } from "../../lib/LeuElement.js"
|
|
11
|
+
|
|
12
|
+
// @ts-ignore
|
|
9
13
|
import styles from "./popup.css"
|
|
10
14
|
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {"top"|"top-start"|"top-end"|"bottom"|"bottom-start"|"bottom-end"|"left"|"left-start"|"left-end"|"right"|"right-start"|"right-end"} Placement
|
|
17
|
+
*/
|
|
18
|
+
|
|
11
19
|
/**
|
|
12
20
|
* @tagname leu-popup
|
|
13
21
|
*/
|
|
14
|
-
export class LeuPopup extends
|
|
22
|
+
export class LeuPopup extends LeuElement {
|
|
15
23
|
static styles = styles
|
|
16
24
|
|
|
17
25
|
static shadowRootOptions = {
|
|
18
|
-
...
|
|
26
|
+
...LeuElement.shadowRootOptions,
|
|
19
27
|
delegatesFocus: true,
|
|
20
28
|
}
|
|
21
29
|
|
|
22
30
|
static properties = {
|
|
23
31
|
anchor: {},
|
|
24
|
-
active: { type: Boolean },
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
/** @type {"width" | "height" | "both"} */
|
|
33
|
-
matchSize: { type: String },
|
|
34
|
-
/** @type {"width" | "height" | "both"} */
|
|
35
|
-
autoSize: { type: String },
|
|
36
|
-
autoSizePadding: { type: Number },
|
|
32
|
+
active: { type: Boolean, reflect: true },
|
|
33
|
+
placement: { type: String, reflect: true },
|
|
34
|
+
flip: { type: Boolean, reflect: true },
|
|
35
|
+
shift: { type: Boolean, reflect: true },
|
|
36
|
+
shiftPadding: { type: Number, reflect: true },
|
|
37
|
+
matchSize: { type: String, reflect: true },
|
|
38
|
+
autoSize: { type: String, reflect: true },
|
|
39
|
+
autoSizePadding: { type: Number, reflect: true },
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
constructor() {
|
|
@@ -43,6 +46,23 @@ export class LeuPopup extends LitElement {
|
|
|
43
46
|
this.cleanup = undefined
|
|
44
47
|
this.flip = false
|
|
45
48
|
this.shift = false
|
|
49
|
+
|
|
50
|
+
this.active = false
|
|
51
|
+
|
|
52
|
+
/** @type {Placement} */
|
|
53
|
+
this.placement = undefined
|
|
54
|
+
|
|
55
|
+
/** @type {"width" | "height" | "both"} */
|
|
56
|
+
this.matchSize = undefined
|
|
57
|
+
|
|
58
|
+
/** @type {"width" | "height" | "both"} */
|
|
59
|
+
this.autoSize = undefined
|
|
60
|
+
|
|
61
|
+
this.shiftPadding = 0
|
|
62
|
+
this.autoSizePadding = 0
|
|
63
|
+
|
|
64
|
+
/** @type {string | HTMLElement} */
|
|
65
|
+
this.anchor = undefined
|
|
46
66
|
}
|
|
47
67
|
|
|
48
68
|
disconnectedCallback() {
|
|
@@ -68,6 +88,9 @@ export class LeuPopup extends LitElement {
|
|
|
68
88
|
}
|
|
69
89
|
}
|
|
70
90
|
|
|
91
|
+
/**
|
|
92
|
+
* @returns {HTMLElement | null}
|
|
93
|
+
*/
|
|
71
94
|
get popupEl() {
|
|
72
95
|
return this.renderRoot?.querySelector(".popup") ?? null
|
|
73
96
|
}
|