@statistikzh/leu 0.3.0 → 0.5.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/.github/workflows/deploy-github-pages.yaml +33 -0
- package/.storybook/main.js +27 -1
- package/.storybook/manager-head.html +1 -0
- package/.storybook/manager.js +9 -0
- package/.storybook/preview-head.html +1 -1
- package/.storybook/preview.js +59 -6
- package/.storybook/static/logo.svg +19 -0
- package/.storybook/theme.js +7 -0
- package/CHANGELOG.md +54 -0
- package/README.md +1 -1
- package/custom-elements-manifest.config.js +46 -0
- package/dist/Accordion.d.ts +31 -0
- package/dist/Accordion.d.ts.map +1 -0
- package/dist/Accordion.js +257 -0
- package/dist/Breadcrumb.d.ts +69 -0
- package/dist/Breadcrumb.d.ts.map +1 -0
- package/dist/Breadcrumb.js +392 -0
- package/dist/Button-da11d064.d.ts +84 -0
- package/dist/Button-da11d064.d.ts.map +1 -0
- package/dist/Button-da11d064.js +542 -0
- package/dist/Button.d.ts +2 -0
- package/dist/Button.d.ts.map +1 -0
- package/dist/Button.js +6 -423
- package/dist/ButtonGroup.d.ts +24 -0
- package/dist/ButtonGroup.d.ts.map +1 -0
- package/dist/ButtonGroup.js +72 -43
- package/dist/Checkbox.d.ts +13 -0
- package/dist/Checkbox.d.ts.map +1 -0
- package/dist/Checkbox.js +101 -84
- package/dist/CheckboxGroup.d.ts +13 -0
- package/dist/CheckboxGroup.d.ts.map +1 -0
- package/dist/CheckboxGroup.js +41 -37
- package/dist/Chip.d.ts +5 -0
- package/dist/Chip.d.ts.map +1 -0
- package/dist/{Chip-5f70d04f.js → Chip.js} +21 -6
- package/dist/ChipGroup.d.ts +28 -0
- package/dist/ChipGroup.d.ts.map +1 -0
- package/dist/ChipGroup.js +64 -10
- package/dist/ChipLink.d.ts +15 -0
- package/dist/ChipLink.d.ts.map +1 -0
- package/dist/ChipLink.js +4 -7
- package/dist/ChipRemovable.d.ts +13 -0
- package/dist/ChipRemovable.d.ts.map +1 -0
- package/dist/ChipRemovable.js +5 -8
- package/dist/ChipSelectable.d.ts +22 -0
- package/dist/ChipSelectable.d.ts.map +1 -0
- package/dist/ChipSelectable.js +8 -11
- package/dist/Dropdown.d.ts +15 -0
- package/dist/Dropdown.d.ts.map +1 -0
- package/dist/Dropdown.js +73 -26
- package/dist/Input.d.ts +154 -0
- package/dist/Input.d.ts.map +1 -0
- package/dist/Input.js +42 -35
- package/dist/Menu.d.ts +8 -0
- package/dist/Menu.d.ts.map +1 -0
- package/dist/Menu.js +2 -5
- package/dist/MenuItem.d.ts +21 -0
- package/dist/MenuItem.d.ts.map +1 -0
- package/dist/MenuItem.js +32 -17
- package/dist/Pagination.d.ts +27 -0
- package/dist/Pagination.d.ts.map +1 -0
- package/dist/Pagination.js +121 -89
- package/dist/Popup.d.ts +18 -0
- package/dist/Popup.d.ts.map +1 -0
- package/dist/Popup.js +215 -0
- package/dist/Radio.d.ts +12 -0
- package/dist/Radio.d.ts.map +1 -0
- package/dist/Radio.js +9 -8
- package/dist/RadioGroup.d.ts +20 -0
- package/dist/RadioGroup.d.ts.map +1 -0
- package/dist/RadioGroup.js +41 -39
- package/dist/ScrollTop.d.ts +19 -0
- package/dist/ScrollTop.d.ts.map +1 -0
- package/dist/ScrollTop.js +122 -0
- package/dist/Select.d.ts +98 -0
- package/dist/Select.d.ts.map +1 -0
- package/dist/Select.js +79 -122
- package/dist/Table.d.ts +48 -0
- package/dist/Table.d.ts.map +1 -0
- package/dist/Table.js +141 -121
- package/dist/VisuallyHidden.d.ts +8 -0
- package/dist/VisuallyHidden.d.ts.map +1 -0
- package/dist/VisuallyHidden.js +28 -0
- package/dist/_rollupPluginBabelHelpers-20f659f4.d.ts +3 -0
- package/dist/_rollupPluginBabelHelpers-20f659f4.d.ts.map +1 -0
- package/dist/{defineElement-ba770aed.js → _rollupPluginBabelHelpers-20f659f4.js} +1 -15
- package/dist/defineElement-40372b4b.d.ts +9 -0
- package/dist/defineElement-40372b4b.d.ts.map +1 -0
- package/dist/defineElement-40372b4b.js +15 -0
- package/dist/icon-03e86700.d.ts +11 -0
- package/dist/icon-03e86700.d.ts.map +1 -0
- package/dist/index.js.d.ts +21 -0
- package/dist/index.js.d.ts.map +1 -0
- package/dist/index.js.js +42 -0
- package/dist/leu-accordion.d.ts +3 -0
- package/dist/leu-accordion.d.ts.map +1 -0
- package/dist/leu-accordion.js +9 -0
- package/dist/leu-breadcrumb.d.ts +3 -0
- package/dist/leu-breadcrumb.d.ts.map +1 -0
- package/dist/leu-breadcrumb.js +23 -0
- package/dist/leu-button-group.d.ts +3 -0
- package/dist/leu-button-group.d.ts.map +1 -0
- package/dist/leu-button-group.js +6 -6
- package/dist/leu-button.d.ts +3 -0
- package/dist/leu-button.d.ts.map +1 -0
- package/dist/leu-button.js +7 -3
- package/dist/leu-checkbox-group.d.ts +3 -0
- package/dist/leu-checkbox-group.d.ts.map +1 -0
- package/dist/leu-checkbox-group.js +6 -3
- package/dist/leu-checkbox.d.ts +3 -0
- package/dist/leu-checkbox.d.ts.map +1 -0
- package/dist/leu-checkbox.js +6 -3
- package/dist/leu-chip-group.d.ts +3 -0
- package/dist/leu-chip-group.d.ts.map +1 -0
- package/dist/leu-chip-group.js +7 -3
- package/dist/leu-chip-link.d.ts +3 -0
- package/dist/leu-chip-link.d.ts.map +1 -0
- package/dist/leu-chip-link.js +7 -4
- package/dist/leu-chip-removable.d.ts +3 -0
- package/dist/leu-chip-removable.d.ts.map +1 -0
- package/dist/leu-chip-removable.js +7 -4
- package/dist/leu-chip-selectable.d.ts +3 -0
- package/dist/leu-chip-selectable.d.ts.map +1 -0
- package/dist/leu-chip-selectable.js +7 -4
- package/dist/leu-dropdown.d.ts +3 -0
- package/dist/leu-dropdown.d.ts.map +1 -0
- package/dist/leu-dropdown.js +15 -4
- package/dist/leu-input.d.ts +3 -0
- package/dist/leu-input.d.ts.map +1 -0
- package/dist/leu-input.js +7 -3
- package/dist/leu-menu-item.d.ts +3 -0
- package/dist/leu-menu-item.d.ts.map +1 -0
- package/dist/leu-menu-item.js +8 -3
- package/dist/leu-menu.d.ts +3 -0
- package/dist/leu-menu.d.ts.map +1 -0
- package/dist/leu-menu.js +6 -3
- package/dist/leu-pagination.d.ts +3 -0
- package/dist/leu-pagination.d.ts.map +1 -0
- package/dist/leu-pagination.js +12 -4
- package/dist/leu-popup.d.ts +3 -0
- package/dist/leu-popup.d.ts.map +1 -0
- package/dist/leu-popup.js +9 -0
- package/dist/leu-radio-group.d.ts +3 -0
- package/dist/leu-radio-group.d.ts.map +1 -0
- package/dist/leu-radio-group.js +6 -3
- package/dist/leu-radio.d.ts +3 -0
- package/dist/leu-radio.d.ts.map +1 -0
- package/dist/leu-radio.js +6 -3
- package/dist/leu-scroll-top.d.ts +3 -0
- package/dist/leu-scroll-top.d.ts.map +1 -0
- package/dist/leu-scroll-top.js +14 -0
- package/dist/leu-select.d.ts +3 -0
- package/dist/leu-select.d.ts.map +1 -0
- package/dist/leu-select.js +16 -4
- package/dist/leu-table.d.ts +3 -0
- package/dist/leu-table.d.ts.map +1 -0
- package/dist/leu-table.js +13 -4
- package/dist/leu-visually-hidden.d.ts +3 -0
- package/dist/leu-visually-hidden.d.ts.map +1 -0
- package/dist/leu-visually-hidden.js +8 -0
- package/dist/theme.css +386 -2
- package/dist/utils-65469421.d.ts +16 -0
- package/dist/utils-65469421.d.ts.map +1 -0
- package/dist/utils-65469421.js +35 -0
- package/index.js +3 -0
- package/package.json +47 -17
- package/postcss.config.cjs +2 -0
- package/rollup.config.js +21 -40
- package/scripts/generate-component/templates/[Name].js +0 -5
- package/scripts/generate-component/templates/[name].css +3 -3
- package/scripts/generate-component/templates/[namespace]-[name].js +5 -2
- package/scripts/postcss-leu-font-styles.cjs +160 -0
- package/src/components/accordion/Accordion.js +0 -6
- package/src/components/accordion/accordion.css +2 -2
- package/src/components/accordion/leu-accordion.js +5 -2
- package/src/components/accordion/stories/accordion.stories.js +8 -4
- package/src/components/accordion/test/accordion.test.js +95 -3
- package/src/components/breadcrumb/Breadcrumb.js +311 -0
- package/src/components/breadcrumb/breadcrumb.css +103 -0
- package/src/components/breadcrumb/leu-breadcrumb.js +6 -0
- package/src/components/breadcrumb/stories/breadcrumb.stories.js +73 -0
- package/src/components/breadcrumb/test/breadcrumb.test.js +141 -0
- package/src/components/button/Button.js +76 -20
- package/src/components/button/button.css +13 -5
- package/src/components/button/leu-button.js +5 -2
- package/src/components/button/stories/button.stories.js +79 -105
- package/src/components/button/test/button.test.js +184 -3
- package/src/components/button-group/ButtonGroup.js +76 -40
- package/src/components/button-group/leu-button-group.js +5 -2
- package/src/components/button-group/stories/button-group.stories.js +19 -6
- package/src/components/button-group/test/button-group.test.js +87 -4
- package/src/components/checkbox/Checkbox.js +6 -85
- package/src/components/checkbox/CheckboxGroup.js +8 -38
- package/src/components/checkbox/checkbox-group.css +29 -0
- package/src/components/checkbox/checkbox.css +76 -0
- package/src/components/checkbox/leu-checkbox-group.js +5 -2
- package/src/components/checkbox/leu-checkbox.js +5 -2
- package/src/components/checkbox/stories/checkbox-group.stories.js +44 -21
- package/src/components/checkbox/stories/checkbox.stories.js +7 -1
- package/src/components/checkbox/test/checkbox-group.test.js +124 -0
- package/src/components/checkbox/test/checkbox.test.js +72 -59
- package/src/components/chip/Chip.js +1 -0
- package/src/components/chip/ChipGroup.js +42 -7
- package/src/components/chip/ChipLink.js +1 -6
- package/src/components/chip/ChipRemovable.js +2 -7
- package/src/components/chip/ChipSelectable.js +5 -10
- package/src/components/chip/chip-group.css +12 -2
- package/src/components/chip/chip.css +14 -3
- package/src/components/chip/exports.js +4 -10
- package/src/components/chip/leu-chip-group.js +5 -2
- package/src/components/chip/leu-chip-link.js +5 -2
- package/src/components/chip/leu-chip-removable.js +5 -2
- package/src/components/chip/leu-chip-selectable.js +5 -2
- package/src/components/chip/stories/chip-group.stories.js +110 -44
- package/src/components/chip/stories/chip-link.stories.js +16 -4
- package/src/components/chip/stories/chip-removable.stories.js +15 -4
- package/src/components/chip/stories/chip-selectable.stories.js +13 -3
- package/src/components/chip/test/chip-group.test.js +124 -0
- package/src/components/chip/test/chip-link.test.js +58 -0
- package/src/components/chip/test/chip-removable.test.js +79 -0
- package/src/components/chip/test/chip-selectable.test.js +95 -0
- package/src/components/chip/test/chip.test.js +1 -1
- package/src/components/dropdown/Dropdown.js +72 -24
- package/src/components/dropdown/dropdown.css +1 -2
- package/src/components/dropdown/leu-dropdown.js +5 -2
- package/src/components/dropdown/stories/dropdown.stories.js +11 -5
- package/src/components/dropdown/test/dropdown.test.js +6 -6
- package/src/components/icon/icon.js +1 -1
- package/src/components/icon/test/icon.test.js +66 -0
- package/src/components/input/Input.js +25 -28
- package/src/components/input/input.css +11 -8
- package/src/components/input/leu-input.js +5 -2
- package/src/components/input/stories/input.stories.js +21 -2
- package/src/components/input/test/input.test.js +432 -4
- package/src/components/menu/Menu.js +0 -5
- package/src/components/menu/MenuItem.js +20 -13
- package/src/components/menu/leu-menu-item.js +5 -2
- package/src/components/menu/leu-menu.js +5 -2
- package/src/components/menu/menu-item.css +7 -4
- package/src/components/menu/stories/menu-item.stories.js +13 -4
- package/src/components/menu/stories/menu.stories.js +11 -5
- package/src/components/menu/test/menu-item.test.js +180 -0
- package/src/components/menu/test/menu.test.js +10 -2
- package/src/components/pagination/Pagination.js +118 -99
- package/src/components/pagination/leu-pagination.js +5 -2
- package/src/components/pagination/pagination.css +6 -1
- package/src/components/pagination/stories/pagination.stories.js +30 -9
- package/src/components/pagination/test/pagination.test.js +191 -5
- package/src/components/popup/Popup.js +200 -0
- package/src/components/popup/leu-popup.js +6 -0
- package/src/components/popup/popup.css +27 -0
- package/src/components/popup/stories/popup.stories.js +58 -0
- package/src/components/popup/test/popup.test.js +29 -0
- package/src/components/radio/Radio.js +2 -6
- package/src/components/radio/RadioGroup.js +6 -38
- package/src/components/radio/leu-radio-group.js +5 -2
- package/src/components/radio/leu-radio.js +5 -2
- package/src/components/radio/radio-group.css +29 -0
- package/src/components/radio/radio.css +1 -1
- package/src/components/radio/stories/radio-group.stories.js +38 -19
- package/src/components/radio/stories/radio.stories.js +7 -1
- package/src/components/radio/test/radio-group.test.js +86 -0
- package/src/components/radio/test/radio.test.js +108 -17
- package/src/components/scroll-top/ScrollTop.js +87 -0
- package/src/components/scroll-top/leu-scroll-top.js +6 -0
- package/src/components/scroll-top/scroll-top.css +34 -0
- package/src/components/scroll-top/stories/scroll-top.stories.js +217 -0
- package/src/components/scroll-top/test/scroll-top.test.js +22 -0
- package/src/components/select/Select.js +58 -37
- package/src/components/select/leu-select.js +5 -2
- package/src/components/select/select.css +15 -15
- package/src/components/select/stories/select.stories.js +15 -168
- package/src/components/select/test/fixtures.js +162 -0
- package/src/components/select/test/select.test.js +236 -12
- package/src/components/table/Table.js +43 -118
- package/src/components/table/leu-table.js +5 -2
- package/src/components/table/stories/table.stories.js +20 -10
- package/src/components/table/table.css +99 -0
- package/src/components/table/test/table.test.js +1 -1
- package/src/components/visually-hidden/VisuallyHidden.js +13 -0
- package/src/components/visually-hidden/leu-visually-hidden.js +6 -0
- package/src/components/visually-hidden/stories/visually-hidden.stories.js +22 -0
- package/src/components/visually-hidden/test/visually-hidden.test.js +36 -0
- package/src/components/visually-hidden/visually-hidden.css +10 -0
- package/src/lib/defineElement.js +1 -1
- package/src/lib/hasSlotController.js +5 -3
- package/src/lib/utils.js +35 -0
- package/src/styles/custom-properties.css +6 -2
- package/src/styles/font-definitions.json +202 -0
- package/stylelint.config.mjs +2 -0
- package/tsconfig.build.json +21 -0
- package/tsconfig.json +16 -0
- package/{web-dev-server-storybook.config.mjs → web-dev-server.config.mjs} +1 -2
- package/web-test-runner.config.mjs +15 -2
- package/dist/index.js +0 -26
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { html } from "lit"
|
|
2
|
+
import { fixture, expect, oneEvent } from "@open-wc/testing"
|
|
3
|
+
import { sendKeys } from "@web/test-runner-commands"
|
|
4
|
+
|
|
5
|
+
import { iconPaths } from "../../icon/icon.js"
|
|
6
|
+
|
|
7
|
+
import "../leu-chip-removable.js"
|
|
8
|
+
|
|
9
|
+
async function defaultFixture() {
|
|
10
|
+
return fixture(
|
|
11
|
+
html` <leu-chip-removable label="Daten"></leu-chip-removable> `
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe("LeuChipRemovable", () => {
|
|
16
|
+
it("is a defined element", async () => {
|
|
17
|
+
const el = customElements.get("leu-chip-removable")
|
|
18
|
+
|
|
19
|
+
await expect(el).not.to.be.undefined
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it("passes the a11y audit", async () => {
|
|
23
|
+
const el = await defaultFixture()
|
|
24
|
+
|
|
25
|
+
await expect(el).shadowDom.to.be.accessible()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it("renders the label", async () => {
|
|
29
|
+
const el = await defaultFixture()
|
|
30
|
+
|
|
31
|
+
const button = el.shadowRoot.querySelector("button")
|
|
32
|
+
|
|
33
|
+
expect(button).to.have.trimmed.text("Daten")
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it("renders a button element", async () => {
|
|
37
|
+
const el = await defaultFixture()
|
|
38
|
+
|
|
39
|
+
expect(el.shadowRoot.querySelector("button")).to.exist
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it("renders a remove icon", async () => {
|
|
43
|
+
const el = await defaultFixture()
|
|
44
|
+
|
|
45
|
+
const iconPath = el.shadowRoot.querySelector("svg path")
|
|
46
|
+
|
|
47
|
+
expect(iconPath.getAttribute("d")).to.equal(iconPaths.close)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it("delegates the focus to the button element", async () => {
|
|
51
|
+
const el = await defaultFixture()
|
|
52
|
+
|
|
53
|
+
el.focus()
|
|
54
|
+
|
|
55
|
+
expect(el.shadowRoot.querySelector("button")).to.equal(
|
|
56
|
+
el.shadowRoot.activeElement
|
|
57
|
+
)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it("fires a remove event when the button is clicked", async () => {
|
|
61
|
+
const el = await defaultFixture()
|
|
62
|
+
const button = el.shadowRoot.querySelector("button")
|
|
63
|
+
|
|
64
|
+
setTimeout(() => button.click())
|
|
65
|
+
const event = await oneEvent(el, "leu:remove")
|
|
66
|
+
|
|
67
|
+
expect(event).to.exist
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it("fires a remove event when the enter key is pressed", async () => {
|
|
71
|
+
const el = await defaultFixture()
|
|
72
|
+
|
|
73
|
+
el.focus()
|
|
74
|
+
setTimeout(() => sendKeys({ press: "Enter" }))
|
|
75
|
+
const event = await oneEvent(el, "leu:remove")
|
|
76
|
+
|
|
77
|
+
expect(event).to.exist
|
|
78
|
+
})
|
|
79
|
+
})
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { html } from "lit"
|
|
2
|
+
import { ifDefined } from "lit/directives/if-defined.js"
|
|
3
|
+
import { fixture, expect, oneEvent } from "@open-wc/testing"
|
|
4
|
+
import { sendKeys } from "@web/test-runner-commands"
|
|
5
|
+
|
|
6
|
+
import "../leu-chip-selectable.js"
|
|
7
|
+
|
|
8
|
+
async function defaultFixture(args = {}) {
|
|
9
|
+
return fixture(
|
|
10
|
+
html`
|
|
11
|
+
<leu-chip-selectable
|
|
12
|
+
label="Publikationen"
|
|
13
|
+
value="Publikationen"
|
|
14
|
+
variant=${ifDefined(args.variant)}
|
|
15
|
+
?selected=${args.selected}
|
|
16
|
+
></leu-chip-selectable>
|
|
17
|
+
`
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe("LeuChipSelectable", () => {
|
|
22
|
+
it("is a defined element", async () => {
|
|
23
|
+
const el = customElements.get("leu-chip-selectable")
|
|
24
|
+
|
|
25
|
+
await expect(el).not.to.be.undefined
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it("passes the a11y audit", async () => {
|
|
29
|
+
const el = await defaultFixture()
|
|
30
|
+
|
|
31
|
+
await expect(el).shadowDom.to.be.accessible()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it("renders the label", async () => {
|
|
35
|
+
const el = await defaultFixture()
|
|
36
|
+
|
|
37
|
+
const button = el.shadowRoot.querySelector("button")
|
|
38
|
+
|
|
39
|
+
expect(button).to.have.trimmed.text("Publikationen")
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it("renders a button element", async () => {
|
|
43
|
+
const el = await defaultFixture()
|
|
44
|
+
|
|
45
|
+
expect(el.shadowRoot.querySelector("button")).to.exist
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("delegates the focus to the button element", async () => {
|
|
49
|
+
const el = await defaultFixture()
|
|
50
|
+
|
|
51
|
+
el.focus()
|
|
52
|
+
|
|
53
|
+
expect(el.shadowRoot.querySelector("button")).to.equal(
|
|
54
|
+
el.shadowRoot.activeElement
|
|
55
|
+
)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it("fires a input event when the button is clicked", async () => {
|
|
59
|
+
const el = await defaultFixture()
|
|
60
|
+
const button = el.shadowRoot.querySelector("button")
|
|
61
|
+
|
|
62
|
+
setTimeout(() => button.click())
|
|
63
|
+
const event = await oneEvent(el, "input")
|
|
64
|
+
|
|
65
|
+
expect(event).to.exist
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it("fires a input event when the enter key is pressed", async () => {
|
|
69
|
+
const el = await defaultFixture()
|
|
70
|
+
|
|
71
|
+
el.focus()
|
|
72
|
+
setTimeout(() => sendKeys({ press: "Enter" }))
|
|
73
|
+
const event = await oneEvent(el, "input")
|
|
74
|
+
|
|
75
|
+
expect(event).to.exist
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it("removes the selected state when the button is clicked", async () => {
|
|
79
|
+
const el = await defaultFixture({ selected: true })
|
|
80
|
+
const button = el.shadowRoot.querySelector("button")
|
|
81
|
+
|
|
82
|
+
button.click()
|
|
83
|
+
|
|
84
|
+
expect(el.selected).to.be.false
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it("doesn't remove the selected state of a selected radio chip", async () => {
|
|
88
|
+
const el = await defaultFixture({ variant: "radio", selected: true })
|
|
89
|
+
|
|
90
|
+
const button = el.shadowRoot.querySelector("button")
|
|
91
|
+
button.click()
|
|
92
|
+
|
|
93
|
+
expect(el.selected).to.be.true
|
|
94
|
+
})
|
|
95
|
+
})
|
|
@@ -9,7 +9,7 @@ async function defaultFixture() {
|
|
|
9
9
|
|
|
10
10
|
describe("LeuChipLink", () => {
|
|
11
11
|
it("is a defined element", async () => {
|
|
12
|
-
const el =
|
|
12
|
+
const el = customElements.get("leu-chip-link")
|
|
13
13
|
|
|
14
14
|
await expect(el).not.to.be.undefined
|
|
15
15
|
})
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { html, LitElement } from "lit"
|
|
2
|
-
import { defineElement } from "../../lib/defineElement.js"
|
|
3
2
|
import styles from "./dropdown.css"
|
|
4
3
|
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
4
|
+
import "../button/leu-button.js"
|
|
5
|
+
import "../menu/leu-menu.js"
|
|
6
|
+
import "../menu/leu-menu-item.js"
|
|
7
|
+
import "../popup/leu-popup.js"
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @tagname leu-dropdown
|
|
@@ -22,34 +22,82 @@ export class LeuDropdown extends LitElement {
|
|
|
22
22
|
|
|
23
23
|
this.label = ""
|
|
24
24
|
this.expanded = false
|
|
25
|
+
this.menuItems = []
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
connectedCallback() {
|
|
29
|
+
super.connectedCallback()
|
|
30
|
+
this.addEventListener("keyup", this._keyUpHandler)
|
|
31
|
+
document.addEventListener("click", this._documentClickHandler)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
disconnectedCallback() {
|
|
35
|
+
super.disconnectedCallback()
|
|
36
|
+
this._removeMenuItemListeners()
|
|
37
|
+
this.removeEventListener("keyup", this._keyUpHandler)
|
|
38
|
+
document.removeEventListener("click", this._documentClickHandler)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
_documentClickHandler = (event) => {
|
|
42
|
+
if (!this.contains(event.target)) {
|
|
43
|
+
this.expanded = false
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
_keyUpHandler(event) {
|
|
48
|
+
if (event.key === "Escape") {
|
|
49
|
+
this.expanded = false
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
_handleSlotChange() {
|
|
54
|
+
this._removeMenuItemListeners()
|
|
55
|
+
this.menuItems = [...this.querySelectorAll("leu-menu > leu-menu-item")]
|
|
56
|
+
|
|
57
|
+
this.menuItems.forEach((item) =>
|
|
58
|
+
item.addEventListener("click", this._handleMenuItemClick)
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
_removeMenuItemListeners() {
|
|
63
|
+
this.menuItems.forEach((item) => {
|
|
64
|
+
item.removeEventListener("click", this._handleMenuItemClick)
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
_handleMenuItemClick = () => {
|
|
69
|
+
this.expanded = false
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
_handleToggleClick() {
|
|
28
73
|
this.expanded = !this.expanded
|
|
29
74
|
}
|
|
30
75
|
|
|
31
76
|
render() {
|
|
32
77
|
return html`
|
|
33
|
-
<leu-
|
|
34
|
-
icon="download"
|
|
35
|
-
variant="ghost"
|
|
36
|
-
label=${this.label}
|
|
37
|
-
expanded=${this.expanded ? "open" : "closed"}
|
|
38
|
-
aria-expanded=${this.expanded ? "true" : "false"}
|
|
39
|
-
aria-controls="content"
|
|
78
|
+
<leu-popup
|
|
40
79
|
?active=${this.expanded}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
80
|
+
placement="bottom-start"
|
|
81
|
+
shift
|
|
82
|
+
shiftPadding="8"
|
|
83
|
+
autoSize="width"
|
|
84
|
+
autoSizePadding="8"
|
|
85
|
+
>
|
|
86
|
+
<leu-button
|
|
87
|
+
slot="anchor"
|
|
88
|
+
icon="download"
|
|
89
|
+
variant="ghost"
|
|
90
|
+
expanded=${this.expanded ? "true" : "false"}
|
|
91
|
+
aria-expanded=${this.expanded ? "true" : "false"}
|
|
92
|
+
aria-controls="content"
|
|
93
|
+
?active=${this.expanded}
|
|
94
|
+
@click=${this._handleToggleClick}
|
|
95
|
+
>${this.label}</leu-button
|
|
96
|
+
>
|
|
97
|
+
<div id="content" class="content" ?hidden=${!this.expanded}>
|
|
98
|
+
<slot @slotchange=${this._handleSlotChange}></slot>
|
|
99
|
+
</div>
|
|
100
|
+
</leu-popup>
|
|
46
101
|
`
|
|
47
102
|
}
|
|
48
103
|
}
|
|
49
|
-
|
|
50
|
-
export function defineDropdownElements() {
|
|
51
|
-
defineElement("dropdown", LeuDropdown)
|
|
52
|
-
defineButtonElements()
|
|
53
|
-
defineMenuElements()
|
|
54
|
-
defineMenuItemElements()
|
|
55
|
-
}
|
|
@@ -4,17 +4,23 @@ import "../leu-dropdown.js"
|
|
|
4
4
|
export default {
|
|
5
5
|
title: "Dropdown",
|
|
6
6
|
component: "leu-dropdown",
|
|
7
|
+
parameters: {
|
|
8
|
+
design: {
|
|
9
|
+
type: "figma",
|
|
10
|
+
url: "https://www.figma.com/file/d6Pv21UVUbnBs3AdcZijHmbN/KTZH-Design-System?type=design&node-id=136815-217650&mode=design&t=lzVrtq8lxYVJU5TB-11",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
7
13
|
}
|
|
8
14
|
|
|
9
15
|
function Template({ label, expanded }) {
|
|
10
16
|
return html` <leu-dropdown label=${label} ?expanded=${expanded}>
|
|
11
17
|
<leu-menu>
|
|
12
|
-
<leu-menu-item
|
|
13
|
-
<leu-menu-item
|
|
18
|
+
<leu-menu-item label="Als CSV Tabelle"></leu-menu-item>
|
|
19
|
+
<leu-menu-item label="Als XLS Tabelle"></leu-menu-item>
|
|
14
20
|
<hr />
|
|
15
|
-
<leu-menu-item
|
|
16
|
-
<leu-menu-item
|
|
17
|
-
<leu-menu-item
|
|
21
|
+
<leu-menu-item label="Als PNG exportieren"></leu-menu-item>
|
|
22
|
+
<leu-menu-item label="Als SVG exportieren"></leu-menu-item>
|
|
23
|
+
<leu-menu-item label="Als PDF exportieren" disabled></leu-menu-item>
|
|
18
24
|
</leu-menu>
|
|
19
25
|
</leu-dropdown>`
|
|
20
26
|
}
|
|
@@ -6,19 +6,19 @@ import "../leu-dropdown.js"
|
|
|
6
6
|
async function defaultFixture() {
|
|
7
7
|
return fixture(html` <leu-dropdown label="Download">
|
|
8
8
|
<leu-menu>
|
|
9
|
-
<leu-menu-item
|
|
10
|
-
<leu-menu-item
|
|
9
|
+
<leu-menu-item label="Als CSV Tabelle"></leu-menu-item>
|
|
10
|
+
<leu-menu-item label="Als XLS Tabelle"></leu-menu-item>
|
|
11
11
|
<hr />
|
|
12
|
-
<leu-menu-item
|
|
13
|
-
<leu-menu-item
|
|
14
|
-
<leu-menu-item
|
|
12
|
+
<leu-menu-item label="Als PNG exportieren"></leu-menu-item>
|
|
13
|
+
<leu-menu-item label="Als SVG exportieren"></leu-menu-item>
|
|
14
|
+
<leu-menu-item label="Als PDF exportieren"></leu-menu-item>
|
|
15
15
|
</leu-menu>
|
|
16
16
|
</leu-dropdown>`)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
describe("LeuDropdown", () => {
|
|
20
20
|
it("is a defined element", async () => {
|
|
21
|
-
const el =
|
|
21
|
+
const el = customElements.get("leu-dropdown")
|
|
22
22
|
|
|
23
23
|
await expect(el).not.to.be.undefined
|
|
24
24
|
})
|
|
@@ -5,7 +5,7 @@ import { html, svg } from "lit"
|
|
|
5
5
|
// - click icon and then export as svg on the right drawer
|
|
6
6
|
// - copy svg path (multiple with space between)
|
|
7
7
|
// - update @param {TYPE} with console.log() below
|
|
8
|
-
const iconPaths = {
|
|
8
|
+
export const iconPaths = {
|
|
9
9
|
addNew:
|
|
10
10
|
"M12 1C5.926 1 1 5.925 1 12C1 18.075 5.926 23 12 23C18.074 23 23 18.075 23 12C23 5.925 18.074 1 12 1ZM17 13H13V17H11V13H7V11H11V7H13V11H17V13Z",
|
|
11
11
|
angleDropDown: "M17 9.5L12 14.5L7 9.5L17 9.5Z",
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { html } from "lit"
|
|
2
|
+
import { fixture, expect } from "@open-wc/testing"
|
|
3
|
+
|
|
4
|
+
import { Icon, iconPaths } from "../icon.js"
|
|
5
|
+
|
|
6
|
+
async function defaultFixture(args = {}) {
|
|
7
|
+
const { name = "edit", size } = args
|
|
8
|
+
return fixture(html`${Icon(name, size)} `)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
describe("Icon", () => {
|
|
12
|
+
it("passes the a11y audit", async () => {
|
|
13
|
+
const el = await defaultFixture()
|
|
14
|
+
|
|
15
|
+
await expect(el).shadowDom.to.be.accessible()
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it("renders an svg html element", async () => {
|
|
19
|
+
const el = await defaultFixture()
|
|
20
|
+
|
|
21
|
+
expect(el).to.have.tagName("svg")
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it("renders a single path", async () => {
|
|
25
|
+
const el = await defaultFixture()
|
|
26
|
+
|
|
27
|
+
expect(el.querySelectorAll("path")).to.have.lengthOf(1)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it("renders the correct path", async () => {
|
|
31
|
+
const el = await defaultFixture({ name: "share" })
|
|
32
|
+
|
|
33
|
+
const d = el.querySelector("path").getAttribute("d")
|
|
34
|
+
|
|
35
|
+
expect(d).to.equal(iconPaths.share)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it("has the size 24x24 by default", async () => {
|
|
39
|
+
const el = await defaultFixture()
|
|
40
|
+
|
|
41
|
+
const width = el.getAttribute("width")
|
|
42
|
+
const height = el.getAttribute("height")
|
|
43
|
+
|
|
44
|
+
expect(width).to.equal("24")
|
|
45
|
+
expect(height).to.equal("24")
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("has the size 16x16", async () => {
|
|
49
|
+
const el = await defaultFixture({ size: "16" })
|
|
50
|
+
|
|
51
|
+
const width = el.getAttribute("width")
|
|
52
|
+
const height = el.getAttribute("height")
|
|
53
|
+
|
|
54
|
+
expect(width).to.equal("16")
|
|
55
|
+
expect(height).to.equal("16")
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it("has always a square size", async () => {
|
|
59
|
+
const el = await defaultFixture({ size: "564" })
|
|
60
|
+
|
|
61
|
+
const width = el.getAttribute("width")
|
|
62
|
+
const height = el.getAttribute("height")
|
|
63
|
+
|
|
64
|
+
expect(width).to.equal(height)
|
|
65
|
+
})
|
|
66
|
+
})
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { html, LitElement, nothing } from "lit"
|
|
2
2
|
import { classMap } from "lit/directives/class-map.js"
|
|
3
3
|
import { ifDefined } from "lit/directives/if-defined.js"
|
|
4
|
+
import { live } from "lit/directives/live.js"
|
|
4
5
|
import { createRef, ref } from "lit/directives/ref.js"
|
|
5
6
|
|
|
6
7
|
import { Icon } from "../icon/icon.js"
|
|
7
|
-
import { defineElement } from "../../lib/defineElement.js"
|
|
8
8
|
|
|
9
9
|
import styles from "./input.css"
|
|
10
10
|
|
|
@@ -56,6 +56,7 @@ const VALIDATION_MESSAGES = {
|
|
|
56
56
|
* @prop {string} maxlength - The maximum length of the input element.
|
|
57
57
|
* @prop {object} validationMessages - Custom validation messages. The key is the name of the validity state and the value is the message.
|
|
58
58
|
* @prop {boolean} novalidate - Disables the browser's validation.
|
|
59
|
+
* @prop {string} step - The step value of the input element.
|
|
59
60
|
*
|
|
60
61
|
* @fires {CustomEvent} input - Dispatched when the value of the input element changes.
|
|
61
62
|
* @fires {CustomEvent} change - Dispatched when the value of the input element changes and the input element loses focus.
|
|
@@ -91,12 +92,13 @@ export class LeuInput extends LitElement {
|
|
|
91
92
|
/* Validation attributes */
|
|
92
93
|
pattern: { type: String, reflect: true },
|
|
93
94
|
type: { type: String, reflect: true },
|
|
94
|
-
min: { type:
|
|
95
|
-
max: { type:
|
|
96
|
-
maxlength: { type:
|
|
97
|
-
minlength: { type:
|
|
95
|
+
min: { type: String, reflect: true },
|
|
96
|
+
max: { type: String, reflect: true },
|
|
97
|
+
maxlength: { type: String, reflect: true },
|
|
98
|
+
minlength: { type: String, reflect: true },
|
|
98
99
|
validationMessages: { type: Object },
|
|
99
100
|
novalidate: { type: Boolean, reflect: true },
|
|
101
|
+
step: { type: String, reflect: true },
|
|
100
102
|
|
|
101
103
|
/** @type {ValidityState} */
|
|
102
104
|
_validity: { state: true },
|
|
@@ -117,19 +119,9 @@ export class LeuInput extends LitElement {
|
|
|
117
119
|
this.required = false
|
|
118
120
|
this.clearable = false
|
|
119
121
|
|
|
120
|
-
this.value = ""
|
|
121
|
-
this.name = ""
|
|
122
|
-
this.error = ""
|
|
123
|
-
|
|
124
|
-
this.label = ""
|
|
125
|
-
this.prefix = ""
|
|
126
|
-
this.suffix = ""
|
|
127
|
-
|
|
128
122
|
/** @type {keyof typeof SIZE_TYPES} */
|
|
129
123
|
this.size = SIZE_TYPES.REGULAR
|
|
130
124
|
|
|
131
|
-
this.icon = ""
|
|
132
|
-
|
|
133
125
|
this.type = "text"
|
|
134
126
|
this._validity = null
|
|
135
127
|
this.validationMessages = {}
|
|
@@ -201,7 +193,9 @@ export class LeuInput extends LitElement {
|
|
|
201
193
|
* @returns {void}
|
|
202
194
|
*/
|
|
203
195
|
handleChange(event) {
|
|
204
|
-
|
|
196
|
+
if (event.target.validity.valid) {
|
|
197
|
+
this.value = event.target.value
|
|
198
|
+
}
|
|
205
199
|
|
|
206
200
|
const customEvent = new CustomEvent(event.type, event)
|
|
207
201
|
this.dispatchEvent(customEvent)
|
|
@@ -217,6 +211,12 @@ export class LeuInput extends LitElement {
|
|
|
217
211
|
*/
|
|
218
212
|
handleInput(event) {
|
|
219
213
|
this.value = event.target.value
|
|
214
|
+
|
|
215
|
+
const customEvent = new CustomEvent("input", {
|
|
216
|
+
bubbles: true,
|
|
217
|
+
composed: true,
|
|
218
|
+
})
|
|
219
|
+
this.dispatchEvent(customEvent)
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
/**
|
|
@@ -348,7 +348,7 @@ export class LeuInput extends LitElement {
|
|
|
348
348
|
return html`<div class="error-icon">${Icon("caution")}</div>`
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
-
if (this.clearable && this.value
|
|
351
|
+
if (this.clearable && this.value) {
|
|
352
352
|
return html`<button
|
|
353
353
|
class="clear-button"
|
|
354
354
|
@click=${this.clear}
|
|
@@ -359,7 +359,7 @@ export class LeuInput extends LitElement {
|
|
|
359
359
|
</button>`
|
|
360
360
|
}
|
|
361
361
|
|
|
362
|
-
if (this.icon
|
|
362
|
+
if (this.icon) {
|
|
363
363
|
return html`<div class="icon">${Icon(this.icon)}</div>`
|
|
364
364
|
}
|
|
365
365
|
|
|
@@ -367,7 +367,7 @@ export class LeuInput extends LitElement {
|
|
|
367
367
|
}
|
|
368
368
|
|
|
369
369
|
isInvalid() {
|
|
370
|
-
if (this.error
|
|
370
|
+
if (this.error) {
|
|
371
371
|
return true
|
|
372
372
|
}
|
|
373
373
|
|
|
@@ -381,7 +381,7 @@ export class LeuInput extends LitElement {
|
|
|
381
381
|
|
|
382
382
|
const inputWrapperClasses = {
|
|
383
383
|
"input-wrapper": true,
|
|
384
|
-
"input-wrapper--empty": this.value
|
|
384
|
+
"input-wrapper--empty": !this.value,
|
|
385
385
|
"input-wrapper--invalid": isInvalid,
|
|
386
386
|
}
|
|
387
387
|
|
|
@@ -403,20 +403,21 @@ export class LeuInput extends LitElement {
|
|
|
403
403
|
@invalid=${this.handleInvalid}
|
|
404
404
|
?disabled=${this.disabled}
|
|
405
405
|
?required=${this.required}
|
|
406
|
+
.value=${live(this.value ?? "")}
|
|
406
407
|
pattern=${ifDefined(this.pattern)}
|
|
407
408
|
min=${ifDefined(this.min)}
|
|
408
409
|
max=${ifDefined(this.max)}
|
|
409
410
|
maxlength=${ifDefined(this.maxlength)}
|
|
410
411
|
minlength=${ifDefined(this.minlength)}
|
|
411
|
-
|
|
412
|
+
step=${ifDefined(this.step)}
|
|
412
413
|
ref=${ref(this._inputRef)}
|
|
413
414
|
aria-invalid=${isInvalid}
|
|
414
415
|
/>
|
|
415
|
-
<label for="input-${this.getId()}" class="label"
|
|
416
|
-
${this.prefix
|
|
416
|
+
<label for="input-${this.getId()}" class="label">${this.label}</label>
|
|
417
|
+
${this.prefix
|
|
417
418
|
? html`<div class="prefix" .aria-hidden=${true}>${this.prefix}</div>`
|
|
418
419
|
: nothing}
|
|
419
|
-
${this.suffix
|
|
420
|
+
${this.suffix
|
|
420
421
|
? html`<div class="suffix" .aria-hidden=${true}>${this.suffix}</div>`
|
|
421
422
|
: nothing}
|
|
422
423
|
${this.renderAfterContent()}
|
|
@@ -425,7 +426,3 @@ export class LeuInput extends LitElement {
|
|
|
425
426
|
`
|
|
426
427
|
}
|
|
427
428
|
}
|
|
428
|
-
|
|
429
|
-
export function defineInputElements() {
|
|
430
|
-
defineElement("input", LeuInput)
|
|
431
|
-
}
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
|
|
27
27
|
--input-clear-color: var(--leu-color-black-60);
|
|
28
28
|
|
|
29
|
-
--input-font-regular: var(--leu-font-regular);
|
|
30
|
-
--input-font-black: var(--leu-font-black);
|
|
29
|
+
--input-font-regular: var(--leu-font-family-regular);
|
|
30
|
+
--input-font-black: var(--leu-font-family-black);
|
|
31
31
|
|
|
32
32
|
display: block;
|
|
33
33
|
font-family: var(--input-font-regular);
|
|
@@ -115,6 +115,7 @@
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
/* is size regular AND (has focus OR contains a value) */
|
|
118
|
+
.input-wrapper--invalid .label,
|
|
118
119
|
:host(:not([size])) .label,
|
|
119
120
|
:host([size="regular"]) .label {
|
|
120
121
|
top: calc(0.75rem - var(--input-border-width));
|
|
@@ -138,18 +139,20 @@
|
|
|
138
139
|
content: "*";
|
|
139
140
|
}
|
|
140
141
|
|
|
142
|
+
/* is not disabled AND has focus AND is empty */
|
|
143
|
+
:host(:not([disabled], :focus-within)) .input-wrapper--empty .label {
|
|
144
|
+
--input-label-color: var(--input-label-color-empty);
|
|
145
|
+
}
|
|
146
|
+
|
|
141
147
|
/* is empty AND has no focus */
|
|
142
|
-
:host(:not(:focus-within))
|
|
148
|
+
:host(:not(:focus-within))
|
|
149
|
+
.input-wrapper--empty:not(.input-wrapper--invalid)
|
|
150
|
+
.label {
|
|
143
151
|
font-family: var(--input-font-regular);
|
|
144
152
|
font-size: 1rem;
|
|
145
153
|
top: calc(1.5rem - var(--input-border-width));
|
|
146
154
|
}
|
|
147
155
|
|
|
148
|
-
/* is not disabled AND has focus AND is empty */
|
|
149
|
-
:host(:not([disabled], :focus-within)) .input-wrapper--empty .label {
|
|
150
|
-
--input-label-color: var(--input-label-color-empty);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
156
|
/* is size small AND has no focus AND is empty */
|
|
154
157
|
:host(:not(:focus-within)[size="small"]) .input-wrapper--empty .label {
|
|
155
158
|
top: calc(0.75rem - var(--input-border-width));
|