material-inspired-component-library 1.1.1 → 1.2.1

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.
package/README.md CHANGED
@@ -100,3 +100,7 @@ The library currently consists of the following components:
100
100
  ### 1.1.0 (12.08.2025)
101
101
  **Features**
102
102
  - **Text field**: Added support for multi-line text fields.
103
+
104
+ ### 1.2.0 (17.08.2025)
105
+ **Features**
106
+ - **List**: Added support for switches inside list items.
@@ -59,6 +59,20 @@ The List component offers three CSS classes to control the height and content ca
59
59
  </ul>
60
60
  ```
61
61
 
62
+ Use the anchor element to convert a list item into a hyperlink:
63
+
64
+ ```HTML
65
+ <ul class="micl-list" role="listbox">
66
+ <li class="micl-list-item-one" tabindex="0">
67
+ <a href="https://www.thetimes.com" tabindex="-1">
68
+ <span class="micl-list-item__text">
69
+ <span class="micl-list-item__headline">The Times</span>
70
+ </span>
71
+ </a>
72
+ </li>
73
+ </ul>
74
+ ```
75
+
62
76
  Adding the `micl-list-item--disabled` class to the `<li>` element causes the list item to be displayed in a disabled state.
63
77
 
64
78
  Add the `micl-list__divider` class to the `<ul>` element to automatically place a divider between each list item.
@@ -77,10 +91,10 @@ The text content of a list item can be preceded by various media elements:
77
91
  </li>
78
92
  ```
79
93
 
80
- - **Avatar**: Use `micl-list-item__avatar` with an avatar image (or icon).
94
+ - **Avatar**: Use `micl-list-item__avatar` with a text.
81
95
  ```HTML
82
96
  <li class="micl-list-item-two" tabindex="0">
83
- <span class="material-symbols-outlined micl-list-item__avatar">account_circle</span>
97
+ <span class="micl-list-item__avatar">BJ</span>
84
98
  <span class="micl-list-item__text">
85
99
  <span class="micl-list-item__headline">Bill Jones</span>
86
100
  <span class="micl-list-item__supporting-text">bill.jones@email.com</span>
@@ -111,35 +125,51 @@ The text content of a list item can be preceded by various media elements:
111
125
  ```
112
126
 
113
127
  ### Trailing Content
114
- The text of a list item may be followed by a trailing text or other elements (like a checkbox).
128
+ The text of a list item may be followed by a trailing text, imagery or other elements (like a checkbox).
115
129
 
116
- ```HTML
117
- <li class="micl-list-item-one" tabindex="0">
118
- <span class="micl-list-item__text">
119
- <span class="micl-list-item__headline">To-do items</span>
120
- </span>
121
- <span class="micl-list-item__trailing-text">100+</span>
122
- </li>
123
- ````
130
+ - **Icon**: Use `micl-list-item__icon` with a (Material Symbols) icon.
131
+ ```HTML
132
+ <li class="micl-list-item-two" tabindex="0">
133
+ <span class="micl-list-item__text">
134
+ <span class="micl-list-item__headline">Date and time</span>
135
+ <span class="micl-list-item__supporting-text">Timezones, calendar display</span>
136
+ </span>
137
+ <span class="material-symbols-outlined micl-list-item__icon" aria-hidden="true">more_horiz</span>
138
+ </li>
139
+ ```
140
+
141
+ - **Text**: Use `micl-list-item__trailing-text` with a short text.
142
+ ```HTML
143
+ <li class="micl-list-item-one" tabindex="0">
144
+ <span class="micl-list-item__text">
145
+ <span class="micl-list-item__headline">To-do items</span>
146
+ </span>
147
+ <span class="micl-list-item__trailing-text">100+</span>
148
+ </li>
149
+ ````
124
150
 
125
151
  ### Selecting List Items
126
- To enable selection of list items, integrate a checkbox component within the `<li>` element. The `micl-list-item__text` should typically wrap the headline and supporting text, acting as the label for the checkbox.
152
+ To enable selection of list items, integrate a checkbox or switch component within the `<li>` element.
127
153
 
128
154
  ```HTML
129
155
  <ul class="micl-list micl-list__divider" role="listbox">
130
156
  <li class="micl-list-item-two" tabindex="0">
131
- <label for="checkbox1" class="micl-list-item__text">
132
- <span class="micl-list-item__headline">Blue car</span>
133
- <span class="micl-list-item__supporting-text">A blue car with four wheels.</span>
134
- </label>
135
- <input type="checkbox" id="checkbox1" class="micl-checkbox" value="cb1" tabindex="-1">
157
+ <label>
158
+ <span class="micl-list-item__text">
159
+ <span class="micl-list-item__headline">Blue car</span>
160
+ <span class="micl-list-item__supporting-text">A blue car with four wheels.</span>
161
+ </label>
162
+ <input type="checkbox" id="mycheckbox" class="micl-checkbox" value="cb1" tabindex="-1">
163
+ </span>
136
164
  </li>
137
165
  <li class="micl-list-item-two" tabindex="0">
138
- <label for="checkbox2" class="micl-list-item__text">
139
- <span class="micl-list-item__headline">Red car</span>
140
- <span class="micl-list-item__supporting-text">A red car with tinted windows.</span>
166
+ <label>
167
+ <span class="micl-list-item__text">
168
+ <span class="micl-list-item__headline">Red car</span>
169
+ <span class="micl-list-item__supporting-text">A red car with tinted windows.</span>
170
+ </label>
171
+ <input type="checkbox" id="checkbox2" class="micl-switch" value="cb2" tabindex="-1">
141
172
  </label>
142
- <input type="checkbox" id="checkbox2" class="micl-checkbox" value="cb2" tabindex="-1">
143
173
  </li>
144
174
  </ul>
145
175
  ```
@@ -37,10 +37,10 @@
37
37
  }
38
38
 
39
39
  .micl-list {
40
- --md-sys-list-item-background-color: var(--md-sys-color-surface);
40
+ --md-sys-list-item-container-color: var(--md-sys-color-surface);
41
41
 
42
42
  margin: 0;
43
- padding: 0;
43
+ padding: 8px 0;
44
44
  interpolate-size: allow-keywords;
45
45
  list-style-type: none;
46
46
 
@@ -68,8 +68,8 @@
68
68
  pointer-events: none;
69
69
  }
70
70
  &:not(.micl-list-item--disabled) {
71
- --miclripple: 1;
72
71
  @include ripple.effect;
72
+ --miclripple: 1;
73
73
 
74
74
  cursor: pointer;
75
75
  }
@@ -77,7 +77,7 @@
77
77
  .micl-list-item__content {
78
78
  box-sizing: border-box;
79
79
  padding-inline: var(--md-sys-list-item-padding-inline);
80
- background-color: var(--md-sys-list-item-background-color);
80
+ background-color: var(--md-sys-list-item-container-color);
81
81
  overflow: hidden;
82
82
  }
83
83
  }
@@ -95,16 +95,33 @@
95
95
  .micl-list-item-one,
96
96
  .micl-list-item-two,
97
97
  .micl-list-item-three {
98
+ --md-sys-list-item-thumbnail-aspect-ratio: 1.778;
99
+
98
100
  box-sizing: border-box;
99
101
  display: flex;
100
102
  align-items: center;
101
103
  column-gap: var(--md-sys-list-item-space);
102
104
  padding-inline: var(--md-sys-list-item-space);
103
105
  border-radius: var(--md-sys-shape-corner-none);
104
- background-color: var(--md-sys-list-item-background-color);
106
+ background-color: var(--md-sys-list-item-container-color);
105
107
  list-style: none;
106
108
  transition: background-color var(--md-sys-motion-duration-long2) linear;
107
109
 
110
+ &> a,
111
+ &> label {
112
+ display: inherit;
113
+ align-items: inherit;
114
+ column-gap: inherit;
115
+ border-radius: inherit;
116
+ background-color: inherit;
117
+ inline-size: 100%;
118
+ padding-inline: var(--md-sys-list-item-space);
119
+ text-decoration: none;
120
+ cursor: pointer;
121
+ }
122
+ &:has(> a,> label) {
123
+ padding-inline: 0;
124
+ }
108
125
  &:disabled,
109
126
  &.micl-list-item--disabled {
110
127
  .micl-list-item__icon,
@@ -119,12 +136,16 @@
119
136
  .micl-list-item__thumbnail {
120
137
  opacity: 38%;
121
138
  }
139
+ a, label {
140
+ pointer-events: none;
141
+ cursor: auto;
142
+ }
122
143
  }
123
144
  &:not(:disabled):not(.micl-list-item--disabled) {
124
145
  &:hover {
125
- background-color: color-mix(in srgb, var(--md-sys-list-item-background-color), var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity));
146
+ background-color: color-mix(in srgb, var(--md-sys-list-item-container-color), var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity));
126
147
 
127
- &:has(input[type=checkbox].micl-checkbox) {
148
+ &:has(input[type=checkbox]) {
128
149
  cursor: pointer;
129
150
  }
130
151
  .micl-list-item__icon {
@@ -133,26 +154,26 @@
133
154
  }
134
155
  &:focus-visible {
135
156
  outline: var(--md-sys-state-focus-indicator-thickness) solid var(--md-sys-color-secondary);
136
- background-color: color-mix(in srgb, var(--md-sys-list-item-background-color), var(--md-sys-color-on-surface) var(--md-sys-state-focus-state-layer-opacity));
137
- z-index: 1;
157
+ outline-offset: calc(-1 * var(--md-sys-state-focus-indicator-thickness));
158
+ background-color: color-mix(in srgb, var(--md-sys-list-item-container-color), var(--md-sys-color-on-surface) var(--md-sys-state-focus-state-layer-opacity));
138
159
 
139
160
  .micl-list-item__icon {
140
161
  font-variation-settings: 'FILL' 1;
141
162
  }
142
163
  }
143
164
  &:active {
144
- background-color: color-mix(in srgb, var(--md-sys-list-item-background-color), var(--md-sys-color-on-surface) var(--md-sys-state-pressed-state-layer-opacity));
165
+ background-color: color-mix(in srgb, var(--md-sys-list-item-container-color), var(--md-sys-color-on-surface) var(--md-sys-state-pressed-state-layer-opacity));
145
166
 
146
167
  .micl-list-item__icon {
147
168
  font-variation-settings: 'FILL' 1;
148
169
  }
149
170
  }
150
- &:has(input[type=checkbox].micl-checkbox) {
171
+ &:has(input[type=checkbox]) {
172
+ @include ripple.effect;
151
173
  --miclripple: 1;
152
174
  --md-sys-ripple-background-color: var(--md-sys-color-primary);
153
- @include ripple.effect;
154
175
  }
155
- &:has(input[type=checkbox].micl-checkbox:checked) {
176
+ &:has(input[type=checkbox]:checked) {
156
177
  background-color: var(--md-sys-color-secondary-container);
157
178
 
158
179
  .micl-list-item__headline {
@@ -163,45 +184,70 @@
163
184
  .micl-list-item__trailing-text {
164
185
  color: var(--md-sys-color-on-surface);
165
186
  }
187
+ &:focus-visible {
188
+ background-color: color-mix(in srgb, var(--md-sys-color-secondary-container), var(--md-sys-color-on-surface) var(--md-sys-state-focus-state-layer-opacity));
189
+ }
190
+ &:active {
191
+ background-color: color-mix(in srgb, var(--md-sys-color-secondary-container), var(--md-sys-color-on-surface) var(--md-sys-state-pressed-state-layer-opacity));
192
+ }
166
193
  }
167
- input[type=checkbox].micl-checkbox:not(:disabled):hover,
168
- input[type=checkbox].micl-checkbox:not(:disabled):active {
194
+ input[type=checkbox]:not(:disabled):hover,
195
+ input[type=checkbox]:not(:disabled):active {
169
196
  --checkbox-state-layer-color: initial;
170
197
  --checkbox-outline-color: initial;
171
198
  --md-sys-ripple-background-color: transparent;
172
199
  }
173
200
  }
174
- &> a {
175
- box-sizing: border-box;
176
- display: flex;
177
- align-items: center;
178
- align-self: normal;
179
- width: 100%;
180
- column-gap: var(--md-sys-list-item-space);
181
- text-decoration: none;
182
- }
183
201
  }
184
202
 
185
203
  .micl-list-item-one {
186
204
  min-height: var(--md-sys-list-item-one-height);
187
- padding-block-start: var(--md-sys-list-item-one-padding);
188
- padding-block-end: var(--md-sys-list-item-one-padding);
189
205
 
190
- &:has(.micl-list-item__thumbnail) {
191
- padding-block-start: var(--md-sys-list-item-three-padding);
192
- padding-block-end: var(--md-sys-list-item-three-padding);
193
- padding-inline-start: 0px;
206
+ &:not(:has(> a,> label)) {
207
+ padding-block-start: var(--md-sys-list-item-one-padding);
208
+ padding-block-end: var(--md-sys-list-item-one-padding);
209
+
210
+ &:has(.micl-list-item__thumbnail) {
211
+ padding-block-start: var(--md-sys-list-item-three-padding);
212
+ padding-block-end: var(--md-sys-list-item-three-padding);
213
+ padding-inline-start: 0px;
214
+ }
215
+ }
216
+ &> a,
217
+ &> label {
218
+ padding-block-start: var(--md-sys-list-item-one-padding);
219
+ padding-block-end: var(--md-sys-list-item-one-padding);
220
+
221
+ &:has(.micl-list-item__thumbnail) {
222
+ padding-block-start: var(--md-sys-list-item-three-padding);
223
+ padding-block-end: var(--md-sys-list-item-three-padding);
224
+ padding-inline-start: 0px;
225
+ }
194
226
  }
195
227
  }
196
228
  .micl-list-item-two {
197
229
  min-height: var(--md-sys-list-item-two-height);
198
- padding-block-start: var(--md-sys-list-item-two-padding);
199
- padding-block-end: var(--md-sys-list-item-two-padding);
200
230
 
201
- &:has(.micl-list-item__thumbnail) {
202
- padding-inline-start: 0px;
203
- padding-block-start: 12px;
204
- padding-block-end: 12px;
231
+ &:not(:has(> a, > label)) {
232
+ padding-block-start: var(--md-sys-list-item-two-padding);
233
+ padding-block-end: var(--md-sys-list-item-two-padding);
234
+
235
+ &:has(.micl-list-item__thumbnail) {
236
+ padding-inline-start: 0px;
237
+ padding-block-start: 12px;
238
+ padding-block-end: 12px;
239
+ }
240
+ }
241
+ &> a,
242
+ &> label {
243
+ padding-block-start: var(--md-sys-list-item-two-padding);
244
+ padding-block-end: var(--md-sys-list-item-two-padding);
245
+
246
+ &:has(.micl-list-item__thumbnail) {
247
+ padding-inline-start: 0px;
248
+ padding-block-start: 12px;
249
+ padding-block-end: 12px;
250
+ }
205
251
  }
206
252
  .micl-list-item__supporting-text {
207
253
  white-space: nowrap;
@@ -211,13 +257,27 @@
211
257
  }
212
258
  .micl-list-item-three {
213
259
  min-height: var(--md-sys-list-item-three-height);
214
- padding-block-start: var(--md-sys-list-item-three-padding);
215
- padding-block-end: var(--md-sys-list-item-three-padding);
216
260
 
217
- &:has(.micl-list-item__thumbnail) {
261
+ &:not(:has(> a, > label)) {
262
+ padding-block-start: var(--md-sys-list-item-three-padding);
263
+ padding-block-end: var(--md-sys-list-item-three-padding);
264
+
265
+ &:has(.micl-list-item__thumbnail) {
266
+ padding-block-start: var(--md-sys-list-item-three-padding);
267
+ padding-block-end: var(--md-sys-list-item-three-padding);
268
+ padding-inline-start: 0px;
269
+ }
270
+ }
271
+ &> a,
272
+ &> label {
218
273
  padding-block-start: var(--md-sys-list-item-three-padding);
219
274
  padding-block-end: var(--md-sys-list-item-three-padding);
220
- padding-inline-start: 0px;
275
+
276
+ &:has(.micl-list-item__thumbnail) {
277
+ padding-block-start: var(--md-sys-list-item-three-padding);
278
+ padding-block-end: var(--md-sys-list-item-three-padding);
279
+ padding-inline-start: 0px;
280
+ }
221
281
  }
222
282
  .micl-list-item__icon,
223
283
  .micl-list-item__avatar,
@@ -230,7 +290,7 @@
230
290
  -webkit-box-orient: vertical;
231
291
  -webkit-line-clamp: 2;
232
292
  }
233
- input[type=checkbox].micl-checkbox {
293
+ input[type=checkbox] {
234
294
  align-self: flex-start;
235
295
  margin-block-start: -12px;
236
296
  }
@@ -238,37 +298,39 @@
238
298
 
239
299
  .micl-list-item__icon {
240
300
  color: var(--md-sys-color-on-surface-variant);
301
+ font-size: 24px;
241
302
  font-variation-settings: 'FILL' 0;
242
303
  transition: font-variation-settings var(--md-sys-motion-duration-long2) linear;
243
304
  }
244
305
  .micl-list-item__avatar {
245
- font-size: 40px;
246
- border-radius: var(--md-sys-shape-corner-full);
247
- color: var(--md-sys-color-primary-container);
248
- }
249
- .micl-list-item__avatar-text {
250
306
  @include typography.title-medium;
251
307
 
252
- color: var(--md-sys-on-primary-container);
308
+ display: flex;
309
+ align-items: center;
310
+ justify-content: center;
311
+ block-size: 40px;
312
+ min-inline-size: 40px;
313
+ border-radius: var(--md-sys-shape-corner-full);
314
+ color: var(--md-sys-color-on-primary-container);
315
+ background-color: var(--md-sys-color-primary-container);
253
316
  }
254
317
  .micl-list-item__image {
255
318
  display: inline-block;
256
- width: 56px;
257
319
  height: 56px;
258
320
  min-width: 56px;
259
- min-height: 56px;
260
321
  border-radius: var(--md-sys-shape-corner-none);
322
+ background-position: center;
323
+ background-repeat: no-repeat;
261
324
  background-size: cover;
262
325
  }
263
326
  .micl-list-item__thumbnail {
264
327
  display: inline-block;
265
- width: auto;
266
328
  height: 64px;
267
- min-height: 64px;
268
- aspect-ratio: 1.5;
329
+ min-width: calc(64px * var(--md-sys-list-item-thumbnail-aspect-ratio));
269
330
  border-radius: var(--md-sys-shape-corner-none);
270
- background-size: contain;
331
+ background-position: center;
271
332
  background-repeat: no-repeat;
333
+ background-size: contain;
272
334
  }
273
335
 
274
336
  .micl-list-item__text {
@@ -91,7 +91,7 @@ export default (() =>
91
91
  break;
92
92
  case 'Enter':
93
93
  case ' ':
94
- const cb = (event.target as Element).querySelector('input[type=checkbox].micl-checkbox');
94
+ const cb = (event.target as Element).querySelector('input[type=checkbox]');
95
95
  if (cb instanceof HTMLInputElement) {
96
96
  cb.checked = !cb.checked;
97
97
  }
@@ -33,13 +33,13 @@
33
33
  position-try-fallbacks: flip-block, flip-inline;
34
34
  min-width: 112px;
35
35
  max-width: 280px;
36
- padding-block: 8px;
37
36
  padding-inline: 0;
38
37
  border: none;
39
38
  border-radius: var(--md-sys-shape-corner-extra-small);
40
39
  background-color: var(--md-sys-color-surface-container);
41
40
  box-shadow: var(--md-sys-elevation-level2);
42
41
  opacity: 0;
42
+ overflow: hidden;
43
43
  transform: scaleY(0);
44
44
  transform-origin: top left;
45
45
  transition:
@@ -90,7 +90,7 @@
90
90
  --md-sys-list-item-one-padding: 0;
91
91
  --md-sys-list-item-two-padding: 0;
92
92
  --md-sys-list-item-space: 12px;
93
- --md-sys-list-item-background-color: var(--md-sys-color-surface-container);
93
+ --md-sys-list-item-container-color: var(--md-sys-color-surface-container);
94
94
 
95
95
  .micl-list-item-one,
96
96
  .micl-list-item-two,
@@ -63,7 +63,7 @@
63
63
  --md-sys-list-item-two-padding: 0;
64
64
  --md-sys-list-item-space: 12px;
65
65
  --md-sys-list-item-padding-inline: 16px;
66
- --md-sys-list-item-background-color: var(--md-sys-color-surface-container);
66
+ --md-sys-list-item-container-color: var(--md-sys-color-surface-container);
67
67
  --md-sys-motion-duration-long2: 500ms;
68
68
  --md-sys-state-hover-state-layer-opacity: #{statelayer.$md-sys-state-hover-state-layer-opacity};
69
69
  --md-sys-state-focus-state-layer-opacity: #{statelayer.$md-sys-state-focus-state-layer-opacity};
@@ -65,3 +65,11 @@ The Slider component is aware of the `dir` global attribute that indicates the d
65
65
 
66
66
  ## Compatibility
67
67
  This component uses the `color-mix` CSS functional notation, which might not be supported in your browser. Please check [Browser compatibility](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-mix#browser_compatibility) for details.
68
+
69
+ > [!NOTE]
70
+ > **Gecko browsers** The Slider component uses the `::after` pseudo-element to display the value indicator. For this to work on **Gecko** browsers, like Mozilla Firefox, wrap the Slider component inside a slider container:
71
+ ```HTML
72
+ <div class="micl-slider__container">
73
+ <input type="range" class="micl-slider-l" value="0">
74
+ </div>
75
+ ```