-
Notifications
You must be signed in to change notification settings - Fork 140
refactor: 重构collapse为details实现 #362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
3cfdc2e
5ffc99a
df7f09e
ce3ba4c
ff26366
925207f
5026c13
9f5873f
a834f41
3bd0abf
60430c7
4ddcf52
dba7f64
5ed0807
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,11 @@ | |||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @import './motion.less'; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // ::view-transition-old(root), /* 旧视图*/ | ||||||||||||||||||||||||||||||
| // ::view-transition-new(root) { /* 新视图*/ | ||||||||||||||||||||||||||||||
| // animation-duration: 0.6s; | ||||||||||||||||||||||||||||||
| // } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| #arrow { | ||||||||||||||||||||||||||||||
| .common() { | ||||||||||||||||||||||||||||||
| width: 0; | ||||||||||||||||||||||||||||||
|
|
@@ -35,6 +40,20 @@ | |||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| & > &-item { | ||||||||||||||||||||||||||||||
| border-top: @borderStyle; | ||||||||||||||||||||||||||||||
| list-style-position: outside; | ||||||||||||||||||||||||||||||
| interpolate-size: allow-keywords; | ||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://developer.mozilla.org/en-US/docs/Web/CSS/interpolate-size#browser_compatibility 浏览器兼容性有点差,这个会没办法在 antd 中使用。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
有什么好建议吗 |
||||||||||||||||||||||||||||||
| overflow: hidden; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| &::details-content { | ||||||||||||||||||||||||||||||
| block-size: 0; | ||||||||||||||||||||||||||||||
| transition: block-size 0.6s, content-visibility 0.6s; | ||||||||||||||||||||||||||||||
| transition-behavior: allow-discrete; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| &[open]::details-content { | ||||||||||||||||||||||||||||||
|
Comment on lines
+47
to
+53
|
||||||||||||||||||||||||||||||
| &::details-content { | |
| block-size: 0; | |
| transition: block-size 0.6s, content-visibility 0.6s; | |
| transition-behavior: allow-discrete; | |
| } | |
| &[open]::details-content { | |
| > .rc-collapse-content { | |
| block-size: 0; | |
| transition: block-size 0.6s, content-visibility 0.6s; | |
| transition-behavior: allow-discrete; | |
| } | |
| &[open] > .rc-collapse-content { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
使用现代CSS特性实现动画过渡
代码引入了一些新的CSS特性来实现基于<details>元素的动画效果:
interpolate-size: allow-keywords;允许在尺寸关键词(如auto)和具体值之间进行插值动画::details-content伪元素选择器用于直接控制details内容区域的样式和动画- 使用
transition-behavior: allow-discrete;支持离散过渡效果
这些CSS特性是比较新的,需要注意浏览器兼容性问题。与Panel.tsx中的特性检测(CSS.supports('selector(details::details-content)'))相配合,可以实现渐进增强的用户体验。
建议添加一些注释说明这些属性的浏览器兼容性要求,或考虑为不支持这些特性的浏览器提供兼容性样式。
🤖 Prompt for AI Agents (early access)
In assets/index.less around lines 38 to 50, the CSS uses modern features like
interpolate-size, ::details-content, and transition-behavior which have limited
browser support. Add comments explaining the browser compatibility requirements
for these properties and consider adding fallback styles or alternative
approaches for browsers that do not support these features to ensure graceful
degradation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
兼容性如何?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
兼容性如何?
这只是demo实现,ant实现上考虑下css兼容吧
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
有方案么,最好提前考虑起来。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
有方案么,最好提前考虑起来。
- 兼容
::detail-content的情况使用Panel的className编写动画,openMotion.motionName传入一个空实现 - 不兼容
::detail-content的情况则使用openMotion.motionName编写动画
你看下是不是可行,::detail-content兼容性确实比较差
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我尝试引入startTransition,编译报错,需要升级哪里吗?
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -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 }); | ||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 可选链可能触发 TS18048 编译错误
建议两种修复思路,任选其一:
-const getCurrentHeight: MotionEventHandler = (node) => ({ height: node?.offsetHeight ?? 0 });
+const getCurrentHeight: MotionEventHandler = (node) => ({ height: node ? node.offsetHeight : 0 });
-const getCurrentHeight: MotionEventHandler = (node) => ({ height: node?.offsetHeight ?? 0 });
+const getCurrentHeight: MotionEventHandler = (node?: HTMLElement | null) => ({
+ height: node?.offsetHeight ?? 0,
+});请根据实际调用情况选择,以确保通过 CI 并避免隐藏的空值问题。 📝 Committable suggestion
Suggested change
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| const skipOpacityTransition: MotionEndEventHandler = (_, event) => | ||||||||||||||||||||||
| (event as TransitionEvent).propertyName === 'height'; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,11 +1,11 @@ | ||||||
| import classNames from 'classnames'; | ||||||
| import CSSMotion from '@rc-component/motion'; | ||||||
| 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'; | ||||||
|
|
||||||
| const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((props, ref) => { | ||||||
| const CollapsePanel = React.forwardRef<HTMLDetailsElement, CollapsePanelProps>((props, ref) => { | ||||||
| const { | ||||||
| showArrow = true, | ||||||
| headerClass, | ||||||
|
|
@@ -33,8 +33,10 @@ const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((prop | |||||
| const ifExtraExist = extra !== null && extra !== undefined && typeof extra !== 'boolean'; | ||||||
|
|
||||||
| const collapsibleProps = { | ||||||
| onClick: () => { | ||||||
| onClick: (e: React.MouseEvent) => { | ||||||
| onItemClick?.(panelKey); | ||||||
| e.preventDefault(); | ||||||
| e.stopPropagation(); | ||||||
| }, | ||||||
| onKeyDown: (e: React.KeyboardEvent) => { | ||||||
| if (e.key === 'Enter' || e.keyCode === KeyCode.ENTER || e.which === KeyCode.ENTER) { | ||||||
|
|
@@ -79,16 +81,16 @@ const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((prop | |||||
| ); | ||||||
|
|
||||||
| // ======================== HeaderProps ======================== | ||||||
| const headerProps: React.HTMLAttributes<HTMLDivElement> = { | ||||||
| const headerProps: React.HTMLAttributes<HTMLElement> = { | ||||||
|
||||||
| const headerProps: React.HTMLAttributes<HTMLElement> = { | |
| const headerProps: React.HTMLAttributes<HTMLSummaryElement> = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] This commented-out view-transition snippet appears stale. Removing or relocating it behind a feature flag will keep the stylesheet clearer.