@statistikzh/leu 0.23.0 → 0.24.1
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/ci.yml +8 -8
- package/.github/workflows/deploy-github-pages.yaml +2 -2
- package/.github/workflows/publish.yml +37 -0
- package/.github/workflows/release-please.yml +1 -19
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +26 -0
- package/dist/Accordion.js +1 -1
- package/dist/Button.js +1 -1
- package/dist/ButtonGroup.js +1 -1
- package/dist/ChartWrapper.js +1 -1
- package/dist/Checkbox.js +1 -1
- package/dist/CheckboxGroup.js +1 -1
- package/dist/Chip.js +1 -1
- package/dist/ChipGroup.js +1 -1
- package/dist/ChipLink.js +1 -1
- package/dist/ChipRemovable.js +1 -1
- package/dist/ChipSelectable.js +1 -1
- package/dist/Dialog.js +1 -1
- package/dist/Dropdown.js +1 -1
- package/dist/FileInput.d.ts +0 -1
- package/dist/FileInput.js +1 -35
- package/dist/Icon.js +1 -1
- package/dist/Input.js +1 -1
- package/dist/{LeuElement-CWseJvWv.js → LeuElement-jrR2M5pZ.js} +1 -1
- package/dist/Menu.js +1 -1
- package/dist/MenuItem.js +1 -1
- package/dist/Message.js +1 -1
- package/dist/Pagination.js +1 -1
- package/dist/Placeholder.js +1 -1
- package/dist/Popup.js +1 -1
- package/dist/ProgressBar.js +1 -1
- package/dist/Radio.js +1 -1
- package/dist/RadioGroup.js +1 -1
- package/dist/Range.d.ts +83 -20
- package/dist/Range.js +276 -73
- package/dist/ScrollTop.js +2 -25
- package/dist/Select.js +1 -1
- package/dist/Spinner.js +1 -1
- package/dist/Table.js +1 -1
- package/dist/Tag.js +1 -1
- package/dist/VisuallyHidden.js +1 -1
- package/dist/components/file-input/FileInput.d.ts +2 -2
- package/dist/components/file-input/FileInput.d.ts.map +1 -1
- package/dist/components/range/Range.d.ts +84 -20
- package/dist/components/range/Range.d.ts.map +1 -1
- package/dist/components/range/stories/range.stories.d.ts +231 -0
- package/dist/components/range/stories/range.stories.d.ts.map +1 -0
- package/dist/components/range/test/range.test.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/leu-accordion.js +1 -1
- package/dist/leu-button-group.js +1 -1
- package/dist/leu-button.js +1 -1
- package/dist/leu-chart-wrapper.js +1 -1
- package/dist/leu-checkbox-group.js +1 -1
- package/dist/leu-checkbox.js +1 -1
- package/dist/leu-chip-group.js +1 -1
- package/dist/leu-chip-link.js +1 -1
- package/dist/leu-chip-removable.js +1 -1
- package/dist/leu-chip-selectable.js +1 -1
- package/dist/leu-dialog.js +1 -1
- package/dist/leu-dropdown.js +1 -1
- package/dist/leu-file-input.d.ts +0 -1
- package/dist/leu-file-input.js +1 -35
- package/dist/leu-icon.js +1 -1
- package/dist/leu-input.js +1 -1
- package/dist/leu-menu-item.js +1 -1
- package/dist/leu-menu.js +1 -1
- package/dist/leu-message.js +1 -1
- package/dist/leu-pagination.js +1 -1
- package/dist/leu-placeholder.js +1 -1
- package/dist/leu-popup.js +1 -1
- package/dist/leu-progress-bar.js +1 -1
- package/dist/leu-radio-group.js +1 -1
- package/dist/leu-radio.js +1 -1
- package/dist/leu-range.js +3 -1
- package/dist/leu-scroll-top.js +2 -1
- package/dist/leu-select.js +1 -1
- package/dist/leu-spinner.js +1 -1
- package/dist/leu-table.js +1 -1
- package/dist/leu-tag.js +1 -1
- package/dist/leu-visually-hidden.js +1 -1
- package/dist/lib/utils.d.ts +10 -3
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/utils-DBGsNSJW.js +33 -0
- package/dist/vscode.html-custom-data.json +142 -89
- package/dist/vue/index.d.ts +132 -107
- package/dist/web-types.json +269 -169
- package/package.json +6 -2
- package/src/components/file-input/FileInput.ts +2 -2
- package/src/components/range/Range.ts +257 -85
- package/src/components/range/range.css +48 -1
- package/src/components/range/stories/range.stories.ts +185 -0
- package/src/components/range/test/range.test.ts +210 -6
- package/src/lib/utils.ts +13 -3
- package/dist/components/range/stories/range-slider.stories.d.ts +0 -26
- package/dist/components/range/stories/range-slider.stories.d.ts.map +0 -1
- package/src/components/range/stories/range-slider.stories.ts +0 -142
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { Meta, StoryObj } from "@storybook/web-components"
|
|
2
|
+
import { action } from "@storybook/addon-actions"
|
|
3
|
+
import { html } from "lit"
|
|
4
|
+
import { ifDefined } from "lit/directives/if-defined.js"
|
|
5
|
+
|
|
6
|
+
import "../leu-range.js"
|
|
7
|
+
import type { LeuRange } from "../leu-range.js"
|
|
8
|
+
import "../../input/leu-input.js"
|
|
9
|
+
|
|
10
|
+
type StoryArgs = LeuRange
|
|
11
|
+
type Story = StoryObj<StoryArgs>
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
title: "Components/Range",
|
|
15
|
+
component: "leu-range",
|
|
16
|
+
parameters: {
|
|
17
|
+
design: {
|
|
18
|
+
type: "figma",
|
|
19
|
+
url: "https://www.figma.com/file/d6Pv21UVUbnBs3AdcZijHmbN/KTZH-Design-System?type=design&node-id=17340-81936&mode=design",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
args: {
|
|
23
|
+
label: "Bereich",
|
|
24
|
+
oninput: action("input"),
|
|
25
|
+
},
|
|
26
|
+
} satisfies Meta<StoryArgs>
|
|
27
|
+
|
|
28
|
+
const Template: Story = {
|
|
29
|
+
render: (args) =>
|
|
30
|
+
html` <leu-range
|
|
31
|
+
label=${args.label}
|
|
32
|
+
?disabled=${args.disabled}
|
|
33
|
+
?multiple=${args.multiple}
|
|
34
|
+
min=${ifDefined(args.min)}
|
|
35
|
+
max=${ifDefined(args.max)}
|
|
36
|
+
value=${ifDefined(args.value)}
|
|
37
|
+
step=${ifDefined(args.step)}
|
|
38
|
+
prefix=${ifDefined(args.prefix)}
|
|
39
|
+
suffix=${ifDefined(args.suffix)}
|
|
40
|
+
.valueFormatter=${args.valueFormatter}
|
|
41
|
+
?hide-label=${args["hide-label"]}
|
|
42
|
+
?show-ticks=${args["show-ticks"]}
|
|
43
|
+
?show-range-labels=${args["show-range-labels"]}
|
|
44
|
+
@input=${args.oninput}
|
|
45
|
+
>
|
|
46
|
+
</leu-range>`,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const Regular = {
|
|
50
|
+
...Template,
|
|
51
|
+
args: { min: 0, max: 100, value: "15" },
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const Multiple = {
|
|
55
|
+
...Template,
|
|
56
|
+
args: { min: 1965, max: 2022, value: "1965, 2022", multiple: true },
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const Labeled = {
|
|
60
|
+
...Template,
|
|
61
|
+
args: { label: "Wert auswählen", min: 100000, max: 200000 },
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const HiddenLabel = {
|
|
65
|
+
...Template,
|
|
66
|
+
args: {
|
|
67
|
+
label: "Wert auswählen",
|
|
68
|
+
min: 100000,
|
|
69
|
+
max: 200000,
|
|
70
|
+
"hide-label": true,
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const Disabled = {
|
|
75
|
+
...Template,
|
|
76
|
+
args: { label: "Wert auswählen", min: 0, max: 100, disabled: true },
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const Step = {
|
|
80
|
+
...Template,
|
|
81
|
+
args: { min: 5, max: 123, step: 13 },
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const Ticks = {
|
|
85
|
+
...Template,
|
|
86
|
+
args: {
|
|
87
|
+
label: "Jahr auswählen",
|
|
88
|
+
min: 1962,
|
|
89
|
+
max: 2022,
|
|
90
|
+
step: 1,
|
|
91
|
+
"show-ticks": true,
|
|
92
|
+
"show-range-labels": true,
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const Suffix = {
|
|
97
|
+
...Template,
|
|
98
|
+
args: {
|
|
99
|
+
label: "Betrag auswählen",
|
|
100
|
+
min: 100,
|
|
101
|
+
max: 200,
|
|
102
|
+
step: 1,
|
|
103
|
+
suffix: " CHF",
|
|
104
|
+
"show-range-labels": true,
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export const CustomFormatter = {
|
|
109
|
+
...Template,
|
|
110
|
+
args: {
|
|
111
|
+
label: "Schuljahr",
|
|
112
|
+
min: 15,
|
|
113
|
+
max: 24,
|
|
114
|
+
step: 1,
|
|
115
|
+
"show-range-labels": true,
|
|
116
|
+
valueFormatter: (value: number) => `${value}/${value + 1}`,
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function CombinedTemplate(args: StoryArgs) {
|
|
121
|
+
const values = (args.value ?? "").split(",").map((v) => Number(v.trim()))
|
|
122
|
+
function handleInputInput() {
|
|
123
|
+
const inputs = document.querySelectorAll("leu-input")
|
|
124
|
+
const range = document.querySelector("leu-range")
|
|
125
|
+
range.value = [inputs[0].value, inputs[1].value]
|
|
126
|
+
}
|
|
127
|
+
return html`
|
|
128
|
+
<leu-range
|
|
129
|
+
label=${args.label}
|
|
130
|
+
?disabled=${args.disabled}
|
|
131
|
+
?multiple=${args.multiple}
|
|
132
|
+
min=${ifDefined(args.min)}
|
|
133
|
+
max=${ifDefined(args.max)}
|
|
134
|
+
value=${ifDefined(args.value)}
|
|
135
|
+
step=${ifDefined(args.step)}
|
|
136
|
+
prefix=${ifDefined(args.prefix)}
|
|
137
|
+
suffix=${ifDefined(args.suffix)}
|
|
138
|
+
?hide-label=${args["hide-label"]}
|
|
139
|
+
?show-ticks=${args["show-ticks"]}
|
|
140
|
+
?show-range-labels=${args["show-range-labels"]}
|
|
141
|
+
@input=${(e) => {
|
|
142
|
+
const inputs = document.querySelectorAll("leu-input")
|
|
143
|
+
const valueList = e.target.valueAsArray
|
|
144
|
+
|
|
145
|
+
inputs[0].value = valueList[0]
|
|
146
|
+
inputs[1].value = valueList[1]
|
|
147
|
+
}}
|
|
148
|
+
>
|
|
149
|
+
</leu-range>
|
|
150
|
+
<div style="display: flex; gap: 1rem; margin-top: 1rem;">
|
|
151
|
+
<leu-input
|
|
152
|
+
label="Von"
|
|
153
|
+
?disabled=${args.disabled}
|
|
154
|
+
type="number"
|
|
155
|
+
min=${ifDefined(args.min)}
|
|
156
|
+
max=${ifDefined(args.max)}
|
|
157
|
+
value=${ifDefined(values[0])}
|
|
158
|
+
step=${ifDefined(args.step)}
|
|
159
|
+
size="small"
|
|
160
|
+
@input=${handleInputInput}
|
|
161
|
+
></leu-input>
|
|
162
|
+
<leu-input
|
|
163
|
+
label="Von"
|
|
164
|
+
?disabled=${args.disabled}
|
|
165
|
+
type="number"
|
|
166
|
+
min=${ifDefined(args.min)}
|
|
167
|
+
max=${ifDefined(args.max)}
|
|
168
|
+
value=${ifDefined(values[1])}
|
|
169
|
+
step=${ifDefined(args.step)}
|
|
170
|
+
size="small"
|
|
171
|
+
@input=${handleInputInput}
|
|
172
|
+
></leu-input>
|
|
173
|
+
</div>
|
|
174
|
+
`
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export const Combined = {
|
|
178
|
+
render: CombinedTemplate,
|
|
179
|
+
args: {
|
|
180
|
+
min: 1965,
|
|
181
|
+
max: 2022,
|
|
182
|
+
value: "1965, 2022",
|
|
183
|
+
multiple: true,
|
|
184
|
+
},
|
|
185
|
+
}
|
|
@@ -1,24 +1,228 @@
|
|
|
1
1
|
import { html } from "lit"
|
|
2
2
|
import { fixture, expect } from "@open-wc/testing"
|
|
3
|
+
import { ifDefined } from "lit/directives/if-defined.js"
|
|
3
4
|
|
|
4
5
|
import "../leu-range.js"
|
|
6
|
+
import type { LeuRange } from "../leu-range.js"
|
|
5
7
|
|
|
6
|
-
async function defaultFixture() {
|
|
7
|
-
return fixture(html`
|
|
8
|
-
<leu-range
|
|
8
|
+
async function defaultFixture(args = {}) {
|
|
9
|
+
return fixture<LeuRange>(html`
|
|
10
|
+
<leu-range
|
|
11
|
+
label=${args.label}
|
|
12
|
+
?disabled=${args.disabled}
|
|
13
|
+
?multiple=${args.multiple}
|
|
14
|
+
min=${ifDefined(args.min)}
|
|
15
|
+
max=${ifDefined(args.max)}
|
|
16
|
+
value=${ifDefined(args.value)}
|
|
17
|
+
step=${ifDefined(args.step)}
|
|
18
|
+
prefix=${ifDefined(args.prefix)}
|
|
19
|
+
suffix=${ifDefined(args.suffix)}
|
|
20
|
+
.valueFormatter=${args.valueFormatter}
|
|
21
|
+
?hide-label=${args["hide-label"]}
|
|
22
|
+
?show-ticks=${args["show-ticks"]}
|
|
23
|
+
?show-range-labels=${args["show-range-labels"]}
|
|
24
|
+
>
|
|
25
|
+
</leu-range>
|
|
9
26
|
`)
|
|
10
27
|
}
|
|
11
28
|
|
|
12
29
|
describe("LeuRange", () => {
|
|
13
30
|
it("is a defined element", async () => {
|
|
14
|
-
const el =
|
|
31
|
+
const el = customElements.get("leu-range")
|
|
15
32
|
|
|
16
|
-
|
|
33
|
+
expect(el).not.to.be.undefined
|
|
17
34
|
})
|
|
18
35
|
|
|
19
36
|
it("passes the a11y audit", async () => {
|
|
20
|
-
const el = await defaultFixture(
|
|
37
|
+
const el = await defaultFixture({
|
|
38
|
+
label: "Test Label",
|
|
39
|
+
min: 0,
|
|
40
|
+
max: 100,
|
|
41
|
+
value: 50,
|
|
42
|
+
})
|
|
21
43
|
|
|
22
44
|
await expect(el).shadowDom.to.be.accessible()
|
|
23
45
|
})
|
|
46
|
+
|
|
47
|
+
it("renders the label", async () => {
|
|
48
|
+
const el = await defaultFixture({ label: "Test Label" })
|
|
49
|
+
|
|
50
|
+
const label = el.shadowRoot?.querySelector(".label")
|
|
51
|
+
|
|
52
|
+
expect(label).to.exist
|
|
53
|
+
expect(label).to.contain.text("Test Label")
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it("renders the label visually hidden when 'hide-label' is set", async () => {
|
|
57
|
+
const el = await defaultFixture({ label: "Test Label", "hide-label": true })
|
|
58
|
+
|
|
59
|
+
const label = el.shadowRoot?.querySelector(".label")
|
|
60
|
+
|
|
61
|
+
expect(label).to.exist
|
|
62
|
+
expect(label).to.contain.text("Test Label")
|
|
63
|
+
await expect(el).shadowDom.to.be.accessible()
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it("renders the range labels", async () => {
|
|
67
|
+
const el = await defaultFixture({
|
|
68
|
+
min: 23,
|
|
69
|
+
max: 87,
|
|
70
|
+
"show-range-labels": true,
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
const minLabel = el.shadowRoot?.querySelector(".tick-label--min")
|
|
74
|
+
const maxLabel = el.shadowRoot?.querySelector(".tick-label--max")
|
|
75
|
+
|
|
76
|
+
expect(minLabel).to.exist
|
|
77
|
+
expect(maxLabel).to.exist
|
|
78
|
+
|
|
79
|
+
expect(minLabel).to.contain.text("23")
|
|
80
|
+
expect(maxLabel).to.contain.text("87")
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it("renders tick marks when 'show-ticks' is set", async () => {
|
|
84
|
+
const el = await defaultFixture({
|
|
85
|
+
min: 0,
|
|
86
|
+
max: 10,
|
|
87
|
+
step: 3,
|
|
88
|
+
"show-ticks": true,
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
const ticksContainer = el.shadowRoot?.querySelector(".ticks")
|
|
92
|
+
expect(ticksContainer).to.exist
|
|
93
|
+
|
|
94
|
+
const ticks = ticksContainer?.querySelectorAll(".tick")
|
|
95
|
+
expect(ticks?.length).to.equal(4)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it("renders prefix and suffix", async () => {
|
|
99
|
+
const el = await defaultFixture({
|
|
100
|
+
prefix: "$",
|
|
101
|
+
suffix: " CHF",
|
|
102
|
+
min: 25,
|
|
103
|
+
max: 75,
|
|
104
|
+
value: 50,
|
|
105
|
+
"show-range-labels": true,
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
const minLabel = el.shadowRoot?.querySelector(".tick-label--min")
|
|
109
|
+
const maxLabel = el.shadowRoot?.querySelector(".tick-label--max")
|
|
110
|
+
const valueLabel = el.shadowRoot?.querySelector("output")
|
|
111
|
+
|
|
112
|
+
expect(minLabel).to.exist
|
|
113
|
+
expect(maxLabel).to.exist
|
|
114
|
+
expect(valueLabel).to.exist
|
|
115
|
+
|
|
116
|
+
expect(minLabel).to.contain.text("$25 CHF")
|
|
117
|
+
expect(maxLabel).to.contain.text("$75 CHF")
|
|
118
|
+
expect(valueLabel).to.contain.text("$50 CHF")
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it("uses custom valueFormatter if provided", async () => {
|
|
122
|
+
const el = await defaultFixture({
|
|
123
|
+
valueFormatter: (value: number) => `Value: ${value}`,
|
|
124
|
+
min: 10,
|
|
125
|
+
max: 90,
|
|
126
|
+
value: 50,
|
|
127
|
+
"show-range-labels": true,
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
const minLabel = el.shadowRoot?.querySelector(".tick-label--min")
|
|
131
|
+
const maxLabel = el.shadowRoot?.querySelector(".tick-label--max")
|
|
132
|
+
const valueLabel = el.shadowRoot?.querySelector("output")
|
|
133
|
+
|
|
134
|
+
expect(minLabel).to.exist
|
|
135
|
+
expect(maxLabel).to.exist
|
|
136
|
+
expect(valueLabel).to.exist
|
|
137
|
+
|
|
138
|
+
expect(minLabel).to.contain.text("Value: 10")
|
|
139
|
+
expect(maxLabel).to.contain.text("Value: 90")
|
|
140
|
+
expect(valueLabel).to.contain.text("Value: 50")
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it("prefix and suffix are ignored when valueFormatter is provided", async () => {
|
|
144
|
+
const el = await defaultFixture({
|
|
145
|
+
prefix: "$",
|
|
146
|
+
suffix: " CHF",
|
|
147
|
+
valueFormatter: (value: number) => `${value}/${value + 1}`,
|
|
148
|
+
min: 10,
|
|
149
|
+
max: 15,
|
|
150
|
+
value: 12,
|
|
151
|
+
"show-range-labels": true,
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
const minLabel = el.shadowRoot?.querySelector(".tick-label--min")
|
|
155
|
+
const maxLabel = el.shadowRoot?.querySelector(".tick-label--max")
|
|
156
|
+
const valueLabel = el.shadowRoot?.querySelector("output")
|
|
157
|
+
|
|
158
|
+
expect(minLabel).to.contain.text("10/11")
|
|
159
|
+
expect(maxLabel).to.contain.text("15/16")
|
|
160
|
+
expect(valueLabel).to.contain.text("12/13")
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
it("disables the range slider", async () => {
|
|
164
|
+
const el = await defaultFixture({ disabled: true })
|
|
165
|
+
|
|
166
|
+
const input = el.shadowRoot?.querySelector("input")
|
|
167
|
+
expect(input).to.have.attribute("disabled")
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
it("clamps and rounds when value is set", async () => {
|
|
171
|
+
const el = await defaultFixture({ min: 0, max: 10, step: 3 })
|
|
172
|
+
|
|
173
|
+
el.value = "8"
|
|
174
|
+
await el.updateComplete
|
|
175
|
+
|
|
176
|
+
expect(el.value).to.equal("9")
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
it("re-normalizes when min/max/step changes", async () => {
|
|
180
|
+
const el = await defaultFixture({ min: 0, max: 10, step: 2 })
|
|
181
|
+
|
|
182
|
+
el.value = "9"
|
|
183
|
+
await el.updateComplete
|
|
184
|
+
|
|
185
|
+
expect(el.value).to.equal("10")
|
|
186
|
+
|
|
187
|
+
el.max = 6
|
|
188
|
+
await el.updateComplete
|
|
189
|
+
|
|
190
|
+
expect(el.value).to.equal("6")
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
it("sets the second handle to min when multiple and a single value is provided", async () => {
|
|
194
|
+
const el = await defaultFixture({
|
|
195
|
+
multiple: true,
|
|
196
|
+
min: 10,
|
|
197
|
+
max: 100,
|
|
198
|
+
value: 20,
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
expect(el.value).to.equal("10,20")
|
|
202
|
+
|
|
203
|
+
el.value = "30"
|
|
204
|
+
await el.updateComplete
|
|
205
|
+
expect(el.value).to.equal("10,30")
|
|
206
|
+
|
|
207
|
+
el.value = "30, 40"
|
|
208
|
+
await el.updateComplete
|
|
209
|
+
expect(el.value).to.equal("30,40")
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
it("re-normalizes both values when multiple and min/max/step changes", async () => {
|
|
213
|
+
const el = await defaultFixture({
|
|
214
|
+
multiple: true,
|
|
215
|
+
min: 0,
|
|
216
|
+
max: 10,
|
|
217
|
+
step: 2,
|
|
218
|
+
value: "3,7",
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
expect(el.value).to.equal("4,8")
|
|
222
|
+
|
|
223
|
+
el.max = 6
|
|
224
|
+
await el.updateComplete
|
|
225
|
+
|
|
226
|
+
expect(el.value).to.equal("4,6")
|
|
227
|
+
})
|
|
24
228
|
})
|
package/src/lib/utils.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @param {Number} timeout - Default is 500 ms
|
|
5
5
|
* @returns {Function} - Your function wrapped in a timeout function
|
|
6
6
|
*/
|
|
7
|
-
const debounce = function debounce(func, timeout = 500) {
|
|
7
|
+
export const debounce = function debounce(func, timeout = 500) {
|
|
8
8
|
let timer = null
|
|
9
9
|
return (...args) => {
|
|
10
10
|
clearTimeout(timer)
|
|
@@ -20,7 +20,7 @@ const debounce = function debounce(func, timeout = 500) {
|
|
|
20
20
|
* @param {Number} timeout - Default is 500 ms
|
|
21
21
|
* @returns {Function} - Your function wrapped in a timeout function
|
|
22
22
|
*/
|
|
23
|
-
const throttle = function throttle(func, timeout = 500) {
|
|
23
|
+
export const throttle = function throttle(func, timeout = 500) {
|
|
24
24
|
let timer = null
|
|
25
25
|
return (...args) => {
|
|
26
26
|
if (timer === null) {
|
|
@@ -32,4 +32,14 @@ const throttle = function throttle(func, timeout = 500) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Clamp a number between a minimum and maximum value.
|
|
37
|
+
*/
|
|
38
|
+
export const clamp = (value: number, min: number, max: number) =>
|
|
39
|
+
Math.min(Math.max(value, min), max)
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Check if a value is a finite number.
|
|
43
|
+
*/
|
|
44
|
+
export const isNumber = (value: unknown): value is number =>
|
|
45
|
+
typeof value === "number" && Number.isFinite(value)
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import "../leu-range.js";
|
|
2
|
-
import "../../input/leu-input.js";
|
|
3
|
-
/**
|
|
4
|
-
* @type {import("@storybook/web-components").Meta}
|
|
5
|
-
*/
|
|
6
|
-
declare const _default: {
|
|
7
|
-
title: string;
|
|
8
|
-
component: string;
|
|
9
|
-
parameters: {
|
|
10
|
-
design: {
|
|
11
|
-
type: string;
|
|
12
|
-
url: string;
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
args: {
|
|
16
|
-
label: string;
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
export default _default;
|
|
20
|
-
export declare const Regular: any;
|
|
21
|
-
export declare const Multiple: any;
|
|
22
|
-
export declare const Labeled: any;
|
|
23
|
-
export declare const Disabled: any;
|
|
24
|
-
export declare const Step: any;
|
|
25
|
-
export declare const Combined: any;
|
|
26
|
-
//# sourceMappingURL=range-slider.stories.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"range-slider.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/range/stories/range-slider.stories.ts"],"names":[],"mappings":"AAGA,OAAO,iBAAiB,CAAA;AACxB,OAAO,0BAA0B,CAAA;AAEjC;;GAEG;;;;;;;;;;;;;;AACH,wBAYC;AAiBD,eAAO,MAAM,OAAO,KAAoB,CAAA;AAOxC,eAAO,MAAM,QAAQ,KAAoB,CAAA;AAQzC,eAAO,MAAM,OAAO,KAAoB,CAAA;AAOxC,eAAO,MAAM,QAAQ,KAAoB,CAAA;AAQzC,eAAO,MAAM,IAAI,KAAoB,CAAA;AAmErC,eAAO,MAAM,QAAQ,KAA4B,CAAA"}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { html } from "lit"
|
|
2
|
-
import { ifDefined } from "lit/directives/if-defined.js"
|
|
3
|
-
|
|
4
|
-
import "../leu-range.js"
|
|
5
|
-
import "../../input/leu-input.js"
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @type {import("@storybook/web-components").Meta}
|
|
9
|
-
*/
|
|
10
|
-
export default {
|
|
11
|
-
title: "Components/Range",
|
|
12
|
-
component: "leu-range",
|
|
13
|
-
parameters: {
|
|
14
|
-
design: {
|
|
15
|
-
type: "figma",
|
|
16
|
-
url: "https://www.figma.com/file/d6Pv21UVUbnBs3AdcZijHmbN/KTZH-Design-System?type=design&node-id=17340-81936&mode=design",
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
args: {
|
|
20
|
-
label: "Bereich",
|
|
21
|
-
},
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function Template({ label, disabled, value, min, max, step, multiple }) {
|
|
25
|
-
return html`
|
|
26
|
-
<leu-range
|
|
27
|
-
label=${label}
|
|
28
|
-
?disabled=${disabled}
|
|
29
|
-
?multiple=${multiple}
|
|
30
|
-
min=${ifDefined(min)}
|
|
31
|
-
max=${ifDefined(max)}
|
|
32
|
-
value=${ifDefined(value)}
|
|
33
|
-
step=${ifDefined(step)}
|
|
34
|
-
>
|
|
35
|
-
</leu-range>
|
|
36
|
-
`
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export const Regular = Template.bind({})
|
|
40
|
-
Regular.args = {
|
|
41
|
-
min: 0,
|
|
42
|
-
max: 100,
|
|
43
|
-
value: "15",
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export const Multiple = Template.bind({})
|
|
47
|
-
Multiple.args = {
|
|
48
|
-
min: 1965,
|
|
49
|
-
max: 2022,
|
|
50
|
-
value: "1965, 2022",
|
|
51
|
-
multiple: true,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export const Labeled = Template.bind({})
|
|
55
|
-
Labeled.args = {
|
|
56
|
-
label: "Wert auswählen",
|
|
57
|
-
min: 100000,
|
|
58
|
-
max: 200000,
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export const Disabled = Template.bind({})
|
|
62
|
-
Disabled.args = {
|
|
63
|
-
label: "Wert auswählen",
|
|
64
|
-
min: 0,
|
|
65
|
-
max: 100,
|
|
66
|
-
disabled: true,
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export const Step = Template.bind({})
|
|
70
|
-
Step.args = {
|
|
71
|
-
min: 5,
|
|
72
|
-
max: 123,
|
|
73
|
-
step: 13,
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function CombinedTemplate({
|
|
77
|
-
label,
|
|
78
|
-
disabled,
|
|
79
|
-
value = "",
|
|
80
|
-
min,
|
|
81
|
-
max,
|
|
82
|
-
step,
|
|
83
|
-
multiple,
|
|
84
|
-
}) {
|
|
85
|
-
const values = value.split(",").map((v) => Number(v.trim()))
|
|
86
|
-
function handleInputInput() {
|
|
87
|
-
const inputs = document.querySelectorAll("leu-input")
|
|
88
|
-
const range = document.querySelector("leu-range")
|
|
89
|
-
range.value = [inputs[0].value, inputs[1].value]
|
|
90
|
-
}
|
|
91
|
-
return html`
|
|
92
|
-
<leu-range
|
|
93
|
-
label=${label}
|
|
94
|
-
?disabled=${disabled}
|
|
95
|
-
?multiple=${multiple}
|
|
96
|
-
min=${ifDefined(min)}
|
|
97
|
-
max=${ifDefined(max)}
|
|
98
|
-
value=${ifDefined(value)}
|
|
99
|
-
step=${ifDefined(step)}
|
|
100
|
-
@input=${(e) => {
|
|
101
|
-
const inputs = document.querySelectorAll("leu-input")
|
|
102
|
-
const valueList = e.target.valueAsArray
|
|
103
|
-
|
|
104
|
-
inputs[0].value = valueList[0]
|
|
105
|
-
inputs[1].value = valueList[1]
|
|
106
|
-
}}
|
|
107
|
-
>
|
|
108
|
-
</leu-range>
|
|
109
|
-
<div style="display: flex; gap: 1rem;">
|
|
110
|
-
<leu-input
|
|
111
|
-
label="Von"
|
|
112
|
-
?disabled=${disabled}
|
|
113
|
-
type="number"
|
|
114
|
-
min=${ifDefined(min)}
|
|
115
|
-
max=${ifDefined(max)}
|
|
116
|
-
value=${ifDefined(values[0])}
|
|
117
|
-
step=${ifDefined(step)}
|
|
118
|
-
size="small"
|
|
119
|
-
@input=${handleInputInput}
|
|
120
|
-
></leu-input>
|
|
121
|
-
<leu-input
|
|
122
|
-
label="Von"
|
|
123
|
-
?disabled=${disabled}
|
|
124
|
-
type="number"
|
|
125
|
-
min=${ifDefined(min)}
|
|
126
|
-
max=${ifDefined(max)}
|
|
127
|
-
value=${ifDefined(values[1])}
|
|
128
|
-
step=${ifDefined(step)}
|
|
129
|
-
size="small"
|
|
130
|
-
@input=${handleInputInput}
|
|
131
|
-
></leu-input>
|
|
132
|
-
</div>
|
|
133
|
-
`
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export const Combined = CombinedTemplate.bind({})
|
|
137
|
-
Combined.args = {
|
|
138
|
-
min: 1965,
|
|
139
|
-
max: 2022,
|
|
140
|
-
value: "1965, 2022",
|
|
141
|
-
multiple: true,
|
|
142
|
-
}
|