@assistant-ui/react
Version:
Open-source TypeScript/React library for building production-grade AI chat experiences
165 lines (164 loc) • 4.89 kB
JavaScript
"use client";
import { Primitive as Primitive$1 } from "../../utils/Primitive.js";
import { useComposerSend } from "./ComposerSend.js";
import { ComposerCompactContext } from "./ComposerCompactContext.js";
import { COMPOSER_INPUT_SELECTOR, CONTENT_EDITABLE_SELECTOR } from "./composerInputSelector.js";
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
import { forwardRef, useState, version } from "@assistant-ui/tap/react-shim";
import { useAuiState } from "@assistant-ui/store";
import { jsx } from "react/jsx-runtime";
import { composeEventHandlers } from "radix-ui/internal";
// src/primitives/composer/ComposerRoot.tsx
const INTERACTIVE_ELEMENT_SELECTOR = [
"a",
"audio[controls]",
"button",
"details",
"embed",
"iframe",
"input",
"label",
"select",
"summary",
"textarea",
"video[controls]",
CONTENT_EDITABLE_SELECTOR,
"[tabindex]"
].join(", ");
const isReact18 = version.startsWith("18.");
/**
* The root form container for message composition.
*
* This component provides a form wrapper that handles message submission when the form
* is submitted (e.g., via Enter key or submit button). It automatically prevents the
* default form submission and triggers the composer's send functionality.
*
* Clicking blank form space focuses the composer input (the first textarea or
* contenteditable inside the form). Text selection cannot start from blank
* areas; descendants that need native mousedown defaults can call
* `stopPropagation()` in their own `onMouseDown`.
*
* @example
* ```tsx
* <ComposerPrimitive.Root>
* <ComposerPrimitive.Input placeholder="Type your message..." />
* <ComposerPrimitive.Send>Send</ComposerPrimitive.Send>
* </ComposerPrimitive.Root>
* ```
*/
const ComposerPrimitiveRoot = forwardRef((t0, forwardedRef) => {
const $ = c(27);
let compact;
let inert;
let onMouseDown;
let onSubmit;
let rest;
if ($[0] !== t0) {
({onSubmit, onMouseDown, compact, inert, ...rest} = t0);
$[0] = t0;
$[1] = compact;
$[2] = inert;
$[3] = onMouseDown;
$[4] = onSubmit;
$[5] = rest;
} else {
compact = $[1];
inert = $[2];
onMouseDown = $[3];
onSubmit = $[4];
rest = $[5];
}
const send = useComposerSend();
const composerType = useAuiState(_temp);
const [multiline, setMultiline] = useState(false);
let t1;
if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
t1 = { setMultiline };
$[6] = t1;
} else t1 = $[6];
const compactContext = t1;
let t2;
if ($[7] !== compact) {
t2 = (s_0) => compact ? s_0.composer.attachments.length === 0 && s_0.composer.quote == null && s_0.composer.queue.length === 0 && s_0.composer.dictation == null && !s_0.composer.text.includes("\n") : false;
$[7] = compact;
$[8] = t2;
} else t2 = $[8];
const isCompact = useAuiState(t2) && !multiline;
const inertAttribute = isReact18 && typeof inert === "boolean" ? inert ? "" : void 0 : inert;
let t3;
if ($[9] !== send) {
t3 = (e) => {
e.preventDefault();
if (!send) return;
send();
};
$[9] = send;
$[10] = t3;
} else t3 = $[10];
const handleSubmit = t3;
const handleMouseDown = _temp2;
const t4 = compact ? compactContext : null;
const t5 = inertAttribute;
const t6 = isCompact ? "" : void 0;
let t7;
if ($[11] !== handleSubmit || $[12] !== onSubmit) {
t7 = composeEventHandlers(onSubmit, handleSubmit);
$[11] = handleSubmit;
$[12] = onSubmit;
$[13] = t7;
} else t7 = $[13];
let t8;
if ($[14] !== onMouseDown) {
t8 = composeEventHandlers(onMouseDown, handleMouseDown);
$[14] = onMouseDown;
$[15] = t8;
} else t8 = $[15];
let t9;
if ($[16] !== composerType || $[17] !== forwardedRef || $[18] !== rest || $[19] !== t5 || $[20] !== t6 || $[21] !== t7 || $[22] !== t8) {
t9 = /* @__PURE__ */ jsx(Primitive$1.form, {
...rest,
inert: t5,
"data-aui-composer-type": composerType,
"data-compact": t6,
ref: forwardedRef,
onSubmit: t7,
onMouseDown: t8
});
$[16] = composerType;
$[17] = forwardedRef;
$[18] = rest;
$[19] = t5;
$[20] = t6;
$[21] = t7;
$[22] = t8;
$[23] = t9;
} else t9 = $[23];
let t10;
if ($[24] !== t4 || $[25] !== t9) {
t10 = /* @__PURE__ */ jsx(ComposerCompactContext.Provider, {
value: t4,
children: t9
});
$[24] = t4;
$[25] = t9;
$[26] = t10;
} else t10 = $[26];
return t10;
});
ComposerPrimitiveRoot.displayName = "ComposerPrimitive.Root";
function _temp(s) {
return s.composer.type;
}
function _temp2(e_0) {
if (e_0.button !== 0) return;
const target = e_0.target;
if (!(target instanceof Element) || !e_0.currentTarget.contains(target)) return;
const interactive = target.closest(INTERACTIVE_ELEMENT_SELECTOR);
if (interactive && e_0.currentTarget.contains(interactive)) return;
const input = e_0.currentTarget.querySelector(COMPOSER_INPUT_SELECTOR);
if (!input) return;
e_0.preventDefault();
input.focus();
}
export { ComposerPrimitiveRoot };
//# sourceMappingURL=ComposerRoot.js.map