material-inspired-component-library 1.2.2 → 2.0.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 (59) hide show
  1. package/README.md +18 -0
  2. package/components/badge/README.md +65 -0
  3. package/components/badge/index.scss +68 -0
  4. package/components/button/README.md +1 -1
  5. package/components/button/index.scss +60 -89
  6. package/components/button/index.ts +5 -0
  7. package/components/card/index.scss +29 -30
  8. package/components/checkbox/index.scss +1 -6
  9. package/components/dialog/index.scss +11 -7
  10. package/components/iconbutton/README.md +1 -1
  11. package/components/iconbutton/index.scss +46 -80
  12. package/components/iconbutton/index.ts +5 -0
  13. package/components/list/index.scss +39 -30
  14. package/components/list/index.ts +10 -9
  15. package/components/menu/README.md +67 -4
  16. package/components/menu/index.scss +29 -29
  17. package/components/menu/index.ts +47 -16
  18. package/components/navigationrail/README.md +150 -0
  19. package/components/navigationrail/index.scss +468 -0
  20. package/components/{checkbox → navigationrail}/index.ts +12 -7
  21. package/components/radio/index.scss +22 -12
  22. package/components/select/index.scss +5 -11
  23. package/components/textfield/index.scss +8 -2
  24. package/dist/badge.css +1 -0
  25. package/dist/badge.js +1 -0
  26. package/dist/bottomsheet.css +1 -1
  27. package/dist/button.css +1 -1
  28. package/dist/card.css +1 -1
  29. package/dist/checkbox.css +1 -1
  30. package/dist/components/menu/index.d.ts +0 -11
  31. package/dist/components/navigationrail/index.d.ts +5 -0
  32. package/dist/dialog.css +1 -1
  33. package/dist/iconbutton.css +1 -1
  34. package/dist/list.css +1 -1
  35. package/dist/menu.css +1 -1
  36. package/dist/micl.css +1 -1
  37. package/dist/micl.js +1 -1
  38. package/dist/navigationrail.css +1 -0
  39. package/dist/navigationrail.js +1 -0
  40. package/dist/radio.css +1 -1
  41. package/dist/select.css +1 -1
  42. package/dist/slider.css +1 -1
  43. package/dist/switch.css +1 -1
  44. package/dist/textfield.css +1 -1
  45. package/docs/button.html +5 -5
  46. package/docs/docs.css +2 -1
  47. package/docs/docs.js +2 -2
  48. package/docs/index.html +35 -2
  49. package/docs/menu.html +183 -3
  50. package/docs/micl.css +1 -1
  51. package/docs/micl.js +1 -1
  52. package/docs/navigationrail.html +81 -0
  53. package/micl.ts +20 -25
  54. package/package.json +10 -7
  55. package/styles/statelayer.scss +14 -0
  56. package/styles.scss +18 -1
  57. package/webpack.config.js +37 -0
  58. package/dist/components/checkbox/index.d.ts +0 -5
  59. package/styles/ripple.scss +0 -50
package/README.md CHANGED
@@ -79,6 +79,7 @@ This will initialize all MICL components, including those that will be added to
79
79
  ## Available components ✅
80
80
  The library currently consists of the following components:
81
81
  - [x] [Accordion](components/accordion/README.md)
82
+ - [x] [Badge](components/badge/README.md)
82
83
  - [x] [Bottom sheet](components/bottomsheet/README.md)
83
84
  - [x] [Button](components/button/README.md)
84
85
  - [x] [Card](components/card/README.md)
@@ -88,6 +89,7 @@ The library currently consists of the following components:
88
89
  - [x] [Icon button](components/iconbutton/README.md)
89
90
  - [x] [List](components/list/README.md)
90
91
  - [x] [Menu](components/menu/README.md)
92
+ - [x] [Navigation rail](components/navigationrail/README.md)
91
93
  - [x] [Radio button](components/radio/README.md)
92
94
  - [x] [Select](components/select/README.md)
93
95
  - [x] [Side sheet](components/sidesheet/README.md)
@@ -97,10 +99,26 @@ The library currently consists of the following components:
97
99
 
98
100
  ## Change Log
99
101
 
102
+ ### 2.0.0 (04.09.2025)
103
+ **Features**
104
+
105
+ - **Navigation rail**: New component.
106
+ - **Badge**: New component.
107
+ - **Ripple**: Now uses custom CSS properties.
108
+
109
+ ### 1.3.0 (23.08.2025)
110
+ **Features**
111
+
112
+ - **Menu**: Added support for submenus.
113
+ - **Ripple**: The ripple-effect does not use a pseudo-element anymore.
114
+ - **State layer**: Rewrite for simpler styling.
115
+
100
116
  ### 1.2.0 (17.08.2025)
101
117
  **Features**
118
+
102
119
  - **List**: Added support for switches inside list items.
103
120
 
104
121
  ### 1.1.0 (12.08.2025)
105
122
  **Features**
123
+
106
124
  - **Text field**: Added support for multi-line text fields.
@@ -0,0 +1,65 @@
1
+ # Badge
2
+ This component implements the the [Material Design 3 Expressive Badge](https://m3.material.io/components/badges/overview) design. Badges are small status indicators that can show a count or simply signal new information.
3
+
4
+ ## Basic Usage
5
+
6
+ ### HTML
7
+ To add a large badge, use a `<span>` element with the `micl-badge-large` class and add a short text inside. For a small badge, which is a simple dot, use a `<span>` with the `micl-badge-small` class and leave the element empty.
8
+
9
+ ```HTML
10
+ <span class="micl-badge-large">57</span>
11
+
12
+ <span class="micl-badge-small"></span>
13
+ ```
14
+
15
+ ### CSS
16
+ Import the badge styles into your project:
17
+
18
+ ```CSS
19
+ @use "material-inspired-component-library/dist/badge";
20
+ ```
21
+
22
+ ### JavaScript
23
+ No custom JavaScript is required for the core functionality of this component.
24
+
25
+ ### Demo
26
+ A live example of the [Badge component](https://henkpb.github.io/micl/index.html) is available for you to interact with.
27
+
28
+ ## Anchoring
29
+ Badges are typically placed on top of other elements, like icons. To anchor a badge to a specific element, use CSS `anchor positioning`.
30
+
31
+ 1. Assign a unique `anchor-name` to the element you want to anchor the badge to. The value should start with `--`.
32
+ 2. Use the `position-anchor` CSS property on the badge and set its value to the `anchor-name` of the target element.
33
+
34
+ ```HTML
35
+ <span class="material-symbols-outlined" style="anchor-name:--inbox">inbox</span>
36
+ <span class="micl-badge-large" style="position-anchor:--inbox">57</span>
37
+ ```
38
+
39
+ You can fine-tune the badge's position relative to its anchor using the following CSS variables:
40
+
41
+ | Variable name | Default Value | Description |
42
+ | ------------- | ------------- | ----------- |
43
+ | --md-sys-badge-inline-offset | 0px | Adjusts the horizontal position of the badge |
44
+ | --md-sys-badge-block-offset | 0px | Adjusts the vertical position of the badge |
45
+
46
+
47
+ ## Customizations
48
+ You can customize the appearance of the Badge component by overriding its global CSS variables. These variables are declared on the `:root` pseudo-class and can be changed on any appropriate parent element to affect its child badges.
49
+
50
+ | Variable name | Default Value | Description |
51
+ | ------------- | ------------- | ----------- |
52
+ | --md-sys-badge-small-size | 6px | The height and width of the small badge |
53
+ | --md-sys-badge-large-size | 16px | The height and minimum width of the large badge |
54
+ | --md-sys-badge-large-padding | 4px | The horizontal padding used for the large badge |
55
+
56
+ **Example: Changing the size of the small badge**
57
+
58
+ ```HTML
59
+ <div style="--md-sys-badge-small-size:8px">
60
+ <span class="micl-badge-small"></span>
61
+ </div>
62
+ ```
63
+
64
+ ## Compatibility
65
+ This component uses **anchor positioning**, a modern CSS feature that may not be fully supported in all browsers. Please check [Browser compatibility](https://developer.mozilla.org/en-US/docs/Web/CSS/anchor#browser_compatibility) for details.
@@ -0,0 +1,68 @@
1
+ //
2
+ // Copyright © 2025 Hermana AS
3
+ //
4
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ // of this software and associated documentation files (the "Software"), to deal
6
+ // in the Software without restriction, including without limitation the rights
7
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ // copies of the Software, and to permit persons to whom the Software is
9
+ // furnished to do so, subject to the following conditions:
10
+ //
11
+ // The above copyright notice and this permission notice shall be included in all
12
+ // copies or substantial portions of the Software.
13
+ //
14
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ // SOFTWARE.
21
+
22
+ @use '../../styles/typography';
23
+
24
+ :root {
25
+ --md-sys-badge-small-size: 6px;
26
+ --md-sys-badge-large-size: 16px;
27
+ --md-sys-badge-large-padding: 4px;
28
+ }
29
+
30
+ .micl-badge-small {
31
+ --md-sys-badge-inline-offset: 0px;
32
+ --md-sys-badge-block-offset: 0px;
33
+
34
+ box-sizing: border-box;
35
+ position: fixed;
36
+ inline-size: var(--md-sys-badge-small-size);
37
+ block-size: var(--md-sys-badge-small-size);
38
+ inset: unset;
39
+ inset-block-start: calc(anchor(start) + var(--md-sys-badge-block-offset));
40
+ inset-inline-start: calc(anchor(end) - var(--md-sys-badge-small-size) - var(--md-sys-badge-inline-offset));
41
+ border-radius: calc(var(--md-sys-badge-small-size) / 2);
42
+ margin: 0;
43
+ padding: 0;
44
+ background-color: var(--md-sys-color-error);
45
+ color: var(--md-sys-color-on-error);
46
+ }
47
+
48
+ .micl-badge-large {
49
+ --md-sys-badge-inline-offset: 0px;
50
+ --md-sys-badge-block-offset: 0px;
51
+
52
+ @include typography.label-small;
53
+
54
+ box-sizing: border-box;
55
+ position: fixed;
56
+ inline-size: fit-content;
57
+ max-inline-size: 34px;
58
+ min-inline-size: var(--md-sys-badge-large-size);
59
+ block-size: var(--md-sys-badge-large-size);
60
+ inset: unset;
61
+ inset-block-start: calc(anchor(start) - 2px + var(--md-sys-badge-block-offset));
62
+ inset-inline-start: calc(anchor(end) - 12px - var(--md-sys-badge-inline-offset));
63
+ margin: 0;
64
+ padding-inline: var(--md-sys-badge-large-padding);
65
+ border-radius: calc(var(--md-sys-badge-large-size) / 2);
66
+ background-color: var(--md-sys-color-error);
67
+ color: var(--md-sys-color-on-error);
68
+ }
@@ -18,7 +18,7 @@ Import the button styles into your project:
18
18
  ```
19
19
 
20
20
  ### JavaScript
21
- This component requires JavaScript for interactive features like the **ripple effect** and **toggle logic**:
21
+ This component requires JavaScript for interactive features like the **toggle logic**:
22
22
 
23
23
  ```JavaScript
24
24
  import micl from "material-inspired-component-library/dist/micl";
@@ -21,7 +21,6 @@
21
21
 
22
22
  @use '../../styles/elevation';
23
23
  @use '../../styles/motion';
24
- @use '../../styles/ripple';
25
24
  @use '../../styles/shapes';
26
25
  @use '../../styles/statelayer';
27
26
  @use '../../styles/typography';
@@ -54,11 +53,23 @@ button.micl-button-outlined-xl {
54
53
  --md-sys-button-motion-effects: #{motion.$md-sys-motion-expressive-fast-spatial};
55
54
  --md-sys-button-motion-duration: #{motion.$md-sys-motion-expressive-fast-spatial-duration};
56
55
  --md-sys-button-motion-duration-reverse: #{motion.$md-sys-motion-expressive-fast-spatial-duration};
56
+ --micl-ripple: 1;
57
57
 
58
+ position: relative;
59
+ display: inline-flex;
60
+ align-items: center;
58
61
  padding: 0;
59
62
  border: none;
63
+ background-image:
64
+ radial-gradient(circle at var(--micl-x, center) var(--micl-y, center), transparent 0%, rgb(from var(--statelayer-color) r g b / var(--statelayer-opacity)) 10%, transparent 10%),
65
+ linear-gradient(rgb(from var(--statelayer-color) r g b / var(--statelayer-opacity)));
66
+ background-repeat: no-repeat;
67
+ background-size: 10000%, 100%;
60
68
  cursor: pointer;
61
- transition: border-radius var(--md-sys-button-motion-duration) var(--md-sys-button-motion-effects);
69
+ transition:
70
+ border-radius var(--md-sys-button-motion-duration) var(--md-sys-button-motion-effects),
71
+ background-size 3000ms,
72
+ --statelayer-opacity var(--md-sys-button-motion-duration) linear;
62
73
 
63
74
  &:disabled {
64
75
  background-color: rgb(from var(--md-sys-color-on-surface) r g b / 10%);
@@ -66,9 +77,15 @@ button.micl-button-outlined-xl {
66
77
  box-shadow: var(--md-sys-elevation-level0);
67
78
  cursor: default;
68
79
  }
69
- &:not(:disabled):focus-visible {
70
- outline: var(--md-sys-state-focus-indicator-thickness) solid var(--md-sys-color-secondary);
71
- outline-offset: 3px;
80
+ &:not(:disabled) {
81
+ &:focus-visible {
82
+ outline: var(--md-sys-state-focus-indicator-thickness) solid var(--md-sys-color-secondary);
83
+ outline-offset: 3px;
84
+ }
85
+ &:active {
86
+ background-size: 0%, 100%;
87
+ transition: background-size 0ms;
88
+ }
72
89
  }
73
90
  .micl-button__icon {
74
91
  font-variation-settings: 'FILL' 0;
@@ -83,6 +100,7 @@ button.micl-button-tonal-xs,
83
100
  button.micl-button-outlined-xs {
84
101
  @include typography.label-large;
85
102
 
103
+ column-gap: 8px;
86
104
  min-width: var(--md-sys-target-size);
87
105
  height: var(--md-sys-target-size);
88
106
  padding-inline: 12px;
@@ -105,9 +123,6 @@ button.micl-button-outlined-xs {
105
123
  }
106
124
  }
107
125
  &:not(:disabled) {
108
- --miclripple: 1;
109
- @include ripple.effect;
110
-
111
126
  &:active {
112
127
  &.micl-button-elevated-xs {
113
128
  border-radius: var(--md-sys-shape-corner-small);
@@ -123,8 +138,6 @@ button.micl-button-outlined-xs {
123
138
  .micl-button__icon {
124
139
  font-size: 20px;
125
140
  width: 20px;
126
- margin-right: 8px;
127
- vertical-align: text-bottom;
128
141
  }
129
142
  }
130
143
 
@@ -135,6 +148,7 @@ button.micl-button-tonal-s,
135
148
  button.micl-button-outlined-s {
136
149
  @include typography.label-large;
137
150
 
151
+ column-gap: 8px;
138
152
  min-width: var(--md-sys-target-size);
139
153
  height: var(--md-sys-target-size);
140
154
  padding-inline: 16px;
@@ -157,9 +171,6 @@ button.micl-button-outlined-s {
157
171
  }
158
172
  }
159
173
  &:not(:disabled) {
160
- --miclripple: 1;
161
- @include ripple.effect;
162
-
163
174
  &:active:not(:disabled) {
164
175
  &.micl-button-elevated-s {
165
176
  border-radius: var(--md-sys-shape-corner-small);
@@ -175,8 +186,6 @@ button.micl-button-outlined-s {
175
186
  .micl-button__icon {
176
187
  font-size: 20px;
177
188
  width: 20px;
178
- margin-right: 8px;
179
- vertical-align: text-bottom;
180
189
  }
181
190
  }
182
191
 
@@ -187,6 +196,7 @@ button.micl-button-tonal-m,
187
196
  button.micl-button-outlined-m {
188
197
  @include typography.title-medium;
189
198
 
199
+ column-gap: 8px;
190
200
  min-width: 56px;
191
201
  height: 56px;
192
202
  padding-inline: 24px;
@@ -203,9 +213,6 @@ button.micl-button-outlined-m {
203
213
  }
204
214
  }
205
215
  &:not(:disabled) {
206
- --miclripple: 1;
207
- @include ripple.effect;
208
-
209
216
  &:active:not(:disabled) {
210
217
  border-radius: var(--md-sys-shape-corner-medium);
211
218
  }
@@ -213,8 +220,6 @@ button.micl-button-outlined-m {
213
220
  .micl-button__icon {
214
221
  font-size: 24px;
215
222
  width: 24px;
216
- margin-right: 8px;
217
- vertical-align: text-bottom;
218
223
  }
219
224
  }
220
225
 
@@ -225,6 +230,7 @@ button.micl-button-tonal-l,
225
230
  button.micl-button-outlined-l {
226
231
  @include typography.headline-small;
227
232
 
233
+ column-gap: 12px;
228
234
  min-width: 96px;
229
235
  height: 96px;
230
236
  padding-inline: 48px;
@@ -241,9 +247,6 @@ button.micl-button-outlined-l {
241
247
  }
242
248
  }
243
249
  &:not(:disabled) {
244
- --miclripple: 1;
245
- @include ripple.effect;
246
-
247
250
  &:active:not(:disabled) {
248
251
  border-radius: var(--md-sys-shape-corner-large);
249
252
  }
@@ -251,8 +254,6 @@ button.micl-button-outlined-l {
251
254
  .micl-button__icon {
252
255
  font-size: 32px;
253
256
  width: 32px;
254
- margin-right: 12px;
255
- vertical-align: text-bottom;
256
257
  }
257
258
  }
258
259
 
@@ -263,6 +264,7 @@ button.micl-button-tonal-xl,
263
264
  button.micl-button-outlined-xl {
264
265
  @include typography.headline-large;
265
266
 
267
+ column-gap: 16px;
266
268
  min-width: 136px;
267
269
  height: 136px;
268
270
  padding-inline: 64px;
@@ -279,9 +281,6 @@ button.micl-button-outlined-xl {
279
281
  }
280
282
  }
281
283
  &:not(:disabled) {
282
- --miclripple: 1;
283
- @include ripple.effect;
284
-
285
284
  &:active:not(:disabled) {
286
285
  border-radius: var(--md-sys-shape-corner-large);
287
286
  }
@@ -289,8 +288,6 @@ button.micl-button-outlined-xl {
289
288
  .micl-button__icon {
290
289
  font-size: 40px;
291
290
  width: 40px;
292
- margin-right: 16px;
293
- vertical-align: text-bottom;
294
291
  }
295
292
  }
296
293
 
@@ -299,22 +296,24 @@ button.micl-button-text-s,
299
296
  button.micl-button-text-m,
300
297
  button.micl-button-text-l,
301
298
  button.micl-button-text-xl {
299
+ --statelayer-color: var(--md-sys-color-primary);
300
+
302
301
  background-color: transparent;
303
302
  color: var(--md-sys-color-primary);
304
303
 
305
304
  &:not(:disabled) {
306
305
  &:hover {
307
- background-color: rgb(from var(--md-sys-color-primary) r g b / var(--md-sys-state-hover-state-layer-opacity));
306
+ --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity);
308
307
 
309
308
  .micl-button__icon {
310
309
  font-variation-settings: 'FILL' 1;
311
310
  }
312
311
  }
313
312
  &:focus-visible {
314
- background-color: rgb(from var(--md-sys-color-primary) r g b / var(--md-sys-state-focus-state-layer-opacity));
313
+ --statelayer-opacity: var(--md-sys-state-focus-state-layer-opacity);
315
314
  }
316
315
  &:active {
317
- background-color: rgb(from var(--md-sys-color-primary) r g b / var(--md-sys-state-pressed-state-layer-opacity));
316
+ --statelayer-opacity: var(--md-sys-state-pressed-state-layer-opacity);
318
317
  }
319
318
  }
320
319
  }
@@ -324,12 +323,16 @@ button.micl-button-elevated-s,
324
323
  button.micl-button-elevated-m,
325
324
  button.micl-button-elevated-l,
326
325
  button.micl-button-elevated-xl {
326
+ --statelayer-color: var(--md-sys-color-primary);
327
+
327
328
  background-color: var(--md-sys-color-surface-container-low);
328
329
  color: var(--md-sys-color-primary);
329
330
  box-shadow: var(--md-sys-elevation-level1);
330
331
 
331
332
  &:not(:disabled) {
332
333
  &.micl-button--toggle.micl-button--selected {
334
+ --statelayer-color: var(--md-sys-color-on-primary);
335
+
333
336
  background-color: var(--md-sys-color-primary);
334
337
  color: var(--md-sys-color-on-primary);
335
338
 
@@ -338,28 +341,17 @@ button.micl-button-elevated-xl {
338
341
  }
339
342
  }
340
343
  &:hover {
341
- background-color: color-mix(in srgb, var(--md-sys-color-surface-container-low), var(--md-sys-color-primary), var(--md-sys-state-hover-state-layer-opacity));
344
+ --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity);
342
345
 
343
- &.micl-button--toggle.micl-button--selected {
344
- background-color: color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) var(--md-sys-state-hover-state-layer-opacity));
345
- }
346
346
  .micl-button__icon {
347
347
  font-variation-settings: 'FILL' 1;
348
348
  }
349
349
  }
350
350
  &:focus-visible {
351
- background-color: color-mix(in srgb, var(--md-sys-color-surface-container-low), var(--md-sys-color-primary), var(--md-sys-state-focus-state-layer-opacity));
352
-
353
- &.micl-button--toggle.micl-button--selected {
354
- background-color: color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) var(--md-sys-state-focus-state-layer-opacity));
355
- }
351
+ --statelayer-opacity: var(--md-sys-state-focus-state-layer-opacity);
356
352
  }
357
353
  &:active {
358
- background-color: color-mix(in srgb, var(--md-sys-color-surface-container-low), var(--md-sys-color-primary), var(--md-sys-state-pressed-state-layer-opacity));
359
-
360
- &.micl-button--toggle.micl-button--selected {
361
- background-color: color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) var(--md-sys-state-pressed-state-layer-opacity));
362
- }
354
+ --statelayer-opacity: var(--md-sys-state-pressed-state-layer-opacity);
363
355
  }
364
356
  }
365
357
  }
@@ -377,6 +369,8 @@ button.micl-button-filled-s,
377
369
  button.micl-button-filled-m,
378
370
  button.micl-button-filled-l,
379
371
  button.micl-button-filled-xl {
372
+ --statelayer-color: var(--md-sys-color-on-primary);
373
+
380
374
  background-color: var(--md-sys-color-primary);
381
375
  color: var(--md-sys-color-on-primary);
382
376
 
@@ -387,32 +381,23 @@ button.micl-button-filled-xl {
387
381
  }
388
382
  }
389
383
  &.micl-button--toggle:not(.micl-button--selected) {
384
+ --statelayer-color: var(--md-sys-color-on-surface-variant);
385
+
390
386
  background-color: var(--md-sys-color-surface-container);
391
387
  color: var(--md-sys-color-on-surface-variant);
392
388
  }
393
389
  &:hover {
394
- background-color: color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) var(--md-sys-state-hover-state-layer-opacity));
390
+ --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity);
395
391
 
396
- &.micl-button--toggle:not(.micl-button--selected) {
397
- background-color: color-mix(in srgb, var(--md-sys-color-surface-container), var(--md-sys-color-on-surface-variant) var(--md-sys-state-hover-state-layer-opacity));
398
- }
399
392
  .micl-button__icon {
400
393
  font-variation-settings: 'FILL' 1;
401
394
  }
402
395
  }
403
396
  &:focus-visible {
404
- background-color: color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) var(--md-sys-state-focus-state-layer-opacity));
405
-
406
- &.micl-button--toggle:not(.micl-button--selected) {
407
- background-color: color-mix(in srgb, var(--md-sys-color-surface-container), var(--md-sys-color-on-surface-variant) var(--md-sys-state-focus-state-layer-opacity));
408
- }
397
+ --statelayer-opacity: var(--md-sys-state-focus-state-layer-opacity);
409
398
  }
410
399
  &:active {
411
- background-color: color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) var(--md-sys-state-pressed-state-layer-opacity));
412
-
413
- &.micl-button--toggle:not(.micl-button--selected) {
414
- background-color: color-mix(in srgb, var(--md-sys-color-surface-container), var(--md-sys-color-on-surface-variant) var(--md-sys-state-pressed-state-layer-opacity));
415
- }
400
+ --statelayer-opacity: var(--md-sys-state-pressed-state-layer-opacity);
416
401
  }
417
402
  }
418
403
  }
@@ -422,11 +407,15 @@ button.micl-button-tonal-s,
422
407
  button.micl-button-tonal-m,
423
408
  button.micl-button-tonal-l,
424
409
  button.micl-button-tonal-xl {
410
+ --statelayer-color: var(--md-sys-color-on-secondary-container);
411
+
425
412
  background-color: var(--md-sys-color-secondary-container);
426
413
  color: var(--md-sys-color-on-secondary-container);
427
414
 
428
415
  &:not(:disabled) {
429
416
  &.micl-button--toggle.micl-button--selected {
417
+ --statelayer-color: var(--md-sys-color-on-secondary);
418
+
430
419
  background-color: var(--md-sys-color-secondary);
431
420
  color: var(--md-sys-color-on-secondary);
432
421
 
@@ -435,28 +424,17 @@ button.micl-button-tonal-xl {
435
424
  }
436
425
  }
437
426
  &:hover {
438
- background-color: color-mix(in srgb, var(--md-sys-color-secondary-container), var(--md-sys-color-on-secondary-container) var(--md-sys-state-hover-state-layer-opacity));
427
+ --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity);
439
428
 
440
- &.micl-button--toggle.micl-button--selected {
441
- background-color: color-mix(in srgb, var(--md-sys-color-secondary), var(--md-sys-color-on-secondary) var(--md-sys-state-hover-state-layer-opacity));
442
- }
443
429
  .micl-button__icon {
444
430
  font-variation-settings: 'FILL' 1;
445
431
  }
446
432
  }
447
433
  &:focus-visible {
448
- background-color: color-mix(in srgb, var(--md-sys-color-secondary-container), var(--md-sys-color-on-secondary-container) var(--md-sys-state-focus-state-layer-opacity));
449
-
450
- &.micl-button--toggle.micl-button--selected {
451
- background-color: color-mix(in srgb, var(--md-sys-color-secondary), var(--md-sys-color-on-secondary) var(--md-sys-state-focus-state-layer-opacity));
452
- }
434
+ --statelayer-opacity: var(--md-sys-state-focus-state-layer-opacity);
453
435
  }
454
436
  &:active {
455
- background-color: color-mix(in srgb, var(--md-sys-color-secondary-container), var(--md-sys-color-on-secondary-container) var(--md-sys-state-pressed-state-layer-opacity));
456
-
457
- &.micl-button--toggle.micl-button--selected {
458
- background-color: color-mix(in srgb, var(--md-sys-color-secondary), var(--md-sys-color-on-secondary) var(--md-sys-state-pressed-state-layer-opacity));
459
- }
437
+ --statelayer-opacity: var(--md-sys-state-pressed-state-layer-opacity);
460
438
  }
461
439
  }
462
440
  }
@@ -466,11 +444,15 @@ button.micl-button-outlined-s,
466
444
  button.micl-button-outlined-m,
467
445
  button.micl-button-outlined-l,
468
446
  button.micl-button-outlined-xl {
447
+ --statelayer-color: var(--md-sys-color-on-surface-variant);
448
+
469
449
  background-color: transparent;
470
450
  color: var(--md-sys-color-on-surface-variant);
471
451
 
472
452
  &:not(:disabled) {
473
453
  &.micl-button--toggle.micl-button--selected {
454
+ --statelayer-color: var(--md-sys-color-inverse-on-surface);
455
+
474
456
  background-color: var(--md-sys-color-inverse-surface);
475
457
  color: var(--md-sys-color-inverse-on-surface);
476
458
 
@@ -479,28 +461,17 @@ button.micl-button-outlined-xl {
479
461
  }
480
462
  }
481
463
  &:hover {
482
- background-color: rgb(from var(--md-sys-color-on-surface-variant) r g b / var(--md-sys-state-hover-state-layer-opacity));
464
+ --statelayer-opacity: var(--md-sys-state-hover-state-layer-opacity);
483
465
 
484
- &.micl-button--toggle.micl-button--selected {
485
- background-color: color-mix(in srgb, var(--md-sys-color-inverse-surface), var(--md-sys-color-inverse-on-surface) var(--md-sys-state-hover-state-layer-opacity));
486
- }
487
466
  .micl-button__icon {
488
467
  font-variation-settings: 'FILL' 1;
489
468
  }
490
469
  }
491
470
  &:focus-visible {
492
- background-color: rgb(from var(--md-sys-color-on-surface-variant) r g b / var(--md-sys-state-focus-state-layer-opacity));
493
-
494
- &.micl-button--toggle.micl-button--selected {
495
- background-color: color-mix(in srgb, var(--md-sys-color-inverse-surface), var(--md-sys-color-inverse-on-surface) var(--md-sys-state-focus-state-layer-opacity));
496
- }
471
+ --statelayer-opacity: var(--md-sys-state-focus-state-layer-opacity);
497
472
  }
498
473
  &:active {
499
- background-color: rgb(from var(--md-sys-color-on-surface-variant) r g b / var(--md-sys-state-pressed-state-layer-opacity));
500
-
501
- &.micl-button--toggle.micl-button--selected {
502
- background-color: color-mix(in srgb, var(--md-sys-color-inverse-surface), var(--md-sys-color-inverse-on-surface) var(--md-sys-state-pressed-state-layer-opacity));
503
- }
474
+ --statelayer-opacity: var(--md-sys-state-pressed-state-layer-opacity);
504
475
  }
505
476
  }
506
477
  }
@@ -37,7 +37,12 @@ export default (() =>
37
37
  }
38
38
  }
39
39
  if (event.target.classList.contains('micl-button--toggle')) {
40
+ event.target.classList.add('micl-button--toggled');
40
41
  event.target.classList.toggle('micl-button--selected');
42
+ if (!!event.target.dataset.miclalt) {
43
+ [event.target.textContent, event.target.dataset.miclalt] =
44
+ [event.target.dataset.miclalt, event.target.textContent];
45
+ }
41
46
  }
42
47
  };
43
48