From 4efa91663014fab6742688d1d76ae059bdb83d11 Mon Sep 17 00:00:00 2001 From: Jon Rohan Date: Thu, 3 Jul 2025 02:31:10 +0000 Subject: [PATCH 1/4] Refactor components to use BoxWithFallback and remove defaultSxProp references - Updated CircleBadge snapshots to reflect class name changes. - Refactored CounterLabel to use BoxWithFallback and removed defaultSxProp. - Modified DataTable's TableContainer to utilize BoxWithFallback. - Changed Details component to use BoxWithFallback instead of Box. - Updated FormControl to replace Box with BoxWithFallback. - Refactored Header, InlineMessage, Pagehead, Radio, SegmentedControl, and SubNav components to use BoxWithFallback. - Simplified Spinner component by using BoxWithFallback. - Updated Timeline components to utilize BoxWithFallback for consistency. - Removed defaultSxProp references across various components for cleaner code. --- packages/react/src/ActionList/Description.tsx | 3 +- packages/react/src/ActionList/Divider.tsx | 3 +- packages/react/src/ActionList/Group.tsx | 8 +- packages/react/src/ActionList/Item.tsx | 3 +- packages/react/src/ActionList/LinkItem.tsx | 3 +- packages/react/src/ActionList/List.tsx | 13 +-- packages/react/src/ActionList/Visuals.tsx | 25 ++---- packages/react/src/Avatar/Avatar.tsx | 3 +- .../react/src/AvatarStack/AvatarStack.tsx | 11 +-- .../react/src/ButtonGroup/ButtonGroup.tsx | 17 +--- .../__snapshots__/CircleBadge.test.tsx.snap | 6 +- .../react/src/CounterLabel/CounterLabel.tsx | 19 +--- packages/react/src/DataTable/Table.tsx | 5 +- packages/react/src/Details/Details.tsx | 27 +----- .../react/src/FormControl/FormControl.tsx | 33 +++---- packages/react/src/Header/Header.tsx | 49 +++-------- .../react/src/InlineMessage/InlineMessage.tsx | 35 ++------ packages/react/src/PageLayout/PageLayout.tsx | 15 ++-- packages/react/src/Pagehead/Pagehead.tsx | 10 +-- packages/react/src/Radio/Radio.tsx | 28 +----- .../src/SegmentedControl/SegmentedControl.tsx | 3 +- .../SegmentedControlButton.tsx | 3 +- .../SegmentedControlIconButton.tsx | 3 +- packages/react/src/SideNav.tsx | 3 +- packages/react/src/Spinner/Spinner.tsx | 16 +--- packages/react/src/SubNav/SubNav.tsx | 66 ++++---------- packages/react/src/Timeline/Timeline.tsx | 87 +++++-------------- packages/react/src/Token/Token.tsx | 3 - .../src/VisuallyHidden/VisuallyHidden.tsx | 17 +--- .../UnderlinePanels/UnderlinePanels.tsx | 11 +-- .../components/UnderlineTabbedInterface.tsx | 49 +---------- 31 files changed, 132 insertions(+), 445 deletions(-) diff --git a/packages/react/src/ActionList/Description.tsx b/packages/react/src/ActionList/Description.tsx index d11cf1da9c5..2db37e74ac7 100644 --- a/packages/react/src/ActionList/Description.tsx +++ b/packages/react/src/ActionList/Description.tsx @@ -3,7 +3,6 @@ import Truncate from '../Truncate' import type {SxProp} from '../sx' import {ItemContext} from './shared' import classes from './ActionList.module.css' -import {defaultSxProp} from '../utils/defaultSxProp' import {BoxWithFallback} from '../internal/components/BoxWithFallback' import {clsx} from 'clsx' @@ -25,7 +24,7 @@ export type ActionListDescriptionProps = { export const Description: React.FC> = ({ variant = 'inline', - sx = defaultSxProp, + sx, className, truncate, ...props diff --git a/packages/react/src/ActionList/Divider.tsx b/packages/react/src/ActionList/Divider.tsx index 37f839d9301..5caa365a49c 100644 --- a/packages/react/src/ActionList/Divider.tsx +++ b/packages/react/src/ActionList/Divider.tsx @@ -2,7 +2,6 @@ import type React from 'react' import type {SxProp} from '../sx' import {clsx} from 'clsx' import classes from './ActionList.module.css' -import {defaultSxProp} from '../utils/defaultSxProp' import {BoxWithFallback} from '../internal/components/BoxWithFallback' export type ActionListDividerProps = SxProp & { @@ -12,7 +11,7 @@ export type ActionListDividerProps = SxProp & { /** * Visually separates `Item`s or `Group`s in an `ActionList`. */ -export const Divider: React.FC> = ({sx = defaultSxProp, className}) => { +export const Divider: React.FC> = ({sx, className}) => { return ( > as: Component = 'h3', className, children, - sx = defaultSxProp, id, ...rest }) => { return ( // Box is temporary to support lingering sx usage - + {children} ) @@ -81,7 +79,6 @@ export const Group: React.FC> = ({ role, className, 'aria-label': ariaLabel, - sx = defaultSxProp, ...props }) => { const id = useId() @@ -108,7 +105,6 @@ export const Group: React.FC> = ({ as="li" className={clsx(className, groupClasses.Group)} role={listRole ? 'none' : undefined} - sx={sx} {...props} > @@ -160,7 +156,7 @@ export const GroupHeading: React.FC { diff --git a/packages/react/src/ActionList/Item.tsx b/packages/react/src/ActionList/Item.tsx index 390f9a6c53c..66cb93a4bf6 100644 --- a/packages/react/src/ActionList/Item.tsx +++ b/packages/react/src/ActionList/Item.tsx @@ -2,7 +2,6 @@ import React from 'react' import {useId} from '../hooks/useId' import {useSlots} from '../hooks/useSlots' -import {defaultSxProp} from '../utils/defaultSxProp' import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic' import {ActionListContainerContext} from './ActionListContainerContext' import {Description} from './Description' @@ -54,7 +53,7 @@ export const Item = React.forwardRef( selected = undefined, active = false, onSelect: onSelectUser, - sx: sxProp = defaultSxProp, + sx: sxProp, id, role, loading, diff --git a/packages/react/src/ActionList/LinkItem.tsx b/packages/react/src/ActionList/LinkItem.tsx index 8f1b291e73b..ab53052afec 100644 --- a/packages/react/src/ActionList/LinkItem.tsx +++ b/packages/react/src/ActionList/LinkItem.tsx @@ -3,7 +3,6 @@ import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../uti import Link from '../Link' import {Item} from './Item' import type {ActionListItemProps} from './shared' -import {defaultSxProp} from '../utils/defaultSxProp' // adopted from React.AnchorHTMLAttributes type LinkProps = { @@ -27,7 +26,7 @@ export type ActionListLinkItemProps = Pick< LinkProps export const LinkItem = React.forwardRef( - ({sx = defaultSxProp, active, inactiveText, variant, as: Component, className, ...props}, forwardedRef) => { + ({sx, active, inactiveText, variant, as: Component, className, ...props}, forwardedRef) => { return ( ( ( - { - variant = 'inset', - selectionVariant, - showDividers = false, - role, - sx: sxProp = defaultSxProp, - disableFocusZone = false, - className, - ...props - }, + {variant = 'inset', selectionVariant, showDividers = false, role, disableFocusZone = false, className, ...props}, forwardedRef, ): JSX.Element => { const [slots, childrenWithoutSlots] = useSlots(props.children, { @@ -68,7 +58,6 @@ export const List = React.forwardRef( {slots.heading} -export const VisualContainer: React.FC> = ({ - sx = defaultSxProp, - className, - ...props -}) => { - return +export const VisualContainer: React.FC> = ({className, ...props}) => { + return } export type ActionListLeadingVisualProps = VisualProps -export const LeadingVisual: React.FC> = ({ - sx = defaultSxProp, - className, - ...props -}) => { +export const LeadingVisual: React.FC> = ({className, ...props}) => { return ( - + {props.children} ) } export type ActionListTrailingVisualProps = VisualProps -export const TrailingVisual: React.FC> = ({ - sx = defaultSxProp, - className, - ...props -}) => { +export const TrailingVisual: React.FC> = ({className, ...props}) => { const {trailingVisualId} = React.useContext(ItemContext) return ( - + {props.children} ) diff --git a/packages/react/src/Avatar/Avatar.tsx b/packages/react/src/Avatar/Avatar.tsx index 5adbeea57c0..a580ef72b71 100644 --- a/packages/react/src/Avatar/Avatar.tsx +++ b/packages/react/src/Avatar/Avatar.tsx @@ -3,7 +3,6 @@ import React from 'react' import type {SxProp} from '../sx' import type {ResponsiveValue} from '../hooks/useResponsiveValue' import {isResponsiveValue} from '../hooks/useResponsiveValue' -import {defaultSxProp} from '../utils/defaultSxProp' import {BoxWithFallback} from '../internal/components/BoxWithFallback' import classes from './Avatar.module.css' @@ -24,7 +23,7 @@ export type AvatarProps = { React.ComponentPropsWithoutRef<'img'> const Avatar = React.forwardRef(function Avatar( - {alt = '', size = DEFAULT_AVATAR_SIZE, square = false, sx: sxProp = defaultSxProp, className, style, ...rest}, + {alt = '', size = DEFAULT_AVATAR_SIZE, square = false, sx: sxProp, className, style, ...rest}, ref, ) { const isResponsive = isResponsiveValue(size) diff --git a/packages/react/src/AvatarStack/AvatarStack.tsx b/packages/react/src/AvatarStack/AvatarStack.tsx index 27def7bbb70..dadb3a9b6b7 100644 --- a/packages/react/src/AvatarStack/AvatarStack.tsx +++ b/packages/react/src/AvatarStack/AvatarStack.tsx @@ -5,7 +5,6 @@ import type {AvatarProps} from '../Avatar/Avatar' import {DEFAULT_AVATAR_SIZE} from '../Avatar/Avatar' import type {ResponsiveValue} from '../hooks/useResponsiveValue' import {isResponsiveValue} from '../hooks/useResponsiveValue' -import {defaultSxProp} from '../utils/defaultSxProp' import type {WidthOnlyViewportRangeKeys} from '../utils/types/ViewportRangeKeys' import classes from './AvatarStack.module.css' import {hasInteractiveNodes} from '../internal/utils/hasInteractiveNodes' @@ -58,15 +57,7 @@ const AvatarStackBody = ({ ) } -const AvatarStack = ({ - children, - alignRight, - disableExpand, - size, - className, - style, - sx: sxProp = defaultSxProp, -}: AvatarStackProps) => { +const AvatarStack = ({children, alignRight, disableExpand, size, className, style, sx: sxProp}: AvatarStackProps) => { const [hasInteractiveChildren, setHasInteractiveChildren] = useState(false) const stackContainer = useRef(null) diff --git a/packages/react/src/ButtonGroup/ButtonGroup.tsx b/packages/react/src/ButtonGroup/ButtonGroup.tsx index 0869e1e1b92..3793d15df52 100644 --- a/packages/react/src/ButtonGroup/ButtonGroup.tsx +++ b/packages/react/src/ButtonGroup/ButtonGroup.tsx @@ -5,8 +5,7 @@ import {clsx} from 'clsx' import {FocusKeys, useFocusZone} from '../hooks/useFocusZone' import {useProvidedRefOrCreate} from '../hooks' import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic' -import Box from '../Box' -import {defaultSxProp} from '../utils/defaultSxProp' +import {BoxWithFallback} from '../internal/components/BoxWithFallback' export type ButtonGroupProps = { /** The role of the group */ @@ -17,7 +16,7 @@ export type ButtonGroupProps = { SxProp const ButtonGroup = React.forwardRef(function ButtonGroup( - {children, className, role, sx, ...rest}, + {children, className, role, ...rest}, forwardRef, ) { const buttons = React.Children.map(children, (child, index) =>
{child}
) @@ -30,18 +29,10 @@ const ButtonGroup = React.forwardRef(function But focusOutBehavior: 'wrap', }) - if (sx !== defaultSxProp) { - return ( - - {buttons} - - ) - } - return ( -
+ {buttons} -
+
) }) as PolymorphicForwardRefComponent<'div', ButtonGroupProps> diff --git a/packages/react/src/CircleBadge/__snapshots__/CircleBadge.test.tsx.snap b/packages/react/src/CircleBadge/__snapshots__/CircleBadge.test.tsx.snap index e1a65fbd2eb..6887bc05d06 100644 --- a/packages/react/src/CircleBadge/__snapshots__/CircleBadge.test.tsx.snap +++ b/packages/react/src/CircleBadge/__snapshots__/CircleBadge.test.tsx.snap @@ -2,19 +2,19 @@ exports[`CircleBadge > respects the inline prop 1`] = `
`; exports[`CircleBadge > respects the variant prop 1`] = `
`; exports[`CircleBadge > uses the size prop to override the variant prop 1`] = `
`; diff --git a/packages/react/src/CounterLabel/CounterLabel.tsx b/packages/react/src/CounterLabel/CounterLabel.tsx index 8dbf46ebcda..fd47aa3c0f8 100644 --- a/packages/react/src/CounterLabel/CounterLabel.tsx +++ b/packages/react/src/CounterLabel/CounterLabel.tsx @@ -4,9 +4,8 @@ import type React from 'react' import {forwardRef} from 'react' import type {SxProp} from '../sx' import {VisuallyHidden} from '../VisuallyHidden' -import {defaultSxProp} from '../utils/defaultSxProp' -import Box from '../Box' import classes from './CounterLabel.module.css' +import {BoxWithFallback} from '../internal/components/BoxWithFallback' export type CounterLabelProps = React.PropsWithChildren< HTMLAttributes & { @@ -16,7 +15,7 @@ export type CounterLabelProps = React.PropsWithChildren< > const CounterLabel = forwardRef( - ({scheme = 'secondary', sx = defaultSxProp, className, children, ...rest}, forwardedRef) => { + ({scheme = 'secondary', className, children, ...rest}, forwardedRef) => { const label =  ({children}) const counterProps = { ref: forwardedRef, @@ -25,21 +24,11 @@ const CounterLabel = forwardRef( ...rest, } - if (sx !== defaultSxProp) { - return ( - <> - - {children} - - {label} - - ) - } return ( <> - + {children} - + {label} ) diff --git a/packages/react/src/DataTable/Table.tsx b/packages/react/src/DataTable/Table.tsx index 3ee8249f3e3..7ed6ae88cf9 100644 --- a/packages/react/src/DataTable/Table.tsx +++ b/packages/react/src/DataTable/Table.tsx @@ -12,7 +12,6 @@ import {SkeletonText} from '../experimental/Skeleton/SkeletonText' import {ScrollableRegion} from '../ScrollableRegion' import {Button} from '../internal/components/ButtonReset' import classes from './Table.module.css' -import {defaultSxProp} from '../utils/defaultSxProp' import {BoxWithFallback} from '../internal/components/BoxWithFallback' // ---------------------------------------------------------------------------- @@ -236,9 +235,9 @@ function TableCellPlaceholder({children}: TableCellPlaceholderProps) { // ---------------------------------------------------------------------------- export type TableContainerProps = React.PropsWithChildren> -function TableContainer({children, className, sx: sxProp = defaultSxProp, ...rest}: TableContainerProps) { +function TableContainer({children, className, ...rest}: TableContainerProps) { return ( - + {children} ) diff --git a/packages/react/src/Details/Details.tsx b/packages/react/src/Details/Details.tsx index 4a001484b8e..88b293cac94 100644 --- a/packages/react/src/Details/Details.tsx +++ b/packages/react/src/Details/Details.tsx @@ -3,11 +3,10 @@ import type {SxProp} from '../sx' import {clsx} from 'clsx' import classes from './Details.module.css' import {useMergedRefs} from '../internal/hooks/useMergedRefs' -import {defaultSxProp} from '../utils/defaultSxProp' -import Box from '../Box' +import {BoxWithFallback} from '../internal/components/BoxWithFallback' const Root = React.forwardRef( - ({className, children, sx: sxProp = defaultSxProp, ...rest}, forwardRef): ReactElement => { + ({className, children, ...rest}, forwardRef): ReactElement => { const detailsRef = React.useRef(null) const ref = useMergedRefs(forwardRef, detailsRef) const [hasSummary, setHasSummary] = useState(false) @@ -40,36 +39,18 @@ const Root = React.forwardRef( } }, []) - if (sxProp !== defaultSxProp) { - return ( - - {/* Include default summary if summary is not provided */} - {!hasSummary && {'See Details'}} - {children} - - ) - } - return ( -
+ {/* Include default summary if summary is not provided */} {!hasSummary && {'See Details'}} {children} -
+
) }, ) Root.displayName = 'Details' -export type SummaryProps = { - /** - * HTML element to render summary as. - */ - as?: As - children?: React.ReactNode -} & React.ComponentPropsWithoutRef - function Summary({as, children, ...props}: SummaryProps) { const Component = as ?? 'summary' return ( diff --git a/packages/react/src/FormControl/FormControl.tsx b/packages/react/src/FormControl/FormControl.tsx index 91d6b9dc0e5..93c7d96eae7 100644 --- a/packages/react/src/FormControl/FormControl.tsx +++ b/packages/react/src/FormControl/FormControl.tsx @@ -8,7 +8,6 @@ import {SelectPanel} from '../SelectPanel' import TextInput from '../TextInput' import TextInputWithTokens from '../TextInputWithTokens' import Textarea from '../Textarea' -import Box from '../Box' import {CheckboxOrRadioGroupContext} from '../internal/components/CheckboxOrRadioGroup' import ValidationAnimationContainer from '../internal/components/ValidationAnimationContainer' import {useSlots} from '../hooks/useSlots' @@ -21,7 +20,7 @@ import FormControlValidation from './_FormControlValidation' import {FormControlContextProvider} from './_FormControlContext' import {warning} from '../utils/warning' import classes from './FormControl.module.css' -import {defaultSxProp} from '../utils/defaultSxProp' +import {BoxWithFallback} from '../internal/components/BoxWithFallback' export type FormControlProps = { children?: React.ReactNode @@ -169,26 +168,16 @@ const FormControl = React.forwardRef( }} > {isChoiceInput || layout === 'horizontal' ? ( - sx !== defaultSxProp ? ( - - {InputChildren} - - ) : ( -
- {InputChildren} -
- ) + + {InputChildren} + ) : ( - ( {slots.validation} ) : null} {slots.caption} - + )} ) diff --git a/packages/react/src/Header/Header.tsx b/packages/react/src/Header/Header.tsx index 0d5c2c6efc8..4b03a14d4bd 100644 --- a/packages/react/src/Header/Header.tsx +++ b/packages/react/src/Header/Header.tsx @@ -4,75 +4,46 @@ import React from 'react' import {clsx} from 'clsx' import classes from './Header.module.css' import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic' -import {defaultSxProp} from '../utils/defaultSxProp' -import Box from '../Box' +import {BoxWithFallback} from '../internal/components/BoxWithFallback' export type HeaderProps = React.ComponentProps<'header'> & SxProp & {as?: React.ElementType} export type HeaderItemProps = React.ComponentProps<'div'> & SxProp & {full?: boolean} export type HeaderLinkProps = React.ComponentProps<'a'> & SxProp & {to?: Location | Pathname; as?: React.ElementType} const Header = React.forwardRef(function Header( - {children, className, sx: sxProp = defaultSxProp, as = 'header', ...rest}, + {children, className, as = 'header', ...rest}, forwardRef, ) { - if (sxProp !== defaultSxProp || as !== 'header') { - return ( - - {children} - - ) - } return ( -
+ {children} -
+ ) }) as PolymorphicForwardRefComponent<'header', HeaderProps> Header.displayName = 'Header' const HeaderItem = React.forwardRef(function HeaderItem( - {children, className, sx: sxProp = defaultSxProp, full, ...rest}, + {children, className, full, ...rest}, forwardRef, ) { - if (sxProp !== defaultSxProp) { - return ( - - {children} - - ) - } return ( -
+ {children} -
+ ) }) HeaderItem.displayName = 'Header.Item' const HeaderLink = React.forwardRef(function HeaderLink( - {children, className, sx: sxProp = defaultSxProp, as = 'a', ...rest}, + {children, className, as = 'a', ...rest}, forwardRef, ) { - if (sxProp !== defaultSxProp || as !== 'a') { - return ( - - {children} - - ) - } return ( - + {children} - + ) }) diff --git a/packages/react/src/InlineMessage/InlineMessage.tsx b/packages/react/src/InlineMessage/InlineMessage.tsx index c3becd4c410..d016792546a 100644 --- a/packages/react/src/InlineMessage/InlineMessage.tsx +++ b/packages/react/src/InlineMessage/InlineMessage.tsx @@ -3,8 +3,7 @@ import {clsx} from 'clsx' import type React from 'react' import classes from './InlineMessage.module.css' import type {SxProp} from '../sx' -import {defaultSxProp} from '../utils/defaultSxProp' -import Box from '../Box' +import {BoxWithFallback} from '../internal/components/BoxWithFallback' type MessageVariant = 'critical' | 'success' | 'unavailable' | 'warning' export type InlineMessageProps = React.ComponentPropsWithoutRef<'div'> & @@ -41,34 +40,18 @@ const variantToSmallIcon = (variant: MessageVariant): React.ReactNode => { return icons[variant] } -export function InlineMessage({ - children, - className, - size = 'medium', - variant, - sx: sxProp = defaultSxProp, - ...rest -}: InlineMessageProps) { +export function InlineMessage({children, className, size = 'medium', variant, ...rest}: InlineMessageProps) { const icon = size === 'small' ? variantToSmallIcon(variant) : variantToIcon(variant) - if (sxProp !== defaultSxProp) { - return ( - - {icon} - {children} - - ) - } return ( -
+ {icon} {children} -
+ ) } diff --git a/packages/react/src/PageLayout/PageLayout.tsx b/packages/react/src/PageLayout/PageLayout.tsx index a81051854bf..1db19d71951 100644 --- a/packages/react/src/PageLayout/PageLayout.tsx +++ b/packages/react/src/PageLayout/PageLayout.tsx @@ -13,7 +13,6 @@ import {warning} from '../utils/warning' import classes from './PageLayout.module.css' import {BoxWithFallback} from '../internal/components/BoxWithFallback' -import {defaultSxProp} from '../utils/defaultSxProp' const REGION_ORDER = { header: 0, @@ -74,7 +73,7 @@ const Root: React.FC> = ({ rowGap = 'normal', columnGap = 'normal', children, - sx = defaultSxProp, + sx, className, style, _slotsConfig: slotsConfig, @@ -128,7 +127,7 @@ type DividerProps = { const HorizontalDivider: React.FC> = ({ variant = 'none', - sx = defaultSxProp, + sx, className, position, style, @@ -170,7 +169,7 @@ const VerticalDivider: React.FC { const [isDragging, setIsDragging] = React.useState(false) const [isKeyboardDrag, setIsKeyboardDrag] = React.useState(false) @@ -367,7 +366,7 @@ const Header: React.FC> = ({ hidden = false, children, style, - sx = defaultSxProp, + sx, className, }) => { // Combine divider and dividerWhenNarrow for backwards compatibility @@ -463,7 +462,7 @@ const Content: React.FC> = ({ padding = 'none', hidden = false, children, - sx = defaultSxProp, + sx, className, style, }) => { @@ -602,7 +601,7 @@ const Pane = React.forwardRef> = ({ dividerWhenNarrow = 'inherit', hidden = false, children, - sx = defaultSxProp, + sx, className, style, }) => { diff --git a/packages/react/src/Pagehead/Pagehead.tsx b/packages/react/src/Pagehead/Pagehead.tsx index 2632f3b6c26..69a96928590 100644 --- a/packages/react/src/Pagehead/Pagehead.tsx +++ b/packages/react/src/Pagehead/Pagehead.tsx @@ -2,14 +2,10 @@ import type React from 'react' import {clsx} from 'clsx' import {type SxProp} from '../sx' import classes from './Pagehead.module.css' -import {defaultSxProp} from '../utils/defaultSxProp' -import Box from '../Box' +import {BoxWithFallback} from '../internal/components/BoxWithFallback' -const Pagehead = ({className, sx: sxProp = defaultSxProp, ...rest}: PageheadProps) => { - if (sxProp !== defaultSxProp || rest.as) { - return - } - return
+const Pagehead = ({className, ...rest}: PageheadProps) => { + return } /** diff --git a/packages/react/src/Radio/Radio.tsx b/packages/react/src/Radio/Radio.tsx index d6bd8178021..0f898871900 100644 --- a/packages/react/src/Radio/Radio.tsx +++ b/packages/react/src/Radio/Radio.tsx @@ -5,8 +5,7 @@ import {RadioGroupContext} from '../RadioGroup/RadioGroup' import {clsx} from 'clsx' import sharedClasses from '../Checkbox/shared.module.css' import classes from './Radio.module.css' -import {defaultSxProp} from '../utils/defaultSxProp' -import Box from '../Box' +import {BoxWithFallback} from '../internal/components/BoxWithFallback' export type RadioProps = { /** @@ -47,7 +46,6 @@ const Radio = React.forwardRef( disabled, name: nameProp, onChange, - sx: sxProp = defaultSxProp, required, value, className, @@ -70,29 +68,9 @@ const Radio = React.forwardRef( ) } - if (sxProp !== defaultSxProp) { - return ( - - ) - } - return ( - > = ({ fullWidth, onChange, size, - sx: sxProp = defaultSxProp, + sx: sxProp, variant = 'default', className, ...rest diff --git a/packages/react/src/SegmentedControl/SegmentedControlButton.tsx b/packages/react/src/SegmentedControl/SegmentedControlButton.tsx index 3c555015590..cafd127ca20 100644 --- a/packages/react/src/SegmentedControl/SegmentedControlButton.tsx +++ b/packages/react/src/SegmentedControl/SegmentedControlButton.tsx @@ -2,7 +2,6 @@ import type {ButtonHTMLAttributes} from 'react' import type React from 'react' import type {IconProps} from '@primer/octicons-react' import type {SxProp} from '../sx' -import {defaultSxProp} from '../utils/defaultSxProp' import {isElement} from 'react-is' import classes from './SegmentedControl.module.css' @@ -25,7 +24,7 @@ const SegmentedControlButton: React.FC - } - - return +function StyledSpinner({className, ...props}: SpinnerProps) { + return } StyledSpinner.displayName = 'Spinner' diff --git a/packages/react/src/SubNav/SubNav.tsx b/packages/react/src/SubNav/SubNav.tsx index 1f9bbd688e4..4b7fedae5b4 100644 --- a/packages/react/src/SubNav/SubNav.tsx +++ b/packages/react/src/SubNav/SubNav.tsx @@ -4,9 +4,8 @@ import React from 'react' import type {ComponentProps} from '../utils/types' import styles from './SubNav.module.css' -import {defaultSxProp} from '../utils/defaultSxProp' import type {SxProp} from '../sx' -import Box from '../Box' +import {BoxWithFallback} from '../internal/components/BoxWithFallback' type StyledSubNavProps = React.ComponentProps<'nav'> & { actions?: React.ReactNode @@ -18,29 +17,20 @@ type StyledSubNavLinksProps = React.ComponentProps<'div'> & SxProp type StyledSubNavLinkProps = React.ComponentProps<'a'> & {to?: To; selected?: boolean} & SxProp const SubNav = React.forwardRef(function SubNav( - {actions, className, children, label, sx: sxProp = defaultSxProp, ...rest}, + {actions, className, children, label, ...rest}, forwardRef, ) { - if (sxProp !== defaultSxProp) { - return ( - -
{children}
- {actions &&
{actions}
} -
- ) - } return ( - +
) }) SubNav.displayName = 'SubNav' @@ -48,18 +38,11 @@ SubNav.displayName = 'SubNav' // SubNav.Links const SubNavLinks = React.forwardRef( - ({children, className, sx: sxProp = defaultSxProp, ...rest}, forwardRef) => { - if (sxProp !== defaultSxProp) { - return ( - - {children} - - ) - } + ({children, className, ...rest}, forwardRef) => { return ( -
+ {children} -
+
) }, ) @@ -68,25 +51,10 @@ SubNavLinks.displayName = 'SubNav.Links' // SubNav.Link const SubNavLink = React.forwardRef( - ({children, className, sx: sxProp = defaultSxProp, ...rest}, forwardRef) => { - if (sxProp !== defaultSxProp) { - return ( - - {children} - - ) - } - + ({children, className, ...rest}, forwardRef) => { return ( - ( {...rest} > {children} - + ) }, ) diff --git a/packages/react/src/Timeline/Timeline.tsx b/packages/react/src/Timeline/Timeline.tsx index 1ba71c9e5fd..04af8f5e220 100644 --- a/packages/react/src/Timeline/Timeline.tsx +++ b/packages/react/src/Timeline/Timeline.tsx @@ -1,39 +1,23 @@ import {clsx} from 'clsx' import React from 'react' -import Box from '../Box' import type {SxProp} from '../sx' import classes from './Timeline.module.css' -import {defaultSxProp} from '../utils/defaultSxProp' +import {BoxWithFallback} from '../internal/components/BoxWithFallback' type StyledTimelineProps = {clipSidebar?: boolean; className?: string} & SxProp export type TimelineProps = StyledTimelineProps & React.ComponentPropsWithoutRef<'div'> -const Timeline = React.forwardRef( - ({clipSidebar, className, sx: sxProp = defaultSxProp, ...props}, forwardRef) => { - if (sxProp !== defaultSxProp) { - return ( - - ) - } - - return ( -
- ) - }, -) +const Timeline = React.forwardRef(({clipSidebar, className, ...props}, forwardRef) => { + return ( + + ) +}) Timeline.displayName = 'Timeline' @@ -47,21 +31,9 @@ export type TimelineItemsProps = StyledTimelineItemProps & SxProp & React.Compon export type TimelineItemProps = StyledTimelineItemProps & SxProp & React.ComponentPropsWithoutRef<'div'> const TimelineItem = React.forwardRef( - ({condensed, className, sx: sxProp = defaultSxProp, ...props}, forwardRef) => { - if (sxProp !== defaultSxProp) { - return ( - - ) - } + ({condensed, className, ...props}, forwardRef) => { return ( -
-const TimelineBadge = ({sx: sxProp = defaultSxProp, className, ...props}: TimelineBadgeProps) => { - if (sxProp !== defaultSxProp) { - return ( -
- -
- ) - } +const TimelineBadge = ({className, ...props}: TimelineBadgeProps) => { return (
-
+
) } @@ -99,14 +64,9 @@ export type TimelineBodyProps = { } & SxProp & React.ComponentPropsWithoutRef<'div'> -const TimelineBody = React.forwardRef( - ({className, sx: sxProp = defaultSxProp, ...props}, forwardRef) => { - if (sxProp !== defaultSxProp) { - return - } - return
- }, -) +const TimelineBody = React.forwardRef(({className, ...props}, forwardRef) => { + return +}) TimelineBody.displayName = 'TimelineBody' @@ -116,14 +76,9 @@ export type TimelineBreakProps = { } & SxProp & React.ComponentPropsWithoutRef<'div'> -const TimelineBreak = React.forwardRef( - ({className, sx: sxProp = defaultSxProp, ...props}, forwardRef) => { - if (sxProp !== defaultSxProp) { - return - } - return
- }, -) +const TimelineBreak = React.forwardRef(({className, ...props}, forwardRef) => { + return +}) TimelineBreak.displayName = 'TimelineBreak' diff --git a/packages/react/src/Token/Token.tsx b/packages/react/src/Token/Token.tsx index 1e0f0609993..51b2660df8e 100644 --- a/packages/react/src/Token/Token.tsx +++ b/packages/react/src/Token/Token.tsx @@ -2,7 +2,6 @@ import type {MouseEventHandler} from 'react' import type React from 'react' import {forwardRef} from 'react' import {type SxProp} from '../sx' -import {defaultSxProp} from '../utils/defaultSxProp' import type {TokenBaseProps} from './TokenBase' import TokenBase, {defaultTokenSize, isTokenInteractive} from './TokenBase' import RemoveTokenButton from './_RemoveTokenButton' @@ -45,7 +44,6 @@ const Token = forwardRef((props, forwardedRef) => { hideRemoveButton, href, onClick, - sx: sxProp = defaultSxProp, className, style, ...rest @@ -68,7 +66,6 @@ const Token = forwardRef((props, forwardedRef) => { className={clsx(className, classes.Token)} text={text} size={size} - sx={sxProp} data-is-selected={props.isSelected} data-is-remove-btn={!(hideRemoveButton || !onRemove)} {...(!hasMultipleActionTargets ? interactiveTokenProps : {})} diff --git a/packages/react/src/VisuallyHidden/VisuallyHidden.tsx b/packages/react/src/VisuallyHidden/VisuallyHidden.tsx index c1fa5a9bd1a..c56c16c971c 100644 --- a/packages/react/src/VisuallyHidden/VisuallyHidden.tsx +++ b/packages/react/src/VisuallyHidden/VisuallyHidden.tsx @@ -3,8 +3,7 @@ import {clsx} from 'clsx' import type React from 'react' import {type HTMLAttributes} from 'react' import classes from './VisuallyHidden.module.css' -import {defaultSxProp} from '../utils/defaultSxProp' -import Box from '../Box' +import {BoxWithFallback} from '../internal/components/BoxWithFallback' /** * Provides a component that implements the "visually hidden" technique. This is @@ -16,19 +15,11 @@ import Box from '../Box' * * @see https://www.scottohara.me/blog/2023/03/21/visually-hidden-hack.html */ -export const VisuallyHidden = ({className, children, sx: sxProp = defaultSxProp, ...rest}: VisuallyHiddenProps) => { - if (sxProp !== defaultSxProp) { - return ( - - {children} - - ) - } - +export const VisuallyHidden = ({className, children, ...rest}: VisuallyHiddenProps) => { return ( - + {children} - + ) } diff --git a/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.tsx b/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.tsx index 94ec2df6142..0a9ca088c3b 100644 --- a/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.tsx +++ b/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.tsx @@ -17,15 +17,15 @@ import { UnderlineItem, type UnderlineItemProps, } from '../../internal/components/UnderlineTabbedInterface' -import Box, {type BoxProps} from '../../Box' +import {type BoxProps} from '../../Box' import {useId} from '../../hooks' import {invariant} from '../../utils/invariant' import {type SxProp} from '../../sx' -import {defaultSxProp} from '../../utils/defaultSxProp' import {useResizeObserver, type ResizeObserverEntry} from '../../hooks/useResizeObserver' import useIsomorphicLayoutEffect from '../../utils/useIsomorphicLayoutEffect' import classes from './UnderlinePanels.module.css' import {clsx} from 'clsx' +import {BoxWithFallback} from '../../internal/components/BoxWithFallback' export type UnderlinePanelsProps = { /** @@ -83,7 +83,6 @@ const UnderlinePanels: FC = ({ 'aria-labelledby': ariaLabelledBy, children, loadingCounters, - sx: sxProp = defaultSxProp, className, ...props }) => { @@ -176,7 +175,6 @@ const UnderlinePanels: FC = ({ ref={wrapperRef} slot="tablist-wrapper" data-icons-visible={iconsVisible} - sx={sxProp} className={clsx(className, classes.StyledUnderlineWrapper)} {...props} > @@ -189,7 +187,7 @@ const UnderlinePanels: FC = ({ ) } -const Tab: FC = ({'aria-selected': ariaSelected, sx: sxProp = defaultSxProp, onSelect, ...props}) => { +const Tab: FC = ({'aria-selected': ariaSelected, onSelect, ...props}) => { const clickHandler = React.useCallback( (event: React.MouseEvent) => { if (!event.defaultPrevented && typeof onSelect === 'function') { @@ -213,7 +211,6 @@ const Tab: FC = ({'aria-selected': ariaSelected, sx: sxProp = defaultS role="tab" tabIndex={ariaSelected ? 0 : -1} aria-selected={ariaSelected} - sx={sxProp} type="button" onClick={clickHandler} onKeyDown={keyDownHandler} @@ -225,7 +222,7 @@ const Tab: FC = ({'aria-selected': ariaSelected, sx: sxProp = defaultS Tab.displayName = 'UnderlinePanels.Tab' const Panel: FC = props => { - return + return } Panel.displayName = 'UnderlinePanels.Panel' diff --git a/packages/react/src/internal/components/UnderlineTabbedInterface.tsx b/packages/react/src/internal/components/UnderlineTabbedInterface.tsx index 3ad480b97df..a2887dd13ad 100644 --- a/packages/react/src/internal/components/UnderlineTabbedInterface.tsx +++ b/packages/react/src/internal/components/UnderlineTabbedInterface.tsx @@ -7,7 +7,6 @@ import type {IconProps} from '@primer/octicons-react' import CounterLabel from '../../CounterLabel' import {type SxProp} from '../../sx' import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../../utils/polymorphic' -import {defaultSxProp} from '../../utils/defaultSxProp' import classes from './UnderlineTabbedInterface.module.css' import {clsx} from 'clsx' @@ -24,12 +23,9 @@ type UnderlineWrapperProps = { } & SxProp export const UnderlineWrapper = forwardRef( - ( - {children, className, sx: sxProp = defaultSxProp, ...rest}: PropsWithChildren, - forwardedRef, - ) => { + ({children, className, ...rest}: PropsWithChildren, forwardedRef) => { return ( - + {children} ) @@ -48,38 +44,6 @@ export const LoadingCounter = () => { return } -// We can uncomment these when/if we add overflow behavior -// to the UnderlinePanels component -// -// export const StyledMoreButton = styled(Button)` -// margin: 0; -// border: 0; -// background: transparent; -// font-weight: normal; -// box-shadow: none; -// padding-block: var(--control-small-paddingBlock); -// padding-inline: var(--control-small-paddingInline-condensed); - -// > span[data-component='trailingVisual'] { -// margin-left: 0; -// } -// ` - -// export const StyledOverflowDivider = styled.span` -// display: inline-block; -// border-left: 1px solid var(--borderColor-muted); -// width: 1px; -// margin-right: var(--control-xsmall-gap); -// /* The height of the divider - reference from Figma */ -// height: 24px; -// ` - -// export const StyledMoreMenuListItem = styled.li` -// display: flex; -// align-items: center; -// height: 45px; -// ` - export type UnderlineItemProps = { as?: React.ElementType | 'a' | 'button' className?: string @@ -100,20 +64,13 @@ export const UnderlineItem = forwardRef( icon: Icon, iconsVisible, loadingCounters, - sx: sxProp = defaultSxProp, className, ...rest }: PropsWithChildren, forwardedRef, ) => { return ( - + {iconsVisible && Icon && {isElement(Icon) ? Icon : }} {children && ( From d1a54683085821f443b2d37c7120169a7c6650e1 Mon Sep 17 00:00:00 2001 From: Jon Rohan Date: Mon, 7 Jul 2025 12:13:45 -0700 Subject: [PATCH 2/4] Update Details.tsx --- packages/react/src/Details/Details.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/react/src/Details/Details.tsx b/packages/react/src/Details/Details.tsx index 88b293cac94..6ccc87fec60 100644 --- a/packages/react/src/Details/Details.tsx +++ b/packages/react/src/Details/Details.tsx @@ -51,6 +51,14 @@ const Root = React.forwardRef( Root.displayName = 'Details' +export type SummaryProps = { + /** + * HTML element to render summary as. + */ + as?: As + children?: React.ReactNode +} & React.ComponentPropsWithoutRef + function Summary({as, children, ...props}: SummaryProps) { const Component = as ?? 'summary' return ( From 9341539eeec6f5328419639711cc7c4649e29dca Mon Sep 17 00:00:00 2001 From: Jon Rohan Date: Mon, 7 Jul 2025 12:51:41 -0700 Subject: [PATCH 3/4] Create thick-rules-shout.md --- .changeset/thick-rules-shout.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/thick-rules-shout.md diff --git a/.changeset/thick-rules-shout.md b/.changeset/thick-rules-shout.md new file mode 100644 index 00000000000..96b35f2854e --- /dev/null +++ b/.changeset/thick-rules-shout.md @@ -0,0 +1,5 @@ +--- +"@primer/react": patch +--- + +chore: Refactor components to use BoxWithFallback instead of custom Box if statements and remove defaultSxProp references From 5d2d0dbbcbc64fe68a2d26e0c96a6356b1736fa6 Mon Sep 17 00:00:00 2001 From: Jon Rohan Date: Mon, 7 Jul 2025 13:49:58 -0700 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Josh Black --- packages/react/src/Details/Details.tsx | 2 +- packages/react/src/SubNav/SubNav.tsx | 2 +- packages/react/src/VisuallyHidden/VisuallyHidden.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react/src/Details/Details.tsx b/packages/react/src/Details/Details.tsx index 6ccc87fec60..d54aed4f2e2 100644 --- a/packages/react/src/Details/Details.tsx +++ b/packages/react/src/Details/Details.tsx @@ -40,7 +40,7 @@ const Root = React.forwardRef( }, []) return ( - + {/* Include default summary if summary is not provided */} {!hasSummary && {'See Details'}} {children} diff --git a/packages/react/src/SubNav/SubNav.tsx b/packages/react/src/SubNav/SubNav.tsx index 4b7fedae5b4..7e68ecde7b0 100644 --- a/packages/react/src/SubNav/SubNav.tsx +++ b/packages/react/src/SubNav/SubNav.tsx @@ -22,7 +22,7 @@ const SubNav = React.forwardRef(function SubNav( ) { return ( { return ( - + {children} )