UNPKG

@clayui/drop-down

Version:
282 lines (281 loc) 10.4 kB
"use strict"; 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";