Skip to content

Commit 6e03bf9

Browse files
authored
refactor(Flash): update sx usage to CSS Modules (#6007)
1 parent f1fedf3 commit 6e03bf9

File tree

4 files changed

+113
-101
lines changed

4 files changed

+113
-101
lines changed

.changeset/giant-bushes-matter.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@primer/react': minor
3+
---
4+
5+
Update Flash from sx to CSS Modules
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
.Flash {
2+
position: relative;
3+
padding: var(--base-size-16);
4+
margin-top: 0;
5+
color: var(--fgColor-default);
6+
border-style: solid;
7+
border-width: var(--borderWidth-thin);
8+
border-radius: var(--borderRadius-medium);
9+
10+
&:where([data-variant='default']) {
11+
background-color: var(--bgColor-accent-muted);
12+
border-color: var(--borderColor-accent-muted);
13+
14+
& :where(svg) {
15+
color: var(--fgColor-accent);
16+
}
17+
}
18+
19+
&:where([data-variant='success']) {
20+
background-color: var(--bgColor-success-muted);
21+
border-color: var(--borderColor-success-muted);
22+
23+
& :where(svg) {
24+
color: var(--fgColor-success);
25+
}
26+
}
27+
28+
&:where([data-variant='danger']) {
29+
background-color: var(--bgColor-danger-muted);
30+
border-color: var(--borderColor-danger-muted);
31+
32+
& :where(svg) {
33+
color: var(--fgColor-danger);
34+
}
35+
}
36+
37+
&:where([data-variant='warning']) {
38+
background-color: var(--bgColor-attention-muted);
39+
border-color: var(--borderColor-attention-muted);
40+
41+
& :where(svg) {
42+
color: var(--fgColor-attention);
43+
}
44+
}
45+
46+
&:where([data-full]) {
47+
/* stylelint-disable-next-line primer/spacing */
48+
margin-top: -1px;
49+
border-width: var(--borderWidth-thin) 0;
50+
border-radius: 0;
51+
}
52+
53+
& :where(p:last-child) {
54+
margin-bottom: 0;
55+
}
56+
57+
& :where(svg) {
58+
margin-right: var(--base-size-8);
59+
}
60+
}

packages/react/src/Flash/Flash.tsx

Lines changed: 18 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,29 @@
1+
import {clsx} from 'clsx'
12
import React from 'react'
2-
import styled from 'styled-components'
3-
import {variant} from 'styled-system'
4-
import {get} from '../constants'
53
import type {SxProp} from '../sx'
6-
import sx from '../sx'
7-
import type {ComponentProps} from '../utils/types'
84
import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic'
5+
import {BoxWithFallback} from '../internal/components/BoxWithFallback'
6+
import classes from './Flash.module.css'
97

10-
const variants = variant({
11-
variants: {
12-
default: {
13-
color: 'fg.default',
14-
backgroundColor: 'accent.subtle',
15-
borderColor: 'accent.muted',
16-
svg: {
17-
color: 'accent.fg',
18-
},
19-
},
20-
success: {
21-
color: 'fg.default',
22-
backgroundColor: 'success.subtle',
23-
borderColor: 'success.muted',
24-
svg: {
25-
color: 'success.fg',
26-
},
27-
},
28-
danger: {
29-
color: 'fg.default',
30-
backgroundColor: 'danger.subtle',
31-
borderColor: 'danger.muted',
32-
svg: {
33-
color: 'danger.fg',
34-
},
35-
},
36-
warning: {
37-
color: 'fg.default',
38-
backgroundColor: 'attention.subtle',
39-
borderColor: 'attention.muted',
40-
svg: {
41-
color: 'attention.fg',
42-
},
43-
},
44-
},
45-
})
46-
47-
type StyledFlashProps = {
8+
export type FlashProps = React.ComponentPropsWithoutRef<'div'> & {
9+
className?: string
4810
variant?: 'default' | 'warning' | 'success' | 'danger'
4911
full?: boolean
5012
} & SxProp
5113

52-
const StyledFlash = styled.div<StyledFlashProps>`
53-
position: relative;
54-
color: ${get('colors.fg.default')};
55-
padding: ${get('space.3')};
56-
border-style: solid;
57-
border-width: ${props => (props.full ? '1px 0px' : '1px')};
58-
border-radius: ${props => (props.full ? '0' : get('radii.2'))};
59-
margin-top: ${props => (props.full ? '-1px' : '0')};
60-
61-
p:last-child {
62-
margin-bottom: 0;
63-
}
64-
65-
svg {
66-
margin-right: ${get('space.2')};
67-
}
68-
69-
${variants};
70-
${sx};
71-
`
72-
73-
export type FlashProps = ComponentProps<typeof StyledFlash>
74-
75-
const Flash = React.forwardRef(function Flash({as, variant = 'default', ...rest}, ref) {
76-
return <StyledFlash ref={ref} as={as} variant={variant} {...rest} />
77-
}) as PolymorphicForwardRefComponent<'div', StyledFlashProps>
14+
const Flash = React.forwardRef(function Flash({as, className, variant = 'default', full, sx, ...rest}, ref) {
15+
return (
16+
<BoxWithFallback
17+
{...rest}
18+
ref={ref}
19+
as={as}
20+
className={clsx(classes.Flash, className)}
21+
data-full={full ? '' : undefined}
22+
data-variant={variant}
23+
sx={sx}
24+
/>
25+
)
26+
}) as PolymorphicForwardRefComponent<'div', FlashProps>
7827

7928
if (__DEV__) {
8029
Flash.displayName = 'Flash'
Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,42 @@
11
import React from 'react'
22
import Flash from '..'
3-
import {render, behavesAsComponent, checkExports} from '../../utils/testing'
4-
import {render as HTMLRender} from '@testing-library/react'
5-
import axe from 'axe-core'
3+
import {render, screen} from '@testing-library/react'
64

75
describe('Flash', () => {
8-
behavesAsComponent({Component: Flash})
9-
10-
checkExports('Flash', {
11-
default: Flash,
6+
it('should support the `full` prop', () => {
7+
render(
8+
<>
9+
<Flash data-testid="full" full />
10+
<Flash data-testid="no-full" />
11+
</>,
12+
)
13+
expect(screen.getByTestId('full')).toHaveAttribute('data-full', '')
14+
expect(screen.getByTestId('no-full')).not.toHaveAttribute('data-full')
1215
})
1316

14-
it('should have no axe violations', async () => {
15-
const {container} = HTMLRender(<Flash variant="warning" />)
16-
const results = await axe.run(container)
17-
expect(results).toHaveNoViolations()
17+
it('should support the `variant` prop', () => {
18+
render(
19+
<>
20+
<Flash data-testid="danger" variant="danger" />
21+
<Flash data-testid="success" variant="success" />
22+
<Flash data-testid="warning" variant="warning" />
23+
<Flash data-testid="default" variant="default" />
24+
</>,
25+
)
26+
27+
expect(screen.getByTestId('danger')).toHaveAttribute('data-variant', 'danger')
28+
expect(screen.getByTestId('success')).toHaveAttribute('data-variant', 'success')
29+
expect(screen.getByTestId('warning')).toHaveAttribute('data-variant', 'warning')
30+
expect(screen.getByTestId('default')).toHaveAttribute('data-variant', 'default')
1831
})
1932

20-
it('respects the "full" prop', () => {
21-
expect(render(<Flash full />)).toHaveStyleRule('margin-top', '-1px')
22-
expect(render(<Flash full />)).toHaveStyleRule('border-radius', '0')
23-
expect(render(<Flash full />)).toHaveStyleRule('border-width', '1px 0px')
33+
it('should support `className` on the outermost element', () => {
34+
const {container} = render(<Flash className="test-class" />)
35+
expect(container.firstChild).toHaveClass('test-class')
2436
})
2537

26-
it('respects the "variant" prop', () => {
27-
expect(render(<Flash variant="warning" />)).toHaveStyleRule(
28-
'background-color',
29-
'var(--bgColor-attention-muted,var(--color-attention-subtle,#fff8c5))',
30-
)
31-
expect(render(<Flash variant="danger" />)).toHaveStyleRule(
32-
'background-color',
33-
'var(--bgColor-danger-muted,var(--color-danger-subtle,#ffebe9))',
34-
)
35-
expect(render(<Flash variant="success" />)).toHaveStyleRule(
36-
'background-color',
37-
'var(--bgColor-success-muted,var(--color-success-subtle,#dafbe1))',
38-
)
39-
expect(render(<Flash />)).toHaveStyleRule(
40-
'background-color',
41-
'var(--bgColor-accent-muted,var(--color-accent-subtle,#ddf4ff))',
42-
)
38+
it('should spread props to the outermost element', () => {
39+
const {container} = render(<Flash data-testid="test" />)
40+
expect(container.firstChild).toHaveAttribute('data-testid', 'test')
4341
})
4442
})

0 commit comments

Comments
 (0)