@clayui/drop-down
Version:
ClayDropDown component
282 lines (281 loc) • 10.4 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var DropDownWithDrilldown_exports = {};
__export(DropDownWithDrilldown_exports, {
ClayDropDownWithDrilldown: () => ClayDropDownWithDrilldown
});
module.exports = __toCommonJS(DropDownWithDrilldown_exports);
var import_button = require("@clayui/button");
var import_shared = require("@clayui/shared");
var import_classnames = __toESM(require("classnames"));
var import_react = __toESM(require("react"));
var import_react_transition_group = require("react-transition-group");
var import_Caption = __toESM(require("./Caption"));
var import_DropDown = __toESM(require("./DropDown"));
var import_Help = __toESM(require("./Help"));
var import_Items = require("./Items");
var import_Search = __toESM(require("./Search"));
function ClayDropDownWithDrilldown({
active: externalActive,
alignmentByViewport,
alignmentPosition,
caption,
className,
containerElement,
defaultActive = false,
footerContent,
helpText,
defaultActiveMenu,
initialActiveMenu,
menuElementAttrs,
menuHeight,
menuWidth,
menus,
messages = {
back: "Back",
goTo: "Go to"
},
offsetFn,
onActiveChange,
onSearchValueChange = () => {
},
renderMenuOnClick,
searchable,
searchProps,
searchValue = "",
spritemap,
trigger,
triggerIcon = null
}) {
const [activeMenu, setActiveMenu] = (0, import_react.useState)(
defaultActiveMenu ?? initialActiveMenu
);
const [direction, setDirection] = (0, import_react.useState)();
const [history, setHistory] = (0, import_react.useState)([]);
const triggerElementRef = (0, import_react.useRef)(null);
const { isFocusVisible } = (0, import_shared.useInteractionFocus)();
const [active, setActive] = (0, import_shared.useControlledState)({
defaultName: "defaultActive",
defaultValue: defaultActive,
handleName: "onActiveChange",
name: "active",
onChange: onActiveChange,
value: externalActive
});
const focusHistoryRef = (0, import_react.useRef)([]);
const innerRef = (0, import_react.useRef)(null);
const menuIds = Object.keys(menus);
const Wrap = footerContent ? "form" : import_react.default.Fragment;
(0, import_react.useEffect)(() => {
if (!isFocusVisible()) {
return;
}
if (innerRef.current) {
if (direction === "prev") {
const [previous] = focusHistoryRef.current.slice(-1);
focusHistoryRef.current = focusHistoryRef.current.slice(
0,
focusHistoryRef.current.length - 1
);
previous?.focus();
} else {
const itemEl = innerRef.current.querySelector(
".drilldown-current a.dropdown-item, .drilldown-current button.dropdown-item"
);
focusHistoryRef.current = [
...focusHistoryRef.current,
document.activeElement
];
itemEl?.focus();
}
}
}, [activeMenu, direction, innerRef, focusHistoryRef, menus]);
const onBack = (0, import_react.useCallback)(() => {
const [parent] = history.slice(-1);
setHistory(history.slice(0, history.length - 1));
setDirection("prev");
setActiveMenu(parent.id);
}, [history]);
const onForward = (0, import_react.useCallback)(
(label, id) => {
setHistory((history2) => [
...history2,
{ id: activeMenu, title: label }
]);
setDirection("next");
setActiveMenu(id);
},
[activeMenu]
);
const onClose = (0, import_react.useCallback)(() => {
setActive(false);
triggerElementRef.current?.focus();
}, []);
const hasLeftSymbols = (0, import_react.useMemo)(
() => menus[activeMenu] ? (0, import_Items.findNested)(menus[activeMenu], "symbolLeft") : false,
[activeMenu, menus]
);
return /* @__PURE__ */ import_react.default.createElement(
import_DropDown.default,
{
active,
alignmentByViewport,
alignmentPosition,
className,
containerElement,
hasLeftSymbols,
hasRightSymbols: true,
menuElementAttrs: {
...menuElementAttrs,
className: (0, import_classnames.default)(menuElementAttrs?.className, "drilldown")
},
menuHeight,
menuWidth,
offsetFn,
onActiveChange: (value) => {
if (!active) {
setActiveMenu(defaultActiveMenu);
focusHistoryRef.current = [];
setHistory([]);
setDirection("prev");
}
setActive(value);
},
renderMenuOnClick,
trigger: import_react.default.cloneElement(trigger, {
ref: (node) => {
if (node) {
triggerElementRef.current = node;
const { ref } = trigger;
if (typeof ref === "function") {
ref(node);
}
}
}
}),
triggerIcon
},
/* @__PURE__ */ import_react.default.createElement(
import_Items.ClayDropDownContext.Provider,
{
value: {
close: onClose,
messages,
onForward
}
},
/* @__PURE__ */ import_react.default.createElement("div", { className: "drilldown-inner", ref: innerRef }, menuIds.map((menuKey) => {
const items = menus[menuKey].map(
({ label, title, ...item }) => ({
...item,
label: label || title
})
);
const header = activeMenu === menuKey && !!history.length ? history.slice(-1)[0].title : void 0;
const initialClasses = (0, import_classnames.default)("transitioning", {
"drilldown-prev-initial": direction === "prev"
});
const active2 = activeMenu === menuKey;
return /* @__PURE__ */ import_react.default.createElement(
import_react_transition_group.CSSTransition,
{
"aria-hidden": !active2,
className: (0, import_classnames.default)("drilldown-item", {
"drilldown-current": active2
}),
classNames: {
enter: initialClasses,
enterActive: `drilldown-transition drilldown-${direction}-active`,
exit: initialClasses,
exitActive: `drilldown-transition drilldown-${direction}-active`
},
in: active2,
key: menuKey,
timeout: 250
},
/* @__PURE__ */ import_react.default.createElement("div", { className: "drilldown-item-inner" }, header && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(
"div",
{
className: "dropdown-header",
"data-testid": `back-button-${header}`,
onClick: onBack
},
/* @__PURE__ */ import_react.default.createElement(
import_button.ClayButtonWithIcon,
{
"aria-label": messages.back,
className: "component-action dropdown-item-indicator-start",
onClick: onBack,
spritemap,
symbol: "angle-left",
tabIndex: -1,
title: messages.back
}
),
/* @__PURE__ */ import_react.default.createElement("span", { className: "dropdown-item-indicator-text-start" }, header)
), /* @__PURE__ */ import_react.default.createElement("div", { className: "dropdown-divider" })), defaultActiveMenu === menuKey ? /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, helpText && /* @__PURE__ */ import_react.default.createElement(import_Help.default, null, helpText), searchable && /* @__PURE__ */ import_react.default.createElement(
import_Search.default,
{
...searchProps,
onChange: onSearchValueChange,
spritemap,
value: searchValue
}
), /* @__PURE__ */ import_react.default.createElement(Wrap, null, footerContent ? /* @__PURE__ */ import_react.default.createElement("div", { className: "inline-scroller" }, /* @__PURE__ */ import_react.default.createElement(
import_Items.DropDownItems,
{
items,
spritemap
}
)) : /* @__PURE__ */ import_react.default.createElement(
import_Items.DropDownItems,
{
items,
spritemap
}
), caption && /* @__PURE__ */ import_react.default.createElement(import_Caption.default, null, caption), footerContent && /* @__PURE__ */ import_react.default.createElement(
"div",
{
className: "dropdown-section",
role: "presentation"
},
footerContent
))) : /* @__PURE__ */ import_react.default.createElement(
import_Items.DropDownItems,
{
items,
spritemap
}
))
);
}))
)
);
}
ClayDropDownWithDrilldown.displayName = "ClayDropDownWithDrilldown";