UNPKG

@nutui/nutui-react-taro

Version:

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

155 lines (154 loc) 6.38 kB
import { a as __awaiter } from "./tslib.es6-iWu3F_1J.js"; import React__default, { forwardRef, useState, useRef, useEffect, useCallback, useMemo, useImperativeHandle } from "react"; import classNames from "classnames"; import { usePageScroll } from "@tarojs/taro"; import { View } from "@tarojs/components"; import { CSSTransition } from "react-transition-group"; import { Check } from "@nutui/icons-react-taro"; import { g as getWindowInfo } from "./get-system-info-D27xNglo.js"; import { O as Overlay } from "./overlay.taro-C8eXSsJH.js"; import { g as getRectByTaro } from "./get-rect-by-taro-D0h6aiDr.js"; import { C as ComponentDefaults } from "./typings-DV9RBfhj.js"; import { u as usePropsValue } from "./use-props-value-SH9krhkx.js"; const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { titleIcon: null, columns: 1, direction: "down", icon: null, closeOnClickAway: true, activeTitleClass: "", inactiveTitleClass: "", onChange: (value) => void 0 }); const MenuItem = forwardRef((props, ref) => { const { className, style, options, value, defaultValue, columns, title, icon, direction, onChange, activeTitleClass, inactiveTitleClass, closeOnClickAway, children, activeColor, show, parent, index } = Object.assign(Object.assign({}, defaultProps), props); const [showPopup, setShowPopup] = useState(show); const [innerValue, setValue] = usePropsValue({ defaultValue, value, finalValue: void 0, onChange: (v) => { const [option] = options.filter((o) => o.value === v); onChange === null || onChange === void 0 ? void 0 : onChange(option); } }); const cssRef = useRef(null); useEffect(() => { setShowPopup(show); }, [show]); const getParentOffset = useCallback(() => { setTimeout(() => __awaiter(void 0, void 0, void 0, function* () { const p = parent.menuRef.current; const rect = yield getRectByTaro(p); setPosition({ height: rect.height, top: rect.top }); }), 100); }, [parent.menuRef]); useEffect(() => { getParentOffset(); }, [showPopup, getParentOffset]); const windowHeight = useMemo(() => getWindowInfo().windowHeight, []); const updateItemOffset = useCallback(() => { if (!parent.lockScroll) return; const p = parent.menuRef.current; getRectByTaro(p).then((rect) => { if (rect) { setPosition({ height: rect.height, top: rect.top }); } }); }, [direction, windowHeight, parent.lockScroll, parent.menuRef]); usePageScroll(updateItemOffset); useImperativeHandle(ref, () => ({ toggle: (s) => { const from = "REF"; s ? parent.toggleMenuItem(index, from) : parent.hideMenuItem(index, from); } })); const getIconCName = (optionVal, value2) => { return classNames({ [activeTitleClass]: optionVal === value2, [inactiveTitleClass]: optionVal !== value2 }); }; const setTitle = (text) => { if (!title) { parent.updateTitle(text, index); } }; const handleClick = (item) => { parent.toggleMenuItem(index); setTitle(item.text); setValue(item.value); }; const [position, setPosition] = useState({ top: 0, height: 0 }); const isShow = () => { if (showPopup) return {}; return { display: "none" }; }; const getPosition = () => { return direction === "down" ? { top: `${position.top + position.height}px`, bottom: "0", height: "initial" } : { bottom: `${getWindowInfo().windowHeight - position.top}px`, top: "0", height: "initial" }; }; const placeholderStyle = () => { if (direction === "down") { return Object.assign({ height: `${position.top + position.height}px` }, isShow()); } return Object.assign({ height: `${getWindowInfo().windowHeight - position.top}px`, top: "auto" }, isShow()); }; return React__default.createElement( View, { className: "nut-menu-container" }, closeOnClickAway ? React__default.createElement(View, { className: `nut-menu-placeholder-element ${classNames({ up: direction === "up" })}`, style: placeholderStyle(), onClick: () => parent.toggleMenuItem(index) }) : null, parent.overlay ? React__default.createElement(Overlay, { className: "nut-menu-container-overlay", style: getPosition(), lockScroll: parent.lockScroll, visible: showPopup, closeOnOverlayClick: parent.closeOnOverlayClick, onClick: () => { parent.closeOnOverlayClick && parent.hideMenuItem(index); } }) : null, React__default.createElement( View, { className: classNames({ "nut-menu-container-wrap": direction === "down", "nut-menu-container-wrap-up": direction !== "down" }, className), style: Object.assign(Object.assign({}, style), isShow()) }, React__default.createElement( CSSTransition, { nodeRef: cssRef, in: showPopup, timeout: 100, classNames: direction === "down" ? "nut-menu-container-down" : "nut-menu-container-up" }, React__default.createElement( View, { className: "nut-menu-container-content" }, options === null || options === void 0 ? void 0 : options.map((item, index2) => { return React__default.createElement( View, { className: `nut-menu-container-item ${classNames({ active: item.value === innerValue })}`, key: item.text, style: { flexBasis: `${100 / columns}%` }, onClick: () => { handleClick(item); } }, item.value === innerValue ? React__default.createElement(React__default.Fragment, null, icon ? React__default.cloneElement(icon, { className: `nut-menu-container-item-icon ${icon.props.className || ""}` }) : React__default.createElement(Check, { color: activeColor, size: 16, className: `nut-menu-container-item-icon ${getIconCName(item.value, value)}` })) : null, React__default.createElement(View, { className: `nut-menu-container-item-title ${getIconCName(item.value, value)}`, style: { color: `${item.value === innerValue ? activeColor : ""}` } }, item.text) ); }), children ) ) ) ); }); MenuItem.displayName = "NutMenuItem"; export { MenuItem as M };