@rcarls/rc-theme-material 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +600 -0
  2. package/DESIGN.md +1399 -0
  3. package/README.md +138 -5
  4. package/bridge.css +150 -55
  5. package/components/accordion.css +43 -157
  6. package/components/adaptive-menu.css +123 -0
  7. package/components/app-bar.css +49 -7
  8. package/components/bottom-sheet.css +10 -7
  9. package/components/button.css +215 -2
  10. package/components/card.css +2 -0
  11. package/components/carousel.css +23 -0
  12. package/components/chip-group.css +15 -0
  13. package/components/chip.css +12 -1
  14. package/components/combobox.css +68 -14
  15. package/components/dialog.css +77 -15
  16. package/components/disclosure.css +128 -84
  17. package/components/field.css +566 -0
  18. package/components/icons.css +48 -6
  19. package/components/list-item.css +142 -32
  20. package/components/listbox.css +5 -4
  21. package/components/markdown-editor.css +62 -35
  22. package/components/menu-button.css +105 -1
  23. package/components/menu.css +32 -16
  24. package/components/menubar.css +4 -1
  25. package/components/modes.css +36 -17
  26. package/components/navigation-bar.css +3 -5
  27. package/components/navigation-rail.css +5 -7
  28. package/components/popover.css +50 -0
  29. package/components/progress.css +15 -0
  30. package/components/range-slider.css +8 -3
  31. package/components/scroller.css +7 -0
  32. package/components/search-bar.css +12 -2
  33. package/components/segmented-button.css +2 -28
  34. package/components/select.css +106 -14
  35. package/components/splitter.css +4 -1
  36. package/components/switch.css +9 -1
  37. package/components/textarea.css +13 -3
  38. package/components/toolbar.css +2 -1
  39. package/components/tooltip.css +12 -0
  40. package/components/transfer-list.css +5 -1
  41. package/components/virtual-canvas.css +4 -1
  42. package/components/virtual-scroller.css +7 -0
  43. package/components.css +11 -1
  44. package/constraints/material.json +99 -0
  45. package/css-components/button.css +66 -0
  46. package/css-components/card.css +14 -0
  47. package/css-components/chip-group.css +9 -0
  48. package/css-components/chip.css +80 -0
  49. package/css-components/disclosure.css +25 -0
  50. package/css-components/list.css +34 -0
  51. package/css-components/select.css +20 -0
  52. package/css-components/textarea.css +22 -0
  53. package/css-components.css +31 -0
  54. package/defaults.css +329 -14
  55. package/native.css +258 -0
  56. package/package.json +21 -2
  57. package/state-layer.css +5 -1
@@ -0,0 +1,566 @@
1
+ @layer rc-theme-material.components {
2
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field {
3
+ display: inline-block;
4
+ inline-size: min(100%, 28rem);
5
+ --_rc-field-input-line-height: max(var(--md-sys-typescale-body-large-line-height, 1.5rem), 1em);
6
+ --_rc-field-label-line-height: max(var(--md-sys-typescale-body-small-line-height, 1rem), 1em);
7
+ --rc-field-min-block-size: max(
8
+ 3.5em,
9
+ calc(var(--_rc-field-label-line-height) + var(--_rc-field-input-line-height))
10
+ );
11
+ --rc-field-gap: 0.75rem;
12
+ --rc-field-padding: 0 1rem;
13
+ --rc-field-border: 0;
14
+ --rc-field-radius: var(--md-filled-text-field-container-shape, 0.25rem 0.25rem 0 0);
15
+ --rc-field-background: var(
16
+ --md-filled-text-field-container-color,
17
+ var(--md-sys-color-surface-container-highest, Field)
18
+ );
19
+ --rc-field-color: var(
20
+ --md-filled-text-field-input-text-color,
21
+ var(--md-sys-color-on-surface, FieldText)
22
+ );
23
+ --rc-field-label-color: var(
24
+ --md-filled-text-field-label-text-color,
25
+ var(--md-sys-color-on-surface-variant, GrayText)
26
+ );
27
+ --rc-field-error-color: var(
28
+ --md-filled-text-field-error-focus-label-text-color,
29
+ var(--md-sys-color-error, red)
30
+ );
31
+ --rc-field-disabled-opacity: 1;
32
+ --rc-field-focus-outline: 0;
33
+ --rc-field-supporting-color: var(--md-sys-color-on-surface-variant, GrayText);
34
+ --rc-field-supporting-font-size: var(--md-sys-typescale-body-small-size, 0.75rem);
35
+ }
36
+
37
+ /*
38
+ * Filled fields reserve their block padding on the container instead of
39
+ * centering the label and control inside the minimum height, so the floated
40
+ * label stays 8px below the top edge however tall the control grows. The
41
+ * trailing padding gives back the 1px active indicator so a single-line
42
+ * field stays at the 56px minimum.
43
+ */
44
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field:not(.rc-field--outlined) {
45
+ --rc-field-padding: 0.5rem 1rem calc(0.5rem - 1px);
46
+ }
47
+
48
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field::part(field) {
49
+ position: relative;
50
+ align-items: stretch;
51
+ border-block-end: 1px solid
52
+ var(
53
+ --md-filled-text-field-active-indicator-color,
54
+ var(--md-sys-color-on-surface-variant, GrayText)
55
+ );
56
+ font-family: var(--md-sys-typescale-body-large-font, inherit);
57
+ font-size: var(--md-sys-typescale-body-large-size, 1rem);
58
+ line-height: var(--md-sys-typescale-body-large-line-height, 1.5rem);
59
+ }
60
+
61
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field::part(field)::after {
62
+ position: absolute;
63
+ inset-inline: 0;
64
+ inset-block-end: -1px;
65
+ block-size: 2px;
66
+ background: var(--md-sys-color-primary, Highlight);
67
+ content: '';
68
+ transform: scaleX(0);
69
+ transform-origin: center;
70
+ }
71
+
72
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field::part(content) {
73
+ position: relative;
74
+ justify-content: center;
75
+ }
76
+
77
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field::part(label) {
78
+ position: absolute;
79
+ z-index: 1;
80
+ inset-inline-start: 0;
81
+ inset-block-start: 50%;
82
+ max-inline-size: 100%;
83
+ overflow: hidden;
84
+ font-family: var(--md-sys-typescale-body-large-font, inherit);
85
+ font-size: var(--md-sys-typescale-body-large-size, 1rem);
86
+ line-height: var(--md-sys-typescale-body-large-line-height, 1.5rem);
87
+ text-overflow: ellipsis;
88
+ white-space: nowrap;
89
+ pointer-events: none;
90
+ transform: translateY(-50%);
91
+ transform-origin: left top;
92
+ }
93
+
94
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-focused]::part(label),
95
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-populated]::part(label),
96
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-multiline]::part(label) {
97
+ inset-block-start: 0;
98
+ font-family: var(--md-sys-typescale-body-small-font, inherit);
99
+ font-size: var(--md-sys-typescale-body-small-size, 0.75rem);
100
+ line-height: var(--md-sys-typescale-body-small-line-height, 1rem);
101
+ transform: translateY(0);
102
+ }
103
+
104
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-has-label]::part(control) {
105
+ min-block-size: var(--_rc-field-input-line-height);
106
+ padding-block-start: var(--_rc-field-label-line-height);
107
+ }
108
+
109
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field::part(control) {
110
+ min-block-size: var(--_rc-field-input-line-height);
111
+ }
112
+
113
+ :where(.rc-theme-material, :host(.rc-theme-material))
114
+ rc-field.rc-field--outlined[data-multiline]::part(content) {
115
+ padding-block: 0.5rem;
116
+ }
117
+
118
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-multiline]::part(control) {
119
+ align-items: flex-start;
120
+ }
121
+
122
+ :where(.rc-theme-material, :host(.rc-theme-material))
123
+ rc-field[data-multiline][data-has-label]::part(control) {
124
+ padding-block-start: var(--_rc-field-label-line-height);
125
+ }
126
+
127
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field > input,
128
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field > textarea {
129
+ caret-color: var(--md-sys-color-primary, Highlight);
130
+ }
131
+
132
+ :where(.rc-theme-material, :host(.rc-theme-material))
133
+ rc-field
134
+ > rc-textarea[data-rc-field-control] {
135
+ --rc-textarea-border: 0;
136
+ --rc-textarea-border-radius: 0;
137
+ --rc-textarea-background: transparent;
138
+ --rc-textarea-gutter-bg: transparent;
139
+ --rc-textarea-focus-outline: 0;
140
+ inline-size: 100%;
141
+ }
142
+
143
+ /* Text starts on the input line under the floated label, as a native textarea. */
144
+ :where(.rc-theme-material, :host(.rc-theme-material))
145
+ rc-field:not(.rc-field--outlined)
146
+ > rc-textarea[data-rc-field-control] {
147
+ --rc-textarea-padding-block: 0 0.5rem;
148
+ --rc-textarea-padding-inline: 1rem;
149
+ }
150
+
151
+ :where(.rc-theme-material, :host(.rc-theme-material))
152
+ rc-field
153
+ > rc-select[data-rc-field-control] {
154
+ --rc-select-control-block-size: var(--md-sys-typescale-body-large-line-height, 1.5rem);
155
+ --rc-select-border: 0;
156
+ --rc-select-radius: 0;
157
+ --rc-select-padding-block: 0;
158
+ --rc-chip-touch-target-overlap-block-start: 0.5rem;
159
+ --rc-chip-touch-target-overlap-block-end: 0.5rem;
160
+ --rc-field: transparent;
161
+ inline-size: 100%;
162
+ }
163
+
164
+ /*
165
+ * rc-field resets the slotted native control's outline, but a ::slotted()
166
+ * rule loses to any page rule, such as a reset's Firefox :-moz-focusring
167
+ * outline. The field already shows focus, so clear the control's own
168
+ * outline from the light DOM too.
169
+ */
170
+ :where(.rc-theme-material, :host(.rc-theme-material))
171
+ rc-field
172
+ > :is(input, select, textarea):focus-visible {
173
+ outline: none;
174
+ }
175
+
176
+ /*
177
+ * rc-select's own hover/focus-visible/open chrome is hardcoded border-color and
178
+ * box-shadow, not resettable custom properties like the resting border above, so a
179
+ * more specific selector is the only way to suppress it once rc-field's own #field
180
+ * surface owns that visual instead.
181
+ */
182
+ :where(.rc-theme-material, :host(.rc-theme-material))
183
+ rc-field
184
+ > rc-select[data-rc-field-control]::part(trigger):hover,
185
+ :where(.rc-theme-material, :host(.rc-theme-material))
186
+ rc-field
187
+ > rc-select[data-rc-field-control]::part(trigger):focus-visible,
188
+ :where(.rc-theme-material, :host(.rc-theme-material))
189
+ rc-field
190
+ > rc-select[data-rc-field-control]::part(trigger)[aria-expanded='true'] {
191
+ border-color: transparent;
192
+ background: transparent;
193
+ box-shadow: none;
194
+ /* rc-field's label and active indicator already show focus. */
195
+ outline: none;
196
+ }
197
+
198
+ :where(.rc-theme-material, :host(.rc-theme-material))
199
+ rc-field
200
+ > rc-combobox[data-rc-field-control] {
201
+ --rc-combobox-control-block-size: var(--md-sys-typescale-body-large-line-height, 1.5rem);
202
+ --rc-combobox-border: 0;
203
+ --rc-combobox-radius: 0;
204
+ --rc-combobox-padding-block: 0;
205
+ --rc-chip-touch-target-overlap-block-start: 0.5rem;
206
+ --rc-chip-touch-target-overlap-block-end: 0.5rem;
207
+ --rc-field: transparent;
208
+ inline-size: 100%;
209
+ }
210
+
211
+ /*
212
+ * Full-size chips are taller than the input line, so keep a little space
213
+ * between their outline and the floated label. Dense chips sit on the
214
+ * input line and need none.
215
+ */
216
+ :where(.rc-theme-material, :host(.rc-theme-material))
217
+ rc-field:not(.rc-field--outlined)
218
+ > :is(
219
+ rc-combobox:not(.rc-combobox--dense),
220
+ rc-select:not(.rc-select--dense)
221
+ )[data-rc-field-control]::part(chips) {
222
+ padding-block-start: 0.25rem;
223
+ }
224
+
225
+ /* Dense chips leave more of the 3rem touch target to overlap. */
226
+ :where(.rc-theme-material, :host(.rc-theme-material))
227
+ rc-field
228
+ > :is(rc-combobox.rc-combobox--dense, rc-select.rc-select--dense)[data-rc-field-control] {
229
+ --rc-chip-touch-target-overlap-block-start: 0.75rem;
230
+ --rc-chip-touch-target-overlap-block-end: 0.75rem;
231
+ }
232
+
233
+ :where(.rc-theme-material, :host(.rc-theme-material))
234
+ rc-field
235
+ > rc-combobox[data-rc-field-control]::part(anchor):hover,
236
+ :where(.rc-theme-material, :host(.rc-theme-material))
237
+ rc-field
238
+ > rc-combobox[data-rc-field-control]::part(anchor):focus-within {
239
+ border-color: transparent;
240
+ background: transparent;
241
+ box-shadow: none;
242
+ /* rc-field's label and active indicator already show focus. */
243
+ outline: none;
244
+ }
245
+
246
+ :where(.rc-theme-material, :host(.rc-theme-material))
247
+ rc-field
248
+ rc-combobox[data-rc-field-control]::part(input) {
249
+ caret-color: var(--md-sys-color-primary, Highlight);
250
+ }
251
+
252
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-control-provider] {
253
+ --rc-field-padding: 0;
254
+ }
255
+
256
+ :where(.rc-theme-material, :host(.rc-theme-material))
257
+ rc-field[data-control-provider]:not(.rc-field--outlined) {
258
+ --rc-field-padding: 0.5rem 0 calc(0.5rem - 1px);
259
+ }
260
+
261
+ /* A multiline control provider supplies its own trailing block space. */
262
+ :where(.rc-theme-material, :host(.rc-theme-material))
263
+ rc-field[data-control-provider][data-multiline]:not(.rc-field--outlined) {
264
+ --rc-field-padding: 0.5rem 0 0;
265
+ }
266
+
267
+ :where(.rc-theme-material, :host(.rc-theme-material))
268
+ rc-field[data-control-provider]::part(label) {
269
+ inset-inline-start: 1rem;
270
+ }
271
+
272
+ :where(.rc-theme-material, :host(.rc-theme-material))
273
+ rc-field[data-control-provider]::part(trailing) {
274
+ margin-inline-end: 1rem;
275
+ }
276
+
277
+ :where(.rc-theme-material, :host(.rc-theme-material))
278
+ rc-field.rc-field--outlined[data-control-provider][data-multiline]::part(content) {
279
+ /*
280
+ * A single-line field's label gets its resting space above the field's
281
+ * top edge for free: #field centers content within its own taller
282
+ * min-block-size. A multiline control-provider's content fills #field's
283
+ * whole height instead, so there's no leftover space to center into.
284
+ * Padding here wouldn't reach the label: an absolutely positioned
285
+ * child's containing block is the padding EDGE (the border/padding
286
+ * boundary), not the content edge, so an ancestor's own padding only
287
+ * moves its in-flow children (the control), never an abspos one. Margin
288
+ * moves the ancestor's own box instead, carrying both children down
289
+ * together and reproducing the single-line field's free top space.
290
+ * padding-block is reset to 0 here too: the general [data-multiline]
291
+ * rule above would otherwise still apply its own 0.5rem, additionally
292
+ * shifting only the in-flow control and pulling it out of alignment
293
+ * with the label again.
294
+ */
295
+ padding-block: 0;
296
+ margin-block-start: 0.5rem;
297
+ }
298
+
299
+ :where(.rc-theme-material, :host(.rc-theme-material))
300
+ rc-field[data-has-label]:not([data-focused]):not([data-populated])
301
+ > input::placeholder,
302
+ :where(.rc-theme-material, :host(.rc-theme-material))
303
+ rc-field[data-has-label]:not([data-focused]):not([data-populated])
304
+ > textarea::placeholder,
305
+ /* A group's legend never rests in the input, so its placeholders wait for focus instead. */
306
+ :where(.rc-theme-material, :host(.rc-theme-material))
307
+ rc-field[data-group]:not([data-focused])
308
+ > fieldset
309
+ > :is(input, textarea)::placeholder {
310
+ color: transparent;
311
+ }
312
+
313
+ /* A read-only field keeps its focus indicator but no hover affordance, since
314
+ hovering cannot lead to an edit. */
315
+ :where(.rc-theme-material, :host(.rc-theme-material))
316
+ rc-field:not([data-readonly]):hover::part(field) {
317
+ border-block-end-color: var(--md-sys-color-on-surface, CanvasText);
318
+ background: color-mix(
319
+ in srgb,
320
+ var(--md-sys-color-on-surface, CanvasText) 4%,
321
+ var(--md-filled-text-field-container-color, var(--md-sys-color-surface-container-highest))
322
+ );
323
+ }
324
+
325
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-focused]::part(field)::after {
326
+ transform: scaleX(1);
327
+ }
328
+
329
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-focused]::part(label) {
330
+ color: var(--md-sys-color-primary, Highlight);
331
+ }
332
+
333
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-invalid]::part(field) {
334
+ border-block-end-color: var(--md-sys-color-error, red);
335
+ }
336
+
337
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-invalid]::part(field)::after {
338
+ background: var(--md-sys-color-error, red);
339
+ }
340
+
341
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-invalid]::part(label) {
342
+ color: var(--md-sys-color-error, red);
343
+ }
344
+
345
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-disabled]::part(field) {
346
+ border-block-end-color: color-mix(
347
+ in srgb,
348
+ var(--md-sys-color-on-surface, CanvasText) 38%,
349
+ transparent
350
+ );
351
+ background: color-mix(in srgb, var(--md-sys-color-on-surface, CanvasText) 4%, transparent);
352
+ color: color-mix(in srgb, var(--md-sys-color-on-surface, CanvasText) 38%, transparent);
353
+ }
354
+
355
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-disabled]::part(label),
356
+ :where(.rc-theme-material, :host(.rc-theme-material))
357
+ rc-field[data-disabled]::part(supporting-text) {
358
+ color: color-mix(in srgb, var(--md-sys-color-on-surface, CanvasText) 38%, transparent);
359
+ }
360
+
361
+ /*
362
+ * Grouped controls: a <fieldset> whose <legend> names the field. The legend
363
+ * uses the floating label mechanics: it rests on the input line while the
364
+ * group is idle and its primary input empty, and floats to the caption line
365
+ * on focus or once the primary input has a value. A leading addon already
366
+ * occupies the input line's start, so a group that begins with one keeps its
367
+ * legend floated. The primary text input grows and selects or enhanced
368
+ * controls attach before or after it, connected by the shared container and
369
+ * active indicator rather than chrome of their own.
370
+ */
371
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-group] > fieldset {
372
+ --rc-field-control-gap: 0.75rem;
373
+ padding-block-start: var(--_rc-field-group-label-space, var(--_rc-field-label-line-height));
374
+ }
375
+
376
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-group] > fieldset > legend {
377
+ position: absolute;
378
+ z-index: 1;
379
+ inset-inline-start: 0;
380
+ inset-block-start: 0;
381
+ max-inline-size: 100%;
382
+ overflow: hidden;
383
+ font-family: var(--md-sys-typescale-body-small-font, inherit);
384
+ font-size: var(--md-sys-typescale-body-small-size, 0.75rem);
385
+ line-height: var(--md-sys-typescale-body-small-line-height, 1rem);
386
+ text-overflow: ellipsis;
387
+ white-space: nowrap;
388
+ pointer-events: none;
389
+ transform: translate(var(--_rc-field-legend-x, 0), var(--_rc-field-legend-y, 0));
390
+ transform-origin: left top;
391
+ }
392
+
393
+ :where(.rc-theme-material, :host(.rc-theme-material))
394
+ rc-field[data-group]:not([data-focused]):not([data-populated])
395
+ > fieldset:has(> legend + :is(input, textarea))
396
+ > legend {
397
+ inset-block-start: 50%;
398
+ font-family: var(--md-sys-typescale-body-large-font, inherit);
399
+ font-size: var(--md-sys-typescale-body-large-size, 1rem);
400
+ line-height: var(--md-sys-typescale-body-large-line-height, 1.5rem);
401
+ --_rc-field-legend-y: -50%;
402
+ }
403
+
404
+ :where(.rc-theme-material, :host(.rc-theme-material))
405
+ rc-field[data-group][data-focused]
406
+ > fieldset
407
+ > legend {
408
+ color: var(--md-sys-color-primary, Highlight);
409
+ }
410
+
411
+ :where(.rc-theme-material, :host(.rc-theme-material))
412
+ rc-field[data-group][data-invalid]
413
+ > fieldset
414
+ > legend {
415
+ color: var(--md-sys-color-error, red);
416
+ }
417
+
418
+ :where(.rc-theme-material, :host(.rc-theme-material))
419
+ rc-field[data-group][data-disabled]
420
+ > fieldset
421
+ > legend {
422
+ color: color-mix(in srgb, var(--md-sys-color-on-surface, CanvasText) 38%, transparent);
423
+ }
424
+
425
+ :where(.rc-theme-material, :host(.rc-theme-material))
426
+ rc-field[data-group]
427
+ > fieldset
428
+ > :is(input, textarea) {
429
+ caret-color: var(--md-sys-color-primary, Highlight);
430
+ }
431
+
432
+ :where(.rc-theme-material, :host(.rc-theme-material))
433
+ rc-field[data-group]
434
+ > fieldset
435
+ > :is(input, select, textarea):focus-visible {
436
+ outline: none;
437
+ }
438
+
439
+ /* WebKit gives a native select a taller minimum than the input line. */
440
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-group] > fieldset > select {
441
+ block-size: var(--_rc-field-input-line-height);
442
+ field-sizing: content;
443
+ cursor: pointer;
444
+ }
445
+
446
+ :where(.rc-theme-material, :host(.rc-theme-material))
447
+ rc-field[data-group]
448
+ > fieldset
449
+ > rc-select[data-rc-field-control] {
450
+ --rc-select-control-block-size: var(--md-sys-typescale-body-large-line-height, 1.5rem);
451
+ --rc-select-border: 0;
452
+ --rc-select-radius: 0;
453
+ --rc-select-padding-block: 0;
454
+ --rc-field: transparent;
455
+ }
456
+
457
+ /* The outlined legend rides the outline like a floated outlined label. */
458
+ :where(.rc-theme-material, :host(.rc-theme-material))
459
+ rc-field.rc-field--outlined[data-group]
460
+ > fieldset
461
+ > legend {
462
+ --_rc-field-legend-x: -0.25rem;
463
+ --_rc-field-legend-y: -50%;
464
+ padding-inline: 0.25rem;
465
+ background: var(--md-sys-color-surface, Canvas);
466
+ }
467
+
468
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field.rc-field--outlined {
469
+ /* The outlined label rides the outline, so a group reserves no caption line. */
470
+ --_rc-field-group-label-space: 0;
471
+ --rc-field-min-block-size: max(3.5em, calc(var(--_rc-field-input-line-height) + 2em));
472
+ --rc-field-background: transparent;
473
+ --rc-field-radius: var(
474
+ --md-outlined-text-field-container-shape,
475
+ var(--md-sys-shape-corner-extra-small, 0.25rem)
476
+ );
477
+ }
478
+
479
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field.rc-field--outlined::part(field) {
480
+ border: 1px solid
481
+ var(--md-outlined-text-field-outline-color, var(--md-sys-color-outline, ButtonBorder));
482
+ }
483
+
484
+ :where(.rc-theme-material, :host(.rc-theme-material))
485
+ rc-field.rc-field--outlined::part(field)::after {
486
+ inset: -1px;
487
+ block-size: auto;
488
+ border: 2px solid var(--md-sys-color-primary, Highlight);
489
+ border-radius: inherit;
490
+ background: transparent;
491
+ transform: none;
492
+ opacity: 0;
493
+ pointer-events: none;
494
+ }
495
+
496
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field.rc-field--outlined::part(label) {
497
+ inset-block-start: 50%;
498
+ padding-inline: 0.25rem;
499
+ background: var(--md-sys-color-surface, Canvas);
500
+ transform: translate(-0.25rem, -50%);
501
+ }
502
+
503
+ :where(.rc-theme-material, :host(.rc-theme-material))
504
+ rc-field.rc-field--outlined[data-focused]::part(label),
505
+ :where(.rc-theme-material, :host(.rc-theme-material))
506
+ rc-field.rc-field--outlined[data-populated]::part(label),
507
+ :where(.rc-theme-material, :host(.rc-theme-material))
508
+ rc-field.rc-field--outlined[data-multiline]::part(label) {
509
+ inset-block-start: 0;
510
+ transform: translate(-0.25rem, -50%);
511
+ }
512
+
513
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field.rc-field--outlined::part(control) {
514
+ padding-block-start: 0;
515
+ }
516
+
517
+ :where(.rc-theme-material, :host(.rc-theme-material))
518
+ rc-field.rc-field--outlined[data-focused]::part(field)::after {
519
+ opacity: 1;
520
+ }
521
+
522
+ :where(.rc-theme-material, :host(.rc-theme-material))
523
+ rc-field.rc-field--outlined[data-invalid]::part(field),
524
+ :where(.rc-theme-material, :host(.rc-theme-material))
525
+ rc-field.rc-field--outlined[data-invalid]::part(field)::after {
526
+ border-color: var(--md-sys-color-error, red);
527
+ }
528
+
529
+ @media (prefers-reduced-motion: no-preference) {
530
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field::part(field),
531
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field::part(label),
532
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field[data-group] > fieldset > legend,
533
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field::part(field)::after {
534
+ /*
535
+ * inset-block-start and font-size move the label's box (the floating
536
+ * label crossing from placeholder position to the shrunk caption
537
+ * position), which is spatial motion, not effects, even though it was
538
+ * previously grouped with the color/opacity properties around it. The
539
+ * full transform-based label rewrite is tracked separately.
540
+ */
541
+ transition:
542
+ background-color var(--rc-motion-effects-duration-fast, 150ms)
543
+ var(--rc-motion-effects-easing-default, ease),
544
+ border-color var(--rc-motion-effects-duration-fast, 150ms)
545
+ var(--rc-motion-effects-easing-default, ease),
546
+ color var(--rc-motion-effects-duration-fast, 150ms)
547
+ var(--rc-motion-effects-easing-default, ease),
548
+ inset-block-start var(--rc-motion-spatial-duration-fast, 300ms)
549
+ var(--rc-motion-spatial-easing-fast, ease),
550
+ font-size var(--rc-motion-spatial-duration-fast, 300ms)
551
+ var(--rc-motion-spatial-easing-fast, ease),
552
+ line-height var(--rc-motion-effects-duration-fast, 150ms)
553
+ var(--rc-motion-effects-easing-default, ease),
554
+ opacity var(--rc-motion-effects-duration-fast, 150ms)
555
+ var(--rc-motion-effects-easing-default, ease),
556
+ transform var(--rc-motion-spatial-duration-fast, 300ms)
557
+ var(--rc-motion-spatial-easing-fast, ease);
558
+ }
559
+ }
560
+
561
+ @media (forced-colors: active) {
562
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-field::part(field) {
563
+ forced-color-adjust: auto;
564
+ }
565
+ }
566
+ }
@@ -1,13 +1,15 @@
1
1
  @layer rc-theme-material.components {
2
2
  :where(.rc-theme-material, :host(.rc-theme-material))
3
- :where(
4
- [data-rc-icon],
5
- [data-rc-button-icon],
6
- [data-rc-button-selected-icon],
7
- [data-rc-navigation-icon]
8
- ) {
3
+ :where([data-rc-icon], [data-rc-navigation-icon]) {
9
4
  display: inline-grid;
10
5
  place-items: center;
6
+ /*
7
+ * Reserve the icon square even while the slot is empty, as an SVG icon
8
+ * element (such as <iconify-icon>) is for a frame after it mounts. An
9
+ * icon-font glyph already fills 1em, so it renders the same.
10
+ */
11
+ min-inline-size: 1em;
12
+ min-block-size: 1em;
11
13
  font-size: var(--rc-icon-font-size, 1.5rem);
12
14
  /*
13
15
  * Unlayered icon-font boilerplate otherwise beats this layered theme rule.
@@ -16,4 +18,44 @@
16
18
  */
17
19
  line-height: var(--rc-icon-font-line-height, var(--rc-icon-font-size, 1.5rem)) !important;
18
20
  }
21
+
22
+ :where(.rc-theme-material, :host(.rc-theme-material))
23
+ :where([data-rc-button-icon], [data-rc-button-selected-icon], [data-rc-chip-icon]) {
24
+ display: inline-grid;
25
+ place-items: center;
26
+ min-inline-size: 1em;
27
+ min-block-size: 1em;
28
+ font-size: var(--rc-compact-icon-font-size, 1.125rem);
29
+ line-height: var(
30
+ --rc-compact-icon-font-line-height,
31
+ var(--rc-compact-icon-font-size, 1.125rem)
32
+ ) !important;
33
+ }
34
+
35
+ :where(.rc-theme-material, :host(.rc-theme-material))
36
+ rc-button[icon-only]
37
+ :where([data-rc-button-icon], [data-rc-button-selected-icon]) {
38
+ font-size: var(--rc-icon-button-icon-font-size, 1.5rem);
39
+ line-height: var(--rc-icon-button-icon-font-size, 1.5rem) !important;
40
+ }
41
+
42
+ /*
43
+ * An icon-only button's marker attributes (above) are an opt-in contract:
44
+ * a consumer's icon element has to know to carry `data-rc-button-icon`.
45
+ * When it doesn't (an <svg>, an <iconify-icon>, and similar),
46
+ * that icon would otherwise silently inherit the button's label font-size
47
+ * instead of the icon-button icon size. rc-button only sets `icon-only`
48
+ * once it classifies the native button as icon-having and label-less, so
49
+ * its direct children are icon content unless a responsive composition
50
+ * exposes an authored `[data-rc-menu-label]`; size every other direct
51
+ * child as an icon. The explicit marker rule above still matters for an
52
+ * icon nested one level deeper than a direct child.
53
+ */
54
+ :where(.rc-theme-material, :host(.rc-theme-material))
55
+ rc-button[icon-only]
56
+ > button
57
+ > :not([data-rc-menu-label]) {
58
+ font-size: var(--rc-icon-button-icon-font-size, 1.5rem);
59
+ line-height: var(--rc-icon-button-icon-font-size, 1.5rem) !important;
60
+ }
19
61
  }