mtrl 0.5.2 → 0.5.3
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/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/package.json +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -2
- package/src/styles/abstract/_base.scss +2 -0
- package/src/styles/abstract/_config.scss +28 -0
- package/src/styles/abstract/_functions.scss +124 -0
- package/src/styles/abstract/_mixins.scss +401 -0
- package/src/styles/abstract/_theme.scss +269 -0
- package/src/styles/abstract/_variables.scss +338 -0
- package/src/styles/base/_reset.scss +86 -0
- package/src/styles/base/_typography.scss +155 -0
- package/src/styles/components/_badge.scss +183 -0
- package/src/styles/components/_bottom-app-bar.scss +103 -0
- package/src/styles/components/_button.scss +756 -0
- package/src/styles/components/_card.scss +401 -0
- package/src/styles/components/_carousel.scss +645 -0
- package/src/styles/components/_checkbox.scss +231 -0
- package/src/styles/components/_chips.scss +639 -0
- package/src/styles/components/_datepicker.scss +358 -0
- package/src/styles/components/_dialog.scss +259 -0
- package/src/styles/components/_divider.scss +57 -0
- package/src/styles/components/_extended-fab.scss +309 -0
- package/src/styles/components/_fab.scss +244 -0
- package/src/styles/components/_list.scss +774 -0
- package/src/styles/components/_menu.scss +245 -0
- package/src/styles/components/_navigation-mobile.scss +244 -0
- package/src/styles/components/_navigation-system.scss +151 -0
- package/src/styles/components/_navigation.scss +407 -0
- package/src/styles/components/_progress.scss +101 -0
- package/src/styles/components/_radios.scss +187 -0
- package/src/styles/components/_search.scss +306 -0
- package/src/styles/components/_segmented-button.scss +227 -0
- package/src/styles/components/_select.scss +274 -0
- package/src/styles/components/_sheet.scss +236 -0
- package/src/styles/components/_slider.scss +264 -0
- package/src/styles/components/_snackbar.scss +211 -0
- package/src/styles/components/_switch.scss +305 -0
- package/src/styles/components/_tabs.scss +421 -0
- package/src/styles/components/_textfield.scss +1024 -0
- package/src/styles/components/_timepicker.scss +451 -0
- package/src/styles/components/_tooltip.scss +241 -0
- package/src/styles/components/_top-app-bar.scss +225 -0
- package/src/styles/main.scss +129 -0
- package/src/styles/themes/_autumn.scss +105 -0
- package/src/styles/themes/_base-theme.scss +85 -0
- package/src/styles/themes/_baseline.scss +173 -0
- package/src/styles/themes/_bluekhaki.scss +125 -0
- package/src/styles/themes/_brownbeige.scss +125 -0
- package/src/styles/themes/_browngreen.scss +125 -0
- package/src/styles/themes/_forest.scss +77 -0
- package/src/styles/themes/_greenbeige.scss +125 -0
- package/src/styles/themes/_index.scss +19 -0
- package/src/styles/themes/_material.scss +125 -0
- package/src/styles/themes/_ocean.scss +77 -0
- package/src/styles/themes/_sageivory.scss +125 -0
- package/src/styles/themes/_spring.scss +77 -0
- package/src/styles/themes/_summer.scss +87 -0
- package/src/styles/themes/_sunset.scss +60 -0
- package/src/styles/themes/_tealcaramel.scss +125 -0
- package/src/styles/themes/_winter.scss +77 -0
- package/src/styles/utilities/_colors.scss +154 -0
- package/src/styles/utilities/_flexbox.scss +194 -0
- package/src/styles/utilities/_layout.scss +665 -0
- package/src/styles/utilities/_ripple.scss +79 -0
- package/src/styles/utilities/_spacing.scss +139 -0
- package/src/styles/utilities/_typography.scss +178 -0
- package/src/styles/utilities/_visibility.scss +142 -0
|
@@ -0,0 +1,756 @@
|
|
|
1
|
+
// src/components/button/_styles.scss
|
|
2
|
+
@use '../../styles/abstract/base' as base;
|
|
3
|
+
@use '../../styles/abstract/variables' as v;
|
|
4
|
+
@use '../../styles/abstract/functions' as f;
|
|
5
|
+
@use '../../styles/abstract/mixins' as m;
|
|
6
|
+
@use '../../styles/abstract/theme' as t;
|
|
7
|
+
|
|
8
|
+
$component: '#{base.$prefix}-button';
|
|
9
|
+
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// BUTTON COMPONENT STYLES
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Supports:
|
|
14
|
+
// - Multiple variants (filled, elevated, tonal, outlined, text)
|
|
15
|
+
// - Icon integration
|
|
16
|
+
// - Progress indicator integration
|
|
17
|
+
// - Circular/icon-only buttons
|
|
18
|
+
// - Ripple effects
|
|
19
|
+
// - State layers
|
|
20
|
+
// - Accessibility focus indicators
|
|
21
|
+
// =============================================================================
|
|
22
|
+
|
|
23
|
+
.#{$component} {
|
|
24
|
+
// Base styles
|
|
25
|
+
position: relative;
|
|
26
|
+
display: inline-flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
min-width: v.button('min-width');
|
|
30
|
+
height: v.button('height');
|
|
31
|
+
padding: 0 v.button('padding-horizontal');
|
|
32
|
+
border: none;
|
|
33
|
+
border-radius: v.button('border-radius');
|
|
34
|
+
background-color: transparent;
|
|
35
|
+
color: inherit;
|
|
36
|
+
font: inherit;
|
|
37
|
+
text-decoration: none;
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
user-select: none;
|
|
40
|
+
vertical-align: middle;
|
|
41
|
+
appearance: none;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
will-change: border-radius, transform;
|
|
44
|
+
|
|
45
|
+
// Typography
|
|
46
|
+
@include m.typography('label-large');
|
|
47
|
+
|
|
48
|
+
// Default to round shape (pill-shaped)
|
|
49
|
+
border-radius: v.button('border-radius');
|
|
50
|
+
|
|
51
|
+
// Explicitly apply fast transition to border-radius
|
|
52
|
+
transition:
|
|
53
|
+
background-color v.motion('duration-short2') v.motion('easing-standard'),
|
|
54
|
+
color v.motion('duration-short2') v.motion('easing-standard'),
|
|
55
|
+
box-shadow v.motion('duration-short2') v.motion('easing-standard'),
|
|
56
|
+
border-radius v.motion('duration-short1') v.motion('easing-standard-accelerate'),
|
|
57
|
+
transform v.motion('duration-short1') v.motion('easing-standard-accelerate');
|
|
58
|
+
|
|
59
|
+
// Focus styles
|
|
60
|
+
&:focus {
|
|
61
|
+
outline: none;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&:focus-visible {
|
|
65
|
+
outline: 2px solid t.color('outline');
|
|
66
|
+
outline-offset: 2px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Interactive states
|
|
70
|
+
&:disabled {
|
|
71
|
+
pointer-events: none;
|
|
72
|
+
color: t.alpha('surface', 0.38);
|
|
73
|
+
background-color: t.alpha('surface', 0.12);
|
|
74
|
+
|
|
75
|
+
.#{$component}-icon {
|
|
76
|
+
color: t.alpha('surface', 0.38);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// State layer for ripple effect
|
|
81
|
+
&::before {
|
|
82
|
+
content: '';
|
|
83
|
+
position: absolute;
|
|
84
|
+
top: 0;
|
|
85
|
+
left: 0;
|
|
86
|
+
right: 0;
|
|
87
|
+
bottom: 0;
|
|
88
|
+
background-color: currentColor;
|
|
89
|
+
opacity: 0;
|
|
90
|
+
pointer-events: none;
|
|
91
|
+
transition: opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Ensure proper layout with icons
|
|
95
|
+
&-icon {
|
|
96
|
+
display: inline-flex;
|
|
97
|
+
align-items: center;
|
|
98
|
+
justify-content: center;
|
|
99
|
+
width: 22px;
|
|
100
|
+
height: 22px;
|
|
101
|
+
|
|
102
|
+
svg {
|
|
103
|
+
width: 22px;
|
|
104
|
+
height: 22px;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
+ .#{$component}-text {
|
|
108
|
+
margin-left: 8px;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Progress element styling
|
|
113
|
+
&-progress {
|
|
114
|
+
display: inline-flex;
|
|
115
|
+
align-items: center;
|
|
116
|
+
justify-content: center;
|
|
117
|
+
margin-inline-end: 8px;
|
|
118
|
+
width: 20px;
|
|
119
|
+
height: 20px;
|
|
120
|
+
|
|
121
|
+
// When it's the mtrl-progress element itself
|
|
122
|
+
&.#{base.$prefix}-progress {
|
|
123
|
+
// Reset progress default size since we're setting it here
|
|
124
|
+
width: 20px;
|
|
125
|
+
height: 20px;
|
|
126
|
+
|
|
127
|
+
&-canvas {
|
|
128
|
+
color: currentColor;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// In text-only buttons (no icon), progress acts like an icon
|
|
133
|
+
&:first-child {
|
|
134
|
+
margin-inline-start: 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// When following a visible icon, add left margin too
|
|
138
|
+
.#{$component}-icon:not([style*="display: none"]) + & {
|
|
139
|
+
margin-inline-start: 4px;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
&-text {
|
|
144
|
+
// Text truncation for long button labels
|
|
145
|
+
@include m.truncate;
|
|
146
|
+
|
|
147
|
+
.#{$component}--icon-only & {
|
|
148
|
+
@include m.visually-hidden;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Circular buttons
|
|
153
|
+
&--circular {
|
|
154
|
+
flex: none !important;
|
|
155
|
+
border-radius: 50%;
|
|
156
|
+
padding: 8px;
|
|
157
|
+
min-width: unset;
|
|
158
|
+
width: 40px !important ;
|
|
159
|
+
height: 40px;
|
|
160
|
+
display: inline-flex;
|
|
161
|
+
align-items: center;
|
|
162
|
+
justify-content: center;
|
|
163
|
+
|
|
164
|
+
// Material Design 3 Accessibility Requirement:
|
|
165
|
+
// Icon buttons must have a minimum touch target of 48x48dp
|
|
166
|
+
// even when their visual size appears smaller
|
|
167
|
+
|
|
168
|
+
// Circular buttons should always remain circular when pressed
|
|
169
|
+
&:active,
|
|
170
|
+
&.#{$component}--active {
|
|
171
|
+
border-radius: 50%;
|
|
172
|
+
&.#{$component}--square {
|
|
173
|
+
border-radius: 12px !important;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
&.#{$component}--square {
|
|
178
|
+
border-radius: 12px;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Size-specific circular button dimensions
|
|
182
|
+
&.#{$component}--xs {
|
|
183
|
+
// Ensure minimum 48dp touch target for accessibility
|
|
184
|
+
width: v.button('height-xs');
|
|
185
|
+
height: v.button('height-xs');
|
|
186
|
+
padding: 8px;
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
// Adjust icon size to maintain visual proportions
|
|
190
|
+
.#{$component}-icon {
|
|
191
|
+
width: v.button('icon-size-xs');
|
|
192
|
+
height: v.button('icon-size-xs');
|
|
193
|
+
|
|
194
|
+
svg {
|
|
195
|
+
width: v.button('icon-size-xs');
|
|
196
|
+
height: v.button('icon-size-xs');
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
&.#{$component}--s {
|
|
204
|
+
// Ensure minimum 48dp touch target for accessibility
|
|
205
|
+
width: v.button('height-s');
|
|
206
|
+
height: v.button('height-s');
|
|
207
|
+
padding: 8px;
|
|
208
|
+
|
|
209
|
+
// Standard icon size for S
|
|
210
|
+
.#{$component}-icon {
|
|
211
|
+
width: v.button('icon-size-s');
|
|
212
|
+
height: v.button('icon-size-s');
|
|
213
|
+
|
|
214
|
+
svg {
|
|
215
|
+
width: v.button('icon-size-s');
|
|
216
|
+
height: v.button('icon-size-s');
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
&.#{$component}--m {
|
|
222
|
+
width: v.button('height-m');
|
|
223
|
+
height: v.button('height-m');
|
|
224
|
+
padding: 12px;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
&.#{$component}--l {
|
|
228
|
+
width: v.button('height-l');
|
|
229
|
+
height: v.button('height-l');
|
|
230
|
+
padding: 20px;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
&.#{$component}--xl {
|
|
234
|
+
width: v.button('height-xl');
|
|
235
|
+
height: v.button('height-xl');
|
|
236
|
+
padding: 32px;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.#{$component}-icon {
|
|
240
|
+
margin: 0;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Hide text in circular buttons
|
|
244
|
+
.#{$component}-text {
|
|
245
|
+
display: none;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Progress in circular buttons
|
|
249
|
+
.#{$component}-progress {
|
|
250
|
+
margin: 0;
|
|
251
|
+
|
|
252
|
+
&.#{base.$prefix}-progress {
|
|
253
|
+
width: 24px;
|
|
254
|
+
height: 24px;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Override padding adjustments for circular buttons
|
|
259
|
+
&.#{$component}--progress {
|
|
260
|
+
padding: 0 !important;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
&--icon {
|
|
265
|
+
padding: 0 v.button('padding-horizontal') 0 calc(v.button('padding-horizontal') / 2 + 4px);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Shape variants
|
|
269
|
+
&--round {
|
|
270
|
+
// Default round shape - already applied in base styles
|
|
271
|
+
// Sizes M, L, XL get special pill-shaped radius
|
|
272
|
+
&.#{$component}--m {
|
|
273
|
+
border-radius: calc(v.button('height-m') / 2);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
&.#{$component}--l {
|
|
277
|
+
border-radius: calc(v.button('height-l') / 2);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
&.#{$component}--xl {
|
|
281
|
+
border-radius: calc(v.button('height-xl') / 2);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
&--square {
|
|
286
|
+
// Square shape with size-specific border radius
|
|
287
|
+
&.#{$component}--xs,
|
|
288
|
+
&.#{$component}--s {
|
|
289
|
+
border-radius: f.get-shape('medium'); // 12dp
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
&.#{$component}--m {
|
|
293
|
+
border-radius: f.get-shape('large'); // 16dp
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
&.#{$component}--l,
|
|
297
|
+
&.#{$component}--xl {
|
|
298
|
+
border-radius: f.get-shape('extra-large'); // 28dp
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Pressed state for square buttons - no morphing needed
|
|
302
|
+
&:active,
|
|
303
|
+
&.#{$component}--active {
|
|
304
|
+
// Square buttons maintain their border radius when pressed
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Size variants
|
|
309
|
+
&--xs {
|
|
310
|
+
height: v.button('height-xs');
|
|
311
|
+
padding: 0 v.button('padding-xs');
|
|
312
|
+
min-width: 48px;
|
|
313
|
+
|
|
314
|
+
&.#{$component}--icon {
|
|
315
|
+
padding: 0 v.button('padding-xs') 0 calc(v.button('padding-xs') / 2 + 4px);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
&.#{$component}--progress {
|
|
319
|
+
padding: 0 v.button('padding-xs') 0 calc(v.button('padding-xs') / 2 + 4px);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
&.#{$component}--text {
|
|
323
|
+
padding: 0 calc(v.button('padding-xs') - 4px);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.#{$component}-icon {
|
|
327
|
+
width: v.button('icon-size-xs');
|
|
328
|
+
height: v.button('icon-size-xs');
|
|
329
|
+
|
|
330
|
+
svg {
|
|
331
|
+
width: v.button('icon-size-xs');
|
|
332
|
+
height: v.button('icon-size-xs');
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.#{$component}-progress {
|
|
337
|
+
width: v.button('icon-size-xs');
|
|
338
|
+
height: v.button('icon-size-xs');
|
|
339
|
+
|
|
340
|
+
&.#{base.$prefix}-progress {
|
|
341
|
+
width: v.button('icon-size-xs');
|
|
342
|
+
height: v.button('icon-size-xs');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
&--s {
|
|
348
|
+
// S is the default size, already defined in base styles
|
|
349
|
+
// Explicitly setting them here for clarity
|
|
350
|
+
height: v.button('height-s');
|
|
351
|
+
padding: 0 v.button('padding-s');
|
|
352
|
+
|
|
353
|
+
&.#{$component}--icon {
|
|
354
|
+
padding: 0 v.button('padding-s') 0 calc(v.button('padding-s') / 2 + 4px);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
&.#{$component}--progress {
|
|
358
|
+
padding: 0 v.button('padding-s') 0 calc(v.button('padding-s') / 2 + 4px);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
&.#{$component}--text {
|
|
362
|
+
padding: 0 v.button('padding-horizontal-small');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
&--m {
|
|
367
|
+
height: v.button('height-m');
|
|
368
|
+
padding: 0 v.button('padding-m');
|
|
369
|
+
min-width: 80px;
|
|
370
|
+
|
|
371
|
+
&.#{$component}--icon {
|
|
372
|
+
padding: 0 v.button('padding-m') 0 calc(v.button('padding-m') / 2 + 8px);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
&.#{$component}--progress {
|
|
376
|
+
padding: 0 v.button('padding-m') 0 calc(v.button('padding-m') / 2 + 8px);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
&.#{$component}--text {
|
|
380
|
+
padding: 0 calc(v.button('padding-m') - 4px);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
.#{$component}-icon {
|
|
384
|
+
width: v.button('icon-size-m');
|
|
385
|
+
height: v.button('icon-size-m');
|
|
386
|
+
|
|
387
|
+
svg {
|
|
388
|
+
width: v.button('icon-size-m');
|
|
389
|
+
height: v.button('icon-size-m');
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.#{$component}-progress {
|
|
394
|
+
width: v.button('icon-size-m');
|
|
395
|
+
height: v.button('icon-size-m');
|
|
396
|
+
|
|
397
|
+
&.#{base.$prefix}-progress {
|
|
398
|
+
width: v.button('icon-size-m');
|
|
399
|
+
height: v.button('icon-size-m');
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
&--l {
|
|
405
|
+
height: v.button('height-l');
|
|
406
|
+
padding: 0 v.button('padding-l');
|
|
407
|
+
min-width: 120px;
|
|
408
|
+
|
|
409
|
+
// Use larger typography for L and XL sizes
|
|
410
|
+
@include m.typography('title-large');
|
|
411
|
+
|
|
412
|
+
&.#{$component}--icon {
|
|
413
|
+
padding: 0 v.button('padding-l') 0 calc(v.button('padding-l') / 2 + 12px);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
&.#{$component}--progress {
|
|
417
|
+
padding: 0 v.button('padding-l') 0 calc(v.button('padding-l') / 2 + 12px);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
&.#{$component}--text {
|
|
421
|
+
padding: 0 calc(v.button('padding-l') - 8px);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.#{$component}-icon {
|
|
425
|
+
width: v.button('icon-size-l');
|
|
426
|
+
height: v.button('icon-size-l');
|
|
427
|
+
|
|
428
|
+
svg {
|
|
429
|
+
width: v.button('icon-size-l');
|
|
430
|
+
height: v.button('icon-size-l');
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
+ .#{$component}-text {
|
|
434
|
+
margin-left: 16px;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.#{$component}-progress {
|
|
439
|
+
width: v.button('icon-size-l');
|
|
440
|
+
height: v.button('icon-size-l');
|
|
441
|
+
margin-inline-end: 16px;
|
|
442
|
+
|
|
443
|
+
&.#{base.$prefix}-progress {
|
|
444
|
+
width: v.button('icon-size-l');
|
|
445
|
+
height: v.button('icon-size-l');
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
&--xl {
|
|
451
|
+
height: v.button('height-xl');
|
|
452
|
+
padding: 0 v.button('padding-xl');
|
|
453
|
+
min-width: 160px;
|
|
454
|
+
|
|
455
|
+
// Use larger typography for L and XL sizes
|
|
456
|
+
@include m.typography('headline-medium');
|
|
457
|
+
|
|
458
|
+
&.#{$component}--icon {
|
|
459
|
+
padding: 0 v.button('padding-xl') 0 calc(v.button('padding-xl') / 2 + 16px);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
&.#{$component}--progress {
|
|
463
|
+
padding: 0 v.button('padding-xl') 0 calc(v.button('padding-xl') / 2 + 16px);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
&.#{$component}--text {
|
|
467
|
+
padding: 0 calc(v.button('padding-xl') - 12px);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
.#{$component}-icon {
|
|
471
|
+
width: v.button('icon-size-xl');
|
|
472
|
+
height: v.button('icon-size-xl');
|
|
473
|
+
|
|
474
|
+
svg {
|
|
475
|
+
width: v.button('icon-size-xl');
|
|
476
|
+
height: v.button('icon-size-xl');
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
+ .#{$component}-text {
|
|
480
|
+
margin-left: 24px;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
.#{$component}-progress {
|
|
485
|
+
width: v.button('icon-size-xl');
|
|
486
|
+
height: v.button('icon-size-xl');
|
|
487
|
+
margin-inline-end: 24px;
|
|
488
|
+
|
|
489
|
+
&.#{base.$prefix}-progress {
|
|
490
|
+
width: v.button('icon-size-xl');
|
|
491
|
+
height: v.button('icon-size-xl');
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
&--active {
|
|
497
|
+
// Common active state styling for all variants
|
|
498
|
+
box-shadow: none;
|
|
499
|
+
|
|
500
|
+
// Per MD3, buttons have a significantly more rectangular appearance when pressed
|
|
501
|
+
// Default to small shape
|
|
502
|
+
border-radius: f.get-shape('small');
|
|
503
|
+
|
|
504
|
+
// ARIA attribute to indicate active state for accessibility
|
|
505
|
+
&[aria-expanded="true"] {
|
|
506
|
+
// For compatibility with ARIA
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Size-specific active state border radius based on MD3 specs
|
|
511
|
+
// Only applies to round shape buttons - square buttons maintain their radius
|
|
512
|
+
&--round {
|
|
513
|
+
&.#{$component}--xs,
|
|
514
|
+
&.#{$component}--s {
|
|
515
|
+
&:active,
|
|
516
|
+
&.#{$component}--active {
|
|
517
|
+
// XS and S sizes use 12dp radius when pressed
|
|
518
|
+
border-radius: f.get-shape('medium');
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
&.#{$component}--m {
|
|
523
|
+
&:active,
|
|
524
|
+
&.#{$component}--active {
|
|
525
|
+
// M size uses 16dp radius when pressed
|
|
526
|
+
border-radius: f.get-shape('large');
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
&.#{$component}--l,
|
|
531
|
+
&.#{$component}--xl {
|
|
532
|
+
&:active,
|
|
533
|
+
&.#{$component}--active {
|
|
534
|
+
// L and XL sizes use 28dp radius when pressed
|
|
535
|
+
border-radius: f.get-shape('extra-large');
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// FILLED BUTTON
|
|
541
|
+
&--filled {
|
|
542
|
+
background-color: t.color('primary');
|
|
543
|
+
color: t.color('on-primary');
|
|
544
|
+
|
|
545
|
+
// Progress inherits the on-primary color
|
|
546
|
+
.#{base.$prefix}-progress-canvas {
|
|
547
|
+
color: t.color('on-primary');
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
&:hover {
|
|
551
|
+
@include m.state-layer(t.color('on-primary'), 'hover');
|
|
552
|
+
// According to MD3, filled buttons DO have elevation on hover
|
|
553
|
+
@include m.elevation(1);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
&:active,
|
|
557
|
+
&.#{$component}--active {
|
|
558
|
+
@include m.state-layer(t.color('on-primary'), 'pressed');
|
|
559
|
+
// MD3 reduces elevation on press
|
|
560
|
+
@include m.elevation(0);
|
|
561
|
+
}
|
|
562
|
+
&:disabled {
|
|
563
|
+
@include m.elevation(0);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// ELEVATED BUTTON
|
|
568
|
+
&--elevated {
|
|
569
|
+
background-color: t.color('surface-container-low');
|
|
570
|
+
color: t.color('primary');
|
|
571
|
+
@include m.elevation(1);
|
|
572
|
+
|
|
573
|
+
// Progress uses primary color
|
|
574
|
+
.#{base.$prefix}-progress-canvas {
|
|
575
|
+
color: t.color('primary');
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
&:hover {
|
|
579
|
+
@include m.state-layer(t.color('primary'), 'hover');
|
|
580
|
+
// MD3 increases elevation on hover
|
|
581
|
+
@include m.elevation(2);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
&:active,
|
|
585
|
+
&.#{$component}--active {
|
|
586
|
+
@include m.state-layer(t.color('primary'), 'pressed');
|
|
587
|
+
// MD3 reduces elevation on press, but not completely removed
|
|
588
|
+
@include m.elevation(1);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
&:disabled {
|
|
592
|
+
@include m.elevation(0);
|
|
593
|
+
box-shadow: none;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
// Handle icon color in elevated button
|
|
597
|
+
.#{$component}-icon {
|
|
598
|
+
color: t.color('primary');
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// TONAL BUTTON
|
|
603
|
+
&--tonal {
|
|
604
|
+
background-color: t.color('secondary-container');
|
|
605
|
+
color: t.color('on-secondary-container');
|
|
606
|
+
// MD3 tonal buttons have a subtle initial elevation
|
|
607
|
+
@include m.elevation(0);
|
|
608
|
+
|
|
609
|
+
// Progress uses on-secondary-container color
|
|
610
|
+
.#{base.$prefix}-progress-canvas {
|
|
611
|
+
color: t.color('on-secondary-container');
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
&:hover {
|
|
615
|
+
@include m.state-layer(t.color('on-secondary-container'), 'hover');
|
|
616
|
+
// MD3 tonal buttons have elevation on hover
|
|
617
|
+
@include m.elevation(1);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
&:active,
|
|
621
|
+
&.#{$component}--active {
|
|
622
|
+
@include m.state-layer(t.color('on-secondary-container'), 'pressed');
|
|
623
|
+
// MD3 reduces elevation on press
|
|
624
|
+
@include m.elevation(0);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
&:disabled {
|
|
628
|
+
box-shadow: none;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// OUTLINED BUTTON
|
|
633
|
+
&--outlined {
|
|
634
|
+
border: 1px solid rgba(var(--mtrl-sys-color-outline-rgb), 0.38);
|
|
635
|
+
color: t.color('primary');
|
|
636
|
+
|
|
637
|
+
// Progress uses primary color
|
|
638
|
+
.#{base.$prefix}-progress-canvas {
|
|
639
|
+
color: t.color('primary');
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
&:hover {
|
|
643
|
+
@include m.state-layer(t.color('primary'), 'hover');
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
&:active,
|
|
647
|
+
&.#{$component}--active {
|
|
648
|
+
@include m.state-layer(t.color('primary'), 'pressed');
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
&:disabled {
|
|
652
|
+
border: 1px solid t.alpha('outline', 0.12);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// TEXT BUTTON
|
|
657
|
+
&--text {
|
|
658
|
+
min-width: v.button('min-width');
|
|
659
|
+
padding: 0 v.button('padding-horizontal-small');
|
|
660
|
+
color: t.color('primary');
|
|
661
|
+
|
|
662
|
+
// Progress uses primary color
|
|
663
|
+
.#{base.$prefix}-progress-canvas {
|
|
664
|
+
color: t.color('primary');
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
&:hover {
|
|
668
|
+
@include m.state-layer(t.color('primary'), 'hover');
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
&:active,
|
|
672
|
+
&.#{$component}--active {
|
|
673
|
+
@include m.state-layer(t.color('primary'), 'pressed');
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
&:disabled {
|
|
677
|
+
background-color: transparent;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// Special case for icon-only buttons
|
|
682
|
+
&--icon-only {
|
|
683
|
+
min-width: v.button('height');
|
|
684
|
+
width: v.button('height');
|
|
685
|
+
padding: 0;
|
|
686
|
+
border-radius: 50%;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// When button has progress showing
|
|
690
|
+
&--progress {
|
|
691
|
+
// Reduce left padding when progress is showing, similar to icon buttons
|
|
692
|
+
padding: 0 v.button('padding-horizontal') 0 calc(v.button('padding-horizontal') / 2 + 4px);
|
|
693
|
+
|
|
694
|
+
// Per MD3, round buttons have a significantly more rectangular appearance when progress (active) is showing
|
|
695
|
+
// Square buttons maintain their standard border radius
|
|
696
|
+
&.#{$component}--round {
|
|
697
|
+
&.#{$component}--xs,
|
|
698
|
+
&.#{$component}--s {
|
|
699
|
+
border-radius: f.get-shape('medium') !important;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
&.#{$component}--m {
|
|
703
|
+
border-radius: f.get-shape('large') !important;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
&.#{$component}--l,
|
|
707
|
+
&.#{$component}--xl {
|
|
708
|
+
border-radius: f.get-shape('extra-large') !important;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// If button also has an icon, use even less left padding
|
|
713
|
+
&.#{$component}--icon {
|
|
714
|
+
padding: 0 v.button('padding-horizontal') 0 calc(v.button('padding-horizontal') / 2);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// FIX: Disabled on dark theme (recommandations do not work as expected)
|
|
720
|
+
body[data-theme-mode=dark] {
|
|
721
|
+
// Interactive states
|
|
722
|
+
.#{$component} {
|
|
723
|
+
&:disabled {
|
|
724
|
+
color: t.alpha('on-surface-dim', 0.38);
|
|
725
|
+
background-color: t.alpha('surface-dim', 0.12);
|
|
726
|
+
|
|
727
|
+
.#{$component}-text {
|
|
728
|
+
opacity: 0.38;
|
|
729
|
+
}
|
|
730
|
+
.#{$component}-icon {
|
|
731
|
+
opacity: 0.38;
|
|
732
|
+
color: t.alpha('on-surface-dim', 0.12);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// Add loading state styles
|
|
739
|
+
.#{$component} {
|
|
740
|
+
// Loading state animations
|
|
741
|
+
&[disabled] {
|
|
742
|
+
&.#{$component}--progress {
|
|
743
|
+
.#{$component}-progress {
|
|
744
|
+
// Ensure progress is visible in disabled state
|
|
745
|
+
opacity: 0.7;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// Smooth transitions when showing/hiding progress
|
|
751
|
+
.#{$component}-progress {
|
|
752
|
+
&.#{base.$prefix}-progress {
|
|
753
|
+
transition: opacity v.motion('duration-short2') v.motion('easing-standard');
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|