@statistikzh/leu 0.26.0 → 0.28.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 (209) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/.storybook/main.ts +1 -1
  3. package/.storybook/preview.ts +6 -4
  4. package/.storybook/static/global.css +5 -0
  5. package/CHANGELOG.md +44 -0
  6. package/dist/{Accordion-B04QkmHz.js → Accordion-D9kLsiBW.js} +1 -1
  7. package/dist/Accordion.d.ts +1 -1
  8. package/dist/Accordion.js +2 -2
  9. package/dist/{Button-BgNUxmo_.d.ts → Button-DcuvEVkC.d.ts} +14 -12
  10. package/dist/{Button-BkhqVjug.js → Button-DyNVOHCd.js} +90 -82
  11. package/dist/Button.d.ts +1 -1
  12. package/dist/Button.js +4 -4
  13. package/dist/{ButtonGroup-B8U9fDvM.js → ButtonGroup-MEh4vb5a.js} +2 -2
  14. package/dist/ButtonGroup.d.ts +1 -1
  15. package/dist/ButtonGroup.js +5 -5
  16. package/dist/{ChartWrapper-CSMFwz9e.js → ChartWrapper-DAl91BIN.js} +2 -2
  17. package/dist/ChartWrapper.d.ts +3 -3
  18. package/dist/ChartWrapper.js +3 -3
  19. package/dist/{Checkbox-Dd1QLpfn.js → Checkbox-CGGyUW9U.js} +2 -2
  20. package/dist/Checkbox.d.ts +3 -3
  21. package/dist/Checkbox.js +3 -3
  22. package/dist/{CheckboxGroup-Bz2eWEFL.js → CheckboxGroup-DXt5iMdj.js} +2 -2
  23. package/dist/CheckboxGroup.d.ts +1 -1
  24. package/dist/CheckboxGroup.js +4 -4
  25. package/dist/{Chip-XAQIIsXq.js → Chip-BGs71WGH.js} +1 -1
  26. package/dist/{Chip-DLKM9P7v.d.ts → Chip-DVGjEPJE.d.ts} +1 -1
  27. package/dist/Chip.d.ts +1 -1
  28. package/dist/Chip.js +2 -2
  29. package/dist/{ChipGroup-Ta8Ht4jc.d.ts → ChipGroup-BK5BYM0X.d.ts} +2 -2
  30. package/dist/{ChipGroup-DLqfK2kn.js → ChipGroup-BcGyusP-.js} +1 -1
  31. package/dist/ChipGroup.d.ts +1 -1
  32. package/dist/ChipGroup.js +3 -3
  33. package/dist/{ChipLink-BAxyQO2M.d.ts → ChipLink-BdG2o-nk.d.ts} +1 -1
  34. package/dist/ChipLink.d.ts +1 -1
  35. package/dist/ChipLink.js +2 -2
  36. package/dist/{ChipRemovable-DBjwt0CH.d.ts → ChipRemovable-CCwSQTAL.d.ts} +2 -2
  37. package/dist/ChipRemovable.d.ts +1 -1
  38. package/dist/ChipRemovable.js +3 -3
  39. package/dist/{ChipSelectable-CMJNcE4U.d.ts → ChipSelectable-BQ3VLVi5.d.ts} +1 -1
  40. package/dist/ChipSelectable.d.ts +1 -1
  41. package/dist/ChipSelectable.js +2 -2
  42. package/dist/{Dialog-DHuXR_oo.js → Dialog-BzuyL1U3.js} +2 -2
  43. package/dist/Dialog.d.ts +3 -3
  44. package/dist/Dialog.js +3 -3
  45. package/dist/{Dropdown-DtFTePbc.js → Dropdown-plyBTM15.js} +5 -5
  46. package/dist/Dropdown.d.ts +6 -6
  47. package/dist/Dropdown.js +8 -8
  48. package/dist/{FileInput-b8sbLDPI.js → FileInput-BT3Fe-0J.js} +22 -7
  49. package/dist/FileInput.d.ts +16 -5
  50. package/dist/FileInput.js +6 -6
  51. package/dist/{Icon-Op80LrrO.d.ts → Icon-CUfh3eb3.d.ts} +1 -1
  52. package/dist/{Icon-C_yYuynf.js → Icon-D83qesg5.js} +1 -1
  53. package/dist/Icon.d.ts +1 -1
  54. package/dist/Icon.js +2 -2
  55. package/dist/{Input-DEOVocTa.js → Input-D7zS50oz.js} +32 -11
  56. package/dist/{Input-D2THgo7c.d.ts → Input-fEiQvGDF.d.ts} +9 -5
  57. package/dist/Input.d.ts +1 -1
  58. package/dist/Input.js +3 -3
  59. package/dist/{LeuElement-BeFrgKes.js → LeuElement-DQI8cqZV.js} +1 -1
  60. package/dist/{Menu-BeqqtCw6.js → Menu-DRU1LiMM.js} +2 -2
  61. package/dist/{Menu-CQdx1ef3.d.ts → Menu-Z2b7dsB5.d.ts} +2 -2
  62. package/dist/Menu.d.ts +1 -1
  63. package/dist/Menu.js +4 -4
  64. package/dist/{MenuItem-DVg8-1Bq.js → MenuItem-DCttylRO.js} +2 -2
  65. package/dist/{MenuItem-QcgnRk_7.d.ts → MenuItem-LY4TRIho.d.ts} +2 -2
  66. package/dist/MenuItem.d.ts +1 -1
  67. package/dist/MenuItem.js +3 -3
  68. package/dist/{Message-BhknWvAF.js → Message-0NxnKEqw.js} +2 -2
  69. package/dist/Message.d.ts +2 -2
  70. package/dist/Message.js +3 -3
  71. package/dist/{Pagination-CqkHh-Vd.d.ts → Pagination-9eZ8WMvR.d.ts} +4 -4
  72. package/dist/{Pagination-DJI5MIi_.js → Pagination-CIy7YvWE.js} +4 -4
  73. package/dist/Pagination.d.ts +1 -1
  74. package/dist/Pagination.js +6 -6
  75. package/dist/{Placeholder-BJybFwSg.js → Placeholder-Dol_X5Hp.js} +1 -1
  76. package/dist/Placeholder.d.ts +1 -1
  77. package/dist/Placeholder.js +2 -2
  78. package/dist/{Popup-Btgm2a3D.d.ts → Popup-B5iDSLIO.d.ts} +1 -1
  79. package/dist/{Popup-DNlm_9AA.js → Popup-nJrJHGSy.js} +1 -1
  80. package/dist/Popup.d.ts +1 -1
  81. package/dist/Popup.js +2 -2
  82. package/dist/{ProgressBar-B0wYj1KF.js → ProgressBar-Dmq9veqU.js} +1 -1
  83. package/dist/ProgressBar.d.ts +1 -1
  84. package/dist/ProgressBar.js +2 -2
  85. package/dist/{Radio-DMCL8c4D.js → Radio-W5ck_IJI.js} +1 -1
  86. package/dist/Radio.d.ts +1 -1
  87. package/dist/Radio.js +2 -2
  88. package/dist/{RadioGroup-CM6IyBlq.js → RadioGroup-De5x2YCO.js} +2 -2
  89. package/dist/RadioGroup.d.ts +1 -1
  90. package/dist/RadioGroup.js +3 -3
  91. package/dist/{Range-B72rtfln.js → Range-NCdfDkeD.js} +1 -1
  92. package/dist/Range.d.ts +1 -1
  93. package/dist/Range.js +2 -2
  94. package/dist/{ScrollTop-BFAqBVDR.js → ScrollTop-DwcNIKmN.js} +20 -20
  95. package/dist/ScrollTop.d.ts +8 -8
  96. package/dist/ScrollTop.js +5 -5
  97. package/dist/{Select-vxl3BvD4.js → Select-Bpicra9q.js} +153 -134
  98. package/dist/Select.d.ts +80 -78
  99. package/dist/Select.js +9 -9
  100. package/dist/{Spinner-DDTqijTO.js → Spinner-BBiVZxFH.js} +1 -1
  101. package/dist/{Spinner-CrM1enM0.d.ts → Spinner-DHYaX6-Y.d.ts} +1 -1
  102. package/dist/Spinner.d.ts +1 -1
  103. package/dist/Spinner.js +2 -2
  104. package/dist/Tab-CN97q0nj.d.ts +30 -0
  105. package/dist/Tab-Ce9nrDok.js +117 -0
  106. package/dist/Tab.d.ts +2 -0
  107. package/dist/Tab.js +3 -0
  108. package/dist/TabGroup-C-cd4Wcx.js +248 -0
  109. package/dist/TabGroup.d.ts +64 -0
  110. package/dist/TabGroup.js +5 -0
  111. package/dist/TabPanel-BW1ydVBT.js +65 -0
  112. package/dist/TabPanel-DQgWP7LO.d.ts +26 -0
  113. package/dist/TabPanel.d.ts +2 -0
  114. package/dist/TabPanel.js +3 -0
  115. package/dist/{Table-BgCxfBcm.js → Table-DiYqIzBu.js} +3 -3
  116. package/dist/Table.d.ts +3 -3
  117. package/dist/Table.js +7 -7
  118. package/dist/{Tag-DK2KkPIQ.js → Tag-Ct8Hhv7W.js} +1 -1
  119. package/dist/Tag.d.ts +1 -1
  120. package/dist/Tag.js +2 -2
  121. package/dist/{VisuallyHidden-OeQvhxYn.d.ts → VisuallyHidden-CB7aRJzF.d.ts} +1 -1
  122. package/dist/{VisuallyHidden-pll3amXE.js → VisuallyHidden-CpYXyuC7.js} +1 -1
  123. package/dist/VisuallyHidden.d.ts +1 -1
  124. package/dist/VisuallyHidden.js +2 -2
  125. package/dist/index.d.ts +14 -14
  126. package/dist/index.js +30 -30
  127. package/dist/leu-accordion.js +2 -2
  128. package/dist/leu-button-group.js +5 -5
  129. package/dist/leu-button.d.ts +1 -1
  130. package/dist/leu-button.js +4 -4
  131. package/dist/leu-chart-wrapper.js +3 -3
  132. package/dist/leu-checkbox-group.js +4 -4
  133. package/dist/leu-checkbox.js +3 -3
  134. package/dist/leu-chip-group.d.ts +1 -1
  135. package/dist/leu-chip-group.js +3 -3
  136. package/dist/leu-chip-link.d.ts +1 -1
  137. package/dist/leu-chip-link.js +2 -2
  138. package/dist/leu-chip-removable.d.ts +1 -1
  139. package/dist/leu-chip-removable.js +3 -3
  140. package/dist/leu-chip-selectable.d.ts +1 -1
  141. package/dist/leu-chip-selectable.js +2 -2
  142. package/dist/leu-dialog.js +3 -3
  143. package/dist/leu-dropdown.js +8 -8
  144. package/dist/leu-file-input.js +6 -6
  145. package/dist/leu-icon.d.ts +1 -1
  146. package/dist/leu-icon.js +2 -2
  147. package/dist/leu-input.d.ts +1 -1
  148. package/dist/leu-input.js +3 -3
  149. package/dist/leu-menu-item.d.ts +1 -1
  150. package/dist/leu-menu-item.js +3 -3
  151. package/dist/leu-menu.d.ts +1 -1
  152. package/dist/leu-menu.js +4 -4
  153. package/dist/leu-message.js +3 -3
  154. package/dist/leu-pagination.d.ts +1 -1
  155. package/dist/leu-pagination.js +6 -6
  156. package/dist/leu-placeholder.js +2 -2
  157. package/dist/leu-popup.d.ts +1 -1
  158. package/dist/leu-popup.js +2 -2
  159. package/dist/leu-progress-bar.js +2 -2
  160. package/dist/leu-radio-group.js +3 -3
  161. package/dist/leu-radio.js +2 -2
  162. package/dist/leu-range.js +2 -2
  163. package/dist/leu-scroll-top.js +5 -5
  164. package/dist/leu-select.js +9 -9
  165. package/dist/leu-spinner.d.ts +1 -1
  166. package/dist/leu-spinner.js +2 -2
  167. package/dist/leu-tab-group.d.ts +10 -0
  168. package/dist/leu-tab-group.js +8 -0
  169. package/dist/leu-tab-panel.d.ts +10 -0
  170. package/dist/leu-tab-panel.js +6 -0
  171. package/dist/leu-tab.d.ts +10 -0
  172. package/dist/leu-tab.js +6 -0
  173. package/dist/leu-table.js +7 -7
  174. package/dist/leu-tag.js +2 -2
  175. package/dist/leu-visually-hidden.d.ts +1 -1
  176. package/dist/leu-visually-hidden.js +2 -2
  177. package/dist/vscode.html-custom-data.json +90 -35
  178. package/dist/vue/index.d.ts +89 -29
  179. package/dist/web-types.json +182 -76
  180. package/package.json +1 -2
  181. package/src/components/button/Button.ts +45 -30
  182. package/src/components/button/button.css +55 -54
  183. package/src/components/button/stories/button.stories.ts +17 -20
  184. package/src/components/button/test/button.test.ts +46 -0
  185. package/src/components/file-input/FileInput.ts +24 -5
  186. package/src/components/input/Input.ts +43 -8
  187. package/src/components/input/test/input.test.ts +106 -1
  188. package/src/components/scroll-top/ScrollTop.ts +18 -16
  189. package/src/components/select/Select.ts +198 -125
  190. package/src/components/select/select.css +4 -0
  191. package/src/components/select/stories/select.stories.ts +10 -0
  192. package/src/components/select/test/select.test.ts +440 -35
  193. package/src/components/tab/Tab.ts +72 -0
  194. package/src/components/tab/TabGroup.ts +267 -0
  195. package/src/components/tab/TabPanel.ts +59 -0
  196. package/src/components/tab/leu-tab-group.ts +11 -0
  197. package/src/components/tab/leu-tab-panel.ts +11 -0
  198. package/src/components/tab/leu-tab.ts +11 -0
  199. package/src/components/tab/stories/tab.stories.ts +97 -0
  200. package/src/components/tab/tab-group.css +63 -0
  201. package/src/components/tab/tab-panel.css +10 -0
  202. package/src/components/tab/tab.css +54 -0
  203. package/src/components/tab/test/tab-group.test.ts +426 -0
  204. package/src/components/tab/test/tab-panel.test.ts +102 -0
  205. package/src/components/tab/test/tab.test.ts +139 -0
  206. package/tsconfig.json +1 -0
  207. /package/dist/{FormAssociatedMixin-Cc74LjbC.d.ts → FormAssociatedMixin-Cw7LsSUE.d.ts} +0 -0
  208. /package/dist/{LeuElement-pJFU18Xm.d.ts → LeuElement-DK1jntuu.d.ts} +0 -0
  209. /package/dist/{hasSlotController-DWPyZ52b.d.ts → hasSlotController-BjKyhJm-.d.ts} +0 -0
@@ -5,21 +5,22 @@
5
5
  /*
6
6
  * @todo : Disable hover styles for loading state
7
7
  */
8
- button {
8
+ .button {
9
9
  position: relative;
10
-
11
10
  font-family: var(--leu-font-family-black);
12
11
  text-align: center;
12
+ text-decoration: none;
13
13
  appearance: none;
14
14
  transition: background 0.1s ease;
15
15
  cursor: pointer;
16
16
  border: none;
17
17
  border-radius: 2px;
18
18
 
19
- max-width: 100%;
20
- display: flex;
19
+ display: inline-flex;
20
+ justify-content: center;
21
21
  align-items: center;
22
22
  column-gap: 8px;
23
+ width: 100%;
23
24
  }
24
25
 
25
26
  .content {
@@ -29,49 +30,49 @@ button {
29
30
  white-space: nowrap;
30
31
  }
31
32
 
32
- button.round {
33
+ .button--round {
33
34
  border-radius: 50%;
34
35
  }
35
36
 
36
- button.disabled {
37
+ .button--disabled {
37
38
  cursor: not-allowed;
38
39
  }
39
40
 
40
- button.loading {
41
+ .button--loading {
41
42
  cursor: wait;
42
43
  }
43
44
 
44
- button:focus-visible {
45
+ .button:focus-visible {
45
46
  outline: 2px solid var(--leu-color-func-cyan);
46
47
  outline-offset: 2px;
47
48
  }
48
49
 
49
- button.inverted:focus-visible {
50
+ .button--inverted:focus-visible {
50
51
  outline: 2px solid var(--leu-color-black-0);
51
52
  }
52
53
 
53
- :host([fluid]) button {
54
- width: 100%;
55
- justify-content: center;
54
+ .button--icon-only {
55
+ aspect-ratio: 1;
56
+ width: unset;
56
57
  }
57
58
 
58
- button.loading :where(.content, .icon-wrapper) {
59
+ .button--loading :where(.content, .icon-wrapper) {
59
60
  visibility: hidden;
60
61
  }
61
62
 
62
63
  /* size - regular */
63
- button.regular {
64
+ .button--regular {
64
65
  padding: 12px 24px;
65
66
  font-size: 16px;
66
67
  line-height: 24px;
67
68
  }
68
69
 
69
- button.regular.icon-only {
70
+ .button--regular.button--icon-only {
70
71
  padding: 12px;
71
72
  }
72
73
 
73
74
  /* size - small */
74
- button.small {
75
+ .button--small {
75
76
  padding: 6px 24px;
76
77
  font-size: 14px;
77
78
  line-height: 20px;
@@ -79,62 +80,62 @@ button.small {
79
80
  --leu-icon-size: 1rem;
80
81
  }
81
82
 
82
- button.small.icon-only {
83
+ .button--small.button--icon-only {
83
84
  padding: 8px;
84
85
  }
85
86
 
86
87
  /* primary */
87
- button.primary {
88
+ .button--primary {
88
89
  color: var(--leu-color-black-0);
89
90
  background: var(--leu-color-black-100);
90
91
  }
91
92
 
92
- button.primary:hover {
93
+ .button--primary:hover {
93
94
  color: var(--leu-color-black-0);
94
95
  background: var(--leu-color-black-transp-80);
95
96
  }
96
97
 
97
- button.primary.active {
98
+ .button--primary.button--active {
98
99
  color: var(--leu-color-black-0);
99
100
  background: var(--leu-color-black-100);
100
101
  }
101
102
 
102
- button.primary.active:hover {
103
+ .button--primary.button--active:hover {
103
104
  background: var(--leu-color-black-transp-80);
104
105
  }
105
106
 
106
- button.primary.disabled {
107
+ .button--primary.button--disabled {
107
108
  color: var(--leu-color-black-0);
108
109
  background: var(--leu-color-black-transp-20);
109
110
  }
110
111
 
111
112
  /* secondary */
112
- button.secondary {
113
+ .button--secondary {
113
114
  color: var(--leu-color-black-transp-60);
114
115
  background: var(--leu-color-black-transp-10);
115
116
  }
116
117
 
117
- button.secondary:hover {
118
+ .button--secondary:hover {
118
119
  color: var(--leu-color-black-100);
119
120
  background: var(--leu-color-black-transp-20);
120
121
  }
121
122
 
122
- button.secondary.active {
123
+ .button--secondary.button--active {
123
124
  color: var(--leu-color-black-0);
124
125
  background: var(--leu-color-black-100);
125
126
  }
126
127
 
127
- button.secondary.active:hover {
128
+ .button--secondary.button--active:hover {
128
129
  background: var(--leu-color-black-transp-80);
129
130
  }
130
131
 
131
- button.secondary.disabled {
132
+ .button--secondary.button--disabled {
132
133
  color: var(--leu-color-black-transp-20);
133
134
  background: var(--leu-color-black-transp-5);
134
135
  }
135
136
 
136
137
  /* ghost */
137
- button.ghost {
138
+ .button--ghost {
138
139
  --leu-icon-size: 1rem;
139
140
 
140
141
  background: transparent;
@@ -144,74 +145,74 @@ button.ghost {
144
145
  height: 2rem;
145
146
  }
146
147
 
147
- button.ghost:hover {
148
+ .button--ghost:hover {
148
149
  color: var(--leu-color-black-100);
149
150
  }
150
151
 
151
- button.ghost.active {
152
+ .button--ghost.button--active {
152
153
  color: var(--leu-color-black-100);
153
154
  }
154
155
 
155
- button.ghost.disabled {
156
+ .button--ghost.button--disabled {
156
157
  color: var(--leu-color-black-20);
157
158
  }
158
159
 
159
160
  /* primary + inverted */
160
- button.primary.inverted {
161
+ .button--primary.button--inverted {
161
162
  color: var(--leu-color-black-100);
162
163
  background: var(--leu-color-black-0);
163
164
  }
164
165
 
165
- button.primary.inverted:hover {
166
+ .button--primary.button--inverted:hover {
166
167
  color: var(--leu-color-black-100);
167
168
  background: var(--leu-color-white-transp-70);
168
169
  }
169
170
 
170
- button.primary.inverted.active {
171
+ .button--primary.button--inverted.button--active {
171
172
  color: var(--leu-color-black-0);
172
173
  background: var(--leu-color-black-100);
173
174
  }
174
175
 
175
- button.primary.inverted.disabled {
176
+ .button--primary.button--inverted.button--disabled {
176
177
  color: var(--leu-color-black-40);
177
178
  background: var(--leu-color-white-transp-70);
178
179
  }
179
180
 
180
181
  /* secondary + inverted */
181
- button.secondary.inverted {
182
+ .button--secondary.button--inverted {
182
183
  color: var(--leu-color-black-0);
183
184
  background: var(--leu-color-black-transp-20);
184
185
  }
185
186
 
186
- button.secondary.inverted:hover {
187
+ .button--secondary.button--inverted:hover {
187
188
  color: var(--leu-color-black-0);
188
189
  background: var(--leu-color-black-transp-40);
189
190
  }
190
191
 
191
- button.secondary.inverted.active {
192
+ .button--secondary.button--inverted.button--active {
192
193
  color: var(--leu-color-black-100);
193
194
  background: var(--leu-color-black-0);
194
195
  }
195
196
 
196
- button.secondary.inverted.disabled {
197
+ .button--secondary.button--inverted.button--disabled {
197
198
  color: var(--leu-color-white-transp-70);
198
199
  background: var(--leu-color-black-transp-10);
199
200
  }
200
201
 
201
202
  /* ghost + inverted */
202
- button.ghost.inverted {
203
+ .button--ghost.button--inverted {
203
204
  color: var(--leu-color-black-0);
204
205
  }
205
206
 
206
- button.ghost.inverted:hover {
207
+ .button--ghost.button--inverted:hover {
207
208
  color: var(--leu-color-white-transp-70);
208
209
  }
209
210
 
210
- button.ghost.inverted.active {
211
+ .button--ghost.button--inverted.button--active {
211
212
  color: var(--leu-color-black-0);
212
213
  }
213
214
 
214
- button.ghost.inverted.disabled {
215
+ .button--ghost.button--inverted.button--disabled {
215
216
  color: var(--leu-color-black-20);
216
217
  }
217
218
 
@@ -224,12 +225,12 @@ button.ghost.inverted.disabled {
224
225
  display: none;
225
226
  }
226
227
 
227
- .icon-before .icon-wrapper--before,
228
- .icon-after .icon-wrapper--after {
228
+ .button--icon-before .icon-wrapper--before,
229
+ .button--icon-after .icon-wrapper--after {
229
230
  display: block;
230
231
  }
231
232
 
232
- .ghost .icon-wrapper {
233
+ .button--ghost .icon-wrapper {
233
234
  position: relative;
234
235
  width: 2rem;
235
236
  padding: 0 0.5rem;
@@ -237,14 +238,14 @@ button.ghost.inverted.disabled {
237
238
  --_color: currentcolor;
238
239
  }
239
240
 
240
- .ghost .icon-wrapper__slot {
241
+ .button--ghost .icon-wrapper__slot {
241
242
  display: block;
242
243
  position: relative;
243
244
  z-index: 1;
244
245
  color: var(--_color);
245
246
  }
246
247
 
247
- .ghost .icon-wrapper::before {
248
+ .button--ghost .icon-wrapper::before {
248
249
  content: "";
249
250
  position: absolute;
250
251
  z-index: 0;
@@ -257,32 +258,32 @@ button.ghost.inverted.disabled {
257
258
  background: var(--_bg);
258
259
  }
259
260
 
260
- .ghost.active .icon-wrapper {
261
+ .button--ghost.button--active .icon-wrapper {
261
262
  --_bg: var(--leu-color-black-100);
262
263
  --_color: var(--leu-color-black-0);
263
264
  }
264
265
 
265
- .ghost.disabled .icon-wrapper {
266
+ .button--ghost.button--disabled .icon-wrapper {
266
267
  --_bg: var(--leu-color-black-transp-5);
267
268
  }
268
269
 
269
270
  /* inverted */
270
271
 
271
- .ghost.inverted .icon-wrapper {
272
+ .button--ghost.button--inverted .icon-wrapper {
272
273
  --_bg: var(--leu-color-black-transp-20);
273
274
  }
274
275
 
275
- .ghost.inverted:hover .icon-wrapper {
276
+ .button--ghost.button--inverted:hover .icon-wrapper {
276
277
  --_bg: var(--leu-color-black-transp-40);
277
278
  --_color: var(--leu-color-black-0);
278
279
  }
279
280
 
280
- .ghost.inverted.disabled .icon-wrapper {
281
+ .button--ghost.button--inverted.button--disabled .icon-wrapper {
281
282
  --_bg: var(--leu-color-black-transp-20);
282
283
  --_color: var(--leu-color-white-transp-70);
283
284
  }
284
285
 
285
- .ghost.active.inverted .icon-wrapper {
286
+ .button--ghost.button--active.button--inverted .icon-wrapper {
286
287
  --_bg: var(--leu-color-black-0);
287
288
  --_color: var(--leu-color-black-100);
288
289
  }
@@ -29,7 +29,7 @@ export default {
29
29
  }
30
30
 
31
31
  function Template(args = {}) {
32
- const component = html`
32
+ return html`
33
33
  <div data-root>
34
34
  <leu-button
35
35
  content=${ifDefined(args.content)}
@@ -37,12 +37,14 @@ function Template(args = {}) {
37
37
  variant=${ifDefined(args.variant)}
38
38
  type=${ifDefined(args.type)}
39
39
  expanded=${ifDefined(args.expanded)}
40
+ href=${ifDefined(args.href)}
41
+ target=${ifDefined(args.target)}
40
42
  ?round=${args.round}
41
43
  ?active=${args.active}
42
44
  ?inverted=${args.inverted}
43
45
  ?disabled=${args.disabled}
44
46
  ?loading=${args.loading}
45
- @click=${copyContent}
47
+ @click=${args.href ? undefined : copyContent}
46
48
  >
47
49
  ${args.icon
48
50
  ? html`<leu-icon
@@ -53,23 +55,6 @@ function Template(args = {}) {
53
55
  ${args.content}
54
56
  </leu-button>
55
57
  </div>
56
- <br />
57
- <p>Click the button to copy the code to the clipboard</p>
58
- `
59
-
60
- return html`
61
- <style>
62
- * {
63
- font-family: Helvetica;
64
- }
65
- </style>
66
- <div
67
- style="${args.inverted
68
- ? "background:var(--leu-color-accent-blue); color: var(--leu-color-white-transp-90);"
69
- : ""}padding:40px;"
70
- >
71
- ${component}
72
- </div>
73
58
  `
74
59
  }
75
60
 
@@ -89,6 +74,7 @@ Regular.argTypes = {
89
74
  round: { control: "boolean" },
90
75
  active: { control: "boolean" },
91
76
  loading: { control: "boolean" },
77
+ href: { control: "text" },
92
78
  }
93
79
  Regular.args = {
94
80
  content: "Click Mich...",
@@ -104,6 +90,17 @@ Regular.args = {
104
90
  type: null,
105
91
  }
106
92
 
93
+ export const Link = Template.bind({})
94
+ Link.args = {
95
+ content: "Zu den Daten",
96
+ icon: "link",
97
+ iconPosition: "before",
98
+ href: "https://datenkatalog.statistik.zh.ch/",
99
+ target: "_blank",
100
+ variant: "ghost",
101
+ size: "regular",
102
+ }
103
+
107
104
  const items = [
108
105
  { content: "Normal" },
109
106
  { content: "Active", active: true },
@@ -301,6 +298,7 @@ function TemplateOverview() {
301
298
  .table {
302
299
  display: grid;
303
300
  align-items: center;
301
+ justify-items: start;
304
302
  grid-template-columns: auto auto auto;
305
303
  gap: 10px;
306
304
  padding: 10px;
@@ -327,7 +325,6 @@ function TemplateOverview() {
327
325
  size=${ifDefined(size.size)}
328
326
  variant=${ifDefined(group.variant)}
329
327
  expanded=${ifDefined(item.expanded)}
330
- ?round=${item.round}
331
328
  ?active=${item.active}
332
329
  ?disabled=${item.disabled}
333
330
  ?inverted=${group.inverted}
@@ -32,6 +32,16 @@ describe("LeuButton", () => {
32
32
  await expect(el).shadowDom.to.be.accessible()
33
33
  })
34
34
 
35
+ it("passes the a11y audit when rendered as link", async () => {
36
+ const el = await fixture(
37
+ html` <leu-button href="https://datenkatalog.statistik.zh.ch/"
38
+ >Link</leu-button
39
+ >`,
40
+ )
41
+
42
+ await expect(el).shadowDom.to.be.accessible()
43
+ })
44
+
35
45
  it("renders the label", async () => {
36
46
  const el = await fixture(html` <leu-button>Sichern</leu-button>`)
37
47
 
@@ -192,6 +202,42 @@ describe("LeuButton", () => {
192
202
  expect(clicked).to.be.false
193
203
  })
194
204
 
205
+ it("renders as an anchor when href is set", async () => {
206
+ const el = await fixture(
207
+ html` <leu-button
208
+ href="https://datenkatalog.statistik.zh.ch/"
209
+ target="_blank"
210
+ >Zu den Daten <leu-icon name="link" slot="before"></leu-icon
211
+ ></leu-button>`,
212
+ )
213
+
214
+ const anchor = el.shadowRoot.querySelector("a")
215
+
216
+ expect(anchor).to.exist
217
+ expect(anchor).to.have.attribute(
218
+ "href",
219
+ "https://datenkatalog.statistik.zh.ch/",
220
+ )
221
+ expect(anchor).to.have.attribute("target", "_blank")
222
+ })
223
+
224
+ it("does not set disabled or type attribute on anchor", async () => {
225
+ const el = await fixture(
226
+ html` <leu-button
227
+ href="https://datenkatalog.statistik.zh.ch/"
228
+ disabled
229
+ type="submit"
230
+ >Zu den Daten <leu-icon name="link" slot="before"></leu-icon
231
+ ></leu-button>`,
232
+ )
233
+
234
+ const anchor = el.shadowRoot.querySelector("a")
235
+
236
+ expect(anchor).to.exist
237
+ expect(anchor).to.not.have.attribute("disabled")
238
+ expect(anchor).to.not.have.attribute("type")
239
+ })
240
+
195
241
  describe("form association", () => {
196
242
  it("submits the form when type is submit", async () => {
197
243
  const form = await fixture<HTMLFormElement>(html`
@@ -145,16 +145,35 @@ export class LeuFileInput extends FormAssociatedMixin(LeuElement) {
145
145
  )
146
146
  }
147
147
 
148
+ /**
149
+ * This implementation Uses base-10 (decimal) units:
150
+ * 1 KB = 1_000 bytes
151
+ * 1 MB = 1_000_000 bytes
152
+ * 1 GB = 1_000_000_000 bytes
153
+ *
154
+ * To switch to base-2 (binary), use the following implementation:
155
+ * // const KB = 1024
156
+ * // const MB = 1024 * 1024
157
+ * // const GB = 1024 * 1024 * 1024
158
+ */
148
159
  protected static formatFileSize(size: number) {
149
- if (size < 1e3) {
150
- return html`${size}&nbsp;bytes`
160
+ const KB = 1e3
161
+ const MB = 1e6
162
+ const GB = 1e9
163
+
164
+ if (size >= GB) {
165
+ return html`${(size / GB).toFixed(1)}&nbsp;GB`
166
+ }
167
+
168
+ if (size >= MB) {
169
+ return html`${(size / MB).toFixed(1)}&nbsp;MB`
151
170
  }
152
171
 
153
- if (size >= 1e3 && size < 1e6) {
154
- return html`${(size / 1e3).toFixed(1)}&nbsp;KB`
172
+ if (size >= KB) {
173
+ return html`${(size / KB).toFixed(1)}&nbsp;KB`
155
174
  }
156
175
 
157
- return html`${(size / 1e6).toFixed(1)}&nbsp;MB`
176
+ return html`${size}&nbsp;bytes`
158
177
  }
159
178
 
160
179
  protected handleDragEnter = (event: DragEvent) => {
@@ -86,10 +86,6 @@ export class LeuInput extends FormAssociatedMixin(LeuElement) {
86
86
  @property({ type: Boolean, reflect: true })
87
87
  clearable: boolean = false
88
88
 
89
- /** The value of the input element. */
90
- @property({ type: String, reflect: true })
91
- value: string = ""
92
-
93
89
  /** A custom error that is completely independent of the validity state. Useful for displaying server side errors. */
94
90
  @property({ type: String, reflect: true })
95
91
  error: string = ""
@@ -150,6 +146,26 @@ export class LeuInput extends FormAssociatedMixin(LeuElement) {
150
146
  @property({ type: Boolean, reflect: true })
151
147
  novalidate: boolean = false
152
148
 
149
+ /** The default value of the input element. */
150
+ @property({ type: String, reflect: true, attribute: "value" })
151
+ defaultValue: string = ""
152
+
153
+ protected _value: string
154
+
155
+ /** The value of the input element. */
156
+ @property({ type: String, attribute: false })
157
+ set value(value: string) {
158
+ this._value = value
159
+ }
160
+
161
+ get value(): string {
162
+ if (typeof this._value === "string") {
163
+ return this._value
164
+ }
165
+
166
+ return this.defaultValue
167
+ }
168
+
153
169
  @state()
154
170
  _validity: ValidityState | null = null
155
171
 
@@ -171,15 +187,32 @@ export class LeuInput extends FormAssociatedMixin(LeuElement) {
171
187
  }
172
188
 
173
189
  formResetCallback() {
174
- this.value = ""
190
+ this.value = this.defaultValue
175
191
  }
176
192
 
177
193
  protected setFormValue(): void {
178
- this.internals.setFormValue(this.value)
194
+ this.internals.setFormValue(this.disabled ? null : this.value)
179
195
  }
180
196
 
181
197
  protected willUpdate(changedProperties: PropertyValues<this>): void {
182
- if (changedProperties.has("value")) {
198
+ super.willUpdate(changedProperties)
199
+ let valueChanged = false
200
+
201
+ if (
202
+ changedProperties.has("defaultValue") &&
203
+ !changedProperties.has("value") &&
204
+ !this.hasInteracted
205
+ ) {
206
+ this.value = this.defaultValue
207
+ valueChanged = true
208
+ }
209
+
210
+ if (
211
+ valueChanged ||
212
+ changedProperties.has("value") ||
213
+ changedProperties.has("name") ||
214
+ changedProperties.has("disabled")
215
+ ) {
183
216
  this.setFormValue()
184
217
  }
185
218
  }
@@ -225,6 +258,7 @@ export class LeuInput extends FormAssociatedMixin(LeuElement) {
225
258
  * @fires {CustomEvent} change
226
259
  */
227
260
  protected handleChange(event: Event & { target: HTMLInputElement }) {
261
+ this.hasInteracted = true
228
262
  if (event.target.validity.valid) {
229
263
  this.value = event.target.value
230
264
  }
@@ -239,6 +273,7 @@ export class LeuInput extends FormAssociatedMixin(LeuElement) {
239
273
  * the event can be handled outside the shadow DOM.
240
274
  */
241
275
  protected handleInput(event: Event & { target: HTMLInputElement }) {
276
+ this.hasInteracted = true
242
277
  this.value = event.target.value
243
278
 
244
279
  const customEvent = new CustomEvent("input", {
@@ -311,7 +346,7 @@ export class LeuInput extends FormAssociatedMixin(LeuElement) {
311
346
  return true
312
347
  }
313
348
 
314
- return this._validity === null || this.novalidate
349
+ return this._validity === null || this.novalidate || this.disabled
315
350
  ? false
316
351
  : !this._validity.valid
317
352
  }