import CloseOutlined from '@ant-design/icons/CloseOutlined'; import classNames from 'classnames'; import RcDrawer from 'rc-drawer'; import type { DrawerProps as RcDrawerProps } from 'rc-drawer'; import type { CSSMotionProps } from 'rc-motion'; import * as React from 'react'; import { ConfigContext } from '../config-provider'; import { NoFormStyle } from '../form/context'; import { getTransitionName } from '../_util/motion'; import { tuple } from '../_util/type'; // CSSINJS import useStyle from './style'; const SizeTypes = tuple('default', 'large'); type sizeType = typeof SizeTypes[number]; export interface PushState { distance: string | number; } // Drawer diff props: 'open' | 'motion' | 'maskMotion' | 'wrapperClassName' export interface DrawerProps extends RcDrawerProps { size?: sizeType; closable?: boolean; closeIcon?: React.ReactNode; /** Wrapper dom node style of header and body */ drawerStyle?: React.CSSProperties; headerStyle?: React.CSSProperties; bodyStyle?: React.CSSProperties; footerStyle?: React.CSSProperties; title?: React.ReactNode; visible?: boolean; footer?: React.ReactNode; extra?: React.ReactNode; afterVisibleChange?: (visible: boolean) => void; } const defaultPushState: PushState = { distance: 180 }; function Drawer({ rootClassName, width, height, size = 'default', closable = true, mask = true, push = defaultPushState, closeIcon = , bodyStyle, drawerStyle, visible, children, style, title, headerStyle, onClose, footer, footerStyle, prefixCls: customizePrefixCls, getContainer: customizeGetContainer, extra, afterVisibleChange, ...rest }: DrawerProps) { const { getPopupContainer, getPrefixCls, direction } = React.useContext(ConfigContext); const prefixCls = getPrefixCls('drawer', customizePrefixCls); // Style const [wrapSSR, hashId] = useStyle(prefixCls); const getContainer = // 有可能为 false,所以不能直接判断 customizeGetContainer === undefined && getPopupContainer ? () => getPopupContainer(document.body) : customizeGetContainer; const closeIconNode = closable && ( ); function renderHeader() { if (!title && !closable) { return null; } return (
{closeIconNode} {title &&
{title}
}
{extra &&
{extra}
}
); } function renderFooter() { if (!footer) { return null; } const footerClassName = `${prefixCls}-footer`; return (
{footer}
); } const drawerClassName = classNames( { 'no-mask': !mask, [`${prefixCls}-rtl`]: direction === 'rtl', }, rootClassName, hashId, ); // ============================ Size ============================ const mergedWidth = React.useMemo(() => width ?? (size === 'large' ? 736 : 378), [width, size]); const mergedHeight = React.useMemo( () => height ?? (size === 'large' ? 736 : 378), [height, size], ); // =========================== Motion =========================== const maskMotion: CSSMotionProps = { motionName: getTransitionName(prefixCls, 'mask-motion'), motionAppear: true, motionEnter: true, motionLeave: true, motionDeadline: 500, }; const panelMotion: RcDrawerProps['motion'] = motionPlacement => ({ motionName: getTransitionName(prefixCls, `panel-motion-${motionPlacement}`), motionAppear: true, motionEnter: true, motionLeave: true, motionDeadline: 500, }); // =========================== Render =========================== return wrapSSR( { afterVisibleChange?.(open); }} >
{renderHeader()}
{children}
{renderFooter()}
, ); } if (process.env.NODE_ENV !== 'production') { Drawer.displayName = 'Drawer'; } interface PurePanelProps extends DrawerProps {} function PurePanel({ style, ...restProps }: PurePanelProps) { const containerRef = React.useRef(null); return (
); } Drawer._InternalPanelDoNotUseOrYouWillBeFired = PurePanel; export default Drawer;