UNPKG

@assistant-ui/react

Version:

TypeScript/React library for AI Chat

80 lines (79 loc) 2.87 kB
"use client"; // src/primitives/thread/ThreadViewportSlack.tsx import { Slot } from "@radix-ui/react-slot"; import { createContext, useCallback, useContext } from "react"; import { useThreadViewportStore } from "../../context/react/ThreadViewportContext.js"; import { useAssistantState } from "../../context/index.js"; import { useManagedRef } from "../../utils/hooks/useManagedRef.js"; import { jsx } from "react/jsx-runtime"; var SlackNestingContext = createContext(false); var parseCssLength = (value, element) => { const match = value.match(/^([\d.]+)(em|px|rem)$/); if (!match) return 0; const num = parseFloat(match[1]); const unit = match[2]; if (unit === "px") return num; if (unit === "em") { const fontSize = parseFloat(getComputedStyle(element).fontSize) || 16; return num * fontSize; } if (unit === "rem") { const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16; return num * rootFontSize; } return 0; }; var ThreadPrimitiveViewportSlack = ({ children, fillClampThreshold = "10em", fillClampOffset = "6em" }) => { const isLast = useAssistantState( // only add slack if the message is the last message and we already have at least 3 messages ({ message }) => message.isLast && message.index >= 2 ); const threadViewportStore = useThreadViewportStore({ optional: true }); const isNested = useContext(SlackNestingContext); const callback = useCallback( (el) => { if (!threadViewportStore || isNested) return; const updateMinHeight = () => { const state = threadViewportStore.getState(); if (state.turnAnchor === "top" && isLast) { const { viewport, inset, userMessage } = state.height; const threshold = parseCssLength(fillClampThreshold, el); const offset = parseCssLength(fillClampOffset, el); const clampAdjustment = userMessage <= threshold ? userMessage : offset; const minHeight = Math.max(0, viewport - inset - clampAdjustment); el.style.minHeight = `${minHeight}px`; el.style.flexShrink = "0"; el.style.transition = "min-height 0s"; } else { el.style.minHeight = ""; el.style.flexShrink = ""; el.style.transition = ""; } }; updateMinHeight(); return threadViewportStore.subscribe(updateMinHeight); }, [ threadViewportStore, isLast, isNested, fillClampThreshold, fillClampOffset ] ); const ref = useManagedRef(callback); return /* @__PURE__ */ jsx(SlackNestingContext.Provider, { value: true, children: /* @__PURE__ */ jsx(Slot, { ref, children }) }); }; ThreadPrimitiveViewportSlack.displayName = "ThreadPrimitive.ViewportSlack"; export { ThreadPrimitiveViewportSlack }; //# sourceMappingURL=ThreadViewportSlack.js.map