Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changeset/sweet-results-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': major
---

Remove support for `sx` from the Dialog component and sub-components
12 changes: 0 additions & 12 deletions e2e/components/Dialog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,6 @@ const stories = [
title: 'Position sidesheet',
id: 'components-dialog-features--side-sheet',
},
{
title: 'Dev: With Css',
id: 'components-dialog-dev--with-css',
},
{
title: 'Dev: With Sx',
id: 'components-dialog-dev--with-sx',
},
{
title: 'Dev: With Sx And Css',
id: 'components-dialog-dev--with-sx-and-css',
},
] as const

test.describe('Dialog', () => {
Expand Down
107 changes: 0 additions & 107 deletions packages/react/src/Dialog/Dialog.dev.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,113 +87,6 @@ export const WithCss = ({width, height, subtitle}: DialogStoryProps) => {
)
}

function SxHeader({title, subtitle, dialogLabelId}: React.PropsWithChildren<DialogProps & {dialogLabelId: string}>) {
if (typeof title === 'string' && typeof subtitle === 'string') {
return (
<Dialog.Header sx={{color: 'accent.emphasis'}}>
<h1 id={dialogLabelId}>{title.toUpperCase()}</h1>
</Dialog.Header>
)
}
return null
}
function SxBody({children}: React.PropsWithChildren<DialogProps>) {
return <Dialog.Body sx={{color: 'danger.emphasis'}}>{children}</Dialog.Body>
}
function SxFooter({footerButtons}: React.PropsWithChildren<DialogProps>) {
return (
<Dialog.Footer sx={{fontFamily: 'Times New Roman'}}>
{footerButtons ? <Dialog.Buttons buttons={footerButtons} /> : null}
</Dialog.Footer>
)
}
export const WithSx = ({width, height, subtitle}: DialogStoryProps) => {
const [isOpen, setIsOpen] = useState(true)
const onDialogClose = useCallback(() => setIsOpen(false), [])
return (
<>
<Button onClick={() => setIsOpen(!isOpen)}>Show dialog</Button>
{isOpen && (
<Dialog
title="My Dialog"
subtitle={subtitle ? 'This is a subtitle!' : undefined}
width={width}
height={height}
renderHeader={SxHeader}
renderBody={SxBody}
renderFooter={SxFooter}
onClose={onDialogClose}
footerButtons={[
{buttonType: 'danger', content: 'Delete the universe', onClick: onDialogClose},
{buttonType: 'primary', content: 'Proceed'},
]}
sx={{borderColor: 'accent.emphasis', borderWidth: '1px', borderStyle: 'solid', animation: 'none !important'}}
>
{lipsum}
</Dialog>
)}
</>
)
}

function SxAndCssHeader({
title,
subtitle,
dialogLabelId,
}: React.PropsWithChildren<DialogProps & {dialogLabelId: string}>) {
if (typeof title === 'string' && typeof subtitle === 'string') {
return (
<Dialog.Header sx={{color: 'accent.emphasis'}} className="testCustomClassnameColor">
<h1 id={dialogLabelId}>{title.toUpperCase()}</h1>
</Dialog.Header>
)
}
return null
}
function SxAndCssBody({children}: React.PropsWithChildren<DialogProps>) {
return (
<Dialog.Body sx={{color: 'danger.emphasis'}} className="testCustomClassnameColor">
{children}
</Dialog.Body>
)
}
function SxAndCssFooter({footerButtons}: React.PropsWithChildren<DialogProps>) {
return (
<Dialog.Footer sx={{fontFamily: 'Times New Roman'}} className="testCustomClassnameMono">
{footerButtons ? <Dialog.Buttons buttons={footerButtons} /> : null}
</Dialog.Footer>
)
}
export const WithSxAndCss = ({width, height, subtitle}: DialogStoryProps) => {
const [isOpen, setIsOpen] = useState(true)
const onDialogClose = useCallback(() => setIsOpen(false), [])
return (
<>
<Button onClick={() => setIsOpen(!isOpen)}>Show dialog</Button>
{isOpen && (
<Dialog
title="My Dialog"
subtitle={subtitle ? 'This is a subtitle!' : undefined}
width={width}
height={height}
renderHeader={SxAndCssHeader}
renderBody={SxAndCssBody}
renderFooter={SxAndCssFooter}
onClose={onDialogClose}
footerButtons={[
{buttonType: 'danger', content: 'Delete the universe', onClick: onDialogClose},
{buttonType: 'primary', content: 'Proceed'},
]}
sx={{borderColor: 'border.accent', borderWidth: '1px', borderStyle: 'solid', animation: 'none !important'}}
className="testCustomClassnameBorder"
>
{lipsum}
</Dialog>
)}
</>
)
}

export const WithScrollBody = () => {
const [isOpen, setIsOpen] = useState(false)
const buttonRef = useRef<HTMLButtonElement>(null)
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/Dialog/Dialog.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ function CustomHeader({
return null
}
function CustomBody({children}: React.PropsWithChildren<DialogProps>) {
return <Dialog.Body sx={{bg: 'danger.subtle'}}>{children}</Dialog.Body>
return <Dialog.Body style={{backgroundColor: 'var(--bgColor-danger-muted)'}}>{children}</Dialog.Body>
}
function CustomFooter({footerButtons}: React.PropsWithChildren<DialogProps>) {
return (
<Dialog.Footer sx={{bg: 'attention.subtle'}}>
<Dialog.Footer style={{backgroundColor: 'var(--bgColor-attention-muted)'}}>
{footerButtons ? <Dialog.Buttons buttons={footerButtons} /> : null}
</Dialog.Footer>
)
Expand Down
12 changes: 12 additions & 0 deletions packages/react/src/Dialog/Dialog.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,18 @@ Add a border between the body and footer if:
flex-shrink: 0;
}

.HeaderInner {
display: flex;
}

.HeaderContent {
display: flex;
padding-inline: var(--base-size-8);
padding-block: var(--base-size-6);
flex-direction: column;
flex-grow: 1;
}

.Title {
margin: 0; /* override default margin */
font-size: var(--text-body-size-medium);
Expand Down
55 changes: 24 additions & 31 deletions packages/react/src/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import React, {useCallback, useEffect, useRef, useState, type SyntheticEvent} from 'react'
import type {ButtonProps} from '../Button'
import {Button, IconButton} from '../Button'
import Box from '../Box'
import {useOnEscapePress, useProvidedRefOrCreate} from '../hooks'
import {useFocusTrap} from '../hooks/useFocusTrap'
import type {SxProp} from '../sx'
import {XIcon} from '@primer/octicons-react'
import {useFocusZone} from '../hooks/useFocusZone'
import {FocusKeys} from '@primer/behaviors'
Expand All @@ -17,7 +15,6 @@ import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../uti

import classes from './Dialog.module.css'
import {clsx} from 'clsx'
import {BoxWithFallback} from '../internal/components/BoxWithFallback'

/* Dialog Version 2 */

Expand Down Expand Up @@ -52,7 +49,7 @@ export type DialogButtonProps = Omit<ButtonProps, 'content'> & {
/**
* Props to customize the rendering of the Dialog.
*/
export interface DialogProps extends SxProp {
export interface DialogProps {
/**
* Title of the Dialog. Also serves as the aria-label for this Dialog.
*/
Expand Down Expand Up @@ -198,13 +195,13 @@ const DefaultHeader: React.FC<React.PropsWithChildren<DialogHeaderProps>> = ({
}, [onClose])
return (
<Dialog.Header>
<Box display="flex">
<Box display="flex" px={2} py="6px" flexDirection="column" flexGrow={1}>
<div className={classes.HeaderInner}>
<div className={classes.HeaderContent}>
<Dialog.Title id={dialogLabelId}>{title ?? 'Dialog'}</Dialog.Title>
{subtitle && <Dialog.Subtitle id={dialogDescriptionId}>{subtitle}</Dialog.Subtitle>}
</Box>
</div>
<Dialog.CloseButton onClose={onCloseClick} />
</Box>
</div>
</Dialog.Header>
)
}
Expand Down Expand Up @@ -245,7 +242,6 @@ const _Dialog = React.forwardRef<HTMLDivElement, React.PropsWithChildren<DialogP
position = defaultPosition,
returnFocusRef,
initialFocusRef,
sx,
className,
} = props
const dialogLabelId = useId()
Expand Down Expand Up @@ -311,8 +307,7 @@ const _Dialog = React.forwardRef<HTMLDivElement, React.PropsWithChildren<DialogP
return (
<>
<Portal>
<BoxWithFallback
as="div"
<div
ref={backdropRef}
className={classes.Backdrop}
{...positionDataAttributes}
Expand All @@ -321,8 +316,7 @@ const _Dialog = React.forwardRef<HTMLDivElement, React.PropsWithChildren<DialogP
setLastMouseDownIsBackdrop(e.target === e.currentTarget)
}}
>
<BoxWithFallback
as="div"
<div
ref={dialogRef}
role={role}
aria-labelledby={dialogLabelId}
Expand All @@ -331,58 +325,57 @@ const _Dialog = React.forwardRef<HTMLDivElement, React.PropsWithChildren<DialogP
{...positionDataAttributes}
data-width={width}
data-height={height}
sx={sx}
className={clsx(className, classes.Dialog)}
>
{header}
<ScrollableRegion aria-labelledby={dialogLabelId} className={classes.DialogOverflowWrapper}>
{body}
</ScrollableRegion>
{footer}
</BoxWithFallback>
</BoxWithFallback>
</div>
</div>
</Portal>
</>
)
})
_Dialog.displayName = 'Dialog'

type StyledHeaderProps = React.ComponentProps<'div'> & SxProp
type StyledHeaderProps = React.ComponentProps<'div'>

const Header = React.forwardRef<HTMLElement, StyledHeaderProps>(function Header({className, ...rest}, forwardRef) {
return <BoxWithFallback as="div" ref={forwardRef} className={clsx(className, classes.Header)} {...rest} />
const Header = React.forwardRef<HTMLDivElement, StyledHeaderProps>(function Header({className, ...rest}, forwardRef) {
return <div ref={forwardRef} className={clsx(className, classes.Header)} {...rest} />
})
Header.displayName = 'Dialog.Header'

type StyledTitleProps = React.ComponentProps<'h1'> & SxProp
type StyledTitleProps = React.ComponentProps<'h1'>

const Title = React.forwardRef<HTMLElement, StyledTitleProps>(function Title({className, ...rest}, forwardRef) {
return <BoxWithFallback as="h1" ref={forwardRef} className={clsx(className, classes.Title)} {...rest} />
const Title = React.forwardRef<HTMLHeadingElement, StyledTitleProps>(function Title({className, ...rest}, forwardRef) {
return <h1 ref={forwardRef} className={clsx(className, classes.Title)} {...rest} />
})
Title.displayName = 'Dialog.Title'

type StyledSubtitleProps = React.ComponentProps<'h2'> & SxProp
type StyledSubtitleProps = React.ComponentProps<'h2'>

const Subtitle = React.forwardRef<HTMLElement, StyledSubtitleProps>(function Subtitle(
const Subtitle = React.forwardRef<HTMLHeadingElement, StyledSubtitleProps>(function Subtitle(
{className, ...rest},
forwardRef,
) {
return <BoxWithFallback as="h2" ref={forwardRef} className={clsx(className, classes.Subtitle)} {...rest} />
return <h2 ref={forwardRef} className={clsx(className, classes.Subtitle)} {...rest} />
})
Subtitle.displayName = 'Dialog.Subtitle'

type StyledBodyProps = React.ComponentProps<'div'> & SxProp
type StyledBodyProps = React.ComponentProps<'div'>

const Body = React.forwardRef<HTMLElement, StyledBodyProps>(function Body({className, ...rest}, forwardRef) {
return <BoxWithFallback as="div" ref={forwardRef} className={clsx(className, classes.Body)} {...rest} />
const Body = React.forwardRef<HTMLDivElement, StyledBodyProps>(function Body({className, ...rest}, forwardRef) {
return <div ref={forwardRef} className={clsx(className, classes.Body)} {...rest} />
}) as PolymorphicForwardRefComponent<'div', StyledBodyProps>

Body.displayName = 'Dialog.Body'

type StyledFooterProps = React.ComponentProps<'div'> & SxProp
type StyledFooterProps = React.ComponentProps<'div'>

const Footer = React.forwardRef<HTMLElement, StyledFooterProps>(function Footer({className, ...rest}, forwardRef) {
return <BoxWithFallback as="div" ref={forwardRef} className={clsx(className, classes.Footer)} {...rest} />
const Footer = React.forwardRef<HTMLDivElement, StyledFooterProps>(function Footer({className, ...rest}, forwardRef) {
return <div ref={forwardRef} className={clsx(className, classes.Footer)} {...rest} />
})
Footer.displayName = 'Dialog.Footer'

Expand Down
2 changes: 1 addition & 1 deletion packages/styled-react/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default defineConfig({
tsconfig: 'tsconfig.build.json',
}),
babel({
presets: ['@babel/preset-typescript', '@babel/preset-react'],
presets: ['@babel/preset-typescript', ['@babel/preset-react', {runtime: 'automatic'}]],
extensions: ['.ts', '.tsx'],
babelHelpers: 'bundled',
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,33 @@ describe('@primer/react', () => {
expect(window.getComputedStyle(screen.getByRole('dialog')).backgroundColor).toBe('rgb(255, 0, 0)')
})

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

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

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

test('Flash supports `sx` prop', () => {
render(<Flash data-testid="component" sx={{background: 'red'}} />)
expect(window.getComputedStyle(screen.getByTestId('component')).backgroundColor).toBe('rgb(255, 0, 0)')
Expand Down
1 change: 1 addition & 0 deletions packages/styled-react/src/components/Box.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {Box, type BoxProps} from '@primer/react'
Loading
Loading