close
Skip to content

Commit d570787

Browse files
feat(ui): adds dashed button style (#15728)
This PR adds a new `dashed` button style property. Changes: - removes box-shadow from buttons and replaces it with border - adds "always on" 1px solid transparent border - reduces line-height by 2px from `calc(var(--base) * 1.2)` to `calc(var(--base) * 1.1)` (.1 --base is 2px) to account for new "always on" border Fixes button with icon-only had incorrect padding set, should be equal left and right. Adds custom page in the admin test suite `/admin/button-styles` so we can quickly see all button variations. (as you can see we support styles that do not have any default styles, like `error`). Updating all of those is out of scope for this PR but I think this custom view will help us with button updates in the future. <img width="2021" height="1261" alt="CleanShot 2026-02-23 at 11 15 45" src="https://github.com/user-attachments/assets/8d97fb19-51c3-46a3-9148-c54b15d49723" />
1 parent aaddeac commit d570787

5 files changed

Lines changed: 271 additions & 27 deletions

File tree

‎packages/ui/src/elements/Button/index.scss‎

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
&--style-primary {
2323
--color: var(--theme-elevation-0);
2424
--bg-color: var(--theme-elevation-800);
25-
--box-shadow: none;
2625
--hover-bg: var(--theme-elevation-600);
2726
--hover-color: var(--color);
2827

@@ -37,18 +36,34 @@
3736
&--style-secondary {
3837
--color: var(--theme-text);
3938
--bg-color: transparent;
40-
--box-shadow: inset 0 0 0 1px var(--theme-elevation-800);
39+
--btn-border: 1px solid var(--theme-elevation-800);
4140
--hover-color: var(--theme-elevation-600);
42-
--hover-box-shadow: inset 0 0 0 1px var(--theme-elevation-400);
41+
--hover-btn-border: 1px solid var(--theme-elevation-400);
4342

4443
&.btn--disabled {
4544
--color: var(--theme-elevation-200);
46-
--box-shadow: inset 0 0 0 1px var(--theme-elevation-200);
47-
--hover-box-shadow: inset 0 0 0 1px var(--theme-elevation-200);
45+
--btn-border: 1px solid var(--theme-elevation-200);
46+
--hover-btn-border: 1px solid var(--theme-elevation-200);
4847
--hover-color: var(--color);
4948
}
5049
}
5150

51+
&--style-dashed {
52+
--color: var(--theme-elevation-500);
53+
--bg-color: transparent;
54+
--hover-color: var(--theme-text);
55+
--btn-border: 1px dashed var(--theme-elevation-200);
56+
--hover-btn-border: 1px dashed var(--theme-elevation-400);
57+
58+
&.btn--disabled {
59+
--color: var(--theme-elevation-250);
60+
--hover-color: var(--color);
61+
--hover-bg: transparent;
62+
--btn-border: 1px dashed var(--theme-elevation-200);
63+
--hover-btn-border: var(--btn-border);
64+
}
65+
}
66+
5267
&--style-pill {
5368
--bg-color: var(--theme-elevation-150);
5469
--color: var(--theme-elevation-800);
@@ -86,12 +101,12 @@
86101
--color: var(--theme-text);
87102
--bg-color: var(--theme-elevation-100);
88103
--hover-bg: var(--theme-elevation-150);
89-
--box-shadow: inset 0 0 0 1px var(--theme-elevation-200);
90-
--hover-box-shadow: inset 0 0 0 1px var(--theme-elevation-250);
104+
--btn-border: 1px solid var(--theme-elevation-200);
105+
--hover-btn-border: 1px solid var(--theme-elevation-250);
91106

92107
&.btn--disabled {
93108
--color: var(--theme-elevation-450);
94-
--hover-box-shadow: var(--box-shadow);
109+
--hover-btn-border: var(--btn-border);
95110
--hover-bg: var(--bg-color);
96111
--hover-color: var(--color);
97112
}
@@ -105,7 +120,6 @@
105120

106121
&.btn--disabled {
107122
--btn-font-weight: 600;
108-
--hover-box-shadow: var(--box-shadow);
109123
--bg-color: var(--theme-elevation-100);
110124
--hover-bg: var(--bg-color);
111125
--hover-color: var(--color);
@@ -121,7 +135,7 @@
121135
.popup-button {
122136
color: var(--color, inherit);
123137
background-color: var(--bg-color);
124-
box-shadow: var(--box-shadow);
138+
border: var(--btn-border, 1px solid transparent);
125139
border-radius: $style-radius-m;
126140
align-items: center;
127141

@@ -143,7 +157,14 @@
143157
&:active {
144158
background-color: var(--hover-bg);
145159
color: var(--hover-color);
146-
box-shadow: var(--hover-box-shadow);
160+
border: var(--hover-btn-border, 1px solid transparent);
161+
162+
.btn__icon .stroke {
163+
stroke: var(--hover-color, currentColor);
164+
}
165+
.btn__icon .fill {
166+
fill: var(--hover-color, currentColor);
167+
}
147168
}
148169
}
149170
}
@@ -155,8 +176,8 @@
155176
&:focus,
156177
&:active {
157178
color: var(--hover-color);
158-
box-shadow: var(--hover-box-shadow);
159179
background-color: var(--hover-bg);
180+
border: var(--hover-btn-border, var(--btn-border, 1px solid transparent));
160181
}
161182
}
162183

@@ -176,25 +197,23 @@
176197
--btn-icon-padding: 0px; // This will be needed when we make icons go edge to edge instead of having built in padding in the svg code
177198
--btn-icon-content-gap: calc(var(--base) * 0.4);
178199
--margin-block: calc(var(--base) * 1.2);
179-
--btn-line-height: calc(var(--base) * 1.2);
200+
--btn-line-height: calc(var(--base) * 1.1);
201+
--btn-base-transition: 100ms cubic-bezier(0, 0.2, 0.2, 1);
180202

181203
border-radius: var(--style-radius-s);
182204
font-size: var(--base-body-size);
183205
font-family: var(--font-body);
184206
font-weight: var(--btn-font-weight, normal);
185207
margin-block: var(--margin-block);
186208
line-height: var(--btn-line-height);
187-
border: 0;
209+
border: var(--btn-border, 1px solid transparent);
188210
cursor: pointer;
189211
text-decoration: none;
190-
transition-property: border, color, box-shadow, background;
191-
transition-duration: 100ms;
192-
transition-timing-function: cubic-bezier(0, 0.2, 0.2, 1);
212+
transition: border, color, background, var(--btn-base-transition);
193213
padding: var(--btn-padding-block-start) var(--btn-padding-inline-end)
194214
var(--btn-padding-block-end) var(--btn-padding-inline-start);
195215
color: var(--color, inherit);
196216
background-color: var(--bg-color, transparent);
197-
box-shadow: var(--box-shadow, none);
198217

199218
&__icon {
200219
width: 100%;
@@ -271,11 +290,11 @@
271290
--btn-padding-inline-start: calc(var(--base) * 0.4);
272291
--btn-padding-block-end: 0;
273292

274-
&.btn--icon-position-left {
293+
&:not(.btn--icon-only).btn--icon-position-left {
275294
--btn-padding-inline-start: calc(var(--base) * 0.3);
276295
}
277296

278-
&.btn--icon-position-right {
297+
&:not(.btn--icon-only).btn--icon-position-right {
279298
--btn-padding-inline-end: calc(var(--base) * 0.3);
280299
}
281300

@@ -292,10 +311,10 @@
292311
--btn-padding-inline-end: calc(var(--base) * 0.3);
293312
--btn-padding-inline-start: calc(var(--base) * 0.3);
294313
--btn-padding-block-end: 0;
295-
&.btn--icon-position-left {
314+
&:not(.btn--icon-only).btn--icon-position-left {
296315
--btn-padding-inline-start: calc(var(--base) * 0.2);
297316
}
298-
&.btn--icon-position-right {
317+
&:not(.btn--icon-only).btn--icon-position-right {
299318
--btn-padding-inline-end: calc(var(--base) * 0.2);
300319
}
301320
&.btn--icon-style-with-border {
@@ -305,18 +324,18 @@
305324

306325
&--size-medium {
307326
// --btn-icon-padding: 0px;
308-
--btn-icon-size: calc(var(--base) * 1.2);
327+
--btn-icon-size: calc(var(--base) * 1.1);
309328
--btn-icon-content-gap: calc(var(--base) * 0.2);
310329
--btn-padding-block-start: calc(var(--base) * 0.2);
311330
--btn-padding-inline-end: calc(var(--base) * 0.6);
312331
--btn-padding-block-end: calc(var(--base) * 0.2);
313332
--btn-padding-inline-start: calc(var(--base) * 0.6);
314333

315-
&.btn--icon-position-left {
334+
&:not(.btn--icon-only).btn--icon-position-left {
316335
--btn-padding-inline-start: calc(var(--base) * 0.4);
317336
}
318337

319-
&.btn--icon-position-right {
338+
&:not(.btn--icon-only).btn--icon-position-right {
320339
--btn-padding-inline-end: calc(var(--base) * 0.4);
321340
}
322341

@@ -334,11 +353,11 @@
334353
--btn-padding-inline-start: calc(var(--base) * 0.8);
335354
--btn-padding-block-end: calc(var(--base) * 0.4);
336355

337-
&.btn--icon-position-left {
356+
&:not(.btn--icon-only).btn--icon-position-left {
338357
--btn-padding-inline-start: calc(var(--base) * 0.6);
339358
}
340359

341-
&.btn--icon-position-right {
360+
&:not(.btn--icon-only).btn--icon-position-right {
342361
--btn-padding-inline-end: calc(var(--base) * 0.6);
343362
}
344363

‎packages/ui/src/elements/Button/types.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export type Props = {
1010
'aria-label'?: string
1111
buttonId?: string
1212
buttonStyle?:
13+
| 'dashed'
1314
| 'error'
1415
| 'icon-label'
1516
| 'none'

‎test/admin/components/AfterNavLinks/index.tsx‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ export const AfterNavLinks: PayloadClientReactComponent<
6161
Minimal Template
6262
</Link>
6363
</p>
64+
<p className="nav__link" style={{ margin: 0 }}>
65+
<Link
66+
href={`${adminRoute}/button-styles`}
67+
style={{ color: '#1976d2', textDecoration: 'none' }}
68+
>
69+
Button Styles
70+
</Link>
71+
</p>
6472
<div id="custom-css" />
6573
</div>
6674
</div>

0 commit comments

Comments
 (0)