Skip to content

Commit 2fbdd3b

Browse files
JelloBageljonrohan
andauthoredDec 6, 2024··
feat(BaseStyles): Convert BaseStyles to CSS modules behind team feature flag (#5361)
* Create css modules for BaseStyles * Convert BaseStyles to CSS modules behind team feature flag * Add changeset * Update anchoroverlay snapshot for BaseStyles * Fix lint * Fix integration regression * Update snapshot to remove unnecessary whitespace --------- Co-authored-by: Jon Rohan <yes@jonrohan.codes>
1 parent b5ff840 commit 2fbdd3b

File tree

4 files changed

+88
-8
lines changed

4 files changed

+88
-8
lines changed
 

‎.changeset/grumpy-numbers-eat.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@primer/react": minor
3+
---
4+
5+
Convert BaseStyles to CSS modules behind team feature flag
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* stylelint-disable selector-max-specificity */
2+
/* stylelint-disable selector-type-no-unknown */
3+
4+
/* --------------------------------
5+
* Global Styles
6+
*--------------------------------- */
7+
* {
8+
box-sizing: border-box;
9+
}
10+
11+
body {
12+
margin: 0;
13+
}
14+
15+
table {
16+
/* stylelint-disable-next-line primer/borders */
17+
border-collapse: collapse;
18+
}
19+
20+
[role='button']:focus:not(:focus-visible):not(.focus-visible),
21+
[role='tabpanel'][tabindex='0']:focus:not(:focus-visible):not(.focus-visible),
22+
button:focus:not(:focus-visible):not(.focus-visible),
23+
summary:focus:not(:focus-visible):not(.focus-visible),
24+
a:focus:not(:focus-visible):not(.focus-visible) {
25+
outline: none;
26+
box-shadow: none;
27+
}
28+
29+
[tabindex='0']:focus:not(:focus-visible):not(.focus-visible),
30+
details-dialog:focus:not(:focus-visible):not(.focus-visible) {
31+
outline: none;
32+
}
33+
34+
/* -------------------------------------------------------------------------- */
35+
36+
.BaseStyles {
37+
/* Global styles for light mode */
38+
&:has([data-color-mode='light']) {
39+
input & {
40+
color-scheme: light;
41+
}
42+
}
43+
44+
/* Global styles for dark mode */
45+
&:has([data-color-mode='dark']) {
46+
input & {
47+
color-scheme: dark;
48+
}
49+
}
50+
}

‎packages/react/src/BaseStyles.tsx

+21-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
import React from 'react'
2+
import {clsx} from 'clsx'
23
import styled, {createGlobalStyle} from 'styled-components'
4+
import type {ComponentProps} from './utils/types'
35
import type {SystemCommonProps, SystemTypographyProps} from './constants'
46
import {COMMON, TYPOGRAPHY} from './constants'
57
import {useTheme} from './ThemeProvider'
6-
import type {ComponentProps} from './utils/types'
8+
import {useFeatureFlag} from './FeatureFlags'
9+
import {toggleStyledComponent} from './internal/utils/toggleStyledComponent'
10+
import classes from './BaseStyles.module.css'
711

812
// load polyfill for :focus-visible
913
import 'focus-visible'
1014

15+
const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_team'
16+
1117
const GlobalStyle = createGlobalStyle<{colorScheme?: 'light' | 'dark'}>`
1218
* { box-sizing: border-box; }
1319
body { margin: 0; }
@@ -29,27 +35,34 @@ const GlobalStyle = createGlobalStyle<{colorScheme?: 'light' | 'dark'}>`
2935
}
3036
`
3137

32-
const Base = styled.div<SystemTypographyProps & SystemCommonProps>`
33-
${TYPOGRAPHY};
34-
${COMMON};
35-
`
38+
const Base = toggleStyledComponent(
39+
CSS_MODULES_FEATURE_FLAG,
40+
'div',
41+
styled.div<SystemTypographyProps & SystemCommonProps>`
42+
${TYPOGRAPHY};
43+
${COMMON};
44+
`,
45+
)
3646

3747
export type BaseStylesProps = ComponentProps<typeof Base>
3848

3949
function BaseStyles(props: BaseStylesProps) {
40-
const {children, color = 'fg.default', fontFamily = 'normal', lineHeight = 'default', ...rest} = props
50+
const {children, color = 'fg.default', fontFamily = 'normal', lineHeight = 'default', className, ...rest} = props
4151

4252
const {colorScheme, dayScheme, nightScheme} = useTheme()
53+
const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG)
54+
55+
const stylingProps = enabled ? {className: clsx(classes.BaseStyles, className)} : {className}
4356

4457
/**
4558
* We need to map valid primer/react color modes onto valid color modes for primer/primitives
4659
* valid color modes for primer/primitives: auto | light | dark
4760
* valid color modes for primer/primer: auto | day | night | light | dark
4861
*/
49-
5062
return (
5163
<Base
5264
{...rest}
65+
{...stylingProps}
5366
color={color}
5467
fontFamily={fontFamily}
5568
lineHeight={lineHeight}
@@ -58,7 +71,7 @@ function BaseStyles(props: BaseStylesProps) {
5871
data-light-theme={dayScheme}
5972
data-dark-theme={nightScheme}
6073
>
61-
<GlobalStyle colorScheme={colorScheme?.includes('dark') ? 'dark' : 'light'} />
74+
{!enabled && <GlobalStyle colorScheme={colorScheme?.includes('dark') ? 'dark' : 'light'} />}
6275
{children}
6376
</Base>
6477
)

‎packages/react/src/__tests__/BaseStyles.test.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,16 @@ describe('BaseStyles', () => {
3030
const {container} = render(<BaseStyles {...styles}></BaseStyles>)
3131
expect(container.children[0]).toHaveStyle({color: '#f00', 'font-family': 'Arial', 'line-height': '3.5'})
3232
})
33+
34+
it('accepts className and style props', () => {
35+
const styles = {
36+
style: {margin: '10px'},
37+
className: 'test-classname',
38+
sx: {},
39+
}
40+
41+
const {container} = render(<BaseStyles {...styles}></BaseStyles>)
42+
expect(container.children[0]).toHaveClass('test-classname')
43+
expect(container.children[0]).toHaveStyle({margin: '10px'})
44+
})
3345
})

0 commit comments

Comments
 (0)
Please sign in to comment.