@ariakit/react-core
Version:
Ariakit React core
156 lines (153 loc) • 5.07 kB
JavaScript
"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
};