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 }