From 3cfdc2ea0f0c22662112d161b13a82cd16aac6b1 Mon Sep 17 00:00:00 2001 From: ivliu Date: Mon, 17 Mar 2025 22:07:51 +0800 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84collapse?= =?UTF-8?q?=E4=B8=BAdetails=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + src/Collapse.tsx | 23 +++++++++++++---------- src/Panel.tsx | 10 +++++----- src/interface.ts | 6 +++--- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 2623981..e1c3a36 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ coverage es yarn.lock package-lock.json +pnpm-lock.yaml .storybook .doc diff --git a/src/Collapse.tsx b/src/Collapse.tsx index e75ec5f..ce650f5 100644 --- a/src/Collapse.tsx +++ b/src/Collapse.tsx @@ -46,18 +46,21 @@ const Collapse = React.forwardRef((props, ref) => }); const onItemClick = (key: React.Key) => - setActiveKey(() => { - if (accordion) { - return activeKey[0] === key ? [] : [key]; - } + // ? 为了解决https://github.com/facebook/react/issues/15486 + React.startTransition(() => { + setActiveKey(() => { + if (accordion) { + return activeKey[0] === key ? [] : [key]; + } - const index = activeKey.indexOf(key); - const isActive = index > -1; - if (isActive) { - return activeKey.filter((item) => item !== key); - } + const index = activeKey.indexOf(key); + const isActive = index > -1; + if (isActive) { + return activeKey.filter((item) => item !== key); + } - return [...activeKey, key]; + return [...activeKey, key]; + }); }); // ======================== Children ======================== diff --git a/src/Panel.tsx b/src/Panel.tsx index c463325..948e293 100644 --- a/src/Panel.tsx +++ b/src/Panel.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type { CollapsePanelProps } from './interface'; import PanelContent from './PanelContent'; -const CollapsePanel = React.forwardRef((props, ref) => { +const CollapsePanel = React.forwardRef((props, ref) => { const { showArrow = true, headerClass, @@ -87,8 +87,8 @@ const CollapsePanel = React.forwardRef((prop // ======================== Render ======================== return ( -
-
+
+ {showArrow && iconNode} ((prop {header} {ifExtraExist &&
{extra}
} -
+ ((prop ); }} -
+ ); }); diff --git a/src/interface.ts b/src/interface.ts index 123c793..d4a6d2b 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -16,7 +16,7 @@ export interface ItemType > { key?: CollapsePanelProps['panelKey']; label?: CollapsePanelProps['header']; - ref?: React.RefObject; + ref?: React.RefObject; } export interface CollapseProps { @@ -42,7 +42,7 @@ export interface CollapseProps { } export type SemanticName = 'header' | 'title' | 'body' | 'icon'; -export interface CollapsePanelProps extends React.DOMAttributes { +export interface CollapsePanelProps extends React.DOMAttributes { id?: string; header?: string | React.ReactNode; prefixCls?: string; @@ -50,7 +50,7 @@ export interface CollapsePanelProps extends React.DOMAttributes showArrow?: boolean; className?: string; classNames?: Partial>; - style?: object; + style?: React.CSSProperties; styles?: Partial>; isActive?: boolean; openMotion?: CSSMotionProps; From 5ffc99aa27027a959c61695c4e1dca67a33fc5fc Mon Sep 17 00:00:00 2001 From: ivliu Date: Tue, 18 Mar 2025 10:51:22 +0800 Subject: [PATCH 02/11] =?UTF-8?q?fix:=20=E7=94=A8=E4=BE=8B=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Panel.tsx | 2 +- tests/__snapshots__/index.spec.tsx.snap | 32 ++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Panel.tsx b/src/Panel.tsx index 948e293..b4f285d 100644 --- a/src/Panel.tsx +++ b/src/Panel.tsx @@ -79,7 +79,7 @@ const CollapsePanel = React.forwardRef(( ); // ======================== HeaderProps ======================== - const headerProps: React.HTMLAttributes = { + const headerProps: React.HTMLAttributes = { className: headerClassName, style: styles?.header, ...(['header', 'icon'].includes(collapsible) ? {} : collapsibleProps), diff --git a/tests/__snapshots__/index.spec.tsx.snap b/tests/__snapshots__/index.spec.tsx.snap index 8e1a456..4742571 100644 --- a/tests/__snapshots__/index.spec.tsx.snap +++ b/tests/__snapshots__/index.spec.tsx.snap @@ -4,10 +4,10 @@ exports[`collapse props items should work with nested 1`] = `
-
- -
-
+ +
- -
-
-
+ +
- -
-
+ +
- -
+ + `; From df7f09ee8fbc6a50d9b4cef0588ba2e00218d13a Mon Sep 17 00:00:00 2001 From: ivliu Date: Wed, 19 Mar 2025 11:50:55 +0800 Subject: [PATCH 03/11] =?UTF-8?q?fix:=20=E8=A1=A5=E5=85=A8=E7=BC=BA?= =?UTF-8?q?=E5=A4=B1=E7=9A=84=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index b349b40..0c5e665 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ }, "devDependencies": { "@rc-component/father-plugin": "^2.0.1", + "@rc-component/np": "^1.0.3", "@testing-library/jest-dom": "^6.1.4", "@testing-library/react": "^14.1.2", "@testing-library/user-event": "^14.5.2", From ce3ba4c8992250a3135c686a3a571ba9a87bdf90 Mon Sep 17 00:00:00 2001 From: ivliu Date: Wed, 19 Mar 2025 15:32:43 +0800 Subject: [PATCH 04/11] =?UTF-8?q?feat:=20=E9=98=BB=E6=AD=A2onItemClick?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=86=92=E6=B3=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Panel.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Panel.tsx b/src/Panel.tsx index b4f285d..f74908a 100644 --- a/src/Panel.tsx +++ b/src/Panel.tsx @@ -33,8 +33,9 @@ const CollapsePanel = React.forwardRef(( const ifExtraExist = extra !== null && extra !== undefined && typeof extra !== 'boolean'; const collapsibleProps = { - onClick: () => { + onClick: (e: React.MouseEvent) => { onItemClick?.(panelKey); + e.stopPropagation(); }, onKeyDown: (e: React.KeyboardEvent) => { if (e.key === 'Enter' || e.keyCode === KeyCode.ENTER || e.which === KeyCode.ENTER) { From ff26366ca3478d6a48bc03bd5e2a92122800f7ee Mon Sep 17 00:00:00 2001 From: ivliu Date: Sat, 10 May 2025 11:18:03 +0800 Subject: [PATCH 05/11] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E5=8A=A8?= =?UTF-8?q?=E7=94=BB=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/index.less | 14 +++++++ src/Collapse.tsx | 3 +- src/Panel.tsx | 101 ++++++++++++++++++++++++++++++++++------------ 3 files changed, 91 insertions(+), 27 deletions(-) diff --git a/assets/index.less b/assets/index.less index 4093e0f..f4e956f 100644 --- a/assets/index.less +++ b/assets/index.less @@ -35,6 +35,20 @@ & > &-item { border-top: @borderStyle; + list-style-position: outside; + interpolate-size: allow-keywords; + overflow: hidden; + + &::details-content { + block-size: 0; + transition: block-size 0.6s, content-visibility 0.6s; + transition-behavior: allow-discrete; + } + + &[open]::details-content { + block-size: auto; + } + &:first-child { border-top: none; } diff --git a/src/Collapse.tsx b/src/Collapse.tsx index ce650f5..6df8e44 100644 --- a/src/Collapse.tsx +++ b/src/Collapse.tsx @@ -46,7 +46,8 @@ const Collapse = React.forwardRef((props, ref) => }); const onItemClick = (key: React.Key) => - // ? 为了解决https://github.com/facebook/react/issues/15486 + // ? 用于解决react状态与details[open]状态不一致的问题 + // ? 具体参考issue https://github.com/facebook/react/issues/15486 React.startTransition(() => { setActiveKey(() => { if (accordion) { diff --git a/src/Panel.tsx b/src/Panel.tsx index f74908a..9b58606 100644 --- a/src/Panel.tsx +++ b/src/Panel.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames'; import CSSMotion from 'rc-motion'; import KeyCode from '@rc-component/util/lib/KeyCode'; -import React from 'react'; +import React, { useMemo } from 'react'; import type { CollapsePanelProps } from './interface'; import PanelContent from './PanelContent'; @@ -32,6 +32,15 @@ const CollapsePanel = React.forwardRef(( const ifExtraExist = extra !== null && extra !== undefined && typeof extra !== 'boolean'; + // ? 用于判断浏览器是否支持::details-content 否则使用CSSMotion + const supportsDetailsContentSelector = useMemo( + () => + typeof document !== 'undefined' && typeof document.createElement === 'function' + ? CSS.supports('selector(details::details-content)') + : false, + [], + ); + const collapsibleProps = { onClick: (e: React.MouseEvent) => { onItemClick?.(panelKey); @@ -68,6 +77,8 @@ const CollapsePanel = React.forwardRef(( [`${prefixCls}-item-disabled`]: disabled, }, className, + // ? 修改为details实现后动画是作用在details元素上 需要将motionName设置在details上 + supportsDetailsContentSelector && openMotion?.motionName, ); const headerClassName = classNames( @@ -87,6 +98,68 @@ const CollapsePanel = React.forwardRef(( }; // ======================== Render ======================== + + const leavedClassName = `${prefixCls}-panel-hidden`; + const createPanelContent = ( + props: Partial<{ + className: string; + style: React.CSSProperties; + motionRef: (node: HTMLDivElement) => void; + }>, + ) => { + const { className, style, motionRef } = props; + + return ( + + {children} + + ); + }; + let detailsChildren = ( + + {({ className, style }, motionRef) => + createPanelContent({ + className, + style, + motionRef, + }) + } + + ); + + // ? 模拟CSSMotion子元素生命周期管理 + if (supportsDetailsContentSelector) { + if (isActive) { + detailsChildren = createPanelContent({}); + } else if (!destroyInactivePanel && leavedClassName) { + detailsChildren = createPanelContent({ + className: leavedClassName, + }); + } else if (forceRender || (!destroyInactivePanel && !leavedClassName)) { + detailsChildren = createPanelContent({ + style: { display: 'none' }, + }); + } else { + detailsChildren = null; + } + } + return (
@@ -100,31 +173,7 @@ const CollapsePanel = React.forwardRef(( {ifExtraExist &&
{extra}
}
- - {({ className: motionClassName, style: motionStyle }, motionRef) => { - return ( - - {children} - - ); - }} - + {detailsChildren}
); }); From 925207f4b3d28d8523b28649756d119299d05b0b Mon Sep 17 00:00:00 2001 From: ivliu Date: Sat, 10 May 2025 11:51:21 +0800 Subject: [PATCH 06/11] =?UTF-8?q?feat:=20=E5=B0=86useEffect=E4=B8=AD?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E8=AE=BE=E7=BD=AE=E6=94=B9=E4=B8=BA=E6=B4=BE?= =?UTF-8?q?=E7=94=9F=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PanelContent.tsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/PanelContent.tsx b/src/PanelContent.tsx index e5fc2fc..800e292 100644 --- a/src/PanelContent.tsx +++ b/src/PanelContent.tsx @@ -18,13 +18,7 @@ const PanelContent = React.forwardRef< styles, } = props; - const [rendered, setRendered] = React.useState(isActive || forceRender); - - React.useEffect(() => { - if (forceRender || isActive) { - setRendered(true); - } - }, [forceRender, isActive]); + const rendered = isActive || forceRender; if (!rendered) { return null; From a834f4119b5749fca1f1d7701abad2f5d270b034 Mon Sep 17 00:00:00 2001 From: ivliu Date: Fri, 13 Jun 2025 22:39:31 +0800 Subject: [PATCH 07/11] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81view=20transiti?= =?UTF-8?q?on=E8=BF=87=E6=B8=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/index.less | 5 +++++ src/Collapse.tsx | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/assets/index.less b/assets/index.less index f4e956f..59f57a3 100644 --- a/assets/index.less +++ b/assets/index.less @@ -4,6 +4,11 @@ @import './motion.less'; +// ::view-transition-old(root), /* 旧视图*/ +// ::view-transition-new(root) { /* 新视图*/ +// animation-duration: 0.6s; +// } + #arrow { .common() { width: 0; diff --git a/src/Collapse.tsx b/src/Collapse.tsx index 2229cab..705fd49 100644 --- a/src/Collapse.tsx +++ b/src/Collapse.tsx @@ -77,7 +77,10 @@ const Collapse = React.forwardRef((props, ref) => expandIcon, collapsible, destroyOnHidden, - onItemClick, + onItemClick: + 'startViewTransition' in document && typeof React.startTransition === 'function' + ? (key: React.Key) => document.startViewTransition(() => onItemClick(key)) + : onItemClick, activeKey, classNames: customizeClassNames, styles, From 60430c744f38cfcc62f2765bb092046568e7446f Mon Sep 17 00:00:00 2001 From: ivliu Date: Fri, 13 Jun 2025 22:52:48 +0800 Subject: [PATCH 08/11] =?UTF-8?q?feat:=20=E9=98=BB=E6=AD=A2=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E8=A1=8C=E4=B8=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Collapse.tsx | 2 +- src/Panel.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Collapse.tsx b/src/Collapse.tsx index 705fd49..b33c386 100644 --- a/src/Collapse.tsx +++ b/src/Collapse.tsx @@ -79,7 +79,7 @@ const Collapse = React.forwardRef((props, ref) => destroyOnHidden, onItemClick: 'startViewTransition' in document && typeof React.startTransition === 'function' - ? (key: React.Key) => document.startViewTransition(() => onItemClick(key)) + ? (key) => document.startViewTransition(() => onItemClick(key)) : onItemClick, activeKey, classNames: customizeClassNames, diff --git a/src/Panel.tsx b/src/Panel.tsx index 1ff77e3..90f94c1 100644 --- a/src/Panel.tsx +++ b/src/Panel.tsx @@ -34,6 +34,7 @@ const CollapsePanel = React.forwardRef(( const collapsibleProps = { onClick: (e: React.MouseEvent) => { onItemClick?.(panelKey); + e.preventDefault(); e.stopPropagation(); }, onKeyDown: (e: React.KeyboardEvent) => { From 4ddcf523321c1edfcce36410b27cb8918ae77120 Mon Sep 17 00:00:00 2001 From: ivliu Date: Sat, 14 Jun 2025 17:46:31 +0800 Subject: [PATCH 09/11] =?UTF-8?q?feat:=20=E7=A7=BB=E9=99=A4startTransition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Collapse.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Collapse.tsx b/src/Collapse.tsx index b33c386..2229cab 100644 --- a/src/Collapse.tsx +++ b/src/Collapse.tsx @@ -77,10 +77,7 @@ const Collapse = React.forwardRef((props, ref) => expandIcon, collapsible, destroyOnHidden, - onItemClick: - 'startViewTransition' in document && typeof React.startTransition === 'function' - ? (key) => document.startViewTransition(() => onItemClick(key)) - : onItemClick, + onItemClick, activeKey, classNames: customizeClassNames, styles, From dba7f6407f2ef6cd8342e72a0b45eac8ba675812 Mon Sep 17 00:00:00 2001 From: ivliu Date: Mon, 16 Jun 2025 20:28:10 +0800 Subject: [PATCH 10/11] =?UTF-8?q?feat:=20=E6=81=A2=E5=A4=8DCSSMotion?= =?UTF-8?q?=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/examples/_util/motionUtil.ts | 2 +- src/Panel.tsx | 34 ++++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/docs/examples/_util/motionUtil.ts b/docs/examples/_util/motionUtil.ts index 7163efe..0d986c9 100644 --- a/docs/examples/_util/motionUtil.ts +++ b/docs/examples/_util/motionUtil.ts @@ -6,7 +6,7 @@ import type { const getCollapsedHeight: MotionEventHandler = () => ({ height: 0, opacity: 0 }); const getRealHeight: MotionEventHandler = (node) => ({ height: node.scrollHeight, opacity: 1 }); -const getCurrentHeight: MotionEventHandler = (node) => ({ height: node.offsetHeight }); +const getCurrentHeight: MotionEventHandler = (node) => ({ height: node?.offsetHeight ?? 0 }); const skipOpacityTransition: MotionEndEventHandler = (_, event) => (event as TransitionEvent).propertyName === 'height'; diff --git a/src/Panel.tsx b/src/Panel.tsx index 90f94c1..8894c5c 100644 --- a/src/Panel.tsx +++ b/src/Panel.tsx @@ -1,5 +1,6 @@ import classNames from 'classnames'; import KeyCode from '@rc-component/util/lib/KeyCode'; +import CSSMotion from '@rc-component/motion'; import React from 'react'; import type { CollapsePanelProps } from './interface'; import PanelContent from './PanelContent'; @@ -68,8 +69,6 @@ const CollapsePanel = React.forwardRef(( [`${prefixCls}-item-disabled`]: disabled, }, className, - // ? 修改为details实现后动画是作用在details元素上 需要将motionName设置在details上 - openMotion?.motionName, ); const headerClassName = classNames( @@ -102,16 +101,31 @@ const CollapsePanel = React.forwardRef(( {ifExtraExist &&
{extra}
} - - {children} - + {({ className: motionClassName, style: motionStyle }, motionRef) => { + return ( + + {children} + + ); + }} + ); }); From 5ed08070bd13a45b79ad3fc75e40d91bc3e848ad Mon Sep 17 00:00:00 2001 From: ivliu Date: Mon, 16 Jun 2025 20:42:43 +0800 Subject: [PATCH 11/11] =?UTF-8?q?feat:=20=E6=81=A2=E5=A4=8DPanelContent=20?= =?UTF-8?q?style=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PanelContent.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/PanelContent.tsx b/src/PanelContent.tsx index d5c39b2..9f08e53 100644 --- a/src/PanelContent.tsx +++ b/src/PanelContent.tsx @@ -35,10 +35,7 @@ const PanelContent = React.forwardRef< }, className, )} - style={{ - display: isActive ? 'block' : 'none', - ...style, - }} + style={style} role={role} >