From 9c0c10787cd010810144946f667a00d9cce92d77 Mon Sep 17 00:00:00 2001 From: Josh Black Date: Mon, 10 Oct 2022 11:45:20 -0500 Subject: [PATCH] fix(ButtonBase): memoize sx prop (#2323) * fix(ButtonBase): memoize sx prop * refactor(ButtonBase): pull out inline trailing icon styles * Create fuzzy-needles-peel.md * refactor(ButtonBase): memoize sxProp separately --- .changeset/fuzzy-needles-peel.md | 5 +++++ src/Button/ButtonBase.tsx | 24 +++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 .changeset/fuzzy-needles-peel.md 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 && ( - + )}