@hitachivantara/uikit-react-core
Version:
Core React components for the NEXT Design System.
137 lines (136 loc) • 4.11 kB
JavaScript
import { jsx } from "react/jsx-runtime";
import { forwardRef, useMemo } from "react";
import { useDefaultProps } from "@hitachivantara/uikit-react-utils";
import { useBaseDropdownContext } from "../BaseDropdown/context.js";
import { useControlled } from "../hooks/useControlled.js";
import { useLabels } from "../hooks/useLabels.js";
import { useUniqueId } from "../hooks/useUniqueId.js";
import { HvIcon } from "../icons.js";
import { getPrevNextFocus } from "../utils/focusableElementFinder.js";
import { isKey } from "../utils/keyboardUtils.js";
import { setId } from "../utils/setId.js";
import { useClasses } from "./DropDownMenu.styles.js";
import { staticClasses } from "./DropDownMenu.styles.js";
import { HvBaseDropdown } from "../BaseDropdown/BaseDropdown.js";
import { HvList } from "../List/List.js";
import { HvDropdownButton } from "../DropdownButton/DropdownButton.js";
const DEFAULT_LABELS = {
dropdownMenu: "Dropdown menu"
};
const HeaderComponent = forwardRef(
function HeaderComponent2(props, ref) {
const { open, icon, disabled, ...others } = props;
const { popperPlacement } = useBaseDropdownContext();
return /* @__PURE__ */ jsx(
HvDropdownButton,
{
icon: true,
ref,
open,
disabled,
"aria-expanded": open,
"aria-haspopup": "menu",
placement: popperPlacement,
...others,
children: icon || /* @__PURE__ */ jsx(HvIcon, { name: "DotsVertical" })
}
);
}
);
const HvDropDownMenu = forwardRef(function HvDropDownMenu2(props, ref) {
const {
id: idProp,
classes: classesProp,
className,
icon,
placement = "right",
dataList,
disablePortal = false,
onToggle,
onClick,
keepOpened = true,
disabled = false,
expanded,
defaultExpanded = false,
category = "secondaryGhost",
// TODO - remove and update variant default in v6
variant,
size = "md",
labels: labelsProp,
...others
} = useDefaultProps("HvDropDownMenu", props);
const { classes, cx } = useClasses(classesProp);
const labels = useLabels(DEFAULT_LABELS, labelsProp);
const [open, setOpen] = useControlled(expanded, Boolean(defaultExpanded));
const id = useUniqueId(idProp);
const listId = setId(id, "list");
const handleClose = (event) => {
setOpen(false);
onToggle?.(event, false);
};
const handleKeyDown = (event) => {
if (isKey(event, "Tab")) {
const focusNodes = getPrevNextFocus(setId(id, "icon-button"));
const node = event.shiftKey ? focusNodes.prevFocus : focusNodes.nextFocus;
if (node) setTimeout(() => node.focus(), 0);
handleClose(event);
}
event.preventDefault();
};
const condensed = useMemo(() => dataList.every((el) => !el.icon), [dataList]);
return /* @__PURE__ */ jsx(
HvBaseDropdown,
{
ref,
id,
className: cx(classes.root, classes.container, classes.icon, className, {
[classes.iconSelected]: open
// TODO: rename to open
}),
classes: {
container: classes.baseContainer,
panel: classes.menuListRoot
},
expanded: open && !disabled,
headerComponent: HeaderComponent,
size,
variant: variant ?? category,
open,
"aria-label": labels.dropdownMenu,
icon,
placement,
variableWidth: true,
disablePortal,
onToggle: (e, s) => {
setOpen(s);
onToggle?.(e, s);
},
disabled,
onContainerCreation: (containerEl) => {
containerEl?.getElementsByTagName("li")[0]?.focus();
},
...others,
children: /* @__PURE__ */ jsx(
HvList,
{
id: listId,
values: dataList,
selectable: false,
condensed,
onClick: (event, item) => {
if (!keepOpened) handleClose(event);
onClick?.(event, item);
},
onKeyDown: handleKeyDown,
classes: {
root: classes.menuList
}
}
)
}
);
});
export {
HvDropDownMenu,
staticClasses as dropDownMenuClasses
};