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

     1  /* eslint-disable react/jsx-props-no-spreading */
     2  import React, { Ref, ReactNode } from 'react';
     3  import ModalUnstyled from '@mui/base/ModalUnstyled';
     4  import Button from '@webapp/ui/Button';
     5  import cx from 'classnames';
     6  import styles from './Dialog.module.css';
     7  
     8  const Backdrop = React.forwardRef<
     9    HTMLDivElement,
    10    { open?: boolean; className: string }
    11  >((props, ref) => {
    12    const { open, className, ...other } = props;
    13    return <div className={styles.backdrop} ref={ref} {...other} />;
    14  });
    15  
    16  type DialogHeaderProps = { children: ReactNode; className?: string } & (
    17    | { closeable: true; onClose: () => void }
    18    | { closeable?: false }
    19  );
    20  export const DialogHeader = React.forwardRef(
    21    (props: DialogHeaderProps, ref?: Ref<HTMLInputElement>) => {
    22      const { children, className, closeable } = props;
    23      return (
    24        <div className={cx(styles.header, className)} ref={ref}>
    25          {children}
    26          {closeable ? (
    27            <Button
    28              aria-label="Close"
    29              onClick={() => props.onClose()}
    30              noBox
    31              className={styles.closeButton}
    32            />
    33          ) : null}
    34        </div>
    35      );
    36    }
    37  );
    38  
    39  interface DialogFooterProps {
    40    children: ReactNode;
    41    className?: string;
    42  }
    43  export const DialogFooter = React.forwardRef(
    44    (props: DialogFooterProps, ref?: Ref<HTMLInputElement>) => {
    45      const { children, className } = props;
    46      return (
    47        <div className={cx(styles.footer, className)} ref={ref}>
    48          {children}
    49        </div>
    50      );
    51    }
    52  );
    53  
    54  interface DialogBodyProps {
    55    children: ReactNode;
    56    className?: string;
    57  }
    58  export const DialogBody = React.forwardRef(
    59    (props: DialogBodyProps, ref?: Ref<HTMLInputElement>) => {
    60      const { children, className } = props;
    61      return (
    62        <div className={cx(styles.body, className)} ref={ref}>
    63          {children}
    64        </div>
    65      );
    66    }
    67  );
    68  
    69  type DialogProps = Exclude<
    70    React.ComponentProps<typeof ModalUnstyled>,
    71    'components'
    72  > & {
    73    className?: string;
    74    /** The header ID */
    75    ['aria-labelledby']: string;
    76  };
    77  export function Dialog(props: DialogProps) {
    78    const { className } = props;
    79    return (
    80      <ModalUnstyled
    81        {...props}
    82        components={{ Backdrop }}
    83        className={cx(styles.modal, className)}
    84      >
    85        <div
    86          aria-modal="true"
    87          aria-labelledby={props['aria-labelledby']}
    88          className={styles.modalContainer}
    89        >
    90          {props.children}
    91        </div>
    92      </ModalUnstyled>
    93    );
    94  }
    95  
    96  export function DialogActions({ children }: { children: React.ReactNode }) {
    97    return <div className={styles.dialogActions}>{children}</div>;
    98  }