import * as React from 'react'; import { VisuallyHidden } from 'react-aria'; import classNames from 'classnames'; import type { SafeExtract, Variant } from '../../types'; import { Icon } from '../Icon/Icon'; import type { IconName } from '../Icon/IconName'; import { Loader } from '../Loader/Loader'; import { Tooltip } from '../Tooltip/Tooltip'; const loaderElement = ; export interface IconButtonProps extends React.ButtonHTMLAttributes { /** * Disables the button. * If true, the button will be disabled and not interactive. * @default false */ disabled?: boolean; /** * Form attribute of the button. * This is useful for buttons that are part of a form and need to submit the form data. * If not provided, the button will not submit any form. * @default undefined */ form?: React.ButtonHTMLAttributes['form']; /** * Removes the button border, making it look like an icon. */ ghost?: boolean; /** * Sets the icon to be displayed in the button. */ icon: IconName; /** * Sets the tooltip label for the button. * If provided, the button will be wrapped in a Tooltip component. * If you want to use the button without a label, omit it, but the button should have aria-label for accessibility. */ label?: string; /** * If true, the button will show a loading spinner instead of the icon. */ isLoading?: boolean; /** * Callback triggered when the button loses focus. */ onBlur?: React.ButtonHTMLAttributes['onBlur']; /** * Callback triggered when the button is pressed. */ onClick?: React.ButtonHTMLAttributes['onClick']; /** * Callback triggered when the button receives focus. */ onFocus?: React.ButtonHTMLAttributes['onFocus']; /** * @default 'sm' */ size?: 'sm' | 'md' | 'lg'; /** * Sets the size of the icon inside the button. * @default 'md' */ iconSize?: 'sm' | 'md' | 'lg'; /** * Sets the title attribute of the button. * This is useful for providing additional information about the button's action. * It will be displayed as a tooltip in most browsers when hovering over the button. * @default undefined */ title?: React.ButtonHTMLAttributes['title']; /** * Sets the type of the button. * Can be 'button', 'submit', or 'reset'. * If not provided, it defaults to 'button'. * This is useful for buttons that are not used for form submission. * @default 'button' */ type?: React.ButtonHTMLAttributes['type']; /** * Sets the color variant of the button. * @default 'primary' */ variant?: SafeExtract; } export function getIconButtonProps

({ label, variant = 'primary', type = 'button', size = 'sm', iconSize = 'md', icon, ghost, isLoading, disabled, ...rest }: P) { return { ...rest, className: classNames(`iconButton`, `iconButton--${size}`, { [`iconButton--${variant}`]: !disabled, [`iconButton--${variant}--disabled`]: isLoading || disabled, [`iconButton--ghost`]: ghost, [`iconButton--isLoading`]: isLoading, }), disabled: isLoading || disabled, type, children: ( <> {isLoading ? loaderElement : null} {!!label && {label}} ), }; } export const IconButton = React.forwardRef(function IconButton( props: IconButtonProps, forwardedRef: React.Ref ) { if (props.label) { return (