@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
161 lines (160 loc) • 7.39 kB
JavaScript
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array";
import React, { useCallback, useEffect, useRef, useState } from "react";
import classNames from "classnames";
import { ArrowDown, ArrowUp } from "@nutui/icons-react";
import { MenuItem } from "../menuitem/menuitem";
import { ComponentDefaults } from "../../utils/typings";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
activeColor: '',
closeOnOverlayClick: true,
scrollFixed: false,
lockScroll: true,
overlay: true,
icon: null,
onOpen: function(index, from) {},
onClose: function(index, from) {}
});
export var Menu = function(props) {
var _ref = _object_spread({}, defaultProps, props), className = _ref.className, icon = _ref.icon, scrollFixed = _ref.scrollFixed, lockScroll = _ref.lockScroll, overlay = _ref.overlay, closeOnOverlayClick = _ref.closeOnOverlayClick, children = _ref.children, activeColor = _ref.activeColor, onClose = _ref.onClose, onOpen = _ref.onOpen, rest = _object_without_properties(_ref, [
"className",
"icon",
"scrollFixed",
"lockScroll",
"overlay",
"closeOnOverlayClick",
"children",
"activeColor",
"onClose",
"onOpen"
]);
var menuRef = useRef(null);
var _useState = _sliced_to_array(useState([]), 2), showMenuItem = _useState[0], setShowMenuItem = _useState[1];
var _useState1 = _sliced_to_array(useState([]), 2), menuItemTitle = _useState1[0], setMenuItemTitle = _useState1[1];
var _useState2 = _sliced_to_array(useState(false), 2), isScrollFixed = _useState2[0], setIsScrollFixed = _useState2[1];
var cls = classNames("nut-menu", className, {
'scroll-fixed': isScrollFixed
});
var getScrollTop = function(el) {
return Math.max(0, el === window ? window.scrollY : el.scrollTop);
};
var onScroll = useCallback(function() {
var scrollTop = getScrollTop(window);
var isFixed = scrollTop > (typeof scrollFixed === 'boolean' ? 30 : Number(scrollFixed));
setIsScrollFixed(isFixed);
}, [
scrollFixed
]);
useEffect(function() {
if (scrollFixed) {
window.addEventListener('scroll', onScroll);
}
return function() {
return window.removeEventListener('scroll', onScroll);
};
}, [
scrollFixed,
onScroll
]);
var toggleMenuItem = function(index) {
var from = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 'NORMAL';
showMenuItem[index] = !showMenuItem[index];
if (showMenuItem[index]) {
onOpen && onOpen(index, from);
} else {
onClose && onClose(index, from);
}
var temp = showMenuItem.map(function(i, idx) {
return idx === index ? i : false;
});
setShowMenuItem(_to_consumable_array(temp));
};
var hideMenuItem = function(index) {
var from = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 'NORMAL';
showMenuItem[index] = false;
setShowMenuItem(_to_consumable_array(showMenuItem));
onClose && onClose(index, from);
};
var updateTitle = function(text, index) {
menuItemTitle[index] = text;
setMenuItemTitle(_to_consumable_array(menuItemTitle));
};
var cloneChildren = function() {
return React.Children.map(children, function(child, index) {
return /*#__PURE__*/ React.cloneElement(child, _object_spread_props(_object_spread({}, child.props), {
show: showMenuItem[index],
index: index,
activeColor: activeColor,
parent: {
closeOnOverlayClick: closeOnOverlayClick,
overlay: overlay,
lockScroll: lockScroll,
toggleMenuItem: toggleMenuItem,
updateTitle: updateTitle,
hideMenuItem: hideMenuItem,
menuRef: menuRef
}
}));
});
};
var menuTitle = function() {
return React.Children.map(children, function(child, index) {
if (/*#__PURE__*/ React.isValidElement(child)) {
var _child_props = child.props, title = _child_props.title, titleIcon = _child_props.titleIcon, options = _child_props.options, value = _child_props.value, defaultValue = _child_props.defaultValue, disabled = _child_props.disabled, direction = _child_props.direction;
var selected = options === null || options === void 0 ? void 0 : options.filter(function(option) {
return option.value === (value !== undefined ? value : defaultValue);
});
var finallyTitle = function() {
if (title) return title;
if (menuItemTitle && menuItemTitle[index]) return menuItemTitle[index];
if (selected && selected.length && selected[0].text) return selected[0].text;
return '';
};
var finallyIcon = function() {
if (titleIcon) return titleIcon;
if (icon) return icon;
return direction === 'up' ? /*#__PURE__*/ React.createElement(ArrowUp, {
className: "nut-menu-title-icon",
width: "12px",
height: "12px"
}) : /*#__PURE__*/ React.createElement(ArrowDown, {
className: "nut-menu-title-icon",
width: "12px",
height: "12px"
});
};
return /*#__PURE__*/ React.createElement("div", {
className: classNames('nut-menu-title', "nut-menu-title-".concat(index), {
active: showMenuItem[index],
disabled: disabled
}),
style: {
color: showMenuItem[index] ? activeColor : ''
},
key: index,
onClick: function(e) {
e.stopPropagation();
if ((!options || !options.length) && !child.props.children) return;
!disabled && toggleMenuItem(index);
}
}, /*#__PURE__*/ React.createElement("div", {
className: "nut-menu-title-text"
}, finallyTitle()), finallyIcon());
}
return null;
});
};
return /*#__PURE__*/ React.createElement("div", _object_spread_props(_object_spread({}, rest), {
className: cls,
ref: menuRef
}), /*#__PURE__*/ React.createElement("div", {
className: classNames('nut-menu-bar', {
opened: showMenuItem.includes(true)
})
}, menuTitle()), cloneChildren());
};
Menu.displayName = 'NutMenu';
Menu.Item = MenuItem;