@wener/console
Version:
Base console UI toolkit
140 lines (139 loc) • 6.74 kB
JavaScript
import React, { forwardRef, useState } from "react";
import { HiChevronDown, HiChevronRight } from "react-icons/hi2";
import { PiCaretDoubleLeftThin, PiCaretDoubleRightThin } from "react-icons/pi";
import { flexRender, useControllable } from "@wener/reaction";
import { clsx } from "clsx";
import { Tooltip } from "../../../floating/index.js";
import { HeaderContentFooterLayout, LeftContentRightLayout, OverlayScrollbar } from "../../components/index.js";
import { AutoNavLink } from "../../links/index.js";
const SideMenuItem = ({ item, expanded, NavLink = AutoNavLink }) => {
const [collapse, setCollapse] = useState(true);
if ("children" in item) {
const { label, icon, children } = item;
if (!expanded) {
return /*#__PURE__*/ React.createElement("li", null, /*#__PURE__*/ React.createElement("span", null, icon));
}
return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("li", {
onClick: () => {
setCollapse(!collapse);
}
}, /*#__PURE__*/ React.createElement("span", null, icon, label, /*#__PURE__*/ React.createElement("span", {
className: "flex-1"
}), collapse ? /*#__PURE__*/ React.createElement(HiChevronRight, null) : /*#__PURE__*/ React.createElement(HiChevronDown, null))), !collapse && children.map((item, i) => {
return /*#__PURE__*/ React.createElement(SideMenuItem, {
expanded: true,
item: {
...item,
type: "item",
icon: /*#__PURE__*/ React.createElement("div", {
className: "inline-block w-4"
}),
iconActive: undefined
},
key: `${label}/${i}`
});
}));
// fixme collapse not works
// return (
// <li className="collapse">
// <span tabIndex={0} className="collapse-title">
// {icon}
// {label}
// </span>
// <ul
// className={classNames(
// // "collapse-content",
// // ' gap-0.5 bg-base-100',
// )}
// >
// {children.map((item, i) => {
// return <li key={i}>
// <span>{item.label}</span>
// </li>
// })}
// </ul>
// </li>
}
if (item.type === "title") {
if (!expanded) {
return /*#__PURE__*/ React.createElement("li", {
className: "menu-title w-full px-0.5 py-0"
}, /*#__PURE__*/ React.createElement("span", {
className: "w-full truncate text-center text-[10px]"
}, item.label));
}
return /*#__PURE__*/ React.createElement("li", {
className: "menu-title"
}, /*#__PURE__*/ React.createElement("span", null, item.label));
}
const { href, icon, end, iconActive, label } = item;
// data-tooltip 由于 overflow 实际无法显示
return /*#__PURE__*/ React.createElement(Tooltip, {
portal: true,
content: !expanded && label,
placement: "right",
className: "hidden md:block"
}, /*#__PURE__*/ React.createElement("li", null, /*#__PURE__*/ React.createElement(NavLink, {
href: href,
end: end,
title: label,
className: ({ isActive }) => clsx(expanded ? "" : "justify-center p-2", isActive ? "active" : "inactive")
}, ({ isActive: active }) => {
let ico = flexRender(active ? iconActive || icon : icon, {
active,
className: "w-6 h-6"
}, true);
return /*#__PURE__*/ React.createElement(React.Fragment, null, ico, expanded && label);
})));
};
export const ExpandableMenu = ({ expanded, title, header: _header, icon, items, onExpandedChange, children }) => {
return /*#__PURE__*/ React.createElement(HeaderContentFooterLayout, {
className: clsx("z-30 border-r border-base-300", "transition-[width]", expanded ? "w-[200px]" : "w-[49px]"),
header: /*#__PURE__*/ React.createElement("header", {
className: clsx("flex flex-wrap items-center py-4 text-xl font-light", expanded ? "px-4" : "justify-center")
}, icon, expanded && title && /*#__PURE__*/ React.createElement("span", {
className: "pl-2"
}, title), flexRender(_header, {
expanded
})),
footer: /*#__PURE__*/ React.createElement("div", {
"data-tip": expanded ? "\u6536\u8D77\u4FA7\u8FB9\u680F" : "\u5C55\u5F00\u4FA7\u8FB9\u680F",
className: clsx("flex flex-col items-stretch", "font-thin opacity-75", // 都通过 tooltip 提示
// !expanded && 'tooltip tooltip-right',
"tooltip tooltip-right")
}, /*#__PURE__*/ React.createElement("button", {
type: "button",
onClick: () => {
onExpandedChange?.(!expanded);
},
className: "flex h-12 items-center p-4 hover:bg-base-300"
}, expanded ? /*#__PURE__*/ React.createElement(PiCaretDoubleLeftThin, null) : /*#__PURE__*/ React.createElement(PiCaretDoubleRightThin, null)))
}, /*#__PURE__*/ React.createElement(OverlayScrollbar, {
className: "h-full"
}, /*#__PURE__*/ React.createElement("ul", {
className: clsx("menu gap-0.5 bg-base-100", expanded ? "p-2" : "p-0")
}, items.map((item, i) => {
return /*#__PURE__*/ React.createElement(SideMenuItem, {
item: item,
expanded: expanded,
key: i
});
})), children));
};
export const ExpandableSideMenuLayout = /*#__PURE__*/ forwardRef(({ children, header: _header, title, icon, items, NavLink = AutoNavLink, expanded: _expanded, onExpandedChange: _onExpandedChange, initialExpanded: _initialExpanded, ...props }, ref) => {
const [expanded, setExpanded] = useControllable(_expanded, _onExpandedChange, () => _initialExpanded ?? (typeof window === "undefined" ? true : window.matchMedia("(min-width: 768px)").matches));
return /*#__PURE__*/ React.createElement(LeftContentRightLayout, {
className: "h-full",
left: /*#__PURE__*/ React.createElement(ExpandableMenu, {
expanded: expanded,
onExpandedChange: setExpanded,
title: title,
items: items,
icon: icon,
header: _header
}),
ref: ref
}, children);
});
ExpandableSideMenuLayout.displayName = "ExpandableSideMenuLayout";
//# sourceMappingURL=ExpandableSideMenuLayout.js.map