@hitachivantara/uikit-react-core
Version:
Core React components for the NEXT Design System.
127 lines (126 loc) • 3.76 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { useContext } from "react";
import { useDefaultProps } from "@hitachivantara/uikit-react-utils";
import { isKey } from "../../../utils/keyboardUtils.js";
import { Bar } from "../MenuBar/Bar.js";
import { FocusContext } from "../utils/FocusContext.js";
import { SelectionContext } from "../utils/SelectionContext.js";
import { useClasses } from "./MenuItem.styles.js";
import { staticClasses } from "./MenuItem.styles.js";
import { HvTypography } from "../../../Typography/Typography.js";
const traverseItem = (node) => {
let href;
let target;
if (node?.href) {
href = node?.href;
target = node?.target;
} else if (node?.data != null && node?.data?.length > 0) {
let i = 0;
while (href == null && i < node.data.length) {
const childNavItem = traverseItem(node?.data[i]);
if (childNavItem?.href != null) {
href = childNavItem?.href;
target = childNavItem?.target;
break;
}
i += 1;
}
}
return { href, target };
};
const HvHeaderMenuItem = (props) => {
const {
id,
item,
type,
onClick,
levels,
currentLevel,
classes: classesProp,
className
} = useDefaultProps("HvHeaderMenuItem", props);
const { classes, cx } = useClasses(classesProp);
const selectionPath = useContext(SelectionContext);
const { dispatch } = useContext(FocusContext);
const { data } = item;
const hasSubLevel = data?.length;
const isMenu = type === "menu";
const isSelected = selectionPath?.[isMenu ? 1 : 0] === item.id;
const isCurrent = isSelected ? hasSubLevel ? true : "page" : void 0;
const actionHandler = (event) => {
if (event.type === "click" || isKey(event, "Enter") || isKey(event, "Space")) {
if (event.type === "click") {
event.currentTarget.blur();
}
onClick?.(event, item);
}
};
const handleFocus = (event) => {
dispatch?.({ type: "setItemFocused", itemFocused: event.currentTarget });
};
const label = /* @__PURE__ */ jsx(
HvTypography,
{
component: "span",
variant: isSelected ? "label" : "body",
"data-text": item.label,
children: item.label
}
);
let itemHref = item?.href;
let itemTarget = item?.target;
if (item?.href == null) {
const { href, target } = traverseItem(item);
itemHref = href;
itemTarget = target;
}
const ItemComponent = itemHref ? "a" : "div";
const itemProps = itemHref ? { href: itemHref, target: itemTarget, "aria-label": item.label } : { role: "button", tabIndex: 0 };
return /* @__PURE__ */ jsxs(
"li",
{
id,
className: cx(
classes.root,
{
[classes.menu]: isMenu,
[classes.menubar]: !isMenu,
[classes.selected]: !!isSelected
},
className
),
children: [
/* @__PURE__ */ jsx(
ItemComponent,
{
className: cx(classes.item, {
[classes.link]: itemHref,
[classes.button]: !itemHref
}),
onFocus: handleFocus,
onClick: actionHandler,
onKeyDown: actionHandler,
"aria-current": isCurrent,
...itemProps,
children: label
}
),
hasSubLevel && currentLevel < levels && currentLevel < 2 && /* @__PURE__ */ jsx(Bar, { data, type: "menu", children: data.map((itm) => /* @__PURE__ */ jsx(
HvHeaderMenuItem,
{
item: itm,
type: "menu",
onClick,
levels,
currentLevel: currentLevel + 1
},
itm.id
)) })
]
}
);
};
export {
HvHeaderMenuItem,
staticClasses as headerMenuItemClasses
};