@ariakit/react-core
Version:
Ariakit React core
183 lines (181 loc) • 6.4 kB
JavaScript
"use client";
import {
usePopover
} from "../__chunks/C6DAL6ZN.js";
import {
createDialogComponent
} from "../__chunks/CAGBPNDP.js";
import "../__chunks/M5DFOEFU.js";
import "../__chunks/AOQQTIBO.js";
import "../__chunks/5M6RIVE2.js";
import "../__chunks/S2F2XXEH.js";
import "../__chunks/DXGKYUAD.js";
import "../__chunks/LC6GJMGV.js";
import "../__chunks/6GXEOXGT.js";
import "../__chunks/JZEJYXOQ.js";
import "../__chunks/HLTQOHKZ.js";
import "../__chunks/PVECYOSC.js";
import "../__chunks/SOMPWLIQ.js";
import "../__chunks/W6WVJJEY.js";
import "../__chunks/CZ4GFWYL.js";
import "../__chunks/Z5GCVBAY.js";
import "../__chunks/IGR4SXG2.js";
import "../__chunks/677M2CI3.js";
import "../__chunks/S7U6BLGA.js";
import "../__chunks/FVE2C5B3.js";
import "../__chunks/3NDVDEB4.js";
import "../__chunks/AOUGVQZ3.js";
import "../__chunks/K2ZF5NU7.js";
import "../__chunks/63XF7ACK.js";
import {
useComboboxList
} from "../__chunks/MNJRSAAC.js";
import "../__chunks/K4R5DNTX.js";
import "../__chunks/Y2U4BRIM.js";
import "../__chunks/T22PY7TE.js";
import "../__chunks/QJ4LGO2N.js";
import {
useComboboxProviderContext
} from "../__chunks/OLVWQA7U.js";
import "../__chunks/Y67KZUMI.js";
import "../__chunks/T2AZQXQU.js";
import "../__chunks/ABN76PSX.js";
import "../__chunks/APTFW6PT.js";
import "../__chunks/OE2EFRVA.js";
import "../__chunks/SWN3JYXT.js";
import {
useStoreState
} from "../__chunks/RTNCFSKZ.js";
import "../__chunks/5CPL3B7G.js";
import {
createElement,
createHook,
forwardRef
} from "../__chunks/VOQWLFSQ.js";
import "../__chunks/5GGHRIN3.js";
import "../__chunks/SK3NAZA3.js";
import {
__objRest,
__spreadProps,
__spreadValues
} from "../__chunks/3YLGPPWQ.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(_a) {
var _b = _a, {
store,
modal,
tabIndex,
alwaysVisible,
autoFocusOnHide = true,
hideOnInteractOutside = true
} = _b, props = __objRest(_b, [
"store",
"modal",
"tabIndex",
"alwaysVisible",
"autoFocusOnHide",
"hideOnInteractOutside"
]);
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(__spreadValues({ store, alwaysVisible }, props));
props = usePopover(__spreadProps(__spreadValues({
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 _a2;
const elements = ((_a2 = props.getPersistentElements) == null ? void 0 : _a2.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 _a2, _b2;
const state = store == null ? void 0 : store.getState();
const contentId = (_a2 = state == null ? void 0 : state.contentElement) == null ? void 0 : _a2.id;
const baseId = (_b2 = state == null ? void 0 : state.baseElement) == null ? void 0 : _b2.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
};