@assistant-ui/react 0.12.28 → 0.14.0

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.
Files changed (124) hide show
  1. package/dist/client/ExternalThread.d.ts.map +1 -1
  2. package/dist/client/ExternalThread.js +0 -2
  3. package/dist/client/ExternalThread.js.map +1 -1
  4. package/dist/client/InMemoryThreadList.d.ts.map +1 -1
  5. package/dist/client/InMemoryThreadList.js +3 -0
  6. package/dist/client/InMemoryThreadList.js.map +1 -1
  7. package/dist/client/SingleThreadList.d.ts.map +1 -1
  8. package/dist/client/SingleThreadList.js +3 -0
  9. package/dist/client/SingleThreadList.js.map +1 -1
  10. package/dist/context/providers/ThreadViewportProvider.d.ts.map +1 -1
  11. package/dist/context/providers/ThreadViewportProvider.js +2 -10
  12. package/dist/context/providers/ThreadViewportProvider.js.map +1 -1
  13. package/dist/context/stores/ThreadViewport.d.ts +46 -4
  14. package/dist/context/stores/ThreadViewport.d.ts.map +1 -1
  15. package/dist/context/stores/ThreadViewport.js +51 -7
  16. package/dist/context/stores/ThreadViewport.js.map +1 -1
  17. package/dist/index.d.ts +1 -29
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -28
  20. package/dist/index.js.map +1 -1
  21. package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.d.ts +1 -1
  22. package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.d.ts.map +1 -1
  23. package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.js +1 -1
  24. package/dist/legacy-runtime/runtime-cores/assistant-transport/utils.js.map +1 -1
  25. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  26. package/dist/primitives/composer/ComposerInput.js +9 -4
  27. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  28. package/dist/primitives/message/MessageRoot.d.ts +6 -30
  29. package/dist/primitives/message/MessageRoot.d.ts.map +1 -1
  30. package/dist/primitives/message/MessageRoot.js +68 -25
  31. package/dist/primitives/message/MessageRoot.js.map +1 -1
  32. package/dist/primitives/thread/ThreadViewport.d.ts +38 -0
  33. package/dist/primitives/thread/ThreadViewport.d.ts.map +1 -1
  34. package/dist/primitives/thread/ThreadViewport.js +53 -5
  35. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  36. package/dist/primitives/thread/ThreadViewportFooter.d.ts +2 -1
  37. package/dist/primitives/thread/ThreadViewportFooter.d.ts.map +1 -1
  38. package/dist/primitives/thread/ThreadViewportFooter.js +2 -1
  39. package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
  40. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.d.ts +22 -0
  41. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.d.ts.map +1 -0
  42. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.js +53 -0
  43. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.js.map +1 -0
  44. package/dist/primitives/thread/topAnchor/createReserveObservers.d.ts +5 -0
  45. package/dist/primitives/thread/topAnchor/createReserveObservers.d.ts.map +1 -0
  46. package/dist/primitives/thread/topAnchor/createReserveObservers.js +38 -0
  47. package/dist/primitives/thread/topAnchor/createReserveObservers.js.map +1 -0
  48. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.d.ts +22 -0
  49. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.d.ts.map +1 -0
  50. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.js +75 -0
  51. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.js.map +1 -0
  52. package/dist/primitives/thread/topAnchor/topAnchorTurn.d.ts +15 -0
  53. package/dist/primitives/thread/topAnchor/topAnchorTurn.d.ts.map +1 -0
  54. package/dist/primitives/thread/topAnchor/topAnchorTurn.js +13 -0
  55. package/dist/primitives/thread/topAnchor/topAnchorTurn.js.map +1 -0
  56. package/dist/primitives/thread/topAnchor/topAnchorUtils.d.ts +15 -0
  57. package/dist/primitives/thread/topAnchor/topAnchorUtils.d.ts.map +1 -0
  58. package/dist/primitives/thread/topAnchor/topAnchorUtils.js +51 -0
  59. package/dist/primitives/thread/topAnchor/topAnchorUtils.js.map +1 -0
  60. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.d.ts +7 -0
  61. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.d.ts.map +1 -0
  62. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js +18 -0
  63. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js.map +1 -0
  64. package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
  65. package/dist/primitives/thread/useThreadViewportAutoScroll.js +13 -1
  66. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  67. package/dist/primitives/thread.d.ts +0 -1
  68. package/dist/primitives/thread.d.ts.map +1 -1
  69. package/dist/primitives/thread.js +0 -1
  70. package/dist/primitives/thread.js.map +1 -1
  71. package/dist/primitives/threadList/ThreadListLoadMore.d.ts +13 -0
  72. package/dist/primitives/threadList/ThreadListLoadMore.d.ts.map +1 -0
  73. package/dist/primitives/threadList/ThreadListLoadMore.js +11 -0
  74. package/dist/primitives/threadList/ThreadListLoadMore.js.map +1 -0
  75. package/dist/primitives/threadList.d.ts +1 -0
  76. package/dist/primitives/threadList.d.ts.map +1 -1
  77. package/dist/primitives/threadList.js +1 -0
  78. package/dist/primitives/threadList.js.map +1 -1
  79. package/dist/utils/hooks/useManagedRef.d.ts.map +1 -1
  80. package/dist/utils/hooks/useManagedRef.js +1 -0
  81. package/dist/utils/hooks/useManagedRef.js.map +1 -1
  82. package/dist/utils/hooks/useOnResizeContent.d.ts.map +1 -1
  83. package/dist/utils/hooks/useOnResizeContent.js +1 -2
  84. package/dist/utils/hooks/useOnResizeContent.js.map +1 -1
  85. package/package.json +10 -10
  86. package/src/client/ExternalThread.ts +0 -2
  87. package/src/client/InMemoryThreadList.ts +3 -0
  88. package/src/client/SingleThreadList.ts +3 -0
  89. package/src/context/providers/ThreadViewportProvider.tsx +2 -12
  90. package/src/context/stores/ThreadViewport.ts +111 -11
  91. package/src/index.ts +0 -35
  92. package/src/legacy-runtime/runtime-cores/assistant-transport/utils.ts +1 -5
  93. package/src/primitives/composer/ComposerInput.test.tsx +232 -0
  94. package/src/primitives/composer/ComposerInput.tsx +9 -4
  95. package/src/primitives/message/MessageRoot.tsx +135 -57
  96. package/src/primitives/thread/ThreadViewport.tsx +95 -4
  97. package/src/primitives/thread/ThreadViewportFooter.tsx +2 -1
  98. package/src/primitives/thread/topAnchor/computeTopAnchorSlack.test.ts +131 -0
  99. package/src/primitives/thread/topAnchor/computeTopAnchorSlack.ts +94 -0
  100. package/src/primitives/thread/topAnchor/createReserveObservers.ts +50 -0
  101. package/src/primitives/thread/topAnchor/mountTopAnchorReserve.test.ts +131 -0
  102. package/src/primitives/thread/topAnchor/mountTopAnchorReserve.ts +127 -0
  103. package/src/primitives/thread/topAnchor/topAnchorTurn.test.ts +46 -0
  104. package/src/primitives/thread/topAnchor/topAnchorTurn.ts +30 -0
  105. package/src/primitives/thread/topAnchor/topAnchorUtils.ts +58 -0
  106. package/src/primitives/thread/topAnchor/useTopAnchorReserve.ts +19 -0
  107. package/src/primitives/thread/useThreadViewportAutoScroll.ts +15 -1
  108. package/src/primitives/thread.ts +0 -1
  109. package/src/primitives/threadList/ThreadListLoadMore.tsx +24 -0
  110. package/src/primitives/threadList.ts +1 -0
  111. package/src/tests/RemoteThreadListRuntime.adapterProvider.test.tsx +138 -0
  112. package/src/tests/RemoteThreadListRuntime.deferredProvider.test.tsx +28 -17
  113. package/src/utils/hooks/useManagedRef.ts +1 -0
  114. package/src/utils/hooks/useOnResizeContent.ts +1 -2
  115. package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.d.ts +0 -3
  116. package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.d.ts.map +0 -1
  117. package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.js +0 -3
  118. package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.js.map +0 -1
  119. package/dist/primitives/thread/ThreadViewportSlack.d.ts +0 -20
  120. package/dist/primitives/thread/ThreadViewportSlack.d.ts.map +0 -1
  121. package/dist/primitives/thread/ThreadViewportSlack.js +0 -80
  122. package/dist/primitives/thread/ThreadViewportSlack.js.map +0 -1
  123. package/src/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.ts +0 -6
  124. package/src/primitives/thread/ThreadViewportSlack.tsx +0 -116
@@ -1,8 +1,8 @@
1
1
  // @vitest-environment jsdom
2
2
 
3
- import { render } from "@testing-library/react";
3
+ import { act, render } from "@testing-library/react";
4
4
  import { type FC, type PropsWithChildren, useState } from "react";
5
- import { describe, expect, it } from "vitest";
5
+ import { afterEach, describe, expect, it, vi } from "vitest";
6
6
  import { useRemoteThreadListRuntime } from "@assistant-ui/core/react";
7
7
  import { makeAdapter } from "./remote-thread-list-test-helpers";
8
8
  import type { AssistantRuntime } from "@assistant-ui/core";
@@ -39,14 +39,13 @@ const RuntimeCapture: FC<{
39
39
  return null;
40
40
  };
41
41
 
42
- // regression for #3678: deferred unstable_Provider must not strand the runtime binder.
43
- describe("useRemoteThreadListRuntime with a deferred unstable_Provider", () => {
44
- it("composer.setText does not throw EMPTY_THREAD_ERROR when unstable_Provider defers children", () => {
45
- const Provider: FC<PropsWithChildren> = ({ children }) => {
46
- const [ready] = useState(false);
47
- if (!ready) return null;
48
- return <>{children}</>;
49
- };
42
+ afterEach(() => {
43
+ vi.useRealTimers();
44
+ });
45
+
46
+ describe("useRemoteThreadListRuntime with unstable_Provider", () => {
47
+ it("composer.setText works when unstable_Provider renders children unconditionally", () => {
48
+ const Provider: FC<PropsWithChildren> = ({ children }) => <>{children}</>;
50
49
  const adapter = makeAdapter({ unstable_Provider: Provider });
51
50
 
52
51
  const runtimeRef: { current: AssistantRuntime | null } = { current: null };
@@ -61,19 +60,31 @@ describe("useRemoteThreadListRuntime with a deferred unstable_Provider", () => {
61
60
  expect(() => runtime!.thread.composer.setText("hello")).not.toThrow();
62
61
  });
63
62
 
64
- it("composer.setText still works when unstable_Provider renders children unconditionally", () => {
65
- const Provider: FC<PropsWithChildren> = ({ children }) => <>{children}</>;
63
+ it("warns in dev when unstable_Provider defers children", () => {
64
+ vi.useFakeTimers();
65
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
66
+
67
+ const Provider: FC<PropsWithChildren> = ({ children }) => {
68
+ const [ready] = useState(false);
69
+ if (!ready) return null;
70
+ return <>{children}</>;
71
+ };
66
72
  const adapter = makeAdapter({ unstable_Provider: Provider });
67
73
 
68
- const runtimeRef: { current: AssistantRuntime | null } = { current: null };
69
74
  render(
70
75
  <RuntimeProvider adapter={adapter}>
71
- <RuntimeCapture runtimeRef={runtimeRef} />
76
+ <div />
72
77
  </RuntimeProvider>,
73
78
  );
74
79
 
75
- const runtime = runtimeRef.current;
76
- expect(runtime).toBeTruthy();
77
- expect(() => runtime!.thread.composer.setText("hello")).not.toThrow();
80
+ act(() => {
81
+ vi.advanceTimersByTime(150);
82
+ });
83
+
84
+ expect(warn).toHaveBeenCalledWith(
85
+ expect.stringContaining("did not render its `children` synchronously"),
86
+ );
87
+
88
+ warn.mockRestore();
78
89
  });
79
90
  });
@@ -10,6 +10,7 @@ export const useManagedRef = <TNode>(
10
10
  // Call the previous cleanup function
11
11
  if (cleanupRef.current) {
12
12
  cleanupRef.current();
13
+ cleanupRef.current = undefined;
13
14
  }
14
15
 
15
16
  // Call the new callback and store its cleanup function
@@ -13,8 +13,7 @@ export const useOnResizeContent = (callback: () => void) => {
13
13
 
14
14
  const mutationObserver = new MutationObserver((mutations) => {
15
15
  // Filter out style-only attribute mutations to prevent feedback loops
16
- // with components like ThreadViewportSlack that write styles in response
17
- // to viewport changes
16
+ // with code paths that write styles in response to viewport changes.
18
17
  const hasRelevantMutation = mutations.some(
19
18
  (m) => m.type !== "attributes" || m.attributeName !== "style",
20
19
  );
@@ -1,3 +0,0 @@
1
- export { getExternalStoreMessage, getExternalStoreMessages, bindExternalStoreMessage, } from "@assistant-ui/core";
2
- export { symbolInnerMessage } from "@assistant-ui/core/internal";
3
- //# sourceMappingURL=getExternalStoreMessage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getExternalStoreMessage.d.ts","sourceRoot":"","sources":["../../../../src/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -1,3 +0,0 @@
1
- export { getExternalStoreMessage, getExternalStoreMessages, bindExternalStoreMessage, } from "@assistant-ui/core";
2
- export { symbolInnerMessage } from "@assistant-ui/core/internal";
3
- //# sourceMappingURL=getExternalStoreMessage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getExternalStoreMessage.js","sourceRoot":"","sources":["../../../../src/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -1,20 +0,0 @@
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 | undefined;
5
- /** Offset used when clamping large user messages */
6
- fillClampOffset?: string | undefined;
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
@@ -1 +0,0 @@
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,GAAG,SAAS,CAAC;IACxC,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,EAAE,EAAE,CAAC,wBAAwB,CA2DrE,CAAC"}
@@ -1,80 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- import { Slot } from "radix-ui";
4
- import { createContext, useCallback, useContext, } from "react";
5
- import { useThreadViewportStore } from "../../context/react/ThreadViewportContext.js";
6
- import { useAuiState } from "@assistant-ui/store";
7
- import { useManagedRef } from "../../utils/hooks/useManagedRef.js";
8
- const SlackNestingContext = createContext(false);
9
- const parseCssLength = (value, element) => {
10
- const match = value.match(/^([\d.]+)(em|px|rem)$/);
11
- if (!match)
12
- return 0;
13
- const num = parseFloat(match[1]);
14
- const unit = match[2];
15
- if (unit === "px")
16
- return num;
17
- if (unit === "em") {
18
- const fontSize = parseFloat(getComputedStyle(element).fontSize) || 16;
19
- return num * fontSize;
20
- }
21
- if (unit === "rem") {
22
- const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
23
- return num * rootFontSize;
24
- }
25
- return 0;
26
- };
27
- /**
28
- * A slot component that provides minimum height to enable scroll anchoring.
29
- *
30
- * When using `turnAnchor="top"`, this component ensures there is
31
- * enough scroll room below the anchor point (last user message) for it to scroll
32
- * to the top of the viewport. The min-height is applied only to the last
33
- * assistant message.
34
- *
35
- * This component is used internally by MessagePrimitive.Root.
36
- */
37
- export const ThreadPrimitiveViewportSlack = ({ children, fillClampThreshold = "10em", fillClampOffset = "6em", }) => {
38
- const shouldApplySlack = useAuiState(
39
- // only add slack to the last assistant message following a user message (valid turn)
40
- (s) => s.message.isLast &&
41
- s.message.role === "assistant" &&
42
- s.message.index >= 1 &&
43
- s.thread.messages.at(s.message.index - 1)?.role === "user");
44
- const threadViewportStore = useThreadViewportStore({ optional: true });
45
- const isNested = useContext(SlackNestingContext);
46
- const callback = useCallback((el) => {
47
- if (!threadViewportStore || isNested)
48
- return;
49
- const updateMinHeight = () => {
50
- const state = threadViewportStore.getState();
51
- if (state.turnAnchor === "top" && shouldApplySlack) {
52
- const { viewport, inset, userMessage } = state.height;
53
- const threshold = parseCssLength(fillClampThreshold, el);
54
- const offset = parseCssLength(fillClampOffset, el);
55
- const clampAdjustment = userMessage <= threshold ? userMessage : offset;
56
- const minHeight = Math.max(0, viewport - inset - clampAdjustment);
57
- el.style.minHeight = `${minHeight}px`;
58
- el.style.flexShrink = "0";
59
- el.style.transition = "min-height 0s";
60
- }
61
- else {
62
- el.style.minHeight = "";
63
- el.style.flexShrink = "";
64
- el.style.transition = "";
65
- }
66
- };
67
- updateMinHeight();
68
- return threadViewportStore.subscribe(updateMinHeight);
69
- }, [
70
- threadViewportStore,
71
- shouldApplySlack,
72
- isNested,
73
- fillClampThreshold,
74
- fillClampOffset,
75
- ]);
76
- const ref = useManagedRef(callback);
77
- return (_jsx(SlackNestingContext.Provider, { value: true, children: _jsx(Slot.Root, { ref: ref, children: children }) }));
78
- };
79
- ThreadPrimitiveViewportSlack.displayName = "ThreadPrimitive.ViewportSlack";
80
- //# sourceMappingURL=ThreadViewportSlack.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ThreadViewportSlack.js","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewportSlack.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +0,0 @@
1
- export {
2
- getExternalStoreMessage,
3
- getExternalStoreMessages,
4
- bindExternalStoreMessage,
5
- } from "@assistant-ui/core";
6
- export { symbolInnerMessage } from "@assistant-ui/core/internal";
@@ -1,116 +0,0 @@
1
- "use client";
2
-
3
- import { Slot } from "radix-ui";
4
- import {
5
- createContext,
6
- type FC,
7
- type ReactNode,
8
- useCallback,
9
- useContext,
10
- } from "react";
11
- import { useThreadViewportStore } from "../../context/react/ThreadViewportContext";
12
- import { useAuiState } from "@assistant-ui/store";
13
- import { useManagedRef } from "../../utils/hooks/useManagedRef";
14
-
15
- const SlackNestingContext = createContext(false);
16
-
17
- const parseCssLength = (value: string, element: HTMLElement): number => {
18
- const match = value.match(/^([\d.]+)(em|px|rem)$/);
19
- if (!match) return 0;
20
-
21
- const num = parseFloat(match[1]!);
22
- const unit = match[2];
23
-
24
- if (unit === "px") return num;
25
- if (unit === "em") {
26
- const fontSize = parseFloat(getComputedStyle(element).fontSize) || 16;
27
- return num * fontSize;
28
- }
29
- if (unit === "rem") {
30
- const rootFontSize =
31
- parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
32
- return num * rootFontSize;
33
- }
34
- return 0;
35
- };
36
-
37
- export type ThreadViewportSlackProps = {
38
- /** Threshold at which the user message height clamps to the offset */
39
- fillClampThreshold?: string | undefined;
40
- /** Offset used when clamping large user messages */
41
- fillClampOffset?: string | undefined;
42
- children: ReactNode;
43
- };
44
-
45
- /**
46
- * A slot component that provides minimum height to enable scroll anchoring.
47
- *
48
- * When using `turnAnchor="top"`, this component ensures there is
49
- * enough scroll room below the anchor point (last user message) for it to scroll
50
- * to the top of the viewport. The min-height is applied only to the last
51
- * assistant message.
52
- *
53
- * This component is used internally by MessagePrimitive.Root.
54
- */
55
- export const ThreadPrimitiveViewportSlack: FC<ThreadViewportSlackProps> = ({
56
- children,
57
- fillClampThreshold = "10em",
58
- fillClampOffset = "6em",
59
- }) => {
60
- const shouldApplySlack = useAuiState(
61
- // only add slack to the last assistant message following a user message (valid turn)
62
- (s) =>
63
- s.message.isLast &&
64
- s.message.role === "assistant" &&
65
- s.message.index >= 1 &&
66
- s.thread.messages.at(s.message.index - 1)?.role === "user",
67
- );
68
- const threadViewportStore = useThreadViewportStore({ optional: true });
69
- const isNested = useContext(SlackNestingContext);
70
-
71
- const callback = useCallback(
72
- (el: HTMLElement) => {
73
- if (!threadViewportStore || isNested) return;
74
-
75
- const updateMinHeight = () => {
76
- const state = threadViewportStore.getState();
77
- if (state.turnAnchor === "top" && shouldApplySlack) {
78
- const { viewport, inset, userMessage } = state.height;
79
- const threshold = parseCssLength(fillClampThreshold, el);
80
- const offset = parseCssLength(fillClampOffset, el);
81
- const clampAdjustment =
82
- userMessage <= threshold ? userMessage : offset;
83
-
84
- const minHeight = Math.max(0, viewport - inset - clampAdjustment);
85
- el.style.minHeight = `${minHeight}px`;
86
- el.style.flexShrink = "0";
87
- el.style.transition = "min-height 0s";
88
- } else {
89
- el.style.minHeight = "";
90
- el.style.flexShrink = "";
91
- el.style.transition = "";
92
- }
93
- };
94
-
95
- updateMinHeight();
96
- return threadViewportStore.subscribe(updateMinHeight);
97
- },
98
- [
99
- threadViewportStore,
100
- shouldApplySlack,
101
- isNested,
102
- fillClampThreshold,
103
- fillClampOffset,
104
- ],
105
- );
106
-
107
- const ref = useManagedRef<HTMLElement>(callback);
108
-
109
- return (
110
- <SlackNestingContext.Provider value={true}>
111
- <Slot.Root ref={ref}>{children}</Slot.Root>
112
- </SlackNestingContext.Provider>
113
- );
114
- };
115
-
116
- ThreadPrimitiveViewportSlack.displayName = "ThreadPrimitive.ViewportSlack";