UNPKG

@nutui/nutui-react

Version:

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

123 lines (122 loc) 5.03 kB
import { _ as __rest } from "./tslib.es6.js"; import React__default, { useRef, useState, useEffect } from "react"; import classNames from "classnames"; import { ArrowUp, ArrowDown } from "@nutui/icons-react"; import { M as MenuItem } from "./menuitem2.js"; import { C as ComponentDefaults } from "./typings.js"; const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { activeColor: "", closeOnOverlayClick: true, scrollFixed: false, lockScroll: true, overlay: true, icon: null, onOpen: (index, from) => { }, onClose: (index, from) => { } }); const Menu = (props) => { const _a = Object.assign(Object.assign({}, defaultProps), props), { className, icon, scrollFixed, lockScroll, overlay, closeOnOverlayClick, children, activeColor, onClose, onOpen } = _a, rest = __rest(_a, ["className", "icon", "scrollFixed", "lockScroll", "overlay", "closeOnOverlayClick", "children", "activeColor", "onClose", "onOpen"]); const menuRef = useRef(null); const [isScrollFixed, setIsScrollFixed] = useState(false); const getScrollTop = (el) => { return Math.max(0, "scrollTop" in el ? el.scrollTop : el.pageYOffset); }; const onScroll = () => { const { scrollFixed: scrollFixed2 } = props; const scrollTop = getScrollTop(window); const isFixed = scrollTop > (typeof scrollFixed2 === "boolean" ? 30 : Number(scrollFixed2)); setIsScrollFixed(isFixed); }; useEffect(() => { if (scrollFixed) { window.addEventListener("scroll", onScroll); } return () => window.removeEventListener("scroll", onScroll); }, []); const [showMenuItem, setShowMenuItem] = useState([]); const [menuItemTitle, setMenuItemTitle] = useState([]); const toggleMenuItem = (index, from = "NORMAL") => { showMenuItem[index] = !showMenuItem[index]; if (showMenuItem[index]) { onOpen && onOpen(index, from); } else { onClose && onClose(index, from); } const temp = showMenuItem.map((i, idx) => idx === index ? i : false); setShowMenuItem([...temp]); }; const hideMenuItem = (index, from = "NORMAL") => { showMenuItem[index] = false; setShowMenuItem([...showMenuItem]); onClose && onClose(index, from); }; const updateTitle = (text, index) => { menuItemTitle[index] = text; setMenuItemTitle([...menuItemTitle]); }; const cloneChildren = () => { return React__default.Children.map(children, (child, index) => { return React__default.cloneElement(child, Object.assign(Object.assign({}, child.props), { show: showMenuItem[index], index, activeColor, parent: { closeOnOverlayClick, overlay, lockScroll, toggleMenuItem, updateTitle, hideMenuItem, menuRef } })); }); }; const menuTitle = () => { return React__default.Children.map(children, (child, index) => { if (React__default.isValidElement(child)) { const { title, titleIcon, options, value, defaultValue, disabled, direction } = child.props; const selected = options === null || options === void 0 ? void 0 : options.filter((option) => option.value === (value !== void 0 ? value : defaultValue)); const finallyTitle = () => { if (title) return title; if (menuItemTitle && menuItemTitle[index]) return menuItemTitle[index]; if (selected && selected.length && selected[0].text) return selected[0].text; return ""; }; const finallyIcon = () => { if (titleIcon) return titleIcon; if (icon) return icon; return direction === "up" ? React__default.createElement(ArrowUp, { className: "nut-menu-title-icon", width: "12px", height: "12px" }) : React__default.createElement(ArrowDown, { className: "nut-menu-title-icon", width: "12px", height: "12px" }); }; return React__default.createElement( "div", { className: classNames("nut-menu-title", `nut-menu-title-${index}`, { active: showMenuItem[index], disabled }), style: { color: showMenuItem[index] ? activeColor : "" }, key: index, onClick: (e) => { e.stopPropagation(); if ((!options || !options.length) && !child.props.children) return; !disabled && toggleMenuItem(index); } }, React__default.createElement("div", { className: "nut-menu-title-text" }, finallyTitle()), finallyIcon() ); } return null; }); }; return React__default.createElement( "div", Object.assign({}, rest, { className: classNames(`nut-menu`, className, { "scroll-fixed": isScrollFixed }), ref: menuRef }), React__default.createElement("div", { className: classNames("nut-menu-bar", { opened: showMenuItem.includes(true) }) }, menuTitle()), cloneChildren() ); }; Menu.displayName = "NutMenu"; Menu.Item = MenuItem; export { Menu as default };