|
1 | | -@use 'sass:map'; |
2 | | -@use '@material/fab' as mdc-fab; |
3 | | -@use '@material/fab/extended-fab-theme' as mdc-extended-fab-theme; |
4 | | -@use '@material/fab/fab-theme' as mdc-fab-theme; |
5 | | -@use '@material/fab/fab-small-theme' as mdc-fab-small-theme; |
6 | | -@use '@material/typography/typography' as mdc-typography; |
7 | | -@use '@material/theme/custom-properties' as mdc-custom-properties; |
8 | | - |
9 | 1 | @use './button-base'; |
10 | | -@use '../core/mdc-helpers/mdc-helpers'; |
11 | 2 | @use '../core/tokens/token-utils'; |
12 | 3 | @use '../core/style/private' as style-private; |
| 4 | +@use '../core/style/vendor-prefixes'; |
13 | 5 | @use '../core/focus-indicators/private' as focus-indicators-private; |
14 | 6 | @use '../core/tokens/m2/mdc/extended-fab' as tokens-mdc-extended-fab; |
15 | 7 | @use '../core/tokens/m2/mdc/fab' as tokens-mdc-fab; |
16 | 8 | @use '../core/tokens/m2/mat/fab' as tokens-mat-fab; |
17 | 9 | @use '../core/tokens/m2/mdc/fab-small' as tokens-mdc-fab-small; |
18 | 10 | @use '../core/tokens/m2/mat/fab-small' as tokens-mat-fab-small; |
19 | 11 |
|
20 | | -@include mdc-custom-properties.configure($emit-fallback-values: false, $emit-fallback-vars: false) { |
21 | | - $mdc-fab-token-slots: tokens-mdc-fab.get-token-slots(); |
22 | | - $mdc-fab-small-token-slots: tokens-mdc-fab-small.get-token-slots(); |
23 | | - $mdc-extended-fab-token-slots: tokens-mdc-extended-fab.get-token-slots(); |
24 | | - $exclude-tokens: ( |
25 | | - // Exclude the elevation tokens here since we output them manually below. |
26 | | - container-elevation: null, |
27 | | - focus-container-elevation: null, |
28 | | - hover-container-elevation: null, |
29 | | - pressed-container-elevation: null, |
30 | | - container-shadow-color: null, |
31 | | - ); |
| 12 | +.mat-mdc-fab-base { |
| 13 | + @include button-base.mat-private-button-interactive(); |
| 14 | + @include style-private.private-animation-noop(); |
| 15 | + @include vendor-prefixes.user-select(none); |
| 16 | + position: relative; |
| 17 | + display: inline-flex; |
| 18 | + align-items: center; |
| 19 | + justify-content: center; |
| 20 | + box-sizing: border-box; |
| 21 | + width: 56px; |
| 22 | + height: 56px; |
| 23 | + padding: 0; |
| 24 | + border: none; |
| 25 | + fill: currentColor; |
| 26 | + text-decoration: none; |
| 27 | + cursor: pointer; |
| 28 | + -moz-appearance: none; |
| 29 | + -webkit-appearance: none; |
| 30 | + overflow: visible; |
| 31 | + transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1), opacity 15ms linear 30ms, |
| 32 | + transform 270ms 0ms cubic-bezier(0, 0, 0.2, 1); |
| 33 | + flex-shrink: 0; // Prevent the button from shrinking since it's always supposed to be a circle. |
32 | 34 |
|
33 | | - // Note: it's important to pass the query here, otherwise MDC generates |
34 | | - // some unnecessary typography styles for the extended FAB. |
35 | | - @include mdc-fab.static-styles($query: mdc-helpers.$mdc-base-styles-query); |
| 35 | + &::before { |
| 36 | + position: absolute; |
| 37 | + box-sizing: border-box; |
| 38 | + width: 100%; |
| 39 | + height: 100%; |
| 40 | + top: 0; |
| 41 | + left: 0; |
| 42 | + border: 1px solid transparent; |
| 43 | + border-radius: inherit; |
| 44 | + content: ''; |
| 45 | + pointer-events: none; |
| 46 | + } |
36 | 47 |
|
37 | | - .mat-mdc-fab { |
38 | | - @include mdc-fab-theme.theme-styles(map.merge($mdc-fab-token-slots, $exclude-tokens)); |
| 48 | + // MDC used to include this and it seems like a lot of apps depend on it. |
| 49 | + &[hidden] { |
| 50 | + display: none; |
39 | 51 | } |
40 | 52 |
|
41 | | - .mat-mdc-mini-fab { |
42 | | - @include mdc-fab-small-theme.theme-styles( |
43 | | - map.merge($mdc-fab-small-token-slots, $exclude-tokens)); |
| 53 | + &::-moz-focus-inner { |
| 54 | + padding: 0; |
| 55 | + border: 0; |
44 | 56 | } |
45 | 57 |
|
46 | | - .mat-mdc-extended-fab { |
47 | | - // Before tokens MDC included the font smoothing automatically, but with |
48 | | - // tokens it doesn't. We add it since it can cause tiny differences in |
49 | | - // screenshot tests and it generally looks better. |
50 | | - @include mdc-typography.smooth-font(); |
51 | | - @include mdc-extended-fab-theme.theme-styles( |
52 | | - map.merge($mdc-extended-fab-token-slots, $exclude-tokens)); |
| 58 | + &:active, &:focus { |
| 59 | + outline: none; |
53 | 60 | } |
54 | | -} |
55 | 61 |
|
56 | | -.mat-mdc-fab, .mat-mdc-mini-fab { |
57 | | - @include button-base.mat-private-button-interactive(); |
58 | | - @include style-private.private-animation-noop(); |
59 | | - flex-shrink: 0; // Prevent the button from shrinking since it's always supposed to be a circle. |
| 62 | + &:hover { |
| 63 | + cursor: pointer; |
| 64 | + } |
60 | 65 |
|
61 | | - // MDC adds some styles to fab and mini-fab that conflict with some of our focus indicator |
62 | | - // styles and don't actually do anything. This undoes those conflicting styles. |
63 | | - &:not(.mdc-ripple-upgraded):focus::before { |
64 | | - background: transparent; |
65 | | - opacity: 1; |
| 66 | + & > svg { |
| 67 | + width: 100%; |
66 | 68 | } |
67 | 69 |
|
68 | 70 | // MDC expects the fab icon to contain this HTML content: |
|
73 | 75 | // mixin will style the icons appropriately. |
74 | 76 | // stylelint-disable-next-line selector-class-pattern |
75 | 77 | .mat-icon, .material-icons { |
76 | | - @include mdc-fab.icon_(); |
| 78 | + transition: transform 180ms 90ms cubic-bezier(0, 0, 0.2, 1); |
| 79 | + fill: currentColor; |
| 80 | + will-change: transform; |
77 | 81 | } |
78 | 82 |
|
79 | 83 | .mat-mdc-focus-indicator::before { |
|
93 | 97 |
|
94 | 98 | @mixin _fab-elevation($mdc-tokens) { |
95 | 99 | @include token-utils.use-tokens($mdc-tokens...) { |
96 | | - @include button-base.mat-private-button-elevation(container-elevation); |
| 100 | + @include token-utils.create-token-slot(box-shadow, container-elevation-shadow); |
97 | 101 |
|
98 | 102 | &:hover { |
99 | | - @include button-base.mat-private-button-elevation(hover-container-elevation); |
| 103 | + @include token-utils.create-token-slot(box-shadow, hover-container-elevation-shadow); |
100 | 104 | } |
101 | 105 |
|
102 | 106 | &:focus { |
103 | | - @include button-base.mat-private-button-elevation(focus-container-elevation); |
| 107 | + @include token-utils.create-token-slot(box-shadow, focus-container-elevation-shadow); |
104 | 108 | } |
105 | 109 |
|
106 | 110 | &:active, &:focus:active { |
107 | | - @include button-base.mat-private-button-elevation(pressed-container-elevation); |
| 111 | + @include token-utils.create-token-slot(box-shadow, pressed-container-elevation-shadow); |
108 | 112 | } |
109 | 113 | } |
110 | 114 | } |
|
113 | 117 | @include button-base.mat-private-button-touch-target(true, $mat-tokens...); |
114 | 118 | @include button-base.mat-private-button-ripple($mat-tokens...); |
115 | 119 |
|
116 | | - @include mdc-helpers.disable-mdc-fallback-declarations { |
117 | | - @include token-utils.use-tokens($mat-tokens...) { |
118 | | - @include token-utils.create-token-slot(color, foreground-color, inherit); |
119 | | - } |
| 120 | + @include token-utils.use-tokens($mdc-tokens...) { |
| 121 | + @include token-utils.create-token-slot(background-color, container-color); |
| 122 | + @include token-utils.create-token-slot(border-radius, container-shape); |
| 123 | + } |
| 124 | + |
| 125 | + @include token-utils.use-tokens($mat-tokens...) { |
| 126 | + @include token-utils.create-token-slot(color, foreground-color, inherit); |
120 | 127 | } |
121 | 128 |
|
122 | 129 | @include _fab-elevation($mdc-tokens); |
|
137 | 144 | } |
138 | 145 |
|
139 | 146 | .mat-mdc-mini-fab { |
| 147 | + width: 40px; |
| 148 | + height: 40px; |
| 149 | + |
140 | 150 | @include _fab-structure( |
141 | 151 | (tokens-mdc-fab-small.$prefix, tokens-mdc-fab-small.get-token-slots()), |
142 | 152 | (tokens-mat-fab-small.$prefix, tokens-mat-fab-small.get-token-slots()), |
143 | 153 | ); |
144 | 154 | } |
145 | 155 |
|
146 | 156 | .mat-mdc-extended-fab { |
147 | | - @include _fab-elevation((tokens-mdc-extended-fab.$prefix, |
148 | | - tokens-mdc-extended-fab.get-token-slots())); |
| 157 | + $mdc-tokens: (tokens-mdc-extended-fab.$prefix, tokens-mdc-extended-fab.get-token-slots()); |
| 158 | + |
| 159 | + // Before tokens MDC included the font smoothing automatically, but with |
| 160 | + // tokens it doesn't. We add it since it can cause tiny differences in |
| 161 | + // screenshot tests and it generally looks better. |
| 162 | + @include vendor-prefixes.smooth-font(); |
| 163 | + border-radius: 24px; |
| 164 | + padding-left: 20px; |
| 165 | + padding-right: 20px; |
| 166 | + width: auto; |
| 167 | + max-width: 100%; |
| 168 | + line-height: normal; |
| 169 | + |
| 170 | + @include _fab-elevation($mdc-tokens); |
149 | 171 |
|
150 | 172 | @include button-base.mat-private-button-disabled { |
151 | 173 | // Necessary for interactive disabled buttons. |
|
154 | 176 | } |
155 | 177 | } |
156 | 178 |
|
157 | | - & > .mat-icon, |
158 | | - & > .material-icons { // stylelint-disable-line selector-class-pattern |
159 | | - @include mdc-fab.extended-icon-padding( |
160 | | - mdc-fab.$extended-icon-padding, |
161 | | - mdc-fab.$extended-label-padding |
162 | | - ); |
| 179 | + @include token-utils.use-tokens($mdc-tokens...) { |
| 180 | + @include token-utils.create-token-slot(height, container-height); |
| 181 | + @include token-utils.create-token-slot(border-radius, container-shape); |
| 182 | + @include token-utils.create-token-slot(font-family, label-text-font); |
| 183 | + @include token-utils.create-token-slot(font-size, label-text-size); |
| 184 | + @include token-utils.create-token-slot(font-weight, label-text-weight); |
| 185 | + @include token-utils.create-token-slot(letter-spacing, label-text-tracking); |
| 186 | + } |
| 187 | + |
| 188 | + // stylelint-disable selector-class-pattern |
| 189 | + // For Extended FAB with text label followed by icon. |
| 190 | + // We are checking for the a button class because white this is a FAB it |
| 191 | + // uses the same template as button. |
| 192 | + [dir='rtl'] & .mdc-button__label + .mat-icon, |
| 193 | + [dir='rtl'] & .mdc-button__label + .material-icons, |
| 194 | + > .mat-icon, |
| 195 | + > .material-icons { |
| 196 | + margin-left: -8px; |
| 197 | + margin-right: 12px; |
163 | 198 | } |
164 | 199 |
|
| 200 | + .mdc-button__label + .mat-icon, |
| 201 | + .mdc-button__label + .material-icons, |
| 202 | + [dir='rtl'] & > .mat-icon, |
| 203 | + [dir='rtl'] & > .material-icons { |
| 204 | + margin-left: 12px; |
| 205 | + margin-right: -8px; |
| 206 | + } |
| 207 | + // stylelint-enable selector-class-pattern |
| 208 | + |
165 | 209 | // All FABs are square except the extended ones so we |
166 | 210 | // need to set the touch target back to full-width. |
167 | 211 | .mat-mdc-button-touch-target { |
168 | 212 | width: 100%; |
169 | 213 | } |
170 | | - |
171 | | - // For Extended FAB with text label followed by icon. |
172 | | - // We are checking for the a button class because white this is a FAB it |
173 | | - // uses the same template as button. |
174 | | - // stylelint-disable-next-line selector-class-pattern |
175 | | - .mdc-button__label + .mat-icon, .mdc-button__label + .material-icons { |
176 | | - @include mdc-fab.extended-icon-padding( |
177 | | - mdc-fab.$extended-icon-padding, |
178 | | - mdc-fab.$extended-label-padding, |
179 | | - $is-icon-at-end: true |
180 | | - ); |
181 | | - } |
182 | 214 | } |
183 | 215 |
|
0 commit comments