77@use ' ../core/tokens/m2/mat/legacy-button-toggle' as tokens-mat-legacy-button-toggle ;
88@use ' ../core/tokens/m2/mat/standard-button-toggle' as tokens-mat-standard-button-toggle ;
99
10- $standard-padding : 0 12px !default ;
11- $legacy-padding : 0 16px !default ;
12- $checkmark-padding : 12px !default ;
10+ $standard-padding : 12px !default ;
11+ $legacy-padding : 16px !default ;
12+ $_checkmark-size : 18px !default ;
13+ $_checkmark-margin : 12px ;
14+ $_checkmark-transition : 150ms 45ms cubic-bezier (0.4 , 0 , 0.2 , 1 );
1315
1416// TODO(crisbeto): these variables aren't used anymore and should be removed.
1517$legacy-height : 36px !default ;
@@ -104,13 +106,51 @@ $_standard-tokens: (
104106 .mat-icon svg {
105107 vertical-align : top ;
106108 }
109+ }
107110
108- .mat-pseudo-checkbox {
109- margin-right : $checkmark-padding ;
110- [dir = ' rtl' ] & {
111- margin-right : 0 ;
112- margin-left : $checkmark-padding ;
113- }
111+ .mat-button-toggle-checkbox-wrapper {
112+ display : inline-block ;
113+ justify-content : flex-start ;
114+ align-items : center ;
115+ width : 0 ;
116+ height : $_checkmark-size ;
117+ line-height : $_checkmark-size ;
118+ overflow : hidden ;
119+ box-sizing : border-box ;
120+ position : absolute ;
121+ top : 50% ;
122+ left : $legacy-padding ;
123+
124+ // Uses a 3d transform, because otherwise Safari has some some of rendering
125+ // artifact that adds a small gap between the two parts of the checkmark.
126+ transform : translate3d (0 , -50% , 0 );
127+
128+ [dir = ' rtl' ] & {
129+ left : auto ;
130+ right : $legacy-padding ;
131+ }
132+
133+ .mat-button-toggle-appearance-standard & {
134+ left : $standard-padding ;
135+ }
136+
137+ [dir = ' rtl' ] .mat-button-toggle-appearance-standard & {
138+ left : auto ;
139+ right : $standard-padding ;
140+ }
141+
142+ .mat-button-toggle-checked & {
143+ width : $_checkmark-size ;
144+ }
145+
146+ .mat-button-toggle-animations-enabled & {
147+ transition : width $_checkmark-transition ;
148+ }
149+
150+ // Disable the transition in vertical mode since it looks weird.
151+ // There should be a limited amount of usages anyway.
152+ .mat-button-toggle-vertical & {
153+ transition : none ;
114154 }
115155}
116156
@@ -219,7 +259,7 @@ $_standard-tokens: (
219259.mat-button-toggle-label-content {
220260 @include vendor-prefixes .user-select (none );
221261 display : inline-block ;
222- padding : $legacy-padding ;
262+ padding : 0 $legacy-padding ;
223263
224264 @include token-utils .use-tokens ($_legacy-tokens ...) {
225265 @include token-utils .create-token-slot (line-height , height );
@@ -229,7 +269,7 @@ $_standard-tokens: (
229269 position : relative ;
230270
231271 .mat-button-toggle-appearance-standard & {
232- padding : $standard-padding ;
272+ padding : 0 $standard-padding ;
233273
234274 @include token-utils .use-tokens ($_standard-tokens ...) {
235275 @include token-utils .create-token-slot (line-height , height );
@@ -292,6 +332,7 @@ $_standard-tokens: (
292332}
293333
294334.mat-button-toggle-button {
335+ $checkmark-spacing : $_checkmark-size + $_checkmark-margin ;
295336 border : 0 ;
296337 background : none ;
297338 color : inherit ;
@@ -302,6 +343,16 @@ $_standard-tokens: (
302343 width : 100% ; // Stretch the button in case the consumer set a custom width.
303344 cursor : pointer ;
304345
346+ .mat-button-toggle-animations-enabled & {
347+ transition : padding $_checkmark-transition ;
348+ }
349+
350+ // Disable the transition in vertical mode since it looks weird.
351+ // There should be a limited amount of usages anyway.
352+ .mat-button-toggle-vertical & {
353+ transition : none ;
354+ }
355+
305356 .mat-button-toggle-disabled & {
306357 cursor : default ;
307358 }
@@ -310,6 +361,22 @@ $_standard-tokens: (
310361 & ::-moz-focus-inner {
311362 border : 0 ;
312363 }
364+
365+ // Note that we use padding and `position: absolute` to show/hide the checkmark, instead of
366+ // just transitioning it between `width: 18px` and `width: 0`, because it was being shown/hidden
367+ // with `@if` before the transition was added and leaving it in the DOM while hidden can break
368+ // some pre-existing layouts.
369+ & :has (.mat-button-toggle-checkbox-wrapper ) {
370+ .mat-button-toggle-checked & {
371+ padding-left : $checkmark-spacing ;
372+ }
373+
374+ [dir = ' rtl' ] .mat-button-toggle-checked & {
375+ padding-left : 0 ;
376+ padding-right : $checkmark-spacing ;
377+ }
378+ }
379+
313380}
314381
315382// Change the border-radius of the focus indicator to match the
0 commit comments