diff --git a/.changeset/happy-rivers-attend.md b/.changeset/happy-rivers-attend.md new file mode 100644 index 00000000000..82def6ab5a5 --- /dev/null +++ b/.changeset/happy-rivers-attend.md @@ -0,0 +1,7 @@ +--- +"@primer/react": minor +--- + +Updates link styles to support underline link preferences. + + diff --git a/.playwright/snapshots/components/BranchName.test.ts-snapshots/BranchName-Default-light-forcedUnderlines-linux.png b/.playwright/snapshots/components/BranchName.test.ts-snapshots/BranchName-Default-light-forcedUnderlines-linux.png new file mode 100644 index 00000000000..161e327bb67 Binary files /dev/null and b/.playwright/snapshots/components/BranchName.test.ts-snapshots/BranchName-Default-light-forcedUnderlines-linux.png differ diff --git a/.playwright/snapshots/components/Breadcrumbs.test.ts-snapshots/Breadcrumbs-Default-light-forcedUnderlines-linux.png b/.playwright/snapshots/components/Breadcrumbs.test.ts-snapshots/Breadcrumbs-Default-light-forcedUnderlines-linux.png new file mode 100644 index 00000000000..10b79842e9c Binary files /dev/null and b/.playwright/snapshots/components/Breadcrumbs.test.ts-snapshots/Breadcrumbs-Default-light-forcedUnderlines-linux.png differ diff --git a/.playwright/snapshots/components/Link.test.ts-snapshots/Link-Default-light-forcedUnderlines-linux.png b/.playwright/snapshots/components/Link.test.ts-snapshots/Link-Default-light-forcedUnderlines-linux.png new file mode 100644 index 00000000000..0ae25820262 Binary files /dev/null and b/.playwright/snapshots/components/Link.test.ts-snapshots/Link-Default-light-forcedUnderlines-linux.png differ diff --git a/.playwright/snapshots/components/Link.test.ts-snapshots/Link-Muted-light-forcedUnderlines-linux.png b/.playwright/snapshots/components/Link.test.ts-snapshots/Link-Muted-light-forcedUnderlines-linux.png new file mode 100644 index 00000000000..ea2038fd8fb Binary files /dev/null and b/.playwright/snapshots/components/Link.test.ts-snapshots/Link-Muted-light-forcedUnderlines-linux.png differ diff --git a/.playwright/snapshots/components/Link.test.ts-snapshots/Link-Underline-light-forcedUnderlines-linux.png b/.playwright/snapshots/components/Link.test.ts-snapshots/Link-Underline-light-forcedUnderlines-linux.png new file mode 100644 index 00000000000..0ae25820262 Binary files /dev/null and b/.playwright/snapshots/components/Link.test.ts-snapshots/Link-Underline-light-forcedUnderlines-linux.png differ diff --git a/.playwright/snapshots/components/LinkButton.test.ts-snapshots/LinkButton-Invisible-light-forcedUnderlines-linux.png b/.playwright/snapshots/components/LinkButton.test.ts-snapshots/LinkButton-Invisible-light-forcedUnderlines-linux.png new file mode 100644 index 00000000000..9984199a841 Binary files /dev/null and b/.playwright/snapshots/components/LinkButton.test.ts-snapshots/LinkButton-Invisible-light-forcedUnderlines-linux.png differ diff --git a/e2e/components/BranchName.test.ts b/e2e/components/BranchName.test.ts index ecf450d8968..0da26edf74c 100644 --- a/e2e/components/BranchName.test.ts +++ b/e2e/components/BranchName.test.ts @@ -39,5 +39,19 @@ test.describe('BranchName', () => { }) }) } + + test.describe('with forced underlines', () => { + test('default @vrt', async ({page}) => { + await visit(page, { + id: 'components-branchname--default', + globals: { + colorScheme: 'light', + prefersLinkUnderlines: 'true', + }, + }) + + expect(await page.screenshot()).toMatchSnapshot('BranchName.Default.light.forcedUnderlines.png') + }) + }) }) }) diff --git a/e2e/components/Breadcrumbs.test.ts b/e2e/components/Breadcrumbs.test.ts index 5b4a763084e..17c4f1b4ea9 100644 --- a/e2e/components/Breadcrumbs.test.ts +++ b/e2e/components/Breadcrumbs.test.ts @@ -43,5 +43,19 @@ test.describe('Breadcrumbs', () => { }) }) } + + test.describe('with forced underlines', () => { + test('default @vrt', async ({page}) => { + await visit(page, { + id: 'components-breadcrumbs--default', + globals: { + colorScheme: 'light', + prefersLinkUnderlines: 'true', + }, + }) + + expect(await page.screenshot()).toMatchSnapshot('Breadcrumbs.Default.light.forcedUnderlines.png') + }) + }) }) }) diff --git a/e2e/components/Link.test.ts b/e2e/components/Link.test.ts index 75259a13e91..d556729b83f 100644 --- a/e2e/components/Link.test.ts +++ b/e2e/components/Link.test.ts @@ -43,6 +43,20 @@ test.describe('Link', () => { }) }) } + + test.describe('with forced underlines', () => { + test('default @vrt', async ({page}) => { + await visit(page, { + id: 'components-link--default', + globals: { + colorScheme: 'light', + prefersLinkUnderlines: 'true', + }, + }) + + expect(await page.screenshot()).toMatchSnapshot('Link.Default.light.forcedUnderlines.png') + }) + }) }) test.describe('Muted', () => { @@ -85,6 +99,20 @@ test.describe('Link', () => { }) }) } + + test.describe('with forced underlines', () => { + test('default @vrt', async ({page}) => { + await visit(page, { + id: 'components-link-features--muted', + globals: { + colorScheme: 'light', + prefersLinkUnderlines: 'true', + }, + }) + + expect(await page.screenshot()).toMatchSnapshot('Link.Muted.light.forcedUnderlines.png') + }) + }) }) test.describe('Underline', () => { @@ -127,5 +155,19 @@ test.describe('Link', () => { }) }) } + + test.describe('with forced underlines', () => { + test('default @vrt', async ({page}) => { + await visit(page, { + id: 'components-link-features--underline', + globals: { + colorScheme: 'light', + prefersLinkUnderlines: 'true', + }, + }) + + expect(await page.screenshot()).toMatchSnapshot('Link.Underline.light.forcedUnderlines.png') + }) + }) }) }) diff --git a/e2e/components/LinkButton.test.ts b/e2e/components/LinkButton.test.ts index 31e0c906172..b9f46f25729 100644 --- a/e2e/components/LinkButton.test.ts +++ b/e2e/components/LinkButton.test.ts @@ -137,6 +137,20 @@ test.describe('LinkButton', () => { }) }) } + + test.describe('with forced underlines', () => { + test('default @vrt', async ({page}) => { + await visit(page, { + id: 'components-linkbutton-features--invisible', + globals: { + colorScheme: 'light', + prefersLinkUnderlines: 'true', + }, + }) + + expect(await page.screenshot()).toMatchSnapshot('LinkButton.Invisible.light.forcedUnderlines.png') + }) + }) }) test.describe('Large', () => { diff --git a/e2e/test-helpers/storybook.ts b/e2e/test-helpers/storybook.ts index 755e8848b12..08eb3bafa4a 100644 --- a/e2e/test-helpers/storybook.ts +++ b/e2e/test-helpers/storybook.ts @@ -28,7 +28,7 @@ export async function visit(page: Page, options: Options) { let params = '' for (const [key, value] of Object.entries(globals)) { if (params !== '') { - params += '&' + params += ';' } params += `${key}:${value}` } diff --git a/src/ActionList/LinkItem.tsx b/src/ActionList/LinkItem.tsx index d4decbe2292..d37c85ad270 100644 --- a/src/ActionList/LinkItem.tsx +++ b/src/ActionList/LinkItem.tsx @@ -32,6 +32,7 @@ export const LinkItem = React.forwardRef(({sx = {}, active, as: Component, ...pr // inherit Item styles color: 'inherit', + textDecoration: 'none', '&:hover': {color: 'inherit', textDecoration: 'none'}, } diff --git a/src/BaseStyles.tsx b/src/BaseStyles.tsx index aece80f6087..896aef31b09 100644 --- a/src/BaseStyles.tsx +++ b/src/BaseStyles.tsx @@ -26,6 +26,13 @@ const GlobalStyle = createGlobalStyle<{colorScheme?: 'light' | 'dark'}>` details-dialog:focus:not(:focus-visible):not(.focus-visible) { outline: none; } + + /* Used to fake conditional styles using a technique by Lea Verou: https://lea.verou.me/blog/2020/10/the-var-space-hack-to-toggle-multiple-values-with-one-custom-property/ */ + /* We have to use a zero-width space character (\u200B) as the value instead of a regular whitespace character because styled-components strips out properties that just have a whitespace value. */ + :root {--prefers-link-underlines: \u200B;} + [data-a11y-link-underlines='true'] { + --prefers-link-underlines: initial; + } ` const Base = styled.div` diff --git a/src/BranchName/BranchName.tsx b/src/BranchName/BranchName.tsx index 0ef498253b3..c05c17da9ce 100644 --- a/src/BranchName/BranchName.tsx +++ b/src/BranchName/BranchName.tsx @@ -11,7 +11,7 @@ const BranchName = styled.a` color: ${get('colors.accent.fg')}; background-color: ${get('colors.accent.subtle')}; border-radius: ${get('radii.2')}; - text-decoration: none; + text-decoration: var(--prefers-link-underlines, underline); ${sx}; ` diff --git a/src/BranchName/__tests__/__snapshots__/BranchName.test.tsx.snap b/src/BranchName/__tests__/__snapshots__/BranchName.test.tsx.snap index 67046d28a4e..10832885435 100644 --- a/src/BranchName/__tests__/__snapshots__/BranchName.test.tsx.snap +++ b/src/BranchName/__tests__/__snapshots__/BranchName.test.tsx.snap @@ -9,8 +9,8 @@ exports[`BranchName renders consistently 1`] = ` color: #0969da; background-color: #ddf4ff; border-radius: 6px; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } (props => ({ color: ${get('colors.accent.fg')}; display: inline-block; font-size: ${get('fontSizes.1')}; - text-decoration: none; + text-decoration: var(--prefers-link-underlines, underline); &:hover { text-decoration: underline; } diff --git a/src/Breadcrumbs/__tests__/__snapshots__/BreadcrumbsItem.test.tsx.snap b/src/Breadcrumbs/__tests__/__snapshots__/BreadcrumbsItem.test.tsx.snap index 39ec4605f7d..d0bc7896195 100644 --- a/src/Breadcrumbs/__tests__/__snapshots__/BreadcrumbsItem.test.tsx.snap +++ b/src/Breadcrumbs/__tests__/__snapshots__/BreadcrumbsItem.test.tsx.snap @@ -5,8 +5,8 @@ exports[`Breadcrumbs.Item adds activeClassName={SELECTED_CLASS} when it gets a " color: #0969da; display: inline-block; font-size: 14px; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c0:hover { @@ -32,8 +32,8 @@ exports[`Breadcrumbs.Item renders consistently 1`] = ` color: #0969da; display: inline-block; font-size: 14px; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c0:hover { @@ -57,8 +57,8 @@ exports[`Breadcrumbs.Item respects the "selected" prop 1`] = ` color: #0969da; display: inline-block; font-size: 14px; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c0:hover { diff --git a/src/Button/__tests__/__snapshots__/Button.test.tsx.snap b/src/Button/__tests__/__snapshots__/Button.test.tsx.snap index df99279ed3f..156d20e7c5f 100644 --- a/src/Button/__tests__/__snapshots__/Button.test.tsx.snap +++ b/src/Button/__tests__/__snapshots__/Button.test.tsx.snap @@ -1511,11 +1511,13 @@ exports[`Button styles invisible button appropriately 1`] = ` display: -webkit-inline-flex; display: -ms-inline-flexbox; display: inline-flex; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c0[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c0:hover { diff --git a/src/Button/styles.ts b/src/Button/styles.ts index d3b3a1ea84d..085c6156c88 100644 --- a/src/Button/styles.ts +++ b/src/Button/styles.ts @@ -109,6 +109,12 @@ export const getVariantStyles = (variant: VariantType = 'default', theme?: Theme backgroundColor: 'transparent', borderColor: 'transparent', boxShadow: 'none', + '&[href]': { + textDecoration: 'var(--prefers-link-underlines, underline)', + '&:hover': { + textDecoration: 'var(--prefers-link-underlines, underline)', + }, + }, '&:hover:not([disabled])': { backgroundColor: 'btn.hoverBg', }, diff --git a/src/Heading/Heading.tsx b/src/Heading/Heading.tsx index 25a224aca34..ce755302cd0 100644 --- a/src/Heading/Heading.tsx +++ b/src/Heading/Heading.tsx @@ -39,6 +39,7 @@ const Heading = forwardRef(({as: Component = 'h2', ...props}, forwardedRef) => { return ( `; diff --git a/src/Link/Link.tsx b/src/Link/Link.tsx index 735c1674466..fc6f3a73643 100644 --- a/src/Link/Link.tsx +++ b/src/Link/Link.tsx @@ -22,9 +22,9 @@ const hoverColor = system({ const StyledLink = styled.a` color: ${props => (props.muted ? get('colors.fg.muted')(props) : get('colors.accent.fg')(props))}; - text-decoration: ${props => (props.underline ? 'underline' : 'none')}; + text-decoration: ${props => (props.underline ? 'underline' : 'var(--prefers-link-underlines, underline)')}; &:hover { - text-decoration: ${props => (props.muted ? 'none' : 'underline')}; + text-decoration: ${props => (props.muted ? 'var(--prefers-link-underlines, underline)' : 'underline')}; ${props => (props.hoverColor ? hoverColor : props.muted ? `color: ${get('colors.accent.fg')(props)}` : '')}; } &:is(button) { diff --git a/src/Link/__tests__/__snapshots__/Link.test.tsx.snap b/src/Link/__tests__/__snapshots__/Link.test.tsx.snap index eaad8694936..87a83747c45 100644 --- a/src/Link/__tests__/__snapshots__/Link.test.tsx.snap +++ b/src/Link/__tests__/__snapshots__/Link.test.tsx.snap @@ -3,8 +3,8 @@ exports[`Link applies button styles when rendering a button element 1`] = ` .c0 { color: #0969da; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c0:hover { @@ -37,8 +37,8 @@ exports[`Link applies button styles when rendering a button element 1`] = ` exports[`Link passes href down to link element 1`] = ` .c0 { color: #0969da; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c0:hover { @@ -72,8 +72,8 @@ exports[`Link passes href down to link element 1`] = ` exports[`Link renders consistently 1`] = ` .c0 { color: #0969da; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c0:hover { @@ -106,8 +106,8 @@ exports[`Link renders consistently 1`] = ` exports[`Link respects hoverColor prop 1`] = ` .c0 { color: #0969da; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c0:hover { @@ -141,14 +141,14 @@ exports[`Link respects hoverColor prop 1`] = ` exports[`Link respects the "sx" prop when "muted" prop is also passed 1`] = ` .c0 { color: #656d76; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); color: #ffffff; } .c0:hover { - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); color: #0969da; } @@ -178,13 +178,13 @@ exports[`Link respects the "sx" prop when "muted" prop is also passed 1`] = ` exports[`Link respects the "muted" prop 1`] = ` .c0 { color: #656d76; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c0:hover { - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); color: #0969da; } diff --git a/src/NavList/__snapshots__/NavList.test.tsx.snap b/src/NavList/__snapshots__/NavList.test.tsx.snap index 7253cc36ff8..ab5636102c6 100644 --- a/src/NavList/__snapshots__/NavList.test.tsx.snap +++ b/src/NavList/__snapshots__/NavList.test.tsx.snap @@ -196,8 +196,8 @@ exports[`NavList renders a simple list 1`] = ` .c3 { color: #0969da; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); padding-left: 8px; padding-right: 8px; padding-top: 6px; @@ -212,6 +212,8 @@ exports[`NavList renders a simple list 1`] = ` flex-grow: 1; border-radius: 6px; color: inherit; + -webkit-text-decoration: none; + text-decoration: none; } .c3:hover { @@ -601,8 +603,8 @@ exports[`NavList renders with groups 1`] = ` .c7 { color: #0969da; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); padding-left: 8px; padding-right: 8px; padding-top: 6px; @@ -617,6 +619,8 @@ exports[`NavList renders with groups 1`] = ` flex-grow: 1; border-radius: 6px; color: inherit; + -webkit-text-decoration: none; + text-decoration: none; } .c7:hover { @@ -1082,8 +1086,8 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav .c11 { color: #0969da; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); padding-left: 16px; padding-right: 8px; padding-top: 6px; @@ -1098,6 +1102,8 @@ exports[`NavList.Item with NavList.SubNav does not have active styles if SubNav flex-grow: 1; border-radius: 6px; color: inherit; + -webkit-text-decoration: none; + text-decoration: none; font-size: 12px; font-weight: 400; } @@ -1560,8 +1566,8 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t .c11 { color: #0969da; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); padding-left: 16px; padding-right: 8px; padding-top: 6px; @@ -1576,6 +1582,8 @@ exports[`NavList.Item with NavList.SubNav has active styles if SubNav contains t flex-grow: 1; border-radius: 6px; color: inherit; + -webkit-text-decoration: none; + text-decoration: none; font-size: 12px; font-weight: 400; } diff --git a/src/UnderlineNav2/__snapshots__/UnderlineNav.test.tsx.snap b/src/UnderlineNav2/__snapshots__/UnderlineNav.test.tsx.snap index 7087305ccb7..e2683254421 100644 --- a/src/UnderlineNav2/__snapshots__/UnderlineNav.test.tsx.snap +++ b/src/UnderlineNav2/__snapshots__/UnderlineNav.test.tsx.snap @@ -94,8 +94,8 @@ exports[`UnderlineNav renders consistently 1`] = ` .c4 { color: #0969da; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); position: relative; display: -webkit-inline-box; display: -webkit-inline-flex; @@ -182,8 +182,8 @@ exports[`UnderlineNav renders consistently 1`] = ` .c7 { color: #0969da; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); position: relative; display: -webkit-inline-box; display: -webkit-inline-flex; diff --git a/src/__tests__/__snapshots__/SideNav.test.tsx.snap b/src/__tests__/__snapshots__/SideNav.test.tsx.snap index d54bec24567..37336e1d5ec 100644 --- a/src/__tests__/__snapshots__/SideNav.test.tsx.snap +++ b/src/__tests__/__snapshots__/SideNav.test.tsx.snap @@ -3,8 +3,8 @@ exports[`SideNav SideNav.Link renders consistently 1`] = ` .c0 { color: #0969da; - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c0:hover { diff --git a/src/__tests__/__snapshots__/TextInput.test.tsx.snap b/src/__tests__/__snapshots__/TextInput.test.tsx.snap index daf421a825e..48bad25b626 100644 --- a/src/__tests__/__snapshots__/TextInput.test.tsx.snap +++ b/src/__tests__/__snapshots__/TextInput.test.tsx.snap @@ -1710,11 +1710,13 @@ exports[`TextInput renders trailingAction icon button 1`] = ` display: -webkit-inline-flex; display: -ms-inline-flexbox; display: inline-flex; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c4[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c4:hover { @@ -2359,11 +2361,13 @@ exports[`TextInput renders trailingAction text button 1`] = ` display: -webkit-inline-flex; display: -ms-inline-flexbox; display: inline-flex; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c3[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c3:hover { @@ -2762,11 +2766,13 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = ` display: -webkit-inline-flex; display: -ms-inline-flexbox; display: inline-flex; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c4[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; + -webkit-text-decoration: var(--prefers-link-underlines,underline); + text-decoration: var(--prefers-link-underlines,underline); } .c4:hover { diff --git a/src/drafts/Button2/styles.ts b/src/drafts/Button2/styles.ts index 474a9e81991..240a8c0044f 100644 --- a/src/drafts/Button2/styles.ts +++ b/src/drafts/Button2/styles.ts @@ -106,6 +106,12 @@ export const getVariantStyles = (variant: VariantType = 'default', theme?: Theme backgroundColor: 'transparent', borderColor: 'transparent', boxShadow: 'none', + '&[href]': { + textDecoration: 'var(--prefers-link-underlines, underline)', + '&:hover': { + textDecoration: 'var(--prefers-link-underlines, underline)', + }, + }, '&:hover:not([disabled])': { backgroundColor: 'btn.hoverBg', }, diff --git a/src/utils/story-helpers.tsx b/src/utils/story-helpers.tsx index a48dcea9208..9a3719e242c 100644 --- a/src/utils/story-helpers.tsx +++ b/src/utils/story-helpers.tsx @@ -9,7 +9,7 @@ import {Icon} from '@primer/octicons-react' // we don't import StoryContext from storybook because of exports that conflict // with primer/react more: https://github.com/primer/react/runs/6129115026?check_suite_focus=true type StoryContext = Record & { - globals: {colorScheme: string; showSurroundingElements?: boolean} + globals: {colorScheme: string; showSurroundingElements?: boolean; prefersLinkUnderlines?: 'true' | 'false'} parameters: Record } @@ -59,7 +59,7 @@ export const withThemeProvider = (Story: React.FC -
{Story(context)}
+
+ {Story(context)} +
@@ -100,7 +102,9 @@ export const withThemeProvider = (Story: React.FC -
{Story(context)}
+
+ {Story(context)} +
) @@ -118,6 +122,16 @@ export const toolbarTypes = { }, showSurroundingElements: {}, }, + prefersLinkUnderlines: { + name: 'Force link underlines', + description: 'Whether to force underlines on links that are not otherwise underlined', + defaultValue: 'false', + toolbar: { + icon: 'link', + items: ['true', 'false'], + title: 'Force link underlines', + }, + }, } export const inputWrapperArgTypes: ArgTypes = {