@assistant-ui/react
Version:
Open-source TypeScript/React library for building production-grade AI chat experiences
39 lines (38 loc) • 1.65 kB
JavaScript
"use client";
import { useThreadRootElementRef } from "../thread/ThreadRootElementContext.js";
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
import "@assistant-ui/tap/react-shim";
// src/primitives/composer/useComposerRunStartFocusGuard.ts
/**
* The run-start focus decision `ComposerPrimitive.Input` makes, for other
* composer implementations (`@assistant-ui/react-lexical`) that have to make the
* same call. The thread root comes from context, so a composer portaled outside
* `ThreadPrimitive.Root` still knows which thread it belongs to; reading the
* `data-aui-thread-root` attribute instead concludes that focus is elsewhere and
* leaves the keyboard where the thread put it.
*
* Returns `false` for a missing element, and for the element itself already
* holding focus.
*/
const useComposerRunStartFocusGuard = () => {
const $ = c(2);
const threadRootRef = useThreadRootElementRef();
let t0;
if ($[0] !== threadRootRef) {
t0 = (composerElement) => {
if (!composerElement) return false;
const doc = composerElement.ownerDocument;
const active = doc.activeElement;
if (!active || active === doc.body) return true;
if (active === composerElement) return false;
if (composerElement.closest("[data-aui-composer-type]")?.contains(active)) return true;
const threadRoot = threadRootRef?.current ?? null;
return threadRoot !== null && threadRoot.contains(active) && active.closest("[data-aui-thread-root]") === threadRoot;
};
$[0] = threadRootRef;
$[1] = t0;
} else t0 = $[1];
return t0;
};
export { useComposerRunStartFocusGuard };
//# sourceMappingURL=useComposerRunStartFocusGuard.js.map