UNPKG

@clayui/drop-down

Version:
263 lines (262 loc) 9.21 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 DropDown_exports = {}; __export(DropDown_exports, { default: () => DropDown_default }); module.exports = __toCommonJS(DropDown_exports); var import_core = require("@clayui/core"); var import_icon = __toESM(require("@clayui/icon")); var import_shared = require("@clayui/shared"); var import_classnames = __toESM(require("classnames")); var import_react = __toESM(require("react")); var import_Action = __toESM(require("./Action")); var import_Caption = __toESM(require("./Caption")); var import_Divider = __toESM(require("./Divider")); var import_DropDownContext = require("./DropDownContext"); var import_FocusMenu = require("./FocusMenu"); var import_Group = __toESM(require("./Group")); var import_Help = __toESM(require("./Help")); var import_Item = __toESM(require("./Item")); var import_ItemList = __toESM(require("./ItemList")); var import_Menu = __toESM(require("./Menu")); var import_Search = __toESM(require("./Search")); var import_Section = __toESM(require("./Section")); const { Collection } = import_core.__NOT_PUBLIC_COLLECTION; const List = import_react.default.forwardRef(function List2({ children, ...otherProps }, ref) { return /* @__PURE__ */ import_react.default.createElement("ul", { ...otherProps, className: "list-unstyled", ref }, children); }); let counter = 0; function DropDown({ active, alignmentByViewport, alignmentPosition, children, className, closeOnClick = false, closeOnClickOutside, containerElement: ContainerElement = "div", defaultActive = false, filterKey, hasLeftSymbols, hasRightSymbols, items, menuElementAttrs, menuHeight, menuWidth, offsetFn, onActiveChange, renderMenuOnClick = false, role = "menu", trigger, triggerIcon = null, ...otherProps }) { const triggerElementRef = (0, import_react.useRef)(null); const menuElementRef = (0, import_react.useRef)(null); const [initialized, setInitialized] = (0, import_react.useState)(!renderMenuOnClick); const [internalActive, setInternalActive] = (0, import_shared.useControlledState)({ defaultName: "defaultActive", defaultValue: defaultActive, handleName: "onActiveChange", name: "active", onChange: onActiveChange, value: active }); const [search, setSearch] = (0, import_react.useState)(""); const ariaControls = (0, import_react.useMemo)(() => { counter++; return `clay-dropdown-menu-${counter}`; }, []); const openMenu = (0, import_react.useCallback)( (value) => { if (!initialized) { setInitialized(true); } setInternalActive(value); }, [initialized] ); const { navigationProps } = (0, import_shared.useNavigation)({ activation: "manual", containerRef: menuElementRef, loop: true, orientation: "vertical", typeahead: true, visible: internalActive }); return /* @__PURE__ */ import_react.default.createElement( ContainerElement, { ...otherProps, className: (0, import_classnames.default)("dropdown", className) }, import_react.default.cloneElement(trigger, { "aria-controls": internalActive ? ariaControls : void 0, "aria-expanded": internalActive, "aria-haspopup": "true", "children": import_react.default.isValidElement(trigger) && // @ts-ignore trigger?.type.displayName === "ClayButton" && triggerIcon ? /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, trigger.props.children, " ", /* @__PURE__ */ import_react.default.createElement(import_icon.default, { className: "ml-1", symbol: triggerIcon })) : trigger.props.children, "className": (0, import_classnames.default)( "dropdown-toggle", trigger.props.className ), "onClick": (event) => { if (trigger.props.onClick) { trigger.props.onClick(event); } openMenu(!internalActive); }, "onKeyDown": (event) => { if (trigger.props.onKeyDown) { trigger.props.onKeyDown(event); } if (event.key === import_shared.Keys.Spacebar) { openMenu(!internalActive); } if (event.key === import_shared.Keys.Down) { event.preventDefault(); event.stopPropagation(); openMenu(true); } if (internalActive && event.key === import_shared.Keys.Down) { event.preventDefault(); event.stopPropagation(); const list = (0, import_shared.getFocusableList)(menuElementRef); if (list.length) { list[0].focus(); } } if ([import_shared.Keys.Spacebar, import_shared.Keys.Down].includes(event.key)) { event.preventDefault(); } }, "ref": (node) => { triggerElementRef.current = node; const { ref } = trigger; if (typeof ref === "function") { ref(node); } } }), initialized && /* @__PURE__ */ import_react.default.createElement( import_Menu.default, { ...menuElementAttrs, active: internalActive, alignElementRef: triggerElementRef, alignmentByViewport, alignmentPosition, closeOnClickOutside, hasLeftSymbols, hasRightSymbols, height: menuHeight, id: ariaControls, offsetFn, onActiveChange: setInternalActive, onKeyDown: (event) => { if (menuElementAttrs?.onKeyDown) { menuElementAttrs.onKeyDown(event); } if (event.key === import_shared.Keys.Tab) { event.preventDefault(); openMenu(false); const list = Array.from( document.querySelectorAll( import_shared.FOCUSABLE_ELEMENTS.join(",") ) ); const position = list.indexOf( triggerElementRef.current ); const nextElement = list[position + 1]; if (nextElement) { nextElement.focus(); } } navigationProps.onKeyDown(event); }, ref: menuElementRef, suppress: [triggerElementRef, menuElementRef], triggerRef: triggerElementRef, width: menuWidth }, /* @__PURE__ */ import_react.default.createElement( import_FocusMenu.FocusMenu, { condition: internalActive, onRender: () => { setTimeout(() => { const list = (0, import_shared.getFocusableList)(menuElementRef); if (list.length) { list[0].focus(); } }, 10); } }, /* @__PURE__ */ import_react.default.createElement( import_DropDownContext.DropDownContext.Provider, { value: { close: () => { setInternalActive(false); triggerElementRef.current?.focus(); }, closeOnClick, filterKey, onSearch: setSearch, search, tabFocus: false } }, children instanceof Function ? /* @__PURE__ */ import_react.default.createElement( Collection, { as: List, items, role }, children ) : children ) ) ) ); } DropDown.Action = import_Action.default; DropDown.Caption = import_Caption.default; DropDown.Divider = import_Divider.default; DropDown.Group = import_Group.default; DropDown.Help = import_Help.default; DropDown.Menu = import_Menu.default; DropDown.Item = import_Item.default; DropDown.ItemList = import_ItemList.default; DropDown.Search = import_Search.default; DropDown.Section = import_Section.default; var DropDown_default = DropDown;