github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/ui/Button.tsx (about)

     1  import React, { ReactNode } from 'react';
     2  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
     3  import type { IconDefinition } from '@fortawesome/fontawesome-common-types';
     4  import cx from 'classnames';
     5  import styles from './Button.module.scss';
     6  
     7  export interface ButtonProps {
     8    kind?: 'default' | 'primary' | 'secondary' | 'danger' | 'outline' | 'float';
     9    // kind?: 'default' | 'primary' | 'secondary' | 'danger' | 'float' | 'outline';
    10    /** Whether the button is disabled or not */
    11    disabled?: boolean;
    12    icon?: IconDefinition;
    13    iconNode?: ReactNode;
    14  
    15    children?: React.ReactNode;
    16  
    17    /** Buttons are grouped so that only the first and last have clear limits */
    18    grouped?: boolean;
    19  
    20    onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
    21  
    22    // TODO
    23    // for the full list use refer to https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input
    24    type?: 'button' | 'submit';
    25    ['data-testid']?: string;
    26  
    27    ['aria-label']?: string;
    28  
    29    className?: string;
    30  
    31    id?: string;
    32    form?: React.ButtonHTMLAttributes<HTMLButtonElement>['form'];
    33  
    34    /** disable a box around it */
    35    noBox?: boolean;
    36  
    37    /** ONLY use this if within a modal (https://stackoverflow.com/a/71848275 and https://citizensadvice.github.io/react-dialogs/modal/auto_focus/index.html) */
    38    autoFocus?: React.ButtonHTMLAttributes<HTMLButtonElement>['autoFocus'];
    39  }
    40  
    41  const Button = React.forwardRef(function Button(
    42    {
    43      disabled = false,
    44      kind = 'default',
    45      type = 'button',
    46      icon,
    47      iconNode,
    48      children,
    49      grouped,
    50      onClick,
    51      id,
    52      className,
    53      form,
    54      noBox,
    55      autoFocus,
    56      ...props
    57    }: ButtonProps,
    58    ref: React.LegacyRef<HTMLButtonElement>
    59  ) {
    60    return (
    61      <button
    62        // needed for tooltip
    63        // eslint-disable-next-line react/jsx-props-no-spreading
    64        {...props}
    65        id={id}
    66        ref={ref}
    67        type={type}
    68        data-testid={props['data-testid']}
    69        disabled={disabled}
    70        onClick={onClick}
    71        form={form}
    72        autoFocus={autoFocus} // eslint-disable-line jsx-a11y/no-autofocus
    73        aria-label={props['aria-label']}
    74        className={cx(
    75          styles.button,
    76          grouped ? styles.grouped : '',
    77          getKindStyles(kind),
    78          className,
    79          noBox && styles.noBox,
    80          iconNode && styles.customIcon,
    81          !icon && !iconNode && styles.noIcon
    82        )}
    83      >
    84        {icon ? (
    85          <FontAwesomeIcon
    86            icon={icon}
    87            className={children ? styles.iconWithText : ''}
    88          />
    89        ) : null}
    90        {iconNode}
    91        {children}
    92      </button>
    93    );
    94  });
    95  
    96  function getKindStyles(kind: ButtonProps['kind']) {
    97    switch (kind) {
    98      case 'default': {
    99        return styles.default;
   100      }
   101  
   102      case 'primary': {
   103        return styles.primary;
   104      }
   105  
   106      case 'secondary': {
   107        return styles.secondary;
   108      }
   109  
   110      case 'danger': {
   111        return styles.danger;
   112      }
   113  
   114      case 'outline': {
   115        return styles.outline;
   116      }
   117  
   118      case 'float': {
   119        return styles.float;
   120      }
   121  
   122      default: {
   123        throw Error(`Unsupported kind ${kind}`);
   124      }
   125    }
   126  }
   127  
   128  export default Button;