Skip to content

Commit d559a3f

Browse files
committed
fix(ui-buttons): fix ai-secondary button size diff
1 parent a04af2b commit d559a3f

2 files changed

Lines changed: 59 additions & 0 deletions

File tree

packages/ui-buttons/src/BaseButton/v2/styles.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,26 @@ const generateStyle = (
5555
condensedMedium: componentTheme.gapButtonContentSm
5656
}
5757

58+
// Outer height token per size, keyed like `sizeVariants`. Used to compensate
59+
// the ai-secondary gradient-border padding.
60+
const heightForSize = {
61+
small: componentTheme.smallHeight,
62+
medium: componentTheme.mediumHeight,
63+
large: componentTheme.largeHeight,
64+
condensedSmall: componentTheme.heightXxs,
65+
condensedMedium: componentTheme.heightXs
66+
}
67+
68+
// ai-secondary draws its gradient "border" as a ::before ring whose space is
69+
// reserved by padding on the button wrapper (see the `&&&&&&&&&&` block below).
70+
// That padding is additive to the content box, so an ai-secondary button ends
71+
// up 2 × borderWidth taller — and, when icon-only, wider — than the same button
72+
// in any other color. Shrink the content box by the same amount to compensate.
73+
const aiSecondaryContentSize =
74+
color === 'ai-secondary'
75+
? `calc(${heightForSize[size!]} - ${componentTheme.borderWidth} * 2)`
76+
: undefined
77+
5878
const shapeVariants = {
5979
circle: { borderRadius: componentTheme.borderRadiusFull },
6080
rectangle: {}
@@ -560,6 +580,14 @@ const generateStyle = (
560580
}),
561581
...(!withBorder && {
562582
borderStyle: 'none'
583+
}),
584+
// ai-secondary uses padding to render its gradient border, which increases
585+
// the outer size. Reduce the content size to keep dimensions consistent.
586+
...(aiSecondaryContentSize && {
587+
...(size === 'condensedSmall' || size === 'condensedMedium'
588+
? { height: aiSecondaryContentSize }
589+
: { minHeight: aiSecondaryContentSize }),
590+
...(hasOnlyIconVisible && { width: aiSecondaryContentSize })
563591
})
564592
},
565593

regression-test/src/app/button/page.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,37 @@ export default function ButtonPage() {
237237
</IconButton>
238238
</View>
239239
</div>
240+
{/*
241+
Unlike every other color, ai-secondary has no real CSS border — it fakes
242+
its gradient "border" with a ::before ring whose space is reserved by
243+
padding on the wrapper. That padding inflates the outer size, so the
244+
content box has to be shrunk back by a hand-written, per-size calc
245+
(2 × borderWidth) to stay identical to the other colors. Because that
246+
compensation is manual and size-specific, it's easy to miss a size or
247+
variant.
248+
*/}
249+
ai-secondary size parity (all sizes):
250+
{(
251+
['small', 'medium', 'large', 'condensedSmall', 'condensedMedium'] as const
252+
).map((size) => (
253+
<div
254+
key={size}
255+
style={{ display: 'flex', gap: '0.5rem', alignItems: 'flex-start' }}
256+
>
257+
<Button size={size} color="secondary">
258+
{size}
259+
</Button>
260+
<Button size={size} color="ai-secondary">
261+
{size}
262+
</Button>
263+
<IconButton size={size} color="secondary" screenReaderLabel="Add">
264+
<IconAddLine />
265+
</IconButton>
266+
<IconButton size={size} color="ai-secondary" screenReaderLabel="AI">
267+
<IconAiColoredSolid />
268+
</IconButton>
269+
</div>
270+
))}
240271
</main>
241272
)
242273
}

0 commit comments

Comments
 (0)