-
Notifications
You must be signed in to change notification settings - Fork 627
feat: add createStyledComponent helper to styled-react package #6588
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
0992aab
5923573
36e29d9
670eb91
b790a14
6cefe22
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import {beforeEach} from 'vitest' | ||
import {cleanup} from '@testing-library/react' | ||
import '@testing-library/jest-dom/vitest' | ||
|
||
beforeEach(() => { | ||
cleanup() | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import {render, screen} from '@testing-library/react' | ||
import {describe, test, expect} from 'vitest' | ||
import {createStyledComponent} from '../createStyledComponent' | ||
|
||
describe('createStyledComponent', () => { | ||
test('supports the sx prop', () => { | ||
const Wrapper = createStyledComponent(function Test(props: React.ComponentPropsWithoutRef<'div'>) { | ||
return <div {...props} data-testid="wrapper" /> | ||
}) | ||
|
||
render(<Wrapper sx={{display: 'flex'}} />) | ||
|
||
const wrapper = screen.getByTestId('wrapper') | ||
const style = window.getComputedStyle(wrapper) | ||
expect(style.display).toBe('flex') | ||
}) | ||
|
||
test('supports the as prop', () => { | ||
const Wrapper = createStyledComponent(function Test({ | ||
as: BaseComponent, | ||
...rest | ||
}: { | ||
as: React.ElementType | ||
className?: string | ||
}) { | ||
return <BaseComponent {...rest} /> | ||
}) | ||
|
||
render(<Wrapper as="section" data-testid="wrapper" sx={{display: 'flex'}} />) | ||
const wrapper = screen.getByTestId('wrapper') | ||
expect(wrapper.tagName).toBe('SECTION') | ||
|
||
const style = window.getComputedStyle(wrapper) | ||
expect(style.display).toBe('flex') | ||
}) | ||
|
||
test('supports original component props on wrapper', () => { | ||
const Wrapper = createStyledComponent(function Test(props: {variant: 'a' | 'b'}) { | ||
return <div data-testid="wrapper" data-variant={props.variant} /> | ||
}) | ||
|
||
render(<Wrapper variant="a" />) | ||
expect(screen.getByTestId('wrapper')).toHaveAttribute('data-variant', 'a') | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import {sx} from '@primer/react' | ||
import type {SxProp} from '@primer/react' | ||
import type React from 'react' | ||
import styled from 'styled-components' | ||
import {background, border, color, flexbox, grid, layout, position, shadow, space, typography} from 'styled-system' | ||
import type { | ||
BackgroundProps, | ||
BorderProps, | ||
ColorProps, | ||
FlexboxProps, | ||
GridProps, | ||
LayoutProps, | ||
PositionProps, | ||
ShadowProps, | ||
SpaceProps, | ||
TypographyProps, | ||
} from 'styled-system' | ||
|
||
type StyledBoxProps = SxProp & | ||
SpaceProps & | ||
ColorProps & | ||
TypographyProps & | ||
LayoutProps & | ||
FlexboxProps & | ||
GridProps & | ||
BackgroundProps & | ||
BorderProps & | ||
PositionProps & | ||
ShadowProps | ||
|
||
/** | ||
* Utility that mirrors the functionality of the `Box` component from | ||
* `@primer/react`. Used to create a styled component variant of a component | ||
* from `@primer/react` that no longer supports `sx` or other styled-system | ||
* props. | ||
* | ||
* Note: make sure to include #__PURE__ when using this function to create a | ||
* component. For example: | ||
* | ||
* ```tsx | ||
* const Link = \/*#__PURE__*\/ createStyledComponent(PrimerLink) | ||
* ``` | ||
*/ | ||
export function createStyledComponent<P>(Component: React.ComponentType<P>) { | ||
return styled(Component)<StyledBoxProps>( | ||
space, | ||
color, | ||
typography, | ||
layout, | ||
flexbox, | ||
grid, | ||
background, | ||
border, | ||
position, | ||
shadow, | ||
sx, | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"extends": "../../tsconfig.base.json", | ||
"include": ["src", "vitest.config.ts"] | ||
"include": ["src", "vitest.config.ts", "config/vitest"] | ||
} | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,21 @@ | ||||||
import react from '@vitejs/plugin-react' | ||||||
import {defineConfig} from 'vitest/config' | ||||||
|
||||||
export default defineConfig({ | ||||||
plugins: [react()], | ||||||
test: { | ||||||
include: ['src/**/*.browser.test.?(c|m)[jt]s?(x)'], | ||||||
setupFiles: ['config/vitest/browser/setup.ts'], | ||||||
browser: { | ||||||
provider: 'playwright', | ||||||
enabled: true, | ||||||
headless: process.env.DEBUG_BROWSER_TESTS === 'true' ? false : true, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nitpick] The conditional can be simplified to
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||
instances: [ | ||||||
{ | ||||||
browser: 'chromium', | ||||||
}, | ||||||
], | ||||||
screenshotFailures: false, | ||||||
}, | ||||||
}, | ||||||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment contains an escaped forward slash that makes the example code invalid. Remove the backslash to show the correct usage:
/*#__PURE__*/
Copilot uses AI. Check for mistakes.