vitess.io/vitess@v0.16.2/web/vtadmin/src/components/Snackbar.tsx (about)

     1  import React from 'react';
     2  import { Icon, Icons } from './Icon';
     3  import { Intent } from './intent';
     4  import { ToastContainer, toast, Slide, ToastOptions } from 'react-toastify';
     5  import 'react-toastify/dist/ReactToastify.css';
     6  
     7  interface SnackbarProps {
     8      message: string;
     9      icon?: Icons;
    10      intent?: Intent;
    11      closeToast?: () => void;
    12  }
    13  
    14  // Needed to choose lighter background color
    15  const translateIntentColor = (intent: Intent) => {
    16      switch (intent) {
    17          case Intent.danger:
    18              return 'red-50';
    19          case Intent.warning:
    20              return 'yellow-50';
    21          case Intent.success:
    22              return 'green-50';
    23          case Intent.none:
    24              return 'gray-50';
    25      }
    26  };
    27  
    28  const Snackbar: React.FC<SnackbarProps> = ({ closeToast, message, icon, intent = Intent.none, ...props }) => {
    29      const intentColor = intent === Intent.none ? 'gray-900' : `${intent}`;
    30  
    31      return (
    32          <div
    33              className={`flex font-medium text-sm text-${intentColor} border border-${intentColor} items-center bg-gray-100 justify-between py-6 px-8 z-20 rounded-xl bg-${translateIntentColor(
    34                  intent
    35              )}`}
    36          >
    37              <div className="flex items-center">
    38                  {icon && (
    39                      <div className="shrink-0">
    40                          <Icon icon={icon} className={`shrink-0 mr-4 fill-current h-8 w-8 min-h-8 min-w-8`} />
    41                      </div>
    42                  )}
    43                  <div className="grow-0 whitespace-normal">{message}</div>
    44              </div>
    45              <button onClick={closeToast}>
    46                  <Icon icon={Icons.delete} className="fill-current text-gray-900 h-6 w-6 ml-8" />
    47              </button>
    48          </div>
    49      );
    50  };
    51  
    52  interface SnackbarContextProps {
    53      warn: (message: string) => void;
    54      danger: (message: string) => void;
    55      success: (message: string) => void;
    56      info: (message: string) => void;
    57  }
    58  
    59  const defaultProps: SnackbarContextProps = {
    60      warn: (message: string) => message,
    61      danger: (message: string) => message,
    62      success: (message: string) => message,
    63      info: (message: string) => message,
    64  };
    65  
    66  interface AddSnackbarParams {
    67      message: string;
    68      icon?: Icons;
    69      intent?: Intent;
    70  }
    71  
    72  export const SnackbarContext = React.createContext<SnackbarContextProps>(defaultProps);
    73  const addSnackbar = (props: AddSnackbarParams, options?: ToastOptions) => {
    74      toast(({ closeToast }) => <Snackbar closeToast={closeToast} key={props.message} {...props} />, {
    75          className: 'mb-2 rounded-2xl',
    76          ...options,
    77      });
    78  };
    79  
    80  export const warn = (message: string, options?: ToastOptions) =>
    81      addSnackbar({ message, intent: Intent.warning, icon: Icons.alertFail }, options);
    82  export const danger = (message: string, options?: ToastOptions) =>
    83      addSnackbar({ message, intent: Intent.danger, icon: Icons.alertFail }, options);
    84  export const success = (message: string, options?: ToastOptions) =>
    85      addSnackbar({ message, intent: Intent.success, icon: Icons.checkSuccess }, options);
    86  export const info = (message: string, options?: ToastOptions) =>
    87      addSnackbar({ message, intent: Intent.none, icon: Icons.info }, options);
    88  
    89  export const SnackbarContainer: React.FC = ({ children }) => {
    90      return (
    91          <div className="fixed right-10 bottom-6" id="snackbar-container">
    92              <ToastContainer
    93                  toastClassName="mb-2"
    94                  autoClose={false}
    95                  position="bottom-right"
    96                  closeButton={false}
    97                  closeOnClick
    98                  hideProgressBar
    99                  pauseOnHover
   100                  transition={Slide}
   101              />
   102          </div>
   103      );
   104  };
   105  
   106  export default Snackbar;