@veracity/vui
Version:
Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.
98 lines (96 loc) • 3.18 kB
JavaScript
import { filterUndefined } from "../utils/object.js";
import { cs } from "../utils/styles.js";
import { isActivePath } from "../utils/window.js";
import { useStyleConfig } from "../core/theme.js";
import vui from "../core/vui.js";
import { Box } from "../box/box.js";
import { Icon } from "../icon/icon.js";
import { Button } from "../button/button.js";
import { SidemenuProvider } from "./context.js";
import { SidemenuItem } from "./sidemenuItem.js";
import { SidemenuTop } from "./sidemenuTop.js";
import { useEffect, useMemo, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
//#region src/sidemenu/sidemenu.tsx
/** A collapsible side menu for navigation. */
const Sidemenu = vui((props, ref) => {
const { children, className, items, isExpanded = false, isSticky = false, size, variant, width = 240, onNavigate, ...rest } = props;
const [isExpandedHorizontally, setIsExpandedHorizontally] = useState(isExpanded);
const context = useMemo(() => filterUndefined({
size,
variant,
isExpandedHorizontally
}), [
size,
variant,
isExpandedHorizontally
]);
const styles = useStyleConfig("Sidemenu", props);
const isDark = variant === "dark";
useEffect(() => {
setIsExpandedHorizontally(isExpanded);
}, [isExpanded]);
const onToggle = () => setIsExpandedHorizontally(!isExpandedHorizontally);
const w = isExpandedHorizontally ? width : 52;
const icon = `falArrow${isExpandedHorizontally ? "Left" : "Right"}`;
const justifyContent = isExpandedHorizontally ? "flex-end" : "center";
function onItemClick(item) {
item?.onClick?.();
if (item?.path) onNavigate?.(item.path);
}
return /* @__PURE__ */ jsx(SidemenuProvider, {
value: context,
children: /* @__PURE__ */ jsxs(Box, {
className: cs("vui-sidemenu", className),
elevation: "3",
flexDirection: "column",
minWidth: 0,
overflowX: "hidden",
position: isSticky ? "sticky" : "static",
ref,
top: isSticky ? top ? top : 0 : "auto",
transitionDuration: "normal",
w,
...styles.container,
...rest,
children: [/* @__PURE__ */ jsx(Box, {
flexDirection: "column",
flexGrow: 1,
justifyContent: "flex-start",
minW: 240,
overflowX: "hidden",
overflowY: "auto",
w: "100%",
children: items ? items?.map?.((item, key) => /* @__PURE__ */ jsx(SidemenuItem, {
isActive: isActivePath(item?.path),
...item,
onClick: () => onItemClick(item)
}, key)) : children
}), /* @__PURE__ */ jsx(Box, {
className: "vui-sidemenu-bottom",
w: "100%",
...styles.bottom,
children: /* @__PURE__ */ jsx(Button, {
"aria-label": isExpandedHorizontally ? "Collapse" : "Expand",
borderRadius: 0,
justifyContent,
minH: size === "lg" ? "56px" : "40px",
onClick: onToggle,
pl: 0,
size: "md",
variant: "tertiary",
intent: isDark ? "contrast" : "brand",
w: "100%",
children: /* @__PURE__ */ jsx(Icon, { name: icon })
})
})]
})
});
});
Sidemenu.Top = SidemenuTop;
Sidemenu.Item = SidemenuItem;
Sidemenu.displayName = "Sidemenu";
//#endregion
export { Sidemenu, Sidemenu as default };
globalThis.__vuiVersion__ = "5.3.1"
//# sourceMappingURL=sidemenu.js.map