UNPKG

@nutui/nutui-react-taro

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

125 lines (124 loc) 4.45 kB
import { _ as __rest } from "./tslib.es6-iWu3F_1J.js"; import React__default, { createContext, useContext, useRef, useState, useMemo, useEffect } from "react"; import classNames from "classnames"; import { createSelectorQuery } from "@tarojs/taro"; import { C as ComponentDefaults } from "./typings-DV9RBfhj.js"; const collapseContext = { isOpen: (name) => { return true; }, updateValue: (name) => { }, expandIcon: null, rotate: 180 }; const CollapseContext = createContext(collapseContext); const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { title: null, name: "", expandIcon: null, disabled: false, extra: null }); const CollapseItem = (props) => { const _a = Object.assign(Object.assign({}, defaultProps), props), { children, title, name, disabled, expandIcon, rotate, extra, style, className } = _a, rest = __rest(_a, ["children", "title", "name", "disabled", "expandIcon", "rotate", "extra", "style", "className"]); const classPrefix = "nut-collapse-item"; const context = useContext(CollapseContext); const wrapperRef = useRef(null); const contentRef = useRef(null); const [refRandomId] = useState(() => Math.random().toString(36).slice(-8)); const target = `#nut-collapse-content-${refRandomId}`; const expanded = useMemo(() => { if (context) { return context.isOpen(name); } return false; }, [name, context.isOpen]); const iconStyle = useMemo(() => { return expanded ? { transform: `translateY(-50%) rotate(${rotate || context.rotate}deg)` } : { 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 getRect = (selector) => { return new Promise((resolve) => { createSelectorQuery().select(selector).boundingClientRect().exec((rect = []) => { resolve(rect[0]); }); }); }; useEffect(() => { setTimeout(() => { getRect(target).then((res) => { if (res === null || res === void 0 ? void 0 : res.height) { setCurrentHeight(`${res.height}px`); } }); }, 200); }, [children]); useEffect(() => { setTimeout(() => { getRect(target).then((res) => { if (res === null || res === void 0 ? void 0 : res.height) { setCurrentHeight(`${res.height}px`); } }); }, 100); }, []); 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 timer2 = setTimeout(() => { setWrapperHeight("auto"); }, 300); setTimer(timer2); } }, 100); }; const init = useRef(true); useEffect(() => { if (init.current) { init.current = false; } else { toggle(); } }, [expanded]); return React__default.createElement( "div", Object.assign({ className: classNames(classPrefix, className), style }, rest), React__default.createElement( "div", { className: classNames(`${classPrefix}-header`, { disabled }), onClick: handleClick }, React__default.createElement("div", { className: `${classPrefix}-title` }, title), React__default.createElement("div", { className: `${classPrefix}-extra` }, extra), React__default.createElement( "div", { className: `${classPrefix}-icon-box` }, React__default.createElement("div", { className: `${classPrefix}-icon`, style: iconStyle }, expandIcon || context.expandIcon) ) ), React__default.createElement( "div", { className: `${classPrefix}-content`, ref: wrapperRef, style: { willChange: "height", height: wrapperHeight } }, React__default.createElement("div", { ref: contentRef, className: `${classPrefix}-content-text`, id: `nut-collapse-content-${refRandomId}` }, children) ) ); }; CollapseItem.displayName = "NutCollapseItem"; export { CollapseItem as C, CollapseContext as a };