Skip to content

Commit

Permalink
Merge https://github.com/primer/react into auto-complete-css-modules
Browse files Browse the repository at this point in the history
  • Loading branch information
hussam-i-am committed Dec 18, 2024
2 parents 4f9a0d2 + bd568fd commit 9131ee9
Show file tree
Hide file tree
Showing 229 changed files with 469 additions and 136 deletions.
5 changes: 5 additions & 0 deletions .changeset/clean-camels-train.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

Bug fix: ButtonGroup with Tooltip border-radius is incorrect
5 changes: 5 additions & 0 deletions .changeset/polite-books-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

Fix Typography and Common props for BaseStyles when CSS modules feature flag is enabled
5 changes: 5 additions & 0 deletions .changeset/shiny-horses-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

Move Header component css module feature flag to ga
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 4 additions & 9 deletions e2e/components/Autocomplete.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@ const stories: Array<{title: string; id: string; setup: (page: Page) => void}> =
await page.keyboard.press('D')
},
},
{
title: 'Playground',
id: 'components-autocomplete--playground',
setup: async page => {
await page.keyboard.press('Backspace')
},
},
{
title: 'Add New Item',
id: 'components-autocomplete-features--add-new-item',
Expand Down Expand Up @@ -64,6 +57,7 @@ const stories: Array<{title: string; id: string; setup: (page: Page) => void}> =
setup: async page => {
await page.keyboard.press('Tab')
await page.keyboard.press('Enter')
await expect(page.getByRole('dialog')).toBeVisible()
await page.keyboard.press('Tab')
await page.keyboard.press('D')
},
Expand Down Expand Up @@ -124,7 +118,7 @@ test.describe('Autocomplete', () => {
},
})

await story.setup(page)
story.setup(page)

await expect(page).toHaveScreenshot(`Autocomplete.${story.title}.${theme}.png`, {animations: 'disabled'})
})
Expand All @@ -137,7 +131,7 @@ test.describe('Autocomplete', () => {
},
})

await story.setup(page)
story.setup(page)

await expect(page).toHaveNoViolations({
rules: {
Expand All @@ -149,6 +143,7 @@ test.describe('Autocomplete', () => {
theme !== 'light_colorblind' &&
theme !== 'light_tritanopia',
},
'aria-valid-attr-value': {enabled: false},
},
})
})
Expand Down
28 changes: 28 additions & 0 deletions e2e/components/ButtonGroup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,32 @@ test.describe('ButtonGroup', () => {
})
}
})

test.describe('Overrides', () => {
for (const theme of themes) {
test.describe(theme, () => {
test('default @vrt', async ({page}) => {
await visit(page, {
id: 'components-buttongroup-devonly--link-button-with-icon-buttons',
globals: {
colorScheme: theme,
},
})

// Default state
expect(await page.screenshot()).toMatchSnapshot(`ButtonGroup.Overrides.${theme}.png`)
})

test('axe @aat', async ({page}) => {
await visit(page, {
id: 'components-buttongroup-devonly--link-button-with-icon-buttons',
globals: {
colorScheme: theme,
},
})
await expect(page).toHaveNoViolations()
})
})
}
})
})
12 changes: 7 additions & 5 deletions packages/react/.storybook/storybook.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,22 +56,24 @@
background-color: var(--bgColor-muted);
}

/* !important simulates CSS layers in dotcom that prioritize custom classes over Primer React styles */

.testCustomClassnameColor {
color: var(--fgColor-sponsors);
color: var(--fgColor-sponsors) !important;
}

.testCustomClassnameBgColor {
background-color: var(--bgColor-sponsors-emphasis);
background-color: var(--bgColor-sponsors-emphasis) !important;
}

.testCustomClassnameBorderColor {
border-color: var(--borderColor-sponsors-emphasis);
border-color: var(--borderColor-sponsors-emphasis) !important;
}

.testCustomClassnameBorder {
border: var(--borderWidth-thin) solid var(--borderColor-sponsors-emphasis);
border: var(--borderWidth-thin) solid var(--borderColor-sponsors-emphasis) !important;
}

.testCustomClassnameMono {
font-family: var(--fontStack-monospace);
font-family: var(--fontStack-monospace) !important;
}
6 changes: 3 additions & 3 deletions packages/react/src/Autocomplete/Autocomplete.dev.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ export const SxProp = () => {
sx={{
width: '100%',
marginRight: '10px',
borderColor: 'deeppink',
}}
size="medium"
style={{border: '1px solid var(--borderColor-closed-emphasis)'}}
/>
<Autocomplete.Overlay
className="test-class-name"
className="testCustomClassnameBorder"
visibility="visible"
sx={{
maxHeight: 'min(50vh, 280px)',
Expand All @@ -32,8 +32,8 @@ export const SxProp = () => {
flexDirection: 'column',
whiteSpace: 'pre-wrap',
},
outline: '1px solid deeppink',
}}
style={{backgroundColor: 'var(--bgColor-attention-emphasis)'}}
>
<Autocomplete.Menu items={[]} selectedItemIds={[]} aria-labelledby="autocompleteLabel" />
</Autocomplete.Overlay>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ const autocompleteStoryMeta: Meta = {
<ThemeProvider>
<BaseStyles>
<Box onKeyDownCapture={reportKey}>
<Box position="absolute" right={5} top={2}>
<Box as="p" position="absolute" right={5} top={2} id="key-press-label">
Last key pressed: {lastKey}
</Box>
<Box paddingTop={5}>
Expand Down Expand Up @@ -567,6 +567,7 @@ export const InOverlayWithCustomScrollContainerRef = () => {
},
}}
block
aria-label="Search"
/>
</Box>
<Box
Expand Down Expand Up @@ -606,7 +607,12 @@ export const InADialog = () => {
return (
<>
<Button onClick={() => setIsDialogOpen(true)}>Show dialog</Button>
<Dialog id="dialog-with-autocomplete" isOpen={isDialogOpen} onDismiss={() => setIsDialogOpen(false)}>
<Dialog
aria-label="Dialog with autocomplete"
id="dialog-with-autocomplete"
isOpen={isDialogOpen}
onDismiss={() => setIsDialogOpen(false)}
>
<div ref={outerContainerRef}>
<Box as="form" sx={{p: 3}}>
{mounted ? (
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/Autocomplete/Autocomplete.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const autocompleteStoryMeta: Meta = {
<ThemeProvider>
<BaseStyles>
<Box onKeyDownCapture={reportKey}>
<Box position="absolute" right={5} top={2}>
<Box as="p" position="absolute" right={5} top={2} id="key-press-label">
Last key pressed: {lastKey}
</Box>
<Box paddingTop={5}>
Expand Down
3 changes: 1 addition & 2 deletions packages/react/src/BaseStyles.dev.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import {BaseStyles} from '.'
import type {Meta} from '@storybook/react'
import React from 'react'
import type {ComponentProps} from './utils/types'

export default {
title: 'Behaviors/BaseStyles/Dev',
component: BaseStyles,
} as Meta<ComponentProps<typeof BaseStyles>>

export const Default = () => <BaseStyles>Hello</BaseStyles>
export const Default = () => 'Hello'
113 changes: 89 additions & 24 deletions packages/react/src/BaseStyles.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React from 'react'
import React, {type CSSProperties, type PropsWithChildren} 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 {useFeatureFlag} from './FeatureFlags'
import {toggleStyledComponent} from './internal/utils/toggleStyledComponent'
import Box from './Box'
import type {SxProp} from './sx'
import {includesSystemProps, getTypographyAndCommonProps} from './utils/includeSystemProps'

import classes from './BaseStyles.module.css'

// load polyfill for :focus-visible
Expand Down Expand Up @@ -35,45 +37,108 @@ const GlobalStyle = createGlobalStyle<{colorScheme?: 'light' | 'dark'}>`
}
`

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

export type BaseStylesProps = ComponentProps<typeof Base>
export type BaseStylesProps = PropsWithChildren & {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
as?: React.ComponentType<any> | keyof JSX.IntrinsicElements
className?: string
style?: CSSProperties
color?: string // Fixes `color` ts-error
} & SystemTypographyProps &
SystemCommonProps &
SxProp

function BaseStyles(props: BaseStylesProps) {
const {children, color = 'fg.default', fontFamily = 'normal', lineHeight = 'default', className, ...rest} = props
const {
children,
color = 'var(--fgColor-default)',
fontFamily = 'normal',
lineHeight = 'default',
className,
as: Component = 'div',
...rest
} = props

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

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

// If props includes TYPOGRAPHY or COMMON props, pass them to the Box component
if (includesSystemProps(props)) {
const systemProps = getTypographyAndCommonProps(props)
return (
// @ts-ignore shh
<Box
as={Component}
className={newClassName}
color={color}
fontFamily={fontFamily}
lineHeight={lineHeight}
data-portal-root
/**
* 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
*/
data-color-mode={colorScheme?.includes('dark') ? 'dark' : 'light'}
data-light-theme={dayScheme}
data-dark-theme={nightScheme}
style={systemProps}
{...rest}
>
{children}
</Box>
)
}

return (
<Component
className={newClassName}
color={color}
fontFamily={fontFamily}
lineHeight={lineHeight}
data-portal-root
/**
* 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
*/
data-color-mode={colorScheme?.includes('dark') ? 'dark' : 'light'}
data-light-theme={dayScheme}
data-dark-theme={nightScheme}
{...rest}
>
{children}
</Component>
)
}

/**
* 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}
<StyledDiv
className={className}
color={color}
fontFamily={fontFamily}
lineHeight={lineHeight}
data-portal-root
/**
* 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
*/
data-color-mode={colorScheme?.includes('dark') ? 'dark' : 'light'}
data-light-theme={dayScheme}
data-dark-theme={nightScheme}
{...rest}
>
{!enabled && <GlobalStyle colorScheme={colorScheme?.includes('dark') ? 'dark' : 'light'} />}
<GlobalStyle colorScheme={colorScheme?.includes('dark') ? 'dark' : 'light'} />
{children}
</Base>
</StyledDiv>
)
}

Expand Down
Loading

0 comments on commit 9131ee9

Please sign in to comment.