mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-11-30 02:59:04 +08:00
refactor: collapse motion (#36597)
* chore: v5.0.0-experimental.5 * refactor: collapse motion
This commit is contained in:
parent
2449eaee5d
commit
357750e081
@ -12,8 +12,8 @@ const getCurrentHeight: MotionEventHandler = node => ({ height: node ? node.offs
|
||||
const skipOpacityTransition: MotionEndEventHandler = (_, event: MotionEvent) =>
|
||||
event?.deadline === true || (event as TransitionEvent).propertyName === 'height';
|
||||
|
||||
const collapseMotion: CSSMotionProps = {
|
||||
motionName: 'ant-motion-collapse',
|
||||
const initCollapseMotion = (rootCls: string = 'ant'): CSSMotionProps => ({
|
||||
motionName: `${rootCls}-motion-collapse`,
|
||||
onAppearStart: getCollapsedHeight,
|
||||
onEnterStart: getCollapsedHeight,
|
||||
onAppearActive: getRealHeight,
|
||||
@ -24,7 +24,7 @@ const collapseMotion: CSSMotionProps = {
|
||||
onEnterEnd: skipOpacityTransition,
|
||||
onLeaveEnd: skipOpacityTransition,
|
||||
motionDeadline: 500,
|
||||
};
|
||||
});
|
||||
|
||||
const SelectPlacements = tuple('bottomLeft', 'bottomRight', 'topLeft', 'topRight');
|
||||
export type SelectCommonPlacement = typeof SelectPlacements[number];
|
||||
@ -44,4 +44,4 @@ const getTransitionName = (rootPrefixCls: string, motion: string, transitionName
|
||||
};
|
||||
|
||||
export { getTransitionName, getTransitionDirection };
|
||||
export default collapseMotion;
|
||||
export default initCollapseMotion;
|
||||
|
@ -7,7 +7,7 @@ import * as React from 'react';
|
||||
import toArray from 'rc-util/lib/Children/toArray';
|
||||
import omit from 'rc-util/lib/omit';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import collapseMotion from '../_util/motion';
|
||||
import initCollapseMotion from '../_util/motion';
|
||||
import { cloneElement } from '../_util/reactNode';
|
||||
import warning from '../_util/warning';
|
||||
import type { CollapsibleType } from './CollapsePanel';
|
||||
@ -64,6 +64,7 @@ const Collapse: CollapseInterface = props => {
|
||||
expandIconPosition = 'start',
|
||||
} = props;
|
||||
const prefixCls = getPrefixCls('collapse', customizePrefixCls);
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
|
||||
// Warning if use legacy type `expandIconPosition`
|
||||
@ -107,7 +108,7 @@ const Collapse: CollapseInterface = props => {
|
||||
hashId,
|
||||
);
|
||||
const openMotion: CSSMotionProps = {
|
||||
...collapseMotion,
|
||||
...initCollapseMotion(rootPrefixCls),
|
||||
motionAppear: false,
|
||||
leavedClassName: `${prefixCls}-content-hidden`,
|
||||
};
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { genCollapseMotion } from '../../style/motion';
|
||||
import type { FullToken, GenerateStyle } from '../../theme';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme';
|
||||
import { resetComponent, resetIcon } from '../../style';
|
||||
@ -233,26 +234,6 @@ const genBorderlessStyle: GenerateStyle<CollapseToken> = token => {
|
||||
};
|
||||
};
|
||||
|
||||
const genMotion: GenerateStyle<CollapseToken> = token => ({
|
||||
[token.componentCls]: {
|
||||
// For common/openAnimation
|
||||
[`${token.antCls}-motion-collapse-legacy`]: {
|
||||
overflow: 'hidden',
|
||||
|
||||
'&-active': {
|
||||
transition: `height ${token.motionDurationMid} ${token.motionEaseInOut},
|
||||
opacity ${token.motionDurationMid} ${token.motionEaseInOut} !important`,
|
||||
},
|
||||
},
|
||||
|
||||
[`${token.antCls}-motion-collapse`]: {
|
||||
overflow: 'hidden',
|
||||
transition: `height ${token.motionDurationMid} ${token.motionEaseInOut},
|
||||
opacity ${token.motionDurationMid} ${token.motionEaseInOut} !important`,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default genComponentStyleHook('Collapse', token => {
|
||||
const collapseToken = mergeToken<CollapseToken>(token, {
|
||||
collapseContentBg: token.colorBgContainer,
|
||||
@ -266,6 +247,6 @@ export default genComponentStyleHook('Collapse', token => {
|
||||
genBaseStyle(collapseToken),
|
||||
genBorderlessStyle(collapseToken),
|
||||
genArrowStyle(collapseToken),
|
||||
genMotion(collapseToken),
|
||||
genCollapseMotion(collapseToken),
|
||||
];
|
||||
});
|
||||
|
@ -1,8 +1,9 @@
|
||||
import classNames from 'classnames';
|
||||
import CSSMotion, { CSSMotionList } from 'rc-motion';
|
||||
import * as React from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import collapseMotion from '../_util/motion';
|
||||
import initCollapseMotion from '../_util/motion';
|
||||
import { FormItemPrefixContext } from './context';
|
||||
import type { ValidateStatus } from './FormItem';
|
||||
import useDebounce from './hooks/useDebounce';
|
||||
@ -51,6 +52,8 @@ export default function ErrorList({
|
||||
const baseClassName = `${prefixCls}-item-explain`;
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
|
||||
const collapseMotion = useMemo(() => initCollapseMotion(rootPrefixCls), [rootPrefixCls]);
|
||||
|
||||
// We have to debounce here again since somewhere use ErrorList directly still need no shaking
|
||||
// ref: https://github.com/ant-design/ant-design/issues/36336
|
||||
const debounceErrors = useDebounce(errors);
|
||||
@ -71,6 +74,7 @@ export default function ErrorList({
|
||||
|
||||
return (
|
||||
<CSSMotion
|
||||
{...collapseMotion}
|
||||
motionDeadline={collapseMotion.motionDeadline}
|
||||
motionName={`${rootPrefixCls}-show-help`}
|
||||
visible={!!fullKeyList.length}
|
||||
@ -86,7 +90,7 @@ export default function ErrorList({
|
||||
>
|
||||
<CSSMotionList
|
||||
keys={fullKeyList}
|
||||
{...collapseMotion}
|
||||
{...initCollapseMotion(rootPrefixCls)}
|
||||
motionName={`${rootPrefixCls}-show-help-item`}
|
||||
component={false}
|
||||
>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
import { zoomIn } from '../../style/motion';
|
||||
import { genCollapseMotion, zoomIn } from '../../style/motion';
|
||||
import type { AliasToken, FullToken, GenerateStyle } from '../../theme';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme';
|
||||
import { resetComponent } from '../../style';
|
||||
@ -539,6 +539,7 @@ export default genComponentStyleHook('Form', (token, { rootPrefixCls }) => {
|
||||
genHorizontalStyle(formToken),
|
||||
genInlineStyle(formToken),
|
||||
genVerticalStyle(formToken),
|
||||
genCollapseMotion(formToken),
|
||||
zoomIn,
|
||||
];
|
||||
});
|
||||
|
@ -14,7 +14,7 @@ import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { fireEvent, render } from '../../../tests/utils';
|
||||
import Layout from '../../layout';
|
||||
import Tooltip from '../../tooltip';
|
||||
import collapseMotion from '../../_util/motion';
|
||||
import initCollapseMotion from '../../_util/motion';
|
||||
import { noop } from '../../_util/warning';
|
||||
|
||||
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
|
||||
@ -522,7 +522,7 @@ describe('Menu', () => {
|
||||
|
||||
it('inline menu collapseMotion should be triggered', async () => {
|
||||
const cloneMotion = {
|
||||
...collapseMotion,
|
||||
...initCollapseMotion(),
|
||||
motionDeadline: 1,
|
||||
};
|
||||
|
||||
|
@ -9,7 +9,7 @@ import { forwardRef } from 'react';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import type { SiderContextProps } from '../layout/Sider';
|
||||
import { SiderContext } from '../layout/Sider';
|
||||
import collapseMotion from '../_util/motion';
|
||||
import initCollapseMotion from '../_util/motion';
|
||||
import { cloneElement } from '../_util/reactNode';
|
||||
import warning from '../_util/warning';
|
||||
import type { ItemType } from './hooks/useItems';
|
||||
@ -122,7 +122,7 @@ const InternalMenu = forwardRef<MenuRef, InternalMenuProps>((props, ref) => {
|
||||
|
||||
const defaultMotions = {
|
||||
horizontal: { motionName: `${rootPrefixCls}-slide-up` },
|
||||
inline: collapseMotion,
|
||||
inline: initCollapseMotion(rootPrefixCls),
|
||||
other: { motionName: `${rootPrefixCls}-zoom-big` },
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { TinyColor } from '@ctrl/tinycolor';
|
||||
import { genCollapseMotion } from '../../style/motion';
|
||||
import type { FullToken, GenerateStyle, UseComponentStyleResult } from '../../theme';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme';
|
||||
import getHorizontalStyle from './horizontal';
|
||||
@ -487,6 +488,9 @@ export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResul
|
||||
|
||||
// RTL
|
||||
getRTLStyle(menuToken),
|
||||
|
||||
// Motion
|
||||
genCollapseMotion(menuToken),
|
||||
];
|
||||
},
|
||||
token => ({
|
||||
|
24
components/style/motion/collapse.tsx
Normal file
24
components/style/motion/collapse.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import type { AliasToken, GenerateStyle } from '../../theme';
|
||||
import type { TokenWithCommonCls } from '../../theme/util/genComponentStyleHook';
|
||||
|
||||
const genCollapseMotion: GenerateStyle<TokenWithCommonCls<AliasToken>> = token => ({
|
||||
[token.componentCls]: {
|
||||
// For common/openAnimation
|
||||
[`${token.antCls}-motion-collapse-legacy`]: {
|
||||
overflow: 'hidden',
|
||||
|
||||
'&-active': {
|
||||
transition: `height ${token.motionDurationMid} ${token.motionEaseInOut},
|
||||
opacity ${token.motionDurationMid} ${token.motionEaseInOut} !important`,
|
||||
},
|
||||
},
|
||||
|
||||
[`${token.antCls}-motion-collapse`]: {
|
||||
overflow: 'hidden',
|
||||
transition: `height ${token.motionDurationMid} ${token.motionEaseInOut},
|
||||
opacity ${token.motionDurationMid} ${token.motionEaseInOut} !important`,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default genCollapseMotion;
|
@ -36,6 +36,7 @@ import {
|
||||
zoomUpIn,
|
||||
zoomUpOut,
|
||||
} from './zoom';
|
||||
import genCollapseMotion from './collapse';
|
||||
|
||||
export {
|
||||
initSlideMotion,
|
||||
@ -72,4 +73,5 @@ export {
|
||||
moveUpIn,
|
||||
moveUpOut,
|
||||
initMoveMotion,
|
||||
genCollapseMotion,
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ import RcTree, { TreeNode } from 'rc-tree';
|
||||
import type { DataNode, Key } from 'rc-tree/lib/interface';
|
||||
import * as React from 'react';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import collapseMotion from '../_util/motion';
|
||||
import initCollapseMotion from '../_util/motion';
|
||||
import DirectoryTree from './DirectoryTree';
|
||||
import dropIndicatorRender from './utils/dropIndicator';
|
||||
import renderSwitcherIcon from './utils/iconUtil';
|
||||
@ -175,10 +175,19 @@ const Tree = React.forwardRef<RcTree, TreeProps>((props, ref) => {
|
||||
checkable,
|
||||
selectable,
|
||||
draggable,
|
||||
motion: customMotion,
|
||||
} = props;
|
||||
const prefixCls = getPrefixCls('tree', customizePrefixCls);
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
|
||||
const motion = customMotion ?? {
|
||||
...initCollapseMotion(rootPrefixCls),
|
||||
motionAppear: false,
|
||||
};
|
||||
|
||||
const newProps = {
|
||||
...props,
|
||||
motion,
|
||||
showLine: Boolean(showLine),
|
||||
dropIndicatorRender,
|
||||
};
|
||||
@ -249,10 +258,6 @@ Tree.defaultProps = {
|
||||
checkable: false,
|
||||
selectable: true,
|
||||
showIcon: false,
|
||||
motion: {
|
||||
...collapseMotion,
|
||||
motionAppear: false,
|
||||
},
|
||||
blockNode: false,
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// deps-lint-skip-all
|
||||
import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
|
||||
import { Keyframes } from '@ant-design/cssinjs';
|
||||
import { genCollapseMotion } from '../../style/motion';
|
||||
import { getStyle as getCheckboxStyle } from '../../checkbox/style';
|
||||
import type { DerivativeToken } from '../../theme';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme';
|
||||
@ -477,4 +477,5 @@ export default genComponentStyleHook('Tree', (token, { prefixCls }) => [
|
||||
[token.componentCls]: getCheckboxStyle(`${prefixCls}-checkbox`, token),
|
||||
},
|
||||
genTreeStyle(prefixCls, token),
|
||||
genCollapseMotion(token),
|
||||
]);
|
||||
|
@ -6,24 +6,17 @@ import classNames from 'classnames';
|
||||
import type { CSSMotionListProps } from 'rc-motion';
|
||||
import CSSMotion, { CSSMotionList } from 'rc-motion';
|
||||
import * as React from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import type { ButtonProps } from '../../button';
|
||||
import Button from '../../button';
|
||||
import { ConfigContext } from '../../config-provider';
|
||||
import useForceUpdate from '../../_util/hooks/useForceUpdate';
|
||||
import collapseMotion from '../../_util/motion';
|
||||
import initCollapseMotion from '../../_util/motion';
|
||||
import { cloneElement, isValidElement } from '../../_util/reactNode';
|
||||
import type { InternalUploadFile, UploadFile, UploadListProps, UploadListType } from '../interface';
|
||||
import { isImageUrl, previewImage } from '../utils';
|
||||
import ListItem from './ListItem';
|
||||
|
||||
const listItemMotion: Partial<CSSMotionListProps> = {
|
||||
...collapseMotion,
|
||||
};
|
||||
|
||||
delete listItemMotion.onAppearEnd;
|
||||
delete listItemMotion.onEnterEnd;
|
||||
delete listItemMotion.onLeaveEnd;
|
||||
|
||||
const InternalUploadList: React.ForwardRefRenderFunction<unknown, UploadListProps> = (
|
||||
{
|
||||
listType,
|
||||
@ -163,6 +156,7 @@ const InternalUploadList: React.ForwardRefRenderFunction<unknown, UploadListProp
|
||||
|
||||
// ============================= Render =============================
|
||||
const prefixCls = getPrefixCls('upload', customizePrefixCls);
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
|
||||
const listClassNames = classNames({
|
||||
[`${prefixCls}-list`]: true,
|
||||
@ -187,6 +181,18 @@ const InternalUploadList: React.ForwardRefRenderFunction<unknown, UploadListProp
|
||||
motionAppear,
|
||||
};
|
||||
|
||||
const listItemMotion: Partial<CSSMotionListProps> = useMemo(() => {
|
||||
const motion = {
|
||||
...initCollapseMotion(rootPrefixCls),
|
||||
};
|
||||
|
||||
delete motion.onAppearEnd;
|
||||
delete motion.onEnterEnd;
|
||||
delete motion.onLeaveEnd;
|
||||
|
||||
return motion;
|
||||
}, [rootPrefixCls]);
|
||||
|
||||
if (listType !== 'picture-card') {
|
||||
motionConfig = {
|
||||
...listItemMotion,
|
||||
|
@ -6,6 +6,7 @@ import genMotionStyle from './motion';
|
||||
import { genPictureCardStyle, genPictureStyle } from './picture';
|
||||
import genRtlStyle from './rtl';
|
||||
import { resetComponent } from '../../style';
|
||||
import { genCollapseMotion } from '../../style/motion';
|
||||
|
||||
export interface ComponentToken {}
|
||||
|
||||
@ -60,5 +61,6 @@ export default genComponentStyleHook('Upload', token => {
|
||||
genListStyle(uploadToken),
|
||||
genMotionStyle(uploadToken),
|
||||
genRtlStyle(uploadToken),
|
||||
genCollapseMotion(uploadToken),
|
||||
];
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user