|
|
|
@ -6,7 +6,6 @@ import RightOutlined from '@ant-design/icons/RightOutlined';
|
|
|
|
|
import classNames from 'classnames';
|
|
|
|
|
import omit from 'rc-util/lib/omit';
|
|
|
|
|
|
|
|
|
|
import isNumeric from '../_util/isNumeric';
|
|
|
|
|
import { ConfigContext } from '../config-provider';
|
|
|
|
|
import { LayoutContext } from './context';
|
|
|
|
|
import useStyle from './style/sider';
|
|
|
|
@ -20,6 +19,8 @@ const dimensionMaxMap = {
|
|
|
|
|
xxl: '1599.98px',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const isNumeric = (value: any) => !Number.isNaN(Number.parseFloat(value)) && isFinite(value);
|
|
|
|
|
|
|
|
|
|
export interface SiderContextProps {
|
|
|
|
|
siderCollapsed?: boolean;
|
|
|
|
|
}
|
|
|
|
@ -152,74 +153,77 @@ const Sider = React.forwardRef<HTMLDivElement, SiderProps>((props, ref) => {
|
|
|
|
|
handleSetCollapsed(!collapsed, 'clickTrigger');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const renderSider = () => {
|
|
|
|
|
const divProps = omit(otherProps, ['collapsed']);
|
|
|
|
|
const rawWidth = collapsed ? collapsedWidth : width;
|
|
|
|
|
// use "px" as fallback unit for width
|
|
|
|
|
const siderWidth = isNumeric(rawWidth) ? `${rawWidth}px` : String(rawWidth);
|
|
|
|
|
// special trigger when collapsedWidth == 0
|
|
|
|
|
const zeroWidthTrigger =
|
|
|
|
|
parseFloat(String(collapsedWidth || 0)) === 0 ? (
|
|
|
|
|
<span
|
|
|
|
|
onClick={toggle}
|
|
|
|
|
className={classNames(
|
|
|
|
|
`${prefixCls}-zero-width-trigger`,
|
|
|
|
|
`${prefixCls}-zero-width-trigger-${reverseArrow ? 'right' : 'left'}`,
|
|
|
|
|
)}
|
|
|
|
|
style={zeroWidthTriggerStyle}
|
|
|
|
|
>
|
|
|
|
|
{trigger || <BarsOutlined />}
|
|
|
|
|
</span>
|
|
|
|
|
) : null;
|
|
|
|
|
const reverseIcon = (direction === 'rtl') === !reverseArrow;
|
|
|
|
|
const iconObj = {
|
|
|
|
|
expanded: reverseIcon ? <RightOutlined /> : <LeftOutlined />,
|
|
|
|
|
collapsed: reverseIcon ? <LeftOutlined /> : <RightOutlined />,
|
|
|
|
|
};
|
|
|
|
|
const status = collapsed ? 'collapsed' : 'expanded';
|
|
|
|
|
const defaultTrigger = iconObj[status];
|
|
|
|
|
const triggerDom =
|
|
|
|
|
trigger !== null
|
|
|
|
|
? zeroWidthTrigger || (
|
|
|
|
|
<div className={`${prefixCls}-trigger`} onClick={toggle} style={{ width: siderWidth }}>
|
|
|
|
|
{trigger || defaultTrigger}
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
: null;
|
|
|
|
|
|
|
|
|
|
const divStyle: React.CSSProperties = {
|
|
|
|
|
...style,
|
|
|
|
|
flex: `0 0 ${siderWidth}`,
|
|
|
|
|
maxWidth: siderWidth, // Fix width transition bug in IE11
|
|
|
|
|
minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349
|
|
|
|
|
width: siderWidth,
|
|
|
|
|
};
|
|
|
|
|
const divProps = omit(otherProps, ['collapsed']);
|
|
|
|
|
const rawWidth = collapsed ? collapsedWidth : width;
|
|
|
|
|
// use "px" as fallback unit for width
|
|
|
|
|
const siderWidth = isNumeric(rawWidth) ? `${rawWidth}px` : String(rawWidth);
|
|
|
|
|
// special trigger when collapsedWidth == 0
|
|
|
|
|
const zeroWidthTrigger =
|
|
|
|
|
parseFloat(String(collapsedWidth || 0)) === 0 ? (
|
|
|
|
|
<span
|
|
|
|
|
onClick={toggle}
|
|
|
|
|
className={classNames(
|
|
|
|
|
`${prefixCls}-zero-width-trigger`,
|
|
|
|
|
`${prefixCls}-zero-width-trigger-${reverseArrow ? 'right' : 'left'}`,
|
|
|
|
|
)}
|
|
|
|
|
style={zeroWidthTriggerStyle}
|
|
|
|
|
>
|
|
|
|
|
{trigger || <BarsOutlined />}
|
|
|
|
|
</span>
|
|
|
|
|
) : null;
|
|
|
|
|
|
|
|
|
|
const reverseIcon = (direction === 'rtl') === !reverseArrow;
|
|
|
|
|
|
|
|
|
|
const iconObj = {
|
|
|
|
|
expanded: reverseIcon ? <RightOutlined /> : <LeftOutlined />,
|
|
|
|
|
collapsed: reverseIcon ? <LeftOutlined /> : <RightOutlined />,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const siderCls = classNames(
|
|
|
|
|
prefixCls,
|
|
|
|
|
`${prefixCls}-${theme}`,
|
|
|
|
|
{
|
|
|
|
|
[`${prefixCls}-collapsed`]: !!collapsed,
|
|
|
|
|
[`${prefixCls}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger,
|
|
|
|
|
[`${prefixCls}-below`]: !!below,
|
|
|
|
|
[`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0,
|
|
|
|
|
},
|
|
|
|
|
className,
|
|
|
|
|
hashId,
|
|
|
|
|
cssVarCls,
|
|
|
|
|
);
|
|
|
|
|
return (
|
|
|
|
|
<aside className={siderCls} {...divProps} style={divStyle} ref={ref}>
|
|
|
|
|
<div className={`${prefixCls}-children`}>{children}</div>
|
|
|
|
|
{collapsible || (below && zeroWidthTrigger) ? triggerDom : null}
|
|
|
|
|
</aside>
|
|
|
|
|
);
|
|
|
|
|
const status = collapsed ? 'collapsed' : 'expanded';
|
|
|
|
|
const defaultTrigger = iconObj[status];
|
|
|
|
|
const triggerDom =
|
|
|
|
|
trigger !== null
|
|
|
|
|
? zeroWidthTrigger || (
|
|
|
|
|
<div className={`${prefixCls}-trigger`} onClick={toggle} style={{ width: siderWidth }}>
|
|
|
|
|
{trigger || defaultTrigger}
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
: null;
|
|
|
|
|
|
|
|
|
|
const divStyle: React.CSSProperties = {
|
|
|
|
|
...style,
|
|
|
|
|
flex: `0 0 ${siderWidth}`,
|
|
|
|
|
maxWidth: siderWidth, // Fix width transition bug in IE11
|
|
|
|
|
minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349
|
|
|
|
|
width: siderWidth,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const contextValue = React.useMemo(() => ({ siderCollapsed: collapsed }), [collapsed]);
|
|
|
|
|
const siderCls = classNames(
|
|
|
|
|
prefixCls,
|
|
|
|
|
`${prefixCls}-${theme}`,
|
|
|
|
|
{
|
|
|
|
|
[`${prefixCls}-collapsed`]: !!collapsed,
|
|
|
|
|
[`${prefixCls}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger,
|
|
|
|
|
[`${prefixCls}-below`]: !!below,
|
|
|
|
|
[`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0,
|
|
|
|
|
},
|
|
|
|
|
className,
|
|
|
|
|
hashId,
|
|
|
|
|
cssVarCls,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const contextValue = React.useMemo<SiderContextProps>(
|
|
|
|
|
() => ({ siderCollapsed: collapsed }),
|
|
|
|
|
[collapsed],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return wrapCSSVar(
|
|
|
|
|
<SiderContext.Provider value={contextValue}>{renderSider()}</SiderContext.Provider>,
|
|
|
|
|
<SiderContext.Provider value={contextValue}>
|
|
|
|
|
<aside className={siderCls} {...divProps} style={divStyle} ref={ref}>
|
|
|
|
|
<div className={`${prefixCls}-children`}>{children}</div>
|
|
|
|
|
{collapsible || (below && zeroWidthTrigger) ? triggerDom : null}
|
|
|
|
|
</aside>
|
|
|
|
|
</SiderContext.Provider>,
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|