Skip to content

Commit

Permalink
feat(BaseStyles): Convert BaseStyles to CSS modules behind team featu…
Browse files Browse the repository at this point in the history
…re 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>
  • Loading branch information
JelloBagel and jonrohan authored Dec 6, 2024
1 parent b5ff840 commit 2fbdd3b
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/grumpy-numbers-eat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": minor
---

Convert BaseStyles to CSS modules behind team feature flag
50 changes: 50 additions & 0 deletions packages/react/src/BaseStyles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* stylelint-disable selector-max-specificity */
/* stylelint-disable selector-type-no-unknown */

/* --------------------------------
* Global Styles
*--------------------------------- */
* {
box-sizing: border-box;
}

body {
margin: 0;
}

table {
/* stylelint-disable-next-line primer/borders */
border-collapse: collapse;
}

[role='button']:focus:not(:focus-visible):not(.focus-visible),
[role='tabpanel'][tabindex='0']:focus:not(:focus-visible):not(.focus-visible),
button:focus:not(:focus-visible):not(.focus-visible),
summary:focus:not(:focus-visible):not(.focus-visible),
a:focus:not(:focus-visible):not(.focus-visible) {
outline: none;
box-shadow: none;
}

[tabindex='0']:focus:not(:focus-visible):not(.focus-visible),
details-dialog:focus:not(:focus-visible):not(.focus-visible) {
outline: none;
}

/* -------------------------------------------------------------------------- */

.BaseStyles {
/* Global styles for light mode */
&:has([data-color-mode='light']) {
input & {
color-scheme: light;
}
}

/* Global styles for dark mode */
&:has([data-color-mode='dark']) {
input & {
color-scheme: dark;
}
}
}
29 changes: 21 additions & 8 deletions packages/react/src/BaseStyles.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import React from 'react'
import {clsx} from 'clsx'
import styled, {createGlobalStyle} from 'styled-components'
import type {ComponentProps} from './utils/types'
import type {SystemCommonProps, SystemTypographyProps} from './constants'
import {COMMON, TYPOGRAPHY} from './constants'
import {useTheme} from './ThemeProvider'
import type {ComponentProps} from './utils/types'
import {useFeatureFlag} from './FeatureFlags'
import {toggleStyledComponent} from './internal/utils/toggleStyledComponent'
import classes from './BaseStyles.module.css'

// load polyfill for :focus-visible
import 'focus-visible'

const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_team'

const GlobalStyle = createGlobalStyle<{colorScheme?: 'light' | 'dark'}>`
* { box-sizing: border-box; }
body { margin: 0; }
Expand All @@ -29,27 +35,34 @@ const GlobalStyle = createGlobalStyle<{colorScheme?: 'light' | 'dark'}>`
}
`

const Base = styled.div<SystemTypographyProps & SystemCommonProps>`
${TYPOGRAPHY};
${COMMON};
`
const Base = toggleStyledComponent(
CSS_MODULES_FEATURE_FLAG,
'div',
styled.div<SystemTypographyProps & SystemCommonProps>`
${TYPOGRAPHY};
${COMMON};
`,
)

export type BaseStylesProps = ComponentProps<typeof Base>

function BaseStyles(props: BaseStylesProps) {
const {children, color = 'fg.default', fontFamily = 'normal', lineHeight = 'default', ...rest} = props
const {children, color = 'fg.default', fontFamily = 'normal', lineHeight = 'default', className, ...rest} = props

const {colorScheme, dayScheme, nightScheme} = useTheme()
const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG)

const stylingProps = enabled ? {className: clsx(classes.BaseStyles, className)} : {className}

/**
* We need to map valid primer/react color modes onto valid color modes for primer/primitives
* valid color modes for primer/primitives: auto | light | dark
* valid color modes for primer/primer: auto | day | night | light | dark
*/

return (
<Base
{...rest}
{...stylingProps}
color={color}
fontFamily={fontFamily}
lineHeight={lineHeight}
Expand All @@ -58,7 +71,7 @@ function BaseStyles(props: BaseStylesProps) {
data-light-theme={dayScheme}
data-dark-theme={nightScheme}
>
<GlobalStyle colorScheme={colorScheme?.includes('dark') ? 'dark' : 'light'} />
{!enabled && <GlobalStyle colorScheme={colorScheme?.includes('dark') ? 'dark' : 'light'} />}
{children}
</Base>
)
Expand Down
12 changes: 12 additions & 0 deletions packages/react/src/__tests__/BaseStyles.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,16 @@ describe('BaseStyles', () => {
const {container} = render(<BaseStyles {...styles}></BaseStyles>)
expect(container.children[0]).toHaveStyle({color: '#f00', 'font-family': 'Arial', 'line-height': '3.5'})
})

it('accepts className and style props', () => {
const styles = {
style: {margin: '10px'},
className: 'test-classname',
sx: {},
}

const {container} = render(<BaseStyles {...styles}></BaseStyles>)
expect(container.children[0]).toHaveClass('test-classname')
expect(container.children[0]).toHaveStyle({margin: '10px'})
})
})

0 comments on commit 2fbdd3b

Please sign in to comment.