UNPKG

@wener/console

Version:

Base console UI toolkit

140 lines (139 loc) 6.74 kB
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