diff --git a/.changeset/giant-horses-knock.md b/.changeset/giant-horses-knock.md new file mode 100644 index 00000000000..2a72dbe84aa --- /dev/null +++ b/.changeset/giant-horses-knock.md @@ -0,0 +1,5 @@ +--- +'@primer/react': patch +--- + +Add a console warning if the Button and IconButton as property is used incorrectly diff --git a/src/Button/ButtonBase.tsx b/src/Button/ButtonBase.tsx index 01840e098d6..6c2894400d1 100644 --- a/src/Button/ButtonBase.tsx +++ b/src/Button/ButtonBase.tsx @@ -5,6 +5,8 @@ import {merge, SxProp} from '../sx' import {useTheme} from '../ThemeProvider' import {ButtonProps, StyledButton} from './types' import {getVariantStyles, getSizeStyles, getButtonStyles} from './styles' +import {useRefObjectAsForwardedRef} from '../hooks/useRefObjectAsForwardedRef' +declare let __DEV__: boolean const defaultSxProp = {} const iconWrapStyles = { @@ -18,6 +20,9 @@ const trailingIconStyles = { const ButtonBase = forwardRef( ({children, as: Component = 'button', sx: sxProp = defaultSxProp, ...props}, forwardedRef): JSX.Element => { const {leadingIcon: LeadingIcon, trailingIcon: TrailingIcon, variant = 'default', size = 'medium', ...rest} = props + const innerRef = React.useRef(null) + useRefObjectAsForwardedRef(forwardedRef, innerRef) + const {theme} = useTheme() const baseStyles = useMemo(() => { return merge.all([getButtonStyles(theme), getSizeStyles(size, variant, false), getVariantStyles(variant, theme)]) @@ -26,8 +31,17 @@ const ButtonBase = forwardRef( return merge(baseStyles, sxProp as SxProp) }, [baseStyles, sxProp]) + React.useEffect(() => { + if (!(innerRef.current instanceof HTMLButtonElement) && !(innerRef.current instanceof HTMLAnchorElement)) { + if (__DEV__) { + // eslint-disable-next-line no-console + console.warn('This component should be an instanceof a semantic button or anchor') + } + } + }, [innerRef]) + return ( - + {LeadingIcon && ( diff --git a/src/Button/types.ts b/src/Button/types.ts index 629809b6f1b..4072002d332 100644 --- a/src/Button/types.ts +++ b/src/Button/types.ts @@ -18,7 +18,9 @@ export type Size = 'small' | 'medium' | 'large' */ type StyledButtonProps = Omit, 'as'> -type ButtonA11yProps = {'aria-label': string; 'aria-labelby'?: never} | {'aria-label'?: never; 'aria-labelby': string} +type ButtonA11yProps = + | {'aria-label': string; 'aria-labelledby'?: never} + | {'aria-label'?: never; 'aria-labelledby': string} export type ButtonBaseProps = { /**