@xylabs/react-appbar
Version:
Common React library for all XY Labs projects that use React
452 lines (433 loc) • 14 kB
JavaScript
// src/AppBarEx.tsx
import {
AppBar,
Container,
Toolbar,
useMediaQuery,
useTheme
} from "@mui/material";
import { FlexGrowRow, FlexRow } from "@xylabs/react-flexbox";
import { isDefinedNotNull, isString } from "@xylabs/typeof";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var AppBarExInner = ({
children,
menu,
contextToolbar,
systemToolbar,
responsive,
...props
}) => {
const { breakpoints } = useTheme();
const belowSm = useMediaQuery(breakpoints.down("sm"));
return /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsxs(FlexRow, { flexWrap: "nowrap", justifyContent: "flex-start", ...props, children: [
contextToolbar ?? /* @__PURE__ */ jsx(Toolbar, {}),
/* @__PURE__ */ jsx(FlexGrowRow, { children: belowSm && responsive ? null : children }),
systemToolbar ?? /* @__PURE__ */ jsx(Toolbar, {}),
menu
] }),
belowSm && isDefinedNotNull(children) && responsive ? /* @__PURE__ */ jsx(Toolbar, { children }) : null
] });
};
var AppBarEx = ({
container,
children,
menu,
contextToolbar,
systemToolbar,
responsive,
...props
}) => {
return /* @__PURE__ */ jsx(AppBar, { position: "static", ...props, children: isString(container) ? /* @__PURE__ */ jsx(Container, { maxWidth: container, children: /* @__PURE__ */ jsx(
AppBarExInner,
{
...{
children,
contextToolbar,
menu,
responsive,
systemToolbar
}
}
) }) : /* @__PURE__ */ jsx(
AppBarExInner,
{
...{
children,
contextToolbar,
menu,
responsive,
systemToolbar
}
}
) });
};
// src/Toolbar/Context/ContextToolbar.tsx
import { Toolbar as Toolbar2 } from "@mui/material";
// src/Toolbar/Context/LogoLinkEx.tsx
import { Typography, useTheme as useTheme2 } from "@mui/material";
import { assertEx } from "@xylabs/assert";
import { FlexRow as FlexRow2 } from "@xylabs/react-flexbox";
import { LinkEx } from "@xylabs/react-link";
import { isString as isString2 } from "@xylabs/typeof";
// src/Toolbar/Context/Logo.tsx
import { LogoDevOutlined, LogoDevRounded } from "@mui/icons-material";
import { useIsDark } from "@xylabs/react-theme";
import { jsx as jsx2 } from "react/jsx-runtime";
var Logo = (props) => {
const dark = useIsDark();
return dark ? /* @__PURE__ */ jsx2(LogoDevRounded, { ...props }) : /* @__PURE__ */ jsx2(LogoDevOutlined, { ...props });
};
// src/Toolbar/Context/LogoLinkEx.tsx
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
var LogoLinkEx = ({
logo,
to = "/",
href,
version = false,
...props
}) => {
const theme = useTheme2();
assertEx(href === void 0, () => "href is not supported");
return /* @__PURE__ */ jsx3(LinkEx, { to, ...props, children: /* @__PURE__ */ jsxs2(FlexRow2, { paddingX: "4px", children: [
logo ?? /* @__PURE__ */ jsx3(
Logo,
{
sx: {
color: theme.vars.palette.primary.contrastText,
height: "40px",
width: "40px"
}
}
),
isString2(version) || version === true ? /* @__PURE__ */ jsx3(
Typography,
{
position: "absolute",
borderRadius: 1,
right: 6,
color: theme.vars.palette.primary.contrastText,
bottom: 0,
bgcolor: theme.vars.palette.text.primary,
paddingX: "2px",
lineHeight: 1,
variant: "caption",
border: `1px ${theme.vars.palette.primary.contrastText} solid`,
children: typeof version === "string" ? version : "1.0"
}
) : null
] }) });
};
// src/Toolbar/Context/ContextToolbar.tsx
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
var ContextToolbar = ({
children,
logo,
logoTo = "/",
version = false,
...props
}) => {
return /* @__PURE__ */ jsxs3(Toolbar2, { ...props, children: [
/* @__PURE__ */ jsx4(LogoLinkEx, { logo, version, to: logoTo }),
children
] });
};
// src/Toolbar/System/SystemToolbar.tsx
import { Toolbar as Toolbar3 } from "@mui/material";
import { ColorSchemeButton } from "@xylabs/react-theme";
import { isDefinedNotNull as isDefinedNotNull2 } from "@xylabs/typeof";
// src/SiteMenu/hooks/useMenuItemsShared.tsx
import { useCollapsible } from "@xylabs/react-shared";
import { useMemo } from "react";
var useMenuItemsShared = () => {
const {
collapse,
collapseEnd,
setCollapse,
setCollapseEnd
} = useCollapsible();
const onMenuItemToggle = (open) => {
setCollapse?.((previous) => open ? false : previous);
setCollapseEnd?.((previous) => open ? false : previous);
};
const defaultSiteMenuListItemProps = useMemo(
() => ({
collapseEnd,
dense: true,
iconOnly: collapse,
sx: { px: "8px" }
}),
[collapse, collapseEnd]
);
return { defaultSiteMenuListItemProps, onMenuItemToggle };
};
// src/SiteMenu/Menu.tsx
import { Menu as MenuIcon2, Settings as SettingsIcon } from "@mui/icons-material";
import {
IconButton as IconButton2,
List as List2,
SwipeableDrawer
} from "@mui/material";
import { FlexRow as FlexRow4 } from "@xylabs/react-flexbox";
import { useEffect, useState as useState2 } from "react";
// src/SiteMenu/MenuListItem/MenuListItemContainer.tsx
import { ListItemText, useTheme as useTheme4 } from "@mui/material";
import { FlexRow as FlexRow3 } from "@xylabs/react-flexbox";
import { useCollapsible as useCollapsible2 } from "@xylabs/react-shared";
import { isString as isString3 } from "@xylabs/typeof";
import { useState } from "react";
import { NavLink } from "react-router-dom";
// src/SiteMenu/MenuListItem/list-item-components/ListItemTooltip.tsx
import { InfoOutlined } from "@mui/icons-material";
import { Tooltip } from "@mui/material";
import { FlexCol } from "@xylabs/react-flexbox";
import { jsx as jsx5 } from "react/jsx-runtime";
var ListItemTooltip = ({ title, ...props }) => {
return /* @__PURE__ */ jsx5(Tooltip, { title, placement: "right", ...props, children: /* @__PURE__ */ jsx5("div", { children: /* @__PURE__ */ jsx5(FlexCol, { justifyContent: "center", children: /* @__PURE__ */ jsx5(InfoOutlined, { sx: { color: "grey" } }) }) }) });
};
// src/SiteMenu/MenuListItem/list-item-components/MenuIcon.tsx
import { Typography as Typography2 } from "@mui/material";
import { jsx as jsx6 } from "react/jsx-runtime";
var MenuIcon = ({ icon, ...props }) => {
return /* @__PURE__ */ jsx6(Typography2, { display: "flex", ...props, children: icon });
};
// src/SiteMenu/MenuListItem/list-item-components/MenuListItem.tsx
import { ListItem } from "@mui/material";
import { jsx as jsx7 } from "react/jsx-runtime";
var MenuListItem = ({
iconOnly,
collapseEnd,
sx,
children,
dense,
...props
}) => {
const listItemSx = iconOnly ? {
borderRadius: "50%",
display: "inline-flex",
flexGrow: 0,
width: "auto"
} : { width: "100%" };
const spacingSx = collapseEnd ? { columnGap: 0 } : { columnGap: 1.5 };
const paddingSx = dense ? { px: "8px" } : { px: "12px" };
return /* @__PURE__ */ jsx7(
ListItem,
{
sx: {
...listItemSx,
...spacingSx,
...paddingSx,
...sx
},
...props,
children
}
);
};
// src/SiteMenu/MenuListItem/sub-nav/SubNavListItemCollapse.tsx
import { Collapse, List } from "@mui/material";
import { jsx as jsx8 } from "react/jsx-runtime";
var SubNavListItemsCollapse = ({
collapse,
openSubNav,
children,
...props
}) => {
return /* @__PURE__ */ jsx8(Collapse, { in: collapse == true ? false : openSubNav, ...props, children: /* @__PURE__ */ jsx8(List, { children }) });
};
// src/SiteMenu/MenuListItem/sub-nav/SubNavToggleIconButton.tsx
import { ExpandMore } from "@mui/icons-material";
import { IconButton, useTheme as useTheme3 } from "@mui/material";
import { jsx as jsx9 } from "react/jsx-runtime";
var SubNavToggleIconButton = ({ setOpenSubNav, openSubNav }) => {
const theme = useTheme3();
return /* @__PURE__ */ jsx9(
IconButton,
{
onClick: (event) => {
event.stopPropagation();
setOpenSubNav?.(!openSubNav);
},
sx: { marginRight: theme.spacing(0.5) },
children: /* @__PURE__ */ jsx9(ExpandMore, {})
}
);
};
// src/SiteMenu/MenuListItem/MenuListItemContainer.tsx
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
var MenuListItemContainer = ({
style,
icon,
iconMenuTextSpacing,
iconOnly,
onButtonClick,
primary,
subNavListItems,
sx,
tooltip,
to,
...props
}) => {
const { dense } = props;
const theme = useTheme4();
const { collapse } = useCollapsible2();
const [openSubNav, setOpenSubNav] = useState(false);
const [hovered, setHovered] = useState(false);
const resolvedIconMenuTextSpacing = iconMenuTextSpacing ?? theme.spacing(1);
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
/* @__PURE__ */ jsxs4(
MenuListItem,
{
disableGutters: true,
iconOnly,
onClick: onButtonClick,
dense,
sx: { justifyContent: "space-between", ...sx },
style: { whiteSpace: "nowrap", ...style },
...props,
children: [
/* @__PURE__ */ jsxs4(
NavLink,
{
className: "site-menu-nav-link",
onMouseEnter: (e) => {
const el = e.currentTarget;
el.style.cursor = "pointer";
el.style.textDecoration = "underline";
el.style.filter = "brightness(75%)";
setHovered(true);
},
onMouseLeave: (e) => {
const el = e.currentTarget;
el.style.cursor = "default";
el.style.textDecoration = "none";
el.style.filter = "";
setHovered(false);
},
color: "inherit",
to: to ?? "",
viewTransition: true,
style: {
color: "inherit",
textDecoration: "none",
display: "flex",
alignItems: "center"
},
children: [
/* @__PURE__ */ jsx10(MenuIcon, { icon, paddingRight: resolvedIconMenuTextSpacing, color: hovered ? "secondary" : "inherit" }),
/* @__PURE__ */ jsx10(ListItemText, { primary })
]
}
),
/* @__PURE__ */ jsxs4(FlexRow3, { style: { marginLeft: theme.spacing(1) }, children: [
subNavListItems ? /* @__PURE__ */ jsx10(SubNavToggleIconButton, { setOpenSubNav, openSubNav }) : null,
isString3(tooltip) ? /* @__PURE__ */ jsx10(ListItemTooltip, { title: tooltip }) : null
] })
]
}
),
subNavListItems ? /* @__PURE__ */ jsx10(SubNavListItemsCollapse, { openSubNav, collapse, children: subNavListItems?.map((item, index) => /* @__PURE__ */ jsx10(MenuListItemContainer, { dense, sx: { pl: theme.spacing(1) }, ...item }, index)) }) : null
] });
};
// src/SiteMenu/Menu.tsx
import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
var SiteMenu = ({
children,
onMenuToggle,
side = "right",
...props
}) => {
const [open, setOpen] = useState2(false);
useEffect(() => {
onMenuToggle?.(open);
}, [onMenuToggle, open]);
return /* @__PURE__ */ jsxs5(FlexRow4, { alignItems: "stretch", ...props, children: [
/* @__PURE__ */ jsx11(
IconButton2,
{
size: "small",
color: "inherit",
onClick: () => {
setOpen(!open);
},
children: /* @__PURE__ */ jsx11(MenuIcon2, { fontSize: "large" })
}
),
/* @__PURE__ */ jsx11(
SwipeableDrawer,
{
anchor: side,
open,
onClick: () => setOpen(false),
onKeyDown: () => setOpen(false),
onClose: () => setOpen(false),
onOpen: () => setOpen(true),
children: children ?? /* @__PURE__ */ jsx11(List2, { children: /* @__PURE__ */ jsx11(MenuListItemContainer, { primary: "Settings", icon: /* @__PURE__ */ jsx11(SettingsIcon, {}), to: "/settings" }) })
}
)
] });
};
// src/SiteMenu/MenuSection.tsx
import { Collapse as Collapse2, ListSubheader } from "@mui/material";
import { FlexCol as FlexCol2 } from "@xylabs/react-flexbox";
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
var MenuSection = ({
iconMenuTextSpacing,
listItems,
showTitle = true,
title,
...props
}) => {
return /* @__PURE__ */ jsxs6(FlexCol2, { alignItems: "stretch", ...props, children: [
/* @__PURE__ */ jsx12(Collapse2, { in: showTitle, timeout: 700, children: /* @__PURE__ */ jsx12(ListSubheader, { children: title }) }),
listItems.map((item, index) => /* @__PURE__ */ jsx12(MenuListItemContainer, { iconMenuTextSpacing, ...item }, index))
] });
};
// src/Toolbar/System/SystemToolbar.tsx
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
var SystemToolbar = ({
children,
darkModeButton = false,
menuItems,
onMenuToggle,
precedingChildren,
...props
}) => {
return /* @__PURE__ */ jsxs7(Toolbar3, { ...props, children: [
precedingChildren,
children,
darkModeButton ? /* @__PURE__ */ jsx13(ColorSchemeButton, {}) : null,
isDefinedNotNull2(menuItems) ? /* @__PURE__ */ jsx13(SiteMenu, { onMenuToggle, children: menuItems }) : null
] });
};
// src/AppBar/Application.tsx
import { jsx as jsx14 } from "react/jsx-runtime";
var ApplicationAppBar = ({
logo,
systemToolbar,
contextToolbar,
responsive = true,
...props
}) => {
return /* @__PURE__ */ jsx14(
AppBarEx,
{
systemToolbar: systemToolbar ?? /* @__PURE__ */ jsx14(SystemToolbar, {}),
contextToolbar: contextToolbar ?? /* @__PURE__ */ jsx14(ContextToolbar, { logo }),
position: "sticky",
responsive,
...props
}
);
};
export {
AppBarEx,
ApplicationAppBar,
ContextToolbar,
MenuListItemContainer,
MenuSection,
SiteMenu,
SystemToolbar,
useMenuItemsShared
};
//# sourceMappingURL=index.mjs.map