// Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { CSSProperties, MouseEventHandler, ReactNode } from 'react'; import classNames from 'classnames'; import { assert } from '../util/assert'; export enum ButtonSize { Medium, Small, } export enum ButtonVariant { Primary = 'Primary', Secondary = 'Secondary', SecondaryAffirmative = 'SecondaryAffirmative', SecondaryDestructive = 'SecondaryDestructive', Destructive = 'Destructive', Calling = 'Calling', SystemMessage = 'SystemMessage', } type PropsType = { className?: string; disabled?: boolean; size?: ButtonSize; style?: CSSProperties; tabIndex?: number; variant?: ButtonVariant; } & ( | { onClick: MouseEventHandler; } | { type: 'submit'; } ) & ( | { 'aria-label': string; children: ReactNode; } | { 'aria-label'?: string; children: ReactNode; } | { 'aria-label': string; children?: ReactNode; } ); const SIZE_CLASS_NAMES = new Map([ [ButtonSize.Medium, 'module-Button--medium'], [ButtonSize.Small, 'module-Button--small'], ]); const VARIANT_CLASS_NAMES = new Map([ [ButtonVariant.Primary, 'module-Button--primary'], [ButtonVariant.Secondary, 'module-Button--secondary'], [ ButtonVariant.SecondaryAffirmative, 'module-Button--secondary module-Button--secondary--affirmative', ], [ ButtonVariant.SecondaryDestructive, 'module-Button--secondary module-Button--secondary--destructive', ], [ButtonVariant.Destructive, 'module-Button--destructive'], [ButtonVariant.Calling, 'module-Button--calling'], [ButtonVariant.SystemMessage, 'module-Button--system-message'], ]); export const Button = React.forwardRef( (props, ref) => { const { children, className, disabled = false, size = ButtonSize.Medium, style, tabIndex, variant = ButtonVariant.Primary, } = props; const ariaLabel = props['aria-label']; let onClick: undefined | MouseEventHandler; let type: 'button' | 'submit'; if ('onClick' in props) { ({ onClick } = props); type = 'button'; } else { onClick = undefined; ({ type } = props); } const sizeClassName = SIZE_CLASS_NAMES.get(size); assert(sizeClassName, ' ); } );