import { forwardRef, useImperativeHandle, useRef, useState } from 'react'; import classnames from 'classnames'; import styles from './InternalIconButton.css'; import compactIconsClassic from '../icons/compact/index'; import InternalPogCompact from '../Pog/InternalPogCompact'; import touchableStyles from '../TapArea.css'; import useFocusVisible from '../useFocusVisible'; import useTapFeedback from '../useTapFeedback'; import useExperimentalTheme from '../utils/useExperimentalTheme'; type Props = { accessibilityLabel: string; accessibilityControls?: string; accessibilityExpanded?: boolean; accessibilityHaspopup?: boolean; accessibilityPopupRole?: 'menu' | 'dialog'; focusColor?: 'lightBackground' | 'darkBackground'; bgColor?: | 'transparent' | 'transparentDarkBackground' | 'transparentDarkGray' | 'gray' | 'lightGray' | 'washLight' | 'white' | 'red' | 'elevation'; dangerouslySetSvgPath?: { __path: string; }; dataTestId?: string; disabled?: boolean; icon?: keyof typeof compactIconsClassic; iconColor?: 'gray' | 'darkGray' | 'red' | 'white' | 'brandPrimary' | 'light' | 'dark'; name?: string; onClick?: (arg1: { event: React.MouseEvent | React.KeyboardEvent; }) => void; padding?: 1 | 2 | 3 | 4 | 5; // eslint-disable-next-line react/no-unused-prop-types ref?: HTMLButtonElement; selected?: boolean; size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'; tabIndex?: -1 | 0; }; const InternalIconButtonWithForwardRef = forwardRef(function IconButton( { accessibilityControls, accessibilityExpanded, accessibilityHaspopup, accessibilityLabel, accessibilityPopupRole, bgColor, focusColor = 'lightBackground', dangerouslySetSvgPath, dataTestId, disabled, icon, iconColor, name, onClick, padding, selected, size = 'sm', tabIndex = 0, }: Props, ref, ) { const innerRef = useRef(null); // When using both forwardRef and innerRef, React.useimperativehandle() allows a parent component // that renders to call inputRef.current.focus() // @ts-expect-error - TS2322 - Type 'HTMLButtonElement | null' is not assignable to type 'HTMLButtonElement'. useImperativeHandle(ref, () => innerRef.current); const theme = useExperimentalTheme(); const { compressStyle, isTapping, handleBlur, handleMouseDown, handleMouseUp, handleTouchStart, handleTouchMove, handleTouchCancel, handleTouchEnd, } = useTapFeedback({ height: innerRef?.current?.clientHeight, width: innerRef?.current?.clientWidth, }); const [isActive, setActive] = useState(false); const [isFocused, setFocused] = useState(false); const [isHovered, setHovered] = useState(false); const { isFocusVisible } = useFocusVisible(); const divStyles = classnames(styles.button, touchableStyles.tapTransition, { [styles.disabled]: disabled && !theme.MAIN, [styles.disabledVr]: disabled && theme.MAIN, [styles.enabled]: !disabled, [touchableStyles.tapCompress]: !disabled && isTapping, }); return ( ); }); InternalIconButtonWithForwardRef.displayName = 'IconButton'; export default InternalIconButtonWithForwardRef;