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