diff --git a/CHANGELOG.md b/CHANGELOG.md index 4686076bd0..eacac1178a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - 新增 `f-dialog` 组件 `mask-background` `mask-opacity` `show-header` 配置项 - 新增 `f-drawer` 组件 `mask-background` `mask-opacity` `show-header` 配置项 - 修复 `f-up-load` 继续多选重置之前文件的问题 +- 修复 `f-collapse-animation` 组件初始展开关闭时动画失效的问题 ## 0.41.0 (2023-06-04) diff --git a/packages/fighting-design/_hooks/index.ts b/packages/fighting-design/_hooks/index.ts index 2ec3632a5c..d070f21bd8 100644 --- a/packages/fighting-design/_hooks/index.ts +++ b/packages/fighting-design/_hooks/index.ts @@ -28,3 +28,4 @@ export * from './use-count-down' export * from './use-trigger' export * from './use-form-check' export * from './use-transition' +export * from './use-collapse-animation' diff --git a/packages/fighting-design/_hooks/use-collapse-animation/index.ts b/packages/fighting-design/_hooks/use-collapse-animation/index.ts new file mode 100644 index 0000000000..4104f8b471 --- /dev/null +++ b/packages/fighting-design/_hooks/use-collapse-animation/index.ts @@ -0,0 +1,126 @@ +import { computed } from 'vue' +import { isNumber } from '../../_utils' +import { useRun } from '..' +import type { CollapseAnimationProps } from '../../collapse-animation' + +export interface UseCollapseAnimationReturn { + after: (el: Element) => void + before: (el: Element) => void + ing: (el: Element) => void +} + +const { run } = useRun() + +export const useCollapseAnimation = (prop: CollapseAnimationProps): UseCollapseAnimationReturn => { + /** 动画样式 */ + const transitionStyle = computed((): string => { + if (isNumber(prop.animationTime)) { + return `${prop.animationTime}s all ease-in-out` + } + return '0.747s all ease-in-out' + }) + + /** + * 在动画开始之前,加点样式 + * + * @param { Object } el 元素节点 + */ + const before = (el: Element): void => { + const node = el as HTMLElement + + node.style.transition = transitionStyle.value + node.style.width = 'auto' + + if (prop.opened) { + node.style.height = '0' + + run(prop.onOpen, el) + + } else { + node.style.height = node.scrollHeight + 'px' + + if (prop.widthAnimation) { + /** 获取父节点 */ + const parent = node.parentElement as HTMLElement + /** + * 获取父节点的宽度 + * + * @see HTMLElement.offsetWidth https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/offsetWidth + * @see Element.clientWidth https://developer.mozilla.org/zh-CN/docs/Web/API/Element/clientWidth + */ + const parentWidth: number = parent.offsetWidth || parent.clientWidth + + node.style.width = `${parentWidth}px` + } + + run(prop.onClose, el) + } + } + + /** + * 在打开和关闭完成之后,移除样式 + * + * @param { Object } el 元素节点 + */ + const after = (el: Element): void => { + const node = el as HTMLElement + + node.style.transition = '' + node.style.height = '' + node.style.width = '' + + if (prop.opened) { + run(prop.onOpenEnd, el) + + } else { + run(prop.onCloseEnd, el) + } + } + + /** + * 运动过程中干点事儿 + * + * @param { Object } el 元素节点 + */ + const ing = (el: Element): void => { + const node = el as HTMLElement + + node.style.overflow = 'hidden' + + if (prop.opened) { + /** 开启执行 */ + node.style.height = node.scrollHeight + 'px' + + /** 如果需要宽度过度 */ + if (prop.widthAnimation) { + node.style.width = '0' + + /** 获取父节点 */ + const parent = node.parentElement as HTMLElement + /** + * 获取父节点的宽度 + * + * @see HTMLElement.offsetWidth https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/offsetWidth + * @see Element.clientWidth https://developer.mozilla.org/zh-CN/docs/Web/API/Element/clientWidth + */ + const parentWidth: number = parent.offsetWidth || parent.clientWidth + + /** 如果两个方法都没有获取到宽度,使用 auto */ + node.style.width = isNumber(parentWidth) ? `${parentWidth}px` : 'auto' + } + } else { + /** 关闭执行 */ + node.style.height = '0' + + if (prop.widthAnimation) { + node.style.width = '0' + } + } + } + + return { + after, + before, + ing + } +} diff --git a/packages/fighting-design/collapse-animation/src/collapse-animation.vue b/packages/fighting-design/collapse-animation/src/collapse-animation.vue index 26cc32223a..ad5efa8d24 100644 --- a/packages/fighting-design/collapse-animation/src/collapse-animation.vue +++ b/packages/fighting-design/collapse-animation/src/collapse-animation.vue @@ -1,27 +1,20 @@