Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ describe('@primer/react/deprecated', () => {

test('TabNav.Link supports `sx` prop', () => {
render(<TabNav.Link data-testid="component" sx={{background: 'red'}} as={Button} />)
expect(screen.getByTestId('component')).toHaveAttribute('role', 'tab')
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(window.getComputedStyle(screen.getByRole('tab')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByRole('tab').tagName).toBe('BUTTON')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ describe('@primer/react/experimental', () => {
})

test('PageHeader supports `sx` prop', () => {
const {container} = render(<PageHeader data-testid="component" sx={{background: 'red'}} />)
const {container} = render(<PageHeader as="div" data-testid="component" sx={{background: 'red'}} role="article" />)
expect(container.firstElementChild!).toHaveAttribute('role', 'article')
expect(window.getComputedStyle(container.firstElementChild!).backgroundColor).toBe('rgb(255, 0, 0)')
})

Expand Down
78 changes: 58 additions & 20 deletions packages/styled-react/src/__tests__/primer-react.browser.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ import {

describe('@primer/react', () => {
test('ActionList supports `sx` prop', () => {
render(<ActionList data-testid="component" sx={{background: 'red'}} />)
render(<ActionList as="ul" data-testid="component" sx={{background: 'red'}} variant="inset" />)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This caught my eye, why do we need to explicitly set ActionList as="ul"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hi @siddharthkp, thanks for the review! Do you mean that we should use as="div" instead of the default ul for ActionList?

@siddharthkp siddharthkp Sep 29, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No sorry, I meant why do we need to pass it any as prop? Does it no longer render a <ul> by default?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The as prop in this test is specifically to catch the polymorphic prop forwarding issue that the pattern in PR #6910 fixes, when you wrap a component with styled(), the as prop can get consumed by styled-components instead of being forwarded to the wrapped component, which causes component specific props to fail to be consumed correctly. That's why we add both as and variant here to test that variant is correctly passed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh lol, my bad! That is literally what you are testing 😅

Do you mean that we should use as="div" instead of the default ul for ActionList?

This is a very good idea in that case!

expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component')).toHaveAttribute('data-variant', 'inset')
})

test('ActionMenu.Button supports `sx` prop', () => {
Expand Down Expand Up @@ -109,7 +110,7 @@ describe('@primer/react', () => {
})

test('Box supports `sx` prop', () => {
render(<Box data-testid="component" sx={{background: 'red'}} />)
render(<Box as="div" data-testid="component" sx={{background: 'red'}} />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
})

Expand All @@ -119,13 +120,15 @@ describe('@primer/react', () => {
})

test('Breadcrumbs.Item supports `sx` prop', () => {
render(<Breadcrumbs.Item data-testid="component" sx={{background: 'red'}} />)
render(<Breadcrumbs.Item as="li" data-testid="component" sx={{background: 'red'}} selected />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component').className.includes('selected')).toBe(true)
})

test('Button supports `sx` prop', () => {
render(<Button data-testid="component" sx={{background: 'red'}} />)
render(<Button as="button" data-testid="component" sx={{background: 'red'}} size="medium" />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component')).toHaveAttribute('data-size', 'medium')
})

test('Checkbox supports `sx` prop', () => {
Expand Down Expand Up @@ -156,8 +159,9 @@ describe('@primer/react', () => {
})

test('Flash supports `sx` prop', () => {
render(<Flash data-testid="component" sx={{background: 'red'}} />)
render(<Flash as="div" data-testid="component" sx={{background: 'red'}} variant="success" />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component')).toHaveAttribute('variant', 'success')
})

test('FormControl supports `sx` prop', () => {
Expand All @@ -170,7 +174,7 @@ describe('@primer/react', () => {
})

test('Header supports `sx` prop', () => {
render(<Header data-testid="component" sx={{background: 'red'}} />)
render(<Header as="header" data-testid="component" sx={{background: 'red'}} />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
})

Expand All @@ -180,23 +184,40 @@ describe('@primer/react', () => {
})

test('IconButton supports `sx` prop', () => {
render(<IconButton aria-label="test" data-testid="component" sx={{background: 'red'}} icon={() => <svg />} />)
render(
<IconButton
as="button"
aria-label="test"
data-testid="component"
sx={{background: 'red'}}
icon={() => <svg />}
/>,
)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')

// Test that IconButton renders the icon component (SVG) in its children
const iconButton = screen.getByTestId('component')
const svgElement = iconButton.querySelector('svg')
expect(svgElement).toBeInTheDocument()
expect(iconButton.children.length).toBeGreaterThan(0)
})

test('Label supports `sx` prop', () => {
render(<Label data-testid="component" sx={{background: 'red'}} />)
render(<Label as="span" data-testid="component" sx={{background: 'red'}} size="large" />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component')).toHaveAttribute('data-size', 'large')
})

test('Link supports `sx` prop', () => {
render(<Link data-testid="component" sx={{background: 'red'}} />)
render(<Link as="a" data-testid="component" sx={{background: 'red'}} inline />)
expect(screen.getByTestId('component')).toHaveAttribute('data-inline', 'true')
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
})

test('LinkButton supports `sx` prop', () => {
render(<LinkButton data-testid="component" sx={{background: 'red'}} />)
render(<LinkButton as="a" data-testid="component" sx={{background: 'red'}} icon={<svg />} />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component')).toHaveAttribute('icon')
})

test('NavList supports `sx` prop', () => {
Expand Down Expand Up @@ -234,19 +255,23 @@ describe('@primer/react', () => {
render(
<ThemeProvider>
<Overlay
as="div"
data-testid="component"
sx={{background: 'red'}}
onClickOutside={() => {}}
onEscape={() => {}}
returnFocusRef={ref}
role="dialog"
/>
</ThemeProvider>,
)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component')).toHaveAttribute('role', 'dialog')
})

test('PageHeader supports `sx` prop', () => {
const {container} = render(<PageHeader data-testid="component" sx={{background: 'red'}} />)
const {container} = render(<PageHeader as="div" data-testid="component" sx={{background: 'red'}} role="article" />)
expect(container.firstElementChild!).toHaveAttribute('role', 'article')
expect(window.getComputedStyle(container.firstElementChild!).backgroundColor).toBe('rgb(255, 0, 0)')
})

Expand All @@ -271,8 +296,13 @@ describe('@primer/react', () => {
})

test('PageLayout.Content supports `sx` prop', () => {
const {container} = render(<PageLayout.Content data-testid="component" sx={{background: 'red'}} />)
expect(window.getComputedStyle(container.firstElementChild!).backgroundColor).toBe('rgb(255, 0, 0)')
const {container} = render(
<PageLayout.Content as="section" data-testid="component" sx={{background: 'red'}} aria-labelledby="normal" />,
)

const outerElement = container.firstElementChild! as HTMLElement
expect(window.getComputedStyle(outerElement).backgroundColor).toBe('rgb(255, 0, 0)')
expect(outerElement).toHaveAttribute('aria-labelledby', 'normal')
})

test('PageLayout.Pane supports `sx` prop', () => {
Expand Down Expand Up @@ -334,8 +364,9 @@ describe('@primer/react', () => {
})

test.skip('Select supports `sx` prop', () => {
render(<Select data-testid="component" sx={{background: 'red'}} />)
render(<Select as="select" data-testid="component" sx={{background: 'red'}} required />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component')).toHaveAttribute('required')
})

test('Spinner supports `sx` prop', () => {
Expand All @@ -359,13 +390,15 @@ describe('@primer/react', () => {
})

test('Text supports `sx` prop', () => {
render(<Text data-testid="component" sx={{background: 'red'}} />)
render(<Text as="span" data-testid="component" sx={{background: 'red'}} size="small" />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component')).toHaveAttribute('data-size', 'small')
})

test('TextInput supports `sx` prop', () => {
const {container} = render(<TextInput sx={{background: 'red'}} />)
const {container} = render(<TextInput as="input" sx={{background: 'red'}} loading />)
expect(window.getComputedStyle(container.firstElementChild!).backgroundColor).toBe('rgb(255, 0, 0)')
expect(container.firstElementChild).toHaveAttribute('data-trailing-visual', 'true')
})

test('TextInput.Action supports `sx` prop', () => {
Expand Down Expand Up @@ -404,8 +437,9 @@ describe('@primer/react', () => {
})

test('Token supports `sx` prop', () => {
render(<Token data-testid="component" sx={{background: 'red'}} text="test" />)
render(<Token as="button" data-testid="component" sx={{background: 'red'}} text="test" />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component')).toHaveTextContent('test')
})

test.todo('Tooltip supports `sx` prop', () => {
Expand All @@ -418,25 +452,29 @@ describe('@primer/react', () => {
})

test('Truncate supports `sx` prop', () => {
render(<Truncate data-testid="component" sx={{background: 'red'}} title="test" />)
render(<Truncate as="div" data-testid="component" sx={{background: 'red'}} title="test" />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component')).toHaveAttribute('title', 'test')
})

test('UnderlineNav supports `sx` prop', () => {
render(
<UnderlineNav aria-label="navigation" data-testid="component" sx={{background: 'red'}}>
<UnderlineNav as="nav" aria-label="navigation" data-testid="component" sx={{background: 'red'}} variant="inset">
<UnderlineNav.Item>test</UnderlineNav.Item>
</UnderlineNav>,
)
expect(window.getComputedStyle(screen.getByLabelText('navigation')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByLabelText('navigation')).toHaveAttribute('data-variant', 'inset')
})

test('UnderlineNav.Item supports `sx` prop', () => {
render(
<UnderlineNav.Item data-testid="component" sx={{background: 'red'}}>
<UnderlineNav.Item as="a" data-testid="component" sx={{background: 'red'}} icon={<svg />}>
test
</UnderlineNav.Item>,
)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
const svgElement = screen.getByTestId('component').querySelector('svg')
expect(svgElement).toBeInTheDocument()
})
})
Loading