mtrl 0.8.0 → 0.9.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 (245) hide show
  1. package/dist/components/badge/config.d.ts +2 -2
  2. package/dist/components/bottom-sheet/bottom-sheet.js +1 -1
  3. package/dist/components/bottom-sheet/config.d.ts +2 -2
  4. package/dist/components/bottom-sheet/features/drag.d.ts +2 -2
  5. package/dist/components/bottom-sheet/features/drag.js +1 -1
  6. package/dist/components/button/api.d.ts +3 -3
  7. package/dist/components/button/button.d.ts +1 -1
  8. package/dist/components/button/config.d.ts +2 -2
  9. package/dist/components/button/features/progress.d.ts +17 -5
  10. package/dist/components/button-group/config.d.ts +20 -0
  11. package/dist/components/card/api.d.ts +10 -1
  12. package/dist/components/card/api.js +6 -1
  13. package/dist/components/card/card.js +1 -1
  14. package/dist/components/card/config.d.ts +15 -9
  15. package/dist/components/card/features.d.ts +2 -1
  16. package/dist/components/card/types.d.ts +5 -4
  17. package/dist/components/carousel/config.d.ts +2 -2
  18. package/dist/components/checkbox/config.d.ts +2 -2
  19. package/dist/components/checkbox/types.d.ts +15 -16
  20. package/dist/components/chips/api.d.ts +6 -6
  21. package/dist/components/chips/chip/api.d.ts +2 -2
  22. package/dist/components/chips/chip/config.d.ts +6 -7
  23. package/dist/components/chips/config.d.ts +2 -2
  24. package/dist/components/chips/features/dom.js +0 -1
  25. package/dist/components/chips/types.d.ts +12 -1
  26. package/dist/components/datepicker/api.d.ts +5 -2
  27. package/dist/components/datepicker/config.d.ts +16 -13
  28. package/dist/components/datepicker/datepicker.js +10 -4
  29. package/dist/components/datepicker/render.d.ts +14 -6
  30. package/dist/components/datepicker/render.js +1 -1
  31. package/dist/components/datepicker/types.d.ts +51 -3
  32. package/dist/components/dialog/api.d.ts +1 -1
  33. package/dist/components/dialog/config.d.ts +3 -4
  34. package/dist/components/dialog/config.js +1 -1
  35. package/dist/components/dialog/features.js +1 -1
  36. package/dist/components/dialog/types.d.ts +1 -1
  37. package/dist/components/divider/features.js +2 -0
  38. package/dist/components/drawer/api.d.ts +3 -3
  39. package/dist/components/drawer/config.d.ts +2 -2
  40. package/dist/components/drawer/drawer.d.ts +1 -1
  41. package/dist/components/drawer/features/headline.d.ts +12 -2
  42. package/dist/components/drawer/features/items.d.ts +17 -3
  43. package/dist/components/drawer/features/state.d.ts +14 -2
  44. package/dist/components/extended-fab/api.d.ts +12 -4
  45. package/dist/components/extended-fab/api.js +12 -0
  46. package/dist/components/extended-fab/config.d.ts +10 -10
  47. package/dist/components/extended-fab/types.d.ts +4 -2
  48. package/dist/components/fab/api.d.ts +9 -2
  49. package/dist/components/fab/api.js +12 -0
  50. package/dist/components/fab/config.d.ts +8 -8
  51. package/dist/components/fab/types.d.ts +2 -1
  52. package/dist/components/icon-button/config.d.ts +2 -2
  53. package/dist/components/icon-button/features/toggle.d.ts +1 -5
  54. package/dist/components/icon-button/types.d.ts +6 -0
  55. package/dist/components/list/api.d.ts +18 -18
  56. package/dist/components/list/config.d.ts +6 -3
  57. package/dist/components/list/config.js +6 -7
  58. package/dist/components/list/features/renderer.js +2 -2
  59. package/dist/components/list/list.d.ts +20 -1
  60. package/dist/components/list/types.d.ts +32 -32
  61. package/dist/components/loading-indicator/config.d.ts +2 -2
  62. package/dist/components/loading-indicator/types.d.ts +3 -1
  63. package/dist/components/menu/api.d.ts +6 -5
  64. package/dist/components/menu/config.d.ts +2 -2
  65. package/dist/components/menu/features/keyboard.d.ts +19 -9
  66. package/dist/components/menu/types.d.ts +25 -9
  67. package/dist/components/navigation/config.d.ts +2 -2
  68. package/dist/components/navigation/features/controller.d.ts +1 -3
  69. package/dist/components/navigation/features/items.d.ts +1 -2
  70. package/dist/components/navigation/system/core.d.ts +6 -6
  71. package/dist/components/navigation/system/events.d.ts +3 -3
  72. package/dist/components/navigation/system/mobile.d.ts +6 -6
  73. package/dist/components/navigation/system/state.d.ts +3 -3
  74. package/dist/components/navigation/system/types.d.ts +43 -11
  75. package/dist/components/navigation/types.d.ts +15 -6
  76. package/dist/components/progress/api.js +0 -1
  77. package/dist/components/progress/config.d.ts +2 -2
  78. package/dist/components/progress/features/canvas.d.ts +14 -5
  79. package/dist/components/progress/features/state.d.ts +1 -2
  80. package/dist/components/progress/types.d.ts +1 -1
  81. package/dist/components/radios/config.d.ts +2 -2
  82. package/dist/components/search/api.js +4 -4
  83. package/dist/components/search/config.d.ts +2 -2
  84. package/dist/components/search/features/suggestions.d.ts +1 -3
  85. package/dist/components/search/features/suggestions.js +5 -5
  86. package/dist/components/search/search.js +1 -1
  87. package/dist/components/segmented-button/config.d.ts +1 -5
  88. package/dist/components/segmented-button/config.js +1 -1
  89. package/dist/components/select/api.d.ts +2 -2
  90. package/dist/components/select/features.d.ts +2 -2
  91. package/dist/components/select/features.js +2 -1
  92. package/dist/components/select/types.d.ts +38 -21
  93. package/dist/components/side-sheet/config.d.ts +2 -2
  94. package/dist/components/slider/api.d.ts +6 -6
  95. package/dist/components/slider/config.d.ts +2 -2
  96. package/dist/components/slider/types.d.ts +2 -2
  97. package/dist/components/snackbar/config.d.ts +2 -2
  98. package/dist/components/snackbar/features.d.ts +3 -3
  99. package/dist/components/snackbar/position.d.ts +1 -1
  100. package/dist/components/snackbar/types.d.ts +5 -6
  101. package/dist/components/split-button/api.js +1 -3
  102. package/dist/components/split-button/config.d.ts +2 -2
  103. package/dist/components/split-button/features/buttons.d.ts +3 -2
  104. package/dist/components/split-button/features/menu.d.ts +3 -2
  105. package/dist/components/split-button/types.d.ts +13 -2
  106. package/dist/components/switch/config.d.ts +2 -2
  107. package/dist/components/switch/types.d.ts +0 -1
  108. package/dist/components/tabs/api.d.ts +8 -5
  109. package/dist/components/tabs/config.d.ts +9 -1
  110. package/dist/components/tabs/features.d.ts +7 -11
  111. package/dist/components/tabs/features.js +2 -1
  112. package/dist/components/tabs/indicator.js +4 -2
  113. package/dist/components/tabs/responsive.js +2 -1
  114. package/dist/components/tabs/tab-api.d.ts +11 -5
  115. package/dist/components/tabs/tab-api.js +1 -1
  116. package/dist/components/tabs/tab.js +9 -1
  117. package/dist/components/tabs/types.d.ts +9 -2
  118. package/dist/components/tabs/utils.d.ts +14 -3
  119. package/dist/components/textfield/api.d.ts +1 -1
  120. package/dist/components/textfield/config.d.ts +2 -2
  121. package/dist/components/textfield/features/error.d.ts +1 -2
  122. package/dist/components/textfield/features/leading-icon.d.ts +1 -2
  123. package/dist/components/textfield/features/prefix-text.d.ts +1 -2
  124. package/dist/components/textfield/features/suffix-text.d.ts +1 -2
  125. package/dist/components/textfield/features/supporting-text.d.ts +1 -2
  126. package/dist/components/textfield/features/trailing-icon.d.ts +1 -2
  127. package/dist/components/textfield/types.d.ts +0 -2
  128. package/dist/components/timepicker/api.d.ts +5 -4
  129. package/dist/components/timepicker/config.d.ts +14 -11
  130. package/dist/components/tooltip/config.d.ts +2 -2
  131. package/dist/components/tooltip/tooltip.d.ts +1 -1
  132. package/dist/core/compose/base.d.ts +2 -2
  133. package/dist/core/compose/base.js +1 -1
  134. package/dist/core/compose/component.d.ts +13 -4
  135. package/dist/core/compose/component.js +1 -1
  136. package/dist/core/compose/features/badge.d.ts +3 -4
  137. package/dist/core/compose/features/badge.js +1 -1
  138. package/dist/core/compose/features/checkable.d.ts +3 -4
  139. package/dist/core/compose/features/debounce.d.ts +2 -3
  140. package/dist/core/compose/features/disabled.d.ts +1 -2
  141. package/dist/core/compose/features/events.d.ts +4 -3
  142. package/dist/core/compose/features/icon.d.ts +1 -5
  143. package/dist/core/compose/features/input.d.ts +2 -3
  144. package/dist/core/compose/features/lifecycle.d.ts +2 -2
  145. package/dist/core/compose/features/lifecycle.js +3 -3
  146. package/dist/core/compose/features/position.d.ts +1 -2
  147. package/dist/core/compose/features/ripple.d.ts +1 -2
  148. package/dist/core/compose/features/size.d.ts +1 -2
  149. package/dist/core/compose/features/style.d.ts +1 -2
  150. package/dist/core/compose/features/text.d.ts +1 -5
  151. package/dist/core/compose/features/textinput.d.ts +2 -3
  152. package/dist/core/compose/features/textlabel.d.ts +1 -2
  153. package/dist/core/compose/features/throttle.d.ts +1 -2
  154. package/dist/core/compose/features/track.d.ts +0 -1
  155. package/dist/core/compose/features/variant.d.ts +1 -2
  156. package/dist/core/compose/index.d.ts +1 -1
  157. package/dist/core/compose/pipe.d.ts +43 -3
  158. package/dist/core/compose/pipe.js +6 -2
  159. package/dist/core/compose/utils/type-guards.d.ts +4 -4
  160. package/dist/core/compose/utils/type-guards.js +1 -1
  161. package/dist/core/config/component.d.ts +12 -9
  162. package/dist/core/config/global.d.ts +12 -8
  163. package/dist/core/config.d.ts +1 -1
  164. package/dist/core/dom/attributes.d.ts +6 -6
  165. package/dist/core/dom/attributes.js +3 -2
  166. package/dist/core/dom/create.d.ts +27 -10
  167. package/dist/core/dom/create.js +0 -24
  168. package/dist/core/dom/utils.d.ts +1 -1
  169. package/dist/core/state/emitter.d.ts +2 -2
  170. package/dist/core/state/events.d.ts +3 -3
  171. package/dist/core/state/lifecycle.d.ts +0 -1
  172. package/dist/core/state/store.d.ts +3 -3
  173. package/dist/core/utils/object.d.ts +2 -2
  174. package/dist/core/utils/performance.d.ts +3 -3
  175. package/dist/core/utils/validate.d.ts +6 -6
  176. package/dist/core/utils/validate.js +13 -12
  177. package/dist/index.cjs +12 -12
  178. package/dist/package.json +1 -1
  179. package/dist/styles/badge.css +2 -2
  180. package/dist/styles/base.css +2 -2
  181. package/dist/styles/bottom-app-bar.css +2 -2
  182. package/dist/styles/bottom-sheet.css +2 -2
  183. package/dist/styles/button-group.css +2 -2
  184. package/dist/styles/button.css +2 -2
  185. package/dist/styles/card.css +2 -2
  186. package/dist/styles/carousel.css +2 -2
  187. package/dist/styles/checkbox.css +2 -2
  188. package/dist/styles/chips.css +2 -2
  189. package/dist/styles/dialog.css +2 -2
  190. package/dist/styles/divider.css +2 -2
  191. package/dist/styles/drawer.css +2 -2
  192. package/dist/styles/extended-fab.css +2 -2
  193. package/dist/styles/fab.css +2 -2
  194. package/dist/styles/icon-button.css +2 -2
  195. package/dist/styles/list.css +2 -2
  196. package/dist/styles/loading-indicator.css +2 -2
  197. package/dist/styles/menu.css +2 -2
  198. package/dist/styles/navigation-rail.css +2 -2
  199. package/dist/styles/navigation.css +2 -2
  200. package/dist/styles/progress.css +2 -2
  201. package/dist/styles/radios.css +2 -2
  202. package/dist/styles/search.css +2 -2
  203. package/dist/styles/segmented-button.css +2 -2
  204. package/dist/styles/select.css +2 -2
  205. package/dist/styles/side-sheet.css +2 -2
  206. package/dist/styles/slider.css +2 -2
  207. package/dist/styles/snackbar.css +2 -2
  208. package/dist/styles/split-button.css +2 -2
  209. package/dist/styles/switch.css +2 -2
  210. package/dist/styles/tabs.css +2 -2
  211. package/dist/styles/textfield.css +2 -2
  212. package/dist/styles/timepicker.css +2 -2
  213. package/dist/styles/tooltip.css +2 -0
  214. package/dist/styles/tooltip.d.ts +1 -0
  215. package/dist/styles/tooltip.js +2 -0
  216. package/dist/styles/top-app-bar.css +2 -2
  217. package/dist/styles/utilities.css +2 -2
  218. package/dist/styles.css +2 -2
  219. package/dist/themes/autumn.css +1 -1
  220. package/dist/themes/baseline.css +1 -1
  221. package/dist/themes/brownbeige.css +1 -1
  222. package/dist/themes/browngreen.css +1 -1
  223. package/dist/themes/desert.css +1 -1
  224. package/dist/themes/forest.css +1 -1
  225. package/dist/themes/highcontrast.css +1 -1
  226. package/dist/themes/legacy.css +1 -1
  227. package/dist/themes/material.css +1 -1
  228. package/dist/themes/ocean.css +1 -1
  229. package/dist/themes/sageivory.css +1 -1
  230. package/dist/themes/spring.css +1 -1
  231. package/dist/themes/summer.css +1 -1
  232. package/dist/themes/sunset.css +1 -1
  233. package/dist/themes/tealcaramel.css +1 -1
  234. package/dist/themes/winter.css +1 -1
  235. package/package.json +2 -2
  236. package/src/styles/abstract/_mixins.scss +5 -1
  237. package/src/styles/components/_checkbox.scss +27 -7
  238. package/src/styles/components/_chips.scss +13 -13
  239. package/src/styles/components/_datepicker.scss +5 -5
  240. package/src/styles/components/_dialog.scss +2 -2
  241. package/src/styles/components/_radios.scss +30 -30
  242. package/src/styles/components/_switch.scss +36 -26
  243. package/src/styles/components/_tabs.scss +59 -58
  244. package/src/styles/components/_timepicker.scss +3 -3
  245. package/src/styles/main.scss +1 -0
@@ -11,57 +11,57 @@ $component: '#{base.$prefix}-radios';
11
11
  display: flex;
12
12
  margin: 0;
13
13
  padding: 0;
14
-
14
+
15
15
  // Vertical layout (default)
16
16
  &--vertical {
17
17
  flex-direction: column;
18
-
18
+
19
19
  .#{$component}-item {
20
20
  margin-bottom: 12px;
21
-
21
+
22
22
  &:last-child {
23
23
  margin-bottom: 0;
24
24
  }
25
25
  }
26
26
  }
27
-
27
+
28
28
  // Horizontal layout
29
29
  &--horizontal {
30
30
  flex-direction: row;
31
31
  flex-wrap: wrap;
32
32
  align-items: flex-start;
33
-
33
+
34
34
  .#{$component}-item {
35
35
  margin-right: 16px;
36
-
36
+
37
37
  &:last-child {
38
38
  margin-right: 0;
39
39
  }
40
40
  }
41
41
  }
42
-
42
+
43
43
  // Disabled state
44
+ // No blanket dimming: DisabledSelectedIconOpacity and
45
+ // DisabledUnselectedIconOpacity are both 0.38, applied per role below.
44
46
  &--disabled {
45
- opacity: 0.6;
46
47
  pointer-events: none;
47
48
  }
48
-
49
+
49
50
  // Radio item
50
51
  &-item {
51
52
  position: relative;
52
53
  display: inline-flex;
53
54
  align-items: center;
54
-
55
+
55
56
  &--disabled {
56
57
  cursor: not-allowed;
57
- opacity: 0.6;
58
-
58
+
59
59
  .#{$component}-label {
60
60
  cursor: not-allowed;
61
61
  }
62
62
  }
63
63
  }
64
-
64
+
65
65
  // Radio input
66
66
  &-input {
67
67
  position: absolute;
@@ -70,41 +70,41 @@ $component: '#{base.$prefix}-radios';
70
70
  width: 0;
71
71
  margin: 0;
72
72
  padding: 0;
73
-
73
+
74
74
  // Focus styles
75
75
  &:focus ~ .#{$component}-label .#{$component}-ripple {
76
- background-color: t.alpha('primary', 0.12);
76
+ background-color: t.alpha('primary', v.state('focus-state-layer-opacity'));
77
77
  }
78
-
78
+
79
79
  // Checked styles
80
80
  &:checked ~ .#{$component}-label {
81
81
  .#{$component}-circle {
82
82
  border-color: t.color('primary');
83
83
  border-width: 1.5px;
84
-
84
+
85
85
  &:after {
86
86
  transform: translate(-50%, -50%) scale(1);
87
87
  opacity: 1;
88
88
  }
89
89
  }
90
90
  }
91
-
91
+
92
92
  // Disabled styles
93
93
  &:disabled ~ .#{$component}-label {
94
94
  .#{$component}-circle {
95
95
  border-color: t.alpha('on-surface', 0.38);
96
-
96
+
97
97
  &:after {
98
98
  background-color: t.alpha('on-surface', 0.38);
99
99
  }
100
100
  }
101
-
101
+
102
102
  .#{$component}-text {
103
103
  color: t.alpha('on-surface', 0.38);
104
104
  }
105
105
  }
106
106
  }
107
-
107
+
108
108
  // Radio label
109
109
  &-label {
110
110
  position: relative;
@@ -113,20 +113,20 @@ $component: '#{base.$prefix}-radios';
113
113
  cursor: pointer;
114
114
  padding: 8px 0;
115
115
  height: 48px;
116
-
116
+
117
117
  // Typography for label
118
118
  @include m.typography('body-medium');
119
-
119
+
120
120
  &--before {
121
121
  flex-direction: row-reverse;
122
-
122
+
123
123
  .#{$component}-text {
124
124
  margin-right: 12px;
125
125
  margin-left: 0;
126
126
  }
127
127
  }
128
128
  }
129
-
129
+
130
130
  // Radio control
131
131
  &-control {
132
132
  position: relative;
@@ -137,7 +137,7 @@ $component: '#{base.$prefix}-radios';
137
137
  height: 40px;
138
138
  flex-shrink: 0;
139
139
  }
140
-
140
+
141
141
  // Radio circle
142
142
  &-circle {
143
143
  position: relative;
@@ -147,7 +147,7 @@ $component: '#{base.$prefix}-radios';
147
147
  border-radius: 50%;
148
148
  box-sizing: border-box;
149
149
  transition: border-color 0.2s ease;
150
-
150
+
151
151
  &:after {
152
152
  content: '';
153
153
  position: absolute;
@@ -162,7 +162,7 @@ $component: '#{base.$prefix}-radios';
162
162
  transition: transform 0.15s ease, opacity 0.15s ease;
163
163
  }
164
164
  }
165
-
165
+
166
166
  // Ripple effect
167
167
  &-ripple {
168
168
  position: absolute;
@@ -172,13 +172,13 @@ $component: '#{base.$prefix}-radios';
172
172
  bottom: 0;
173
173
  border-radius: 50%;
174
174
  transition: background-color 0.15s ease;
175
-
175
+
176
176
  // Apply ripple effect on hover
177
177
  .#{$component}-input:not(:disabled) ~ .#{$component}-label:hover & {
178
178
  background-color: t.alpha('primary', 0.08);
179
179
  }
180
180
  }
181
-
181
+
182
182
  // Radio text
183
183
  &-text {
184
184
  margin-left: 8px;
@@ -71,7 +71,7 @@ $component: '#{base.$prefix}-switch';
71
71
  background-color: t.color('surface-container-highest');
72
72
  border: 2px solid t.color('outline');
73
73
  @include m.motion-transition(background-color, border-color, outline);
74
-
74
+
75
75
  // Ripple effect (consistent size for both hover and press)
76
76
  &::after {
77
77
  content: '';
@@ -101,7 +101,7 @@ $component: '#{base.$prefix}-switch';
101
101
  border-radius: 50%;
102
102
  background-color: t.color('outline');
103
103
  transform: translateX(0);
104
- transition: transform v.motion('duration-medium1') cubic-bezier(0.2, 1.4, 0.35, 1),
104
+ transition: transform v.motion('duration-medium1') cubic-bezier(0.2, 1.4, 0.35, 1),
105
105
  background-color v.motion('duration-medium1') v.motion('easing-emphasized'),
106
106
  width v.motion('duration-medium1') v.motion('easing-emphasized'),
107
107
  height v.motion('duration-medium1') v.motion('easing-emphasized'),
@@ -122,7 +122,7 @@ $component: '#{base.$prefix}-switch';
122
122
  transform: scale(0);
123
123
  transition: all v.motion('duration-short4') v.motion('easing-emphasized');
124
124
  color: t.color('primary');
125
-
125
+
126
126
  svg {
127
127
  width: 14px;
128
128
  height: 14px;
@@ -134,7 +134,7 @@ $component: '#{base.$prefix}-switch';
134
134
  &-helper {
135
135
  @include m.typography('body-medium');
136
136
  color: t.color('on-surface-variant');
137
-
137
+
138
138
  &--error {
139
139
  color: t.color('error');
140
140
  }
@@ -145,12 +145,12 @@ $component: '#{base.$prefix}-switch';
145
145
  &-container {
146
146
  flex-direction: row;
147
147
  }
148
-
148
+
149
149
  &-content {
150
150
  margin-left: 12px;
151
151
  margin-right: 0;
152
152
  }
153
-
153
+
154
154
  // Adjust thumb movement for RTL layout
155
155
  &--checked .#{$component}-thumb {
156
156
  transform: translateX(-20px);
@@ -162,7 +162,7 @@ $component: '#{base.$prefix}-switch';
162
162
  .#{$component}-track {
163
163
  background-color: t.color('primary');
164
164
  border-color: t.color('primary');
165
-
165
+
166
166
  &::after {
167
167
  transform: translateX(14px);
168
168
  }
@@ -196,29 +196,39 @@ $component: '#{base.$prefix}-switch';
196
196
  }
197
197
  }
198
198
 
199
- // Disabled state
199
+ // Disabled state. SwitchTokens splits these: DisabledTrackOpacity is 0.12, while
200
+ // the handle carries its own alpha — DisabledUnselectedHandleOpacity 0.38 over
201
+ // OnSurface, and DisabledSelectedHandleOpacity 1.0 over Surface. A single opacity on
202
+ // the track cascaded onto the handle, so no part matched its token.
200
203
  &--disabled {
201
204
  pointer-events: none;
205
+
202
206
  .#{$component}-track {
203
- opacity: 0.38;
207
+ background-color: t.alpha('on-surface', 0.12);
208
+ border-color: t.alpha('on-surface', 0.12);
204
209
  }
205
-
210
+
211
+ .#{$component}-thumb {
212
+ background-color: t.alpha('on-surface', 0.38);
213
+ }
214
+
206
215
  .#{$component}-label, .#{$component}-helper {
207
- opacity: 0.38;
216
+ color: t.alpha('on-surface', 0.38);
217
+ opacity: 1;
208
218
  }
209
-
210
- // Specific styles for disabled + checked
219
+
220
+ // Selected: the track keeps 0.12, and the handle is Surface at full opacity.
211
221
  &.#{$component}--checked {
212
222
  .#{$component}-track {
213
- background-color: t.color('outline');
214
- border-color: t.color('outline');
215
- opacity: 0.38;
223
+ background-color: t.alpha('on-surface', 0.12);
224
+ border-color: transparent;
216
225
  }
217
-
226
+
218
227
  .#{$component}-thumb {
219
- background-color: t.color('surface-dim');
228
+ background-color: t.color('surface');
229
+
220
230
  &-icon {
221
- color: t.color('on-surface');
231
+ color: t.alpha('on-surface', 0.38);
222
232
  }
223
233
  }
224
234
  }
@@ -239,19 +249,19 @@ $component: '#{base.$prefix}-switch';
239
249
  .#{$component}-thumb {
240
250
  background-color: t.color('on-surface-variant');
241
251
  }
242
-
252
+
243
253
  &::after {
244
254
  background-color: t.color('on-surface');
245
255
  opacity: v.state('hover-state-layer-opacity');
246
256
  transform: translateX(-6px);
247
257
  }
248
258
  }
249
-
259
+
250
260
  .#{$component}-input:active ~ .#{$component}-track::after {
251
261
  opacity: v.state('pressed-state-layer-opacity');
252
262
  }
253
263
  }
254
-
264
+
255
265
  // Hover/active states for checked
256
266
  &.#{$component}--checked {
257
267
  .#{$component}-input:hover ~ .#{$component}-track,
@@ -262,7 +272,7 @@ $component: '#{base.$prefix}-switch';
262
272
  transform: translateX(14px);
263
273
  }
264
274
  }
265
-
275
+
266
276
  .#{$component}-input:active ~ .#{$component}-track::after {
267
277
  opacity: v.state('pressed-state-layer-opacity');
268
278
  }
@@ -275,7 +285,7 @@ $component: '#{base.$prefix}-switch';
275
285
  top: 0;
276
286
  left: 0;
277
287
  }
278
-
288
+
279
289
  &.#{$component}--checked .#{$component}-input:active ~ .#{$component}-track .#{$component}-thumb {
280
290
  left: 0;
281
291
  }
@@ -294,12 +304,12 @@ $component: '#{base.$prefix}-switch';
294
304
  .#{$component}-track {
295
305
  border-width: 2px;
296
306
  }
297
-
307
+
298
308
  &--checked .#{$component}-track {
299
309
  border-color: currentColor;
300
310
  }
301
311
  }
302
-
312
+
303
313
  // Touch target for better mobile experience
304
314
  // @include m.touch-target;
305
315
  }
@@ -28,8 +28,9 @@ $container: "#{base.$prefix}-tabs";
28
28
 
29
29
  // Primary indicator specific styling
30
30
  .#{$container}-indicator {
31
- height: 4px;
32
- border-radius: 3px 3px 0 0;
31
+ // Height comes from the indicator's own option, defaulting to
32
+ // ActiveIndicatorHeight = 3dp; ActiveIndicatorShape is a 3px corner.
33
+ border-radius: 3px;
33
34
  background-color: t.color("primary");
34
35
  }
35
36
  }
@@ -38,18 +39,37 @@ $container: "#{base.$prefix}-tabs";
38
39
  min-height: 48px;
39
40
  // Tab indicator styling for secondary variant
40
41
  .#{$container}-indicator {
41
- height: 2px;
42
+ // TabRowDefaults.SecondaryIndicator takes the primary token for both the
43
+ // height and the colour (TabRow.kt:1080-1081).
42
44
  border-radius: 0;
43
- background-color: t.color("on-surface");
45
+ background-color: t.color("primary");
44
46
  }
45
47
  }
46
48
 
49
+ // A tab is built on a text button, which paints its own ::before state layer in
50
+ // currentColor. The tab paints its own per-variant layer below, so the button's
51
+ // would stack a second one over it. Keep the tab's.
52
+ .#{$component}::before {
53
+ content: none;
54
+ }
55
+
56
+ // Fixed form: Compose divides the row evenly (tabRowWidth / tabCount,
57
+ // TabRow.kt:443-447). Without `scrollable` the component never builds a scroll
58
+ // container, so the tabs are direct children of the root.
59
+ &:not(&--scrollable) > .#{$component} {
60
+ flex: 1;
61
+ }
62
+
47
63
  // Scrollable container
48
64
  &--scrollable {
49
65
  overflow: hidden;
50
66
 
51
67
  .#{$container}-scroll {
52
68
  display: flex;
69
+ // ScrollableTabRowEdgeStartPadding, applied at both edges: TabRow.kt:239
70
+ // documents it as the padding between the starting and ending edge and the
71
+ // tabs inside the row.
72
+ padding-inline: 52px;
53
73
  overflow-x: auto;
54
74
  scrollbar-width: none; // Firefox
55
75
  -ms-overflow-style: none; // IE and Edge
@@ -141,7 +161,9 @@ $container: "#{base.$prefix}-tabs";
141
161
  }
142
162
 
143
163
  // Tab Icon (3. Icon - optional)
144
- &-icon {
164
+ // The icon element the button builds carries mtrl-icon + mtrl-button-icon; a
165
+ // nested &-icon would concatenate onto the compound root and match nothing.
166
+ .#{base.$prefix}-button-icon {
145
167
  display: flex;
146
168
  align-items: center;
147
169
  justify-content: center;
@@ -157,44 +179,40 @@ $container: "#{base.$prefix}-tabs";
157
179
 
158
180
  // Ensure proper vertical spacing for icon and text
159
181
  &--icon-and-text {
160
- .#{$component}-icon {
182
+ .#{base.$prefix}-button-icon {
161
183
  margin-bottom: 4px;
162
184
  }
163
185
  }
164
186
 
165
187
  // Tab Text (4. Label)
166
- &-text {
188
+ .#{base.$prefix}-button-text {
167
189
  @include m.truncate;
168
190
  max-width: 100%;
169
191
  text-align: center;
170
192
  line-height: 1.2;
193
+ }
171
194
 
172
- .#{$component}--icon-only & {
173
- @include m.visually-hidden;
174
- }
195
+ // The modifier is on the tab root, so the label is a descendant of &, not of a
196
+ // second tab.
197
+ &--icon-only .#{base.$prefix}-button-text {
198
+ @include m.visually-hidden;
175
199
  }
176
200
 
177
- // Badge positioning (2. Badge - optional)
178
- .#{base.$prefix}-badge-wrapper {
179
- .#{base.$prefix}-badge {
180
- // Position for different tab layouts
181
- &--top-right {
182
- .#{$component}--icon-only & {
183
- top: 4px;
184
- right: 4px;
185
- }
186
-
187
- .#{$component}--text-only & {
188
- top: 8px;
189
- right: 8px;
190
- }
191
-
192
- .#{$component}--icon-and-text & {
193
- top: 4px;
194
- right: calc(50% - 20px);
195
- }
196
- }
197
- }
201
+ // Badge positioning (2. Badge - optional). The layout modifier is on the tab
202
+ // itself, so these hang off &, not off a nested tab.
203
+ &--icon-only .#{base.$prefix}-badge-wrapper .#{base.$prefix}-badge--top-right {
204
+ top: 4px;
205
+ right: 4px;
206
+ }
207
+
208
+ &--text-only .#{base.$prefix}-badge-wrapper .#{base.$prefix}-badge--top-right {
209
+ top: 8px;
210
+ right: 8px;
211
+ }
212
+
213
+ &--icon-and-text .#{base.$prefix}-badge-wrapper .#{base.$prefix}-badge--top-right {
214
+ top: 4px;
215
+ right: calc(50% - 20px);
198
216
  }
199
217
 
200
218
  // ACTIVE TAB STATES - PRIMARY VARIANT
@@ -203,7 +221,7 @@ $container: "#{base.$prefix}-tabs";
203
221
  &--active {
204
222
  color: t.color("primary");
205
223
  border-radius: 0;
206
- .#{$component}-icon {
224
+ .#{base.$prefix}-button-icon {
207
225
  color: t.color("primary");
208
226
  }
209
227
 
@@ -223,7 +241,7 @@ $container: "#{base.$prefix}-tabs";
223
241
  // Pressed state for active tabs
224
242
  &:active,
225
243
  &.#{$component}--pressed {
226
- background-color: t.alpha("primary", 0.12);
244
+ background-color: t.alpha("primary", v.state("pressed-state-layer-opacity"));
227
245
  border-radius: 5px 5px 0 0;
228
246
  }
229
247
  }
@@ -250,7 +268,7 @@ $container: "#{base.$prefix}-tabs";
250
268
  // Pressed state for inactive tabs
251
269
  &:active,
252
270
  &.#{$component}--pressed {
253
- background-color: t.alpha("on-surface-variant", 0.12);
271
+ background-color: t.alpha("on-surface-variant", v.state("pressed-state-layer-opacity"));
254
272
  border-radius: 5px 5px 0 0;
255
273
  }
256
274
  }
@@ -262,7 +280,7 @@ $container: "#{base.$prefix}-tabs";
262
280
  &--active {
263
281
  color: t.color("on-surface");
264
282
  border-radius: 0;
265
- .#{$component}-icon {
283
+ .#{base.$prefix}-button-icon {
266
284
  color: t.color("on-surface");
267
285
  }
268
286
 
@@ -282,7 +300,7 @@ $container: "#{base.$prefix}-tabs";
282
300
  // Pressed state for active tabs - secondary
283
301
  &:active,
284
302
  &.#{$component}--pressed {
285
- background-color: t.alpha("on-surface", 0.12);
303
+ background-color: t.alpha("on-surface", v.state("pressed-state-layer-opacity"));
286
304
  }
287
305
  }
288
306
 
@@ -308,33 +326,16 @@ $container: "#{base.$prefix}-tabs";
308
326
  // Pressed state for inactive tabs - secondary
309
327
  &:active,
310
328
  &.#{$component}--pressed {
311
- background-color: t.alpha("on-surface-variant", 0.12);
329
+ background-color: t.alpha("on-surface-variant", v.state("pressed-state-layer-opacity"));
312
330
  border-radius: 5px 5px 0 0;
313
331
  }
314
332
  }
315
333
  }
316
334
 
317
- // Ripple effect styling
318
- .#{$component}-ripple {
319
- position: absolute;
320
- top: 0;
321
- left: 0;
322
- right: 0;
323
- bottom: 0;
324
- overflow: hidden;
325
- border-radius: inherit;
326
- pointer-events: none;
327
-
328
- .ripple {
329
- position: absolute;
330
- border-radius: 50%;
331
- transform: scale(0);
332
- pointer-events: none;
333
- background-color: currentColor;
334
- opacity: 0.1;
335
- transform-origin: center;
336
- }
337
- }
335
+ // No ripple rules here: the ripple feature appends .mtrl-ripple with
336
+ // .mtrl-ripple-wave children, both styled by the ripple utility in the base
337
+ // bundle. What stood here addressed .mtrl-button.mtrl-tab-ripple and a bare
338
+ // .ripple, neither of which is ever emitted, and duplicated the utility besides.
338
339
  }
339
340
 
340
341
  // Tab panel styles
@@ -255,7 +255,7 @@ $component: '#{base.$prefix}-time-picker';
255
255
  }
256
256
 
257
257
  &:active {
258
- background-color: t.alpha('on-surface', 0.12);
258
+ background-color: t.alpha('on-surface', v.state('pressed-state-layer-opacity'));
259
259
  }
260
260
  }
261
261
 
@@ -331,7 +331,7 @@ $component: '#{base.$prefix}-time-picker';
331
331
  }
332
332
 
333
333
  &:active {
334
- background-color: t.alpha('on-surface', 0.12);
334
+ background-color: t.alpha('on-surface', v.state('pressed-state-layer-opacity'));
335
335
  }
336
336
 
337
337
  svg {
@@ -373,7 +373,7 @@ $component: '#{base.$prefix}-time-picker';
373
373
  }
374
374
 
375
375
  &:active {
376
- background-color: t.alpha('primary', 0.12);
376
+ background-color: t.alpha('primary', v.state('pressed-state-layer-opacity'));
377
377
  }
378
378
  }
379
379
 
@@ -67,6 +67,7 @@
67
67
  @use "./components/navigation" as navigation;
68
68
  @use "./components/navigation-rail" as navigation-rail;
69
69
  @use "./components/list" as list;
70
+ @use "./components/tooltip" as tooltip;
70
71
 
71
72
  @use "./utilities/ripple" as ripple;
72
73
  @use "./utilities/layout" as layout;