mtrl 0.3.1 → 0.3.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.
Files changed (162) hide show
  1. package/.env +15 -0
  2. package/CONTRIBUTING.md +62 -23
  3. package/DOCS.md +3 -3
  4. package/README.md +43 -20
  5. package/TESTING.md +128 -18
  6. package/dist/index.js +14865 -0
  7. package/git-user-stats.js +545 -0
  8. package/index.ts +9 -67
  9. package/package.json +8 -3
  10. package/src/components/badge/api.ts +15 -1
  11. package/src/components/badge/badge.ts +43 -4
  12. package/src/components/badge/config.ts +40 -8
  13. package/src/components/badge/index.ts +64 -3
  14. package/src/components/badge/types.ts +175 -33
  15. package/src/components/button/api.ts +63 -1
  16. package/src/components/button/button.ts +39 -3
  17. package/src/components/button/config.ts +21 -4
  18. package/src/components/button/index.ts +26 -1
  19. package/src/components/button/types.ts +7 -1
  20. package/src/components/card/api.ts +78 -9
  21. package/src/components/card/card.ts +58 -3
  22. package/src/components/card/config.ts +41 -11
  23. package/src/components/card/features.ts +39 -12
  24. package/src/components/card/index.ts +84 -19
  25. package/src/components/card/types.ts +218 -29
  26. package/src/components/carousel/carousel.ts +92 -28
  27. package/src/components/carousel/constants.ts +107 -21
  28. package/src/components/carousel/index.ts +31 -13
  29. package/src/components/checkbox/checkbox.ts +83 -16
  30. package/src/components/checkbox/index.ts +43 -1
  31. package/src/components/checkbox/types.ts +219 -32
  32. package/src/components/chips/api.ts +194 -0
  33. package/src/components/{chip → chips/chip}/api.ts +42 -2
  34. package/src/components/chips/chip/chip.ts +131 -0
  35. package/src/components/{chip → chips/chip}/config.ts +3 -3
  36. package/src/components/chips/chip/index.ts +3 -0
  37. package/src/components/chips/chips.md +481 -0
  38. package/src/components/chips/chips.ts +75 -0
  39. package/src/components/chips/config.ts +109 -0
  40. package/src/components/chips/constants.ts +61 -0
  41. package/src/components/chips/features/chip-items.ts +33 -0
  42. package/src/components/chips/features/container.ts +77 -0
  43. package/src/components/chips/features/controller.ts +448 -0
  44. package/src/components/chips/features/index.ts +5 -0
  45. package/src/components/chips/features/label.ts +108 -0
  46. package/src/components/chips/index.ts +11 -0
  47. package/src/components/chips/schema.ts +61 -0
  48. package/src/components/{chip → chips}/types.ts +203 -92
  49. package/src/components/dialog/dialog.ts +99 -16
  50. package/src/components/dialog/index.ts +97 -1
  51. package/src/components/dialog/types.ts +375 -69
  52. package/src/components/divider/config.ts +90 -6
  53. package/src/components/divider/divider.ts +32 -2
  54. package/src/components/divider/features.ts +26 -0
  55. package/src/components/divider/index.ts +30 -0
  56. package/src/components/divider/types.ts +86 -9
  57. package/src/components/extended-fab/api.ts +53 -1
  58. package/src/components/extended-fab/config.ts +29 -1
  59. package/src/components/extended-fab/extended-fab.ts +28 -0
  60. package/src/components/extended-fab/index.ts +36 -0
  61. package/src/components/extended-fab/types.ts +458 -13
  62. package/src/components/fab/api.ts +42 -2
  63. package/src/components/fab/config.ts +29 -1
  64. package/src/components/fab/fab.ts +16 -2
  65. package/src/components/fab/index.ts +35 -0
  66. package/src/components/fab/types.ts +374 -10
  67. package/src/components/list/api.ts +12 -2
  68. package/src/components/list/config.ts +21 -0
  69. package/src/components/list/features.ts +6 -0
  70. package/src/components/list/index.ts +56 -1
  71. package/src/components/list/list-item.ts +46 -2
  72. package/src/components/list/list.ts +73 -2
  73. package/src/components/list/types.ts +172 -0
  74. package/src/components/list/utils.ts +26 -2
  75. package/src/components/menu/api.ts +217 -20
  76. package/src/components/menu/config.ts +27 -0
  77. package/src/components/menu/features/visibility.ts +55 -6
  78. package/src/components/menu/index.ts +64 -0
  79. package/src/components/menu/menu-item.ts +46 -3
  80. package/src/components/menu/menu.ts +77 -1
  81. package/src/components/menu/types.ts +404 -39
  82. package/src/components/navigation/nav-item.ts +13 -2
  83. package/src/components/sheet/config.ts +1 -2
  84. package/src/components/sheet/features/gestures.ts +1 -1
  85. package/src/components/sheet/features/position.ts +1 -2
  86. package/src/components/sheet/features/state.ts +1 -1
  87. package/src/components/sheet/index.ts +10 -2
  88. package/src/components/sheet/sheet.ts +1 -2
  89. package/src/components/sheet/types.ts +29 -1
  90. package/src/components/slider/api.ts +1 -1
  91. package/src/components/slider/config.ts +1 -1
  92. package/src/components/slider/features/controller.ts +1 -1
  93. package/src/components/slider/features/handlers.ts +1 -1
  94. package/src/components/slider/features/states.ts +1 -1
  95. package/src/components/slider/index.ts +12 -5
  96. package/src/components/slider/schema.ts +1 -1
  97. package/src/components/slider/types.ts +31 -0
  98. package/src/components/tabs/tab-api.ts +1 -1
  99. package/src/components/tabs/types.ts +1 -1
  100. package/src/components/tooltip/api.ts +6 -2
  101. package/src/components/tooltip/config.ts +9 -28
  102. package/src/components/tooltip/index.ts +10 -1
  103. package/src/components/tooltip/types.ts +38 -3
  104. package/src/core/dom/create.ts +57 -51
  105. package/src/index.ts +129 -31
  106. package/src/styles/abstract/_mixins.scss +23 -9
  107. package/src/styles/abstract/_variables.scss +14 -4
  108. package/src/styles/components/_card.scss +1 -1
  109. package/src/styles/components/_chip.scss +323 -113
  110. package/src/styles/components/_tabs.scss +1 -1
  111. package/src/styles/themes/_autumn.scss +3 -0
  112. package/CLAUDE.md +0 -33
  113. package/src/components/checkbox/constants.ts +0 -37
  114. package/src/components/chip/chip-set.ts +0 -225
  115. package/src/components/chip/chip.ts +0 -118
  116. package/src/components/chip/constants.ts +0 -28
  117. package/src/components/chip/index.ts +0 -12
  118. package/src/components/list/constants.ts +0 -116
  119. package/src/components/sheet/constants.ts +0 -20
  120. package/src/components/slider/constants.ts +0 -32
  121. package/src/components/tooltip/constants.ts +0 -27
  122. package/test/components/badge.test.ts +0 -545
  123. package/test/components/bottom-app-bar.test.ts +0 -303
  124. package/test/components/button.test.ts +0 -233
  125. package/test/components/card.test.ts +0 -560
  126. package/test/components/carousel.test.ts +0 -951
  127. package/test/components/checkbox.test.ts +0 -462
  128. package/test/components/chip.test.ts +0 -692
  129. package/test/components/datepicker.test.ts +0 -1124
  130. package/test/components/dialog.test.ts +0 -990
  131. package/test/components/divider.test.ts +0 -412
  132. package/test/components/extended-fab.test.ts +0 -672
  133. package/test/components/fab.test.ts +0 -561
  134. package/test/components/list.test.ts +0 -365
  135. package/test/components/menu.test.ts +0 -718
  136. package/test/components/navigation.test.ts +0 -186
  137. package/test/components/progress.test.ts +0 -567
  138. package/test/components/radios.test.ts +0 -699
  139. package/test/components/search.test.ts +0 -1135
  140. package/test/components/segmented-button.test.ts +0 -732
  141. package/test/components/sheet.test.ts +0 -641
  142. package/test/components/slider.test.ts +0 -1220
  143. package/test/components/snackbar.test.ts +0 -461
  144. package/test/components/switch.test.ts +0 -452
  145. package/test/components/tabs.test.ts +0 -1369
  146. package/test/components/textfield.test.ts +0 -400
  147. package/test/components/timepicker.test.ts +0 -592
  148. package/test/components/tooltip.test.ts +0 -630
  149. package/test/components/top-app-bar.test.ts +0 -566
  150. package/test/core/dom.attributes.test.ts +0 -148
  151. package/test/core/dom.classes.test.ts +0 -152
  152. package/test/core/dom.events.test.ts +0 -243
  153. package/test/core/emitter.test.ts +0 -141
  154. package/test/core/ripple.test.ts +0 -99
  155. package/test/core/state.store.test.ts +0 -189
  156. package/test/core/utils.normalize.test.ts +0 -61
  157. package/test/core/utils.object.test.ts +0 -120
  158. package/test/setup.js +0 -371
  159. package/test/setup.ts +0 -451
  160. package/tsconfig.json +0 -22
  161. package/typedoc.json +0 -28
  162. package/typedoc.simple.json +0 -14
@@ -37,17 +37,31 @@ $icons: (
37
37
  }
38
38
 
39
39
  // State Layers
40
- @mixin state-layer($color, $state: 'hover', $selector: '&::before') {
40
+ @mixin state-layer($color, $state: 'hover', $selector: false) {
41
41
  position: relative;
42
42
 
43
- #{$selector} {
44
- content: '';
45
- position: absolute;
46
- inset: 0;
47
- background-color: $color;
48
- opacity: f.get-state-opacity($state);
49
- pointer-events: none;
50
- border-radius: inherit;
43
+ @if $selector == false {
44
+ // Default behavior - create a pseudo-element for the state layer
45
+ &::before {
46
+ content: '';
47
+ position: absolute;
48
+ inset: 0;
49
+ background-color: $color;
50
+ opacity: f.get-state-opacity($state);
51
+ pointer-events: none;
52
+ border-radius: inherit;
53
+ }
54
+ } @else {
55
+ // Use the provided selector
56
+ #{$selector} {
57
+ content: '';
58
+ position: absolute;
59
+ inset: 0;
60
+ background-color: $color;
61
+ opacity: f.get-state-opacity($state);
62
+ pointer-events: none;
63
+ border-radius: inherit;
64
+ }
51
65
  }
52
66
  }
53
67
 
@@ -189,11 +189,18 @@ $card: (
189
189
  'padding': 16px
190
190
  ) !default;
191
191
 
192
- // Chip configuration
192
+ // Chip configuration - updated with MD3 values
193
193
  $chip-config: (
194
194
  'height': 32px,
195
195
  'border-radius': 8px,
196
- 'padding-horizontal': 12px
196
+ 'padding-horizontal': 12px,
197
+ 'outlined-border-opacity': 0.12,
198
+ 'outlined-border-hover-opacity': 0.29,
199
+ 'outlined-border-focus-opacity': 0.38,
200
+ 'outlined-selected-border-opacity': 0,
201
+ 'suggestion-height': 48px,
202
+ 'icon-size': 18px,
203
+ 'suggestion-icon-size': 24px
197
204
  ) !default;
198
205
 
199
206
  $button: (
@@ -272,6 +279,9 @@ $spacing-scale: (
272
279
  @return map.get($card, $key);
273
280
  }
274
281
 
275
- @function chip($key) {
276
- @return map.get($chip-config, $key);
282
+ @function chip($key, $fallback: null) {
283
+ @if map.has-key($chip-config, $key) {
284
+ @return map.get($chip-config, $key);
285
+ }
286
+ @return $fallback;
277
287
  }
@@ -302,7 +302,7 @@ $component: '#{base.$prefix}-card';
302
302
 
303
303
  // State classes
304
304
  &--state-disabled {
305
- opacity: 0.38; // Use MTRL standard opacity
305
+ opacity: 0.38; // Use mtrl standard opacity
306
306
  pointer-events: none;
307
307
  }
308
308
 
@@ -1,12 +1,14 @@
1
- // src/components/chip/_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;
1
+ // src/styles/components/_chips.scss
2
+ @use '../abstract/base' as base;
3
+ @use '../abstract/variables' as v;
4
+ @use '../abstract/functions' as f;
5
+ @use '../abstract/mixins' as m;
6
+ @use '../abstract/theme' as t;
7
7
 
8
8
  $component: '#{base.$prefix}-chip';
9
+ $container: '#{base.$prefix}-chips';
9
10
 
11
+ // Chip component styling
10
12
  .#{$component} {
11
13
  // Base styles
12
14
  position: relative;
@@ -18,15 +20,19 @@ $component: '#{base.$prefix}-chip';
18
20
  border-radius: v.chip('border-radius');
19
21
  background-color: transparent;
20
22
  max-width: 100%;
21
- overflow: hidden;
22
23
  user-select: none;
23
24
  cursor: pointer;
24
25
 
25
26
  // Typography
26
27
  @include m.typography('label-large');
27
28
 
28
- // Interaction styles
29
- @include m.motion-transition(background-color, color, border-color, box-shadow);
29
+ // Enhanced transition for width changes
30
+ transition: background-color v.motion('duration-short4') v.motion('easing-standard'),
31
+ color v.motion('duration-short4') v.motion('easing-standard'),
32
+ border-color v.motion('duration-short4') v.motion('easing-standard'),
33
+ box-shadow v.motion('duration-short4') v.motion('easing-standard'),
34
+ padding v.motion('duration-short4') v.motion('easing-standard'),
35
+ width v.motion('duration-short4') v.motion('easing-standard');
30
36
 
31
37
  // Focus styles
32
38
  &:focus {
@@ -51,48 +57,50 @@ $component: '#{base.$prefix}-chip';
51
57
  justify-content: center;
52
58
  width: 100%;
53
59
  height: 100%;
60
+ gap: v.spacing('2');
54
61
  }
55
62
 
56
- // Ensure proper layout with icons
63
+ // Ensure proper layout with icons - independent of scrollable state
57
64
  &-leading-icon,
58
65
  &-trailing-icon {
59
66
  display: inline-flex;
60
67
  align-items: center;
61
68
  justify-content: center;
62
- width: 18px;
63
- height: 18px;
69
+ min-width: v.chip('icon-size');
70
+ height: v.chip('icon-size');
71
+ flex-shrink: 0;
72
+ position: relative; // Add this to ensure stable positioning
64
73
 
65
74
  svg {
66
- width: 18px;
67
- height: 18px;
75
+ width: v.chip('icon-size');
76
+ height: v.chip('icon-size');
68
77
  }
69
78
  }
70
79
 
71
80
  &-leading-icon {
72
- margin-right: 8px;
81
+ margin-right: 0; // Gap is handled by the content container
73
82
  }
74
83
 
75
84
  &-trailing-icon {
76
- margin-left: 8px;
85
+ margin-left: 0; // Gap is handled by the content container
77
86
 
78
87
  &:hover {
79
- opacity: 0.7;
88
+ opacity: 0.8;
80
89
  }
81
90
  }
82
91
 
83
92
  &-text {
84
- // Text truncation for long chip labels
85
- @include m.truncate;
93
+ // Allow text to display normally
94
+ white-space: nowrap;
95
+ overflow: visible;
86
96
  }
87
97
 
88
- // Selected state
98
+ // Selected state (base)
89
99
  &--selected {
90
- // Default selected state styling (can be overridden by variants)
91
- background-color: t.alpha('on-surface', 0.12);
92
100
  font-weight: 500;
93
101
  }
94
102
 
95
- // Ripple container
103
+ // Ripple container - state layers for interaction feedback
96
104
  .ripple {
97
105
  position: absolute;
98
106
  border-radius: 50%;
@@ -102,101 +110,211 @@ $component: '#{base.$prefix}-chip';
102
110
  opacity: 0.12;
103
111
  }
104
112
 
105
- // Variants
113
+ // ====== CHIP VARIANTS ======
114
+
115
+ // Filled chip
106
116
  &--filled {
107
117
  background-color: t.color('surface-container-highest');
108
118
  color: t.color('on-surface');
109
119
 
110
- &:hover {
111
- @include m.state-layer(t.color('on-surface'), 'hover');
120
+ &:hover::after {
121
+ content: '';
122
+ position: absolute;
123
+ inset: 0;
124
+ background-color: t.color('on-surface');
125
+ opacity: 0.08;
126
+ pointer-events: none;
127
+ border-radius: inherit;
112
128
  }
113
129
 
114
- &:active {
115
- @include m.state-layer(t.color('on-surface'), 'pressed');
130
+ &:active::after {
131
+ content: '';
132
+ position: absolute;
133
+ inset: 0;
134
+ background-color: t.color('on-surface');
135
+ opacity: 0.12;
136
+ pointer-events: none;
137
+ border-radius: inherit;
116
138
  }
117
139
 
118
140
  &.#{$component}--selected {
119
141
  background-color: t.color('secondary-container');
120
142
  color: t.color('on-secondary-container');
121
143
 
122
- &:hover {
123
- @include m.state-layer(t.color('on-secondary-container'), 'hover');
144
+ &:hover::after {
145
+ content: '';
146
+ position: absolute;
147
+ inset: 0;
148
+ background-color: t.color('on-secondary-container');
149
+ opacity: 0.08;
150
+ pointer-events: none;
151
+ border-radius: inherit;
124
152
  }
125
153
 
126
- &:active {
127
- @include m.state-layer(t.color('on-secondary-container'), 'pressed');
154
+ &:active::after {
155
+ content: '';
156
+ position: absolute;
157
+ inset: 0;
158
+ background-color: t.color('on-secondary-container');
159
+ opacity: 0.12;
160
+ pointer-events: none;
161
+ border-radius: inherit;
128
162
  }
129
163
  }
130
164
  }
131
165
 
166
+ // Outlined chip
132
167
  &--outlined {
133
- border: 1px solid t.color('outline');
168
+ border: 1px solid t.alpha('outline', v.chip('outlined-border-opacity'));
134
169
  color: t.color('on-surface');
135
170
 
136
- &:hover {
137
- @include m.state-layer(t.color('on-surface'), 'hover');
171
+ &:hover::after {
172
+ content: '';
173
+ position: absolute;
174
+ inset: 0;
175
+ background-color: t.color('on-surface');
176
+ opacity: 0.08;
177
+ pointer-events: none;
178
+ border-radius: inherit;
179
+ }
180
+
181
+ &:focus-visible {
182
+ border-color: t.alpha('outline', v.chip('outlined-border-focus-opacity'));
138
183
  }
139
184
 
140
- &:active {
141
- @include m.state-layer(t.color('on-surface'), 'pressed');
185
+ &:active::after {
186
+ content: '';
187
+ position: absolute;
188
+ inset: 0;
189
+ background-color: t.color('on-surface');
190
+ opacity: 0.12;
191
+ pointer-events: none;
192
+ border-radius: inherit;
142
193
  }
143
194
 
144
195
  &.#{$component}--selected {
145
- border-color: t.color('outline');
196
+ border-color: transparent;
146
197
  background-color: t.color('secondary-container');
147
198
  color: t.color('on-secondary-container');
148
199
 
149
- &:hover {
150
- @include m.state-layer(t.color('on-secondary-container'), 'hover');
200
+ &:hover::after {
201
+ content: '';
202
+ position: absolute;
203
+ inset: 0;
204
+ background-color: t.color('on-secondary-container');
205
+ opacity: 0.08;
206
+ pointer-events: none;
207
+ border-radius: inherit;
151
208
  }
152
209
  }
153
210
  }
154
211
 
212
+ // Elevated chip
155
213
  &--elevated {
156
214
  background-color: t.color('surface-container-low');
157
215
  color: t.color('on-surface');
158
- @include m.elevation(1);
216
+ box-shadow: f.get-elevation(1);
159
217
 
160
- &:hover {
161
- @include m.state-layer(t.color('on-surface'), 'hover');
162
- @include m.elevation(2);
218
+ &:hover::after {
219
+ content: '';
220
+ position: absolute;
221
+ inset: 0;
222
+ background-color: t.color('on-surface');
223
+ opacity: 0.08;
224
+ pointer-events: none;
225
+ border-radius: inherit;
163
226
  }
164
227
 
165
- &:active {
166
- @include m.state-layer(t.color('on-surface'), 'pressed');
167
- @include m.elevation(1);
228
+ &:active::after {
229
+ content: '';
230
+ position: absolute;
231
+ inset: 0;
232
+ background-color: t.color('on-surface');
233
+ opacity: 0.12;
234
+ pointer-events: none;
235
+ border-radius: inherit;
168
236
  }
169
237
 
170
238
  &.#{$component}--selected {
171
239
  background-color: t.color('secondary-container');
172
240
  color: t.color('on-secondary-container');
173
241
 
174
- &:hover {
175
- @include m.state-layer(t.color('on-secondary-container'), 'hover');
242
+ &:hover::after {
243
+ content: '';
244
+ position: absolute;
245
+ inset: 0;
246
+ background-color: t.color('on-secondary-container');
247
+ opacity: 0.08;
248
+ pointer-events: none;
249
+ border-radius: inherit;
176
250
  }
177
251
  }
178
252
  }
179
253
 
180
- // Filter chip specific styling
254
+ // Filter chip
181
255
  &--filter {
182
- background-color: t.color('surface-container-highest');
256
+
183
257
  color: t.color('on-surface');
258
+ position: relative;
259
+ border: 1px solid t.alpha('outline', v.chip('outlined-border-opacity'));
184
260
 
185
- &:hover {
186
- @include m.state-layer(t.color('on-surface'), 'hover');
261
+ // Hover state for unselected chips
262
+ &:hover::after {
263
+ content: '';
264
+ position: absolute;
265
+ inset: 0;
266
+ background-color: t.color('on-surface');
267
+ opacity: 0.08;
268
+ pointer-events: none;
269
+ border-radius: inherit;
187
270
  }
188
271
 
189
272
  &.#{$component}--selected {
273
+
274
+ padding-left: 8px;
190
275
  background-color: t.color('secondary-container');
191
276
  color: t.color('on-secondary-container');
192
-
277
+ --checkmark-color: currentColor; // Will inherit from text color
278
+ border: none;
193
279
  .#{$component}-leading-icon {
194
280
  color: t.color('on-secondary-container');
195
281
  }
282
+
283
+ // Use ::before exclusively for the checkmark icon with mask technique
284
+ &::before {
285
+ content: '';
286
+ display: inline-block;
287
+ width: 18px;
288
+ height: 18px;
289
+ background-color: var(--checkmark-color);
290
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z'/%3E%3C/svg%3E");
291
+ mask-position: center;
292
+ mask-repeat: no-repeat;
293
+ mask-size: contain;
294
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z'/%3E%3C/svg%3E");
295
+ -webkit-mask-position: center;
296
+ -webkit-mask-repeat: no-repeat;
297
+ -webkit-mask-size: contain;
298
+ margin-right: 8px;
299
+ flex-shrink: 0;
300
+ position: static;
301
+ animation: checkmark-appear v.motion('duration-short4') v.motion('easing-emphasized') forwards;
302
+ }
303
+
304
+ // Hover state for selected chips
305
+ &:hover::after {
306
+ content: '';
307
+ position: absolute;
308
+ inset: 0;
309
+ background-color: t.color('on-secondary-container');
310
+ opacity: 0.08;
311
+ pointer-events: none;
312
+ border-radius: inherit;
313
+ }
196
314
  }
197
315
  }
198
316
 
199
- // Assist chip specific styling
317
+ // Assist chip
200
318
  &--assist {
201
319
  background-color: t.color('surface-container-low');
202
320
  color: t.color('on-surface');
@@ -205,6 +323,16 @@ $component: '#{base.$prefix}-chip';
205
323
  color: t.color('primary');
206
324
  }
207
325
 
326
+ &:hover::after {
327
+ content: '';
328
+ position: absolute;
329
+ inset: 0;
330
+ background-color: t.color('on-surface');
331
+ opacity: 0.08;
332
+ pointer-events: none;
333
+ border-radius: inherit;
334
+ }
335
+
208
336
  &.#{$component}--selected {
209
337
  background-color: t.color('secondary-container');
210
338
  color: t.color('on-secondary-container');
@@ -212,13 +340,24 @@ $component: '#{base.$prefix}-chip';
212
340
  .#{$component}-leading-icon {
213
341
  color: t.color('on-secondary-container');
214
342
  }
343
+
344
+ &:hover::after {
345
+ content: '';
346
+ position: absolute;
347
+ inset: 0;
348
+ background-color: t.color('on-secondary-container');
349
+ opacity: 0.08;
350
+ pointer-events: none;
351
+ border-radius: inherit;
352
+ }
215
353
  }
216
354
  }
217
355
 
218
- // Input chip specific styling
356
+ // Input chip
219
357
  &--input {
220
358
  background-color: t.color('surface-container-highest');
221
359
  color: t.color('on-surface');
360
+ border-radius: v.chip('border-radius');
222
361
 
223
362
  .#{$component}-trailing-icon {
224
363
  cursor: pointer;
@@ -227,89 +366,160 @@ $component: '#{base.$prefix}-chip';
227
366
  color: t.color('error');
228
367
  }
229
368
  }
369
+
370
+ &:hover::after {
371
+ content: '';
372
+ position: absolute;
373
+ inset: 0;
374
+ background-color: t.color('on-surface');
375
+ opacity: 0.08;
376
+ pointer-events: none;
377
+ border-radius: inherit;
378
+ }
230
379
  }
231
380
 
232
- // Suggestion chip styling
381
+ // Suggestion chip
233
382
  &--suggestion {
234
383
  background-color: t.color('surface-container');
235
384
  color: t.color('on-surface');
385
+ height: v.chip('suggestion-height');
386
+
387
+ .#{$component}-leading-icon {
388
+ width: v.chip('suggestion-icon-size');
389
+ height: v.chip('suggestion-icon-size');
390
+
391
+ svg {
392
+ width: v.chip('suggestion-icon-size');
393
+ height: v.chip('suggestion-icon-size');
394
+ }
395
+ }
396
+
397
+ &:hover::after {
398
+ content: '';
399
+ position: absolute;
400
+ inset: 0;
401
+ background-color: t.color('on-surface');
402
+ opacity: 0.08;
403
+ pointer-events: none;
404
+ border-radius: inherit;
405
+ }
236
406
 
237
407
  &.#{$component}--selected {
238
408
  background-color: t.color('secondary-container');
239
409
  color: t.color('on-secondary-container');
240
- }
241
- }
242
-
243
- // Size variants
244
- &--small {
245
- height: 24px;
246
- padding: 0 8px;
247
- font-size: 12px;
248
-
249
- .#{$component}-leading-icon,
250
- .#{$component}-trailing-icon {
251
- width: 16px;
252
- height: 16px;
253
410
 
254
- svg {
255
- width: 16px;
256
- height: 16px;
411
+ &:hover::after {
412
+ content: '';
413
+ position: absolute;
414
+ inset: 0;
415
+ background-color: t.color('on-secondary-container');
416
+ opacity: 0.08;
417
+ pointer-events: none;
418
+ border-radius: inherit;
257
419
  }
258
420
  }
259
421
  }
422
+ }
423
+
424
+ // Animation for checkmark appearance
425
+ @keyframes checkmark-appear {
426
+ from {
427
+ transform: scale(0);
428
+ opacity: 0;
429
+ }
430
+ to {
431
+ transform: scale(1);
432
+ opacity: 1;
433
+ }
434
+ }
435
+
436
+ // Chips container
437
+ .#{$container} {
438
+ display: flex;
439
+ flex-wrap: wrap;
440
+ gap: v.spacing('2');
441
+ width: 100%;
442
+ min-height: fit-content;
443
+ height: auto;
260
444
 
261
- &--medium {
262
- // Default size, styles already defined
445
+ // Label styling
446
+ &-label {
447
+ @include m.typography('title-medium');
448
+ color: t.color('on-surface-variant');
449
+ margin-bottom: v.spacing('2');
450
+ display: block;
451
+ width: 100%;
263
452
  }
264
453
 
265
- &--large {
266
- height: 40px;
267
- padding: 0 16px;
268
- font-size: 16px;
454
+ // Layout with label
455
+ &--with-label {
456
+ display: flex;
457
+ flex-direction: column;
269
458
 
270
- .#{$component}-leading-icon,
271
- .#{$component}-trailing-icon {
272
- width: 20px;
273
- height: 20px;
459
+ // When label is at the end
460
+ &.#{$container}--label-end {
461
+ flex-direction: column-reverse;
274
462
 
275
- svg {
276
- width: 20px;
277
- height: 20px;
463
+ .#{$container}-label {
464
+ margin-bottom: 0;
465
+ margin-top: v.spacing('2');
278
466
  }
279
467
  }
280
468
  }
281
- }
282
-
283
- // Chip set container
284
- .#{base.$prefix}-chip-set {
285
- display: flex;
286
- flex-wrap: wrap;
287
- gap: 8px;
288
469
 
470
+ // Container for chips
471
+ &-container {
472
+ display: flex;
473
+ flex-wrap: wrap;
474
+ gap: v.spacing('2');
475
+ width: 100%;
476
+ }
477
+
478
+ // Important: Scrollable state only affects the container, not the chip icons
289
479
  &--scrollable {
290
- flex-wrap: nowrap;
291
- overflow-x: auto;
292
- padding-bottom: 8px;
293
- margin-bottom: -8px; // Compensate for padding to maintain vertical alignment
294
- -webkit-overflow-scrolling: touch; // Smooth scrolling on iOS
295
-
296
- // Hide scrollbar in various browsers while maintaining functionality
297
- &::-webkit-scrollbar {
298
- height: 4px;
299
- }
300
-
301
- &::-webkit-scrollbar-thumb {
302
- background-color: t.alpha('on-surface', 0.2);
303
- border-radius: 4px;
480
+ .#{$container}-container {
481
+ flex-wrap: nowrap;
482
+ overflow-x: auto;
483
+ overflow-y: visible; // Don't clip chips vertically
484
+ -webkit-overflow-scrolling: touch;
485
+ scroll-behavior: smooth;
486
+ padding-bottom: v.spacing('2');
487
+
488
+ // Enhanced scrollable behavior
489
+ position: relative;
490
+ white-space: nowrap;
491
+
492
+ // Improved scrollbar styling
493
+ &::-webkit-scrollbar {
494
+ height: 4px;
495
+ }
496
+
497
+ &::-webkit-scrollbar-thumb {
498
+ background-color: t.alpha('on-surface', 0.2);
499
+ border-radius: 4px;
500
+ }
501
+
502
+ &::-webkit-scrollbar-track {
503
+ background-color: t.alpha('on-surface', 0.05);
504
+ border-radius: 4px;
505
+ }
506
+
507
+ // Style for Firefox
508
+ scrollbar-width: thin;
509
+ scrollbar-color: t.alpha('on-surface', 0.2) t.alpha('on-surface', 0.05);
510
+
511
+ // Ensure chip visibility without affecting internal structure
512
+ .#{$component} {
513
+ flex-shrink: 0; // Prevent chips from shrinking
514
+ }
304
515
  }
305
-
306
- // Style for Firefox
307
- scrollbar-width: thin;
308
- scrollbar-color: t.alpha('on-surface', 0.2) transparent;
309
516
  }
310
517
 
311
518
  &--vertical {
312
- flex-direction: column;
313
- align-items: flex-start;
519
+ .#{$container}-container {
520
+ flex-direction: column;
521
+ align-items: flex-start;
522
+ gap: v.spacing('2');
523
+ }
314
524
  }
315
525
  }