"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; 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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { createMenu: () => createMenu, createMenuItem: () => createMenuItem, createMenuSection: () => createMenuSection, createMenuTrigger: () => createMenuTrigger, createMenuTriggerState: () => createMenuTriggerState, useMenuContext: () => useMenuContext }); module.exports = __toCommonJS(src_exports); // src/createMenu.ts var import_selection = require("@solid-aria/selection"); var import_tree = require("@solid-aria/tree"); var import_utils2 = require("@solid-aria/utils"); // ../../node_modules/.pnpm/@solid-primitives+props@2.1.7_solid-js@1.4.4/node_modules/@solid-primitives/props/dist/esm/index.js var import_web = require("solid-js/web"); var import_solid_js = require("solid-js"); var import_utils = require("@solid-primitives/utils"); var extractCSSregex = /([^:; ]*):\s*([^;]*)/g; var isEventListenerKey = (key) => key[0] === "o" && key[1] === "n" && key.length > 2 && key[2] !== ":" && !key.startsWith("oncapture:"); function stringStyleToObject(style) { const object = {}; let match; while (match = extractCSSregex.exec(style)) { object[match[1]] = match[2]; } return object; } function combineStyle(a, b) { if (typeof a === "object" && typeof b === "object") return { ...a, ...b }; if (typeof a === "string" && typeof b === "string") return `${a};${b}`; const objA = typeof a === "object" ? a : stringStyleToObject(a); const objB = typeof b === "object" ? b : stringStyleToObject(b); return { ...objA, ...objB }; } function combineProps(...sources) { if (sources.length === 1) return sources[0]; const merge = (0, import_solid_js.mergeProps)(...sources); const reduce = (key, calc) => { let v = void 0; for (const props of sources) { const propV = props[key]; if (!v) v = propV; else if (propV) v = calc(v, propV); } return v; }; const listeners = {}; for (const props of sources) { for (const key in props) { if (!isEventListenerKey(key)) continue; const v = props[key]; const name = key.toLowerCase(); let callback; if (typeof v === "function") callback = v; else if (Array.isArray(v)) { if (v.length === 1) callback = v[0]; else callback = v[0].bind(void 0, v[1]); } else { delete listeners[name]; continue; } const callbacks = listeners[name]; if (!callbacks) listeners[name] = [callback]; else callbacks.push(callback); } } return new Proxy(merge, { get(target, key) { if (typeof key !== "string") return Reflect.get(target, key); if (key === "style") return reduce("style", combineStyle); if (key === "ref") { const callbacks = []; for (const props of sources) { const cb = props[key]; if (typeof cb === "function") callbacks.push(cb); } return (0, import_utils.chain)(callbacks); } if (isEventListenerKey(key)) { const callbacks = listeners[key.toLowerCase()]; return Array.isArray(callbacks) ? (0, import_utils.chain)(callbacks) : Reflect.get(target, key); } if (key === "class" || key === "className") return reduce(key, (a, b) => `${a} ${b}`); if (key === "classList") return reduce(key, (a, b) => ({ ...a, ...b })); return Reflect.get(target, key); } }); } // src/createMenu.ts var import_solid_js2 = require("solid-js"); function createMenu(props, ref) { const defaultProps = { shouldFocusWrap: true, closeOnSelect: true, selectionMode: "none" }; props = (0, import_solid_js2.mergeProps)(defaultProps, props); const state = (0, import_tree.createTreeState)(props); const domProps = (0, import_solid_js2.mergeProps)((0, import_solid_js2.createMemo)(() => (0, import_utils2.filterDOMProps)(props, { labelable: true }))); const createSelectableListProps = (0, import_solid_js2.mergeProps)(props, { selectionManager: state.selectionManager, collection: state.collection, disabledKeys: state.disabledKeys }); const { listProps } = (0, import_selection.createSelectableList)(createSelectableListProps, ref); const baseMenuProps = { role: "menu" }; const menuProps = combineProps(domProps, listProps, baseMenuProps); const context = { state: () => state, closeOnSelect: () => props.closeOnSelect ?? true, shouldFocusOnHover: () => props.shouldFocusOnHover ?? false, isVirtualized: () => props.isVirtualized ?? false }; const MenuProvider = (props2) => { return (0, import_solid_js2.createComponent)(MenuContext.Provider, { value: context, get children() { return props2.children; } }); }; (0, import_solid_js2.onMount)(() => { if (!props["aria-label"] && !props["aria-labelledby"]) { console.warn("An aria-label or aria-labelledby prop is required for accessibility."); } }); return { MenuProvider, state, menuProps }; } var MenuContext = (0, import_solid_js2.createContext)(); function useMenuContext() { const context = (0, import_solid_js2.useContext)(MenuContext); if (!context) { throw new Error("[solid-aria]: useMenuContext should be used in a MenuProvider."); } return context; } // src/createMenuItem.ts var import_collection = require("@solid-aria/collection"); var import_interactions = require("@solid-aria/interactions"); var import_selection2 = require("@solid-aria/selection"); var import_utils3 = require("@solid-aria/utils"); var import_solid_js3 = require("solid-js"); function createMenuItem(props, ref) { const context = useMenuContext(); const [labelId] = (0, import_utils3.createSlotId)(); const [descriptionId] = (0, import_utils3.createSlotId)(); const [keyboardId] = (0, import_utils3.createSlotId)(); const manager = () => context.state().selectionManager(); const isDisabled = () => context.state().disabledKeys().has(props.key); const isSelected = () => manager().isSelected(props.key); const isFocused = () => manager().focusedKey() === props.key; const closeOnSelect = () => props.closeOnSelect ?? context.closeOnSelect(); const onKeyDown = (e) => { var _a, _b; if (e.repeat) { return; } switch (e.key) { case " ": if (!isDisabled() && manager().selectionMode() === "none" && closeOnSelect()) { (_a = props.onClose) == null ? void 0 : _a.call(props); } break; case "Enter": if (!isDisabled() && closeOnSelect()) { (_b = props.onClose) == null ? void 0 : _b.call(props); } break; } }; const onPressStart = (e) => { var _a; if (e.pointerType === "keyboard") { (_a = props.onAction) == null ? void 0 : _a.call(props, props.key); } }; const onPressUp = (e) => { var _a, _b; if (e.pointerType !== "keyboard") { (_a = props.onAction) == null ? void 0 : _a.call(props, props.key); if (closeOnSelect() ?? manager().selectionMode() !== "multiple") { (_b = props.onClose) == null ? void 0 : _b.call(props); } } }; const { itemProps, isPressed } = (0, import_selection2.createSelectableItem)({ key: () => props.key, selectionManager: manager, shouldSelectOnPressUp: true, allowsDifferentPressOrigin: true, isVirtualized: context.isVirtualized, isDisabled }, ref); const { pressProps } = (0, import_interactions.createPress)({ isDisabled, onPressStart, onPressUp }); const { hoverProps } = (0, import_interactions.createHover)({ isDisabled: () => isDisabled() || !context.shouldFocusOnHover(), onHoverStart: () => { if (!(0, import_interactions.isKeyboardFocusVisible)()) { manager().setFocused(true); manager().setFocusedKey(props.key); } } }); const baseMenuItemProps = { get role() { switch (manager().selectionMode()) { case "single": return "menuitemradio"; case "multiple": return "menuitemcheckbox"; default: return "menuitem"; } }, get "aria-disabled"() { return isDisabled(); }, get "aria-label"() { return props["aria-label"]; }, get "aria-labelledby"() { return labelId(); }, get "aria-describedby"() { return [descriptionId(), keyboardId()].filter(Boolean).join(" ") || void 0; }, get "aria-checked"() { return manager().selectionMode() !== "none" ? isSelected() : void 0; }, get "aria-posinset"() { if (!context.isVirtualized()) { return void 0; } const item = context.state().collection().getItem(props.key); return item ? item.index + 1 : void 0; }, get "aria-setsize"() { if (!context.isVirtualized()) { return void 0; } return (0, import_collection.getItemCount)(context.state().collection()); } }; const menuItemProps = (0, import_solid_js3.mergeProps)(baseMenuItemProps, combineProps(itemProps, pressProps, hoverProps, { onKeyDown })); const labelProps = { get id() { return labelId(); } }; const descriptionProps = { get id() { return descriptionId(); } }; const keyboardShortcutProps = { get id() { return keyboardId(); } }; return { isFocused, isSelected, isDisabled, isPressed, menuItemProps, labelProps, descriptionProps, keyboardShortcutProps }; } // src/createMenuSection.ts var import_utils4 = require("@solid-aria/utils"); var import_solid_js4 = require("solid-js"); function createMenuSection(props) { const headingId = (0, import_utils4.createId)(); const heading = (0, import_solid_js4.createMemo)(() => props.heading); const itemProps = { role: "presentation" }; const headingProps = { get id() { return heading() ? headingId : void 0; }, get "aria-hidden"() { return heading() ? true : void 0; } }; const groupProps = { role: "group", get "aria-label"() { return props["aria-label"]; }, get "aria-labelledby"() { return heading() ? headingId : void 0; } }; return { itemProps, headingProps, groupProps }; } // src/createMenuTrigger.ts var import_interactions2 = require("@solid-aria/interactions"); var import_overlays2 = require("@solid-aria/overlays"); var import_utils5 = require("@solid-aria/utils"); var import_solid_js6 = require("solid-js"); // src/createMenuTriggerState.ts var import_overlays = require("@solid-aria/overlays"); var import_solid_js5 = require("solid-js"); function createMenuTriggerState(props) { const overlayTriggerState = (0, import_overlays.createOverlayTriggerState)(props); const [focusStrategy, setFocusStrategy] = (0, import_solid_js5.createSignal)(); const open = (focusStrategy2) => { setFocusStrategy(focusStrategy2); overlayTriggerState.open(); }; const toggle = (focusStrategy2) => { setFocusStrategy(focusStrategy2); overlayTriggerState.toggle(); }; return (0, import_solid_js5.mergeProps)(overlayTriggerState, { focusStrategy, open, toggle }); } // src/createMenuTrigger.ts function createMenuTrigger(props, ref, state = createMenuTriggerState(props)) { const defaultProps = { type: "menu", trigger: "press", accessibilityDescription: "Long press or press Alt + ArrowDown to open menu" }; props = (0, import_solid_js6.mergeProps)(defaultProps, props); const menuTriggerId = (0, import_utils5.createId)(); const { triggerProps, overlayProps } = (0, import_overlays2.createOverlayTrigger)({ type: () => props.type ?? "menu" }, state); const onKeyDown = (e) => { const refEl = ref(); if (!refEl || props.isDisabled || props.trigger === "longPress" && !e.altKey) { return; } switch (e.key) { case "Enter": case " ": if (props.trigger === "longPress") { return; } case "ArrowDown": e.stopPropagation(); e.preventDefault(); state.toggle("first"); break; case "ArrowUp": e.stopPropagation(); e.preventDefault(); state.toggle("last"); break; } }; const { longPressProps } = (0, import_interactions2.createLongPress)({ isDisabled: () => props.isDisabled || props.trigger !== "longPress", accessibilityDescription: () => props.accessibilityDescription, onLongPressStart: () => state.close(), onLongPress: () => state.open("first") }); const pressProps = { onPressStart: (e) => { if (e.pointerType !== "touch" && e.pointerType !== "keyboard" && !props.isDisabled) { state.toggle(e.pointerType === "virtual" ? "first" : void 0); } }, onPress: (e) => { if (e.pointerType === "touch" && !props.isDisabled) { state.toggle(); } } }; const combinedTriggerProps = (0, import_solid_js6.createMemo)(() => { return combineProps(triggerProps, props.trigger === "press" ? pressProps : {}, props.trigger === "longPress" ? longPressProps : {}); }); const baseMenuTriggerProps = { id: menuTriggerId, onKeyDown }; const baseMenuProps = { "aria-labelledby": menuTriggerId }; return { menuTriggerProps: (0, import_solid_js6.mergeProps)(combinedTriggerProps, baseMenuTriggerProps), menuProps: (0, import_solid_js6.mergeProps)(overlayProps, baseMenuProps), state }; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { createMenu, createMenuItem, createMenuSection, createMenuTrigger, createMenuTriggerState, useMenuContext });