Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
448a776
refactor(styled-react): update how we re-export components
joshblack Sep 4, 2025
d6817df
chore: add changesets
joshblack Sep 4, 2025
8fe405d
chore(lint): fix eslint error
joshblack Sep 4, 2025
3c52b30
chore: disable Box eslint warning in styled-react
joshblack Sep 4, 2025
8e84f1f
chore: remove eslint-disable
joshblack Sep 4, 2025
ab6d98c
refactor: add tests for styled-react entrypoint
joshblack Sep 5, 2025
c34dff9
test: add tests for each entrypoint
joshblack Sep 5, 2025
4907e80
docs: add architecture docs
joshblack Sep 5, 2025
ad98370
chore: clean up lint errors
joshblack Sep 5, 2025
02c3a4e
chore: add changesets
joshblack Sep 5, 2025
3c876dc
chore: add changeset
joshblack Sep 5, 2025
7094882
Merge branch 'main' into refactor/update-styled-react-entrypoint
joshblack Sep 5, 2025
1c864f6
docs: fix markdownlint errors
joshblack Sep 5, 2025
6e2373e
Merge branch 'refactor/update-styled-react-entrypoint' of github.com:…
joshblack Sep 5, 2025
064b24a
chore: remove BranchName from styled-react
joshblack Sep 5, 2025
967c7e3
Merge branch 'main' into refactor/update-styled-react-entrypoint
joshblack Sep 5, 2025
b457e81
chore: remove ProgressBar
joshblack Sep 5, 2025
9bd61a5
Merge branch 'main' into refactor/update-styled-react-entrypoint
joshblack Sep 8, 2025
a540961
Merge branch 'refactor/update-styled-react-entrypoint' of github.com:…
joshblack Sep 8, 2025
ba0563a
chore: remove details component
joshblack Sep 8, 2025
e84b0e5
Merge branch 'main' into refactor/update-styled-react-entrypoint
joshblack Sep 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/chubby-colts-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/styled-react': patch
---

Refactor ToggleSwitch export type to match original type from @primer/react
5 changes: 5 additions & 0 deletions .changeset/nine-cobras-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': minor
---

Add ToggleSwitchProps type to package exports
1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const config = defineConfig([
'contributor-docs/adrs/*',
'examples/codesandbox/**/*',
'packages/react/src/utils/polymorphic.ts',
'packages/styled-react/src/polymorphic.d.ts',
'**/storybook-static',
'**/CHANGELOG.md',
'**/node_modules/**/*',
Expand Down
3 changes: 3 additions & 0 deletions package-lock.json

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
Expand Up @@ -177,6 +177,7 @@ exports[`@primer/react > should not update exports without a semver change 1`] =
"type TimelineItemsProps",
"type TimelineProps",
"ToggleSwitch",
"type ToggleSwitchProps",
"Token",
"type TokenProps",
"Tooltip",
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export type {StateLabelProps} from './StateLabel'
export {default as SubNav} from './SubNav'
export type {SubNavProps, SubNavLinkProps, SubNavLinksProps} from './SubNav'
export {default as ToggleSwitch} from './ToggleSwitch'
export type {ToggleSwitchProps} from './ToggleSwitch'
export {default as TextInput} from './TextInput'
export type {TextInputProps} from './TextInput'
export {default as TextInputWithTokens} from './TextInputWithTokens'
Expand Down
1 change: 1 addition & 0 deletions packages/styled-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"type-check": "tsc --noEmit"
},
"devDependencies": {
"@babel/preset-react": "^7.27.1",
"@babel/preset-typescript": "^7.27.1",
"@primer/react": "^38.0.0-rc.1",
"@rollup/plugin-babel": "^6.0.4",
Expand Down
4 changes: 2 additions & 2 deletions packages/styled-react/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ function createPackageRegex(name) {
}

export default defineConfig({
input: ['src/index.ts', 'src/experimental.ts', 'src/deprecated.ts'],
input: ['src/index.tsx', 'src/experimental.tsx', 'src/deprecated.tsx'],
external: dependencies.map(createPackageRegex),
plugins: [
typescript({
tsconfig: 'tsconfig.build.json',
}),
babel({
presets: ['@babel/preset-typescript'],
presets: ['@babel/preset-typescript', '@babel/preset-react'],
extensions: ['.ts', '.tsx'],
babelHelpers: 'bundled',
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

exports[`@primer/styled-react exports 1`] = `
[
"ToggleSwitch",
"ActionList",
"ActionMenu",
"Autocomplete",
"Avatar",
"Box",
"BranchName",
"Breadcrumbs",
"Button",
Expand All @@ -25,6 +25,7 @@ exports[`@primer/styled-react exports 1`] = `
"LabelGroup",
"Link",
"LinkButton",
"merge",
"NavList",
"Overlay",
"PageHeader",
Expand All @@ -41,21 +42,20 @@ exports[`@primer/styled-react exports 1`] = `
"Stack",
"StateLabel",
"SubNav",
"sx",
"Text",
"Textarea",
"TextInput",
"TextInputWithTokens",
"theme",
"themeGet",
"ThemeProvider",
"Timeline",
"ToggleSwitch",
"Token",
"Tooltip",
"Truncate",
"UnderlineNav",
"Box",
"sx",
"ThemeProvider",
"merge",
"theme",
"themeGet",
"useColorSchemeVar",
"useTheme",
]
Expand Down
18 changes: 15 additions & 3 deletions packages/styled-react/src/__tests__/exports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,25 @@ import * as StyledReactDeprecated from '../deprecated'
import * as StyledReactExperimental from '../experimental'

test('@primer/styled-react exports', () => {
expect(Object.keys(StyledReact)).toMatchSnapshot()
expect(
Object.keys(StyledReact).sort((a, b) => {
return a.localeCompare(b)
}),
).toMatchSnapshot()
})

test('@primer/styled-react/deprecated exports', () => {
expect(Object.keys(StyledReactDeprecated)).toMatchSnapshot()
expect(
Object.keys(StyledReactDeprecated).sort((a, b) => {
return a.localeCompare(b)
}),
).toMatchSnapshot()
})

test('@primer/styled-react/experimental exports', () => {
expect(Object.keys(StyledReactExperimental)).toMatchSnapshot()
expect(
Object.keys(StyledReactExperimental).sort((a, b) => {
return a.localeCompare(b)
}),
).toMatchSnapshot()
})
70 changes: 0 additions & 70 deletions packages/styled-react/src/index.ts

This file was deleted.

105 changes: 105 additions & 0 deletions packages/styled-react/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {
type BetterSystemStyleObject,
Box,
type BoxProps,
type SxProp,
ToggleSwitch as PrimerToggleSwitch,
type ToggleSwitchProps as PrimerToggleSwitchProps,
} from '@primer/react'
import {forwardRef} from 'react'
import type {
BackgroundProps,
BorderProps,
ColorProps,
FlexboxProps,
GridProps,
LayoutProps,
PositionProps,
ShadowProps,
SpaceProps,
TypographyProps,
} from 'styled-system'
import type {ForwardRefComponent} from './polymorphic'

type StyledProps = SxProp &
SpaceProps &
ColorProps &
TypographyProps &
LayoutProps &
FlexboxProps &
GridProps &
BackgroundProps &
BorderProps &
PositionProps &
ShadowProps

const ToggleSwitch = forwardRef(function ToggleSwitch(props, ref) {
// @ts-expect-error there is an issue with polymorphic `as` with this
// component
Comment thread
joshblack marked this conversation as resolved.
Outdated
return <Box as={PrimerToggleSwitch} ref={ref} {...props} />

Check failure on line 39 in packages/styled-react/src/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Prefer plain HTML elements over `Box` when not using `sx` for styling
}) as ForwardRefComponent<'span', PrimerToggleSwitchProps & Omit<StyledProps, keyof PrimerToggleSwitchProps>>

export {ToggleSwitch}

export {
ActionList,
ActionMenu,
Autocomplete,
Avatar,
BranchName,
Breadcrumbs,
Button,
Checkbox,
CheckboxGroup,
CircleBadge,
CounterLabel,
Details,
Dialog,
Flash,
FormControl,
Header,
Heading,
IconButton,
Label,
LabelGroup,
Link,
LinkButton,
NavList,
Overlay,
PageHeader,
PageLayout,
Popover,
ProgressBar,
RadioGroup,
RelativeTime,
SegmentedControl,
Select,
SelectPanel,
SideNav,
Spinner,
Stack,
StateLabel,
SubNav,
Text,
Textarea,
TextInput,
TextInputWithTokens,
Timeline,
Token,
Tooltip,
Truncate,
UnderlineNav,

// styled-components components or types
Box,
sx,

// theming depends on styled-components
ThemeProvider,
merge,
theme,
themeGet,
useColorSchemeVar,
useTheme,
} from '@primer/react'
export type {BoxProps, SxProp, BetterSystemStyleObject}
60 changes: 60 additions & 0 deletions packages/styled-react/src/polymorphic.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* This file is originally from `@radix-ui/react-polymorphic` before the package
* was deprecated. The original source for this lived in the URL below.
*
* @see https://github.com/radix-ui/primitives/blob/17ffcb7aaa42cbd36b3c210ba86d7d73d218e5be/packages/react/polymorphic/src/polymorphic.ts
*/

import * as React from 'react'

/* -------------------------------------------------------------------------------------------------
* Utility types
* -----------------------------------------------------------------------------------------------*/
type Merge<P1 = {}, P2 = {}> = Omit<P1, keyof P2> & P2

/**
* Infers the OwnProps if E is a ForwardRefExoticComponentWithAs
*/
type OwnProps<E> = E extends ForwardRefComponent<any, infer P> ? P : {}

/**
* Infers the JSX.IntrinsicElement if E is a ForwardRefExoticComponentWithAs
*/
type IntrinsicElement<E> = E extends ForwardRefComponent<infer I, any> ? I : never

type ForwardRefExoticComponent<E, OwnProps> = React.ForwardRefExoticComponent<
Merge<E extends React.ElementType ? React.ComponentPropsWithRef<E> : never, OwnProps & {as?: E}>
>

/* -------------------------------------------------------------------------------------------------
* ForwardRefComponent
* -----------------------------------------------------------------------------------------------*/

interface ForwardRefComponent<
IntrinsicElementString,
OwnProps = {},
/**
* Extends original type to ensure built in React types play nice
* with polymorphic components still e.g. `React.ElementRef` etc.
*/
> extends ForwardRefExoticComponent<IntrinsicElementString, OwnProps> {
/**
* When `as` prop is passed, use this overload.
* Merges original own props (without DOM props) and the inferred props
* from `as` element with the own props taking precedence.
*
* We explicitly avoid `React.ElementType` and manually narrow the prop types
* so that events are typed when using JSX.IntrinsicElements.
*/
<As = IntrinsicElementString>(
props: As extends ''
? {as: keyof JSX.IntrinsicElements}
: As extends React.ComponentType<infer P>
? Merge<P, OwnProps & {as: As}>
: As extends keyof JSX.IntrinsicElements
? Merge<JSX.IntrinsicElements[As], OwnProps & {as: As}>
: never,
): React.ReactElement | null
}

export type {ForwardRefComponent, OwnProps, IntrinsicElement, Merge}
Loading
Loading