Skip to content

Commit 798f5ae

Browse files
asyncLizcopybara-github
authored andcommitted
fix(button): allow overriding cursor using CSS
Prep to move some styles to the host, which allows for better host styling, like setting padding and text wrapping. It will also support host aria by not relying on `<button>` pseudo selectors. PiperOrigin-RevId: 579977848
1 parent 7d78580 commit 798f5ae

File tree

4 files changed

+107
-109
lines changed

4 files changed

+107
-109
lines changed

button/internal/_elevation.scss

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,50 +20,50 @@ $_md-sys-motion: tokens.md-sys-motion-values();
2020
transition-timing-function: map.get($_md-sys-motion, 'emphasized-easing');
2121
}
2222

23-
.button:disabled md-elevation {
23+
:host([disabled]) md-elevation {
2424
transition: none;
2525
}
2626

27-
.button {
27+
md-elevation {
2828
@include elevation.theme(
2929
(
3030
'level': var(--_container-elevation),
3131
'shadow-color': var(--_container-shadow-color),
3232
)
3333
);
34+
}
3435

35-
// apply elevation in order of focused, hovered, pressed, disabled
36-
// this ensures a button will have hover elevation after being focused
37-
&:focus {
38-
@include elevation.theme(
39-
(
40-
'level': var(--_focus-container-elevation),
41-
)
42-
);
43-
}
36+
// apply elevation in order of focused, hovered, pressed, disabled
37+
// this ensures a button will have hover elevation after being focused
38+
:host(:focus-within) md-elevation {
39+
@include elevation.theme(
40+
(
41+
'level': var(--_focus-container-elevation),
42+
)
43+
);
44+
}
4445

45-
&:hover {
46-
@include elevation.theme(
47-
(
48-
'level': var(--_hover-container-elevation),
49-
)
50-
);
51-
}
46+
:host(:hover) md-elevation {
47+
@include elevation.theme(
48+
(
49+
'level': var(--_hover-container-elevation),
50+
)
51+
);
52+
}
5253

53-
&:active {
54-
@include elevation.theme(
55-
(
56-
'level': var(--_pressed-container-elevation),
57-
)
58-
);
59-
}
54+
:host(:active) md-elevation {
55+
@include elevation.theme(
56+
(
57+
'level': var(--_pressed-container-elevation),
58+
)
59+
);
60+
}
6061

61-
&:disabled {
62-
@include elevation.theme(
63-
(
64-
'level': var(--_disabled-container-elevation),
65-
)
66-
);
67-
}
62+
:host([disabled]) md-elevation {
63+
@include elevation.theme(
64+
(
65+
'level': var(--_disabled-container-elevation),
66+
)
67+
);
6868
}
6969
}

button/internal/_icon.scss

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,30 @@
88
// class, which is loaded separately so the order of CSS definitions is not
99
// guaranteed. Therefore, increase specifity to ensure overrides apply.
1010
::slotted([slot='icon']) {
11-
.button & {
12-
display: inline-flex;
13-
position: relative;
14-
writing-mode: horizontal-tb;
15-
fill: currentColor;
16-
color: var(--_icon-color);
17-
font-size: var(--_icon-size);
18-
inline-size: var(--_icon-size);
19-
block-size: var(--_icon-size);
20-
}
11+
display: inline-flex;
12+
position: relative;
13+
writing-mode: horizontal-tb;
14+
fill: currentColor;
15+
color: var(--_icon-color);
16+
font-size: var(--_icon-size);
17+
inline-size: var(--_icon-size);
18+
block-size: var(--_icon-size);
19+
}
2120

22-
.button:hover & {
23-
color: var(--_hover-icon-color);
24-
}
21+
:host(:hover) ::slotted([slot='icon']) {
22+
color: var(--_hover-icon-color);
23+
}
2524

26-
.button:focus & {
27-
color: var(--_focus-icon-color);
28-
}
25+
:host(:focus-within) ::slotted([slot='icon']) {
26+
color: var(--_focus-icon-color);
27+
}
2928

30-
.button:active & {
31-
color: var(--_pressed-icon-color);
32-
}
29+
:host(:active) ::slotted([slot='icon']) {
30+
color: var(--_pressed-icon-color);
31+
}
3332

34-
.button:disabled & {
35-
color: var(--_disabled-icon-color);
36-
opacity: var(--_disabled-icon-opacity);
37-
}
33+
:host([disabled]) ::slotted([slot='icon']) {
34+
color: var(--_disabled-icon-color);
35+
opacity: var(--_disabled-icon-opacity);
3836
}
3937
}

button/internal/_outlined-button.scss

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,20 @@
7474
border-start-end-radius: var(--_container-shape-start-end);
7575
border-end-start-radius: var(--_container-shape-end-start);
7676
border-end-end-radius: var(--_container-shape-end-end);
77+
}
7778

78-
.button:active & {
79-
border-color: var(--_pressed-outline-color);
80-
}
79+
:host(:active) .button__outline {
80+
border-color: var(--_pressed-outline-color);
81+
}
8182

82-
.button:disabled & {
83-
border-color: var(--_disabled-outline-color);
84-
opacity: var(--_disabled-outline-opacity);
85-
}
83+
:host([disabled]) .button__outline {
84+
border-color: var(--_disabled-outline-color);
85+
opacity: var(--_disabled-outline-opacity);
86+
}
8687

87-
@media (forced-colors: active) {
88-
.button:disabled & {
89-
opacity: 1;
90-
}
88+
@media (forced-colors: active) {
89+
:host([disabled]) .button__outline {
90+
opacity: 1;
9191
}
9292
}
9393

button/internal/_shared.scss

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
@mixin styles() {
1515
:host {
16+
cursor: pointer;
1617
display: inline-flex;
1718
height: var(--_container-height);
1819
outline: none;
@@ -57,6 +58,7 @@
5758
}
5859

5960
.button {
61+
cursor: inherit;
6062
display: inline-flex;
6163
align-items: center;
6264
justify-content: center;
@@ -80,60 +82,58 @@
8082
padding-inline-end: var(--_trailing-space);
8183
gap: 8px;
8284

83-
&::before {
84-
// Background color. Separate node for disabled opacity styles.
85-
background-color: var(--_container-color);
86-
border-radius: inherit;
87-
content: '';
88-
inset: 0;
89-
position: absolute;
90-
}
91-
9285
&::-moz-focus-inner {
9386
padding: 0;
9487
border: 0;
9588
}
89+
}
9690

97-
&:hover {
98-
color: var(--_hover-label-text-color);
99-
cursor: pointer;
100-
}
91+
:host(:hover) .button {
92+
color: var(--_hover-label-text-color);
93+
}
10194

102-
&:focus {
103-
color: var(--_focus-label-text-color);
104-
}
95+
:host(:focus-within) .button {
96+
color: var(--_focus-label-text-color);
97+
}
10598

106-
&:active {
107-
color: var(--_pressed-label-text-color);
108-
outline: none;
109-
}
99+
:host(:active) .button {
100+
color: var(--_pressed-label-text-color);
101+
}
110102

111-
&:disabled .button__label {
112-
color: var(--_disabled-label-text-color);
113-
opacity: var(--_disabled-label-text-opacity);
114-
}
103+
.button::before {
104+
// Background color. Separate node for disabled opacity styles.
105+
background-color: var(--_container-color);
106+
border-radius: inherit;
107+
content: '';
108+
inset: 0;
109+
position: absolute;
110+
}
115111

116-
&:disabled::before {
117-
background-color: var(--_disabled-container-color);
118-
opacity: var(--_disabled-container-opacity);
112+
:host([disabled]) .button__label {
113+
color: var(--_disabled-label-text-color);
114+
opacity: var(--_disabled-label-text-opacity);
115+
}
116+
117+
:host([disabled]) .button::before {
118+
background-color: var(--_disabled-container-color);
119+
opacity: var(--_disabled-container-opacity);
120+
}
121+
122+
@media (forced-colors: active) {
123+
.button::before {
124+
content: '';
125+
box-sizing: border-box;
126+
border: 1px solid CanvasText;
127+
border-radius: inherit;
128+
inset: 0;
129+
pointer-events: none;
130+
position: absolute;
119131
}
120132

121-
@media (forced-colors: active) {
122-
&::before {
123-
content: '';
124-
box-sizing: border-box;
125-
border: 1px solid CanvasText;
126-
border-radius: inherit;
127-
inset: 0;
128-
pointer-events: none;
129-
position: absolute;
130-
}
131-
132-
&:disabled {
133-
--_disabled-icon-opacity: 1;
134-
--_disabled-container-opacity: 1;
135-
--_disabled-label-text-opacity: 1;
136-
}
133+
:host([disabled]) .button {
134+
--_disabled-icon-opacity: 1;
135+
--_disabled-container-opacity: 1;
136+
--_disabled-label-text-opacity: 1;
137137
}
138138
}
139139

0 commit comments

Comments
 (0)