@statistikzh/leu 0.6.0 → 0.8.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 (126) hide show
  1. package/.eslintrc.json +4 -1
  2. package/CHANGELOG.md +30 -0
  3. package/dist/Accordion.d.ts +1 -1
  4. package/dist/Accordion.js +1 -1
  5. package/dist/Breadcrumb.d.ts +1 -1
  6. package/dist/Breadcrumb.d.ts.map +1 -1
  7. package/dist/Breadcrumb.js +3 -1
  8. package/dist/{Button-9692e403.d.ts → Button-3adfb3ed.d.ts} +2 -2
  9. package/dist/Button-3adfb3ed.d.ts.map +1 -0
  10. package/dist/{Button-9692e403.js → Button-3adfb3ed.js} +1 -1
  11. package/dist/Button.d.ts +1 -1
  12. package/dist/Button.js +2 -2
  13. package/dist/ButtonGroup.d.ts +1 -1
  14. package/dist/ButtonGroup.d.ts.map +1 -1
  15. package/dist/ButtonGroup.js +1 -1
  16. package/dist/Checkbox.d.ts +1 -1
  17. package/dist/Checkbox.d.ts.map +1 -1
  18. package/dist/Checkbox.js +3 -1
  19. package/dist/CheckboxGroup.d.ts +3 -2
  20. package/dist/CheckboxGroup.d.ts.map +1 -1
  21. package/dist/CheckboxGroup.js +6 -3
  22. package/dist/Chip.d.ts +1 -1
  23. package/dist/Chip.d.ts.map +1 -1
  24. package/dist/Chip.js +19 -17
  25. package/dist/ChipGroup.d.ts +8 -2
  26. package/dist/ChipGroup.d.ts.map +1 -1
  27. package/dist/ChipGroup.js +32 -5
  28. package/dist/ChipLink.js +1 -1
  29. package/dist/ChipRemovable.d.ts +7 -0
  30. package/dist/ChipRemovable.d.ts.map +1 -1
  31. package/dist/ChipRemovable.js +23 -3
  32. package/dist/ChipSelectable.d.ts +9 -1
  33. package/dist/ChipSelectable.d.ts.map +1 -1
  34. package/dist/ChipSelectable.js +23 -11
  35. package/dist/Dropdown.d.ts +1 -1
  36. package/dist/Dropdown.d.ts.map +1 -1
  37. package/dist/Dropdown.js +2 -2
  38. package/dist/Icon.d.ts +98 -2
  39. package/dist/Icon.d.ts.map +1 -1
  40. package/dist/Icon.js +1 -1
  41. package/dist/Input.d.ts +7 -2
  42. package/dist/Input.d.ts.map +1 -1
  43. package/dist/Input.js +16 -3
  44. package/dist/{LeuElement-6de6f209.d.ts → LeuElement-a20c5fd6.d.ts} +2 -2
  45. package/dist/LeuElement-a20c5fd6.d.ts.map +1 -0
  46. package/dist/LeuElement-a20c5fd6.js +52 -0
  47. package/dist/Menu.d.ts +2 -2
  48. package/dist/Menu.js +1 -1
  49. package/dist/MenuItem.d.ts +2 -2
  50. package/dist/MenuItem.js +4 -4
  51. package/dist/Pagination.d.ts +1 -1
  52. package/dist/Pagination.js +2 -2
  53. package/dist/Popup.d.ts +1 -1
  54. package/dist/Popup.d.ts.map +1 -1
  55. package/dist/Popup.js +3 -1
  56. package/dist/Radio.d.ts +1 -1
  57. package/dist/Radio.d.ts.map +1 -1
  58. package/dist/Radio.js +3 -1
  59. package/dist/RadioGroup.d.ts +1 -1
  60. package/dist/RadioGroup.d.ts.map +1 -1
  61. package/dist/RadioGroup.js +22 -10
  62. package/dist/ScrollTop.d.ts +1 -1
  63. package/dist/ScrollTop.js +2 -2
  64. package/dist/Select.d.ts +1 -1
  65. package/dist/Select.d.ts.map +1 -1
  66. package/dist/Select.js +4 -2
  67. package/dist/Table.d.ts +1 -1
  68. package/dist/Table.d.ts.map +1 -1
  69. package/dist/Table.js +4 -3
  70. package/dist/VisuallyHidden.d.ts +1 -1
  71. package/dist/VisuallyHidden.d.ts.map +1 -1
  72. package/dist/VisuallyHidden.js +5 -3
  73. package/dist/index.d.ts +2 -2
  74. package/dist/index.js +3 -3
  75. package/dist/leu-accordion.js +1 -1
  76. package/dist/leu-breadcrumb.js +1 -1
  77. package/dist/leu-button-group.js +1 -1
  78. package/dist/leu-button.d.ts +1 -1
  79. package/dist/leu-button.js +2 -2
  80. package/dist/leu-checkbox-group.js +1 -1
  81. package/dist/leu-checkbox.js +1 -1
  82. package/dist/leu-chip-group.js +1 -1
  83. package/dist/leu-chip-link.js +1 -1
  84. package/dist/leu-chip-removable.js +1 -1
  85. package/dist/leu-chip-selectable.js +1 -1
  86. package/dist/leu-dropdown.js +2 -2
  87. package/dist/leu-icon.js +1 -1
  88. package/dist/leu-input.js +1 -1
  89. package/dist/leu-menu-item.js +1 -1
  90. package/dist/leu-menu.js +1 -1
  91. package/dist/leu-pagination.js +2 -2
  92. package/dist/leu-popup.js +1 -1
  93. package/dist/leu-radio-group.js +1 -1
  94. package/dist/leu-radio.js +1 -1
  95. package/dist/leu-scroll-top.js +2 -2
  96. package/dist/leu-select.js +2 -2
  97. package/dist/leu-table.js +2 -2
  98. package/dist/leu-visually-hidden.js +1 -1
  99. package/dist/vscode.html-custom-data.json +32 -8
  100. package/dist/vue/index.d.ts +29 -9
  101. package/dist/web-types.json +236 -235
  102. package/package.json +4 -3
  103. package/rollup.config.js +9 -0
  104. package/src/components/checkbox/CheckboxGroup.js +3 -2
  105. package/src/components/checkbox/stories/checkbox-group.stories.js +3 -3
  106. package/src/components/chip/ChipGroup.js +28 -4
  107. package/src/components/chip/ChipRemovable.js +18 -0
  108. package/src/components/chip/ChipSelectable.js +24 -10
  109. package/src/components/chip/chip.css +16 -16
  110. package/src/components/chip/stories/chip-group.stories.js +6 -9
  111. package/src/components/chip/stories/chip-removable.stories.js +6 -2
  112. package/src/components/chip/stories/chip-selectable.stories.js +1 -1
  113. package/src/components/chip/test/chip-group.test.js +67 -0
  114. package/src/components/chip/test/chip-removable.test.js +36 -2
  115. package/src/components/chip/test/chip-selectable.test.js +18 -8
  116. package/src/components/input/Input.js +14 -1
  117. package/src/components/input/stories/input.stories.js +3 -3
  118. package/src/components/input/test/input.test.js +20 -0
  119. package/src/components/menu/MenuItem.js +1 -1
  120. package/src/components/menu/menu-item.css +2 -2
  121. package/src/components/radio/RadioGroup.js +15 -11
  122. package/src/components/radio/stories/radio-group.stories.js +3 -3
  123. package/src/lib/LeuElement.js +19 -11
  124. package/dist/Button-9692e403.d.ts.map +0 -1
  125. package/dist/LeuElement-6de6f209.d.ts.map +0 -1
  126. 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.8.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",
@@ -58,6 +58,7 @@
58
58
  "@rollup/plugin-babel": "^6.0.4",
59
59
  "@rollup/plugin-commonjs": "^25.0.7",
60
60
  "@rollup/plugin-json": "^6.0.0",
61
+ "@rollup/plugin-replace": "^5.0.7",
61
62
  "@rollup/plugin-typescript": "^11.1.6",
62
63
  "@storybook/addon-designs": "^7.0.9",
63
64
  "@storybook/addon-essentials": "^7.6.17",
@@ -66,7 +67,7 @@
66
67
  "@storybook/web-components": "^7.6.17",
67
68
  "@web/dev-server": "^0.4.6",
68
69
  "@web/dev-server-rollup": "^0.6.4",
69
- "@web/storybook-builder": "^0.1.16",
70
+ "@web/storybook-builder": "^0.1.6",
70
71
  "@web/storybook-framework-web-components": "^0.1.2",
71
72
  "@web/test-runner": "^0.18.2",
72
73
  "@web/test-runner-commands": "^0.9.0",
package/rollup.config.js CHANGED
@@ -4,8 +4,17 @@ import { fileURLToPath } from "url"
4
4
  import postcss from "rollup-plugin-postcss"
5
5
  import postcssLit from "rollup-plugin-postcss-lit"
6
6
  import { babel } from "@rollup/plugin-babel"
7
+ import replace from "@rollup/plugin-replace"
7
8
 
8
9
  export const plugins = [
10
+ {
11
+ plugin: replace,
12
+ args: [
13
+ {
14
+ __LEU_VERSION__: JSON.stringify(process.env.npm_package_version),
15
+ },
16
+ ],
17
+ },
9
18
  {
10
19
  plugin: postcss,
11
20
  args: [
@@ -19,7 +19,8 @@ export class LeuCheckboxGroup extends LeuElement {
19
19
 
20
20
  constructor() {
21
21
  super()
22
- this.orientation = "HORIZONTAL"
22
+ /** @type {"horizontal" | "vertical"} */
23
+ this.orientation = "horizontal"
23
24
  this.items = []
24
25
  }
25
26
 
@@ -38,7 +39,7 @@ export class LeuCheckboxGroup extends LeuElement {
38
39
  render() {
39
40
  const fieldsetClasses = {
40
41
  fieldset: "true",
41
- "fieldset--vertical": this.orientation === "VERTICAL",
42
+ "fieldset--vertical": this.orientation === "vertical",
42
43
  }
43
44
 
44
45
  return html`
@@ -9,7 +9,7 @@ export default {
9
9
  argTypes: {
10
10
  legend: { control: "text" },
11
11
  orientation: {
12
- options: ["VERTICAL", "HORIZONTAL"],
12
+ options: ["vertical", "horizontal"],
13
13
  control: { type: "checkbox" },
14
14
  },
15
15
  },
@@ -49,11 +49,11 @@ HorizontalLabel.args = {
49
49
 
50
50
  export const Vertical = Template.bind({})
51
51
  Vertical.args = {
52
- orientation: "VERTICAL",
52
+ orientation: "vertical",
53
53
  }
54
54
 
55
55
  export const VerticalLabel = Template.bind({})
56
56
  VerticalLabel.args = {
57
- orientation: "VERTICAL",
57
+ orientation: "vertical",
58
58
  label: "Anrede",
59
59
  }
@@ -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.getValue())
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
  }
@@ -7,6 +7,7 @@ import { LeuIcon } from "../icon/Icon.js"
7
7
  * @slot - The content of the chip
8
8
  * @tagname leu-chip-removable
9
9
  * @fires remove - Dispatched when the user clicks on the chip
10
+ * @prop {string} value - The value of the chip.
10
11
  */
11
12
  export class LeuChipRemovable extends LeuChipBase {
12
13
  static dependencies = {
@@ -15,12 +16,29 @@ export class LeuChipRemovable extends LeuChipBase {
15
16
 
16
17
  static properties = {
17
18
  ...LeuChipBase.properties,
19
+ value: { type: String, reflect: true },
20
+ }
21
+
22
+ constructor() {
23
+ super()
24
+ this.value = ""
25
+ }
26
+
27
+ /**
28
+ * Returns the value of the chip. If `value` is not set, it will return the text content
29
+ * @returns {string}
30
+ */
31
+ getValue() {
32
+ return this.value || this.textContent.trim()
18
33
  }
19
34
 
20
35
  handleClick() {
21
36
  const customEvent = new CustomEvent("leu:remove", {
22
37
  bubbles: true,
23
38
  composed: true,
39
+ detail: {
40
+ value: this.getValue(),
41
+ },
24
42
  })
25
43
  this.dispatchEvent(customEvent)
26
44
  }
@@ -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,8 @@ 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
46
+ this.value = ""
44
47
 
45
48
  if (this.variant === VARIANTS.radio && this.size === SIZES.small) {
46
49
  console.warn("Small size has no effect on radio variant")
@@ -48,19 +51,22 @@ export class LeuChipSelectable extends LeuChipBase {
48
51
  }
49
52
 
50
53
  handleClick() {
51
- let nextSelectedState = this.selected
54
+ let nextcheckedState = this.checked
52
55
 
53
56
  if (this.variant === VARIANTS.radio) {
54
- nextSelectedState = true
57
+ nextcheckedState = true
55
58
  } else {
56
- nextSelectedState = !this.selected
59
+ nextcheckedState = !this.checked
57
60
  }
58
61
 
59
- if (nextSelectedState !== this.selected) {
60
- this.selected = nextSelectedState
62
+ if (nextcheckedState !== this.checked) {
63
+ this.checked = nextcheckedState
61
64
  this.dispatchEvent(
62
65
  new CustomEvent("input", {
63
- detail: { selected: this.selected },
66
+ detail: {
67
+ checked: this.checked,
68
+ value: this.getValue(),
69
+ },
64
70
  bubbles: true,
65
71
  composed: true,
66
72
  })
@@ -68,11 +74,19 @@ export class LeuChipSelectable extends LeuChipBase {
68
74
  }
69
75
  }
70
76
 
77
+ /**
78
+ * Returns the value of the chip. If `value` is not set, it will return the text content
79
+ * @returns {string}
80
+ */
81
+ getValue() {
82
+ return this.value || this.textContent.trim()
83
+ }
84
+
71
85
  render() {
72
86
  return html`<button
73
- @click=${(e) => this.handleClick(e)}
87
+ @click=${() => this.handleClick()}
74
88
  class="button"
75
- aria-pressed=${this.selected ? "true" : "false"}
89
+ aria-pressed=${this.checked ? "true" : "false"}
76
90
  >
77
91
  <span class="label"><slot></slot></span>
78
92
  </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
  `
@@ -1,4 +1,5 @@
1
1
  import { html } from "lit"
2
+ import { action } from "@storybook/addon-actions"
2
3
 
3
4
  import "../leu-chip-removable.js"
4
5
 
@@ -6,7 +7,8 @@ export default {
6
7
  title: "Chip/Removable",
7
8
  component: "leu-chip-removable",
8
9
  args: {
9
- label: "Publikationen",
10
+ label: "Daten",
11
+ onRemove: action("leu:remove"),
10
12
  },
11
13
  parameters: {
12
14
  design: {
@@ -27,7 +29,9 @@ function Template(args) {
27
29
  : "var(--leu-color-black-5)"}; padding: 1rem;"
28
30
  data-root
29
31
  >
30
- <leu-chip-removable ?inverted=${args.inverted}
32
+ <leu-chip-removable
33
+ @leu:remove=${args.onRemove}
34
+ ?inverted=${args.inverted}
31
35
  >${args.label}</leu-chip-removable
32
36
  >
33
37
  </div>
@@ -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
  })
@@ -1,11 +1,18 @@
1
1
  import { html } from "lit"
2
2
  import { fixture, expect, oneEvent } from "@open-wc/testing"
3
3
  import { sendKeys } from "@web/test-runner-commands"
4
+ import { ifDefined } from "lit/directives/if-defined.js"
4
5
 
5
6
  import "../leu-chip-removable.js"
6
7
 
7
- async function defaultFixture() {
8
- return fixture(html` <leu-chip-removable>Daten</leu-chip-removable> `)
8
+ async function defaultFixture(args = {}) {
9
+ return fixture(
10
+ html`
11
+ <leu-chip-removable value=${ifDefined(args.value)}
12
+ >${args.label ?? "Daten"}</leu-chip-removable
13
+ >
14
+ `
15
+ )
9
16
  }
10
17
 
11
18
  describe("LeuChipRemovable", () => {
@@ -70,4 +77,31 @@ describe("LeuChipRemovable", () => {
70
77
 
71
78
  expect(event).to.exist
72
79
  })
80
+
81
+ it("sends the value in the remove event", async () => {
82
+ const el = await defaultFixture({ label: `Daten  ` }) // eslint-disable-line no-irregular-whitespace
83
+ const button = el.shadowRoot.querySelector("button")
84
+
85
+ setTimeout(() => button.click())
86
+ const event = await oneEvent(el, "leu:remove")
87
+
88
+ expect(event.detail.value).to.equal("Daten")
89
+
90
+ el.value = "test"
91
+
92
+ setTimeout(() => button.click())
93
+ const event2 = await oneEvent(el, "leu:remove")
94
+
95
+ expect(event2.detail.value).to.equal("test")
96
+ })
97
+
98
+ it("returns the value or label when getValue is called", async () => {
99
+ const el = await defaultFixture({ label: `Daten  ` }) // eslint-disable-line no-irregular-whitespace
100
+
101
+ expect(el.getValue()).to.equal("Daten")
102
+
103
+ el.value = "daten-01"
104
+
105
+ expect(el.getValue()).to.equal("daten-01")
106
+ })
73
107
  })
@@ -9,9 +9,9 @@ async function defaultFixture(args = {}) {
9
9
  return fixture(
10
10
  html`
11
11
  <leu-chip-selectable
12
- value="Publikationen"
12
+ value=${ifDefined(args.value)}
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,31 @@ 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
+ })
93
+
94
+ it("returns the value or label when getValue is called", async () => {
95
+ const el = await defaultFixture()
96
+
97
+ expect(el.getValue()).to.equal("Publikationen")
98
+
99
+ el.value = "publikationen-01"
100
+
101
+ expect(el.getValue()).to.equal("publikationen-01")
92
102
  })
93
103
  })
@@ -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
  })