diff --git a/src/config.json b/src/config.json index 792fd0f5a0..7cb04916e9 100644 --- a/src/config.json +++ b/src/config.json @@ -1127,7 +1127,7 @@ "dd": false }, { - "version": "2.0.0", + "version": "3.0.0", "name": "Collapse", "type": "component", "cName": "折叠面板", @@ -1135,12 +1135,12 @@ "sort": 2, "show": true, "taro": true, - "v15": -1, - "author": "zhenyulei", - "dd": false + "v15": 1, + "author": "oasis", + "dd": true }, { - "version": "2.0.0", + "version": "3.0.0", "name": "CollapseItem", "type": "component", "cName": "折叠面板子组件", @@ -1148,8 +1148,8 @@ "sort": 13, "show": false, "exportEmpty": true, - "author": "zhenyulei", - "dd": false + "author": "oasis", + "dd": true }, { "version": "3.0.0", diff --git a/src/packages/collapse/__test__/__snapshots__/collapse.spec.tsx.snap b/src/packages/collapse/__test__/__snapshots__/collapse.spec.tsx.snap index 75e2bb6729..0eb362ae53 100644 --- a/src/packages/collapse/__test__/__snapshots__/collapse.spec.tsx.snap +++ b/src/packages/collapse/__test__/__snapshots__/collapse.spec.tsx.snap @@ -42,12 +42,16 @@ exports[`should match snapshot 1`] = `
- 京东“厂直优品计划”首推“政府优品馆” 3年覆盖80%镇级政府 +
+ 京东“厂直优品计划”首推“政府优品馆” 3年覆盖80%镇级政府 +
@@ -88,12 +92,16 @@ exports[`should match snapshot 1`] = `
- 京东“厂直优品计划”首推“政府优品馆” 3年覆盖80%镇级政府 +
+ 京东“厂直优品计划”首推“政府优品馆” 3年覆盖80%镇级政府 +
@@ -101,7 +109,7 @@ exports[`should match snapshot 1`] = ` class="nut-collapse-item" >
- 京东“厂直优品计划”首推“政府优品馆” +
+ 京东“厂直优品计划”首推“政府优品馆” +
diff --git a/src/packages/collapse/__test__/collapse.spec.tsx b/src/packages/collapse/__test__/collapse.spec.tsx index 8cbcbd4f13..27717f29c5 100644 --- a/src/packages/collapse/__test__/collapse.spec.tsx +++ b/src/packages/collapse/__test__/collapse.spec.tsx @@ -63,10 +63,13 @@ test('prop activeName', async () => { ) - - expect( - container.querySelectorAll('.nut-collapse-item-content')[2] - ).toHaveStyle('height:0px') + waitFor(() => { + expect( + container.querySelectorAll('.nut-collapse-item-content-wrapper')[2] + ).toHaveStyle({ + height: '0', + }) + }) }) test('prop rotate', async () => { diff --git a/src/packages/collapseitem/collapseitem.scss b/src/packages/collapseitem/collapseitem.scss index c3b8a31c60..6a2e1fa134 100644 --- a/src/packages/collapseitem/collapseitem.scss +++ b/src/packages/collapseitem/collapseitem.scss @@ -38,8 +38,12 @@ left: 16px; bottom: 0; border-bottom: $collapse-item-header-border-bottom; - -webkit-transform: scaleY(0.5); - transform: scaleY(0.5); + /* #ifdef harmony */ + transform: scale(1, 1); + /* #endif */ + /* #ifndef harmony */ + transform: scale(1, 0.5); + /* #endif */ } } @@ -78,7 +82,7 @@ transition: transform 0.3s; } - &-header.disabled { + &-header-disabled { color: $collapse-item-disabled-color; .nut-collapse-item-title { @@ -90,14 +94,26 @@ } } - &-content { + &-content-wrapper { + width: 100%; + position: relative; + box-sizing: border-box; overflow: hidden; + &-tran { + transition: all 0.3s linear; + } + } + + &-content { display: block; + position: absolute; + height: auto; + width: 100%; + box-sizing: border-box; color: $collapse-wrapper-content-color; font-size: $collapse-wrapper-content-font-size; line-height: $collapse-wrapper-content-line-height; background-color: $collapse-wrapper-content-background-color; - transition: all 0.3s linear; &-text { color: $collapse-wrapper-content-color; @@ -105,6 +121,7 @@ } } } + [dir='rtl'] .nut-collapse-item, .nut-rtl .nut-collapse-item { &-icon { diff --git a/src/packages/collapseitem/collapseitem.taro.tsx b/src/packages/collapseitem/collapseitem.taro.tsx index be8fa23170..ab9a90f263 100644 --- a/src/packages/collapseitem/collapseitem.taro.tsx +++ b/src/packages/collapseitem/collapseitem.taro.tsx @@ -1,17 +1,20 @@ import React, { FunctionComponent, - useEffect, - useState, ReactNode, useContext, - useRef, + useEffect, useMemo, + useRef, + useState, } from 'react' import { View } from '@tarojs/components' import classNames from 'classnames' -import { createSelectorQuery } from '@tarojs/taro' +import { nextTick } from '@tarojs/taro' import { BasicComponent, ComponentDefaults } from '@/utils/typings' import CollapseContext from '../collapse/context' +import { getRectByTaro } from '@/utils/get-rect-by-taro' +import useUuid from '@/hooks/use-uuid' +import { useRefState } from '@/hooks/use-ref-state' export interface CollapseItemProps extends BasicComponent { title: ReactNode @@ -54,8 +57,8 @@ export const CollapseItem: FunctionComponent< const context = useContext(CollapseContext) const wrapperRef: any = useRef(null) const contentRef: any = useRef(null) - const [refRandomId] = useState(() => Math.random().toString(36).slice(-8)) - const target = `#nut-collapse-content-${refRandomId}` + const uid = useUuid() + const target = `nut-collapse-content-${uid}` const expanded = useMemo(() => { if (context) { @@ -70,86 +73,45 @@ export const CollapseItem: FunctionComponent< : { transform: 'translateY(-50%)' } }, [expanded, rotate]) - const handleClick = () => { - if (!disabled) { - context.updateValue(name) - } - } - - const [timer, setTimer] = useState(null) - const [currentHeight, setCurrentHeight] = useState('auto') - const inAnimation = useRef(false) - const [wrapperHeight, setWrapperHeight] = useState(() => - expanded ? 'auto' : '0px' - ) + const [tran, setTran] = useState(0) + const [currentHeight, setCurrentHeight] = useRefState(0) + const [wrapperHeight, setWrapperHeight] = useState(0) - const getRect = (selector: string) => { - return new Promise((resolve) => { - createSelectorQuery() - .select(selector) - .boundingClientRect() - .exec((rect = []) => { - resolve(rect[0]) - }) - }) - } - - useEffect(() => { - setTimeout(() => { - getRect(target).then((res: any) => { - if (res?.height) { - setCurrentHeight(`${res.height}px`) - } + const updateRectHeight = async () => { + const res = await getRectByTaro(contentRef.current, target) + if (res?.height) { + setCurrentHeight(res.height) + setWrapperHeight(expanded ? res.height : 0) + nextTick(() => { + setTran(1) }) - }, 200) - }, [children]) - + } + } useEffect(() => { - setTimeout(() => { - getRect(target).then((res: any) => { - if (res?.height) { - setCurrentHeight(`${res.height}px`) - } - }) - }, 100) - }, []) + nextTick(() => { + updateRectHeight() + }) + }, [children, expanded]) const toggle = () => { - // 连续切换状态时,清除打开的后续操作 - if (timer) { - clearTimeout(timer) - setTimer(timer) - } - const start = expanded ? '0px' : currentHeight - const end = expanded ? currentHeight : '0px' - inAnimation.current = true - setWrapperHeight(start) - setTimeout(() => { - setWrapperHeight(end) - inAnimation.current = false - if (expanded) { - const timer = setTimeout(() => { - setWrapperHeight('auto') - }, 300) - setTimer(timer) - } - }, 100) + const end = !expanded ? currentHeight.current : 0 + setWrapperHeight(end) } - - const init = useRef(true) - - useEffect(() => { - if (init.current) { - init.current = false - } else { - toggle() + const handleClick = () => { + if (!disabled) { + context.updateValue(name) + setTimeout(() => { + toggle() + }, 150) } - }, [expanded]) + } return (
{title} @@ -161,19 +123,21 @@ export const CollapseItem: FunctionComponent< - - {children} + + {children}
diff --git a/src/packages/collapseitem/collapseitem.tsx b/src/packages/collapseitem/collapseitem.tsx index 672e5e0055..556835eeb4 100644 --- a/src/packages/collapseitem/collapseitem.tsx +++ b/src/packages/collapseitem/collapseitem.tsx @@ -1,14 +1,16 @@ import React, { FunctionComponent, - useEffect, ReactNode, useContext, - useRef, + useEffect, useMemo, + useRef, + useState, } from 'react' import classNames from 'classnames' import { BasicComponent, ComponentDefaults } from '@/utils/typings' import CollapseContext from '../collapse/context' +import { useRefState } from '@/hooks/use-ref-state' export interface CollapseItemProps extends BasicComponent { title: ReactNode @@ -65,56 +67,40 @@ export const CollapseItem: FunctionComponent< : { transform: 'translateY(-50%)' } }, [expanded, rotate]) - const handleClick = () => { - if (!disabled) { - context.updateValue(name) - } - } + const [tran, setTran] = useState(0) + const [currentHeight, setCurrentHeight] = useRefState(0) + const [wrapperHeight, setWrapperHeight] = useState(0) - const onTransitionEnd = () => { - if (expanded) { - if (wrapperRef.current) { - wrapperRef.current.style.height = '' - } - } + const updateRectHeight = async () => { + const height = contentRef.current.offsetHeight + setCurrentHeight(height) + setWrapperHeight(expanded ? height : 0) + setTimeout(() => { + setTran(1) + }) } - const getOffsetHeight = () => { - const height = contentRef.current?.offsetHeight - return height ? `${height}px` : '' - } + useEffect(() => { + updateRectHeight() + }, [children, expanded]) const toggle = () => { - const start = expanded ? '0px' : getOffsetHeight() - if (wrapperRef.current) { - wrapperRef.current.style.height = start - } - requestAnimationFrame(() => { - requestAnimationFrame(() => { - const end = expanded ? getOffsetHeight() : '0px' - if (wrapperRef.current) { - wrapperRef.current.style.height = end - } - }) - }) + const end = !expanded ? currentHeight.current : 0 + setWrapperHeight(end) } - const init = useRef(true) - - useEffect(() => { - if (init.current) { - init.current = false - if (!expanded) { - wrapperRef.current.style.height = '0px' - } - } else { + const handleClick = () => { + if (!disabled) { + context.updateValue(name) toggle() } - }, [expanded]) + } return (
{title}
@@ -126,12 +112,23 @@ export const CollapseItem: FunctionComponent<
-
- {children} +
+
+ {children} +