From e3b7646fbf067d0bc5454d7e5f903790040a8267 Mon Sep 17 00:00:00 2001 From: Jon Rohan Date: Wed, 17 Sep 2025 01:05:20 +0000 Subject: [PATCH 01/12] Remove sx support from the TabNav component --- packages/react/src/TabNav/TabNav.tsx | 16 +++++-------- packages/styled-react/src/components/Box.tsx | 1 + .../styled-react/src/components/TabNav.tsx | 23 +++++++++++++++++++ packages/styled-react/src/deprecated.tsx | 3 ++- packages/styled-react/src/sx.ts | 1 + 5 files changed, 33 insertions(+), 11 deletions(-) create mode 100644 packages/styled-react/src/components/Box.tsx create mode 100644 packages/styled-react/src/components/TabNav.tsx create mode 100644 packages/styled-react/src/sx.ts diff --git a/packages/react/src/TabNav/TabNav.tsx b/packages/react/src/TabNav/TabNav.tsx index 46d38c3c5d6..2fc83b5fa4a 100644 --- a/packages/react/src/TabNav/TabNav.tsx +++ b/packages/react/src/TabNav/TabNav.tsx @@ -2,16 +2,13 @@ import {clsx} from 'clsx' import type {To} from 'history' import React, {useRef, useState} from 'react' import {FocusKeys, useFocusZone} from '../hooks/useFocusZone' -import type {SxProp} from '../sx' -import type {ComponentProps} from '../utils/types' import styles from './TabNav.module.css' -import {BoxWithFallback} from '../internal/components/BoxWithFallback' /** * @deprecated */ -export type TabNavProps = ComponentProps +export type TabNavProps = React.HTMLProps /** * @deprecated @@ -53,13 +50,13 @@ function TabNav({children, 'aria-label': ariaLabel, ...rest}: TabNavProps) { ) return ( - }> +
}> - +
) } @@ -73,18 +70,17 @@ export type TabNavLinkProps = React.DetailedHTMLProps(function TabNavLink( - {selected, className, as = 'a', ...rest}: TabNavLinkProps, + {selected, className, as: Component = 'a', ...rest}: TabNavLinkProps, ref, ) { return ( - +}) as ForwardRefComponent<'div', TabNavProps> + +const TabNavLink = forwardRef(function TabNavLinkImpl(props, ref) { + return +}) as ForwardRefComponent<'div', TabNavLinkProps> + +const TabNav = Object.assign(TabNavImpl, { + Link: TabNavLink, +}) + +export {TabNav, type TabNavProps, type TabNavLinkProps} diff --git a/packages/styled-react/src/deprecated.tsx b/packages/styled-react/src/deprecated.tsx index 7f9c75b5124..210011b1fa5 100644 --- a/packages/styled-react/src/deprecated.tsx +++ b/packages/styled-react/src/deprecated.tsx @@ -1 +1,2 @@ -export {Dialog, Octicon, TabNav, Tooltip} from '@primer/react/deprecated' +export {TabNav, type TabNavProps, type TabNavLinkProps} from './components/TabNav' +export {Dialog, Octicon, Tooltip} from '@primer/react/deprecated' diff --git a/packages/styled-react/src/sx.ts b/packages/styled-react/src/sx.ts new file mode 100644 index 00000000000..01f43b165e3 --- /dev/null +++ b/packages/styled-react/src/sx.ts @@ -0,0 +1 @@ +export type {SxProp} from '@primer/react' From dd57a1e30e6e2810d134c75592c35c1ee6e66349 Mon Sep 17 00:00:00 2001 From: Jon Rohan Date: Tue, 16 Sep 2025 18:10:52 -0700 Subject: [PATCH 02/12] Create changeset --- .changeset/lucky-wasps-nail.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/lucky-wasps-nail.md diff --git a/.changeset/lucky-wasps-nail.md b/.changeset/lucky-wasps-nail.md new file mode 100644 index 00000000000..37174b1f61f --- /dev/null +++ b/.changeset/lucky-wasps-nail.md @@ -0,0 +1,6 @@ +--- +"@primer/react": major +"@primer/styled-react": patch +--- + +Remove support for `sx` from the `TabNav` component From 8c4431e6f640f00079f0f6163bc8f6d6455cb3f0 Mon Sep 17 00:00:00 2001 From: Jon Rohan Date: Wed, 24 Sep 2025 05:22:18 +0000 Subject: [PATCH 03/12] Use link ref component --- packages/styled-react/src/components/TabNav.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/styled-react/src/components/TabNav.tsx b/packages/styled-react/src/components/TabNav.tsx index e2942e14409..5f2ad1f7270 100644 --- a/packages/styled-react/src/components/TabNav.tsx +++ b/packages/styled-react/src/components/TabNav.tsx @@ -14,7 +14,7 @@ const TabNavImpl = forwardRef(function TabNavImpl(props, ref) { const TabNavLink = forwardRef(function TabNavLinkImpl(props, ref) { return -}) as ForwardRefComponent<'div', TabNavLinkProps> +}) as ForwardRefComponent<'a', TabNavLinkProps> const TabNav = Object.assign(TabNavImpl, { Link: TabNavLink, From 8677994c2bd20c59c8e75d3bf0a215fbaf93cc01 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Thu, 25 Sep 2025 10:13:33 -0400 Subject: [PATCH 04/12] use styled() wrapper in TabNav --- .../styled-react/src/components/TabNav.tsx | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/styled-react/src/components/TabNav.tsx b/packages/styled-react/src/components/TabNav.tsx index 5f2ad1f7270..527805c100f 100644 --- a/packages/styled-react/src/components/TabNav.tsx +++ b/packages/styled-react/src/components/TabNav.tsx @@ -3,18 +3,23 @@ import type {TabNavProps as PrimerTabNavProps, TabNavLinkProps as PrimerTabNavLi import {forwardRef} from 'react' import {Box} from './Box' import type {ForwardRefComponent} from '../polymorphic' -import type {SxProp} from '../sx' +import {sx, type SxProp} from '../sx' +import styled from 'styled-components' type TabNavProps = PrimerTabNavProps & SxProp type TabNavLinkProps = PrimerTabNavLinkProps & SxProp -const TabNavImpl = forwardRef(function TabNavImpl(props, ref) { - return -}) as ForwardRefComponent<'div', TabNavProps> +const TabNavImpl: ForwardRefComponent<'div', TabNavProps> = styled(PrimerTabNav).withConfig({ + shouldForwardProp: prop => (prop as keyof TabNavProps) !== 'sx', +})` + ${sx} +` -const TabNavLink = forwardRef(function TabNavLinkImpl(props, ref) { - return -}) as ForwardRefComponent<'a', TabNavLinkProps> +const TabNavLink = styled(PrimerTabNav.Link).withConfig({ + shouldForwardProp: prop => (prop as keyof TabNavLinkProps) !== 'sx', +})` + ${sx} +` const TabNav = Object.assign(TabNavImpl, { Link: TabNavLink, From 85f4d7118130a6fbd1260a8a074b462325367eff Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Thu, 25 Sep 2025 11:20:30 -0400 Subject: [PATCH 05/12] remove unused imports --- packages/styled-react/src/components/TabNav.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/styled-react/src/components/TabNav.tsx b/packages/styled-react/src/components/TabNav.tsx index 527805c100f..076f150e152 100644 --- a/packages/styled-react/src/components/TabNav.tsx +++ b/packages/styled-react/src/components/TabNav.tsx @@ -1,7 +1,5 @@ import {TabNav as PrimerTabNav} from '@primer/react/deprecated' import type {TabNavProps as PrimerTabNavProps, TabNavLinkProps as PrimerTabNavLinkProps} from '@primer/react/deprecated' -import {forwardRef} from 'react' -import {Box} from './Box' import type {ForwardRefComponent} from '../polymorphic' import {sx, type SxProp} from '../sx' import styled from 'styled-components' From 1cde2a78091c9ad4a1a972bc23243ad5638820c1 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Thu, 25 Sep 2025 11:26:05 -0400 Subject: [PATCH 06/12] fix ttpes --- packages/styled-react/src/components/TabNav.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/styled-react/src/components/TabNav.tsx b/packages/styled-react/src/components/TabNav.tsx index 076f150e152..271e4d425b8 100644 --- a/packages/styled-react/src/components/TabNav.tsx +++ b/packages/styled-react/src/components/TabNav.tsx @@ -1,13 +1,12 @@ import {TabNav as PrimerTabNav} from '@primer/react/deprecated' import type {TabNavProps as PrimerTabNavProps, TabNavLinkProps as PrimerTabNavLinkProps} from '@primer/react/deprecated' -import type {ForwardRefComponent} from '../polymorphic' import {sx, type SxProp} from '../sx' import styled from 'styled-components' type TabNavProps = PrimerTabNavProps & SxProp type TabNavLinkProps = PrimerTabNavLinkProps & SxProp -const TabNavImpl: ForwardRefComponent<'div', TabNavProps> = styled(PrimerTabNav).withConfig({ +const TabNavImpl = styled(PrimerTabNav).withConfig({ shouldForwardProp: prop => (prop as keyof TabNavProps) !== 'sx', })` ${sx} From ef7a58d9f56c9f4dd56d7ae07dc0184ce6cc8042 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Thu, 25 Sep 2025 13:05:19 -0400 Subject: [PATCH 07/12] type fixes --- packages/react/src/TabNav/TabNav.tsx | 5 +++-- packages/styled-react/src/components/TabNav.tsx | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/react/src/TabNav/TabNav.tsx b/packages/react/src/TabNav/TabNav.tsx index 2fc83b5fa4a..876e130160f 100644 --- a/packages/react/src/TabNav/TabNav.tsx +++ b/packages/react/src/TabNav/TabNav.tsx @@ -2,6 +2,7 @@ import {clsx} from 'clsx' import type {To} from 'history' import React, {useRef, useState} from 'react' import {FocusKeys, useFocusZone} from '../hooks/useFocusZone' +import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic' import styles from './TabNav.module.css' @@ -75,7 +76,7 @@ export type TabNavLinkProps = React.DetailedHTMLProps(function TabNavLink( +const TabNavLink = React.forwardRef(function TabNavLink( {selected, className, as: Component = 'a', ...rest}: TabNavLinkProps, ref, ) { @@ -89,7 +90,7 @@ const TabNavLink = React.forwardRef(function {...rest} /> ) -}) +}) as PolymorphicForwardRefComponent<'a', TabNavLinkProps> TabNavLink.displayName = 'TabNav.Link' diff --git a/packages/styled-react/src/components/TabNav.tsx b/packages/styled-react/src/components/TabNav.tsx index 271e4d425b8..022806d00db 100644 --- a/packages/styled-react/src/components/TabNav.tsx +++ b/packages/styled-react/src/components/TabNav.tsx @@ -2,6 +2,7 @@ import {TabNav as PrimerTabNav} from '@primer/react/deprecated' import type {TabNavProps as PrimerTabNavProps, TabNavLinkProps as PrimerTabNavLinkProps} from '@primer/react/deprecated' import {sx, type SxProp} from '../sx' import styled from 'styled-components' +import {type ForwardRefComponent} from '../polymorphic' type TabNavProps = PrimerTabNavProps & SxProp type TabNavLinkProps = PrimerTabNavLinkProps & SxProp @@ -12,7 +13,7 @@ const TabNavImpl = styled(PrimerTabNav).withConfig({ ${sx} ` -const TabNavLink = styled(PrimerTabNav.Link).withConfig({ +const TabNavLink: ForwardRefComponent<'a', TabNavLinkProps> = styled(PrimerTabNav.Link).withConfig({ shouldForwardProp: prop => (prop as keyof TabNavLinkProps) !== 'sx', })` ${sx} From 9ff5487fd31032123ffc83e7f74324ecf5400177 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Thu, 25 Sep 2025 13:13:35 -0400 Subject: [PATCH 08/12] fix? --- packages/styled-react/src/components/TabNav.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/styled-react/src/components/TabNav.tsx b/packages/styled-react/src/components/TabNav.tsx index 022806d00db..762b00703a9 100644 --- a/packages/styled-react/src/components/TabNav.tsx +++ b/packages/styled-react/src/components/TabNav.tsx @@ -1,7 +1,7 @@ import {TabNav as PrimerTabNav} from '@primer/react/deprecated' import type {TabNavProps as PrimerTabNavProps, TabNavLinkProps as PrimerTabNavLinkProps} from '@primer/react/deprecated' import {sx, type SxProp} from '../sx' -import styled from 'styled-components' +import styled, {type StyledComponent} from 'styled-components' import {type ForwardRefComponent} from '../polymorphic' type TabNavProps = PrimerTabNavProps & SxProp @@ -19,7 +19,11 @@ const TabNavLink: ForwardRefComponent<'a', TabNavLinkProps> = styled(PrimerTabNa ${sx} ` -const TabNav = Object.assign(TabNavImpl, { +type TabNavComponent = StyledComponent & { + Link: typeof TabNavLink +} + +const TabNav: TabNavComponent = Object.assign(TabNavImpl, { Link: TabNavLink, }) From 4afea95284e6d5435c5c424e27ed64f0ef1fb0db Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Thu, 25 Sep 2025 13:18:19 -0400 Subject: [PATCH 09/12] eslint ignore --- packages/styled-react/src/components/TabNav.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/styled-react/src/components/TabNav.tsx b/packages/styled-react/src/components/TabNav.tsx index 762b00703a9..290fc430e9f 100644 --- a/packages/styled-react/src/components/TabNav.tsx +++ b/packages/styled-react/src/components/TabNav.tsx @@ -18,7 +18,7 @@ const TabNavLink: ForwardRefComponent<'a', TabNavLinkProps> = styled(PrimerTabNa })` ${sx} ` - +// eslint-disable-next-line @typescript-eslint/no-explicit-any type TabNavComponent = StyledComponent & { Link: typeof TabNavLink } From 7ee152431a92ff4c1457ab9eba22cb8ba5f58bb0 Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Thu, 25 Sep 2025 16:22:35 -0400 Subject: [PATCH 10/12] git commit -m "test" --- packages/react/src/TabNav/TabNav.tsx | 1 + .../src/__tests__/primer-react-deprecated.browser.test.tsx | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/react/src/TabNav/TabNav.tsx b/packages/react/src/TabNav/TabNav.tsx index 876e130160f..e575212ec43 100644 --- a/packages/react/src/TabNav/TabNav.tsx +++ b/packages/react/src/TabNav/TabNav.tsx @@ -80,6 +80,7 @@ const TabNavLink = React.forwardRef(function TabNavLink( {selected, className, as: Component = 'a', ...rest}: TabNavLinkProps, ref, ) { + console.log('hi') return ( { test('Dialog supports `sx` prop', () => { @@ -18,9 +19,10 @@ describe('@primer/react/deprecated', () => { expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)') }) - test('TabNav.Link supports `sx` prop', () => { - render() + test.only('TabNav.Link supports `sx` prop', () => { + render() expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)') + expect(window.getComputedStyle(screen.getByRole('tab')).backgroundColor).toBe('rgb(255, 0, 0)') }) test('Tooltip supports `sx` prop', () => { From be66cd38cf03595eb3968fabcd786c2815a34f1f Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Thu, 25 Sep 2025 17:27:16 -0400 Subject: [PATCH 11/12] fix as prop --- .../styled-react/src/components/TabNav.tsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/styled-react/src/components/TabNav.tsx b/packages/styled-react/src/components/TabNav.tsx index 290fc430e9f..451d11362a2 100644 --- a/packages/styled-react/src/components/TabNav.tsx +++ b/packages/styled-react/src/components/TabNav.tsx @@ -1,29 +1,31 @@ import {TabNav as PrimerTabNav} from '@primer/react/deprecated' import type {TabNavProps as PrimerTabNavProps, TabNavLinkProps as PrimerTabNavLinkProps} from '@primer/react/deprecated' import {sx, type SxProp} from '../sx' -import styled, {type StyledComponent} from 'styled-components' +import styled from 'styled-components' import {type ForwardRefComponent} from '../polymorphic' type TabNavProps = PrimerTabNavProps & SxProp type TabNavLinkProps = PrimerTabNavLinkProps & SxProp -const TabNavImpl = styled(PrimerTabNav).withConfig({ +const StyledTabNav = styled(PrimerTabNav).withConfig({ shouldForwardProp: prop => (prop as keyof TabNavProps) !== 'sx', })` ${sx} ` -const TabNavLink: ForwardRefComponent<'a', TabNavLinkProps> = styled(PrimerTabNav.Link).withConfig({ +// @ts-ignore +const TabNavImpl = ({as, ...props}: TabNavProps) => + +const StyledTabNavLink: ForwardRefComponent<'a', TabNavLinkProps> = styled(PrimerTabNav.Link).withConfig({ shouldForwardProp: prop => (prop as keyof TabNavLinkProps) !== 'sx', })` ${sx} ` -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type TabNavComponent = StyledComponent & { - Link: typeof TabNavLink -} -const TabNav: TabNavComponent = Object.assign(TabNavImpl, { +// @ts-ignore +const TabNavLink = ({as, ...props}: TabNavLinkProps) => + +const TabNav = Object.assign(TabNavImpl, { Link: TabNavLink, }) From 51e1b7b951812ff47651dd228d106de55f60ac5d Mon Sep 17 00:00:00 2001 From: Marie Lucca Date: Thu, 25 Sep 2025 17:30:04 -0400 Subject: [PATCH 12/12] fix fix fix --- packages/react/src/TabNav/TabNav.tsx | 1 - .../src/__tests__/primer-react-deprecated.browser.test.tsx | 3 ++- packages/styled-react/src/components/TabNav.tsx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react/src/TabNav/TabNav.tsx b/packages/react/src/TabNav/TabNav.tsx index e575212ec43..876e130160f 100644 --- a/packages/react/src/TabNav/TabNav.tsx +++ b/packages/react/src/TabNav/TabNav.tsx @@ -80,7 +80,6 @@ const TabNavLink = React.forwardRef(function TabNavLink( {selected, className, as: Component = 'a', ...rest}: TabNavLinkProps, ref, ) { - console.log('hi') return ( { expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)') }) - test.only('TabNav.Link supports `sx` prop', () => { + test('TabNav.Link supports `sx` prop', () => { render() expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)') expect(window.getComputedStyle(screen.getByRole('tab')).backgroundColor).toBe('rgb(255, 0, 0)') + expect(screen.getByRole('tab').tagName).toBe('BUTTON') }) test('Tooltip supports `sx` prop', () => { diff --git a/packages/styled-react/src/components/TabNav.tsx b/packages/styled-react/src/components/TabNav.tsx index 451d11362a2..94e39f50eb3 100644 --- a/packages/styled-react/src/components/TabNav.tsx +++ b/packages/styled-react/src/components/TabNav.tsx @@ -13,7 +13,7 @@ const StyledTabNav = styled(PrimerTabNav).withConfig({ ${sx} ` -// @ts-ignore +// @ts-ignore forwardedAs is valid here but I don't know how to fix the typescript error const TabNavImpl = ({as, ...props}: TabNavProps) => const StyledTabNavLink: ForwardRefComponent<'a', TabNavLinkProps> = styled(PrimerTabNav.Link).withConfig({ @@ -22,7 +22,7 @@ const StyledTabNavLink: ForwardRefComponent<'a', TabNavLinkProps> = styled(Prime ${sx} ` -// @ts-ignore +// @ts-ignore forwardedAs is valid here but I don't know how to fix the typescript error const TabNavLink = ({as, ...props}: TabNavLinkProps) => const TabNav = Object.assign(TabNavImpl, {