@ariakit/react-core
Version:
Ariakit React core
171 lines (169 loc) • 6.08 kB
JavaScript
"use client";
import {
usePopover
} from "../__chunks/4Z6JSVUY.js";
import {
createDialogComponent
} from "../__chunks/2S4Q4M35.js";
import "../__chunks/SWBQ42SL.js";
import "../__chunks/AOQQTIBO.js";
import "../__chunks/5M6RIVE2.js";
import "../__chunks/IEBFIEPB.js";
import "../__chunks/RBTTLCIN.js";
import "../__chunks/UG4JNWMY.js";
import "../__chunks/6GXEOXGT.js";
import "../__chunks/Y7OMCS5T.js";
import "../__chunks/HLTQOHKZ.js";
import "../__chunks/DJAL6CN3.js";
import "../__chunks/NQXOL4RD.js";
import "../__chunks/NE2XEEQN.js";
import "../__chunks/CZ4GFWYL.js";
import "../__chunks/Z5GCVBAY.js";
import "../__chunks/IGR4SXG2.js";
import "../__chunks/677M2CI3.js";
import "../__chunks/S7U6BLGA.js";
import "../__chunks/LVVSG7VH.js";
import "../__chunks/3NDVDEB4.js";
import "../__chunks/AOUGVQZ3.js";
import "../__chunks/K2ZF5NU7.js";
import "../__chunks/63XF7ACK.js";
import {
useComboboxList
} from "../__chunks/MDHGE4WQ.js";
import "../__chunks/HAX24JB7.js";
import "../__chunks/5NIUVND5.js";
import "../__chunks/33YRLYNQ.js";
import "../__chunks/HIN2NSI2.js";
import {
useComboboxProviderContext
} from "../__chunks/7P7IWEBR.js";
import "../__chunks/MWF5B7KS.js";
import "../__chunks/63N3TCQX.js";
import "../__chunks/FFSBKSAM.js";
import "../__chunks/72IB6YNO.js";
import "../__chunks/US3TW2XI.js";
import "../__chunks/SWN3JYXT.js";
import {
useStoreState
} from "../__chunks/Q3KUZPD7.js";
import "../__chunks/45YOMIF3.js";
import {
createElement,
createHook,
forwardRef
} from "../__chunks/ILRXHV7V.js";
import "../__chunks/K2XTQB3X.js";
import "../__chunks/YXGXYGQX.js";
// src/combobox/combobox-popover.tsx
import { getDocument } from "@ariakit/core/utils/dom";
import { invariant, isFalsyBooleanCallback } from "@ariakit/core/utils/misc";
import { useRef } from "react";
var TagName = "div";
function isController(target, ...ids) {
if (!target) return false;
if ("id" in target) {
const selector = ids.filter(Boolean).map((id) => `[aria-controls~="${id}"]`).join(", ");
if (!selector) return false;
return target.matches(selector);
}
return false;
}
var useComboboxPopover = createHook(
function useComboboxPopover2({
store,
modal,
tabIndex,
alwaysVisible,
autoFocusOnHide = true,
hideOnInteractOutside = true,
...props
}) {
const context = useComboboxProviderContext();
store = store || context;
invariant(
store,
process.env.NODE_ENV !== "production" && "ComboboxPopover must receive a `store` prop or be wrapped in a ComboboxProvider component."
);
const baseElement = store.useState("baseElement");
const hiddenByClickOutsideRef = useRef(false);
const treeSnapshotKey = useStoreState(
store.tag,
(state) => state == null ? void 0 : state.renderedItems.length
);
props = useComboboxList({ store, alwaysVisible, ...props });
props = usePopover({
store,
modal,
alwaysVisible,
backdrop: false,
autoFocusOnShow: false,
finalFocus: baseElement,
preserveTabOrderAnchor: null,
unstable_treeSnapshotKey: treeSnapshotKey,
...props,
// When the combobox popover is modal, we make sure to include the
// combobox input and all the combobox controls (cancel, disclosure) in
// the list of persistent elements so they make part of the modal context,
// allowing users to tab through them.
getPersistentElements() {
var _a;
const elements = ((_a = props.getPersistentElements) == null ? void 0 : _a.call(props)) || [];
if (!modal) return elements;
if (!store) return elements;
const { contentElement, baseElement: baseElement2 } = store.getState();
if (!baseElement2) return elements;
const doc = getDocument(baseElement2);
const selectors = [];
if (contentElement == null ? void 0 : contentElement.id) {
selectors.push(`[aria-controls~="${contentElement.id}"]`);
}
if (baseElement2 == null ? void 0 : baseElement2.id) {
selectors.push(`[aria-controls~="${baseElement2.id}"]`);
}
if (!selectors.length) return [...elements, baseElement2];
const selector = selectors.join(",");
const controlElements = doc.querySelectorAll(selector);
return [...elements, ...controlElements];
},
// The combobox popover should focus on the combobox input when it hides,
// unless the event was triggered by a click outside the popover, in which
// case the input shouldn't be re-focused.
autoFocusOnHide(element) {
if (isFalsyBooleanCallback(autoFocusOnHide, element)) return false;
if (hiddenByClickOutsideRef.current) {
hiddenByClickOutsideRef.current = false;
return false;
}
return true;
},
// Make sure we don't hide the popover when the user interacts with the
// combobox cancel or the combobox disclosure buttons. They will have the
// aria-controls attribute pointing to either the combobox input or the
// combobox popover elements.
hideOnInteractOutside(event) {
var _a, _b;
const state = store == null ? void 0 : store.getState();
const contentId = (_a = state == null ? void 0 : state.contentElement) == null ? void 0 : _a.id;
const baseId = (_b = state == null ? void 0 : state.baseElement) == null ? void 0 : _b.id;
if (isController(event.target, contentId, baseId)) return false;
const result = typeof hideOnInteractOutside === "function" ? hideOnInteractOutside(event) : hideOnInteractOutside;
if (result) {
hiddenByClickOutsideRef.current = event.type === "click";
}
return result;
}
});
return props;
}
);
var ComboboxPopover = createDialogComponent(
forwardRef(function ComboboxPopover2(props) {
const htmlProps = useComboboxPopover(props);
return createElement(TagName, htmlProps);
}),
useComboboxProviderContext
);
export {
ComboboxPopover,
useComboboxPopover
};