mtrl 0.5.2 → 0.5.4

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 (80) hide show
  1. package/dist/components/checkbox/api.d.ts +1 -1
  2. package/dist/components/checkbox/types.d.ts +17 -6
  3. package/dist/components/chips/api.d.ts +5 -2
  4. package/dist/components/chips/chip/api.d.ts +1 -1
  5. package/dist/components/chips/config.d.ts +5 -1
  6. package/dist/components/chips/types.d.ts +14 -3
  7. package/dist/components/index.d.ts +1 -0
  8. package/dist/components/select/types.d.ts +21 -3
  9. package/dist/components/switch/types.d.ts +8 -4
  10. package/dist/index.cjs +14 -14
  11. package/dist/index.cjs.map +13 -13
  12. package/dist/index.js +14 -14
  13. package/dist/index.js.map +13 -13
  14. package/dist/package.json +1 -1
  15. package/dist/styles.css +2 -2
  16. package/package.json +4 -2
  17. package/src/styles/abstract/_base.scss +2 -0
  18. package/src/styles/abstract/_config.scss +28 -0
  19. package/src/styles/abstract/_functions.scss +124 -0
  20. package/src/styles/abstract/_mixins.scss +401 -0
  21. package/src/styles/abstract/_theme.scss +269 -0
  22. package/src/styles/abstract/_variables.scss +338 -0
  23. package/src/styles/base/_reset.scss +86 -0
  24. package/src/styles/base/_typography.scss +155 -0
  25. package/src/styles/components/_badge.scss +183 -0
  26. package/src/styles/components/_bottom-app-bar.scss +103 -0
  27. package/src/styles/components/_button.scss +756 -0
  28. package/src/styles/components/_card.scss +401 -0
  29. package/src/styles/components/_carousel.scss +645 -0
  30. package/src/styles/components/_checkbox.scss +231 -0
  31. package/src/styles/components/_chips.scss +643 -0
  32. package/src/styles/components/_datepicker.scss +358 -0
  33. package/src/styles/components/_dialog.scss +259 -0
  34. package/src/styles/components/_divider.scss +57 -0
  35. package/src/styles/components/_extended-fab.scss +309 -0
  36. package/src/styles/components/_fab.scss +244 -0
  37. package/src/styles/components/_list.scss +774 -0
  38. package/src/styles/components/_menu.scss +245 -0
  39. package/src/styles/components/_navigation-mobile.scss +244 -0
  40. package/src/styles/components/_navigation-system.scss +151 -0
  41. package/src/styles/components/_navigation.scss +407 -0
  42. package/src/styles/components/_progress.scss +101 -0
  43. package/src/styles/components/_radios.scss +187 -0
  44. package/src/styles/components/_search.scss +306 -0
  45. package/src/styles/components/_segmented-button.scss +227 -0
  46. package/src/styles/components/_select.scss +274 -0
  47. package/src/styles/components/_sheet.scss +236 -0
  48. package/src/styles/components/_slider.scss +264 -0
  49. package/src/styles/components/_snackbar.scss +211 -0
  50. package/src/styles/components/_switch.scss +305 -0
  51. package/src/styles/components/_tabs.scss +421 -0
  52. package/src/styles/components/_textfield.scss +1035 -0
  53. package/src/styles/components/_timepicker.scss +451 -0
  54. package/src/styles/components/_tooltip.scss +241 -0
  55. package/src/styles/components/_top-app-bar.scss +225 -0
  56. package/src/styles/main.scss +129 -0
  57. package/src/styles/themes/_autumn.scss +105 -0
  58. package/src/styles/themes/_base-theme.scss +85 -0
  59. package/src/styles/themes/_baseline.scss +173 -0
  60. package/src/styles/themes/_bluekhaki.scss +125 -0
  61. package/src/styles/themes/_brownbeige.scss +125 -0
  62. package/src/styles/themes/_browngreen.scss +125 -0
  63. package/src/styles/themes/_forest.scss +77 -0
  64. package/src/styles/themes/_greenbeige.scss +125 -0
  65. package/src/styles/themes/_index.scss +19 -0
  66. package/src/styles/themes/_material.scss +125 -0
  67. package/src/styles/themes/_ocean.scss +77 -0
  68. package/src/styles/themes/_sageivory.scss +125 -0
  69. package/src/styles/themes/_spring.scss +77 -0
  70. package/src/styles/themes/_summer.scss +87 -0
  71. package/src/styles/themes/_sunset.scss +60 -0
  72. package/src/styles/themes/_tealcaramel.scss +125 -0
  73. package/src/styles/themes/_winter.scss +77 -0
  74. package/src/styles/utilities/_colors.scss +154 -0
  75. package/src/styles/utilities/_flexbox.scss +194 -0
  76. package/src/styles/utilities/_layout.scss +665 -0
  77. package/src/styles/utilities/_ripple.scss +79 -0
  78. package/src/styles/utilities/_spacing.scss +139 -0
  79. package/src/styles/utilities/_typography.scss +178 -0
  80. package/src/styles/utilities/_visibility.scss +142 -0
@@ -0,0 +1,305 @@
1
+ // src/components/switch/_switch.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}-switch';
9
+
10
+ .#{$component} {
11
+ // Base styles
12
+ display: inline-flex;
13
+ flex-direction: column;
14
+ position: relative;
15
+ width: 100%;
16
+ padding: 4px 0;
17
+ user-select: none;
18
+
19
+ // Container for switch and label
20
+ &-container {
21
+ display: flex;
22
+ flex-direction: row;
23
+ justify-content: space-between;
24
+ align-items: center;
25
+ min-height: 48px;
26
+ width: 100%;
27
+ }
28
+
29
+ // Content wrapper
30
+ &-content {
31
+ display: flex;
32
+ flex-direction: column;
33
+ flex-grow: 1;
34
+ margin-right: 12px;
35
+ }
36
+
37
+ // Label
38
+ &-label {
39
+ @include m.typography('title-medium');
40
+ font-size: 18px;
41
+ color: t.color('on-surface');
42
+ }
43
+
44
+ // Input (visually hidden but accessible)
45
+ &-input {
46
+ position: absolute;
47
+ opacity: 0;
48
+ width: 100%;
49
+ height: 100%;
50
+ margin: 0;
51
+ cursor: pointer;
52
+ z-index: 1;
53
+
54
+ &:disabled {
55
+ cursor: not-allowed;
56
+ }
57
+
58
+ // Focus indicator
59
+ &:focus-visible ~ .#{$component}-track {
60
+ outline: 2px solid t.color('primary');
61
+ outline-offset: 2px;
62
+ }
63
+ }
64
+
65
+ // Switch track (background bar)
66
+ &-track {
67
+ position: relative;
68
+ min-width: 52px;
69
+ height: 32px;
70
+ border-radius: 16px;
71
+ background-color: t.color('surface-container-highest');
72
+ border: 2px solid t.color('outline');
73
+ @include m.motion-transition(background-color, border-color, outline);
74
+
75
+ // Ripple effect (consistent size for both hover and press)
76
+ &::after {
77
+ content: '';
78
+ position: absolute;
79
+ width: 40px;
80
+ height: 40px;
81
+ top: -6px;
82
+ background-color: transparent;
83
+ opacity: 0;
84
+ border-radius: 50%;
85
+ z-index: 0;
86
+ transform: translateX(-6px);
87
+ transition: opacity v.motion('duration-medium1') v.motion('easing-emphasized'),
88
+ background-color v.motion('duration-medium1') v.motion('easing-emphasized'),
89
+ transform v.motion('duration-medium1') cubic-bezier(0.2, 1.4, 0.35, 1);
90
+ pointer-events: none;
91
+ }
92
+ }
93
+
94
+ // Switch thumb (slider)
95
+ &-thumb {
96
+ position: absolute;
97
+ top: 6px;
98
+ left: 6px;
99
+ width: 16px;
100
+ height: 16px;
101
+ border-radius: 50%;
102
+ background-color: t.color('outline');
103
+ transform: translateX(0);
104
+ transition: transform v.motion('duration-medium1') cubic-bezier(0.2, 1.4, 0.35, 1),
105
+ background-color v.motion('duration-medium1') v.motion('easing-emphasized'),
106
+ width v.motion('duration-medium1') v.motion('easing-emphasized'),
107
+ height v.motion('duration-medium1') v.motion('easing-emphasized'),
108
+ top v.motion('duration-medium1') v.motion('easing-emphasized'),
109
+ left v.motion('duration-medium1') v.motion('easing-emphasized');
110
+ display: flex;
111
+ align-items: center;
112
+ justify-content: center;
113
+ z-index: 1; /* Ensure thumb is above ripple */
114
+ pointer-events: none;
115
+
116
+ // Icon inside thumb
117
+ &-icon {
118
+ display: flex;
119
+ align-items: center;
120
+ justify-content: center;
121
+ opacity: 0;
122
+ transform: scale(0);
123
+ transition: all v.motion('duration-short4') v.motion('easing-emphasized');
124
+ color: t.color('primary');
125
+
126
+ svg {
127
+ width: 14px;
128
+ height: 14px;
129
+ }
130
+ }
131
+ }
132
+
133
+ // Supporting text
134
+ &-helper {
135
+ @include m.typography('body-medium');
136
+ color: t.color('on-surface-variant');
137
+
138
+ &--error {
139
+ color: t.color('error');
140
+ }
141
+ }
142
+
143
+ // RTL support
144
+ @include m.rtl {
145
+ &-container {
146
+ flex-direction: row;
147
+ }
148
+
149
+ &-content {
150
+ margin-left: 12px;
151
+ margin-right: 0;
152
+ }
153
+
154
+ // Adjust thumb movement for RTL layout
155
+ &--checked .#{$component}-thumb {
156
+ transform: translateX(-20px);
157
+ }
158
+ }
159
+
160
+ // Checked state
161
+ &--checked {
162
+ .#{$component}-track {
163
+ background-color: t.color('primary');
164
+ border-color: t.color('primary');
165
+
166
+ &::after {
167
+ transform: translateX(14px);
168
+ }
169
+ }
170
+
171
+ .#{$component}-thumb {
172
+ background-color: t.color('on-primary');
173
+ transform: translateX(20px);
174
+ width: 24px;
175
+ height: 24px;
176
+ top: 2px;
177
+ left: 2px;
178
+
179
+ &-icon {
180
+ opacity: 1;
181
+ transform: scale(1);
182
+ }
183
+ }
184
+ }
185
+
186
+ &--dense {
187
+ .#{$component}-container {
188
+ min-height: initial;
189
+ }
190
+ }
191
+
192
+ // Error state
193
+ &--error {
194
+ .#{$component}-track {
195
+ border-color: t.color('error');
196
+ }
197
+ }
198
+
199
+ // Disabled state
200
+ &--disabled {
201
+ pointer-events: none;
202
+ .#{$component}-track {
203
+ opacity: 0.38;
204
+ }
205
+
206
+ .#{$component}-label, .#{$component}-helper {
207
+ opacity: 0.38;
208
+ }
209
+
210
+ // Specific styles for disabled + checked
211
+ &.#{$component}--checked {
212
+ .#{$component}-track {
213
+ background-color: t.color('outline');
214
+ border-color: t.color('outline');
215
+ opacity: 0.38;
216
+ }
217
+
218
+ .#{$component}-thumb {
219
+ background-color: t.color('surface-dim');
220
+ &-icon {
221
+ color: t.color('on-surface');
222
+ }
223
+ }
224
+ }
225
+ }
226
+
227
+ // Interactive states for enabled switches
228
+ &:not(.#{$component}--disabled) {
229
+ // Remove track hover effects
230
+ .#{$component}-input:hover + .#{$component}-track::before,
231
+ .#{$component}-input:active + .#{$component}-track::before {
232
+ display: none;
233
+ }
234
+
235
+ // Handle hover and active states for both unchecked
236
+ &:not(.#{$component}--checked) {
237
+ .#{$component}-input:hover ~ .#{$component}-track,
238
+ .#{$component}-input:active ~ .#{$component}-track {
239
+ .#{$component}-thumb {
240
+ background-color: t.color('on-surface-variant');
241
+ }
242
+
243
+ &::after {
244
+ background-color: t.color('on-surface');
245
+ opacity: v.state('hover-state-layer-opacity');
246
+ transform: translateX(-6px);
247
+ }
248
+ }
249
+
250
+ .#{$component}-input:active ~ .#{$component}-track::after {
251
+ opacity: v.state('pressed-state-layer-opacity');
252
+ }
253
+ }
254
+
255
+ // Hover/active states for checked
256
+ &.#{$component}--checked {
257
+ .#{$component}-input:hover ~ .#{$component}-track,
258
+ .#{$component}-input:active ~ .#{$component}-track {
259
+ &::after {
260
+ background-color: t.color('primary');
261
+ opacity: v.state('hover-state-layer-opacity');
262
+ transform: translateX(14px);
263
+ }
264
+ }
265
+
266
+ .#{$component}-input:active ~ .#{$component}-track::after {
267
+ opacity: v.state('pressed-state-layer-opacity');
268
+ }
269
+ }
270
+
271
+ // Expand thumb on press for both checked and unchecked
272
+ .#{$component}-input:active ~ .#{$component}-track .#{$component}-thumb {
273
+ width: 28px;
274
+ height: 28px;
275
+ top: 0;
276
+ left: 0;
277
+ }
278
+
279
+ &.#{$component}--checked .#{$component}-input:active ~ .#{$component}-track .#{$component}-thumb {
280
+ left: 0;
281
+ }
282
+ }
283
+
284
+ // Accessibility
285
+ @include m.reduced-motion {
286
+ .#{$component}-track,
287
+ .#{$component}-thumb,
288
+ .#{$component}-thumb-icon {
289
+ transition: none;
290
+ }
291
+ }
292
+
293
+ @include m.high-contrast {
294
+ .#{$component}-track {
295
+ border-width: 2px;
296
+ }
297
+
298
+ &--checked .#{$component}-track {
299
+ border-color: currentColor;
300
+ }
301
+ }
302
+
303
+ // Touch target for better mobile experience
304
+ // @include m.touch-target;
305
+ }
@@ -0,0 +1,421 @@
1
+ // src/components/tabs/_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.#{base.$prefix}-tab';
9
+ $container: '#{base.$prefix}-tabs';
10
+
11
+ // Tabs Container Styles (1. Container)
12
+ .#{$container} {
13
+ position: relative;
14
+ display: flex;
15
+ flex-direction: column;
16
+ width: 100%;
17
+ // background-color: t.color('surface'); // MD3: Surface color
18
+ box-sizing: border-box;
19
+
20
+ // Basic container sizing
21
+ &--primary {
22
+ min-height: 48px;
23
+
24
+ // Tab container with icons and text needs more space
25
+ &:has(.#{$component}--icon-and-text) {
26
+ min-height: 64px;
27
+ }
28
+
29
+ // Primary indicator specific styling
30
+ .#{$container}-indicator {
31
+ height: 4px;
32
+ border-radius: 3px 3px 0 0;
33
+ background-color: t.color('primary');
34
+ }
35
+ }
36
+
37
+ &--secondary {
38
+ min-height: 48px;
39
+ // Tab indicator styling for secondary variant
40
+ .#{$container}-indicator {
41
+ height: 2px;
42
+ border-radius: 0;
43
+ background-color: t.color('on-surface');
44
+ }
45
+ }
46
+
47
+ // Scrollable container
48
+ &--scrollable {
49
+ overflow: hidden;
50
+
51
+ .#{$container}-scroll {
52
+ display: flex;
53
+ overflow-x: auto;
54
+ scrollbar-width: none; // Firefox
55
+ -ms-overflow-style: none; // IE and Edge
56
+
57
+ &::-webkit-scrollbar {
58
+ display: none; // Chrome, Safari, and Opera
59
+ }
60
+ }
61
+ }
62
+
63
+ // Container divider (5. Divider)
64
+ &-divider {
65
+ position: absolute;
66
+ bottom: 0;
67
+ left: 0;
68
+ right: 0;
69
+ height: 1px;
70
+ background-color: t.color('outline-variant'); // MD3: Outline variant color
71
+ }
72
+
73
+ // Tab indicator styling - base styles
74
+ &-indicator {
75
+ position: absolute;
76
+ bottom: 1px;
77
+ transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1),
78
+ width 250ms cubic-bezier(0.4, 0, 0.2, 1);
79
+ z-index: 1; // Ensure indicator appears above divider
80
+ }
81
+ }
82
+
83
+ // Individual Tab Styles
84
+ .#{$component} {
85
+ position: relative;
86
+ display: inline-flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ min-width: 90px;
90
+ max-width: 360px;
91
+ padding: 0 16px;
92
+ border: none;
93
+ border-radius: 5px 5px 0 0;
94
+ background-color: transparent;
95
+ color: t.color('on-surface-variant');
96
+ cursor: pointer;
97
+ user-select: none;
98
+ flex-shrink: 0;
99
+
100
+
101
+
102
+ // Typography for label text (4. Label)
103
+ @include m.typography('label-large');
104
+
105
+ // Transition for state changes
106
+ transition:
107
+ background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
108
+ color 0.2s cubic-bezier(0.4, 0, 0.2, 1);
109
+
110
+ // Container heights based on layout
111
+ &--text-only {
112
+ height: 48px;
113
+ }
114
+
115
+ &--icon-only {
116
+ height: 48px;
117
+ }
118
+
119
+ &--icon-and-text {
120
+ height: 64px;
121
+ flex-direction: column;
122
+ }
123
+
124
+ // Focus styles (3/7. Focused state)
125
+ &:focus {
126
+ outline: none;
127
+ }
128
+
129
+ &:focus-visible {
130
+ outline: 2px solid t.color('primary');
131
+ outline-offset: -2px;
132
+ z-index: 1;
133
+ }
134
+
135
+ // Disabled state
136
+ &--disabled, &:disabled {
137
+ pointer-events: none;
138
+ opacity: 0.38;
139
+ }
140
+
141
+ // Tab Icon (3. Icon - optional)
142
+ &-icon {
143
+ display: flex;
144
+ align-items: center;
145
+ justify-content: center;
146
+ width: 24px;
147
+ height: 24px;
148
+
149
+ svg {
150
+ width: 100%;
151
+ height: 100%;
152
+ fill: currentColor;
153
+ }
154
+ }
155
+
156
+ // Ensure proper vertical spacing for icon and text
157
+ &--icon-and-text {
158
+ .#{$component}-icon {
159
+ margin-bottom: 4px;
160
+ }
161
+ }
162
+
163
+ // Tab Text (4. Label)
164
+ &-text {
165
+ @include m.truncate;
166
+ max-width: 100%;
167
+ text-align: center;
168
+ line-height: 1.2;
169
+
170
+ .#{$component}--icon-only & {
171
+ @include m.visually-hidden;
172
+ }
173
+ }
174
+
175
+ // Badge positioning (2. Badge - optional)
176
+ .#{base.$prefix}-badge-wrapper {
177
+ .#{base.$prefix}-badge {
178
+ // Position for different tab layouts
179
+ &--top-right {
180
+ .#{$component}--icon-only & {
181
+ top: 4px;
182
+ right: 4px;
183
+ }
184
+
185
+ .#{$component}--text-only & {
186
+ top: 8px;
187
+ right: 8px;
188
+ }
189
+
190
+ .#{$component}--icon-and-text & {
191
+ top: 4px;
192
+ right: calc(50% - 20px);
193
+ }
194
+ }
195
+ }
196
+ }
197
+
198
+ // ACTIVE TAB STATES - PRIMARY VARIANT
199
+ .#{$container}--primary & {
200
+ // Active Tab Base State - Apply to primary variant
201
+ &--active {
202
+ color: t.color('primary');
203
+
204
+ .#{$component}-icon {
205
+ color: t.color('primary');
206
+ }
207
+
208
+ // Hover state for active tabs
209
+ &:hover, &.#{$component}--hover {
210
+ background-color: t.alpha('primary', 0.08);
211
+ }
212
+
213
+ // Focused state for active tabs
214
+ &:focus-visible, &.#{$component}--focus {
215
+ background-color: t.alpha('primary', 0.1);
216
+ outline-color: t.color('primary');
217
+ }
218
+
219
+ // Pressed state for active tabs
220
+ &:active, &.#{$component}--pressed {
221
+ background-color: t.alpha('primary', 0.12);
222
+ border-radius: 5px 5px 0 0;
223
+ }
224
+ }
225
+
226
+ // Inactive Tabs - Primary variant
227
+ &:not(.#{$component}--active):not(.#{$component}--disabled):not(:disabled) {
228
+ color: t.color('on-surface-variant');
229
+
230
+ // Hover state for inactive tabs
231
+ &:hover, &.#{$component}--hover {
232
+ background-color: t.alpha('on-surface-variant', 0.08);
233
+ }
234
+
235
+ // Focused state for inactive tabs
236
+ &:focus-visible, &.#{$component}--focus {
237
+ background-color: t.alpha('on-surface-variant', 0.1);
238
+ outline-color: t.color('on-surface-variant');
239
+ }
240
+
241
+ // Pressed state for inactive tabs
242
+ &:active, &.#{$component}--pressed {
243
+ background-color: t.alpha('on-surface-variant', 0.12);
244
+ border-radius: 5px 5px 0 0;
245
+ }
246
+ }
247
+ }
248
+
249
+ // ACTIVE TAB STATES - SECONDARY VARIANT
250
+ .#{$container}--secondary & {
251
+ // Active Tab - Secondary variant
252
+ &--active {
253
+ color: t.color('on-surface');
254
+
255
+ .#{$component}-icon {
256
+ color: t.color('on-surface');
257
+ }
258
+
259
+ // Hover state for active tabs - secondary
260
+ &:hover, &.#{$component}--hover {
261
+ background-color: t.alpha('on-surface', 0.08);
262
+ }
263
+
264
+ // Focused state for active tabs - secondary
265
+ &:focus-visible, &.#{$component}--focus {
266
+ background-color: t.alpha('on-surface', 0.1);
267
+ outline-color: t.color('on-surface');
268
+ }
269
+
270
+ // Pressed state for active tabs - secondary
271
+ &:active, &.#{$component}--pressed {
272
+ background-color: t.alpha('on-surface', 0.12);
273
+ }
274
+ }
275
+
276
+ // Inactive Tabs - Secondary variant
277
+ &:not(.#{$component}--active):not(.#{$component}--disabled):not(:disabled) {
278
+ color: t.color('on-surface-variant');
279
+
280
+ // Hover state for inactive tabs - secondary
281
+ &:hover, &.#{$component}--hover {
282
+ background-color: t.alpha('on-surface-variant', 0.08);
283
+ }
284
+
285
+ // Focused state for inactive tabs - secondary
286
+ &:focus-visible, &.#{$component}--focus {
287
+ background-color: t.alpha('on-surface-variant', 0.1);
288
+ outline-color: t.color('on-surface-variant');
289
+ }
290
+
291
+ // Pressed state for inactive tabs - secondary
292
+ &:active, &.#{$component}--pressed {
293
+ background-color: t.alpha('on-surface-variant', 0.12);
294
+ border-radius: 5px 5px 0 0;
295
+ }
296
+ }
297
+ }
298
+
299
+ // Ripple effect styling
300
+ .#{$component}-ripple {
301
+ position: absolute;
302
+ top: 0;
303
+ left: 0;
304
+ right: 0;
305
+ bottom: 0;
306
+ overflow: hidden;
307
+ border-radius: inherit;
308
+ pointer-events: none;
309
+
310
+ .ripple {
311
+ position: absolute;
312
+ border-radius: 50%;
313
+ transform: scale(0);
314
+ pointer-events: none;
315
+ background-color: currentColor;
316
+ opacity: 0.1;
317
+ transform-origin: center;
318
+ }
319
+ }
320
+ }
321
+
322
+ // Tab panel styles
323
+ .#{base.$prefix}-tab-panel {
324
+ padding: 16px;
325
+
326
+ &[hidden] {
327
+ display: none;
328
+ }
329
+ }
330
+
331
+ // Scroll indicators
332
+ .#{$container} {
333
+ &-scroll-indicator {
334
+ position: absolute;
335
+ top: 0;
336
+ bottom: 0;
337
+ width: 24px;
338
+ pointer-events: none;
339
+ z-index: 1;
340
+ opacity: 0;
341
+ transition: opacity 0.2s ease;
342
+
343
+ &.visible {
344
+ opacity: 1;
345
+ }
346
+
347
+ &--left {
348
+ left: 0;
349
+ background: linear-gradient(to right, t.color('surface'), transparent);
350
+ }
351
+
352
+ &--right {
353
+ right: 0;
354
+ background: linear-gradient(to left, t.color('surface'), transparent);
355
+ }
356
+
357
+ &--shadow {
358
+ &.#{$container}-scroll-indicator--left {
359
+ box-shadow: 2px 0 4px -2px rgba(0, 0, 0, 0.2);
360
+ background: none;
361
+ }
362
+
363
+ &.#{$container}-scroll-indicator--right {
364
+ box-shadow: -2px 0 4px -2px rgba(0, 0, 0, 0.2);
365
+ background: none;
366
+ }
367
+ }
368
+ }
369
+
370
+ &-scroll-button {
371
+ position: absolute;
372
+ top: 50%;
373
+ transform: translateY(-50%);
374
+ width: 40px;
375
+ height: 40px;
376
+ border-radius: 50%;
377
+ background-color: t.color('surface-container-high');
378
+ border: none;
379
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
380
+ display: flex;
381
+ align-items: center;
382
+ justify-content: center;
383
+ cursor: pointer;
384
+ z-index: 2;
385
+
386
+ &:disabled {
387
+ opacity: 0.38;
388
+ cursor: default;
389
+ }
390
+
391
+ svg {
392
+ width: 24px;
393
+ height: 24px;
394
+ fill: t.color('on-surface');
395
+ }
396
+
397
+ &--left {
398
+ left: 4px;
399
+ }
400
+
401
+ &--right {
402
+ right: 4px;
403
+ }
404
+
405
+ &:focus {
406
+ outline: none;
407
+ }
408
+
409
+ &:focus-visible {
410
+ outline: 2px solid t.color('primary');
411
+ }
412
+ }
413
+ }
414
+
415
+ // Responsive styles for small screens
416
+ .#{$container}--responsive-small {
417
+ .#{$component} {
418
+ padding: 0 12px;
419
+ min-width: 72px;
420
+ }
421
+ }