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