Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions e2e/components/Button.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ const stories = [
title: 'Trailing Counter No Text',
id: 'components-button-features--trailing-counter-with-no-text',
},
{
title: 'Dev Link Variant With Underline Preference',
id: 'components-button-dev--link-variant-with-underline-preference',
},
] as const

test.describe('Button', () => {
Expand Down
6 changes: 4 additions & 2 deletions packages/react/.storybook/preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,14 @@ export const decorators = [

// Set data-a11y-link-underlines=true to enable underlines in all stories except the Link dev Inline Story.
let wrapperProps =
context.id !== 'components-link-dev--inline'
context.id !== 'components-link-dev--inline' ||
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect logical operator: using || (OR) makes the condition always true. This should be && (AND) to exclude both stories from the default underline behavior. With OR, any context.id will satisfy at least one condition.

Suggested change
context.id !== 'components-link-dev--inline' ||
context.id !== 'components-link-dev--inline' &&

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is accurate...

Human reviewers - what do you think?

context.id !== 'components-button-dev--link-variant-with-underline-preference'
? {
'data-a11y-link-underlines': context.id !== 'components-link-dev--inline',
'data-a11y-link-underlines': true,
className: clsx('story-wrap'),
}
: {className: clsx('story-wrap')}
console.log('context.id', context.id)
const showSurroundingElements =
context.globals.showSurroundingElements ?? window.localStorage.getItem('showSurroundingElements') === 'true'
return context.globals.colorScheme === 'all' ? (
Expand Down
29 changes: 29 additions & 0 deletions packages/react/src/Button/Button.dev.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,32 @@ export const DisabledButtonVariants = () => {
</Stack>
)
}

export const LinkVariantWithUnderlinePreference = () => {
return (
<Stack gap="spacious">
<Stack gap="condensed" align="start" data-a11y-link-underlines="true">
<Button variant="link">Underline pref on</Button>
<Button
variant="link"
leadingVisual={SearchIcon}
trailingAction={TriangleDownIcon}
trailingVisual={HeartFillIcon}
>
Underline pref on
</Button>
</Stack>
<Stack gap="condensed" align="start" data-a11y-link-underlines="false">
<Button variant="link">Underline pref off</Button>
<Button
variant="link"
leadingVisual={SearchIcon}
trailingAction={TriangleDownIcon}
trailingVisual={HeartFillIcon}
>
Underline pref off
</Button>
</Stack>
</Stack>
)
}
29 changes: 29 additions & 0 deletions packages/react/src/Button/ButtonBase.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@
color: var(--fgColor-link);
text-align: left;
border: unset;
border-radius: 0;

&:hover:not(:disabled, [data-inactive]) {
text-decoration: underline;
Expand Down Expand Up @@ -498,6 +499,34 @@
}
}

[data-a11y-link-underlines='true'] &:where([data-variant='link']) {
&:not(:has(.Visual)) {
text-decoration: underline;
}

&:has(.Visual) {
background-image: linear-gradient(to right, currentColor, currentColor);
background-size: 100% 1.5px;
background-position: 0 calc(100% - 2px);
background-repeat: no-repeat;

&:hover {
text-decoration: none;
}
}
}

[data-a11y-link-underlines='false'] &:where([data-variant='link']) {
&:not(:has(.Visual)) {
text-decoration: none;
background-image: none;
}

&:has(.Visual) {
background-image: none;
}
}

/* Inactive */

&:where([data-inactive]),
Expand Down
Loading