// @flow strict import * as React from 'react'; import {classify} from '../../utils/classify'; import {CircularLoader} from '../CircularLoader'; import type {IconType} from '../Icon'; import {Icon} from '../Icon'; import {Truncate} from '../Truncate'; import css from './Button.module.css'; type ClassNames = $ReadOnly<{wrapper?: string, icon?: string, text?: string}>; /** * Note(Nishant): Although Button supports gradient as a type, its not currently customizable really. * This only supports pre-defined gradient that moves from left to right. * If someone wants to add more gradients, the expectation is that they would add it through a wrapper className. * * We could have taken an extra prop to take in the Gradient colors but that should not be encouraged * as it would add an additional overhead on the component to figure out exact color values from string tokens * and since this is rarely used type anyway, it should be avoided. */ export const BUTTON_TYPES = Object.freeze({ primary: 'primary', secondary: 'secondary', tertiary: 'tertiary', ghost: 'ghost', danger: 'danger', gradient: 'gradient', }); export const BUTTON_ACTION_TYPE = Object.freeze({ button: 'button', submit: 'submit', reset: 'reset', }); export const BUTTON_SIZE = Object.freeze({ small: 'small', medium: 'medium', }); export type ButtonType = $Values; export type ButtonActionType = $Values; export type ButtonSize = $Keys; export type BaseButtonProps = { children?: React.Node, disabled?: mixed, actionType?: ButtonActionType, onClick?: ?(SyntheticEvent) => mixed, ariaLabel?: string, tabIndex?: number, isLoading?: boolean, role?: string, ... }; export type UnstyledButtonProps = { ...BaseButtonProps, className?: string, ... }; export type ButtonProps = { ...BaseButtonProps, classNames?: ClassNames, iconLeftName?: string, iconLeftType?: IconType, iconRightName?: string, iconRightType?: IconType, type?: ButtonType, isFluid?: boolean, size?: ButtonSize, ... }; const ButtonTypeToIconColorMap = { primary: 'inversePrimary', secondary: 'clickable', tertiary: 'primary', ghost: 'primary', danger: 'inversePrimary', gradient: 'inversePrimary', }; const ButtonTypeToLoaderColorMap = { primary: 'colorTextInversePrimary', secondary: 'colorTextClickable', tertiary: 'colorTextPrimary', ghost: 'colorTextPrimary', danger: 'colorTextInversePrimary', gradient: 'colorTextInversePrimary', }; export const UnstyledButton: React$AbstractComponent< UnstyledButtonProps, HTMLButtonElement, > = React.forwardRef( ( { disabled, onClick, className, ariaLabel, actionType, tabIndex = 0, isLoading, role = 'button', ...props }: UnstyledButtonProps, ref, ) => (