diff --git a/.changeset/spotty-colts-hear.md b/.changeset/spotty-colts-hear.md new file mode 100644 index 00000000000..bbf482df079 --- /dev/null +++ b/.changeset/spotty-colts-hear.md @@ -0,0 +1,5 @@ +--- +'@primer/react': major +--- + +Remove the `sx` prop from `Announce`, `AriaAlert`, and `AriaStatus` diff --git a/packages/react/src/live-region/Announce.tsx b/packages/react/src/live-region/Announce.tsx index a0c56271544..15d697bb690 100644 --- a/packages/react/src/live-region/Announce.tsx +++ b/packages/react/src/live-region/Announce.tsx @@ -1,50 +1,56 @@ import {announceFromElement} from '@primer/live-region-element' import type React from 'react' import {useEffect, useRef, useState, type ElementRef} from 'react' -import Box from '../Box' import {useEffectOnce} from '../internal/hooks/useEffectOnce' import {useEffectCallback} from '../internal/hooks/useEffectCallback' - -export type AnnounceProps = React.ComponentPropsWithoutRef & { - /** - * Specify if the content of the element should be announced when this - * component is rendered and is not hidden - * @default false - */ - announceOnShow?: boolean - - /** - * Specify if the element is hidden - * @default false - */ - hidden?: boolean - - /** - * Provide a delay in milliseconds before the announcement is made. This will - * only work with `polite` announcements - */ - delayMs?: number - - /** - * The politeness level to use for the announcement - * @default 'polite' - */ - politeness?: 'assertive' | 'polite' -} +import type {PolymorphicProps} from '../utils/polymorphic2' + +export type AnnounceProps = PolymorphicProps< + 'div', + As, + { + /** + * Specify if the content of the element should be announced when this + * component is rendered and is not hidden + * @default false + */ + announceOnShow?: boolean + + /** + * Specify if the element is hidden + * @default false + */ + hidden?: boolean + + /** + * Provide a delay in milliseconds before the announcement is made. This will + * only work with `polite` announcements + */ + delayMs?: number + + /** + * The politeness level to use for the announcement + * @default 'polite' + */ + politeness?: 'assertive' | 'polite' + } +> /** * `Announce` is a component that will announce the text content of the * `children` passed in to screen readers using the given politeness level. It * will also announce any changes to the text content of `children` */ -export function Announce({ - announceOnShow = true, - children, - delayMs, - hidden = false, - politeness = 'polite', - ...rest -}: AnnounceProps) { +export function Announce(props: AnnounceProps) { + const { + as: BaseComponent = 'div', + announceOnShow = true, + children, + delayMs, + hidden = false, + politeness = 'polite', + ...rest + } = props const ref = useRef>(null) const [previousAnnouncementText, setPreviousAnnouncementText] = useState(null) const savedAnnouncement = useRef | null>(null) @@ -127,9 +133,9 @@ export function Announce({ }, []) return ( - + {children} - + ) } diff --git a/packages/react/src/live-region/AriaAlert.tsx b/packages/react/src/live-region/AriaAlert.tsx index a961180521d..7f9e48fa47f 100644 --- a/packages/react/src/live-region/AriaAlert.tsx +++ b/packages/react/src/live-region/AriaAlert.tsx @@ -1,15 +1,12 @@ import type React from 'react' import {type ElementType} from 'react' import {Announce} from './Announce' -import type {SxProp} from '../sx' +import type {PolymorphicProps} from '../utils/polymorphic2' -export type AriaAlertProps = React.PropsWithChildren< +export type AriaAlertProps = PolymorphicProps< + 'div', + As, { - /** - * Customize the element type of the rendered container - */ - as?: As - /** * Specify if the content of the element should be announced when this * component is rendered and is not hidden @@ -22,14 +19,14 @@ export type AriaAlertProps = React.PropsWithChildren< * @default false */ hidden?: boolean - } & SxProp + } > -export function AriaAlert({ +export function AriaAlert({ announceOnShow = true, children, ...rest -}: AriaAlertProps & React.ComponentPropsWithoutRef) { +}: AriaAlertProps) { return ( {children} diff --git a/packages/react/src/live-region/AriaStatus.tsx b/packages/react/src/live-region/AriaStatus.tsx index fa1f90df28c..a9a4ff13aac 100644 --- a/packages/react/src/live-region/AriaStatus.tsx +++ b/packages/react/src/live-region/AriaStatus.tsx @@ -1,15 +1,12 @@ import type React from 'react' import {type ElementType} from 'react' import {Announce} from './Announce' -import type {SxProp} from '../sx' +import type {PolymorphicProps} from '../utils/polymorphic2' -export type AriaStatusProps = React.PropsWithChildren< +export type AriaStatusProps = PolymorphicProps< + 'div', + As, { - /** - * Customize the element type of the rendered container - */ - as?: As - /** * Specify if the content of the element should be announced when this * component is rendered and is not hidden @@ -27,14 +24,14 @@ export type AriaStatusProps = React.PropsWithChildren< * Provide a delay in milliseconds before the announcement is made */ delayMs?: number - } & SxProp + } > -export function AriaStatus({ +export function AriaStatus({ announceOnShow = false, children, ...rest -}: AriaStatusProps & React.ComponentPropsWithoutRef) { +}: AriaStatusProps) { return ( {children} diff --git a/packages/react/src/live-region/__tests__/Announce.test.tsx b/packages/react/src/live-region/__tests__/Announce.test.tsx index d96ab799508..2940b5a7888 100644 --- a/packages/react/src/live-region/__tests__/Announce.test.tsx +++ b/packages/react/src/live-region/__tests__/Announce.test.tsx @@ -37,15 +37,6 @@ describe('Announce', () => { expect(container.firstChild).toHaveAttribute('data-testid', 'container') }) - it('should support styling via the `sx` prop', () => { - render( - - test - , - ) - expect(screen.getByTestId('container')).toHaveStyle('color: rgb(0, 0, 255)') - }) - it('should support customizing the container element with `as`', () => { render( diff --git a/packages/react/src/live-region/__tests__/AriaAlert.test.tsx b/packages/react/src/live-region/__tests__/AriaAlert.test.tsx index 44f7a216efb..3ea2d2548b1 100644 --- a/packages/react/src/live-region/__tests__/AriaAlert.test.tsx +++ b/packages/react/src/live-region/__tests__/AriaAlert.test.tsx @@ -31,15 +31,6 @@ describe('AriaAlert', () => { expect(container.firstChild).toHaveAttribute('data-testid', 'container') }) - it('should support styling via the `sx` prop', () => { - render( - - test - , - ) - expect(screen.getByTestId('container')).toHaveStyle('color: rgb(0, 0, 255)') - }) - it('should support customizing the container element with `as`', () => { render( diff --git a/packages/react/src/live-region/__tests__/AriaStatus.test.tsx b/packages/react/src/live-region/__tests__/AriaStatus.test.tsx index ad7290ea8d5..0e7380b6798 100644 --- a/packages/react/src/live-region/__tests__/AriaStatus.test.tsx +++ b/packages/react/src/live-region/__tests__/AriaStatus.test.tsx @@ -67,15 +67,6 @@ describe('AriaStatus', () => { expect(container.firstChild).toHaveAttribute('data-testid', 'container') }) - it('should support styling via the `sx` prop', () => { - render( - - test - , - ) - expect(screen.getByTestId('container')).toHaveStyle('color: rgb(0, 0, 255)') - }) - it('should support customizing the container element with `as`', () => { render( diff --git a/packages/react/src/utils/polymorphic2.ts b/packages/react/src/utils/polymorphic2.ts new file mode 100644 index 00000000000..b48264baa27 --- /dev/null +++ b/packages/react/src/utils/polymorphic2.ts @@ -0,0 +1,23 @@ +/** + * This file is an alternative to polymorphic.ts that hopes to support + * polyrmophic components in React. It explicitly hopes to make it easy to + * type the props of components and allow for explicitly setting the type of a + * component + */ + +import type {ElementType} from 'react' + +type AsProp = { + /** + * Customize the element type of the container element for the component + */ + as?: As +} + +type PolymorphicProps = Props & + AsProp & + (As extends React.ElementType + ? Omit, keyof Props> + : Omit, keyof Props>) + +export type {PolymorphicProps}