@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
package/dist/Select.js
CHANGED
|
@@ -1,23 +1,15 @@
|
|
|
1
|
-
import { _ as _defineProperty } from './
|
|
2
|
-
import { css,
|
|
1
|
+
import { _ as _defineProperty, L as LeuElement } from './LeuElement-ba5ea33d.js';
|
|
2
|
+
import { css, nothing, html } from 'lit';
|
|
3
3
|
import { classMap } from 'lit/directives/class-map.js';
|
|
4
|
-
import { map } from 'lit/directives/map.js';
|
|
5
|
-
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
6
4
|
import { createRef, ref } from 'lit/directives/ref.js';
|
|
7
|
-
import {
|
|
8
|
-
import { H as HasSlotController } from './Button-
|
|
9
|
-
import './
|
|
10
|
-
import './
|
|
11
|
-
import './
|
|
12
|
-
import './
|
|
13
|
-
import './
|
|
14
|
-
import './defineElement-40372b4b.js';
|
|
15
|
-
import './Menu.js';
|
|
16
|
-
import './MenuItem.js';
|
|
17
|
-
import 'lit/static-html.js';
|
|
18
|
-
import './Input.js';
|
|
5
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
6
|
+
import { H as HasSlotController, L as LeuButton } from './Button-7370f901.js';
|
|
7
|
+
import { LeuMenu } from './Menu.js';
|
|
8
|
+
import { LeuMenuItem } from './MenuItem.js';
|
|
9
|
+
import { LeuIcon } from './Icon.js';
|
|
10
|
+
import { LeuInput } from './Input.js';
|
|
11
|
+
import { LeuPopup } from './Popup.js';
|
|
19
12
|
import 'lit/directives/live.js';
|
|
20
|
-
import './Popup.js';
|
|
21
13
|
import '@floating-ui/dom';
|
|
22
14
|
|
|
23
15
|
var css_248z = css`:host,
|
|
@@ -66,7 +58,7 @@ var css_248z = css`:host,
|
|
|
66
58
|
font-family: var(--select-font-regular);
|
|
67
59
|
}
|
|
68
60
|
|
|
69
|
-
|
|
61
|
+
:host([disabled]) {
|
|
70
62
|
--select-color: var(--select-color-disabled);
|
|
71
63
|
--select-color-focus: var(--select-color-disabled);
|
|
72
64
|
--select-border-color: var(--select-border-color-disabled);
|
|
@@ -153,19 +145,18 @@ var css_248z = css`:host,
|
|
|
153
145
|
outline-offset: 2px;
|
|
154
146
|
}
|
|
155
147
|
|
|
156
|
-
.select[disabled]
|
|
157
|
-
.select[disabled] .clear-button {
|
|
148
|
+
.select-toggle[disabled],
|
|
149
|
+
.select-toggle[disabled] .clear-button {
|
|
158
150
|
cursor: inherit;
|
|
159
151
|
}
|
|
160
152
|
|
|
161
|
-
.select[disabled] .label {
|
|
153
|
+
.select-toggle[disabled] .label {
|
|
162
154
|
color: var(--select-label-color);
|
|
163
155
|
}
|
|
164
156
|
|
|
165
157
|
.select-toggle.open .label,
|
|
166
158
|
.select-toggle.filled .label,
|
|
167
|
-
.select
|
|
168
|
-
.select:not([disabled]) .select-toggle:active:not([disabled]) .label {
|
|
159
|
+
.select-toggle:focus .label {
|
|
169
160
|
color: var(--select-label-color);
|
|
170
161
|
font-family: var(--select-font-black);
|
|
171
162
|
font-size: 0.75rem;
|
|
@@ -208,7 +199,7 @@ var css_248z = css`:host,
|
|
|
208
199
|
flex-direction: column;
|
|
209
200
|
|
|
210
201
|
width: 100%;
|
|
211
|
-
max-height: var(--auto-size-available-height);
|
|
202
|
+
max-height: min(var(--auto-size-available-height), 24rem);
|
|
212
203
|
|
|
213
204
|
padding: 0;
|
|
214
205
|
margin: 0;
|
|
@@ -219,12 +210,9 @@ var css_248z = css`:host,
|
|
|
219
210
|
box-shadow: var(--select-box-shadow-regular), var(--select-box-shadow-short);
|
|
220
211
|
}
|
|
221
212
|
|
|
222
|
-
.
|
|
213
|
+
.menu {
|
|
223
214
|
display: block;
|
|
224
|
-
padding: 0;
|
|
225
|
-
margin: 0;
|
|
226
215
|
overflow: auto;
|
|
227
|
-
max-height: 100%;
|
|
228
216
|
}
|
|
229
217
|
|
|
230
218
|
.before,
|
|
@@ -241,24 +229,49 @@ var css_248z = css`:host,
|
|
|
241
229
|
display: none;
|
|
242
230
|
}
|
|
243
231
|
|
|
232
|
+
.apply-button-wrapper {
|
|
233
|
+
background-color: var(--leu-color-black-10);
|
|
234
|
+
padding: 0.75rem;
|
|
235
|
+
}
|
|
236
|
+
|
|
244
237
|
.apply-button {
|
|
245
238
|
display: block;
|
|
246
|
-
margin: 0.75rem;
|
|
247
239
|
}
|
|
248
240
|
|
|
249
241
|
.select-search {
|
|
250
242
|
margin: 0.75rem;
|
|
251
243
|
}
|
|
244
|
+
|
|
245
|
+
.filter-message-empty {
|
|
246
|
+
background: var(--leu-color-black-0);
|
|
247
|
+
color: var(--leu-color-black-transp-60);
|
|
248
|
+
|
|
249
|
+
padding: 0.75rem;
|
|
250
|
+
margin: 0;
|
|
251
|
+
}
|
|
252
252
|
`;
|
|
253
253
|
|
|
254
254
|
/**
|
|
255
255
|
* @tagname leu-select
|
|
256
256
|
* @slot before - Optional content the appears before the option list
|
|
257
257
|
* @slot after - Optional content the appears after the option list
|
|
258
|
+
* @property {string} name - Reflects to the name attribute of the hidden input field that would be used in a form
|
|
259
|
+
* @property {boolean} open - The expanded state of the popup
|
|
260
|
+
* @property {string} label - The label of the select
|
|
261
|
+
* @property {array} value - List of selected values. If they're set from outside the component, the select element tries to find all the options with the given values and selects them.
|
|
262
|
+
* @property {boolean} clearable - Show a clearable button to reset the value
|
|
263
|
+
* @property {boolean} disabled - If the select should be disabled
|
|
264
|
+
* @property {boolean} filterable - Show an input field to filter the options inside the popup
|
|
265
|
+
* @property {boolean} multiple - Allow multiple selections
|
|
266
|
+
* @attribute {string} value - The selected values separated by commas.
|
|
258
267
|
*/
|
|
259
|
-
class LeuSelect extends
|
|
268
|
+
class LeuSelect extends LeuElement {
|
|
260
269
|
static get properties() {
|
|
261
270
|
return {
|
|
271
|
+
name: {
|
|
272
|
+
type: String,
|
|
273
|
+
reflect: true
|
|
274
|
+
},
|
|
262
275
|
open: {
|
|
263
276
|
type: Boolean,
|
|
264
277
|
reflect: true
|
|
@@ -267,11 +280,16 @@ class LeuSelect extends LitElement {
|
|
|
267
280
|
type: String,
|
|
268
281
|
reflect: true
|
|
269
282
|
},
|
|
270
|
-
options: {
|
|
271
|
-
type: Array
|
|
272
|
-
},
|
|
273
283
|
value: {
|
|
274
|
-
type: Array
|
|
284
|
+
type: Array,
|
|
285
|
+
converter: {
|
|
286
|
+
fromAttribute(value) {
|
|
287
|
+
if (value) {
|
|
288
|
+
return value.split(",").map(v => v.trim());
|
|
289
|
+
}
|
|
290
|
+
return value;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
275
293
|
},
|
|
276
294
|
clearable: {
|
|
277
295
|
type: Boolean,
|
|
@@ -289,7 +307,13 @@ class LeuSelect extends LitElement {
|
|
|
289
307
|
type: Boolean,
|
|
290
308
|
reflect: true
|
|
291
309
|
},
|
|
292
|
-
|
|
310
|
+
_optionFilter: {
|
|
311
|
+
state: true
|
|
312
|
+
},
|
|
313
|
+
_hasFilterResults: {
|
|
314
|
+
state: true
|
|
315
|
+
},
|
|
316
|
+
_displayValue: {
|
|
293
317
|
state: true
|
|
294
318
|
}
|
|
295
319
|
};
|
|
@@ -313,18 +337,18 @@ class LeuSelect extends LitElement {
|
|
|
313
337
|
* @internal
|
|
314
338
|
* @param {MouseEvent} event
|
|
315
339
|
*/
|
|
316
|
-
_defineProperty(this, "
|
|
340
|
+
_defineProperty(this, "_handleDocumentClick", event => {
|
|
317
341
|
if (event.target instanceof Node && !this.contains(event.target) && this.open) {
|
|
318
|
-
this.
|
|
342
|
+
this._closeDropdown();
|
|
319
343
|
}
|
|
320
344
|
});
|
|
321
345
|
/**
|
|
322
346
|
* @internal
|
|
323
|
-
* @param {KeyboardEvent}
|
|
347
|
+
* @param {KeyboardEvent} event
|
|
324
348
|
*/
|
|
325
|
-
_defineProperty(this, "
|
|
349
|
+
_defineProperty(this, "_handleKeyDown", event => {
|
|
326
350
|
if (event.key === "Escape") {
|
|
327
|
-
this.
|
|
351
|
+
this._closeDropdown();
|
|
328
352
|
}
|
|
329
353
|
});
|
|
330
354
|
this.open = false;
|
|
@@ -334,199 +358,244 @@ class LeuSelect extends LitElement {
|
|
|
334
358
|
this.clearable = false;
|
|
335
359
|
this.filterable = false;
|
|
336
360
|
this.value = [];
|
|
337
|
-
this.options = [];
|
|
338
361
|
this.label = "";
|
|
362
|
+
this.name = "";
|
|
339
363
|
|
|
340
364
|
/** @internal */
|
|
341
|
-
this.
|
|
365
|
+
this._optionFilter = "";
|
|
342
366
|
|
|
343
367
|
/** @internal */
|
|
344
|
-
this.
|
|
368
|
+
this._hasFilterResults = true;
|
|
345
369
|
|
|
346
370
|
/** @internal */
|
|
347
|
-
this.
|
|
371
|
+
this._deferedChangeEvent = false;
|
|
348
372
|
|
|
349
373
|
/** @internal */
|
|
350
|
-
this.
|
|
374
|
+
this._displayValue = "";
|
|
351
375
|
|
|
352
|
-
/**
|
|
353
|
-
* @type {import("lit/directives/ref").Ref<import("../menu/Menu").LeuMenu>}
|
|
354
|
-
*/
|
|
355
|
-
this.menuRef = createRef();
|
|
356
376
|
/**
|
|
357
377
|
* @type {import("lit/directives/ref").Ref<import("../input/Input").LeuInput>}
|
|
358
378
|
*/
|
|
359
|
-
this.
|
|
379
|
+
this._optionFilterRef = createRef();
|
|
360
380
|
/**
|
|
361
381
|
* @type {import("lit/directives/ref").Ref<HTMLButtonElement>}
|
|
362
382
|
*/
|
|
363
|
-
this.
|
|
383
|
+
this._toggleButtonRef = createRef();
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* @type {import("lit/directives/ref").Ref<import("../menu/Menu").LeuMenu>}
|
|
387
|
+
*/
|
|
388
|
+
this._menuRef = createRef();
|
|
364
389
|
}
|
|
365
390
|
connectedCallback() {
|
|
366
391
|
super.connectedCallback();
|
|
367
|
-
document.addEventListener("click", this.
|
|
392
|
+
document.addEventListener("click", this._handleDocumentClick);
|
|
368
393
|
}
|
|
369
394
|
disconnectedCallback() {
|
|
370
395
|
super.disconnectedCallback();
|
|
371
|
-
document.removeEventListener("click", this.
|
|
396
|
+
document.removeEventListener("click", this._handleDocumentClick);
|
|
372
397
|
}
|
|
373
398
|
updated(changedProperties) {
|
|
374
399
|
if (changedProperties.has("open") && this.open) {
|
|
375
400
|
if (this.filterable) {
|
|
376
|
-
this.
|
|
401
|
+
this._optionFilterRef.value.focus();
|
|
377
402
|
} else {
|
|
378
|
-
this.
|
|
403
|
+
this._menuRef.value.focusItem(0);
|
|
379
404
|
}
|
|
380
405
|
} else if (changedProperties.has("open") && !this.open) {
|
|
381
|
-
|
|
406
|
+
// TODO: Check if the ref is guaranteed to be set
|
|
407
|
+
// in the updated method.
|
|
408
|
+
// According to the lit documentation, a ref callback
|
|
409
|
+
// CAN be called with undefined.
|
|
410
|
+
this._toggleButtonRef.value?.focus();
|
|
411
|
+
}
|
|
412
|
+
if (changedProperties.has("value") || changedProperties.has("_optionFilter")) {
|
|
413
|
+
this._updateMenuItems({
|
|
414
|
+
value: changedProperties.has("value"),
|
|
415
|
+
optionFilter: changedProperties.has("_optionFilter")
|
|
416
|
+
});
|
|
382
417
|
}
|
|
383
418
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Apply the current state to the menu items.
|
|
422
|
+
* - Set the active property when the value property has changed.
|
|
423
|
+
* - Hide menu items that do not match the filter.
|
|
424
|
+
*/
|
|
425
|
+
async _updateMenuItems(changed) {
|
|
426
|
+
/** @type {LeuMenu} */
|
|
427
|
+
const menu = this._menuRef.value;
|
|
428
|
+
await menu.updateComplete;
|
|
429
|
+
const menuItems = menu.getMenuItems();
|
|
430
|
+
let hasFilterResults = false;
|
|
431
|
+
|
|
432
|
+
/* eslint-disable no-param-reassign */
|
|
433
|
+
menuItems.forEach(menuItem => {
|
|
434
|
+
if (changed.optionFilter) {
|
|
435
|
+
menuItem.hidden = this._optionFilter !== "" && !menuItem.textContent.toLowerCase().includes(this._optionFilter.toLowerCase());
|
|
436
|
+
hasFilterResults = hasFilterResults || !menuItem.hidden;
|
|
437
|
+
}
|
|
438
|
+
if (changed.value) {
|
|
439
|
+
menuItem.active = this._isSelected(menuItem.getValue());
|
|
440
|
+
if (!this.multiple && menuItem.active) {
|
|
441
|
+
this._displayValue = menuItem.textContent;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
/* eslint-enable no-param-reassign */
|
|
446
|
+
|
|
447
|
+
if (changed.optionFilter) {
|
|
448
|
+
this._hasFilterResults = hasFilterResults;
|
|
449
|
+
menu.setCurrentItem(0);
|
|
387
450
|
}
|
|
388
|
-
return LeuSelect.getOptionLabel(value[0]);
|
|
389
451
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
452
|
+
/**
|
|
453
|
+
* @internal
|
|
454
|
+
* @param {KeyboardEvent} event
|
|
455
|
+
*/
|
|
456
|
+
async _handleToggleKeyDown(event) {
|
|
457
|
+
if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
|
|
458
|
+
event.preventDefault();
|
|
459
|
+
const menu = this._menuRef.value;
|
|
460
|
+
this.open = true;
|
|
461
|
+
await this.updateComplete;
|
|
462
|
+
if (event.key === "ArrowDown" || event.key === "Home") {
|
|
463
|
+
menu.focusItem(0);
|
|
464
|
+
} else if (event.key === "ArrowUp" || event.key === "End") {
|
|
465
|
+
menu.focusItem(-1);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
395
468
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* @internal
|
|
472
|
+
* @param {KeyboardEvent} event
|
|
473
|
+
*/
|
|
474
|
+
_handleFilterInputKeyDown(event) {
|
|
475
|
+
if (event.key === "ArrowDown") {
|
|
476
|
+
this._menuRef.value.focusItem(0);
|
|
477
|
+
} else if (event.key === "ArrowUp") {
|
|
478
|
+
this._menuRef.value.focusItem(-1);
|
|
479
|
+
}
|
|
399
480
|
}
|
|
400
|
-
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Determines the value or label that should be displayed inside the toggle button.
|
|
484
|
+
* @returns {String | nothing}
|
|
485
|
+
*/
|
|
486
|
+
_getDisplayValue() {
|
|
487
|
+
if (this.multiple) {
|
|
488
|
+
return this.value.length === 0 ? `` : `${this.value.length} gewählt`;
|
|
489
|
+
}
|
|
490
|
+
return this._displayValue ?? nothing;
|
|
491
|
+
}
|
|
492
|
+
_emitInputEvent() {
|
|
401
493
|
const inputevent = new CustomEvent("input", {
|
|
402
494
|
composed: true,
|
|
403
495
|
bubbles: true
|
|
404
496
|
});
|
|
405
497
|
this.dispatchEvent(inputevent);
|
|
406
498
|
}
|
|
407
|
-
|
|
499
|
+
_emitChangeEvent() {
|
|
408
500
|
const changeevent = new CustomEvent("change", {
|
|
409
501
|
composed: true,
|
|
410
502
|
bubbles: true
|
|
411
503
|
});
|
|
412
504
|
this.dispatchEvent(changeevent);
|
|
413
505
|
}
|
|
414
|
-
|
|
506
|
+
_clearValue(event) {
|
|
415
507
|
if (!this.disabled) {
|
|
416
508
|
event.stopPropagation();
|
|
417
509
|
this.value = [];
|
|
418
510
|
}
|
|
419
|
-
this.
|
|
511
|
+
this._emitInputEvent();
|
|
512
|
+
this._emitChangeEvent();
|
|
420
513
|
}
|
|
421
|
-
|
|
514
|
+
_toggleDropdown() {
|
|
422
515
|
if (!this.disabled) {
|
|
423
516
|
this.open = !this.open;
|
|
424
517
|
}
|
|
425
518
|
}
|
|
426
|
-
|
|
427
|
-
this.open = true;
|
|
428
|
-
}
|
|
429
|
-
closeDropdown() {
|
|
519
|
+
_closeDropdown() {
|
|
430
520
|
this.open = false;
|
|
431
|
-
if (this.
|
|
432
|
-
this.
|
|
433
|
-
this.
|
|
521
|
+
if (this._deferedChangeEvent) {
|
|
522
|
+
this._emitChangeEvent();
|
|
523
|
+
this._deferedChangeEvent = false;
|
|
434
524
|
}
|
|
435
525
|
}
|
|
526
|
+
_handleFilterInput(event) {
|
|
527
|
+
this._optionFilter = event.target.value;
|
|
528
|
+
}
|
|
436
529
|
|
|
437
530
|
/**
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
* @
|
|
531
|
+
* Checks if the given value is selected.
|
|
532
|
+
* @param {String} menuItemValue
|
|
533
|
+
* @returns {Boolean}
|
|
441
534
|
*/
|
|
442
|
-
|
|
443
|
-
|
|
535
|
+
_isSelected(menuItemValue) {
|
|
536
|
+
return this.value.includes(menuItemValue);
|
|
537
|
+
}
|
|
538
|
+
_handleMenuItemClick(event) {
|
|
539
|
+
if (!(event.target instanceof LeuMenuItem) || event.target.disabled) {
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/** @type {LeuMenuItem} */
|
|
544
|
+
const menuItem = event.target;
|
|
545
|
+
const value = menuItem.getValue();
|
|
546
|
+
const isSelected = this._isSelected(value);
|
|
444
547
|
if (this.multiple) {
|
|
445
|
-
this.value = isSelected ? this.value.filter(v => v !==
|
|
446
|
-
this.
|
|
548
|
+
this.value = isSelected ? this.value.filter(v => v !== value) : this.value.concat(value);
|
|
549
|
+
this._deferedChangeEvent = true;
|
|
447
550
|
} else {
|
|
448
|
-
this.value = isSelected ? [] : [
|
|
551
|
+
this.value = isSelected ? [] : [value];
|
|
552
|
+
this._displayValue = isSelected ? "" : menuItem.textContent;
|
|
449
553
|
}
|
|
450
|
-
this.
|
|
554
|
+
this._emitInputEvent();
|
|
451
555
|
if (!this.multiple) {
|
|
452
|
-
this.
|
|
556
|
+
this._closeDropdown();
|
|
453
557
|
}
|
|
454
558
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
464
|
-
renderMenu() {
|
|
465
|
-
const menuClasses = {
|
|
466
|
-
"select-menu": true,
|
|
467
|
-
multiple: this.multiple
|
|
468
|
-
};
|
|
469
|
-
const filteredOptions = this.getFilteredOptions();
|
|
470
|
-
return html`
|
|
471
|
-
<leu-menu
|
|
472
|
-
role="listbox"
|
|
473
|
-
class=${classMap(menuClasses)}
|
|
474
|
-
aria-multiselectable="${this.multiple}"
|
|
475
|
-
aria-labelledby="select-label"
|
|
476
|
-
ref=${ref(this.menuRef)}
|
|
477
|
-
>
|
|
478
|
-
${filteredOptions.length > 0 ? map(this.getFilteredOptions(), option => {
|
|
479
|
-
const isSelected = this.isSelected(option);
|
|
480
|
-
let beforeIcon;
|
|
481
|
-
if (this.multiple && isSelected) {
|
|
482
|
-
beforeIcon = "check";
|
|
483
|
-
} else if (this.multiple) {
|
|
484
|
-
beforeIcon = "EMPTY";
|
|
485
|
-
}
|
|
486
|
-
return html`<leu-menu-item
|
|
487
|
-
before=${ifDefined(beforeIcon)}
|
|
488
|
-
@click=${() => this.selectOption(option)}
|
|
489
|
-
role="option"
|
|
490
|
-
label=${LeuSelect.getOptionLabel(option)}
|
|
491
|
-
?active=${isSelected}
|
|
492
|
-
aria-selected=${isSelected}
|
|
493
|
-
>
|
|
494
|
-
</leu-menu-item>`;
|
|
495
|
-
}) : html`<leu-menu-item
|
|
496
|
-
label=${this.optionFilter === "" ? "Keine Optionen" : "Keine Resultate"}
|
|
497
|
-
disabled
|
|
498
|
-
></leu-menu-item>`}
|
|
499
|
-
</leu-menu>
|
|
500
|
-
`;
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Close the dropdown if the focus moves outside the component.
|
|
562
|
+
*/
|
|
563
|
+
_handlePopupFocusOut(event) {
|
|
564
|
+
if (!this.contains(event.relatedTarget) && !this.shadowRoot.contains(event.relatedTarget)) {
|
|
565
|
+
this._closeDropdown();
|
|
566
|
+
}
|
|
501
567
|
}
|
|
502
|
-
|
|
568
|
+
_renderFilterInput() {
|
|
503
569
|
if (this.filterable) {
|
|
504
570
|
return html` <leu-input
|
|
505
571
|
class="select-search"
|
|
506
572
|
size="small"
|
|
507
|
-
@input=${this.
|
|
573
|
+
@input=${this._handleFilterInput}
|
|
574
|
+
@keydown=${this._handleFilterInputKeyDown}
|
|
508
575
|
clearable
|
|
509
|
-
ref=${ref(this.
|
|
576
|
+
ref=${ref(this._optionFilterRef)}
|
|
510
577
|
label="Nach Stichwort filtern"
|
|
511
578
|
></leu-input>`;
|
|
512
579
|
}
|
|
513
580
|
return nothing;
|
|
514
581
|
}
|
|
515
|
-
|
|
582
|
+
_renderApplyButton() {
|
|
516
583
|
if (this.multiple) {
|
|
517
584
|
return html`
|
|
518
|
-
<
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
585
|
+
<div class="apply-button-wrapper">
|
|
586
|
+
<leu-button
|
|
587
|
+
type="button"
|
|
588
|
+
class="apply-button"
|
|
589
|
+
@click=${this._closeDropdown}
|
|
590
|
+
fluid
|
|
591
|
+
>Anwenden</leu-button
|
|
592
|
+
>
|
|
593
|
+
</div>
|
|
525
594
|
`;
|
|
526
595
|
}
|
|
527
596
|
return nothing;
|
|
528
597
|
}
|
|
529
|
-
|
|
598
|
+
_renderToggleButton() {
|
|
530
599
|
const toggleClasses = {
|
|
531
600
|
"select-toggle": true,
|
|
532
601
|
open: this.open,
|
|
@@ -534,27 +603,31 @@ class LeuSelect extends LitElement {
|
|
|
534
603
|
labeled: this.label !== ""
|
|
535
604
|
};
|
|
536
605
|
return html`<button
|
|
606
|
+
${ref(this._toggleButtonRef)}
|
|
537
607
|
type="button"
|
|
538
608
|
class=${classMap(toggleClasses)}
|
|
539
|
-
@click=${this.
|
|
540
|
-
|
|
541
|
-
|
|
609
|
+
@click=${this._toggleDropdown}
|
|
610
|
+
@keydown=${this._handleToggleKeyDown}
|
|
611
|
+
?disabled=${this.disabled}
|
|
612
|
+
aria-controls="select-popup"
|
|
542
613
|
aria-expanded="${this.open}"
|
|
614
|
+
aria-labelledby="select-label"
|
|
543
615
|
role="combobox"
|
|
544
|
-
ref=${ref(this.toggleButtonRef)}
|
|
545
616
|
slot="anchor"
|
|
546
617
|
>
|
|
547
618
|
<span class="label" id="select-label">${this.label}</span>
|
|
548
|
-
<span class="value"> ${this.
|
|
549
|
-
<span class="arrow-icon">
|
|
619
|
+
<span class="value"> ${this._getDisplayValue()} </span>
|
|
620
|
+
<span class="arrow-icon">
|
|
621
|
+
<leu-icon name="angleDropDown"></leu-icon>
|
|
622
|
+
</span>
|
|
550
623
|
${this.clearable && this.value.length !== 0 ? html`<button
|
|
551
624
|
type="button"
|
|
552
625
|
class="clear-button"
|
|
553
|
-
@click=${this.
|
|
626
|
+
@click=${this._clearValue}
|
|
554
627
|
aria-label=${`${this.label} zurücksetzen`}
|
|
555
628
|
?disabled=${this.disabled}
|
|
556
629
|
>
|
|
557
|
-
|
|
630
|
+
<leu-icon name="clear"></leu-icon>
|
|
558
631
|
</button>` : nothing}
|
|
559
632
|
</button>`;
|
|
560
633
|
}
|
|
@@ -564,36 +637,61 @@ class LeuSelect extends LitElement {
|
|
|
564
637
|
"select--has-before": this.hasSlotController.test("before"),
|
|
565
638
|
"select--has-after": this.hasSlotController.test("after")
|
|
566
639
|
};
|
|
640
|
+
|
|
641
|
+
/*
|
|
642
|
+
* We use the click event listener with the event delegation pattern
|
|
643
|
+
* so this is not a violation of the rule.
|
|
644
|
+
*/
|
|
645
|
+
/* eslint-disable lit-a11y/click-events-have-key-events */
|
|
567
646
|
return html`<div
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
aria-readonly="${this.disabled}"
|
|
571
|
-
aria-labelledby="select-label"
|
|
572
|
-
@keydown=${this.handleKeyDown}
|
|
573
|
-
>
|
|
574
|
-
<leu-popup
|
|
575
|
-
?active=${this.open}
|
|
576
|
-
placement="bottom-start"
|
|
577
|
-
flip
|
|
578
|
-
matchSize="width"
|
|
579
|
-
autoSize="height"
|
|
580
|
-
autoSizePadding="8"
|
|
647
|
+
class=${classMap(selectClasses)}
|
|
648
|
+
@keydown=${this._handleKeyDown}
|
|
581
649
|
>
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
650
|
+
<leu-popup
|
|
651
|
+
?active=${this.open}
|
|
652
|
+
placement="bottom-start"
|
|
653
|
+
flip
|
|
654
|
+
matchSize="width"
|
|
655
|
+
autoSize="height"
|
|
656
|
+
autoSizePadding="8"
|
|
587
657
|
>
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
658
|
+
${this._renderToggleButton()}
|
|
659
|
+
<div
|
|
660
|
+
id="select-popup"
|
|
661
|
+
class="select-menu-container"
|
|
662
|
+
@focusout=${this._handlePopupFocusOut}
|
|
663
|
+
>
|
|
664
|
+
<slot name="before" class="before"></slot>
|
|
665
|
+
${this._renderFilterInput()}
|
|
666
|
+
<leu-menu
|
|
667
|
+
ref=${ref(this._menuRef)}
|
|
668
|
+
role="listbox"
|
|
669
|
+
aria-multiselectable=${ifDefined(this.multiple ? "true" : undefined)}
|
|
670
|
+
class="menu"
|
|
671
|
+
@click=${this._handleMenuItemClick}
|
|
672
|
+
>
|
|
673
|
+
<slot></slot>
|
|
674
|
+
</leu-menu>
|
|
675
|
+
${this._hasFilterResults ? nothing : html` <p class="filter-message-empty" aria-live="polite">
|
|
676
|
+
Keine Resultate
|
|
677
|
+
</p>`}
|
|
678
|
+
${this._renderApplyButton()}
|
|
679
|
+
<slot name="after" class="after"></slot>
|
|
680
|
+
</div>
|
|
681
|
+
</leu-popup>
|
|
682
|
+
</div>
|
|
683
|
+
<input type="hidden" name=${this.name} .value=${this.value.join(",")} />`;
|
|
684
|
+
/* eslint-enable lit-a11y/click-events-have-key-events */
|
|
595
685
|
}
|
|
596
686
|
}
|
|
687
|
+
_defineProperty(LeuSelect, "dependencies", {
|
|
688
|
+
"leu-button": LeuButton,
|
|
689
|
+
"leu-menu": LeuMenu,
|
|
690
|
+
"leu-menu-item": LeuMenuItem,
|
|
691
|
+
"leu-icon": LeuIcon,
|
|
692
|
+
"leu-input": LeuInput,
|
|
693
|
+
"leu-popup": LeuPopup
|
|
694
|
+
});
|
|
597
695
|
_defineProperty(LeuSelect, "styles", css_248z);
|
|
598
696
|
|
|
599
697
|
export { LeuSelect };
|