@statistikzh/leu 0.6.0 → 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.
Files changed (113) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/Accordion.d.ts +1 -1
  3. package/dist/Accordion.js +1 -1
  4. package/dist/Breadcrumb.d.ts +1 -1
  5. package/dist/Breadcrumb.d.ts.map +1 -1
  6. package/dist/Breadcrumb.js +3 -1
  7. package/dist/{Button-9692e403.d.ts → Button-7370f901.d.ts} +2 -2
  8. package/dist/Button-7370f901.d.ts.map +1 -0
  9. package/dist/{Button-9692e403.js → Button-7370f901.js} +1 -1
  10. package/dist/Button.d.ts +1 -1
  11. package/dist/Button.js +2 -2
  12. package/dist/ButtonGroup.d.ts +1 -1
  13. package/dist/ButtonGroup.d.ts.map +1 -1
  14. package/dist/ButtonGroup.js +1 -1
  15. package/dist/Checkbox.d.ts +1 -1
  16. package/dist/Checkbox.d.ts.map +1 -1
  17. package/dist/Checkbox.js +3 -1
  18. package/dist/CheckboxGroup.d.ts +1 -1
  19. package/dist/CheckboxGroup.d.ts.map +1 -1
  20. package/dist/CheckboxGroup.js +3 -1
  21. package/dist/Chip.d.ts +1 -1
  22. package/dist/Chip.d.ts.map +1 -1
  23. package/dist/Chip.js +19 -17
  24. package/dist/ChipGroup.d.ts +8 -2
  25. package/dist/ChipGroup.d.ts.map +1 -1
  26. package/dist/ChipGroup.js +32 -5
  27. package/dist/ChipLink.js +1 -1
  28. package/dist/ChipRemovable.js +1 -1
  29. package/dist/ChipSelectable.d.ts +3 -1
  30. package/dist/ChipSelectable.d.ts.map +1 -1
  31. package/dist/ChipSelectable.js +13 -11
  32. package/dist/Dropdown.d.ts +1 -1
  33. package/dist/Dropdown.d.ts.map +1 -1
  34. package/dist/Dropdown.js +2 -2
  35. package/dist/Icon.d.ts +98 -2
  36. package/dist/Icon.d.ts.map +1 -1
  37. package/dist/Icon.js +1 -1
  38. package/dist/Input.d.ts +7 -2
  39. package/dist/Input.d.ts.map +1 -1
  40. package/dist/Input.js +16 -3
  41. package/dist/{LeuElement-6de6f209.d.ts → LeuElement-ba5ea33d.d.ts} +2 -2
  42. package/dist/LeuElement-ba5ea33d.d.ts.map +1 -0
  43. package/dist/LeuElement-ba5ea33d.js +49 -0
  44. package/dist/Menu.d.ts +2 -2
  45. package/dist/Menu.js +1 -1
  46. package/dist/MenuItem.d.ts +2 -2
  47. package/dist/MenuItem.js +1 -1
  48. package/dist/Pagination.d.ts +1 -1
  49. package/dist/Pagination.js +2 -2
  50. package/dist/Popup.d.ts +1 -1
  51. package/dist/Popup.d.ts.map +1 -1
  52. package/dist/Popup.js +3 -1
  53. package/dist/Radio.d.ts +1 -1
  54. package/dist/Radio.d.ts.map +1 -1
  55. package/dist/Radio.js +3 -1
  56. package/dist/RadioGroup.d.ts +1 -1
  57. package/dist/RadioGroup.d.ts.map +1 -1
  58. package/dist/RadioGroup.js +19 -8
  59. package/dist/ScrollTop.d.ts +1 -1
  60. package/dist/ScrollTop.js +2 -2
  61. package/dist/Select.d.ts +1 -1
  62. package/dist/Select.d.ts.map +1 -1
  63. package/dist/Select.js +4 -2
  64. package/dist/Table.d.ts +1 -1
  65. package/dist/Table.d.ts.map +1 -1
  66. package/dist/Table.js +4 -3
  67. package/dist/VisuallyHidden.d.ts +1 -1
  68. package/dist/VisuallyHidden.d.ts.map +1 -1
  69. package/dist/VisuallyHidden.js +5 -3
  70. package/dist/index.d.ts +2 -2
  71. package/dist/index.js +3 -3
  72. package/dist/leu-accordion.js +1 -1
  73. package/dist/leu-breadcrumb.js +1 -1
  74. package/dist/leu-button-group.js +1 -1
  75. package/dist/leu-button.d.ts +1 -1
  76. package/dist/leu-button.js +2 -2
  77. package/dist/leu-checkbox-group.js +1 -1
  78. package/dist/leu-checkbox.js +1 -1
  79. package/dist/leu-chip-group.js +1 -1
  80. package/dist/leu-chip-link.js +1 -1
  81. package/dist/leu-chip-removable.js +1 -1
  82. package/dist/leu-chip-selectable.js +1 -1
  83. package/dist/leu-dropdown.js +2 -2
  84. package/dist/leu-icon.js +1 -1
  85. package/dist/leu-input.js +1 -1
  86. package/dist/leu-menu-item.js +1 -1
  87. package/dist/leu-menu.js +1 -1
  88. package/dist/leu-pagination.js +2 -2
  89. package/dist/leu-popup.js +1 -1
  90. package/dist/leu-radio-group.js +1 -1
  91. package/dist/leu-radio.js +1 -1
  92. package/dist/leu-scroll-top.js +2 -2
  93. package/dist/leu-select.js +2 -2
  94. package/dist/leu-table.js +2 -2
  95. package/dist/leu-visually-hidden.js +1 -1
  96. package/dist/vscode.html-custom-data.json +18 -5
  97. package/dist/vue/index.d.ts +21 -9
  98. package/dist/web-types.json +211 -232
  99. package/package.json +3 -3
  100. package/src/components/chip/ChipGroup.js +28 -4
  101. package/src/components/chip/ChipSelectable.js +12 -10
  102. package/src/components/chip/chip.css +16 -16
  103. package/src/components/chip/stories/chip-group.stories.js +6 -9
  104. package/src/components/chip/stories/chip-selectable.stories.js +1 -1
  105. package/src/components/chip/test/chip-group.test.js +67 -0
  106. package/src/components/chip/test/chip-selectable.test.js +7 -7
  107. package/src/components/input/Input.js +14 -1
  108. package/src/components/input/stories/input.stories.js +3 -3
  109. package/src/components/input/test/input.test.js +20 -0
  110. package/src/components/radio/RadioGroup.js +12 -9
  111. package/dist/Button-9692e403.d.ts.map +0 -1
  112. package/dist/LeuElement-6de6f209.d.ts.map +0 -1
  113. package/dist/LeuElement-6de6f209.js +0 -43
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "UI component library of the canton of zurich",
4
4
  "license": "MIT",
5
5
  "author": "statistikzh",
6
- "version": "0.6.0",
6
+ "version": "0.7.0",
7
7
  "type": "module",
8
8
  "main": "dist/index.js",
9
9
  "module": "dist/index.js",
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@floating-ui/dom": "^1.6.3",
49
- "lit": "^3.0.2"
49
+ "lit": "^3.1.4"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@babel/preset-env": "^7.23.3",
@@ -66,7 +66,7 @@
66
66
  "@storybook/web-components": "^7.6.17",
67
67
  "@web/dev-server": "^0.4.6",
68
68
  "@web/dev-server-rollup": "^0.6.4",
69
- "@web/storybook-builder": "^0.1.16",
69
+ "@web/storybook-builder": "^0.1.6",
70
70
  "@web/storybook-framework-web-components": "^0.1.2",
71
71
  "@web/test-runner": "^0.18.2",
72
72
  "@web/test-runner-commands": "^0.9.0",
@@ -45,17 +45,41 @@ export class LeuChipGroup extends LeuElement {
45
45
  connectedCallback() {
46
46
  super.connectedCallback()
47
47
 
48
- this.addEventListener("input", this.handleInput)
48
+ /**
49
+ * It is technically possible to add an event listener to the host element
50
+ * before it is connected to the dom. In that case the outside event listener would
51
+ * be called before the following event listener. But at this point multiple
52
+ * radio chips could be selected at the same time because `handleInput` hasn't been
53
+ * called yet. That's why we use the capture phase.
54
+ */
55
+ this.addEventListener("input", this.handleInput, { capture: true })
49
56
  }
50
57
 
51
58
  disconnectedCallback() {
52
59
  super.disconnectedCallback()
53
60
 
54
- this.removeEventListener("input", this.handleInput)
61
+ this.removeEventListener("input", this.handleInput, { capture: true })
55
62
  }
56
63
 
57
64
  get value() {
58
- return this.items.filter((i) => i.selected).map((i) => i.value)
65
+ return this.items.filter((i) => i.checked).map((i) => i.value)
66
+ }
67
+
68
+ /**
69
+ * Checks the items with the given values.
70
+ * If the selectionMode is single, only the first item with the given value is checked.
71
+ * @param {string[]} valueList
72
+ */
73
+ set value(valueList) {
74
+ let hasChanged = false
75
+
76
+ for (const item of this.items) {
77
+ item.checked = hasChanged ? false : valueList.includes(item.value)
78
+
79
+ if (this.selectionMode === SELECTION_MODES.single && item.checked) {
80
+ hasChanged = true
81
+ }
82
+ }
59
83
  }
60
84
 
61
85
  /**
@@ -78,7 +102,7 @@ export class LeuChipGroup extends LeuElement {
78
102
  handleInput = (e) => {
79
103
  if (this.selectionMode === SELECTION_MODES.single) {
80
104
  this.items.forEach((item) => {
81
- item.selected = item === e.target // eslint-disable-line no-param-reassign
105
+ item.checked = item === e.target // eslint-disable-line no-param-reassign
82
106
  })
83
107
  }
84
108
  }
@@ -18,6 +18,8 @@ export const VARIANTS = {
18
18
  * @slot - The content of the chip
19
19
  * @prop {keyof typeof SIZES} size - The size of the chip. Not supported for radio variant.
20
20
  * @prop {keyof typeof VARIANTS} variant - `toggle` or `radio`. Determines if only one or multiple chips can be selected.
21
+ * @prop {boolean} checked - Whether the chip is selected.
22
+ * @prop {string} value - The value of the chip.
21
23
  */
22
24
  export class LeuChipSelectable extends LeuChipBase {
23
25
  static properties = {
@@ -25,7 +27,7 @@ export class LeuChipSelectable extends LeuChipBase {
25
27
  size: { type: String, reflect: true },
26
28
  variant: { type: String, reflect: true },
27
29
 
28
- selected: { type: Boolean, reflect: true },
30
+ checked: { type: Boolean, reflect: true },
29
31
  value: { type: String, reflect: true },
30
32
  }
31
33
 
@@ -40,7 +42,7 @@ export class LeuChipSelectable extends LeuChipBase {
40
42
  * @default "toggle"
41
43
  */
42
44
  this.variant = VARIANTS.toggle
43
- this.selected = false
45
+ this.checked = false
44
46
 
45
47
  if (this.variant === VARIANTS.radio && this.size === SIZES.small) {
46
48
  console.warn("Small size has no effect on radio variant")
@@ -48,19 +50,19 @@ export class LeuChipSelectable extends LeuChipBase {
48
50
  }
49
51
 
50
52
  handleClick() {
51
- let nextSelectedState = this.selected
53
+ let nextcheckedState = this.checked
52
54
 
53
55
  if (this.variant === VARIANTS.radio) {
54
- nextSelectedState = true
56
+ nextcheckedState = true
55
57
  } else {
56
- nextSelectedState = !this.selected
58
+ nextcheckedState = !this.checked
57
59
  }
58
60
 
59
- if (nextSelectedState !== this.selected) {
60
- this.selected = nextSelectedState
61
+ if (nextcheckedState !== this.checked) {
62
+ this.checked = nextcheckedState
61
63
  this.dispatchEvent(
62
64
  new CustomEvent("input", {
63
- detail: { selected: this.selected },
65
+ detail: { checked: this.checked },
64
66
  bubbles: true,
65
67
  composed: true,
66
68
  })
@@ -70,9 +72,9 @@ export class LeuChipSelectable extends LeuChipBase {
70
72
 
71
73
  render() {
72
74
  return html`<button
73
- @click=${(e) => this.handleClick(e)}
75
+ @click=${() => this.handleClick()}
74
76
  class="button"
75
- aria-pressed=${this.selected ? "true" : "false"}
77
+ aria-pressed=${this.checked ? "true" : "false"}
76
78
  >
77
79
  <span class="label"><slot></slot></span>
78
80
  </button>`
@@ -8,17 +8,17 @@
8
8
  :host {
9
9
  --chip-background-color-default: var(--leu-color-black-transp-10);
10
10
  --chip-background-color-hover: var(--leu-color-black-transp-20);
11
- --chip-background-color-selected: var(--leu-color-black-100);
12
- --chip-background-color-selected-hover: var(--leu-color-black-transp-80);
11
+ --chip-background-color-checked: var(--leu-color-black-100);
12
+ --chip-background-color-checked-hover: var(--leu-color-black-transp-80);
13
13
 
14
14
  --chip-color-default: var(--leu-color-black-transp-60);
15
15
  --chip-color-hover: var(--leu-color-black-100);
16
- --chip-color-selected: var(--leu-color-black-0);
16
+ --chip-color-checked: var(--leu-color-black-0);
17
17
 
18
18
  --chip-radio-border-default: var(--leu-color-black-transp-40);
19
- --chip-radio-border-selected: var(--leu-color-black-0);
19
+ --chip-radio-border-checked: var(--leu-color-black-0);
20
20
  --chip-radio-background-default: var(--leu-color-black-0);
21
- --chip-radio-background-selected: var(--leu-color-func-cyan);
21
+ --chip-radio-background-checked: var(--leu-color-func-cyan);
22
22
 
23
23
  --chip-font-regular: var(--leu-font-family-regular);
24
24
  --chip-font-black: var(--leu-font-family-black);
@@ -42,14 +42,14 @@
42
42
 
43
43
  --chip-color-default: var(--leu-color-black-0);
44
44
  --chip-color-hover: var(--leu-color-black-0);
45
- --chip-color-selected: var(--leu-color-black-0);
45
+ --chip-color-checked: var(--leu-color-black-0);
46
46
  }
47
47
 
48
- :host([selected]) {
49
- --chip-background-color: var(--chip-background-color-selected);
50
- --chip-color: var(--chip-color-selected);
51
- --chip-radio-border: var(--chip-radio-border-selected);
52
- --chip-radio-background: var(--chip-radio-background-selected);
48
+ :host([checked]) {
49
+ --chip-background-color: var(--chip-background-color-checked);
50
+ --chip-color: var(--chip-color-checked);
51
+ --chip-radio-border: var(--chip-radio-border-checked);
52
+ --chip-radio-background: var(--chip-radio-background-checked);
53
53
  }
54
54
 
55
55
  .button {
@@ -95,10 +95,10 @@
95
95
  text-decoration: none;
96
96
  }
97
97
 
98
- :host([selected]) .button:hover,
99
- :host([selected]) .button:focus-visible {
100
- --chip-background-color: var(--chip-background-color-selected-hover);
101
- --chip-color: var(--chip-color-selected);
98
+ :host([checked]) .button:hover,
99
+ :host([checked]) .button:focus-visible {
100
+ --chip-background-color: var(--chip-background-color-checked-hover);
101
+ --chip-color: var(--chip-color-checked);
102
102
  }
103
103
 
104
104
  :host([href][size="large"]) .button {
@@ -126,7 +126,7 @@
126
126
  border-radius: 50%;
127
127
  }
128
128
 
129
- :host([variant="radio"][selected]) .button::before {
129
+ :host([variant="radio"][checked]) .button::before {
130
130
  border-width: 3px;
131
131
  }
132
132
 
@@ -95,7 +95,8 @@ function DefaultTemplate(args) {
95
95
  const content = html`
96
96
  ${chips.map(
97
97
  (chip) => html`
98
- <leu-chip-removable ?inverted=${args.inverted} label=${chip}>
98
+ <leu-chip-removable ?inverted=${args.inverted}>
99
+ ${chip}
99
100
  </leu-chip-removable>
100
101
  `
101
102
  )}
@@ -112,8 +113,8 @@ function SingleTemplate(args) {
112
113
  ?inverted=${args.inverted}
113
114
  variant=${SELECTABLE_VARIANTS.radio}
114
115
  value="chip-${chip}"
115
- label=${chip}
116
116
  >
117
+ ${chip}
117
118
  </leu-chip-selectable>
118
119
  `
119
120
  )}
@@ -126,11 +127,8 @@ function MultipleTemplate(args) {
126
127
  const content = html`
127
128
  ${chips.map(
128
129
  (chip) => html`
129
- <leu-chip-selectable
130
- ?inverted=${args.inverted}
131
- value="chip-${chip}"
132
- label=${chip}
133
- >
130
+ <leu-chip-selectable ?inverted=${args.inverted} value="chip-${chip}">
131
+ ${chip}
134
132
  </leu-chip-selectable>
135
133
  `
136
134
  )}
@@ -143,8 +141,7 @@ function LabeledTemplate(args) {
143
141
  const content = html`
144
142
  ${links.map(
145
143
  (chip) => html`
146
- <leu-chip-link ?inverted=${args.inverted} label=${chip}>
147
- </leu-chip-link>
144
+ <leu-chip-link ?inverted=${args.inverted}> ${chip} </leu-chip-link>
148
145
  `
149
146
  )}
150
147
  `
@@ -38,7 +38,7 @@ function Template(args) {
38
38
  <leu-chip-selectable
39
39
  size=${ifDefined(args.size)}
40
40
  variant=${ifDefined(args.variant)}
41
- ?selected=${args.selected}
41
+ ?checked=${args.checked}
42
42
  ?inverted=${args.inverted}
43
43
  >${args.label}</leu-chip-selectable
44
44
  >
@@ -106,4 +106,71 @@ describe("LeuChipGroup", () => {
106
106
 
107
107
  await expect(event).to.exist
108
108
  })
109
+
110
+ it("checks only chip when the value of the group is set (selection-mode=single)", async () => {
111
+ const el = await singleSelectionFixture()
112
+
113
+ expect(el.items[0].checked).to.be.false
114
+ expect(el.items[1].checked).to.be.false
115
+ expect(el.items[2].checked).to.be.false
116
+
117
+ el.value = ["2"]
118
+
119
+ expect(el.items[0].checked).to.be.false
120
+ expect(el.items[1].checked).to.be.true
121
+ expect(el.items[2].checked).to.be.false
122
+
123
+ // Should check the first item with the given value and not first item of the value list
124
+ el.value = ["2", "1"]
125
+
126
+ expect(el.items[0].checked).to.be.true
127
+ expect(el.items[1].checked).to.be.false
128
+
129
+ el.value = []
130
+
131
+ expect(el.items[0].checked).to.be.false
132
+ expect(el.items[1].checked).to.be.false
133
+ expect(el.items[2].checked).to.be.false
134
+
135
+ el.value = ["asdf"]
136
+
137
+ expect(el.items[0].checked).to.be.false
138
+ expect(el.items[1].checked).to.be.false
139
+ expect(el.items[2].checked).to.be.false
140
+ expect(el.value).to.deep.equal([])
141
+ })
142
+
143
+ it("checks chips when the value of the group is set (selection-mode=multiple)", async () => {
144
+ const el = await multipleSelectionFixture()
145
+
146
+ expect(el.items[0].checked).to.be.false
147
+ expect(el.items[1].checked).to.be.false
148
+ expect(el.items[2].checked).to.be.false
149
+
150
+ el.value = ["2"]
151
+
152
+ expect(el.items[0].checked).to.be.false
153
+ expect(el.items[1].checked).to.be.true
154
+ expect(el.items[2].checked).to.be.false
155
+
156
+ // Should check the first item with the given value and not first item of the value list
157
+ el.value = ["2", "1"]
158
+
159
+ expect(el.items[0].checked).to.be.true
160
+ expect(el.items[1].checked).to.be.true
161
+ expect(el.items[2].checked).to.be.false
162
+
163
+ el.value = []
164
+
165
+ expect(el.items[0].checked).to.be.false
166
+ expect(el.items[1].checked).to.be.false
167
+ expect(el.items[2].checked).to.be.false
168
+
169
+ el.value = ["asdf"]
170
+
171
+ expect(el.items[0].checked).to.be.false
172
+ expect(el.items[1].checked).to.be.false
173
+ expect(el.items[2].checked).to.be.false
174
+ expect(el.value).to.deep.equal([])
175
+ })
109
176
  })
@@ -11,7 +11,7 @@ async function defaultFixture(args = {}) {
11
11
  <leu-chip-selectable
12
12
  value="Publikationen"
13
13
  variant=${ifDefined(args.variant)}
14
- ?selected=${args.selected}
14
+ ?checked=${args.checked}
15
15
  >Publikationen</leu-chip-selectable
16
16
  >
17
17
  `
@@ -73,21 +73,21 @@ describe("LeuChipSelectable", () => {
73
73
  expect(event).to.exist
74
74
  })
75
75
 
76
- it("removes the selected state when the button is clicked", async () => {
77
- const el = await defaultFixture({ selected: true })
76
+ it("removes the checked state when the button is clicked", async () => {
77
+ const el = await defaultFixture({ checked: true })
78
78
  const button = el.shadowRoot.querySelector("button")
79
79
 
80
80
  button.click()
81
81
 
82
- expect(el.selected).to.be.false
82
+ expect(el.checked).to.be.false
83
83
  })
84
84
 
85
- it("doesn't remove the selected state of a selected radio chip", async () => {
86
- const el = await defaultFixture({ variant: "radio", selected: true })
85
+ it("doesn't remove the checked state of a checked radio chip", async () => {
86
+ const el = await defaultFixture({ variant: "radio", checked: true })
87
87
 
88
88
  const button = el.shadowRoot.querySelector("button")
89
89
  button.click()
90
90
 
91
- expect(el.selected).to.be.true
91
+ expect(el.checked).to.be.true
92
92
  })
93
93
  })
@@ -10,6 +10,11 @@ import { LeuIcon } from "../icon/Icon.js"
10
10
  // @ts-ignore
11
11
  import styles from "./input.css"
12
12
 
13
+ export const SIZES = Object.freeze({
14
+ SMALL: "small",
15
+ REGULAR: "regular",
16
+ })
17
+
13
18
  /**
14
19
  * TODO:
15
20
  * - Add section to docs about how to mark up suffix and prefix for screenreaders
@@ -120,12 +125,13 @@ export class LeuInput extends LeuElement {
120
125
  this.clearable = false
121
126
 
122
127
  /** @type {"small" | "regular"} */
123
- this.size = "regular"
128
+ this.size = SIZES.REGULAR
124
129
 
125
130
  this.type = "text"
126
131
  this._validity = null
127
132
  this.validationMessages = {}
128
133
  this.novalidate = false
134
+ this.value = ""
129
135
 
130
136
  /** @internal */
131
137
  this._identifier = ""
@@ -137,6 +143,13 @@ export class LeuInput extends LeuElement {
137
143
  this._inputRef = createRef()
138
144
  }
139
145
 
146
+ get valueAsNumber() {
147
+ if (this.value === "") {
148
+ return NaN
149
+ }
150
+ return Number(this.value)
151
+ }
152
+
140
153
  /**
141
154
  * Method for handling the click event of the wrapper element.
142
155
  * Redirect every click on the wrapper to the input element.
@@ -3,7 +3,7 @@ import { ifDefined } from "lit/directives/if-defined.js"
3
3
 
4
4
  import "../leu-input.js"
5
5
 
6
- import { SIZE_TYPES } from "../Input.js"
6
+ import { SIZES } from "../Input.js"
7
7
  import { paths as iconPaths } from "../../icon/paths.js"
8
8
 
9
9
  export default {
@@ -15,7 +15,7 @@ export default {
15
15
  control: {
16
16
  type: "select",
17
17
  },
18
- options: Object.values(SIZE_TYPES),
18
+ options: Object.values(SIZES),
19
19
  },
20
20
  icon: { control: "select", options: Object.keys(iconPaths) },
21
21
  },
@@ -165,7 +165,7 @@ export const Search = Template.bind({})
165
165
  Search.args = {
166
166
  label: "Suchen",
167
167
  clearable: true,
168
- size: SIZE_TYPES.SMALL,
168
+ size: SIZES.SMALL,
169
169
  icon: "search",
170
170
  novalidate: true,
171
171
  }
@@ -449,4 +449,24 @@ describe("LeuInput", () => {
449
449
  expect(getClearButton()).to.be.null
450
450
  expect(getIcon()).to.be.null
451
451
  })
452
+
453
+ it("returns the value as a number when it is possible", async () => {
454
+ const el = await defaultFixture({ label: "Länge", type: "number" })
455
+
456
+ expect(el.valueAsNumber).to.be.NaN
457
+
458
+ el.focus()
459
+
460
+ await sendKeys({ type: "123" })
461
+
462
+ expect(el.valueAsNumber).to.equal(123)
463
+
464
+ el.type = "text"
465
+ await elementUpdated(el)
466
+
467
+ el.focus()
468
+ await sendKeys({ type: "abc" })
469
+
470
+ expect(el.valueAsNumber).to.be.NaN
471
+ })
452
472
  })
@@ -43,13 +43,20 @@ export class LeuRadioGroup extends LeuElement {
43
43
  }
44
44
 
45
45
  addEventListeners() {
46
- this.addEventListener("input", this.handleInput)
46
+ /**
47
+ * It is technically possible to add an event listener to the host element
48
+ * before it is connected to the dom. In that case the outside event listener would
49
+ * be called before the following event listener. But at this point multiple
50
+ * radio buttons could be selected at the same time because `handleInput` hasn't been
51
+ * called yet. That's why we use the capture phase.
52
+ */
53
+ this.addEventListener("input", this.handleInput, { capture: true })
47
54
  this.addEventListener("focusin", this.handleFocusIn)
48
55
  this.addEventListener("keydown", this.handleKeyDown)
49
56
  }
50
57
 
51
58
  removeEventListeners() {
52
- this.removeEventListener("input", this.handleInput)
59
+ this.removeEventListener("input", this.handleInput, { capture: true })
53
60
  this.removeEventListener("focusin", this.handleFocusIn)
54
61
  this.removeEventListener("keydown", this.handleKeyDown)
55
62
  }
@@ -87,13 +94,9 @@ export class LeuRadioGroup extends LeuElement {
87
94
  }
88
95
 
89
96
  handleInput = (e) => {
90
- if (e.target.checked) {
91
- this.items
92
- .filter((item) => item !== e.target)
93
- .forEach((item) => {
94
- item.checked = false // eslint-disable-line no-param-reassign
95
- })
96
- }
97
+ this.items.forEach((item) => {
98
+ item.checked = item === e.target // eslint-disable-line no-param-reassign
99
+ })
97
100
  }
98
101
 
99
102
  selectItem(selectingItem) {
@@ -1 +0,0 @@
1
- {"version":3,"file":"Button-9692e403.d.ts","sourceRoot":"","sources":["Button-9692e403.js"],"names":[],"mappings":";;;iCAaa,OAAO,KAAK,EAAE,kBAAkB;AAyW7C,wCAA0D;AAhX1D;;;GAGG;AAEH;;;;GAIG;AACH,2CAFgB,kBAAkB;IAGhC,uCAcC;IAHC,UAAgB;IAEhB,eAA0B;IAG5B;;;OAGG;IACH,uBAeC;IAED;;;;OAIG;IACH,qBAEC;IAED;;;OAGG;IACH,gCAEC;IACD,sBAEC;IACD,yBAEC;CACF;AAmTD;;;;;GAKG;AACH;IAQI,WAAiB;IACjB,qBAAqB;IACrB,MADW,MAAM,CACI;IACrB,qBAAqB;IACrB,SADW,MAAM,CACO;IACxB,4CAA4C;IAC5C,MADW,QAAQ,GAAG,QAAQ,GAAG,OAAO,CACpB;IAEpB,qBAAqB;IACrB,eADW,MAAM,CACa;IAE9B,sBAAsB;IACtB,UADW,OAAO,CACG;IACrB,+EAA+E;IAC/E,OADW,OAAO,CACA;IAClB,sBAAsB;IACtB,QADW,OAAO,CACC;IACnB,wDAAwD;IACxD,UADW,OAAO,CACG;IAErB,gGAAgG;IAChG,OADW,OAAO,CACA;IAElB;;;OAGG;IACH,UAFU,CAAC,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAEf;IAE3B,6EAOC;IACD;;;MAaC;IACD,0BAEC;IACD,+CAiCC;CACF;AA7GD,qCAA0C;AAE1C,qCAAmD;AAEnD,gDAAkD;gCA5XI,0BAA0B;wBAC7C,KAAK"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"LeuElement-6de6f209.d.ts","sourceRoot":"","sources":["LeuElement-6de6f209.js"],"names":[],"mappings":"AAyBA;IACE,8EAMC;CAOF;AArCD,8DAOC;2BAT0B,KAAK"}
@@ -1,43 +0,0 @@
1
- import { LitElement } from 'lit';
2
-
3
- function _defineProperty(e, r, t) {
4
- return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
5
- value: t,
6
- enumerable: !0,
7
- configurable: !0,
8
- writable: !0
9
- }) : e[r] = t, e;
10
- }
11
- function _toPrimitive(t, r) {
12
- if ("object" != typeof t || !t) return t;
13
- var e = t[Symbol.toPrimitive];
14
- if (void 0 !== e) {
15
- var i = e.call(t, r || "default");
16
- if ("object" != typeof i) return i;
17
- throw new TypeError("@@toPrimitive must return a primitive value.");
18
- }
19
- return ("string" === r ? String : Number)(t);
20
- }
21
- function _toPropertyKey(t) {
22
- var i = _toPrimitive(t, "string");
23
- return "symbol" == typeof i ? i : i + "";
24
- }
25
-
26
- class LeuElement extends LitElement {
27
- static define(name, constructor = this, options = {}) {
28
- if (!customElements.get(name)) {
29
- customElements.define(name, constructor, options);
30
- } else {
31
- console.info(`${name} is already defined`);
32
- }
33
- }
34
- constructor() {
35
- super();
36
- Object.entries(this.constructor.dependencies).forEach(([name, component]) => {
37
- this.constructor.define(name, component);
38
- });
39
- }
40
- }
41
- _defineProperty(LeuElement, "dependencies", {});
42
-
43
- export { LeuElement as L, _defineProperty as _ };