@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
package/native.css ADDED
@@ -0,0 +1,258 @@
1
+ @layer rc-base, rc-theme-material.defaults, rc-theme-material.bridge, rc-theme-material.native, rc-theme-material.components, rc-theme-material.css-components,
2
+ rc-theme-material.overrides;
3
+
4
+ /* Import defaults.css and bridge.css first when theme tokens are desired. */
5
+ @layer rc-theme-material.native {
6
+ /*
7
+ * Native styles stop at native controls that are part of an RC-owned
8
+ * presentation, and at subtrees the consumer opts out with
9
+ * data-rc-native="off". The exclusions are element-level ownership
10
+ * contracts rather than host boundaries: ordinary controls remain themed in
11
+ * layout components such as rc-toolbar, rc-card, rc-dialog, and rc-popover.
12
+ * An @scope limit would read better, but Firefox drops a :host() scope root
13
+ * that has one.
14
+ */
15
+ :where(.rc-theme-material:not([data-rc-native='off']))
16
+ :where(button, input, select, textarea, progress):not(
17
+ :where(
18
+ [data-rc-native='off'],
19
+ [data-rc-native='off'] *,
20
+ rc-button > :is(button, a[href]),
21
+ rc-chip > :is(button, a[href], label),
22
+ rc-chip > label > input:is([type='checkbox'], [type='radio']),
23
+ rc-combobox > select,
24
+ rc-fab > button,
25
+ rc-fab-menu > [slot='trigger'],
26
+ rc-field > :is(input, select, textarea),
27
+ rc-field > [data-rc-field-control] > :is(input, select, textarea),
28
+ rc-field > fieldset > :is(input, select, textarea),
29
+ rc-listbox > select,
30
+ rc-markdown-editor > textarea,
31
+ rc-navigation-rail > [slot='toggle'],
32
+ rc-menu-button > [slot='trigger'],
33
+ rc-progress > progress,
34
+ rc-range-slider > input[type='range'],
35
+ rc-search-bar > input[type='search'],
36
+ rc-segmented-button > fieldset input[type='radio'],
37
+ rc-select > select,
38
+ rc-slider > input[type='range'],
39
+ rc-switch > input[type='checkbox'],
40
+ rc-textarea > textarea,
41
+ rc-toolbar > button,
42
+ rc-transfer-list > select
43
+ )
44
+ ),
45
+ :host(:not([data-rc-native='off']).rc-theme-material)
46
+ :where(button, input, select, textarea, progress):not(
47
+ :where(
48
+ [data-rc-native='off'],
49
+ [data-rc-native='off'] *,
50
+ rc-button > :is(button, a[href]),
51
+ rc-chip > :is(button, a[href], label),
52
+ rc-chip > label > input:is([type='checkbox'], [type='radio']),
53
+ rc-combobox > select,
54
+ rc-fab > button,
55
+ rc-fab-menu > [slot='trigger'],
56
+ rc-field > :is(input, select, textarea),
57
+ rc-field > [data-rc-field-control] > :is(input, select, textarea),
58
+ rc-field > fieldset > :is(input, select, textarea),
59
+ rc-listbox > select,
60
+ rc-markdown-editor > textarea,
61
+ rc-navigation-rail > [slot='toggle'],
62
+ rc-menu-button > [slot='trigger'],
63
+ rc-progress > progress,
64
+ rc-range-slider > input[type='range'],
65
+ rc-search-bar > input[type='search'],
66
+ rc-segmented-button > fieldset input[type='radio'],
67
+ rc-select > select,
68
+ rc-slider > input[type='range'],
69
+ rc-switch > input[type='checkbox'],
70
+ rc-textarea > textarea,
71
+ rc-toolbar > button,
72
+ rc-transfer-list > select
73
+ )
74
+ ) {
75
+ &:where(button):not(:where(.rc-button, .rc-chip)) {
76
+ box-sizing: border-box;
77
+ display: inline-flex;
78
+ align-items: center;
79
+ justify-content: center;
80
+ gap: var(--rc-button-gap, var(--rc-control-gap, 0.5rem));
81
+ min-block-size: var(--rc-button-block-size, var(--rc-control-block-size, 2.5rem));
82
+ padding-block: var(--rc-button-padding-block, var(--rc-control-padding-block, 0.5rem));
83
+ padding-inline: var(--rc-button-padding-inline, var(--rc-control-padding-inline, 1rem));
84
+ border: var(--rc-button-border, var(--rc-border, 1px solid ButtonBorder));
85
+ border-radius: var(--rc-button-radius, var(--rc-control-radius, 999px));
86
+ background: var(--rc-button-bg, ButtonFace);
87
+ color: var(--rc-button-color, var(--rc-button-text, ButtonText));
88
+ font-family: var(--rc-font-family, sans-serif);
89
+ font-size: var(--rc-font-size, 1rem);
90
+ font-weight: var(--rc-font-weight, 400);
91
+ line-height: var(--rc-line-height, normal);
92
+ cursor: pointer;
93
+ }
94
+
95
+ &:where(
96
+ input:is(
97
+ [type='text'],
98
+ [type='search'],
99
+ [type='email'],
100
+ [type='url'],
101
+ [type='tel'],
102
+ [type='number'],
103
+ [type='password'],
104
+ :where(:not([type]))
105
+ ),
106
+ select,
107
+ textarea
108
+ ) {
109
+ box-sizing: border-box;
110
+ min-block-size: var(--rc-control-block-size, 2.5rem);
111
+ padding-block: var(--rc-control-padding-block, 0.5rem);
112
+ padding-inline: var(--rc-control-padding-inline, 1rem);
113
+ border: var(--rc-border, 1px solid ButtonBorder);
114
+ border-radius: var(--rc-control-radius, 0.5rem);
115
+ background: var(--rc-field, Field);
116
+ color: var(--rc-field-text, FieldText);
117
+ font-family: var(--rc-font-family, sans-serif);
118
+ font-size: var(--rc-font-size, 1rem);
119
+ font-weight: var(--rc-font-weight, 400);
120
+ line-height: var(--rc-line-height, normal);
121
+ }
122
+
123
+ &:where(select):not(:where(.rc-select)) {
124
+ cursor: pointer;
125
+ }
126
+
127
+ &:not(:where(.rc-button, .rc-chip, .rc-select, .rc-textarea)):focus-visible {
128
+ outline: var(--rc-focus-ring, 2px solid Highlight);
129
+ outline-offset: var(--rc-focus-ring-offset, 2px);
130
+ }
131
+
132
+ &:where(input[type='checkbox'], input[type='radio'], input[type='range']) {
133
+ min-block-size: auto;
134
+ padding: 0;
135
+ accent-color: var(--rc-accent, AccentColor);
136
+ }
137
+
138
+ &:where(input[type='range'], progress) {
139
+ inline-size: 100%;
140
+ }
141
+
142
+ &:where(progress) {
143
+ accent-color: var(--rc-accent, AccentColor);
144
+ }
145
+
146
+ &:not(:where(.rc-button, .rc-chip)):where(:disabled) {
147
+ color: var(--rc-text-disabled, GrayText);
148
+ cursor: not-allowed;
149
+ }
150
+ }
151
+ }
152
+
153
+ /*
154
+ * rc-menu and rc-adaptive-menu install light-DOM structure in rc-base. Native
155
+ * rules intentionally reach their authored controls, so this later layer
156
+ * reasserts the complete row contract after native presentation. The narrow
157
+ * wrapper exclusions above remain necessary for shadow ::slotted ownership.
158
+ */
159
+ @layer rc-theme-material.components {
160
+ :where(.rc-theme-material:not([data-rc-native='off']))
161
+ :where(rc-menu :is([role='menuitem'], [role='menuitemcheckbox'], [role='menuitemradio'])):not(
162
+ :where([data-rc-native='off'], [data-rc-native='off'] *)
163
+ ),
164
+ :host(:not([data-rc-native='off']).rc-theme-material)
165
+ :where(rc-menu :is([role='menuitem'], [role='menuitemcheckbox'], [role='menuitemradio'])):not(
166
+ :where([data-rc-native='off'], [data-rc-native='off'] *)
167
+ ) {
168
+ display: flex;
169
+ gap: var(--rc-menu-item-gap, var(--rc-item-gap, 0.5em));
170
+ min-block-size: var(--rc-menu-item-min-block-size, 0px);
171
+ justify-content: normal;
172
+ padding: var(--rc-menu-item-padding-block, var(--rc-item-padding-block, 0.3em))
173
+ var(--rc-menu-item-padding-inline, var(--rc-item-padding-inline, 0.75em));
174
+ border: none;
175
+ border-radius: 0;
176
+ background: transparent;
177
+ color: inherit;
178
+ font: inherit;
179
+ cursor: default;
180
+ outline: none;
181
+ }
182
+
183
+ :where(.rc-theme-material:not([data-rc-native='off']))
184
+ rc-menu
185
+ :is([role='menuitem'], [role='menuitemcheckbox'], [role='menuitemradio']):hover:not(
186
+ :where([data-rc-native='off'], [data-rc-native='off'] *)
187
+ ),
188
+ :host(:not([data-rc-native='off']).rc-theme-material)
189
+ rc-menu
190
+ :is([role='menuitem'], [role='menuitemcheckbox'], [role='menuitemradio']):hover:not(
191
+ :where([data-rc-native='off'], [data-rc-native='off'] *)
192
+ ) {
193
+ background: var(--rc-menu-hover-bg, color-mix(in srgb, Highlight 8%, transparent));
194
+ color: var(--rc-menu-hover-color, inherit);
195
+ }
196
+
197
+ :where(.rc-theme-material:not([data-rc-native='off']))
198
+ rc-menu
199
+ :is([role='menuitem'], [role='menuitemcheckbox'], [role='menuitemradio'])[data-active]:not(
200
+ :where([data-rc-native='off'], [data-rc-native='off'] *)
201
+ ),
202
+ :host(:not([data-rc-native='off']).rc-theme-material)
203
+ rc-menu
204
+ :is([role='menuitem'], [role='menuitemcheckbox'], [role='menuitemradio'])[data-active]:not(
205
+ :where([data-rc-native='off'], [data-rc-native='off'] *)
206
+ ) {
207
+ background: var(--rc-menu-active-bg, color-mix(in srgb, Highlight 8%, transparent));
208
+ color: var(--rc-menu-active-color, inherit);
209
+ }
210
+
211
+ :where(.rc-theme-material:not([data-rc-native='off']))
212
+ rc-menu
213
+ :is(
214
+ button:disabled,
215
+ [role='menuitem'][aria-disabled='true'],
216
+ [role='menuitemcheckbox'][aria-disabled='true'],
217
+ [role='menuitemradio'][aria-disabled='true']
218
+ ):not(:where([data-rc-native='off'], [data-rc-native='off'] *)),
219
+ :host(:not([data-rc-native='off']).rc-theme-material)
220
+ rc-menu
221
+ :is(
222
+ button:disabled,
223
+ [role='menuitem'][aria-disabled='true'],
224
+ [role='menuitemcheckbox'][aria-disabled='true'],
225
+ [role='menuitemradio'][aria-disabled='true']
226
+ ):not(:where([data-rc-native='off'], [data-rc-native='off'] *)) {
227
+ color: var(--rc-menu-disabled-color, var(--rc-text-disabled, GrayText));
228
+ opacity: var(--rc-menu-disabled-opacity, var(--rc-disabled-opacity, 0.55));
229
+ pointer-events: none;
230
+ }
231
+ }
232
+
233
+ @layer rc-theme-material.overrides {
234
+ :where(.rc-theme-material:not([data-rc-native='off']))
235
+ :where(
236
+ rc-adaptive-menu > [data-rc-action-overflowed] > :is(button, a[href]),
237
+ rc-adaptive-menu > :is(button, a[href])[data-rc-action-overflowed]
238
+ ):not(:where([data-rc-native='off'], [data-rc-native='off'] *)),
239
+ :host(:not([data-rc-native='off']).rc-theme-material)
240
+ :where(
241
+ rc-adaptive-menu > [data-rc-action-overflowed] > :is(button, a[href]),
242
+ rc-adaptive-menu > :is(button, a[href])[data-rc-action-overflowed]
243
+ ):not(:where([data-rc-native='off'], [data-rc-native='off'] *)) {
244
+ display: flex;
245
+ gap: var(--rc-adaptive-menu-item-gap, var(--rc-item-gap, 0.5em));
246
+ min-block-size: var(--rc-adaptive-menu-item-min-block-size, 2.5em);
247
+ padding: var(--rc-adaptive-menu-item-padding-block, var(--rc-item-padding-block, 0.3em))
248
+ var(--rc-adaptive-menu-item-padding-inline, var(--rc-item-padding-inline, 0.75em));
249
+ border: none;
250
+ border-radius: 0;
251
+ background: transparent;
252
+ color: inherit;
253
+ font: inherit;
254
+ text-align: start;
255
+ justify-content: normal;
256
+ text-decoration: none;
257
+ }
258
+ }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.5.0",
6
+ "version": "0.7.0",
7
7
  "description": "Material 3 CSS theme and token bridge for rc-webcomponents.",
8
8
  "repository": {
9
9
  "type": "git",
@@ -22,12 +22,19 @@
22
22
  "./defaults.css": "./defaults.css",
23
23
  "./components.css": "./components.css",
24
24
  "./components/*.css": "./components/*.css",
25
+ "./css-components.css": "./css-components.css",
26
+ "./css-components/*.css": "./css-components/*.css",
27
+ "./native.css": "./native.css",
25
28
  "./state-layer.css": "./state-layer.css",
26
- "./theme.css": "./theme.css"
29
+ "./theme.css": "./theme.css",
30
+ "./DESIGN.md": "./DESIGN.md"
27
31
  },
28
32
  "files": [
29
33
  "*.css",
30
34
  "components",
35
+ "css-components",
36
+ "constraints",
37
+ "DESIGN.md",
31
38
  "README.md"
32
39
  ],
33
40
  "scripts": {
@@ -37,7 +44,19 @@
37
44
  "test:browser:firefox": "vitest --run --project=firefox"
38
45
  },
39
46
  "devDependencies": {
47
+ "@rcarls/rc-accordion": "0.7.0",
48
+ "@rcarls/rc-adaptive-menu": "0.7.0",
49
+ "@rcarls/rc-button": "0.7.0",
50
+ "@rcarls/rc-combobox": "0.7.0",
51
+ "@rcarls/rc-dialog": "0.7.0",
52
+ "@rcarls/rc-disclosure": "0.7.0",
53
+ "@rcarls/rc-field": "0.7.0",
54
+ "@rcarls/rc-list": "0.7.0",
55
+ "@rcarls/rc-menu-button": "0.7.0",
56
+ "@rcarls/rc-popover": "0.7.0",
57
+ "@rcarls/rc-select": "0.7.0",
40
58
  "@vitest/browser-playwright": "4.1.5",
59
+ "lit": "^3.0.0",
41
60
  "playwright": "^1.56.0",
42
61
  "vite": "^7.1.7",
43
62
  "vitest": "^4.0.6"
package/state-layer.css CHANGED
@@ -1,3 +1,6 @@
1
+ @layer rc-base, rc-theme-material.defaults, rc-theme-material.bridge, rc-theme-material.native, rc-theme-material.components, rc-theme-material.css-components,
2
+ rc-theme-material.overrides;
3
+
1
4
  @layer rc-theme-material.components {
2
5
  /*
3
6
  * Material 3 state layers for interactive elements that already own their
@@ -16,7 +19,8 @@
16
19
  background: currentColor;
17
20
  opacity: 0;
18
21
  pointer-events: none;
19
- transition: opacity 150ms var(--md-sys-motion-easing-standard, cubic-bezier(0.4, 0, 0.2, 1));
22
+ transition: opacity var(--rc-motion-effects-duration-fast, 150ms)
23
+ var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));
20
24
  }
21
25
 
22
26
  .rc-state-layer:hover::after {