UNPKG

@utahdts/utah-design-system

Version:
105 lines (98 loc) 3.48 kB
import { useCallback, useState } from 'react'; import { BUTTON_APPEARANCE, BUTTON_TYPES, componentColors, handleKeyPress } from '../../../../index'; import { formElementSizesEnum } from '../../../enums/formElementSizesEnum'; import { handleEvent } from '../../../util/handleEvent'; import { joinClassNames } from '../../../util/joinClassNames'; import { Spinner } from '../../widgetsIndicators/Spinner'; import { ConfirmationButtonContextProvider } from './context/ConfirmationButtonContextProvider'; /** @typedef {import('@utahdts/utah-design-system').ButtonAppearance} ButtonAppearance */ /** @typedef {import('@utahdts/utah-design-system').ButtonTypes} ButtonTypes */ /** @typedef {import('@utahdts/utah-design-system').ComponentColors} ComponentColors */ /** @typedef {import('@utahdts/utah-design-system').FormElementSizes} FormElementSizes */ /** @typedef {import('@utahdts/utah-design-system').WrapInElement} WrapInElement */ /** * @param {object} props * @param {ButtonAppearance} [props.appearance] * @param {import('react').ReactNode} props.children * @param {string} [props.className] * @param {ComponentColors} [props.color] * @param {ComponentColors} [props.confirmationColor] * @param {import('react').RefObject<HTMLButtonElement>} [props.innerRef] * @param {boolean} [props.isBusy] * @param {boolean} [props.isDisabled] * @param {string} [props.id] * @param {import('react').MouseEventHandler} props.onClick * @param {FormElementSizes} [props.size] * @param {ButtonTypes} [props.type] * @returns {import('react').JSX.Element} */ export function ConfirmationButton({ appearance = BUTTON_APPEARANCE.OUTLINED, children, className, color = componentColors.NONE, confirmationColor, id, innerRef, isBusy, isDisabled, onClick, size = 'medium', type = BUTTON_TYPES.BUTTON, ...rest }) { const [isClicked, setIsClicked] = useState(false); const resetButton = useCallback(() => { setIsClicked(false); }, []); const handleOnClick = handleEvent((e) => { if (!isBusy) { if (isClicked) { onClick?.(e); resetButton(); } else { setIsClicked(true); } } }); const onClickCallback = useCallback(handleOnClick, [handleOnClick]); return ( <button className={joinClassNames( 'button', className, `button--${appearance}`, // default color is none (color && color !== 'none') && !(isClicked && confirmationColor) ? `button--${color}-color` : null, // default size is medium (size && size !== formElementSizesEnum.MEDIUM) ? `button--${size}` : null, isClicked ? 'button--confirm' : null, isClicked && confirmationColor ? `button--${confirmationColor}-color` : null )} disabled={isDisabled || isBusy} id={id} ref={innerRef} onClick={onClickCallback} onBlur={resetButton} onKeyUp={handleKeyPress('Escape', resetButton)} // eslint-disable-next-line react/button-has-type type={type} {...rest} > <ConfirmationButtonContextProvider isClicked={isClicked}> {children} </ConfirmationButtonContextProvider> { isBusy ? ( <Spinner className="ml-spacing-xs" size={size === formElementSizesEnum.LARGE1X ? 24 : 22} strokeWidth={size === formElementSizesEnum.LARGE1X ? 14 : 12} /> ) : null } </button> ); }