UNPKG

@clayui/drop-down

Version:
197 lines (196 loc) 5.31 kB
import { useControlledState, useIsMobileDevice } from "@clayui/shared"; import React, { useMemo, useRef } from "react"; import Caption from "./Caption"; import ClayDropDown from "./DropDown"; import { ClayDropDownWithDrilldown } from "./DropDownWithDrilldown"; import Help from "./Help"; import { ClayDropDownContext, DropDownItems, findNested } from "./Items"; import Search from "./Search"; let counter = 0; function getId() { return `id-${counter++}`; } function transformTreeToLinkedList(items, id, menu = {}) { menu[id] = []; items?.forEach((item, index) => { const keys = Object.keys(item); menu[id][index] = {}; keys.forEach((key) => { if (item["type"] === "contextual" && Array.isArray(item[key])) { const childId = getId(); menu[id][index].child = childId; transformTreeToLinkedList(item[key], childId, menu); } else { if (item[key] === "contextual") { menu[id][index].type = "item"; } else { menu[id][index][key] = item[key]; } } }); }); return menu; } function ClayDropDownWithItems({ active, alignmentByViewport, alignmentPosition, caption, className, closeOnClickOutside, containerElement, defaultActive = false, footerContent, helpText, items, menuElementAttrs, menuHeight, menuWidth, offsetFn, onActiveChange, onSearchValueChange = () => { }, renderMenuOnClick, searchable, searchProps, searchValue = "", triggerIcon = null, spritemap, trigger }) { const triggerElementRef = useRef(null); const [internalActive, setInternalActive] = useControlledState({ defaultName: "defaultActive", defaultValue: defaultActive, handleName: "onActiveChange", name: "active", onChange: onActiveChange, value: active }); const hasRightSymbols = useMemo( () => !!findNested(items, "symbolRight"), [items] ); const hasLeftSymbols = useMemo( () => !!findNested(items, "symbolLeft"), [items] ); const hasContextual = useMemo( () => items.some((item) => item.type === "contextual"), [items] ); const Wrap = footerContent ? "form" : React.Fragment; const isMobile = useIsMobileDevice(); const activeMenu = useMemo(() => getId(), []); const linkedList = useMemo(() => { if (isMobile && hasContextual) { return transformTreeToLinkedList(items, activeMenu); } }, [items, hasContextual, isMobile]); if (hasContextual && isMobile) { return /* @__PURE__ */ React.createElement( ClayDropDownWithDrilldown, { active: internalActive, alignmentByViewport, alignmentPosition, caption, className, containerElement, defaultActiveMenu: activeMenu, footerContent, helpText, menuElementAttrs, menuHeight, menuWidth, menus: linkedList, offsetFn, onActiveChange: setInternalActive, onSearchValueChange, renderMenuOnClick, searchProps, searchValue, searchable, trigger, triggerIcon } ); } else { return /* @__PURE__ */ React.createElement( ClayDropDown, { active: internalActive, alignmentByViewport, alignmentPosition, className, closeOnClickOutside, containerElement, hasLeftSymbols, hasRightSymbols, menuElementAttrs, menuHeight, menuWidth, offsetFn, onActiveChange: setInternalActive, renderMenuOnClick, trigger: React.cloneElement(trigger, { ref: (node) => { if (node) { triggerElementRef.current = node; const { ref } = trigger; if (typeof ref === "function") { ref(node); } } } }), triggerIcon }, /* @__PURE__ */ React.createElement( ClayDropDownContext.Provider, { value: { close: () => { setInternalActive(false); triggerElementRef.current?.focus(); } } }, helpText && /* @__PURE__ */ React.createElement(Help, null, helpText), searchable && /* @__PURE__ */ React.createElement( Search, { ...searchProps, onChange: onSearchValueChange, spritemap, value: searchValue } ), /* @__PURE__ */ React.createElement(Wrap, null, footerContent ? /* @__PURE__ */ React.createElement("div", { className: "inline-scroller" }, /* @__PURE__ */ React.createElement( DropDownItems, { items, spritemap } )) : /* @__PURE__ */ React.createElement( DropDownItems, { items, spritemap } ), caption && /* @__PURE__ */ React.createElement(Caption, null, caption), footerContent && /* @__PURE__ */ React.createElement( "div", { className: "dropdown-section", role: "presentation" }, footerContent )) ) ); } } ClayDropDownWithItems.displayName = "ClayDropDownWithItems"; export { ClayDropDownWithItems };