Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
6 changes: 6 additions & 0 deletions .changeset/modern-chicken-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@primer/react": major
"@primer/styled-react": patch
---

chore: remove sx from deprecated Dialog
28 changes: 16 additions & 12 deletions packages/react/src/DialogV1/Dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
import React, {forwardRef, useRef, type HTMLAttributes} from 'react'
import {IconButton} from '../Button'
import useDialog from '../hooks/useDialog'
import type {SxProp} from '../sx'
import type {ComponentProps} from '../utils/types'
import {useRefObjectAsForwardedRef} from '../hooks/useRefObjectAsForwardedRef'
import {XIcon} from '@primer/octicons-react'
import {clsx} from 'clsx'
import classes from './Dialog.module.css'
import {BoxWithFallback} from '../internal/components/BoxWithFallback'

// Dialog v1
const noop = () => null

type StyledDialogBaseProps = {
narrow?: boolean
wide?: boolean
} & SxProp
as?: React.ElementType
}

export type DialogHeaderProps = React.PropsWithChildren<HTMLAttributes<HTMLDivElement>> & SxProp
export type DialogHeaderProps = React.PropsWithChildren<HTMLAttributes<HTMLDivElement>> & {
as?: React.ElementType
}

function DialogHeader({children, className, ...rest}: DialogHeaderProps) {
function DialogHeader({children, className, as: Component = 'div', ...rest}: DialogHeaderProps) {
if (React.Children.toArray(children).every(ch => typeof ch === 'string')) {
children = <span className={classes.HeaderChild}>{children}</span>
}

return (
<BoxWithFallback as="div" {...rest} className={clsx(classes.Header, className)}>
<Component {...rest} className={clsx(classes.Header, className)}>
{children}
</BoxWithFallback>
</Component>
)
}

Expand All @@ -36,11 +37,15 @@ type InternalDialogProps = {
onDismiss?: () => void
initialFocusRef?: React.RefObject<HTMLElement>
returnFocusRef?: React.RefObject<HTMLElement>
as?: React.ElementType
} & StyledDialogBaseProps &
HTMLAttributes<HTMLDivElement>

const Dialog = forwardRef<HTMLDivElement, InternalDialogProps>(
({children, onDismiss = noop, isOpen, initialFocusRef, returnFocusRef, className, ...props}, forwardedRef) => {
(
{children, onDismiss = noop, isOpen, initialFocusRef, returnFocusRef, className, as: Component = 'div', ...props},
forwardedRef,
) => {
const overlayRef = useRef(null)
const modalRef = useRef<HTMLDivElement>(null)
useRefObjectAsForwardedRef(forwardedRef, modalRef)
Expand All @@ -65,9 +70,8 @@ const Dialog = forwardRef<HTMLDivElement, InternalDialogProps>(

return isOpen ? (
<>
<BoxWithFallback as="span" className={classes.Overlay} ref={overlayRef} />
<BoxWithFallback
as="div"
<span className={classes.Overlay} ref={overlayRef} />
<Component
tabIndex={-1}
ref={modalRef}
role="dialog"
Expand All @@ -86,7 +90,7 @@ const Dialog = forwardRef<HTMLDivElement, InternalDialogProps>(
className={classes.CloseIcon}
/>
{children}
</BoxWithFallback>
</Component>
</>
) : null
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@ import {Button} from '../index'

describe('@primer/react/deprecated', () => {
test('Dialog supports `sx` prop', () => {
render(<Dialog data-testid="component" isOpen sx={{background: 'red'}} />)
render(<Dialog as="button" data-testid="component" isOpen sx={{background: 'red'}} />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component').role).toBe('dialog')
})

test('Dialog.Header supports `sx` prop', () => {
render(<Dialog.Header as="button" data-testid="component" sx={{background: 'red'}} />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
expect(screen.getByTestId('component').className.includes('Header')).toBe(true)
})

test('Octicon supports `sx` prop', () => {
Expand Down
36 changes: 36 additions & 0 deletions packages/styled-react/src/components/DialogV1.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {Dialog as PrimerDialog} from '@primer/react/deprecated'
import type {
DialogProps as PrimerDialogProps,
DialogHeaderProps as PrimerDialogHeaderProps,
} from '@primer/react/deprecated'
import {Box} from './Box'
import type {SxProp} from '../sx'
import {forwardRef} from 'react'
import type {ForwardRefComponent} from '../polymorphic'

type DialogProps = PrimerDialogProps & SxProp & {as?: React.ElementType}
Comment thread
francinelucca marked this conversation as resolved.
Outdated

const StyledDialog = forwardRef<HTMLDivElement, DialogProps>(function Dialog(props, ref) {
return <Box as={PrimerDialog} ref={ref} {...props} />
})

const DialogImpl = forwardRef(({as, ...props}: DialogProps, ref) => (
<StyledDialog {...props} {...(as ? {forwardedAs: as} : {})} ref={ref} />
)) as ForwardRefComponent<'div', DialogProps>

type DialogHeaderProps = PrimerDialogHeaderProps & SxProp & {as?: React.ElementType}
Comment thread
francinelucca marked this conversation as resolved.
Outdated

const StyledDialogHeader = forwardRef<HTMLDivElement, DialogHeaderProps>(function DialogHeader(props, ref) {
return <Box as={PrimerDialog.Header} ref={ref} {...props} />
})

const DialogHeader = forwardRef(({as, ...props}: DialogHeaderProps, ref) => (
<StyledDialogHeader {...props} {...(as ? {forwardedAs: as} : {})} ref={ref} />
)) as ForwardRefComponent<'div', DialogHeaderProps>

const Dialog = Object.assign(DialogImpl, {
Header: DialogHeader,
})

export {Dialog}
export type {DialogProps, DialogHeaderProps}
3 changes: 2 additions & 1 deletion packages/styled-react/src/deprecated.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export {TabNav, type TabNavProps, type TabNavLinkProps} from './components/TabNav'
export {Dialog, Octicon, Tooltip, type TooltipProps} from '@primer/react/deprecated'
export {Dialog, type DialogProps, type DialogHeaderProps} from './components/DialogV1'
export {Octicon, Tooltip, type TooltipProps} from '@primer/react/deprecated'
Loading