Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions .changeset/sharp-onions-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@primer/react": patch
"@primer/styled-react": patch
---

@primer/styled-react: chore(navlist): remove unneeded exports
@primer/react: add missing isSlot checks
7 changes: 6 additions & 1 deletion packages/react/src/NavList/NavList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ const Item = React.forwardRef<HTMLAnchorElement, NavListItemProps>(

// Get children without SubNav or TrailingAction
const childrenWithoutSubNavOrTrailingAction = React.Children.toArray(children).filter(child =>
isValidElement(child) ? child.type !== SubNav && child.type !== TrailingAction : true,
isValidElement(child)
? child.type !== SubNav &&
child.type !== TrailingAction &&
!isSlot(child, SubNav) &&
!isSlot(child, TrailingAction)
: true,
)

if (!isValidElement(subNav) && defaultOpen)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,31 +271,6 @@ describe('@primer/react', () => {
expect(window.getComputedStyle(itemLiEl!).backgroundColor).toBe('rgb(255, 0, 0)')
})

test('NavList.Group supports `sx` prop', () => {
render(
<NavList>
<NavList.Group data-testid="component" sx={{background: 'red'}}>
<NavList.Item>item</NavList.Item>
</NavList.Group>
</NavList>,
)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
})

test('NavList.GroupHeading supports `sx` prop', () => {
render(
<NavList>
<NavList.Group>
<NavList.GroupHeading data-testid="component" sx={{background: 'red'}}>
test
</NavList.GroupHeading>
<NavList.Item>item</NavList.Item>
</NavList.Group>
</NavList>,
)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
})

test('NavList.LeadingVisual supports `sx` prop', () => {
render(<NavList.LeadingVisual data-testid="component" sx={{background: 'red'}} />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
Expand Down
75 changes: 41 additions & 34 deletions packages/styled-react/src/components/NavList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,63 @@ import {NavList as PrimerNavList} from '@primer/react'
import type {
NavListProps as PrimerNavListProps,
NavListItemProps as PrimerNavListItemProps,
NavListGroupProps as PrimerNavListGroupProps,
NavListGroupHeadingProps as PrimerNavListGroupHeadingProps,
NavListLeadingVisualProps as PrimerNavListLeadingVisualProps,
SlotMarker,
} from '@primer/react'
import {forwardRef, type PropsWithChildren} from 'react'
import {type SxProp} from '../sx'
import Box from './Box'
import styled from 'styled-components'
import {sx} from '../sx'
import type {ForwardRefComponent} from '../polymorphic'

type RefComponent<E extends HTMLElement, P> = React.ForwardRefExoticComponent<P & React.RefAttributes<E>>
type NavListProps = PropsWithChildren<PrimerNavListProps> & SxProp & {as?: React.ElementType}

type NavListProps = PropsWithChildren<PrimerNavListProps> & SxProp
const StyledNavListImpl = styled(PrimerNavList).withConfig({
shouldForwardProp: prop => (prop as keyof NavListProps) !== 'sx',
})<NavListProps>`
${sx}
`

const NavListImpl = forwardRef<HTMLElement, NavListProps>(function NavList(props, ref) {
return <Box as={PrimerNavList} ref={ref} {...props} />
const NavListImpl = forwardRef<HTMLElement, NavListProps>(function NavList({as, ...props}, ref) {
return <StyledNavListImpl ref={ref} {...(as ? {forwardedAs: as} : {})} {...props} />
})

type NavListItemProps = PropsWithChildren<PrimerNavListItemProps> & SxProp
type NavListItemProps = PropsWithChildren<PrimerNavListItemProps> &
SxProp & {
as?: React.ElementType
}

const NavListItem = forwardRef<HTMLAnchorElement, NavListItemProps>(function NavListItem(props, ref) {
// @ts-expect-error - PrimerNavList.Item is not recognized as a valid component type
return <Box as={PrimerNavList.Item} ref={ref} {...props} />
})

type NavListGroupProps = PropsWithChildren<PrimerNavListGroupProps> & SxProp
const StyledNavListItem: ForwardRefComponent<'a', NavListItemProps> = styled(PrimerNavList.Item).withConfig({
shouldForwardProp: prop => (prop as keyof NavListItemProps) !== 'sx',
})<NavListItemProps>`
${sx}
`

const NavListGroup = forwardRef<HTMLLIElement, NavListGroupProps>(function NavListGroup(props, ref) {
// @ts-expect-error - PrimerNavList.Group is not recognized as a valid component type
return <Box as={PrimerNavList.Group} ref={ref} {...props} />
})
const NavListItem = forwardRef<HTMLAnchorElement, NavListItemProps>(({as, ...props}, ref) => {
return <StyledNavListItem {...props} {...(as ? {forwardedAs: as} : {})} ref={ref} />
}) as ForwardRefComponent<'a', NavListItemProps>

type NavListGroupHeadingProps = PropsWithChildren<PrimerNavListGroupHeadingProps> & SxProp
type NavListLeadingVisualProps = PropsWithChildren<PrimerNavListLeadingVisualProps> &
SxProp & {
as?: React.ElementType
}

const NavListGroupHeading = forwardRef<HTMLElement, NavListGroupHeadingProps>(function NavListGroupHeading(props, ref) {
// @ts-expect-error - PrimerNavList.GroupHeading is not recognized as a valid component type
return <Box as={PrimerNavList.GroupHeading} ref={ref} {...props} />
}) as RefComponent<HTMLElement, NavListGroupHeadingProps>
const StyledNavListLeadingVisual = styled(PrimerNavList.LeadingVisual).withConfig({
shouldForwardProp: prop => (prop as keyof NavListLeadingVisualProps) !== 'sx',
})<NavListLeadingVisualProps>`
${sx}
`

type NavListLeadingVisualProps = PropsWithChildren<PrimerNavListLeadingVisualProps> & SxProp
const NavListLeadingVisual = forwardRef<HTMLSpanElement, NavListLeadingVisualProps>(({as, ...props}, ref) => {
return <StyledNavListLeadingVisual {...props} {...(as ? {forwardedAs: as} : {})} ref={ref} />
}) as ForwardRefComponent<'span', NavListLeadingVisualProps>

const NavListLeadingVisual = forwardRef<HTMLSpanElement, NavListLeadingVisualProps>(
function NavListLeadingVisual(props, ref) {
// @ts-expect-error - PrimerNavList.LeadingVisual is not recognized as a valid component type
return <Box as={PrimerNavList.LeadingVisual} ref={ref} {...props} />
},
) as RefComponent<HTMLSpanElement, NavListLeadingVisualProps>
;(NavListLeadingVisual as typeof NavListLeadingVisual & SlotMarker).__SLOT__ = PrimerNavList.LeadingVisual.__SLOT__

type NavListCompound = React.ForwardRefExoticComponent<NavListProps & React.RefAttributes<HTMLElement>> & {
Item: typeof NavListItem
Group: typeof NavListGroup
GroupHeading: typeof NavListGroupHeading
Group: typeof PrimerNavList.Group
GroupHeading: typeof PrimerNavList.GroupHeading
LeadingVisual: typeof NavListLeadingVisual
SubNav: typeof PrimerNavList.SubNav
Divider: typeof PrimerNavList.Divider
Expand All @@ -62,8 +69,8 @@ type NavListCompound = React.ForwardRefExoticComponent<NavListProps & React.RefA

const NavList: NavListCompound = Object.assign(NavListImpl, {
Item: NavListItem,
Group: NavListGroup,
GroupHeading: NavListGroupHeading,
Group: PrimerNavList.Group,
GroupHeading: PrimerNavList.GroupHeading,
LeadingVisual: NavListLeadingVisual,
SubNav: PrimerNavList.SubNav,
Divider: PrimerNavList.Divider,
Expand Down
Loading