// @flow strict import * as React from 'react'; import useMountTransition from '../../hooks/useMountTransition'; import { motionDurationNormal, motionDurationSlow, } from '../../styles/variables/_motion'; import { spaceFluid, spaceNegFluid, spaceNone, } from '../../styles/variables/_space'; import classify from '../../utils/classify'; import {Button} from '../Button'; import type {ModalProps} from '../Modal'; import {Modal} from '../Modal'; import {Truncate} from '../Truncate'; import css from './Panel.module.css'; export type PanelSize = 'small' | 'medium' | 'large'; export type PanelAnchor = 'left' | 'right'; export type PanelHeaderProps = { children?: React.Node, hideCloseBtn?: boolean, onCloseButtonClick?: ?(SyntheticEvent) => mixed, className?: string, size?: 'medium' | 'small', }; type FooterClassNames = $ReadOnly<{ wrapper?: string, actions?: string, }>; export type PanelFooterProps = { children?: React.Node, classNames?: FooterClassNames, }; export type PanelBodyProps = { children?: React.Node, className?: string, }; export type PanelProps = { ...ModalProps, allowBackgroundInteraction?: boolean, size?: PanelSize, anchor?: PanelAnchor, }; const getDefaultPanelAnimation = (anchor: PanelAnchor) => ({ // Configure both open and close durations: duration: { open: parseInt(motionDurationSlow), close: parseInt(motionDurationNormal), }, initial: { transform: `translateX(${anchor === 'right' ? spaceFluid : spaceNegFluid})`, }, open: { transform: `translateX(${spaceNone})`, }, close: { transform: `translateX(${anchor === 'right' ? spaceFluid : spaceNegFluid})`, }, }); export const PanelHeader = ({ children, hideCloseBtn, onCloseButtonClick, className, size, }: PanelHeaderProps): React.Node => ( <> {React.Children.count(children) > 0 && (
{children}
{!hideCloseBtn && ( )}
)} ); export const PanelBody: React$AbstractComponent< PanelBodyProps, HTMLDivElement, > = React.forwardRef( ({children, className}: PanelBodyProps, ref): React.Node => (
{children}
), ); export const PanelFooter = ({ children, classNames, }: PanelFooterProps): React.Node => ( <> {React.Children.count(children) > 0 && (
{children}
)} ); export const Panel = ({ children, isOpen = false, size = 'medium', anchor = 'left', onClose, hideBackdrop = true, classNames, customAnimation, tapOutsideToClose = true, allowBackgroundInteraction, ...restPanelProps }: PanelProps): React.Node => { const isTransitioning = useMountTransition( isOpen, parseInt(motionDurationNormal), ); const defaultPanelAnimation = getDefaultPanelAnimation(anchor); return ( {children} ); };