@assistant-ui/react 0.11.41 → 0.11.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/AssistantClient.d.ts.map +1 -1
- package/dist/client/AssistantClient.js.map +1 -1
- package/dist/client/ModelContext.d.ts +1 -1
- package/dist/client/ModelContext.d.ts.map +1 -1
- package/dist/client/ModelContext.js.map +1 -1
- package/dist/client/ModelContextClient.d.ts +1 -1
- package/dist/client/ThreadMessageClient.d.ts +1 -0
- package/dist/client/ThreadMessageClient.d.ts.map +1 -1
- package/dist/client/ThreadMessageClient.js +3 -1
- package/dist/client/ThreadMessageClient.js.map +1 -1
- package/dist/client/types/Message.d.ts +2 -0
- package/dist/client/types/Message.d.ts.map +1 -1
- package/dist/client/types/ModelContext.d.ts +1 -1
- package/dist/client/types/ModelContext.d.ts.map +1 -1
- package/dist/client/types/Tools.d.ts +1 -2
- package/dist/client/types/Tools.d.ts.map +1 -1
- package/dist/context/providers/ThreadViewportProvider.d.ts +5 -1
- package/dist/context/providers/ThreadViewportProvider.d.ts.map +1 -1
- package/dist/context/providers/ThreadViewportProvider.js +17 -6
- package/dist/context/providers/ThreadViewportProvider.js.map +1 -1
- package/dist/context/react/AssistantApiContext.d.ts +1 -1
- package/dist/context/react/AssistantApiContext.d.ts.map +1 -1
- package/dist/context/react/AssistantApiContext.js +1 -2
- package/dist/context/react/AssistantApiContext.js.map +1 -1
- package/dist/context/stores/ThreadViewport.d.ts +33 -3
- package/dist/context/stores/ThreadViewport.d.ts.map +1 -1
- package/dist/context/stores/ThreadViewport.js +67 -5
- package/dist/context/stores/ThreadViewport.js.map +1 -1
- package/dist/devtools/DevToolsHooks.d.ts +1 -1
- package/dist/devtools/DevToolsHooks.d.ts.map +1 -1
- package/dist/devtools/DevToolsHooks.js.map +1 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.js +2 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
- package/dist/legacy-runtime/client/ComposerRuntimeClient.d.ts +3 -3
- package/dist/legacy-runtime/client/ComposerRuntimeClient.d.ts.map +1 -1
- package/dist/legacy-runtime/client/ComposerRuntimeClient.js.map +1 -1
- package/dist/legacy-runtime/client/EventManagerRuntimeClient.d.ts +1 -1
- package/dist/legacy-runtime/client/ThreadRuntimeClient.js.map +1 -1
- package/dist/legacy-runtime/runtime/MessageRuntime.d.ts +3 -0
- package/dist/legacy-runtime/runtime/MessageRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime/MessageRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime/RuntimeBindings.d.ts +2 -0
- package/dist/legacy-runtime/runtime/RuntimeBindings.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime/ThreadRuntime.d.ts +1 -0
- package/dist/legacy-runtime/runtime/ThreadRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime/ThreadRuntime.js +6 -3
- package/dist/legacy-runtime/runtime/ThreadRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js +5 -5
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/core/BaseThreadRuntimeCore.d.ts +1 -0
- package/dist/legacy-runtime/runtime-cores/core/BaseThreadRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.d.ts +1 -0
- package/dist/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts +2 -0
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts +2 -0
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.d.ts +1 -0
- package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js +2 -1
- package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js.map +1 -1
- package/dist/primitives/composer/ComposerAttachmentDropzone.d.ts +2 -2
- package/dist/primitives/composer/ComposerAttachmentDropzone.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerAttachmentDropzone.js +31 -11
- package/dist/primitives/composer/ComposerAttachmentDropzone.js.map +1 -1
- package/dist/primitives/composer/index.d.ts +1 -0
- package/dist/primitives/composer/index.d.ts.map +1 -1
- package/dist/primitives/composer/index.js +2 -0
- package/dist/primitives/composer/index.js.map +1 -1
- package/dist/primitives/message/MessageRoot.d.ts +3 -0
- package/dist/primitives/message/MessageRoot.d.ts.map +1 -1
- package/dist/primitives/message/MessageRoot.js +24 -2
- package/dist/primitives/message/MessageRoot.js.map +1 -1
- package/dist/primitives/thread/ThreadScrollToBottom.d.ts +7 -2
- package/dist/primitives/thread/ThreadScrollToBottom.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadScrollToBottom.js +7 -4
- package/dist/primitives/thread/ThreadScrollToBottom.js.map +1 -1
- package/dist/primitives/thread/ThreadViewport.d.ts +17 -3
- package/dist/primitives/thread/ThreadViewport.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadViewport.js +19 -5
- package/dist/primitives/thread/ThreadViewport.js.map +1 -1
- package/dist/primitives/thread/ThreadViewportFooter.d.ts +31 -0
- package/dist/primitives/thread/ThreadViewportFooter.d.ts.map +1 -0
- package/dist/primitives/thread/ThreadViewportFooter.js +27 -0
- package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -0
- package/dist/primitives/thread/ThreadViewportSlack.d.ts +20 -0
- package/dist/primitives/thread/ThreadViewportSlack.d.ts.map +1 -0
- package/dist/primitives/thread/ThreadViewportSlack.js +77 -0
- package/dist/primitives/thread/ThreadViewportSlack.js.map +1 -0
- package/dist/primitives/thread/index.d.ts +3 -0
- package/dist/primitives/thread/index.d.ts.map +1 -1
- package/dist/primitives/thread/index.js +7 -1
- package/dist/primitives/thread/index.js.map +1 -1
- package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts +6 -0
- package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
- package/dist/primitives/thread/useThreadViewportAutoScroll.js +17 -8
- package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
- package/dist/utils/hooks/useOnScrollToBottom.d.ts +3 -1
- package/dist/utils/hooks/useOnScrollToBottom.d.ts.map +1 -1
- package/dist/utils/hooks/useOnScrollToBottom.js.map +1 -1
- package/dist/utils/hooks/useSizeHandle.d.ts +11 -0
- package/dist/utils/hooks/useSizeHandle.d.ts.map +1 -0
- package/dist/utils/hooks/useSizeHandle.js +30 -0
- package/dist/utils/hooks/useSizeHandle.js.map +1 -0
- package/dist/utils/tap-store/derived-scopes.d.ts +2 -1
- package/dist/utils/tap-store/derived-scopes.d.ts.map +1 -1
- package/dist/utils/tap-store/derived-scopes.js.map +1 -1
- package/dist/utils/tap-store/store.d.ts +2 -1
- package/dist/utils/tap-store/store.d.ts.map +1 -1
- package/dist/utils/tap-store/store.js.map +1 -1
- package/package.json +3 -3
- package/src/client/AssistantClient.ts +1 -1
- package/src/client/ModelContext.ts +1 -1
- package/src/client/ThreadMessageClient.tsx +4 -1
- package/src/client/types/Message.ts +3 -0
- package/src/client/types/ModelContext.ts +1 -1
- package/src/client/types/Tools.ts +1 -2
- package/src/context/providers/ThreadViewportProvider.tsx +27 -5
- package/src/context/react/AssistantApiContext.tsx +2 -5
- package/src/context/stores/ThreadViewport.tsx +125 -7
- package/src/devtools/DevToolsHooks.ts +1 -1
- package/src/legacy-runtime/AssistantRuntimeProvider.tsx +6 -1
- package/src/legacy-runtime/client/ComposerRuntimeClient.ts +3 -3
- package/src/legacy-runtime/client/ThreadRuntimeClient.ts +2 -2
- package/src/legacy-runtime/runtime/MessageRuntime.ts +2 -0
- package/src/legacy-runtime/runtime/RuntimeBindings.ts +2 -0
- package/src/legacy-runtime/runtime/ThreadRuntime.ts +6 -3
- package/src/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.ts +5 -5
- package/src/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.tsx +1 -0
- package/src/legacy-runtime/runtime-cores/utils/MessageRepository.tsx +1 -0
- package/src/primitives/composer/ComposerAttachmentDropzone.tsx +35 -12
- package/src/primitives/composer/index.ts +1 -0
- package/src/primitives/message/MessageRoot.tsx +45 -2
- package/src/primitives/thread/ThreadScrollToBottom.tsx +12 -3
- package/src/primitives/thread/ThreadViewport.tsx +35 -9
- package/src/primitives/thread/ThreadViewportFooter.tsx +57 -0
- package/src/primitives/thread/ThreadViewportSlack.tsx +109 -0
- package/src/primitives/thread/index.ts +3 -0
- package/src/primitives/thread/useThreadViewportAutoScroll.tsx +24 -12
- package/src/utils/hooks/useOnScrollToBottom.tsx +3 -1
- package/src/utils/hooks/useSizeHandle.ts +43 -0
- package/src/utils/tap-store/derived-scopes.ts +2 -1
- package/src/utils/tap-store/store.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadViewport.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewport.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,
|
|
1
|
+
{"version":3,"file":"ThreadViewport.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewport.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EACL,KAAK,YAAY,EAEjB,wBAAwB,EAEzB,MAAM,OAAO,CAAC;AAMf,yBAAiB,uBAAuB,CAAC;IACvC,KAAY,OAAO,GAAG,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACzD,KAAY,KAAK,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,GAAG;QACnE;;;;;WAKG;QACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjC;;;;WAIG;QACH,UAAU,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;KAC3C,CAAC;CACH;AAiCD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,uBAAuB;;;IA9DhC;;;;;OAKG;iBACU,OAAO,GAAG,SAAS;IAEhC;;;;OAIG;iBACU,KAAK,GAAG,QAAQ,GAAG,SAAS;kDA0D3C,CAAC"}
|
|
@@ -3,20 +3,34 @@
|
|
|
3
3
|
// src/primitives/thread/ThreadViewport.tsx
|
|
4
4
|
import { useComposedRefs } from "@radix-ui/react-compose-refs";
|
|
5
5
|
import { Primitive } from "@radix-ui/react-primitive";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
forwardRef,
|
|
8
|
+
useCallback
|
|
9
|
+
} from "react";
|
|
7
10
|
import { useThreadViewportAutoScroll } from "./useThreadViewportAutoScroll.js";
|
|
8
|
-
import {
|
|
11
|
+
import { ThreadPrimitiveViewportProvider } from "../../context/providers/ThreadViewportProvider.js";
|
|
12
|
+
import { useSizeHandle } from "../../utils/hooks/useSizeHandle.js";
|
|
13
|
+
import { useThreadViewport } from "../../context/react/ThreadViewportContext.js";
|
|
9
14
|
import { jsx } from "react/jsx-runtime";
|
|
15
|
+
var useViewportSizeRef = () => {
|
|
16
|
+
const register = useThreadViewport((s) => s.registerViewport);
|
|
17
|
+
const getHeight = useCallback(
|
|
18
|
+
(el) => el.clientHeight - parseFloat(getComputedStyle(el).paddingTop),
|
|
19
|
+
[]
|
|
20
|
+
);
|
|
21
|
+
return useSizeHandle(register, getHeight);
|
|
22
|
+
};
|
|
10
23
|
var ThreadPrimitiveViewportScrollable = forwardRef(({ autoScroll, children, ...rest }, forwardedRef) => {
|
|
11
24
|
const autoScrollRef = useThreadViewportAutoScroll({
|
|
12
25
|
autoScroll
|
|
13
26
|
});
|
|
14
|
-
const
|
|
27
|
+
const viewportSizeRef = useViewportSizeRef();
|
|
28
|
+
const ref = useComposedRefs(forwardedRef, autoScrollRef, viewportSizeRef);
|
|
15
29
|
return /* @__PURE__ */ jsx(Primitive.div, { ...rest, ref, children });
|
|
16
30
|
});
|
|
17
31
|
ThreadPrimitiveViewportScrollable.displayName = "ThreadPrimitive.ViewportScrollable";
|
|
18
|
-
var ThreadPrimitiveViewport = forwardRef((props, ref) => {
|
|
19
|
-
return /* @__PURE__ */ jsx(
|
|
32
|
+
var ThreadPrimitiveViewport = forwardRef(({ turnAnchor, ...props }, ref) => {
|
|
33
|
+
return /* @__PURE__ */ jsx(ThreadPrimitiveViewportProvider, { options: { turnAnchor }, children: /* @__PURE__ */ jsx(ThreadPrimitiveViewportScrollable, { ...props, ref }) });
|
|
20
34
|
});
|
|
21
35
|
ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
|
|
22
36
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/primitives/thread/ThreadViewport.tsx"],"sourcesContent":["\"use client\";\n\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/primitives/thread/ThreadViewport.tsx"],"sourcesContent":["\"use client\";\n\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport {\n type ComponentRef,\n forwardRef,\n ComponentPropsWithoutRef,\n useCallback,\n} from \"react\";\nimport { useThreadViewportAutoScroll } from \"./useThreadViewportAutoScroll\";\nimport { ThreadPrimitiveViewportProvider } from \"../../context/providers/ThreadViewportProvider\";\nimport { useSizeHandle } from \"../../utils/hooks/useSizeHandle\";\nimport { useThreadViewport } from \"../../context/react/ThreadViewportContext\";\n\nexport namespace ThreadPrimitiveViewport {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.div> & {\n /**\n * Whether to automatically scroll to the bottom when new messages are added.\n * When enabled, the viewport will automatically scroll to show the latest content.\n *\n * Default false if `turnAnchor` is \"top\", otherwise defaults to true.\n */\n autoScroll?: boolean | undefined;\n\n /**\n * Controls scroll anchoring behavior for new messages.\n * - \"bottom\" (default): Messages anchor at the bottom, classic chat behavior.\n * - \"top\": New user messages anchor at the top of the viewport for a focused reading experience.\n */\n turnAnchor?: \"top\" | \"bottom\" | undefined;\n };\n}\n\nconst useViewportSizeRef = () => {\n const register = useThreadViewport((s) => s.registerViewport);\n const getHeight = useCallback(\n (el: HTMLElement) =>\n el.clientHeight - parseFloat(getComputedStyle(el).paddingTop),\n [],\n );\n\n return useSizeHandle(register, getHeight);\n};\n\nconst ThreadPrimitiveViewportScrollable = forwardRef<\n ThreadPrimitiveViewport.Element,\n ThreadPrimitiveViewport.Props\n>(({ autoScroll, children, ...rest }, forwardedRef) => {\n const autoScrollRef = useThreadViewportAutoScroll<HTMLDivElement>({\n autoScroll,\n });\n const viewportSizeRef = useViewportSizeRef();\n const ref = useComposedRefs(forwardedRef, autoScrollRef, viewportSizeRef);\n\n return (\n <Primitive.div {...rest} ref={ref}>\n {children}\n </Primitive.div>\n );\n});\n\nThreadPrimitiveViewportScrollable.displayName =\n \"ThreadPrimitive.ViewportScrollable\";\n\n/**\n * A scrollable viewport container for thread messages.\n *\n * This component provides a scrollable area for displaying thread messages with\n * automatic scrolling capabilities. It manages the viewport state and provides\n * context for child components to access viewport-related functionality.\n *\n * @example\n * ```tsx\n * <ThreadPrimitive.Viewport turnAnchor=\"top\">\n * <ThreadPrimitive.Messages components={{ Message: MyMessage }} />\n * </ThreadPrimitive.Viewport>\n * ```\n */\nexport const ThreadPrimitiveViewport = forwardRef<\n ThreadPrimitiveViewport.Element,\n ThreadPrimitiveViewport.Props\n>(({ turnAnchor, ...props }, ref) => {\n return (\n <ThreadPrimitiveViewportProvider options={{ turnAnchor }}>\n <ThreadPrimitiveViewportScrollable {...props} ref={ref} />\n </ThreadPrimitiveViewportProvider>\n );\n});\n\nThreadPrimitiveViewport.displayName = \"ThreadPrimitive.Viewport\";\n"],"mappings":";;;AAEA,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAC1B;AAAA,EAEE;AAAA,EAEA;AAAA,OACK;AACP,SAAS,mCAAmC;AAC5C,SAAS,uCAAuC;AAChD,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AA4C9B;AAtBJ,IAAM,qBAAqB,MAAM;AAC/B,QAAM,WAAW,kBAAkB,CAAC,MAAM,EAAE,gBAAgB;AAC5D,QAAM,YAAY;AAAA,IAChB,CAAC,OACC,GAAG,eAAe,WAAW,iBAAiB,EAAE,EAAE,UAAU;AAAA,IAC9D,CAAC;AAAA,EACH;AAEA,SAAO,cAAc,UAAU,SAAS;AAC1C;AAEA,IAAM,oCAAoC,WAGxC,CAAC,EAAE,YAAY,UAAU,GAAG,KAAK,GAAG,iBAAiB;AACrD,QAAM,gBAAgB,4BAA4C;AAAA,IAChE;AAAA,EACF,CAAC;AACD,QAAM,kBAAkB,mBAAmB;AAC3C,QAAM,MAAM,gBAAgB,cAAc,eAAe,eAAe;AAExE,SACE,oBAAC,UAAU,KAAV,EAAe,GAAG,MAAM,KACtB,UACH;AAEJ,CAAC;AAED,kCAAkC,cAChC;AAgBK,IAAM,0BAA0B,WAGrC,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,QAAQ;AACnC,SACE,oBAAC,mCAAgC,SAAS,EAAE,WAAW,GACrD,8BAAC,qCAAmC,GAAG,OAAO,KAAU,GAC1D;AAEJ,CAAC;AAED,wBAAwB,cAAc;","names":[]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
2
|
+
import { type ComponentRef, ComponentPropsWithoutRef } from "react";
|
|
3
|
+
export declare namespace ThreadPrimitiveViewportFooter {
|
|
4
|
+
type Element = ComponentRef<typeof Primitive.div>;
|
|
5
|
+
type Props = ComponentPropsWithoutRef<typeof Primitive.div>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A footer container that measures its height for scroll calculations.
|
|
9
|
+
*
|
|
10
|
+
* This component measures its height and provides it to the viewport context
|
|
11
|
+
* for use in scroll calculations (e.g., ViewportSlack min-height).
|
|
12
|
+
*
|
|
13
|
+
* Multiple ViewportFooter components can be used - their heights are summed.
|
|
14
|
+
*
|
|
15
|
+
* Typically used with `className="sticky bottom-0"` to keep the footer
|
|
16
|
+
* visible at the bottom of the viewport while scrolling.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <ThreadPrimitive.Viewport>
|
|
21
|
+
* <ThreadPrimitive.Messages components={{ ... }} />
|
|
22
|
+
* <ThreadPrimitive.ViewportFooter className="sticky bottom-0">
|
|
23
|
+
* <Composer />
|
|
24
|
+
* </ThreadPrimitive.ViewportFooter>
|
|
25
|
+
* </ThreadPrimitive.Viewport>
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare const ThreadPrimitiveViewportFooter: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & {
|
|
29
|
+
asChild?: boolean;
|
|
30
|
+
}, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
31
|
+
//# sourceMappingURL=ThreadViewportFooter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadViewportFooter.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewportFooter.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EACL,KAAK,YAAY,EAEjB,wBAAwB,EAEzB,MAAM,OAAO,CAAC;AAIf,yBAAiB,6BAA6B,CAAC;IAC7C,KAAY,OAAO,GAAG,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACzD,KAAY,KAAK,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;CACpE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,6BAA6B;;0DAexC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/primitives/thread/ThreadViewportFooter.tsx
|
|
4
|
+
import { useComposedRefs } from "@radix-ui/react-compose-refs";
|
|
5
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
6
|
+
import {
|
|
7
|
+
forwardRef,
|
|
8
|
+
useCallback
|
|
9
|
+
} from "react";
|
|
10
|
+
import { useSizeHandle } from "../../utils/hooks/useSizeHandle.js";
|
|
11
|
+
import { useThreadViewport } from "../../context/react/ThreadViewportContext.js";
|
|
12
|
+
import { jsx } from "react/jsx-runtime";
|
|
13
|
+
var ThreadPrimitiveViewportFooter = forwardRef((props, forwardedRef) => {
|
|
14
|
+
const register = useThreadViewport((s) => s.registerContentInset);
|
|
15
|
+
const getHeight = useCallback((el) => {
|
|
16
|
+
const marginTop = parseFloat(getComputedStyle(el).marginTop) || 0;
|
|
17
|
+
return el.offsetHeight + marginTop;
|
|
18
|
+
}, []);
|
|
19
|
+
const resizeRef = useSizeHandle(register, getHeight);
|
|
20
|
+
const ref = useComposedRefs(forwardedRef, resizeRef);
|
|
21
|
+
return /* @__PURE__ */ jsx(Primitive.div, { ...props, ref });
|
|
22
|
+
});
|
|
23
|
+
ThreadPrimitiveViewportFooter.displayName = "ThreadPrimitive.ViewportFooter";
|
|
24
|
+
export {
|
|
25
|
+
ThreadPrimitiveViewportFooter
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=ThreadViewportFooter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/primitives/thread/ThreadViewportFooter.tsx"],"sourcesContent":["\"use client\";\n\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport {\n type ComponentRef,\n forwardRef,\n ComponentPropsWithoutRef,\n useCallback,\n} from \"react\";\nimport { useSizeHandle } from \"../../utils/hooks/useSizeHandle\";\nimport { useThreadViewport } from \"../../context/react/ThreadViewportContext\";\n\nexport namespace ThreadPrimitiveViewportFooter {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.div>;\n}\n\n/**\n * A footer container that measures its height for scroll calculations.\n *\n * This component measures its height and provides it to the viewport context\n * for use in scroll calculations (e.g., ViewportSlack min-height).\n *\n * Multiple ViewportFooter components can be used - their heights are summed.\n *\n * Typically used with `className=\"sticky bottom-0\"` to keep the footer\n * visible at the bottom of the viewport while scrolling.\n *\n * @example\n * ```tsx\n * <ThreadPrimitive.Viewport>\n * <ThreadPrimitive.Messages components={{ ... }} />\n * <ThreadPrimitive.ViewportFooter className=\"sticky bottom-0\">\n * <Composer />\n * </ThreadPrimitive.ViewportFooter>\n * </ThreadPrimitive.Viewport>\n * ```\n */\nexport const ThreadPrimitiveViewportFooter = forwardRef<\n ThreadPrimitiveViewportFooter.Element,\n ThreadPrimitiveViewportFooter.Props\n>((props, forwardedRef) => {\n const register = useThreadViewport((s) => s.registerContentInset);\n const getHeight = useCallback((el: HTMLElement) => {\n const marginTop = parseFloat(getComputedStyle(el).marginTop) || 0;\n return el.offsetHeight + marginTop;\n }, []);\n\n const resizeRef = useSizeHandle(register, getHeight);\n\n const ref = useComposedRefs(forwardedRef, resizeRef);\n\n return <Primitive.div {...props} ref={ref} />;\n});\n\nThreadPrimitiveViewportFooter.displayName = \"ThreadPrimitive.ViewportFooter\";\n"],"mappings":";;;AAEA,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;AAC1B;AAAA,EAEE;AAAA,EAEA;AAAA,OACK;AACP,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AA0CzB;AAdF,IAAM,gCAAgC,WAG3C,CAAC,OAAO,iBAAiB;AACzB,QAAM,WAAW,kBAAkB,CAAC,MAAM,EAAE,oBAAoB;AAChE,QAAM,YAAY,YAAY,CAAC,OAAoB;AACjD,UAAM,YAAY,WAAW,iBAAiB,EAAE,EAAE,SAAS,KAAK;AAChE,WAAO,GAAG,eAAe;AAAA,EAC3B,GAAG,CAAC,CAAC;AAEL,QAAM,YAAY,cAAc,UAAU,SAAS;AAEnD,QAAM,MAAM,gBAAgB,cAAc,SAAS;AAEnD,SAAO,oBAAC,UAAU,KAAV,EAAe,GAAG,OAAO,KAAU;AAC7C,CAAC;AAED,8BAA8B,cAAc;","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type FC, type ReactNode } from "react";
|
|
2
|
+
export type ThreadViewportSlackProps = {
|
|
3
|
+
/** Threshold at which the user message height clamps to the offset */
|
|
4
|
+
fillClampThreshold?: string;
|
|
5
|
+
/** Offset used when clamping large user messages */
|
|
6
|
+
fillClampOffset?: string;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* A slot component that provides minimum height to enable scroll anchoring.
|
|
11
|
+
*
|
|
12
|
+
* When using `turnAnchor="top"`, this component ensures there is
|
|
13
|
+
* enough scroll room below the anchor point (last user message) for it to scroll
|
|
14
|
+
* to the top of the viewport. The min-height is applied only to the last
|
|
15
|
+
* assistant message.
|
|
16
|
+
*
|
|
17
|
+
* This component is used internally by MessagePrimitive.Root.
|
|
18
|
+
*/
|
|
19
|
+
export declare const ThreadPrimitiveViewportSlack: FC<ThreadViewportSlackProps>;
|
|
20
|
+
//# sourceMappingURL=ThreadViewportSlack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadViewportSlack.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewportSlack.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,EAAE,EACP,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AA2Bf,MAAM,MAAM,wBAAwB,GAAG;IACrC,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,EAAE,EAAE,CAAC,wBAAwB,CAoDrE,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/primitives/thread/ThreadViewportSlack.tsx
|
|
4
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
5
|
+
import {
|
|
6
|
+
createContext,
|
|
7
|
+
useCallback,
|
|
8
|
+
useContext
|
|
9
|
+
} from "react";
|
|
10
|
+
import { useThreadViewportStore } from "../../context/react/ThreadViewportContext.js";
|
|
11
|
+
import { useAssistantState } from "../../context/index.js";
|
|
12
|
+
import { useManagedRef } from "../../utils/hooks/useManagedRef.js";
|
|
13
|
+
import { jsx } from "react/jsx-runtime";
|
|
14
|
+
var SlackNestingContext = createContext(false);
|
|
15
|
+
var parseCssLength = (value, element) => {
|
|
16
|
+
const match = value.match(/^([\d.]+)(em|px|rem)$/);
|
|
17
|
+
if (!match) return 0;
|
|
18
|
+
const num = parseFloat(match[1]);
|
|
19
|
+
const unit = match[2];
|
|
20
|
+
if (unit === "px") return num;
|
|
21
|
+
if (unit === "em") {
|
|
22
|
+
const fontSize = parseFloat(getComputedStyle(element).fontSize) || 16;
|
|
23
|
+
return num * fontSize;
|
|
24
|
+
}
|
|
25
|
+
if (unit === "rem") {
|
|
26
|
+
const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
|
|
27
|
+
return num * rootFontSize;
|
|
28
|
+
}
|
|
29
|
+
return 0;
|
|
30
|
+
};
|
|
31
|
+
var ThreadPrimitiveViewportSlack = ({
|
|
32
|
+
children,
|
|
33
|
+
fillClampThreshold = "10em",
|
|
34
|
+
fillClampOffset = "6em"
|
|
35
|
+
}) => {
|
|
36
|
+
const isLast = useAssistantState(({ message }) => message.isLast);
|
|
37
|
+
const threadViewportStore = useThreadViewportStore({ optional: true });
|
|
38
|
+
const isNested = useContext(SlackNestingContext);
|
|
39
|
+
const callback = useCallback(
|
|
40
|
+
(el) => {
|
|
41
|
+
if (!threadViewportStore || isNested) return;
|
|
42
|
+
const updateMinHeight = () => {
|
|
43
|
+
const state = threadViewportStore.getState();
|
|
44
|
+
if (state.turnAnchor === "top" && isLast) {
|
|
45
|
+
const { viewport, inset, userMessage } = state.height;
|
|
46
|
+
const threshold = parseCssLength(fillClampThreshold, el);
|
|
47
|
+
const offset = parseCssLength(fillClampOffset, el);
|
|
48
|
+
const clampAdjustment = userMessage <= threshold ? userMessage : offset;
|
|
49
|
+
const minHeight = Math.max(0, viewport - inset - clampAdjustment);
|
|
50
|
+
el.style.minHeight = `${minHeight}px`;
|
|
51
|
+
el.style.flexShrink = "0";
|
|
52
|
+
el.style.transition = "min-height 0s";
|
|
53
|
+
} else {
|
|
54
|
+
el.style.minHeight = "";
|
|
55
|
+
el.style.flexShrink = "";
|
|
56
|
+
el.style.transition = "";
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
updateMinHeight();
|
|
60
|
+
return threadViewportStore.subscribe(updateMinHeight);
|
|
61
|
+
},
|
|
62
|
+
[
|
|
63
|
+
threadViewportStore,
|
|
64
|
+
isLast,
|
|
65
|
+
isNested,
|
|
66
|
+
fillClampThreshold,
|
|
67
|
+
fillClampOffset
|
|
68
|
+
]
|
|
69
|
+
);
|
|
70
|
+
const ref = useManagedRef(callback);
|
|
71
|
+
return /* @__PURE__ */ jsx(SlackNestingContext.Provider, { value: true, children: /* @__PURE__ */ jsx(Slot, { ref, children }) });
|
|
72
|
+
};
|
|
73
|
+
ThreadPrimitiveViewportSlack.displayName = "ThreadPrimitive.ViewportSlack";
|
|
74
|
+
export {
|
|
75
|
+
ThreadPrimitiveViewportSlack
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=ThreadViewportSlack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/primitives/thread/ThreadViewportSlack.tsx"],"sourcesContent":["\"use client\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n createContext,\n type FC,\n type ReactNode,\n useCallback,\n useContext,\n} from \"react\";\nimport { useThreadViewportStore } from \"../../context/react/ThreadViewportContext\";\nimport { useAssistantState } from \"../../context\";\nimport { useManagedRef } from \"../../utils/hooks/useManagedRef\";\n\nconst SlackNestingContext = createContext(false);\n\nconst parseCssLength = (value: string, element: HTMLElement): number => {\n const match = value.match(/^([\\d.]+)(em|px|rem)$/);\n if (!match) return 0;\n\n const num = parseFloat(match[1]!);\n const unit = match[2];\n\n if (unit === \"px\") return num;\n if (unit === \"em\") {\n const fontSize = parseFloat(getComputedStyle(element).fontSize) || 16;\n return num * fontSize;\n }\n if (unit === \"rem\") {\n const rootFontSize =\n parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\n return num * rootFontSize;\n }\n return 0;\n};\n\nexport type ThreadViewportSlackProps = {\n /** Threshold at which the user message height clamps to the offset */\n fillClampThreshold?: string;\n /** Offset used when clamping large user messages */\n fillClampOffset?: string;\n children: ReactNode;\n};\n\n/**\n * A slot component that provides minimum height to enable scroll anchoring.\n *\n * When using `turnAnchor=\"top\"`, this component ensures there is\n * enough scroll room below the anchor point (last user message) for it to scroll\n * to the top of the viewport. The min-height is applied only to the last\n * assistant message.\n *\n * This component is used internally by MessagePrimitive.Root.\n */\nexport const ThreadPrimitiveViewportSlack: FC<ThreadViewportSlackProps> = ({\n children,\n fillClampThreshold = \"10em\",\n fillClampOffset = \"6em\",\n}) => {\n const isLast = useAssistantState(({ message }) => message.isLast);\n const threadViewportStore = useThreadViewportStore({ optional: true });\n const isNested = useContext(SlackNestingContext);\n\n const callback = useCallback(\n (el: HTMLElement) => {\n if (!threadViewportStore || isNested) return;\n\n const updateMinHeight = () => {\n const state = threadViewportStore.getState();\n if (state.turnAnchor === \"top\" && isLast) {\n const { viewport, inset, userMessage } = state.height;\n const threshold = parseCssLength(fillClampThreshold, el);\n const offset = parseCssLength(fillClampOffset, el);\n const clampAdjustment =\n userMessage <= threshold ? userMessage : offset;\n\n const minHeight = Math.max(0, viewport - inset - clampAdjustment);\n el.style.minHeight = `${minHeight}px`;\n el.style.flexShrink = \"0\";\n el.style.transition = \"min-height 0s\";\n } else {\n el.style.minHeight = \"\";\n el.style.flexShrink = \"\";\n el.style.transition = \"\";\n }\n };\n\n updateMinHeight();\n return threadViewportStore.subscribe(updateMinHeight);\n },\n [\n threadViewportStore,\n isLast,\n isNested,\n fillClampThreshold,\n fillClampOffset,\n ],\n );\n\n const ref = useManagedRef<HTMLElement>(callback);\n\n return (\n <SlackNestingContext.Provider value={true}>\n <Slot ref={ref}>{children}</Slot>\n </SlackNestingContext.Provider>\n );\n};\n\nThreadPrimitiveViewportSlack.displayName = \"ThreadPrimitive.ViewportSlack\";\n"],"mappings":";;;AAEA,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EAGA;AAAA,EACA;AAAA,OACK;AACP,SAAS,8BAA8B;AACvC,SAAS,yBAAyB;AAClC,SAAS,qBAAqB;AA2FxB;AAzFN,IAAM,sBAAsB,cAAc,KAAK;AAE/C,IAAM,iBAAiB,CAAC,OAAe,YAAiC;AACtE,QAAM,QAAQ,MAAM,MAAM,uBAAuB;AACjD,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,MAAM,WAAW,MAAM,CAAC,CAAE;AAChC,QAAM,OAAO,MAAM,CAAC;AAEpB,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,SAAS,MAAM;AACjB,UAAM,WAAW,WAAW,iBAAiB,OAAO,EAAE,QAAQ,KAAK;AACnE,WAAO,MAAM;AAAA,EACf;AACA,MAAI,SAAS,OAAO;AAClB,UAAM,eACJ,WAAW,iBAAiB,SAAS,eAAe,EAAE,QAAQ,KAAK;AACrE,WAAO,MAAM;AAAA,EACf;AACA,SAAO;AACT;AAoBO,IAAM,+BAA6D,CAAC;AAAA,EACzE;AAAA,EACA,qBAAqB;AAAA,EACrB,kBAAkB;AACpB,MAAM;AACJ,QAAM,SAAS,kBAAkB,CAAC,EAAE,QAAQ,MAAM,QAAQ,MAAM;AAChE,QAAM,sBAAsB,uBAAuB,EAAE,UAAU,KAAK,CAAC;AACrE,QAAM,WAAW,WAAW,mBAAmB;AAE/C,QAAM,WAAW;AAAA,IACf,CAAC,OAAoB;AACnB,UAAI,CAAC,uBAAuB,SAAU;AAEtC,YAAM,kBAAkB,MAAM;AAC5B,cAAM,QAAQ,oBAAoB,SAAS;AAC3C,YAAI,MAAM,eAAe,SAAS,QAAQ;AACxC,gBAAM,EAAE,UAAU,OAAO,YAAY,IAAI,MAAM;AAC/C,gBAAM,YAAY,eAAe,oBAAoB,EAAE;AACvD,gBAAM,SAAS,eAAe,iBAAiB,EAAE;AACjD,gBAAM,kBACJ,eAAe,YAAY,cAAc;AAE3C,gBAAM,YAAY,KAAK,IAAI,GAAG,WAAW,QAAQ,eAAe;AAChE,aAAG,MAAM,YAAY,GAAG,SAAS;AACjC,aAAG,MAAM,aAAa;AACtB,aAAG,MAAM,aAAa;AAAA,QACxB,OAAO;AACL,aAAG,MAAM,YAAY;AACrB,aAAG,MAAM,aAAa;AACtB,aAAG,MAAM,aAAa;AAAA,QACxB;AAAA,MACF;AAEA,sBAAgB;AAChB,aAAO,oBAAoB,UAAU,eAAe;AAAA,IACtD;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,cAA2B,QAAQ;AAE/C,SACE,oBAAC,oBAAoB,UAApB,EAA6B,OAAO,MACnC,8BAAC,QAAK,KAAW,UAAS,GAC5B;AAEJ;AAEA,6BAA6B,cAAc;","names":[]}
|
|
@@ -2,6 +2,9 @@ export { ThreadPrimitiveRoot as Root } from "./ThreadRoot";
|
|
|
2
2
|
export { ThreadPrimitiveEmpty as Empty } from "./ThreadEmpty";
|
|
3
3
|
export { ThreadPrimitiveIf as If } from "./ThreadIf";
|
|
4
4
|
export { ThreadPrimitiveViewport as Viewport } from "./ThreadViewport";
|
|
5
|
+
export { ThreadPrimitiveViewportProvider as ViewportProvider } from "../../context/providers/ThreadViewportProvider";
|
|
6
|
+
export { ThreadPrimitiveViewportFooter as ViewportFooter } from "./ThreadViewportFooter";
|
|
7
|
+
export { ThreadPrimitiveViewportSlack as ViewportSlack } from "./ThreadViewportSlack";
|
|
5
8
|
export { ThreadPrimitiveMessages as Messages } from "./ThreadMessages";
|
|
6
9
|
export { ThreadPrimitiveMessageByIndex as MessageByIndex } from "./ThreadMessages";
|
|
7
10
|
export { ThreadPrimitiveScrollToBottom as ScrollToBottom } from "./ThreadScrollToBottom";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,IAAI,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,oBAAoB,IAAI,KAAK,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,iBAAiB,IAAI,EAAE,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,yBAAyB,IAAI,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,IAAI,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,oBAAoB,IAAI,KAAK,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,iBAAiB,IAAI,EAAE,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,+BAA+B,IAAI,gBAAgB,EAAE,MAAM,gDAAgD,CAAC;AACrH,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,4BAA4B,IAAI,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,uBAAuB,IAAI,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,6BAA6B,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,yBAAyB,IAAI,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -3,6 +3,9 @@ import { ThreadPrimitiveRoot } from "./ThreadRoot.js";
|
|
|
3
3
|
import { ThreadPrimitiveEmpty } from "./ThreadEmpty.js";
|
|
4
4
|
import { ThreadPrimitiveIf } from "./ThreadIf.js";
|
|
5
5
|
import { ThreadPrimitiveViewport } from "./ThreadViewport.js";
|
|
6
|
+
import { ThreadPrimitiveViewportProvider } from "../../context/providers/ThreadViewportProvider.js";
|
|
7
|
+
import { ThreadPrimitiveViewportFooter } from "./ThreadViewportFooter.js";
|
|
8
|
+
import { ThreadPrimitiveViewportSlack } from "./ThreadViewportSlack.js";
|
|
6
9
|
import { ThreadPrimitiveMessages } from "./ThreadMessages.js";
|
|
7
10
|
import { ThreadPrimitiveMessageByIndex } from "./ThreadMessages.js";
|
|
8
11
|
import { ThreadPrimitiveScrollToBottom } from "./ThreadScrollToBottom.js";
|
|
@@ -15,6 +18,9 @@ export {
|
|
|
15
18
|
ThreadPrimitiveRoot as Root,
|
|
16
19
|
ThreadPrimitiveScrollToBottom as ScrollToBottom,
|
|
17
20
|
ThreadPrimitiveSuggestion as Suggestion,
|
|
18
|
-
ThreadPrimitiveViewport as Viewport
|
|
21
|
+
ThreadPrimitiveViewport as Viewport,
|
|
22
|
+
ThreadPrimitiveViewportFooter as ViewportFooter,
|
|
23
|
+
ThreadPrimitiveViewportProvider as ViewportProvider,
|
|
24
|
+
ThreadPrimitiveViewportSlack as ViewportSlack
|
|
19
25
|
};
|
|
20
26
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/primitives/thread/index.ts"],"sourcesContent":["export { ThreadPrimitiveRoot as Root } from \"./ThreadRoot\";\nexport { ThreadPrimitiveEmpty as Empty } from \"./ThreadEmpty\";\nexport { ThreadPrimitiveIf as If } from \"./ThreadIf\";\nexport { ThreadPrimitiveViewport as Viewport } from \"./ThreadViewport\";\nexport { ThreadPrimitiveMessages as Messages } from \"./ThreadMessages\";\nexport { ThreadPrimitiveMessageByIndex as MessageByIndex } from \"./ThreadMessages\";\nexport { ThreadPrimitiveScrollToBottom as ScrollToBottom } from \"./ThreadScrollToBottom\";\nexport { ThreadPrimitiveSuggestion as Suggestion } from \"./ThreadSuggestion\";\n"],"mappings":";AAAA,SAAgC,2BAAY;AAC5C,SAAiC,4BAAa;AAC9C,SAA8B,yBAAU;AACxC,SAAoC,+BAAgB;AACpD,SAAoC,+BAAgB;AACpD,SAA0C,qCAAsB;AAChE,SAA0C,qCAAsB;AAChE,SAAsC,iCAAkB;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/primitives/thread/index.ts"],"sourcesContent":["export { ThreadPrimitiveRoot as Root } from \"./ThreadRoot\";\nexport { ThreadPrimitiveEmpty as Empty } from \"./ThreadEmpty\";\nexport { ThreadPrimitiveIf as If } from \"./ThreadIf\";\nexport { ThreadPrimitiveViewport as Viewport } from \"./ThreadViewport\";\nexport { ThreadPrimitiveViewportProvider as ViewportProvider } from \"../../context/providers/ThreadViewportProvider\";\nexport { ThreadPrimitiveViewportFooter as ViewportFooter } from \"./ThreadViewportFooter\";\nexport { ThreadPrimitiveViewportSlack as ViewportSlack } from \"./ThreadViewportSlack\";\nexport { ThreadPrimitiveMessages as Messages } from \"./ThreadMessages\";\nexport { ThreadPrimitiveMessageByIndex as MessageByIndex } from \"./ThreadMessages\";\nexport { ThreadPrimitiveScrollToBottom as ScrollToBottom } from \"./ThreadScrollToBottom\";\nexport { ThreadPrimitiveSuggestion as Suggestion } from \"./ThreadSuggestion\";\n"],"mappings":";AAAA,SAAgC,2BAAY;AAC5C,SAAiC,4BAAa;AAC9C,SAA8B,yBAAU;AACxC,SAAoC,+BAAgB;AACpD,SAA4C,uCAAwB;AACpE,SAA0C,qCAAsB;AAChE,SAAyC,oCAAqB;AAC9D,SAAoC,+BAAgB;AACpD,SAA0C,qCAAsB;AAChE,SAA0C,qCAAsB;AAChE,SAAsC,iCAAkB;","names":[]}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { RefCallback } from "react";
|
|
2
2
|
export declare namespace useThreadViewportAutoScroll {
|
|
3
3
|
type Options = {
|
|
4
|
+
/**
|
|
5
|
+
* Whether to automatically scroll to the bottom when new messages are added.
|
|
6
|
+
* When enabled, the viewport will automatically scroll to show the latest content.
|
|
7
|
+
*
|
|
8
|
+
* Default false if `turnAnchor` is "top", otherwise defaults to true.
|
|
9
|
+
*/
|
|
4
10
|
autoScroll?: boolean | undefined;
|
|
5
11
|
};
|
|
6
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useThreadViewportAutoScroll.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAuB,MAAM,OAAO,CAAC;AAQzD,yBAAiB,2BAA2B,CAAC;IAC3C,KAAY,OAAO,GAAG;QACpB,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KAClC,CAAC;CACH;AAED,eAAO,MAAM,2BAA2B,GAAI,QAAQ,SAAS,WAAW,EAAE,iBAEvE,2BAA2B,CAAC,OAAO,KAAG,WAAW,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"useThreadViewportAutoScroll.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAuB,MAAM,OAAO,CAAC;AAQzD,yBAAiB,2BAA2B,CAAC;IAC3C,KAAY,OAAO,GAAG;QACpB;;;;;WAKG;QACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KAClC,CAAC;CACH;AAED,eAAO,MAAM,2BAA2B,GAAI,QAAQ,SAAS,WAAW,EAAE,iBAEvE,2BAA2B,CAAC,OAAO,KAAG,WAAW,CAAC,QAAQ,CAiF5D,CAAC"}
|
|
@@ -10,16 +10,19 @@ import { useManagedRef } from "../../utils/hooks/useManagedRef.js";
|
|
|
10
10
|
import { writableStore } from "../../context/ReadonlyStore.js";
|
|
11
11
|
import { useThreadViewportStore } from "../../context/react/ThreadViewportContext.js";
|
|
12
12
|
var useThreadViewportAutoScroll = ({
|
|
13
|
-
autoScroll
|
|
13
|
+
autoScroll
|
|
14
14
|
}) => {
|
|
15
15
|
const divRef = useRef(null);
|
|
16
16
|
const threadViewportStore = useThreadViewportStore();
|
|
17
|
+
if (autoScroll === void 0) {
|
|
18
|
+
autoScroll = threadViewportStore.getState().turnAnchor !== "top";
|
|
19
|
+
}
|
|
17
20
|
const lastScrollTop = useRef(0);
|
|
18
|
-
const
|
|
21
|
+
const scrollingToBottomBehaviorRef = useRef(null);
|
|
19
22
|
const scrollToBottom = useCallback((behavior) => {
|
|
20
23
|
const div = divRef.current;
|
|
21
24
|
if (!div) return;
|
|
22
|
-
|
|
25
|
+
scrollingToBottomBehaviorRef.current = behavior;
|
|
23
26
|
div.scrollTo({ top: div.scrollHeight, behavior });
|
|
24
27
|
}, []);
|
|
25
28
|
const handleScroll = () => {
|
|
@@ -30,7 +33,7 @@ var useThreadViewportAutoScroll = ({
|
|
|
30
33
|
if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
|
|
31
34
|
} else {
|
|
32
35
|
if (newIsAtBottom) {
|
|
33
|
-
|
|
36
|
+
scrollingToBottomBehaviorRef.current = null;
|
|
34
37
|
}
|
|
35
38
|
if (newIsAtBottom !== isAtBottom) {
|
|
36
39
|
writableStore(threadViewportStore).setState({
|
|
@@ -41,7 +44,10 @@ var useThreadViewportAutoScroll = ({
|
|
|
41
44
|
lastScrollTop.current = div.scrollTop;
|
|
42
45
|
};
|
|
43
46
|
const resizeRef = useOnResizeContent(() => {
|
|
44
|
-
|
|
47
|
+
const scrollBehavior = scrollingToBottomBehaviorRef.current;
|
|
48
|
+
if (scrollBehavior) {
|
|
49
|
+
scrollToBottom(scrollBehavior);
|
|
50
|
+
} else if (autoScroll && threadViewportStore.getState().isAtBottom) {
|
|
45
51
|
scrollToBottom("instant");
|
|
46
52
|
}
|
|
47
53
|
handleScroll();
|
|
@@ -52,11 +58,14 @@ var useThreadViewportAutoScroll = ({
|
|
|
52
58
|
el.removeEventListener("scroll", handleScroll);
|
|
53
59
|
};
|
|
54
60
|
});
|
|
55
|
-
useOnScrollToBottom(() => {
|
|
56
|
-
scrollToBottom(
|
|
61
|
+
useOnScrollToBottom(({ behavior }) => {
|
|
62
|
+
scrollToBottom(behavior);
|
|
57
63
|
});
|
|
58
64
|
useAssistantEvent("thread.run-start", () => {
|
|
59
|
-
|
|
65
|
+
scrollingToBottomBehaviorRef.current = "auto";
|
|
66
|
+
requestAnimationFrame(() => {
|
|
67
|
+
scrollToBottom("auto");
|
|
68
|
+
});
|
|
60
69
|
});
|
|
61
70
|
const autoScrollRef = useComposedRefs(resizeRef, scrollRef, divRef);
|
|
62
71
|
return autoScrollRef;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.tsx"],"sourcesContent":["\"use client\";\n\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { RefCallback, useCallback, useRef } from \"react\";\nimport { useAssistantEvent } from \"../../context\";\nimport { useOnResizeContent } from \"../../utils/hooks/useOnResizeContent\";\nimport { useOnScrollToBottom } from \"../../utils/hooks/useOnScrollToBottom\";\nimport { useManagedRef } from \"../../utils/hooks/useManagedRef\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\nimport { useThreadViewportStore } from \"../../context/react/ThreadViewportContext\";\n\nexport namespace useThreadViewportAutoScroll {\n export type Options = {\n autoScroll?: boolean | undefined;\n };\n}\n\nexport const useThreadViewportAutoScroll = <TElement extends HTMLElement>({\n autoScroll
|
|
1
|
+
{"version":3,"sources":["../../../src/primitives/thread/useThreadViewportAutoScroll.tsx"],"sourcesContent":["\"use client\";\n\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { RefCallback, useCallback, useRef } from \"react\";\nimport { useAssistantEvent } from \"../../context\";\nimport { useOnResizeContent } from \"../../utils/hooks/useOnResizeContent\";\nimport { useOnScrollToBottom } from \"../../utils/hooks/useOnScrollToBottom\";\nimport { useManagedRef } from \"../../utils/hooks/useManagedRef\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\nimport { useThreadViewportStore } from \"../../context/react/ThreadViewportContext\";\n\nexport namespace useThreadViewportAutoScroll {\n export type Options = {\n /**\n * Whether to automatically scroll to the bottom when new messages are added.\n * When enabled, the viewport will automatically scroll to show the latest content.\n *\n * Default false if `turnAnchor` is \"top\", otherwise defaults to true.\n */\n autoScroll?: boolean | undefined;\n };\n}\n\nexport const useThreadViewportAutoScroll = <TElement extends HTMLElement>({\n autoScroll,\n}: useThreadViewportAutoScroll.Options): RefCallback<TElement> => {\n const divRef = useRef<TElement>(null);\n\n const threadViewportStore = useThreadViewportStore();\n if (autoScroll === undefined) {\n autoScroll = threadViewportStore.getState().turnAnchor !== \"top\";\n }\n\n const lastScrollTop = useRef<number>(0);\n\n // bug: when ScrollToBottom's button changes its disabled state, the scroll stops\n // fix: delay the state change until the scroll is done\n // stores the scroll behavior to reuse during content resize, or null if not scrolling\n const scrollingToBottomBehaviorRef = useRef<ScrollBehavior | null>(null);\n\n const scrollToBottom = useCallback((behavior: ScrollBehavior) => {\n const div = divRef.current;\n if (!div) return;\n\n scrollingToBottomBehaviorRef.current = behavior;\n div.scrollTo({ top: div.scrollHeight, behavior });\n }, []);\n\n const handleScroll = () => {\n const div = divRef.current;\n if (!div) return;\n\n const isAtBottom = threadViewportStore.getState().isAtBottom;\n const newIsAtBottom =\n Math.abs(div.scrollHeight - div.scrollTop - div.clientHeight) < 1 ||\n div.scrollHeight <= div.clientHeight;\n\n if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {\n // ignore scroll down\n } else {\n if (newIsAtBottom) {\n scrollingToBottomBehaviorRef.current = null;\n }\n\n if (newIsAtBottom !== isAtBottom) {\n writableStore(threadViewportStore).setState({\n isAtBottom: newIsAtBottom,\n });\n }\n }\n\n lastScrollTop.current = div.scrollTop;\n };\n\n const resizeRef = useOnResizeContent(() => {\n const scrollBehavior = scrollingToBottomBehaviorRef.current;\n if (scrollBehavior) {\n scrollToBottom(scrollBehavior);\n } else if (autoScroll && threadViewportStore.getState().isAtBottom) {\n scrollToBottom(\"instant\");\n }\n\n handleScroll();\n });\n\n const scrollRef = useManagedRef<HTMLElement>((el) => {\n el.addEventListener(\"scroll\", handleScroll);\n return () => {\n el.removeEventListener(\"scroll\", handleScroll);\n };\n });\n\n useOnScrollToBottom(({ behavior }) => {\n scrollToBottom(behavior);\n });\n\n // autoscroll on run start\n useAssistantEvent(\"thread.run-start\", () => {\n scrollingToBottomBehaviorRef.current = \"auto\";\n requestAnimationFrame(() => {\n scrollToBottom(\"auto\");\n });\n });\n\n const autoScrollRef = useComposedRefs<TElement>(resizeRef, scrollRef, divRef);\n return autoScrollRef as RefCallback<TElement>;\n};\n"],"mappings":";;;AAEA,SAAS,uBAAuB;AAChC,SAAsB,aAAa,cAAc;AACjD,SAAS,yBAAyB;AAClC,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,8BAA8B;AAchC,IAAM,8BAA8B,CAA+B;AAAA,EACxE;AACF,MAAkE;AAChE,QAAM,SAAS,OAAiB,IAAI;AAEpC,QAAM,sBAAsB,uBAAuB;AACnD,MAAI,eAAe,QAAW;AAC5B,iBAAa,oBAAoB,SAAS,EAAE,eAAe;AAAA,EAC7D;AAEA,QAAM,gBAAgB,OAAe,CAAC;AAKtC,QAAM,+BAA+B,OAA8B,IAAI;AAEvE,QAAM,iBAAiB,YAAY,CAAC,aAA6B;AAC/D,UAAM,MAAM,OAAO;AACnB,QAAI,CAAC,IAAK;AAEV,iCAA6B,UAAU;AACvC,QAAI,SAAS,EAAE,KAAK,IAAI,cAAc,SAAS,CAAC;AAAA,EAClD,GAAG,CAAC,CAAC;AAEL,QAAM,eAAe,MAAM;AACzB,UAAM,MAAM,OAAO;AACnB,QAAI,CAAC,IAAK;AAEV,UAAM,aAAa,oBAAoB,SAAS,EAAE;AAClD,UAAM,gBACJ,KAAK,IAAI,IAAI,eAAe,IAAI,YAAY,IAAI,YAAY,IAAI,KAChE,IAAI,gBAAgB,IAAI;AAE1B,QAAI,CAAC,iBAAiB,cAAc,UAAU,IAAI,WAAW;AAAA,IAE7D,OAAO;AACL,UAAI,eAAe;AACjB,qCAA6B,UAAU;AAAA,MACzC;AAEA,UAAI,kBAAkB,YAAY;AAChC,sBAAc,mBAAmB,EAAE,SAAS;AAAA,UAC1C,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAEA,kBAAc,UAAU,IAAI;AAAA,EAC9B;AAEA,QAAM,YAAY,mBAAmB,MAAM;AACzC,UAAM,iBAAiB,6BAA6B;AACpD,QAAI,gBAAgB;AAClB,qBAAe,cAAc;AAAA,IAC/B,WAAW,cAAc,oBAAoB,SAAS,EAAE,YAAY;AAClE,qBAAe,SAAS;AAAA,IAC1B;AAEA,iBAAa;AAAA,EACf,CAAC;AAED,QAAM,YAAY,cAA2B,CAAC,OAAO;AACnD,OAAG,iBAAiB,UAAU,YAAY;AAC1C,WAAO,MAAM;AACX,SAAG,oBAAoB,UAAU,YAAY;AAAA,IAC/C;AAAA,EACF,CAAC;AAED,sBAAoB,CAAC,EAAE,SAAS,MAAM;AACpC,mBAAe,QAAQ;AAAA,EACzB,CAAC;AAGD,oBAAkB,oBAAoB,MAAM;AAC1C,iCAA6B,UAAU;AACvC,0BAAsB,MAAM;AAC1B,qBAAe,MAAM;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AAED,QAAM,gBAAgB,gBAA0B,WAAW,WAAW,MAAM;AAC5E,SAAO;AACT;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useOnScrollToBottom.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useOnScrollToBottom.tsx"],"names":[],"mappings":"AAMA,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"useOnScrollToBottom.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useOnScrollToBottom.tsx"],"names":[],"mappings":"AAMA,eAAO,MAAM,mBAAmB,GAC9B,UAAU,CAAC,MAAM,EAAE;IAAE,QAAQ,EAAE,cAAc,CAAA;CAAE,KAAK,IAAI,SAQzD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/hooks/useOnScrollToBottom.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useEffect } from \"react\";\nimport { useThreadViewport } from \"../../context/react/ThreadViewportContext\";\n\nexport const useOnScrollToBottom = (callback: () => void) => {\n const callbackRef = useCallbackRef(callback);\n const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);\n\n useEffect(() => {\n return onScrollToBottom(callbackRef);\n }, [onScrollToBottom, callbackRef]);\n};\n"],"mappings":";;;AAEA,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAE3B,IAAM,sBAAsB,
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/hooks/useOnScrollToBottom.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useEffect } from \"react\";\nimport { useThreadViewport } from \"../../context/react/ThreadViewportContext\";\n\nexport const useOnScrollToBottom = (\n callback: (config: { behavior: ScrollBehavior }) => void,\n) => {\n const callbackRef = useCallbackRef(callback);\n const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);\n\n useEffect(() => {\n return onScrollToBottom(callbackRef);\n }, [onScrollToBottom, callbackRef]);\n};\n"],"mappings":";;;AAEA,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAE3B,IAAM,sBAAsB,CACjC,aACG;AACH,QAAM,cAAc,eAAe,QAAQ;AAC3C,QAAM,mBAAmB,kBAAkB,CAAC,OAAO,GAAG,gBAAgB;AAEtE,YAAU,MAAM;AACd,WAAO,iBAAiB,WAAW;AAAA,EACrC,GAAG,CAAC,kBAAkB,WAAW,CAAC;AACpC;","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SizeHandle } from "../../context/stores/ThreadViewport";
|
|
2
|
+
/**
|
|
3
|
+
* Hook that creates a ref for tracking element size via a SizeHandle.
|
|
4
|
+
* Automatically sets up ResizeObserver and reports height changes.
|
|
5
|
+
*
|
|
6
|
+
* @param register - Function that returns a SizeHandle (e.g., registerContentInset)
|
|
7
|
+
* @param getHeight - Optional function to compute height (defaults to el.offsetHeight)
|
|
8
|
+
* @returns A ref callback to attach to the element
|
|
9
|
+
*/
|
|
10
|
+
export declare const useSizeHandle: (register: (() => SizeHandle) | null | undefined, getHeight?: (el: HTMLElement) => number) => (el: HTMLElement | null) => void;
|
|
11
|
+
//# sourceMappingURL=useSizeHandle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSizeHandle.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useSizeHandle.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAEtE;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GACxB,UAAU,CAAC,MAAM,UAAU,CAAC,GAAG,IAAI,GAAG,SAAS,EAC/C,YAAY,CAAC,EAAE,EAAE,WAAW,KAAK,MAAM,qCA0BxC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/utils/hooks/useSizeHandle.ts
|
|
4
|
+
import { useCallback } from "react";
|
|
5
|
+
import { useManagedRef } from "./useManagedRef.js";
|
|
6
|
+
var useSizeHandle = (register, getHeight) => {
|
|
7
|
+
const callbackRef = useCallback(
|
|
8
|
+
(el) => {
|
|
9
|
+
if (!register) return;
|
|
10
|
+
const sizeHandle = register();
|
|
11
|
+
const updateHeight = () => {
|
|
12
|
+
const height = getHeight ? getHeight(el) : el.offsetHeight;
|
|
13
|
+
sizeHandle.setHeight(height);
|
|
14
|
+
};
|
|
15
|
+
const ro = new ResizeObserver(updateHeight);
|
|
16
|
+
ro.observe(el);
|
|
17
|
+
updateHeight();
|
|
18
|
+
return () => {
|
|
19
|
+
ro.disconnect();
|
|
20
|
+
sizeHandle.unregister();
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
[register, getHeight]
|
|
24
|
+
);
|
|
25
|
+
return useManagedRef(callbackRef);
|
|
26
|
+
};
|
|
27
|
+
export {
|
|
28
|
+
useSizeHandle
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=useSizeHandle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/hooks/useSizeHandle.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useManagedRef } from \"./useManagedRef\";\nimport type { SizeHandle } from \"../../context/stores/ThreadViewport\";\n\n/**\n * Hook that creates a ref for tracking element size via a SizeHandle.\n * Automatically sets up ResizeObserver and reports height changes.\n *\n * @param register - Function that returns a SizeHandle (e.g., registerContentInset)\n * @param getHeight - Optional function to compute height (defaults to el.offsetHeight)\n * @returns A ref callback to attach to the element\n */\nexport const useSizeHandle = (\n register: (() => SizeHandle) | null | undefined,\n getHeight?: (el: HTMLElement) => number,\n) => {\n const callbackRef = useCallback(\n (el: HTMLElement) => {\n if (!register) return;\n\n const sizeHandle = register();\n\n const updateHeight = () => {\n const height = getHeight ? getHeight(el) : el.offsetHeight;\n sizeHandle.setHeight(height);\n };\n\n const ro = new ResizeObserver(updateHeight);\n ro.observe(el);\n updateHeight();\n\n return () => {\n ro.disconnect();\n sizeHandle.unregister();\n };\n },\n [register, getHeight],\n );\n\n return useManagedRef(callbackRef);\n};\n"],"mappings":";;;AAEA,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAWvB,IAAM,gBAAgB,CAC3B,UACA,cACG;AACH,QAAM,cAAc;AAAA,IAClB,CAAC,OAAoB;AACnB,UAAI,CAAC,SAAU;AAEf,YAAM,aAAa,SAAS;AAE5B,YAAM,eAAe,MAAM;AACzB,cAAM,SAAS,YAAY,UAAU,EAAE,IAAI,GAAG;AAC9C,mBAAW,UAAU,MAAM;AAAA,MAC7B;AAEA,YAAM,KAAK,IAAI,eAAe,YAAY;AAC1C,SAAG,QAAQ,EAAE;AACb,mBAAa;AAEb,aAAO,MAAM;AACX,WAAG,WAAW;AACd,mBAAW,WAAW;AAAA,MACxB;AAAA,IACF;AAAA,IACA,CAAC,UAAU,SAAS;AAAA,EACtB;AAEA,SAAO,cAAc,WAAW;AAClC;","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AssistantApi, AssistantApiField } from "../../context/react/AssistantApiContext";
|
|
2
2
|
import type { AssistantEvent, AssistantEventCallback, AssistantEventSelector } from "../../types/EventTypes";
|
|
3
|
-
import type { ResourceElement
|
|
3
|
+
import type { ResourceElement } from "@assistant-ui/tap";
|
|
4
|
+
import { Unsubscribe } from "../../types";
|
|
4
5
|
/**
|
|
5
6
|
* Extract the API return type from an AssistantApiField
|
|
6
7
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derived-scopes.d.ts","sourceRoot":"","sources":["../../../src/utils/tap-store/derived-scopes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"derived-scopes.d.ts","sourceRoot":"","sources":["../../../src/utils/tap-store/derived-scopes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C;;GAEG;AACH,KAAK,cAAc,CAAC,CAAC,IACnB,CAAC,SAAS,iBAAiB,CAAC,MAAM,IAAI,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC;AAE9D;;;;;GAKG;AACH,KAAK,WAAW,CAAC,CAAC,IAChB,CAAC,SAAS,iBAAiB,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC;AAEhE;;GAEG;AACH,KAAK,sBAAsB,GAAG;KAC3B,CAAC,IAAI,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,SAAS;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,GAC1E,CAAC,GACD,KAAK;CACV,CAAC,MAAM,YAAY,CAAC,CAAC;AAEtB;;GAEG;AACH,MAAM,MAAM,kBAAkB,CAAC,OAAO,SAAS,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI;IAC5E,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,IAAI,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,SAAS,cAAc,EACvD,QAAQ,EAAE,sBAAsB,CAAC,MAAM,CAAC,EACxC,QAAQ,EAAE,sBAAsB,CAAC,MAAM,CAAC,KACrC,WAAW,CAAC;AAEjB;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,WAAW,CAAC;AAExE;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,SAAS,CAAC,EAAE,mBAAmB,CAAC;CACjC,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG;KAC9B,CAAC,IAAI,sBAAsB,CAAC,CAAC,EAAE,eAAe,CAC7C,iBAAiB,CACf,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAC/B;QACE,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC/C,KAAK,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;KAC9C,CACF,CACF;CACF,GAAG,gBAAgB,CAAC;AAErB;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GACtB,OAAO,SAAS,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI;;;YAKhC,OAAO;WACR,MAAM;8CAgBlB,CAAC;AAmBF;;;GAGG;AACH,eAAO,MAAM,aAAa,iFAyCzB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/tap-store/derived-scopes.ts"],"sourcesContent":["import { resource, tapEffect } from \"@assistant-ui/tap\";\nimport { tapMemo, tapRef, tapResource, tapResources } from \"@assistant-ui/tap\";\nimport { createAssistantApiField } from \"../../context/react/AssistantApiContext\";\nimport type {\n AssistantApi,\n AssistantApiField,\n} from \"../../context/react/AssistantApiContext\";\nimport type {\n AssistantEvent,\n AssistantEventCallback,\n AssistantEventSelector,\n} from \"../../types/EventTypes\";\nimport type { ResourceElement
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/tap-store/derived-scopes.ts"],"sourcesContent":["import { resource, tapEffect } from \"@assistant-ui/tap\";\nimport { tapMemo, tapRef, tapResource, tapResources } from \"@assistant-ui/tap\";\nimport { createAssistantApiField } from \"../../context/react/AssistantApiContext\";\nimport type {\n AssistantApi,\n AssistantApiField,\n} from \"../../context/react/AssistantApiContext\";\nimport type {\n AssistantEvent,\n AssistantEventCallback,\n AssistantEventSelector,\n} from \"../../types/EventTypes\";\nimport type { ResourceElement } from \"@assistant-ui/tap\";\nimport { Unsubscribe } from \"../../types\";\n\n/**\n * Extract the API return type from an AssistantApiField\n */\ntype ExtractApiType<T> =\n T extends AssistantApiField<infer TApi, any> ? TApi : never;\n\n/**\n * Extract the metadata type from an AssistantApiField\n *\n * Used in DerivedScopesInput to validate that each field's source/query types match\n * the expected types from AssistantApi.\n */\ntype ExtractMeta<T> =\n T extends AssistantApiField<any, infer TMeta> ? TMeta : never;\n\n/**\n * Get only the field names from AssistantApi (exclude method names)\n */\ntype AssistantApiFieldNames = {\n [K in keyof AssistantApi]: AssistantApi[K] extends { source: any; query: any }\n ? K\n : never;\n}[keyof AssistantApi];\n\n/**\n * Configuration for a derived scope field - infers types from the actual values provided\n */\nexport type DerivedScopeConfig<TSource extends string | null, TQuery, TApi> = {\n source: TSource;\n query: TQuery;\n get: () => TApi;\n};\n\n/**\n * Type for the special `on` callback function\n */\nexport type OnCallbackFn = <TEvent extends AssistantEvent>(\n selector: AssistantEventSelector<TEvent>,\n callback: AssistantEventCallback<TEvent>,\n) => Unsubscribe;\n\n/**\n * Type for the special `subscribe` callback function\n */\nexport type SubscribeCallbackFn = (listener: () => void) => Unsubscribe;\n\n/**\n * Type for the special `flushSync` callback function\n */\nexport type FlushSyncCallbackFn = () => void;\n\n/**\n * Type for special non-field functions in AssistantApi\n */\nexport type SpecialCallbacks = {\n on?: OnCallbackFn;\n subscribe?: SubscribeCallbackFn;\n flushSync?: FlushSyncCallbackFn;\n};\n\n/**\n * Type for the scopes parameter - allows both DerivedScope elements and special callbacks.\n * Field names are restricted to valid AssistantApi field names.\n * TypeScript validates that the source/query/get types match the expected field type.\n */\nexport type DerivedScopesInput = {\n [K in AssistantApiFieldNames]?: ResourceElement<\n AssistantApiField<\n ExtractApiType<AssistantApi[K]>,\n {\n source: ExtractMeta<AssistantApi[K]>[\"source\"];\n query: ExtractMeta<AssistantApi[K]>[\"query\"];\n }\n >\n >;\n} & SpecialCallbacks;\n\n/**\n * DerivedScope resource - memoizes an AssistantApiField based on source and query.\n * The get callback always calls the most recent version (useEffectEvent pattern).\n * TypeScript infers TSource, TQuery, and TApi from the config object.\n * Validation happens at the DerivedScopesInput level.\n */\nexport const DerivedScope = resource(\n <TSource extends string | null, TQuery, TApi>(\n config: DerivedScopeConfig<TSource, TQuery, TApi>,\n ): AssistantApiField<\n TApi,\n {\n source: TSource;\n query: TQuery;\n }\n > => {\n const getRef = tapRef(config.get);\n tapEffect(() => {\n getRef.current = config.get;\n });\n\n return tapMemo(() => {\n return createAssistantApiField({\n source: config.source,\n query: config.query,\n get: () => getRef.current(),\n });\n }, [config.source, JSON.stringify(config.query)]);\n },\n);\n\n/**\n * Helper resource to wrap each scope field - stable resource identity for proper memoization.\n * Creating this outside the map ensures tapResources can properly track and memoize each field.\n */\nconst ScopeFieldWithNameResource = resource(\n (config: {\n fieldName: string;\n scopeElement: ReturnType<typeof DerivedScope>;\n }) => {\n const field = tapResource(config.scopeElement);\n return tapMemo(\n () => [config.fieldName, field] as const,\n [config.fieldName, field],\n );\n },\n);\n\n/**\n * DerivedScopes resource - takes an object of DerivedScope resource elements and special callbacks,\n * and returns a Partial<AssistantApi> with all the derived fields.\n */\nexport const DerivedScopes = resource(\n (scopes: DerivedScopesInput): Partial<AssistantApi> => {\n const { on, subscribe, flushSync, ...scopeFields } = scopes;\n const callbacksRef = tapRef({ on, subscribe, flushSync });\n tapEffect(() => {\n callbacksRef.current = { on, subscribe, flushSync };\n });\n\n const results = tapResources(\n Object.entries(scopeFields).map(([fieldName, scopeElement]) =>\n ScopeFieldWithNameResource(\n {\n fieldName,\n scopeElement: scopeElement as ReturnType<typeof DerivedScope>,\n },\n { key: fieldName },\n ),\n ),\n );\n\n return tapMemo(() => {\n const result = Object.fromEntries(results) as Partial<AssistantApi>;\n\n const {\n on: onCb,\n subscribe: subCb,\n flushSync: flushCb,\n } = callbacksRef.current;\n\n if (onCb) {\n result.on = <TEvent extends AssistantEvent>(\n selector: AssistantEventSelector<TEvent>,\n callback: AssistantEventCallback<TEvent>,\n ) => onCb(selector, callback);\n }\n if (subCb) result.subscribe = (listener) => subCb(listener);\n if (flushCb) result.flushSync = () => flushCb();\n\n return result;\n }, [...results]);\n },\n);\n"],"mappings":";AAAA,SAAS,UAAU,iBAAiB;AACpC,SAAS,SAAS,QAAQ,aAAa,oBAAoB;AAC3D,SAAS,+BAA+B;AAgGjC,IAAM,eAAe;AAAA,EAC1B,CACE,WAOG;AACH,UAAM,SAAS,OAAO,OAAO,GAAG;AAChC,cAAU,MAAM;AACd,aAAO,UAAU,OAAO;AAAA,IAC1B,CAAC;AAED,WAAO,QAAQ,MAAM;AACnB,aAAO,wBAAwB;AAAA,QAC7B,QAAQ,OAAO;AAAA,QACf,OAAO,OAAO;AAAA,QACd,KAAK,MAAM,OAAO,QAAQ;AAAA,MAC5B,CAAC;AAAA,IACH,GAAG,CAAC,OAAO,QAAQ,KAAK,UAAU,OAAO,KAAK,CAAC,CAAC;AAAA,EAClD;AACF;AAMA,IAAM,6BAA6B;AAAA,EACjC,CAAC,WAGK;AACJ,UAAM,QAAQ,YAAY,OAAO,YAAY;AAC7C,WAAO;AAAA,MACL,MAAM,CAAC,OAAO,WAAW,KAAK;AAAA,MAC9B,CAAC,OAAO,WAAW,KAAK;AAAA,IAC1B;AAAA,EACF;AACF;AAMO,IAAM,gBAAgB;AAAA,EAC3B,CAAC,WAAsD;AACrD,UAAM,EAAE,IAAI,WAAW,WAAW,GAAG,YAAY,IAAI;AACrD,UAAM,eAAe,OAAO,EAAE,IAAI,WAAW,UAAU,CAAC;AACxD,cAAU,MAAM;AACd,mBAAa,UAAU,EAAE,IAAI,WAAW,UAAU;AAAA,IACpD,CAAC;AAED,UAAM,UAAU;AAAA,MACd,OAAO,QAAQ,WAAW,EAAE;AAAA,QAAI,CAAC,CAAC,WAAW,YAAY,MACvD;AAAA,UACE;AAAA,YACE;AAAA,YACA;AAAA,UACF;AAAA,UACA,EAAE,KAAK,UAAU;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,QAAQ,MAAM;AACnB,YAAM,SAAS,OAAO,YAAY,OAAO;AAEzC,YAAM;AAAA,QACJ,IAAI;AAAA,QACJ,WAAW;AAAA,QACX,WAAW;AAAA,MACb,IAAI,aAAa;AAEjB,UAAI,MAAM;AACR,eAAO,KAAK,CACV,UACA,aACG,KAAK,UAAU,QAAQ;AAAA,MAC9B;AACA,UAAI,MAAO,QAAO,YAAY,CAAC,aAAa,MAAM,QAAQ;AAC1D,UAAI,QAAS,QAAO,YAAY,MAAM,QAAQ;AAE9C,aAAO;AAAA,IACT,GAAG,CAAC,GAAG,OAAO,CAAC;AAAA,EACjB;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/utils/tap-store/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,eAAe,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/utils/tap-store/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,eAAe,EAGhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,KAAK,CAAC,MAAM;IAC3B;;OAEG;IACH,QAAQ,IAAI,MAAM,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,WAAW,CAAC;IAE7C;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,eAAO,MAAM,OAAO,GACjB,MAAM,EAAE,MAAM;;iFAYhB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/tap-store/store.ts"],"sourcesContent":["import {\n tapMemo,\n tapEffect,\n ResourceElement,\n resource,\n createResource,\n
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/tap-store/store.ts"],"sourcesContent":["import {\n tapMemo,\n tapEffect,\n ResourceElement,\n resource,\n createResource,\n} from \"@assistant-ui/tap\";\nimport { Unsubscribe } from \"../../types\";\n\nexport interface Store<TState> {\n /**\n * Get the current state of the store.\n */\n getState(): TState;\n\n /**\n * Subscribe to the store.\n */\n subscribe(listener: () => void): Unsubscribe;\n\n /**\n * Synchronously flush all the updates to the store.\n */\n flushSync(): void;\n}\n\nexport const asStore = resource(\n <TState, TProps>(element: ResourceElement<TState, TProps>): Store<TState> => {\n const resource = tapMemo(\n () => createResource(element, true),\n [element.type],\n );\n\n tapEffect(() => {\n resource.updateInput(element.props);\n });\n\n return resource;\n },\n);\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,OACK;AAoBA,IAAM,UAAU;AAAA,EACrB,CAAiB,YAA4D;AAC3E,UAAMA,YAAW;AAAA,MACf,MAAM,eAAe,SAAS,IAAI;AAAA,MAClC,CAAC,QAAQ,IAAI;AAAA,IACf;AAEA,cAAU,MAAM;AACd,MAAAA,UAAS,YAAY,QAAQ,KAAK;AAAA,IACpC,CAAC;AAED,WAAOA;AAAA,EACT;AACF;","names":["resource"]}
|
package/package.json
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"conversational-ui",
|
|
29
29
|
"conversational-ai"
|
|
30
30
|
],
|
|
31
|
-
"version": "0.11.
|
|
31
|
+
"version": "0.11.43",
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"type": "module",
|
|
34
34
|
"exports": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"sideEffects": false,
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"assistant-cloud": "^0.1.8",
|
|
52
|
-
"@assistant-ui/tap": "^0.
|
|
52
|
+
"@assistant-ui/tap": "^0.3.0",
|
|
53
53
|
"@radix-ui/primitive": "^1.1.3",
|
|
54
54
|
"@radix-ui/react-compose-refs": "^1.1.2",
|
|
55
55
|
"@radix-ui/react-context": "^1.1.3",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"homepage": "https://www.assistant-ui.com/",
|
|
99
99
|
"repository": {
|
|
100
100
|
"type": "git",
|
|
101
|
-
"url": "https://github.com/assistant-ui/assistant-ui
|
|
101
|
+
"url": "https://github.com/assistant-ui/assistant-ui"
|
|
102
102
|
},
|
|
103
103
|
"bugs": {
|
|
104
104
|
"url": "https://github.com/assistant-ui/assistant-ui/issues"
|