diff --git a/src/custom/BottomSheet/BottomSheet.tsx b/src/custom/BottomSheet/BottomSheet.tsx new file mode 100644 index 000000000..39a5ac8e7 --- /dev/null +++ b/src/custom/BottomSheet/BottomSheet.tsx @@ -0,0 +1,90 @@ +import React, { useId } from 'react'; +import Slide, { SlideProps } from '@mui/material/Slide'; +import { Dialog } from '../../base/Dialog'; +import { DialogContent } from '../../base/DialogContent'; +import { IconButton } from '../../base/IconButton'; +import { Box } from '../../base/Box'; +import { Typography } from '../../base/Typography'; +import { Divider } from '../../base/Divider'; +import { CloseIcon } from '../../icons/Close'; + +const SlideUp = React.forwardRef((props, ref) => ( + +)); +SlideUp.displayName = 'SlideUp'; + +export interface BottomSheetProps { + open: boolean; + onClose: () => void; + title?: string; + children: React.ReactNode; + /** @default '80vh' */ + maxHeight?: string; + closeButtonAriaLabel?: string; +} + +/** + * BottomSheet — a mobile-friendly dialog that slides up from the bottom of the screen. + */ +const BottomSheet = ({ + open, + onClose, + title, + children, + maxHeight = '80vh', + closeButtonAriaLabel = 'Close', +}: BottomSheetProps) => { + const titleId = useId(); + + return ( + + {title && ( + <> + + + {title} + + + + + + + + )} + + {children} + + + ); +}; + +export default BottomSheet; diff --git a/src/custom/BottomSheet/index.ts b/src/custom/BottomSheet/index.ts new file mode 100644 index 000000000..14de58c52 --- /dev/null +++ b/src/custom/BottomSheet/index.ts @@ -0,0 +1,2 @@ +export { default as BottomSheet } from './BottomSheet'; +export type { BottomSheetProps } from './BottomSheet'; diff --git a/src/custom/Modal/index.tsx b/src/custom/Modal/index.tsx index d33fee1bb..0c81f611a 100644 --- a/src/custom/Modal/index.tsx +++ b/src/custom/Modal/index.tsx @@ -1,5 +1,6 @@ import { ButtonProps, DialogProps, styled } from '@mui/material'; import React, { useRef, useState } from 'react'; +import { omit } from 'lodash'; import { Box, Dialog, IconButton, Paper, Typography } from '../../base'; import { ContainedButton, OutlinedButton, TextButton } from '../../base/Button/Button'; import { iconLarge } from '../../constants/iconsSizes'; @@ -162,9 +163,8 @@ export const Modal: React.FC = ({ */ const { fullScreen: initialFullScreenState = false, - fullWidth: _ignoredFullWidth, ...restProps - } = props; + } = omit(props, ['fullWidth']); const [fullScreen, setFullScreen] = useState(initialFullScreenState); diff --git a/src/custom/index.tsx b/src/custom/index.tsx index 489f0e90c..889e6288c 100644 --- a/src/custom/index.tsx +++ b/src/custom/index.tsx @@ -172,3 +172,4 @@ export * from './ShareModal'; export * from './UserSearchField'; export * from './Workspaces'; export * from './LiquidGlass'; +export * from './BottomSheet';