Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 5 additions & 0 deletions .changeset/easy-poets-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': patch
---

Makes Button and LinkButton 'link' variant respect user underline preference
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
5 changes: 3 additions & 2 deletions packages/react/.storybook/preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,10 @@ 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')}
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