UNPKG

@ariakit/react-core

Version:

Ariakit React core

156 lines (153 loc) 5.07 kB
"use client"; import { SelectHeadingContext, SelectScopedContextProvider, useSelectContext } from "./LM7KIZUU.js"; import { useCompositeTypeahead } from "./OYOFZOGB.js"; import { isHidden } from "./K4R5DNTX.js"; import { useComposite } from "./NSTBQJLB.js"; import { createElement, createHook, forwardRef } from "./VOQWLFSQ.js"; import { useAttribute, useBooleanEvent, useEvent, useId, useMergeRefs, useTransactionState, useWrapElement } from "./5GGHRIN3.js"; import { __objRest, __spreadProps, __spreadValues } from "./3YLGPPWQ.js"; // src/select/select-list.tsx import { isSelfTarget } from "@ariakit/core/utils/events"; import { invariant } from "@ariakit/core/utils/misc"; import { createContext, useContext, useEffect, useMemo, useState } from "react"; import { jsx } from "react/jsx-runtime"; var TagName = "div"; var SelectListContext = createContext(null); var useSelectList = createHook( function useSelectList2(_a) { var _b = _a, { store, resetOnEscape = true, hideOnEnter = true, focusOnMove = true, composite, alwaysVisible } = _b, props = __objRest(_b, [ "store", "resetOnEscape", "hideOnEnter", "focusOnMove", "composite", "alwaysVisible" ]); const context = useSelectContext(); store = store || context; invariant( store, process.env.NODE_ENV !== "production" && "SelectList must receive a `store` prop or be wrapped in a SelectProvider component." ); const id = useId(props.id); const value = store.useState("value"); const multiSelectable = Array.isArray(value); const [defaultValue, setDefaultValue] = useState(value); const mounted = store.useState("mounted"); useEffect(() => { if (mounted) return; setDefaultValue(value); }, [mounted, value]); resetOnEscape = resetOnEscape && !multiSelectable; const onKeyDownProp = props.onKeyDown; const resetOnEscapeProp = useBooleanEvent(resetOnEscape); const hideOnEnterProp = useBooleanEvent(hideOnEnter); const onKeyDown = useEvent((event) => { onKeyDownProp == null ? void 0 : onKeyDownProp(event); if (event.defaultPrevented) return; if (event.key === "Escape" && resetOnEscapeProp(event)) { store == null ? void 0 : store.setValue(defaultValue); } if (event.key === " " || event.key === "Enter") { if (isSelfTarget(event) && hideOnEnterProp(event)) { event.preventDefault(); store == null ? void 0 : store.hide(); } } }); const headingContext = useContext(SelectHeadingContext); const headingState = useState(); const [headingId, setHeadingId] = headingContext || headingState; const headingContextValue = useMemo( () => [headingId, setHeadingId], [headingId] ); const [childStore, setChildStore] = useState(null); const setStore = useContext(SelectListContext); useEffect(() => { if (!setStore) return; setStore(store); return () => setStore(null); }, [setStore, store]); props = useWrapElement( props, (element2) => /* @__PURE__ */ jsx(SelectScopedContextProvider, { value: store, children: /* @__PURE__ */ jsx(SelectListContext.Provider, { value: setChildStore, children: /* @__PURE__ */ jsx(SelectHeadingContext.Provider, { value: headingContextValue, children: element2 }) }) }), [store, headingContextValue] ); const hasCombobox = !!store.combobox; composite = composite != null ? composite : !hasCombobox && childStore !== store; const [element, setElement] = useTransactionState( composite ? store.setListElement : null ); const role = useAttribute(element, "role", props.role); const isCompositeRole = role === "listbox" || role === "menu" || role === "tree" || role === "grid"; const ariaMultiSelectable = composite || isCompositeRole ? multiSelectable || void 0 : void 0; const hidden = isHidden(mounted, props.hidden, alwaysVisible); const style = hidden ? __spreadProps(__spreadValues({}, props.style), { display: "none" }) : props.style; if (composite) { props = __spreadValues({ role: "listbox", "aria-multiselectable": ariaMultiSelectable }, props); } const labelId = store.useState( (state) => { var _a2; return headingId || ((_a2 = state.labelElement) == null ? void 0 : _a2.id); } ); props = __spreadProps(__spreadValues({ id, "aria-labelledby": labelId, hidden }, props), { ref: useMergeRefs(setElement, props.ref), style, onKeyDown }); props = useComposite(__spreadProps(__spreadValues({ store }, props), { composite })); props = useCompositeTypeahead(__spreadValues({ store, typeahead: !hasCombobox }, props)); return props; } ); var SelectList = forwardRef(function SelectList2(props) { const htmlProps = useSelectList(props); return createElement(TagName, htmlProps); }); export { useSelectList, SelectList };