@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
125 lines (124 loc) • 4.45 kB
JavaScript
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
};