diff --git a/.changeset/four-schools-grin.md b/.changeset/four-schools-grin.md new file mode 100644 index 00000000000..72c447d1a85 --- /dev/null +++ b/.changeset/four-schools-grin.md @@ -0,0 +1,5 @@ +--- +'@primer/react': minor +--- + +Update BranchName to use CSS Modules behind feature flag diff --git a/e2e/components/BranchName.test.ts b/e2e/components/BranchName.test.ts index feb776b3101..24a7ce82102 100644 --- a/e2e/components/BranchName.test.ts +++ b/e2e/components/BranchName.test.ts @@ -2,110 +2,90 @@ import {test, expect} from '@playwright/test' import {visit} from '../test-helpers/storybook' import {themes} from '../test-helpers/themes' -test.describe('BranchName', () => { - test.describe('Default', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-branchname--default', - globals: { - colorScheme: theme, - }, - }) +const stories = [ + { + title: 'Default', + id: 'components-branchname--default', + focus: true, + }, + { + title: 'Not A Link', + id: 'components-branchname-features--not-a-link', + focus: false, + }, + { + title: 'With A Branch Icon', + id: 'components-branchname-features--with-branch-icon', + focus: false, + }, +] as const - // Default state - expect(await page.screenshot()).toMatchSnapshot(`BranchName.Default.${theme}.png`) +test.describe('BranchName', () => { + for (const story of stories) { + test.describe(story.title, () => { + for (const theme of themes) { + test.describe(theme, () => { + test('default @vrt', async ({page}) => { + await visit(page, { + id: story.id, + globals: { + colorScheme: theme, + primer_react_css_modules_team: true, + }, + }) - // Focus state - await page.keyboard.press('Tab') - expect(await page.screenshot()).toMatchSnapshot(`BranchName.Default.${theme}.focus.png`) - }) + // Default state + expect(await page.screenshot()).toMatchSnapshot(`BranchName.${story.title}.${theme}.png`) - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-branchname--default', - globals: { - colorScheme: theme, - }, + // Focus state + if (story.focus) { + await page.keyboard.press('Tab') + expect(await page.screenshot()).toMatchSnapshot(`BranchName.${story.title}.${theme}.focus.png`) + } }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - test.describe('Not A Link', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-branchname-features--not-a-link', - globals: { - colorScheme: theme, - }, - }) + test('default (styled-components) @vrt', async ({page}) => { + await visit(page, { + id: story.id, + globals: { + colorScheme: theme, + primer_react_css_modules_team: false, + }, + }) - // Default state - expect(await page.screenshot()).toMatchSnapshot(`BranchName.Not A Link.${theme}.png`) - }) + // Default state + expect(await page.screenshot()).toMatchSnapshot(`BranchName.${story.title}.${theme}.png`) - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-branchname-features--not-a-link', - globals: { - colorScheme: theme, - }, + // Focus state + if (story.focus) { + await page.keyboard.press('Tab') + expect(await page.screenshot()).toMatchSnapshot(`BranchName.${story.title}.${theme}.focus.png`) + } }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - test.describe('With A Branch Icon', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-branchname-features--with-branch-icon', - globals: { - colorScheme: theme, - }, + test('axe @aat', async ({page}) => { + await visit(page, { + id: story.id, + globals: { + colorScheme: theme, + primer_react_css_modules_team: true, + }, + }) + await expect(page).toHaveNoViolations() }) - // Default state - expect(await page.screenshot()).toMatchSnapshot(`BranchName.With A Branch Icon.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-branchname-features--with-branch-icon', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', + test('axe (styled-components) @aat', async ({page}) => { + await visit(page, { + id: story.id, + globals: { + colorScheme: theme, + primer_react_css_modules_team: false, }, - }, + }) + await expect(page).toHaveNoViolations() }) }) - }) - } - }) + } + }) + } }) diff --git a/packages/react/src/BranchName/BranchName.module.css b/packages/react/src/BranchName/BranchName.module.css new file mode 100644 index 00000000000..66e9abc2d50 --- /dev/null +++ b/packages/react/src/BranchName/BranchName.module.css @@ -0,0 +1,14 @@ +.BranchName { + display: inline-block; + padding: var(--base-size-2) var(--base-size-6); + font-family: var(--fontStack-monospace); + font-size: var(--text-body-size-small); + color: var(--fgColor-link); + text-decoration: none; + background-color: var(--bgColor-accent-muted); + border-radius: var(--borderRadius-medium); + + &:is(:not(a)) { + color: var(--fgColor-muted); + } +} diff --git a/packages/react/src/BranchName/BranchName.tsx b/packages/react/src/BranchName/BranchName.tsx index 010777c4a2a..e07460191f9 100644 --- a/packages/react/src/BranchName/BranchName.tsx +++ b/packages/react/src/BranchName/BranchName.tsx @@ -1,10 +1,14 @@ +import React from 'react' +import {clsx} from 'clsx' import styled from 'styled-components' import {get} from '../constants' import type {SxProp} from '../sx' import sx from '../sx' -import type {ComponentProps} from '../utils/types' +import {useFeatureFlag} from '../FeatureFlags' +import Box from '../Box' +import classes from './BranchName.module.css' -const BranchName = styled.a` +const StyledBranchName = styled.a` display: inline-block; padding: 2px 6px; font-size: var(--text-body-size-small, ${get('fontSizes.0')}); @@ -19,5 +23,34 @@ const BranchName = styled.a` ${sx}; ` -export type BranchNameProps = ComponentProps +type BranchNameProps = { + as?: As +} & React.ComponentPropsWithoutRef & + SxProp + +function BranchName(props: BranchNameProps) { + const {as: BaseComponent = 'a', className, children, sx, ...rest} = props + const enabled = useFeatureFlag('primer_react_css_modules_team') + if (enabled) { + if (sx) { + return ( + + {children} + + ) + } + return ( + + {children} + + ) + } + return ( + + {children} + + ) +} + +export type {BranchNameProps} export default BranchName