@rcarls/rc-theme-material 0.0.0-next-20260921045401

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 (48) hide show
  1. package/CHANGELOG.md +423 -0
  2. package/README.md +164 -0
  3. package/bridge.css +678 -0
  4. package/components/accordion.css +20 -0
  5. package/components/adaptive-menu.css +162 -0
  6. package/components/app-bar.css +100 -0
  7. package/components/bottom-sheet.css +135 -0
  8. package/components/button.css +270 -0
  9. package/components/card.css +61 -0
  10. package/components/carousel.css +23 -0
  11. package/components/chip-group.css +15 -0
  12. package/components/chip.css +39 -0
  13. package/components/combobox.css +155 -0
  14. package/components/dialog.css +86 -0
  15. package/components/disclosure.css +104 -0
  16. package/components/fab-menu.css +85 -0
  17. package/components/fab.css +51 -0
  18. package/components/field.css +378 -0
  19. package/components/icons.css +52 -0
  20. package/components/list-item.css +146 -0
  21. package/components/listbox.css +47 -0
  22. package/components/markdown-editor.css +72 -0
  23. package/components/menu-button.css +126 -0
  24. package/components/menu.css +147 -0
  25. package/components/menubar.css +27 -0
  26. package/components/modes.css +50 -0
  27. package/components/navigation-bar.css +76 -0
  28. package/components/navigation-rail.css +132 -0
  29. package/components/progress.css +15 -0
  30. package/components/range-slider.css +29 -0
  31. package/components/scroller.css +7 -0
  32. package/components/search-bar.css +58 -0
  33. package/components/segmented-button.css +19 -0
  34. package/components/select.css +197 -0
  35. package/components/slider.css +19 -0
  36. package/components/snackbar.css +23 -0
  37. package/components/splitter.css +35 -0
  38. package/components/switch.css +41 -0
  39. package/components/textarea.css +31 -0
  40. package/components/toolbar.css +32 -0
  41. package/components/transfer-list.css +70 -0
  42. package/components/virtual-canvas.css +16 -0
  43. package/components.css +42 -0
  44. package/constraints/material.json +99 -0
  45. package/defaults.css +1081 -0
  46. package/package.json +53 -0
  47. package/state-layer.css +35 -0
  48. package/theme.css +3 -0
@@ -0,0 +1,162 @@
1
+ @layer rc-theme-material.components {
2
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-adaptive-menu {
3
+ --rc-adaptive-menu-gap: 0;
4
+ --rc-adaptive-menu-trigger-inline-size: 2rem;
5
+ --rc-adaptive-menu-trigger-block-size: 2.5rem;
6
+ --rc-adaptive-menu-touch-target-block-size: 3rem;
7
+ /*
8
+ * Unlike rc-button's narrow variant (opt-in, usable anywhere), the
9
+ * overflow trigger is always the trailing-most control in its toolbar
10
+ * by design -- there's no legitimate placement where something else
11
+ * needs the space this reclaims -- so this defaults unconditionally
12
+ * rather than needing its own opt-in variant. (3rem touch target - 2rem
13
+ * trigger-inline-size) / 2, matching --rc-adaptive-menu-trigger-inline-size
14
+ * above.
15
+ */
16
+ --rc-adaptive-menu-touch-target-overlap-inline-end: 0.5rem;
17
+ --rc-adaptive-menu-trigger-padding: 0.25rem;
18
+ --rc-adaptive-menu-trigger-border: 0;
19
+ --rc-adaptive-menu-trigger-radius: var(--md-sys-shape-corner-full, 9999px);
20
+ --rc-adaptive-menu-trigger-background: transparent;
21
+ --rc-adaptive-menu-trigger-color: var(--md-sys-color-on-surface-variant, ButtonText);
22
+ --rc-adaptive-menu-icon-size: 1.5rem;
23
+ --rc-adaptive-menu-popup-min-inline-size: 7rem;
24
+ --rc-adaptive-menu-popup-padding-block: 0.5rem;
25
+ --rc-adaptive-menu-popup-border: 0;
26
+ --rc-adaptive-menu-popup-radius: var(
27
+ --md-menu-container-shape,
28
+ var(--md-sys-shape-corner-extra-small, 0.25rem)
29
+ );
30
+ --rc-adaptive-menu-popup-background: var(
31
+ --md-menu-container-color,
32
+ var(--md-sys-color-surface-container, Canvas)
33
+ );
34
+ --rc-adaptive-menu-popup-color: var(--md-sys-color-on-surface, CanvasText);
35
+ --rc-adaptive-menu-popup-shadow: 0 1px 2px rgb(0 0 0 / 30%), 0 2px 6px 2px rgb(0 0 0 / 15%);
36
+ --rc-adaptive-menu-item-min-block-size: 3rem;
37
+ --rc-adaptive-menu-item-padding-block: 0;
38
+ --rc-adaptive-menu-item-padding-inline: 0.75rem;
39
+ --rc-adaptive-menu-item-gap: 0.75rem;
40
+ }
41
+
42
+ :where(.rc-theme-material, :host(.rc-theme-material))
43
+ rc-adaptive-menu::part(overflow-trigger):hover {
44
+ background: color-mix(
45
+ in srgb,
46
+ var(--md-sys-color-on-surface-variant, CanvasText)
47
+ calc(var(--md-sys-state-hover-state-layer-opacity, 0.08) * 100%),
48
+ transparent
49
+ );
50
+ }
51
+
52
+ :where(.rc-theme-material, :host(.rc-theme-material))
53
+ rc-adaptive-menu::part(overflow-trigger):focus-visible {
54
+ outline: var(--rc-focus-ring, 2px solid Highlight);
55
+ outline-offset: var(--rc-focus-ring-offset, 2px);
56
+ }
57
+
58
+ :where(.rc-theme-material, :host(.rc-theme-material))
59
+ rc-adaptive-menu
60
+ > [data-rc-action-promoted]:has([data-rc-menu-leading])
61
+ [data-rc-menu-label] {
62
+ position: absolute;
63
+ inline-size: 1px;
64
+ block-size: 1px;
65
+ padding: 0;
66
+ margin: -1px;
67
+ overflow: hidden;
68
+ clip-path: inset(50%);
69
+ white-space: nowrap;
70
+ }
71
+
72
+ :where(.rc-theme-material, :host(.rc-theme-material))
73
+ rc-adaptive-menu
74
+ > rc-menu-button[data-rc-action-promoted] {
75
+ --rc-menu-button-indicator-size: 0px;
76
+ --rc-menu-button-indicator-inset: 0px;
77
+ }
78
+
79
+ :where(.rc-theme-material, :host(.rc-theme-material))
80
+ rc-adaptive-menu
81
+ > rc-menu-button[data-rc-action-promoted]
82
+ > [slot='indicator'] {
83
+ display: none;
84
+ }
85
+
86
+ :where(.rc-theme-material, :host(.rc-theme-material))
87
+ rc-adaptive-menu
88
+ > [data-rc-action-overflowed] {
89
+ inline-size: 100%;
90
+ color: var(--md-sys-color-on-surface, CanvasText);
91
+ }
92
+
93
+ :where(.rc-theme-material, :host(.rc-theme-material))
94
+ rc-adaptive-menu
95
+ > rc-button[data-rc-action-overflowed] {
96
+ display: block;
97
+ min-inline-size: 100%;
98
+ min-block-size: 0;
99
+ --rc-button-block-size: 3rem;
100
+ --rc-button-icon-size: 100%;
101
+ --rc-button-touch-target-inline-size: 100%;
102
+ --rc-button-touch-target-block-size: 3rem;
103
+ --rc-button-padding-inline: 0.75rem;
104
+ --rc-button-padding-block: 0;
105
+ --rc-button-radius: 0;
106
+ --rc-button-bg: transparent;
107
+ --rc-button-color: var(--md-sys-color-on-surface, CanvasText);
108
+ --rc-button-border: 0;
109
+ --rc-button-state-layer-bg: var(--md-sys-color-on-surface, CanvasText);
110
+ --rc-button-progress-color: var(--md-sys-color-on-surface, CanvasText);
111
+ }
112
+
113
+ :where(.rc-theme-material, :host(.rc-theme-material))
114
+ rc-adaptive-menu
115
+ > rc-menu-button[data-rc-action-overflowed] {
116
+ display: block;
117
+ min-inline-size: 100%;
118
+ min-block-size: 0;
119
+ --rc-menu-button-trigger-block-size: 3rem;
120
+ --rc-menu-button-icon-size: 100%;
121
+ --rc-menu-button-touch-target-inline-size: 100%;
122
+ --rc-menu-button-touch-target-block-size: 3rem;
123
+ --rc-menu-button-trigger-padding-block: 0;
124
+ --rc-menu-button-trigger-padding-inline: 0.75rem;
125
+ --rc-menu-button-trigger-gap: 0.75rem;
126
+ --rc-menu-button-trigger-radius: 0;
127
+ --rc-menu-button-trigger-border: 0;
128
+ --rc-menu-button-trigger-background: transparent;
129
+ --rc-menu-button-trigger-color: var(--md-sys-color-on-surface, CanvasText);
130
+ --rc-menu-button-trigger-hover-color: var(--md-sys-color-on-surface, CanvasText);
131
+ --rc-menu-button-trigger-open-color: var(--md-sys-color-on-surface, CanvasText);
132
+ }
133
+
134
+ :where(.rc-theme-material, :host(.rc-theme-material))
135
+ rc-adaptive-menu
136
+ > rc-menu-button[data-rc-action-overflowed]
137
+ > [slot='trigger'] {
138
+ justify-content: flex-start;
139
+ inline-size: 100%;
140
+ min-inline-size: 100%;
141
+ padding-inline: 0.75rem;
142
+ }
143
+
144
+ :where(.rc-theme-material, :host(.rc-theme-material))
145
+ rc-adaptive-menu
146
+ > [data-rc-action-overflowed]
147
+ [data-rc-menu-label] {
148
+ font: var(--md-sys-typescale-body-large-weight, 400)
149
+ var(--md-sys-typescale-body-large-size, 1rem) /
150
+ var(--md-sys-typescale-body-large-line-height, 1.5rem)
151
+ var(--md-sys-typescale-body-large-font, inherit);
152
+ letter-spacing: var(--md-sys-typescale-body-large-tracking, 0.03125rem);
153
+ }
154
+
155
+ :where(.rc-theme-material, :host(.rc-theme-material))
156
+ rc-adaptive-menu
157
+ > [data-rc-action-overflowed]
158
+ [data-rc-menu-leading] {
159
+ font-size: 1.5rem;
160
+ line-height: 1.5rem;
161
+ }
162
+ }
@@ -0,0 +1,100 @@
1
+ @layer rc-theme-material.components {
2
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-app-bar {
3
+ box-shadow: var(--rc-shadow-level0, none);
4
+ font-family: var(--md-sys-typescale-title-large-font, inherit);
5
+ transition:
6
+ box-shadow var(--rc-motion-effects-duration-default, 200ms)
7
+ var(--rc-motion-effects-easing-default, ease),
8
+ translate var(--rc-motion-spatial-duration-default, 400ms)
9
+ var(--rc-motion-spatial-easing-default, ease);
10
+ }
11
+
12
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-app-bar[data-scrolled] {
13
+ --rc-app-bar-bg: var(--md-sys-color-surface-container, Canvas);
14
+ box-shadow: var(--rc-shadow-level2, none);
15
+ }
16
+
17
+ /*
18
+ * A bare <button>/[role=button] dropped directly into an rc-app-bar's
19
+ * leading or trailing action slot gets full M3 icon-button treatment on
20
+ * its own — MD3 "Small" icon button: 40dp visual container / 24dp icon —
21
+ * without needing rc-button. Scoped to a *direct* child
22
+ * (`>`, not a descendant combinator): a button nested inside an
23
+ * `rc-button`/`rc-menu-button` slotted here is several levels deeper in
24
+ * the light DOM and already has its own correct sizing from that
25
+ * component's own theming; a descendant selector here would reach
26
+ * straight through and fight it.
27
+ */
28
+ :where(.rc-theme-material, :host(.rc-theme-material))
29
+ rc-app-bar
30
+ > :is(button, [role='button']):is([slot='leading'], [slot='trailing']) {
31
+ box-sizing: border-box;
32
+ position: relative;
33
+ display: inline-grid;
34
+ place-items: center;
35
+ inline-size: 2.5rem;
36
+ block-size: 2.5rem;
37
+ padding: 0;
38
+ border: 0;
39
+ border-radius: var(--md-sys-shape-corner-full, 999px);
40
+ background: transparent;
41
+ color: inherit;
42
+ }
43
+
44
+ /* Accessible touch-target floor, decoupled from the visual size above —
45
+ the same affordance rc-button's own icon-only buttons provide. A
46
+ no-op once the visible button already meets or exceeds it. */
47
+ :where(.rc-theme-material, :host(.rc-theme-material))
48
+ rc-app-bar
49
+ > :is(button, [role='button']):is([slot='leading'], [slot='trailing'])::before {
50
+ content: '';
51
+ position: absolute;
52
+ inset: calc((3rem - max(100%, 2.5rem)) / -2);
53
+ }
54
+
55
+ /* Sizes the button's own content (typically a single icon) to the MD3
56
+ icon-button glyph size, regardless of whether it carries a marker
57
+ attribute — a direct child of an app-bar action button is
58
+ unambiguously its icon. */
59
+ :where(.rc-theme-material, :host(.rc-theme-material))
60
+ rc-app-bar
61
+ > :is(button, [role='button']):is([slot='leading'], [slot='trailing'])
62
+ > * {
63
+ font-size: 1.5rem;
64
+ line-height: 1.5rem;
65
+ }
66
+
67
+ :where(.rc-theme-material, :host(.rc-theme-material))
68
+ rc-app-bar
69
+ > :is(button, [role='button']):is([slot='leading'], [slot='trailing']):hover {
70
+ background: color-mix(in srgb, var(--md-sys-color-on-surface, CanvasText) 8%, transparent);
71
+ }
72
+
73
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-app-bar.rc-app-bar--center-aligned {
74
+ --rc-app-bar-title-font-size: var(
75
+ --md-top-app-bar-headline-size,
76
+ var(--md-sys-typescale-title-large-size, inherit)
77
+ );
78
+ }
79
+
80
+ :where(.rc-theme-material, :host(.rc-theme-material))
81
+ rc-app-bar.rc-app-bar--center-aligned::part(title) {
82
+ text-align: center;
83
+ }
84
+
85
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-app-bar.rc-app-bar--medium {
86
+ --rc-app-bar-expanded-title-font-size: var(
87
+ --md-medium-top-app-bar-headline-size,
88
+ var(--md-sys-typescale-headline-small-size, inherit)
89
+ );
90
+ --rc-app-bar-expanded-padding-block: 1rem;
91
+ }
92
+
93
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-app-bar.rc-app-bar--large {
94
+ --rc-app-bar-expanded-title-font-size: var(
95
+ --md-large-top-app-bar-headline-size,
96
+ var(--md-sys-typescale-headline-medium-size, inherit)
97
+ );
98
+ --rc-app-bar-expanded-padding-block: 1.25rem;
99
+ }
100
+ }
@@ -0,0 +1,135 @@
1
+ @layer rc-theme-material.components {
2
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-bottom-sheet {
3
+ --rc-bottom-sheet-bg: var(--md-sys-color-surface-container-low, Canvas);
4
+ --rc-bottom-sheet-handle-color: color-mix(
5
+ in srgb,
6
+ var(--md-sys-color-on-surface-variant, GrayText) 40%,
7
+ transparent
8
+ );
9
+ --rc-bottom-sheet-handle-radius: var(--md-sys-shape-corner-full, 999px);
10
+ --rc-bottom-sheet-handle-target-block-size: 3rem;
11
+ --rc-bottom-sheet-snap-duration: var(--rc-motion-spatial-duration-fast, 300ms);
12
+ --rc-bottom-sheet-snap-easing: var(
13
+ --rc-motion-spatial-easing-default,
14
+ cubic-bezier(0.2, 0, 0, 1)
15
+ );
16
+ }
17
+
18
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-bottom-sheet > dialog {
19
+ position: fixed;
20
+ inset: auto 0 0;
21
+ box-sizing: border-box;
22
+ inline-size: 100%;
23
+ max-inline-size: var(--rc-bottom-sheet-max-inline-size, 40rem);
24
+ max-block-size: var(--rc-bottom-sheet-max-block-size, 70dvh);
25
+ margin-block: 0;
26
+ margin-inline: auto;
27
+ padding: var(--rc-bottom-sheet-padding, 0 1rem calc(1rem + env(safe-area-inset-bottom, 0px)));
28
+ overflow: auto;
29
+ border: 0;
30
+ border-radius: var(--rc-bottom-sheet-radius, 1.75rem 1.75rem 0 0);
31
+ background: var(--rc-bottom-sheet-bg, var(--md-sys-color-surface-container-low, Canvas));
32
+ color: var(--rc-bottom-sheet-color, var(--md-sys-color-on-surface, CanvasText));
33
+ box-shadow: var(--rc-bottom-sheet-shadow, var(--rc-shadow-level1, none));
34
+ font-family: var(--md-sys-typescale-body-medium-font, inherit);
35
+ }
36
+
37
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-bottom-sheet > dialog::backdrop {
38
+ background: var(
39
+ --rc-bottom-sheet-scrim,
40
+ var(--rc-dialog-scrim, color-mix(in srgb, var(--md-sys-color-scrim, #000) 32%, transparent))
41
+ );
42
+ }
43
+
44
+ /* Descendant (not child) combinator: consuming apps may nest the handle
45
+ inside their own peek-content wrapper (e.g. grouped with a summary
46
+ row) rather than placing it as a direct child of dialog. */
47
+ :where(.rc-theme-material, :host(.rc-theme-material))
48
+ rc-bottom-sheet
49
+ > dialog
50
+ [data-rc-bottom-sheet-handle] {
51
+ position: relative;
52
+ display: block;
53
+ inline-size: var(--rc-bottom-sheet-handle-target-inline-size, 100%);
54
+ min-block-size: var(--rc-bottom-sheet-handle-target-block-size, 3rem);
55
+ margin: var(--rc-bottom-sheet-handle-target-margin, 0);
56
+ padding: 0;
57
+ border: 0;
58
+ border-radius: inherit;
59
+ background: transparent;
60
+ appearance: none;
61
+ cursor: ns-resize;
62
+ touch-action: none;
63
+ -webkit-tap-highlight-color: transparent;
64
+ }
65
+
66
+ :where(.rc-theme-material, :host(.rc-theme-material))
67
+ rc-bottom-sheet
68
+ > dialog
69
+ [data-rc-bottom-sheet-handle]::before {
70
+ content: '';
71
+ position: absolute;
72
+ inset-block-start: 50%;
73
+ inset-inline-start: 50%;
74
+ inline-size: var(--rc-bottom-sheet-handle-inline-size, 2rem);
75
+ block-size: var(--rc-bottom-sheet-handle-block-size, 0.25rem);
76
+ border-radius: var(--rc-bottom-sheet-handle-radius, 999px);
77
+ background: var(--rc-bottom-sheet-handle-color, GrayText);
78
+ translate: -50% -50%;
79
+ }
80
+
81
+ :where(.rc-theme-material, :host(.rc-theme-material))
82
+ rc-bottom-sheet
83
+ > dialog
84
+ [data-rc-bottom-sheet-handle]:focus-visible {
85
+ outline: 0.125rem solid var(--md-sys-color-primary, Highlight);
86
+ outline-offset: -0.25rem;
87
+ }
88
+
89
+ :where(.rc-theme-material, :host(.rc-theme-material))
90
+ rc-bottom-sheet
91
+ > dialog
92
+ > :is(button, [role='button']):not([data-rc-bottom-sheet-handle]) {
93
+ min-block-size: 2.5rem;
94
+ padding-block: 0;
95
+ padding-inline: 1.5rem;
96
+ border: 0;
97
+ border-radius: var(--md-sys-shape-corner-full, 999px);
98
+ background: transparent;
99
+ color: var(--md-sys-color-primary, ButtonText);
100
+ font: var(--md-sys-typescale-label-large-weight, 500)
101
+ var(--md-sys-typescale-label-large-size, 0.875rem) /
102
+ var(--md-sys-typescale-label-large-line-height, 1.25rem)
103
+ var(--md-sys-typescale-label-large-font, inherit);
104
+ letter-spacing: var(--md-sys-typescale-label-large-tracking, 0.00625em);
105
+ }
106
+
107
+ :where(.rc-theme-material, :host(.rc-theme-material))
108
+ rc-bottom-sheet
109
+ > dialog
110
+ > :is(button, [role='button']):not([data-rc-bottom-sheet-handle], :disabled):hover {
111
+ background: color-mix(in srgb, var(--md-sys-color-primary, ButtonText) 8%, transparent);
112
+ }
113
+
114
+ :where(.rc-theme-material, :host(.rc-theme-material))
115
+ rc-bottom-sheet
116
+ > dialog
117
+ > :is(button, [role='button']):not([data-rc-bottom-sheet-handle]):focus-visible {
118
+ outline: var(--rc-focus-ring, 2px solid Highlight);
119
+ outline-offset: var(--rc-focus-ring-offset, 2px);
120
+ }
121
+
122
+ :where(.rc-theme-material, :host(.rc-theme-material))
123
+ rc-bottom-sheet
124
+ > dialog
125
+ > :is(button, [role='button']):not([data-rc-bottom-sheet-handle], :disabled):active {
126
+ background: color-mix(in srgb, var(--md-sys-color-primary, ButtonText) 12%, transparent);
127
+ }
128
+
129
+ :where(.rc-theme-material, :host(.rc-theme-material))
130
+ rc-bottom-sheet
131
+ > dialog
132
+ > :is(button, [role='button']):not([data-rc-bottom-sheet-handle]):disabled {
133
+ opacity: var(--rc-disabled-opacity, 0.38);
134
+ }
135
+ }
@@ -0,0 +1,270 @@
1
+ @layer rc-theme-material.components {
2
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button {
3
+ --rc-button-bg: var(--md-sys-color-primary, ButtonFace);
4
+ --rc-button-color: var(--md-sys-color-on-primary, ButtonText);
5
+ --rc-button-border: 0;
6
+ --rc-button-radius: var(--md-sys-shape-corner-full, 9999px);
7
+ --rc-button-block-size: 2.5rem;
8
+ --rc-button-padding-block: 0;
9
+ --rc-button-padding-inline: 1.5rem;
10
+ --rc-button-gap: 0.5rem;
11
+ --rc-button-font: var(--md-sys-typescale-label-large-weight, 500)
12
+ var(--md-sys-typescale-label-large-size, 0.875rem) /
13
+ var(--md-sys-typescale-label-large-line-height, 1.25rem)
14
+ var(--md-sys-typescale-label-large-font, inherit);
15
+ --rc-button-state-layer-bg: var(--md-sys-color-on-primary, currentColor);
16
+ --rc-button-hover-state-layer-opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);
17
+ --rc-button-focus-state-layer-opacity: var(--md-sys-state-focus-state-layer-opacity, 0.12);
18
+ --rc-button-pressed-state-layer-opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);
19
+ --rc-button-state-layer-duration: var(--rc-motion-effects-duration-fast, 150ms);
20
+ --rc-button-state-layer-easing: var(
21
+ --md-sys-motion-easing-standard,
22
+ cubic-bezier(0.2, 0, 0, 1)
23
+ );
24
+ --_rc-button-ripple-enabled: 1;
25
+ --_rc-button-ripple-color: var(--md-sys-color-on-primary, currentColor);
26
+ --_rc-button-ripple-opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);
27
+ --_rc-button-ripple-duration: var(--rc-motion-spatial-duration-slow, 500ms);
28
+ --_rc-button-ripple-easing: var(
29
+ --md-sys-motion-easing-emphasized-decelerate,
30
+ cubic-bezier(0.05, 0.7, 0.1, 1)
31
+ );
32
+ --rc-button-progress-color: var(--md-sys-color-on-primary, ButtonText);
33
+ --rc-button-disabled-opacity: var(--rc-disabled-opacity, 0.38);
34
+ }
35
+
36
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button.rc-button--tonal {
37
+ --rc-button-bg: var(--md-sys-color-secondary-container, ButtonFace);
38
+ --rc-button-color: var(--md-sys-color-on-secondary-container, ButtonText);
39
+ --rc-button-state-layer-bg: var(--md-sys-color-on-secondary-container, currentColor);
40
+ --_rc-button-ripple-color: var(--md-sys-color-on-secondary-container, currentColor);
41
+ --rc-button-progress-color: var(--md-sys-color-on-secondary-container, ButtonText);
42
+ }
43
+
44
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button.rc-button--outlined {
45
+ --rc-button-bg: transparent;
46
+ --rc-button-color: var(--md-sys-color-primary, ButtonText);
47
+ --rc-button-border: 1px solid var(--md-sys-color-outline, ButtonBorder);
48
+ --rc-button-state-layer-bg: var(--md-sys-color-primary, currentColor);
49
+ --_rc-button-ripple-color: var(--md-sys-color-primary, currentColor);
50
+ --rc-button-progress-color: var(--md-sys-color-primary, ButtonText);
51
+ }
52
+
53
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button.rc-button--text {
54
+ --rc-button-bg: transparent;
55
+ --rc-button-color: var(--md-sys-color-primary, ButtonText);
56
+ --rc-button-border: 0;
57
+ --rc-button-padding-inline: 0.75rem;
58
+ --rc-button-state-layer-bg: var(--md-sys-color-primary, currentColor);
59
+ --_rc-button-ripple-color: var(--md-sys-color-primary, currentColor);
60
+ --rc-button-progress-color: var(--md-sys-color-primary, ButtonText);
61
+ }
62
+
63
+ :where(.rc-theme-material, :host(.rc-theme-material))
64
+ rc-button.rc-icon-button--standard[icon-only] {
65
+ --rc-button-bg: transparent;
66
+ --rc-button-color: var(--md-sys-color-on-surface-variant, ButtonText);
67
+ --rc-button-border: 0;
68
+ --rc-button-state-layer-bg: var(--md-sys-color-on-surface-variant, currentColor);
69
+ --_rc-button-ripple-color: var(--md-sys-color-on-surface-variant, currentColor);
70
+ --rc-button-progress-color: var(--md-sys-color-on-surface-variant, ButtonText);
71
+ }
72
+
73
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button.rc-icon-button--tonal[icon-only] {
74
+ --rc-button-bg: var(--md-sys-color-secondary-container, ButtonFace);
75
+ --rc-button-color: var(--md-sys-color-on-secondary-container, ButtonText);
76
+ --rc-button-state-layer-bg: var(--md-sys-color-on-secondary-container, currentColor);
77
+ --_rc-button-ripple-color: var(--md-sys-color-on-secondary-container, currentColor);
78
+ --rc-button-progress-color: var(--md-sys-color-on-secondary-container, ButtonText);
79
+ }
80
+
81
+ :where(.rc-theme-material, :host(.rc-theme-material))
82
+ rc-button.rc-icon-button--outlined[icon-only] {
83
+ --rc-button-bg: transparent;
84
+ --rc-button-color: var(--md-sys-color-on-surface-variant, ButtonText);
85
+ --rc-button-border: 1px solid var(--md-sys-color-outline, ButtonBorder);
86
+ --rc-button-state-layer-bg: var(--md-sys-color-on-surface-variant, currentColor);
87
+ --_rc-button-ripple-color: var(--md-sys-color-on-surface-variant, currentColor);
88
+ --rc-button-progress-color: var(--md-sys-color-on-surface-variant, ButtonText);
89
+ }
90
+
91
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button[data-tone='danger'] {
92
+ --rc-button-bg: var(--md-sys-color-error, ButtonFace);
93
+ --rc-button-color: var(--md-sys-color-on-error, ButtonText);
94
+ --rc-button-state-layer-bg: var(--md-sys-color-on-error, currentColor);
95
+ --_rc-button-ripple-color: var(--md-sys-color-on-error, currentColor);
96
+ --rc-button-progress-color: var(--md-sys-color-on-error, ButtonText);
97
+ }
98
+
99
+ :where(.rc-theme-material, :host(.rc-theme-material))
100
+ rc-button:is(
101
+ .rc-button--tonal,
102
+ .rc-button--outlined,
103
+ .rc-button--text,
104
+ .rc-icon-button--standard,
105
+ .rc-icon-button--tonal,
106
+ .rc-icon-button--outlined
107
+ )[data-tone='danger'] {
108
+ --rc-button-bg: transparent;
109
+ --rc-button-color: var(--md-sys-color-error, ButtonText);
110
+ --rc-button-state-layer-bg: var(--md-sys-color-error, currentColor);
111
+ --_rc-button-ripple-color: var(--md-sys-color-error, currentColor);
112
+ --rc-button-progress-color: var(--md-sys-color-error, ButtonText);
113
+ }
114
+
115
+ :where(.rc-theme-material, :host(.rc-theme-material))
116
+ rc-button:is(.rc-button--tonal, .rc-icon-button--tonal)[data-tone='danger'] {
117
+ --rc-button-bg: var(--md-sys-color-error-container, ButtonFace);
118
+ --rc-button-color: var(--md-sys-color-on-error-container, ButtonText);
119
+ --rc-button-state-layer-bg: var(--md-sys-color-on-error-container, currentColor);
120
+ }
121
+
122
+ :where(.rc-theme-material, :host(.rc-theme-material))
123
+ rc-button:is(.rc-button--outlined, .rc-icon-button--outlined)[data-tone='danger'] {
124
+ --rc-button-border: 1px solid var(--md-sys-color-error, ButtonBorder);
125
+ }
126
+
127
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button > button:focus-visible {
128
+ outline: var(--rc-focus-ring, 2px solid Highlight);
129
+ outline-offset: var(--rc-focus-ring-offset, 2px);
130
+ }
131
+
132
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button[disabled] > button:disabled {
133
+ opacity: var(--rc-disabled-opacity, 0.38);
134
+ }
135
+
136
+ :where(.rc-theme-material, :host(.rc-theme-material))
137
+ rc-button[progress][progress-value]::part(progress) {
138
+ font-size: 0;
139
+ }
140
+
141
+ :where(.rc-theme-material, :host(.rc-theme-material))
142
+ rc-button[progress][progress-value]::part(progress)::before {
143
+ display: block;
144
+ }
145
+
146
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button[icon-only] {
147
+ /* MD3 expressive "Small" icon button (the default/unmodified size): a
148
+ 40dp square container around a 24dp icon. rc-button's own touch-target
149
+ affordance (min-inline/block-size 3rem, plus the light-DOM hit-slop)
150
+ makes up the difference to the 48dp minimum tap target on its own; no
151
+ theme-level override is needed for that here. */
152
+ --rc-button-icon-size: 2.5rem;
153
+ --rc-icon-button-icon-font-size: 1.5rem;
154
+ }
155
+
156
+ /*
157
+ * MD3 expressive icon-button sizes. Each sets both the square container
158
+ * (`--rc-button-block-size`/`--rc-button-icon-size`, since `icon-only`'s
159
+ * default width equals its height) and the icon glyph size together, so
160
+ * the two stay in the spec's fixed ratio instead of drifting independently.
161
+ * Values: https://m3.material.io/components/icon-buttons/specs (container
162
+ * height / icon size, dp): extra-small 32/20, small 40/24 (above, default),
163
+ * medium 56/24, large 96/32, extra-large 136/40.
164
+ */
165
+ :where(.rc-theme-material, :host(.rc-theme-material))
166
+ rc-button.rc-button--extra-small[icon-only] {
167
+ --rc-button-block-size: 2rem;
168
+ --rc-button-icon-size: 2rem;
169
+ --rc-icon-button-icon-font-size: 1.25rem;
170
+ }
171
+
172
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button.rc-button--medium[icon-only] {
173
+ --rc-button-block-size: 3.5rem;
174
+ --rc-button-icon-size: 3.5rem;
175
+ --rc-icon-button-icon-font-size: 1.5rem;
176
+ }
177
+
178
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button.rc-button--large[icon-only] {
179
+ --rc-button-block-size: 6rem;
180
+ --rc-button-icon-size: 6rem;
181
+ --rc-icon-button-icon-font-size: 2rem;
182
+ }
183
+
184
+ :where(.rc-theme-material, :host(.rc-theme-material))
185
+ rc-button.rc-button--extra-large[icon-only] {
186
+ --rc-button-block-size: 8.5rem;
187
+ --rc-button-icon-size: 8.5rem;
188
+ --rc-icon-button-icon-font-size: 2.5rem;
189
+ }
190
+
191
+ /*
192
+ * Width variants change only the container's inline size; block size (and
193
+ * the icon itself) stay governed by the size class above, or the default
194
+ * "small" size when none is present. `narrow` suits dense/overflow
195
+ * contexts (an app bar's trailing overflow trigger); `wide` suits roomier
196
+ * toolbars that can spare the extra tap-friendly width. Per-size pairing
197
+ * is required because each size's narrow/wide delta is a fixed spec value,
198
+ * not a proportional one.
199
+ */
200
+ /*
201
+ * The overlap tokens below give back exactly what --rc-button-icon-size
202
+ * leaves unclaimed of the 3rem default touch target ((3rem - icon-size) /
203
+ * 2, matching the button's own centered inflation) -- the narrow variant's
204
+ * documented reason for existing is dense/edge contexts, so this is a
205
+ * default here, not left for every consumer to compute and set
206
+ * individually. Trailing-edge only: narrow's own doc comment names an app
207
+ * bar's *trailing* overflow trigger as the canonical case, and defaulting
208
+ * only one side halves the risk of two adjacent narrow buttons' touch
209
+ * targets colliding if a consumer places one where it does have a real
210
+ * neighbor. Medium/large/extra-large narrow variants already meet or
211
+ * exceed the touch target on their own (see each size's own comment
212
+ * above), so they need no overlap default here.
213
+ */
214
+ :where(.rc-theme-material, :host(.rc-theme-material))
215
+ rc-button.rc-button--extra-small.rc-button--narrow[icon-only] {
216
+ --rc-button-icon-size: 1.75rem;
217
+ --rc-button-touch-target-overlap-inline-end: 0.625rem;
218
+ }
219
+
220
+ :where(.rc-theme-material, :host(.rc-theme-material))
221
+ rc-button.rc-button--extra-small.rc-button--wide[icon-only] {
222
+ --rc-button-icon-size: 2.5rem;
223
+ }
224
+
225
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button.rc-button--narrow[icon-only] {
226
+ --rc-button-icon-size: 2rem;
227
+ --rc-button-touch-target-overlap-inline-end: 0.5rem;
228
+ }
229
+
230
+ :where(.rc-theme-material, :host(.rc-theme-material)) rc-button.rc-button--wide[icon-only] {
231
+ --rc-button-icon-size: 3.25rem;
232
+ }
233
+
234
+ :where(.rc-theme-material, :host(.rc-theme-material))
235
+ rc-button.rc-button--medium.rc-button--narrow[icon-only] {
236
+ --rc-button-icon-size: 3rem;
237
+ /* Already meets the 3rem default touch target on its own; the bare
238
+ .rc-button--narrow[icon-only] rule's overlap default still matches
239
+ here too (class selectors don't exclude each other), so it needs an
240
+ explicit reset. */
241
+ --rc-button-touch-target-overlap-inline-end: 0px;
242
+ }
243
+
244
+ :where(.rc-theme-material, :host(.rc-theme-material))
245
+ rc-button.rc-button--medium.rc-button--wide[icon-only] {
246
+ --rc-button-icon-size: 4.5rem;
247
+ }
248
+
249
+ :where(.rc-theme-material, :host(.rc-theme-material))
250
+ rc-button.rc-button--large.rc-button--narrow[icon-only] {
251
+ --rc-button-icon-size: 4rem;
252
+ --rc-button-touch-target-overlap-inline-end: 0px;
253
+ }
254
+
255
+ :where(.rc-theme-material, :host(.rc-theme-material))
256
+ rc-button.rc-button--large.rc-button--wide[icon-only] {
257
+ --rc-button-icon-size: 8rem;
258
+ }
259
+
260
+ :where(.rc-theme-material, :host(.rc-theme-material))
261
+ rc-button.rc-button--extra-large.rc-button--narrow[icon-only] {
262
+ --rc-button-icon-size: 6.5rem;
263
+ --rc-button-touch-target-overlap-inline-end: 0px;
264
+ }
265
+
266
+ :where(.rc-theme-material, :host(.rc-theme-material))
267
+ rc-button.rc-button--extra-large.rc-button--wide[icon-only] {
268
+ --rc-button-icon-size: 11.5rem;
269
+ }
270
+ }