diff --git a/.changeset/fuzzy-needles-peel.md b/.changeset/fuzzy-needles-peel.md new file mode 100644 index 00000000000..553215a988e --- /dev/null +++ b/.changeset/fuzzy-needles-peel.md @@ -0,0 +1,5 @@ +--- +"@primer/react": patch +--- + +Update `ButtonBase` to minimize re-renders through stable `sx` prop values diff --git a/src/Button/ButtonBase.tsx b/src/Button/ButtonBase.tsx index 10d2e83bc47..c79204f4193 100644 --- a/src/Button/ButtonBase.tsx +++ b/src/Button/ButtonBase.tsx @@ -6,18 +6,28 @@ import {useTheme} from '../ThemeProvider' import {ButtonProps, StyledButton} from './types' import {getVariantStyles, getSizeStyles, getButtonStyles} from './styles' +const defaultSxProp = {} +const iconWrapStyles = { + display: 'inline-block' +} +const trailingIconStyles = { + ...iconWrapStyles, + ml: 2 +} + const ButtonBase = forwardRef( - ({children, as: Component = 'button', sx: sxProp = {}, ...props}, forwardedRef): JSX.Element => { + ({children, as: Component = 'button', sx: sxProp = defaultSxProp, ...props}, forwardedRef): JSX.Element => { const {leadingIcon: LeadingIcon, trailingIcon: TrailingIcon, variant = 'default', size = 'medium'} = props const {theme} = useTheme() - const iconWrapStyles = { - display: 'inline-block' - } - const sxStyles = useMemo(() => { + const baseStyles = useMemo(() => { return merge.all([getButtonStyles(theme), getSizeStyles(size, variant, false), getVariantStyles(variant, theme)]) }, [theme, size, variant]) + const sxStyles = useMemo(() => { + return merge(baseStyles, sxProp as SxProp) + }, [baseStyles, sxProp]) + return ( - + {LeadingIcon && ( @@ -25,7 +35,7 @@ const ButtonBase = forwardRef( )} {children && {children}} {TrailingIcon && ( - + )}