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