@statistikzh/leu 0.26.0 → 0.27.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.
Files changed (115) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +21 -0
  3. package/dist/{Accordion-B04QkmHz.js → Accordion-DLsqXcK8.js} +1 -1
  4. package/dist/Accordion.js +2 -2
  5. package/dist/{Button-BkhqVjug.js → Button-BSyDL_cV.js} +3 -3
  6. package/dist/Button.js +4 -4
  7. package/dist/{ButtonGroup-B8U9fDvM.js → ButtonGroup-BmSvl-Oc.js} +2 -2
  8. package/dist/ButtonGroup.js +5 -5
  9. package/dist/{ChartWrapper-CSMFwz9e.js → ChartWrapper-CvDvQsd5.js} +2 -2
  10. package/dist/ChartWrapper.js +3 -3
  11. package/dist/{Checkbox-Dd1QLpfn.js → Checkbox-Cl_X6gBJ.js} +2 -2
  12. package/dist/Checkbox.js +3 -3
  13. package/dist/{CheckboxGroup-Bz2eWEFL.js → CheckboxGroup-BKhOmZYX.js} +2 -2
  14. package/dist/CheckboxGroup.js +4 -4
  15. package/dist/{Chip-XAQIIsXq.js → Chip-McVP3N_x.js} +1 -1
  16. package/dist/Chip.js +2 -2
  17. package/dist/{ChipGroup-DLqfK2kn.js → ChipGroup-DUGavZeU.js} +1 -1
  18. package/dist/ChipGroup.js +3 -3
  19. package/dist/ChipLink.js +2 -2
  20. package/dist/ChipRemovable.js +3 -3
  21. package/dist/ChipSelectable.js +2 -2
  22. package/dist/{Dialog-DHuXR_oo.js → Dialog-BlDd4T2u.js} +2 -2
  23. package/dist/Dialog.js +3 -3
  24. package/dist/{Dropdown-DtFTePbc.js → Dropdown-BLxSIe6p.js} +5 -5
  25. package/dist/Dropdown.js +8 -8
  26. package/dist/{FileInput-b8sbLDPI.js → FileInput-DntYrpZ-.js} +22 -7
  27. package/dist/FileInput.d.ts +11 -0
  28. package/dist/FileInput.js +6 -6
  29. package/dist/{Icon-C_yYuynf.js → Icon-CbZXpyHU.js} +1 -1
  30. package/dist/Icon.js +2 -2
  31. package/dist/{Input-D2THgo7c.d.ts → Input-CeaAOB4p.d.ts} +6 -2
  32. package/dist/{Input-DEOVocTa.js → Input-DBXX7ev8.js} +32 -11
  33. package/dist/Input.d.ts +1 -1
  34. package/dist/Input.js +3 -3
  35. package/dist/{LeuElement-BeFrgKes.js → LeuElement-k4RjIeoG.js} +1 -1
  36. package/dist/{Menu-BeqqtCw6.js → Menu-Cu8eIF1T.js} +2 -2
  37. package/dist/Menu.js +4 -4
  38. package/dist/{MenuItem-DVg8-1Bq.js → MenuItem-Cs3KFhJm.js} +2 -2
  39. package/dist/MenuItem.js +3 -3
  40. package/dist/{Message-BhknWvAF.js → Message-C6Zlk_2p.js} +2 -2
  41. package/dist/Message.js +3 -3
  42. package/dist/{Pagination-DJI5MIi_.js → Pagination-CB2eVlXk.js} +4 -4
  43. package/dist/Pagination.js +6 -6
  44. package/dist/{Placeholder-BJybFwSg.js → Placeholder-DHMexMhK.js} +1 -1
  45. package/dist/Placeholder.js +2 -2
  46. package/dist/{Popup-DNlm_9AA.js → Popup-8jhVy8gB.js} +1 -1
  47. package/dist/Popup.js +2 -2
  48. package/dist/{ProgressBar-B0wYj1KF.js → ProgressBar-CG0_lHfS.js} +1 -1
  49. package/dist/ProgressBar.js +2 -2
  50. package/dist/{Radio-DMCL8c4D.js → Radio-DG3xqP3s.js} +1 -1
  51. package/dist/Radio.js +2 -2
  52. package/dist/{RadioGroup-CM6IyBlq.js → RadioGroup-BKCp9ICX.js} +2 -2
  53. package/dist/RadioGroup.js +3 -3
  54. package/dist/{Range-B72rtfln.js → Range-7LrESv4K.js} +1 -1
  55. package/dist/Range.js +2 -2
  56. package/dist/{ScrollTop-BFAqBVDR.js → ScrollTop-CJJsfniA.js} +20 -20
  57. package/dist/ScrollTop.d.ts +5 -5
  58. package/dist/ScrollTop.js +5 -5
  59. package/dist/{Select-vxl3BvD4.js → Select-CxEDXIBn.js} +153 -133
  60. package/dist/Select.d.ts +73 -71
  61. package/dist/Select.js +9 -9
  62. package/dist/{Spinner-DDTqijTO.js → Spinner-VhKfzI3Q.js} +1 -1
  63. package/dist/Spinner.js +2 -2
  64. package/dist/{Table-BgCxfBcm.js → Table-rg_JCtsA.js} +3 -3
  65. package/dist/Table.js +7 -7
  66. package/dist/{Tag-DK2KkPIQ.js → Tag-BROUaDAZ.js} +1 -1
  67. package/dist/Tag.js +2 -2
  68. package/dist/{VisuallyHidden-pll3amXE.js → VisuallyHidden-Co_txzxB.js} +1 -1
  69. package/dist/VisuallyHidden.js +2 -2
  70. package/dist/index.d.ts +1 -1
  71. package/dist/index.js +30 -30
  72. package/dist/leu-accordion.js +2 -2
  73. package/dist/leu-button-group.js +5 -5
  74. package/dist/leu-button.js +4 -4
  75. package/dist/leu-chart-wrapper.js +3 -3
  76. package/dist/leu-checkbox-group.js +4 -4
  77. package/dist/leu-checkbox.js +3 -3
  78. package/dist/leu-chip-group.js +3 -3
  79. package/dist/leu-chip-link.js +2 -2
  80. package/dist/leu-chip-removable.js +3 -3
  81. package/dist/leu-chip-selectable.js +2 -2
  82. package/dist/leu-dialog.js +3 -3
  83. package/dist/leu-dropdown.js +8 -8
  84. package/dist/leu-file-input.js +6 -6
  85. package/dist/leu-icon.js +2 -2
  86. package/dist/leu-input.d.ts +1 -1
  87. package/dist/leu-input.js +3 -3
  88. package/dist/leu-menu-item.js +3 -3
  89. package/dist/leu-menu.js +4 -4
  90. package/dist/leu-message.js +3 -3
  91. package/dist/leu-pagination.js +6 -6
  92. package/dist/leu-placeholder.js +2 -2
  93. package/dist/leu-popup.js +2 -2
  94. package/dist/leu-progress-bar.js +2 -2
  95. package/dist/leu-radio-group.js +3 -3
  96. package/dist/leu-radio.js +2 -2
  97. package/dist/leu-range.js +2 -2
  98. package/dist/leu-scroll-top.js +5 -5
  99. package/dist/leu-select.js +9 -9
  100. package/dist/leu-spinner.js +2 -2
  101. package/dist/leu-table.js +7 -7
  102. package/dist/leu-tag.js +2 -2
  103. package/dist/leu-visually-hidden.js +2 -2
  104. package/dist/vscode.html-custom-data.json +14 -27
  105. package/dist/vue/index.d.ts +16 -24
  106. package/dist/web-types.json +41 -60
  107. package/package.json +1 -1
  108. package/src/components/file-input/FileInput.ts +24 -5
  109. package/src/components/input/Input.ts +43 -8
  110. package/src/components/input/test/input.test.ts +106 -1
  111. package/src/components/scroll-top/ScrollTop.ts +18 -16
  112. package/src/components/select/Select.ts +198 -124
  113. package/src/components/select/select.css +4 -0
  114. package/src/components/select/stories/select.stories.ts +10 -0
  115. package/src/components/select/test/select.test.ts +440 -35
@@ -1,4 +1,4 @@
1
- import { t as LeuElement } from "./LeuElement-BeFrgKes.js";
1
+ import { t as LeuElement } from "./LeuElement-k4RjIeoG.js";
2
2
  import { css, html } from "lit";
3
3
  //#region src/components/placeholder/placeholder.css?inline
4
4
  var placeholder_default = css`:host {
@@ -1,3 +1,3 @@
1
- import "./LeuElement-BeFrgKes.js";
2
- import { t as LeuPlaceholder } from "./Placeholder-BJybFwSg.js";
1
+ import "./LeuElement-k4RjIeoG.js";
2
+ import { t as LeuPlaceholder } from "./Placeholder-DHMexMhK.js";
3
3
  export { LeuPlaceholder };
@@ -1,4 +1,4 @@
1
- import { t as LeuElement } from "./LeuElement-BeFrgKes.js";
1
+ import { t as LeuElement } from "./LeuElement-k4RjIeoG.js";
2
2
  import { t as __decorate } from "./decorate-DwpAc4D0.js";
3
3
  import { css, html } from "lit";
4
4
  import { property } from "lit/decorators.js";
package/dist/Popup.js CHANGED
@@ -1,3 +1,3 @@
1
- import "./LeuElement-BeFrgKes.js";
2
- import { t as LeuPopup } from "./Popup-DNlm_9AA.js";
1
+ import "./LeuElement-k4RjIeoG.js";
2
+ import { t as LeuPopup } from "./Popup-8jhVy8gB.js";
3
3
  export { LeuPopup };
@@ -1,4 +1,4 @@
1
- import { t as LeuElement } from "./LeuElement-BeFrgKes.js";
1
+ import { t as LeuElement } from "./LeuElement-k4RjIeoG.js";
2
2
  import { t as __decorate } from "./decorate-DwpAc4D0.js";
3
3
  import { css, html, nothing } from "lit";
4
4
  import { property } from "lit/decorators.js";
@@ -1,3 +1,3 @@
1
- import "./LeuElement-BeFrgKes.js";
2
- import { t as LeuProgressBar } from "./ProgressBar-B0wYj1KF.js";
1
+ import "./LeuElement-k4RjIeoG.js";
2
+ import { t as LeuProgressBar } from "./ProgressBar-CG0_lHfS.js";
3
3
  export { LeuProgressBar };
@@ -1,4 +1,4 @@
1
- import { t as LeuElement } from "./LeuElement-BeFrgKes.js";
1
+ import { t as LeuElement } from "./LeuElement-k4RjIeoG.js";
2
2
  import { t as __decorate } from "./decorate-DwpAc4D0.js";
3
3
  import { css, html } from "lit";
4
4
  import { property } from "lit/decorators.js";
package/dist/Radio.js CHANGED
@@ -1,3 +1,3 @@
1
- import "./LeuElement-BeFrgKes.js";
2
- import { t as LeuRadio } from "./Radio-DMCL8c4D.js";
1
+ import "./LeuElement-k4RjIeoG.js";
2
+ import { t as LeuRadio } from "./Radio-DG3xqP3s.js";
3
3
  export { LeuRadio };
@@ -1,6 +1,6 @@
1
- import { t as LeuElement } from "./LeuElement-BeFrgKes.js";
1
+ import { t as LeuElement } from "./LeuElement-k4RjIeoG.js";
2
2
  import { t as __decorate } from "./decorate-DwpAc4D0.js";
3
- import { t as LeuRadio } from "./Radio-DMCL8c4D.js";
3
+ import { t as LeuRadio } from "./Radio-DG3xqP3s.js";
4
4
  import { css, html } from "lit";
5
5
  import { property } from "lit/decorators.js";
6
6
  import { classMap } from "lit/directives/class-map.js";
@@ -1,4 +1,4 @@
1
- import "./LeuElement-BeFrgKes.js";
2
- import "./Radio-DMCL8c4D.js";
3
- import { t as LeuRadioGroup } from "./RadioGroup-CM6IyBlq.js";
1
+ import "./LeuElement-k4RjIeoG.js";
2
+ import "./Radio-DG3xqP3s.js";
3
+ import { t as LeuRadioGroup } from "./RadioGroup-BKCp9ICX.js";
4
4
  export { LeuRadioGroup };
@@ -1,4 +1,4 @@
1
- import { t as LeuElement } from "./LeuElement-BeFrgKes.js";
1
+ import { t as LeuElement } from "./LeuElement-k4RjIeoG.js";
2
2
  import { t as __decorate } from "./decorate-DwpAc4D0.js";
3
3
  import { n as isNumber, t as clamp } from "./utils-hfk5Nwy8.js";
4
4
  import { css, html, nothing } from "lit";
package/dist/Range.js CHANGED
@@ -1,3 +1,3 @@
1
- import "./LeuElement-BeFrgKes.js";
2
- import { t as LeuRange } from "./Range-B72rtfln.js";
1
+ import "./LeuElement-k4RjIeoG.js";
2
+ import { t as LeuRange } from "./Range-7LrESv4K.js";
3
3
  export { LeuRange };
@@ -1,7 +1,7 @@
1
- import { t as LeuElement } from "./LeuElement-BeFrgKes.js";
1
+ import { t as LeuElement } from "./LeuElement-k4RjIeoG.js";
2
2
  import { t as __decorate } from "./decorate-DwpAc4D0.js";
3
- import { t as LeuIcon } from "./Icon-C_yYuynf.js";
4
- import { t as LeuButton } from "./Button-BkhqVjug.js";
3
+ import { t as LeuIcon } from "./Icon-CbZXpyHU.js";
4
+ import { t as LeuButton } from "./Button-BSyDL_cV.js";
5
5
  import { r as throttle } from "./utils-hfk5Nwy8.js";
6
6
  import { css, html } from "lit";
7
7
  import { state } from "lit/decorators.js";
@@ -63,24 +63,24 @@ var scroll_top_default = css`.scroll-top {
63
63
  /**
64
64
  * @tagname leu-scroll-top
65
65
  */
66
- var LeuScrollTop = class LeuScrollTop extends LeuElement {
66
+ var LeuScrollTop = class extends LeuElement {
67
67
  constructor(..._args) {
68
68
  super(..._args);
69
- this._showButton = false;
70
- this._prevYPos = 0;
71
- this._scrollDown = false;
69
+ this.showButton = false;
70
+ this.prevYPos = 0;
71
+ this.hasScrolledDown = false;
72
72
  this.scroll = () => {
73
- const delta = window.scrollY - this._prevYPos;
74
- if (this._scrollDown) {
75
- if (delta < 0) this._scrollDown = false;
76
- } else if (delta > 0) this._scrollDown = true;
73
+ const delta = window.scrollY - this.prevYPos;
74
+ if (this.hasScrolledDown) {
75
+ if (delta < 0) this.hasScrolledDown = false;
76
+ } else if (delta > 0) this.hasScrolledDown = true;
77
77
  /**
78
78
  * Only show the button when
79
79
  * ... the current scroll position is greater than the window height (below-the-fold) and when
80
80
  * ... scrolling up
81
81
  */
82
- this._showButton = window.scrollY > window.innerHeight && !this._scrollDown;
83
- this._prevYPos = window.scrollY;
82
+ this.showButton = window.scrollY > window.innerHeight && !this.hasScrolledDown;
83
+ this.prevYPos = window.scrollY;
84
84
  };
85
85
  }
86
86
  static {
@@ -94,14 +94,14 @@ var LeuScrollTop = class LeuScrollTop extends LeuElement {
94
94
  }
95
95
  connectedCallback() {
96
96
  super.connectedCallback();
97
- this._scrollListener = throttle(this.scroll, 100);
98
- document.addEventListener("scroll", this._scrollListener, true);
97
+ this.scrollListener = throttle(this.scroll, 100);
98
+ document.addEventListener("scroll", this.scrollListener, true);
99
99
  }
100
100
  disconnectedCallback() {
101
- document.removeEventListener("scroll", this._scrollListener, true);
101
+ document.removeEventListener("scroll", this.scrollListener, true);
102
102
  super.disconnectedCallback();
103
103
  }
104
- static scrollToTop() {
104
+ scrollToTop() {
105
105
  window.scrollTo({
106
106
  top: 0,
107
107
  left: 0,
@@ -112,12 +112,12 @@ var LeuScrollTop = class LeuScrollTop extends LeuElement {
112
112
  return html`
113
113
  <div class=${classMap({
114
114
  "scroll-top": true,
115
- hide: !this._showButton
115
+ hide: !this.showButton
116
116
  })}>
117
117
  <leu-button
118
118
  label="Zum Seitenanfang"
119
119
  round
120
- @click="${() => LeuScrollTop.scrollToTop()}"
120
+ @click="${() => this.scrollToTop()}"
121
121
  >
122
122
  <leu-icon name="arrowUp"></leu-icon>
123
123
  </leu-button>
@@ -125,6 +125,6 @@ var LeuScrollTop = class LeuScrollTop extends LeuElement {
125
125
  `;
126
126
  }
127
127
  };
128
- __decorate([state()], LeuScrollTop.prototype, "_showButton", void 0);
128
+ __decorate([state()], LeuScrollTop.prototype, "showButton", void 0);
129
129
  //#endregion
130
130
  export { LeuScrollTop as t };
@@ -13,14 +13,14 @@ declare class LeuScrollTop extends LeuElement {
13
13
  "leu-icon": typeof LeuIcon;
14
14
  };
15
15
  static styles: any[];
16
- protected _showButton: boolean;
17
- protected _prevYPos: number;
18
- protected _scrollDown: boolean;
19
- protected _scrollListener: EventListener;
16
+ protected showButton: boolean;
17
+ protected prevYPos: number;
18
+ protected hasScrolledDown: boolean;
19
+ protected scrollListener: EventListener;
20
20
  scroll: () => void;
21
21
  connectedCallback(): void;
22
22
  disconnectedCallback(): void;
23
- static scrollToTop(): void;
23
+ scrollToTop(): void;
24
24
  render(): lit_html0.TemplateResult<1>;
25
25
  }
26
26
  //#endregion
package/dist/ScrollTop.js CHANGED
@@ -1,7 +1,7 @@
1
- import "./LeuElement-BeFrgKes.js";
2
- import "./Icon-C_yYuynf.js";
3
- import "./Spinner-DDTqijTO.js";
4
- import "./Button-BkhqVjug.js";
1
+ import "./LeuElement-k4RjIeoG.js";
2
+ import "./Icon-CbZXpyHU.js";
3
+ import "./Spinner-VhKfzI3Q.js";
4
+ import "./Button-BSyDL_cV.js";
5
5
  import "./FormAssociatedMixin-DLPvFtbT.js";
6
- import { t as LeuScrollTop } from "./ScrollTop-BFAqBVDR.js";
6
+ import { t as LeuScrollTop } from "./ScrollTop-CJJsfniA.js";
7
7
  export { LeuScrollTop };
@@ -1,12 +1,15 @@
1
- import { t as LeuElement } from "./LeuElement-BeFrgKes.js";
2
- import { t as LeuIcon } from "./Icon-C_yYuynf.js";
1
+ import { t as LeuElement } from "./LeuElement-k4RjIeoG.js";
2
+ import { t as __decorate } from "./decorate-DwpAc4D0.js";
3
+ import { t as LeuIcon } from "./Icon-CbZXpyHU.js";
3
4
  import { t as HasSlotController } from "./hasSlotController-DSBCVzPD.js";
4
- import { t as LeuButton } from "./Button-BkhqVjug.js";
5
- import { t as LeuMenuItem } from "./MenuItem-DVg8-1Bq.js";
6
- import { t as LeuMenu } from "./Menu-BeqqtCw6.js";
7
- import { t as LeuPopup } from "./Popup-DNlm_9AA.js";
8
- import { t as LeuInput } from "./Input-DEOVocTa.js";
5
+ import { t as LeuButton } from "./Button-BSyDL_cV.js";
6
+ import { t as FormAssociatedMixin } from "./FormAssociatedMixin-DLPvFtbT.js";
7
+ import { t as LeuMenuItem } from "./MenuItem-Cs3KFhJm.js";
8
+ import { t as LeuMenu } from "./Menu-Cu8eIF1T.js";
9
+ import { t as LeuPopup } from "./Popup-8jhVy8gB.js";
10
+ import { t as LeuInput } from "./Input-DBXX7ev8.js";
9
11
  import { css, html, nothing } from "lit";
12
+ import { property, state } from "lit/decorators.js";
10
13
  import { classMap } from "lit/directives/class-map.js";
11
14
  import { ifDefined } from "lit/directives/if-defined.js";
12
15
  import { createRef, ref } from "lit/directives/ref.js";
@@ -107,6 +110,10 @@ var select_default = css`:host {
107
110
  font-family: var(--select-font-regular);
108
111
  }
109
112
 
113
+ :host([required]) .label::after {
114
+ content: "*";
115
+ }
116
+
110
117
  .clear-button {
111
118
  --_length: 1.5rem;
112
119
 
@@ -248,17 +255,33 @@ var select_default = css`:host {
248
255
  * @tagname leu-select
249
256
  * @slot before - Optional content the appears before the option list
250
257
  * @slot after - Optional content the appears after the option list
251
- * @property {string} name - Reflects to the name attribute of the hidden input field that would be used in a form
252
- * @property {boolean} open - The expanded state of the popup
253
- * @property {string} label - The label of the select
254
- * @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.
255
- * @property {boolean} clearable - Show a clearable button to reset the value
256
- * @property {boolean} disabled - If the select should be disabled
257
- * @property {boolean} filterable - Show an input field to filter the options inside the popup
258
- * @property {boolean} multiple - Allow multiple selections
259
258
  * @attribute {string} value - The selected values separated by commas.
260
259
  */
261
- var LeuSelect = class extends LeuElement {
260
+ var LeuSelect = class extends FormAssociatedMixin(LeuElement) {
261
+ constructor(..._args) {
262
+ super(..._args);
263
+ this.label = "";
264
+ this.defaultValue = [];
265
+ this.clearable = false;
266
+ this.filterable = false;
267
+ this.multiple = false;
268
+ this.required = false;
269
+ this.open = false;
270
+ this._optionFilter = "";
271
+ this._hasFilterResults = true;
272
+ this._displayValue = "";
273
+ this._deferedChangeEvent = false;
274
+ this._optionFilterRef = createRef();
275
+ this._toggleButtonRef = createRef();
276
+ this._menuRef = createRef();
277
+ this.hasSlotController = new HasSlotController(this, ["before", "after"]);
278
+ this._handleDocumentClick = (event) => {
279
+ if (!event.composedPath().includes(this) && this.open) this._closeDropdown();
280
+ };
281
+ this._handleKeyDown = (event) => {
282
+ if (event.key === "Escape") this._closeDropdown();
283
+ };
284
+ }
262
285
  static {
263
286
  this.dependencies = {
264
287
  "leu-button": LeuButton,
@@ -272,90 +295,49 @@ var LeuSelect = class extends LeuElement {
272
295
  static {
273
296
  this.styles = [LeuElement.styles, select_default];
274
297
  }
275
- static get properties() {
276
- return {
277
- name: {
278
- type: String,
279
- reflect: true
280
- },
281
- open: {
282
- type: Boolean,
283
- reflect: true
284
- },
285
- label: {
286
- type: String,
287
- reflect: true
288
- },
289
- value: {
290
- type: Array,
291
- converter: { fromAttribute(value) {
292
- if (value) return value.split(",").map((v) => v.trim());
293
- return value;
294
- } }
295
- },
296
- clearable: {
297
- type: Boolean,
298
- reflect: true
299
- },
300
- disabled: {
301
- type: Boolean,
302
- reflect: true
303
- },
304
- filterable: {
305
- type: Boolean,
306
- reflect: true
307
- },
308
- multiple: {
309
- type: Boolean,
310
- reflect: true
311
- },
312
- _optionFilter: { state: true },
313
- _hasFilterResults: { state: true },
314
- _displayValue: { state: true }
298
+ static {
299
+ this.shadowRootOptions = {
300
+ ...LeuElement.shadowRootOptions,
301
+ delegatesFocus: true
315
302
  };
316
303
  }
304
+ /**
305
+ * List of selected values. If they're set from outside the component, the select element
306
+ * finds all the options that match the given values and selects them.
307
+ */
308
+ set value(value) {
309
+ /**
310
+ * @todo Check if all of the value items are actually present in the options
311
+ */
312
+ this._value = value;
313
+ }
314
+ get value() {
315
+ return this._value ?? this.defaultValue;
316
+ }
317
317
  static getOptionLabel(option) {
318
318
  if (typeof option === "object" && option !== null) return option.label;
319
319
  return option;
320
320
  }
321
- constructor() {
322
- super();
323
- this.hasSlotController = new HasSlotController(this, ["before", "after"]);
324
- this._handleDocumentClick = (event) => {
325
- if (!event.composedPath().includes(this) && this.open) this._closeDropdown();
326
- };
327
- this._handleKeyDown = (event) => {
328
- if (event.key === "Escape") this._closeDropdown();
329
- };
330
- this.open = false;
331
- this.disabled = false;
332
- this.open = false;
333
- this.multiple = false;
334
- this.clearable = false;
335
- this.filterable = false;
336
- this.value = [];
337
- this.label = "";
338
- this.name = "";
339
- /** @internal */
340
- this._optionFilter = "";
341
- /** @internal */
342
- this._hasFilterResults = true;
343
- /** @internal */
344
- this._deferedChangeEvent = false;
345
- /** @internal */
321
+ setFormValue() {
322
+ const isEmpty = this.value.length === 0 || !this.value.some((v) => v !== "");
323
+ if (isEmpty || this.disabled) this.internals.setFormValue(null);
324
+ else if (this.multiple) {
325
+ const formData = new FormData();
326
+ this.value.forEach((v) => formData.append(this.name ?? "", v));
327
+ this.internals.setFormValue(formData);
328
+ } else this.internals.setFormValue(this.value[0]);
329
+ if (this.required && isEmpty) this.internals.setValidity({ valueMissing: true }, "Bitte wählen Sie eine Option aus.");
330
+ else this.internals.setValidity({});
331
+ }
332
+ formResetCallback() {
333
+ super.formResetCallback();
334
+ this.value = this.defaultValue;
346
335
  this._displayValue = "";
347
- /**
348
- * @type {import("lit/directives/ref").Ref<import("../input/Input").LeuInput>}
349
- */
350
- this._optionFilterRef = createRef();
351
- /**
352
- * @type {import("lit/directives/ref").Ref<HTMLButtonElement>}
353
- */
354
- this._toggleButtonRef = createRef();
355
- /**
356
- * @type {import("lit/directives/ref").Ref<import("../menu/Menu").LeuMenu>}
357
- */
358
- this._menuRef = createRef();
336
+ }
337
+ willUpdate(changedProperties) {
338
+ super.willUpdate(changedProperties);
339
+ if (changedProperties.has("defaultValue") && !changedProperties.has("value") && !this.hasInteracted) this.value = this.defaultValue;
340
+ if (changedProperties.has("value") || changedProperties.has("defaultValue") || changedProperties.has("name") || changedProperties.has("disabled") || changedProperties.has("required")) this.setFormValue();
359
341
  }
360
342
  connectedCallback() {
361
343
  super.connectedCallback();
@@ -375,13 +357,15 @@ var LeuSelect = class extends LeuElement {
375
357
  multiple: changedProperties.has("multiple")
376
358
  });
377
359
  }
360
+ click() {
361
+ this._toggleButtonRef.value?.click();
362
+ }
378
363
  /**
379
364
  * Apply the current state to the menu items.
380
365
  * - Set the active property when the value property has changed.
381
366
  * - Hide menu items that do not match the filter.
382
367
  */
383
368
  async _updateMenuItems(changed) {
384
- /** @type {LeuMenu} */
385
369
  const menu = this._menuRef.value;
386
370
  await menu.updateComplete;
387
371
  const menuItems = menu.getMenuItems();
@@ -418,7 +402,6 @@ var LeuSelect = class extends LeuElement {
418
402
  }
419
403
  /**
420
404
  * @internal
421
- * @param {KeyboardEvent} event
422
405
  */
423
406
  async _handleToggleKeyDown(event) {
424
407
  if ([
@@ -437,7 +420,6 @@ var LeuSelect = class extends LeuElement {
437
420
  }
438
421
  /**
439
422
  * @internal
440
- * @param {KeyboardEvent} event
441
423
  */
442
424
  _handleFilterInputKeyDown(event) {
443
425
  if (event.key === "ArrowDown") this._menuRef.value.focusItem(0);
@@ -445,7 +427,6 @@ var LeuSelect = class extends LeuElement {
445
427
  }
446
428
  /**
447
429
  * Determines the value or label that should be displayed inside the toggle button.
448
- * @returns {String | nothing}
449
430
  */
450
431
  _getDisplayValue() {
451
432
  if (this.multiple) return this.value.length === 0 ? `` : `${this.value.length} gewählt`;
@@ -468,6 +449,7 @@ var LeuSelect = class extends LeuElement {
468
449
  _clearValue(event) {
469
450
  if (!this.disabled) {
470
451
  event.stopPropagation();
452
+ this.hasInteracted = true;
471
453
  this.value = [];
472
454
  }
473
455
  this._emitInputEvent();
@@ -488,18 +470,16 @@ var LeuSelect = class extends LeuElement {
488
470
  }
489
471
  /**
490
472
  * Checks if the given value is selected.
491
- * @param {String} menuItemValue
492
- * @returns {Boolean}
493
473
  */
494
474
  _isSelected(menuItemValue) {
495
475
  return this.value.includes(menuItemValue);
496
476
  }
497
477
  _handleMenuItemClick(event) {
498
478
  if (!(event.target instanceof LeuMenuItem) || event.target.disabled) return;
499
- /** @type {LeuMenuItem} */
500
479
  const menuItem = event.target;
501
480
  const value = menuItem.getValue();
502
481
  const isSelected = this._isSelected(value);
482
+ this.hasInteracted = true;
503
483
  if (this.multiple) {
504
484
  this.value = isSelected ? this.value.filter((v) => v !== value) : this.value.concat(value);
505
485
  this._deferedChangeEvent = true;
@@ -574,45 +554,85 @@ var LeuSelect = class extends LeuElement {
574
554
  }
575
555
  render() {
576
556
  return html`<div
577
- class=${classMap({
557
+ class=${classMap({
578
558
  select: true,
579
559
  "select--has-before": this.hasSlotController.test("before"),
580
560
  "select--has-after": this.hasSlotController.test("after")
581
561
  })}
582
- @keydown=${this._handleKeyDown}
562
+ @keydown=${this._handleKeyDown}
563
+ >
564
+ <leu-popup
565
+ ?active=${this.open}
566
+ placement="bottom-start"
567
+ flip
568
+ matchSize="width"
569
+ autoSize="height"
570
+ autoSizePadding="8"
583
571
  >
584
- <leu-popup
585
- ?active=${this.open}
586
- placement="bottom-start"
587
- flip
588
- matchSize="width"
589
- autoSize="height"
590
- autoSizePadding="8"
591
- >
592
- ${this._renderToggleButton()}
593
- <div id="select-popup" class="select-menu-container">
594
- <slot name="before" class="before"></slot>
595
- ${this._renderFilterInput()}
596
- <leu-menu
597
- ref=${ref(this._menuRef)}
598
- role="listbox"
599
- aria-multiselectable=${ifDefined(this.multiple ? "true" : void 0)}
600
- class="menu"
601
- @click=${this._handleMenuItemClick}
602
- aria-labelledby="select-label"
603
- >
604
- <slot @slotchange=${this._handleItemSlotChange}> </slot>
605
- </leu-menu>
606
- ${this._hasFilterResults || this._optionFilter === "" ? nothing : html` <p class="filter-message-empty" aria-live="polite">
607
- Keine Resultate
608
- </p>`}
609
- ${this._renderApplyButton()}
610
- <slot name="after" class="after"></slot>
611
- </div>
612
- </leu-popup>
613
- </div>
614
- <input type="hidden" name=${this.name} .value=${this.value.join(",")} />`;
572
+ ${this._renderToggleButton()}
573
+ <div id="select-popup" class="select-menu-container">
574
+ <slot name="before" class="before"></slot>
575
+ ${this._renderFilterInput()}
576
+ <leu-menu
577
+ ref=${ref(this._menuRef)}
578
+ role="listbox"
579
+ aria-multiselectable=${ifDefined(this.multiple ? "true" : void 0)}
580
+ class="menu"
581
+ @click=${this._handleMenuItemClick}
582
+ aria-labelledby="select-label"
583
+ >
584
+ <slot @slotchange=${this._handleItemSlotChange}> </slot>
585
+ </leu-menu>
586
+ ${this._hasFilterResults || this._optionFilter === "" ? nothing : html` <p class="filter-message-empty" aria-live="polite">
587
+ Keine Resultate
588
+ </p>`}
589
+ ${this._renderApplyButton()}
590
+ <slot name="after" class="after"></slot>
591
+ </div>
592
+ </leu-popup>
593
+ </div>`;
615
594
  }
616
595
  };
596
+ __decorate([property({
597
+ type: String,
598
+ reflect: true
599
+ })], LeuSelect.prototype, "label", void 0);
600
+ __decorate([property({
601
+ reflect: true,
602
+ attribute: "value",
603
+ converter: {
604
+ fromAttribute(value) {
605
+ if (value) return value.split(",").map((v) => v.trim());
606
+ return [];
607
+ },
608
+ toAttribute(value) {
609
+ return value.length > 0 ? value.join(",") : null;
610
+ }
611
+ }
612
+ })], LeuSelect.prototype, "defaultValue", void 0);
613
+ __decorate([property({
614
+ type: Array,
615
+ attribute: false
616
+ })], LeuSelect.prototype, "value", null);
617
+ __decorate([property({
618
+ type: Boolean,
619
+ reflect: true
620
+ })], LeuSelect.prototype, "clearable", void 0);
621
+ __decorate([property({
622
+ type: Boolean,
623
+ reflect: true
624
+ })], LeuSelect.prototype, "filterable", void 0);
625
+ __decorate([property({
626
+ type: Boolean,
627
+ reflect: true
628
+ })], LeuSelect.prototype, "multiple", void 0);
629
+ __decorate([property({
630
+ type: Boolean,
631
+ reflect: true
632
+ })], LeuSelect.prototype, "required", void 0);
633
+ __decorate([state()], LeuSelect.prototype, "open", void 0);
634
+ __decorate([state()], LeuSelect.prototype, "_optionFilter", void 0);
635
+ __decorate([state()], LeuSelect.prototype, "_hasFilterResults", void 0);
636
+ __decorate([state()], LeuSelect.prototype, "_displayValue", void 0);
617
637
  //#endregion
618
638
  export { LeuSelect as t };