@assistant-ui/react 0.3.1 → 0.3.2

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/index.mjs CHANGED
@@ -668,7 +668,7 @@ var useContentPartDisplay = () => {
668
668
  throw new Error(
669
669
  "This component can only be used inside ui content parts."
670
670
  );
671
- return c.part.display;
671
+ return c;
672
672
  });
673
673
  return display;
674
674
  };
@@ -681,7 +681,7 @@ var useContentPartImage = () => {
681
681
  throw new Error(
682
682
  "ContentPartImage can only be used inside image content parts."
683
683
  );
684
- return c.part.image;
684
+ return c;
685
685
  });
686
686
  return image;
687
687
  };
@@ -1163,13 +1163,86 @@ var ContentPartProvider = ({
1163
1163
  // src/primitives/contentPart/ContentPartText.tsx
1164
1164
  import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
1165
1165
  import { forwardRef as forwardRef7 } from "react";
1166
+
1167
+ // src/utils/hooks/useSmooth.tsx
1168
+ import { useEffect as useEffect8, useState as useState5 } from "react";
1169
+ var TextStreamAnimator = class {
1170
+ constructor(setText) {
1171
+ this.setText = setText;
1172
+ }
1173
+ animationFrameId = null;
1174
+ lastUpdateTime = Date.now();
1175
+ decayFactor = 0.99;
1176
+ targetText = "";
1177
+ start() {
1178
+ if (this.animationFrameId !== null) return;
1179
+ this.animate();
1180
+ }
1181
+ stop() {
1182
+ if (this.animationFrameId !== null) {
1183
+ cancelAnimationFrame(this.animationFrameId);
1184
+ this.animationFrameId = null;
1185
+ }
1186
+ }
1187
+ animate = () => {
1188
+ const currentTime = Date.now();
1189
+ const deltaTime = currentTime - this.lastUpdateTime;
1190
+ this.lastUpdateTime = currentTime;
1191
+ this.setText((currentText) => {
1192
+ const targetText = this.targetText;
1193
+ if (currentText === targetText) {
1194
+ this.animationFrameId = null;
1195
+ return currentText;
1196
+ }
1197
+ const remainingChars = targetText.length - currentText.length;
1198
+ const charsToAdd = Math.max(
1199
+ 1,
1200
+ Math.floor(
1201
+ remainingChars * (1 - Math.pow(this.decayFactor, deltaTime))
1202
+ )
1203
+ );
1204
+ const newText = targetText.slice(0, currentText.length + charsToAdd);
1205
+ this.animationFrameId = requestAnimationFrame(this.animate);
1206
+ return newText;
1207
+ });
1208
+ };
1209
+ };
1210
+ var useSmooth = (text, smooth = false) => {
1211
+ const [displayedText, setDisplayedText] = useState5(text);
1212
+ const [animatorRef] = useState5(
1213
+ new TextStreamAnimator(setDisplayedText)
1214
+ );
1215
+ useEffect8(() => {
1216
+ if (!smooth) {
1217
+ animatorRef.stop();
1218
+ return;
1219
+ }
1220
+ if (!text.startsWith(animatorRef.targetText)) {
1221
+ setDisplayedText(text);
1222
+ animatorRef.targetText = text;
1223
+ animatorRef.stop();
1224
+ return;
1225
+ }
1226
+ animatorRef.targetText = text;
1227
+ animatorRef.start();
1228
+ }, [animatorRef, smooth, text]);
1229
+ useEffect8(() => {
1230
+ return () => {
1231
+ animatorRef.stop();
1232
+ };
1233
+ }, [animatorRef]);
1234
+ return smooth ? displayedText : text;
1235
+ };
1236
+
1237
+ // src/primitives/contentPart/ContentPartText.tsx
1166
1238
  import { jsx as jsx14 } from "react/jsx-runtime";
1167
- var ContentPartPrimitiveText = forwardRef7((props, forwardedRef) => {
1239
+ var ContentPartPrimitiveText = forwardRef7(({ smooth, ...rest }, forwardedRef) => {
1168
1240
  const {
1169
- part: { text },
1170
- status
1241
+ status,
1242
+ part: { text }
1171
1243
  } = useContentPartText();
1172
- return /* @__PURE__ */ jsx14(Primitive4.span, { "data-status": status, ...props, ref: forwardedRef, children: text });
1244
+ const smoothText = useSmooth(text, smooth);
1245
+ return /* @__PURE__ */ jsx14(Primitive4.span, { "data-status": status, ...rest, ref: forwardedRef, children: smoothText });
1173
1246
  });
1174
1247
  ContentPartPrimitiveText.displayName = "ContentPartPrimitive.Text";
1175
1248
 
@@ -1178,14 +1251,18 @@ import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
1178
1251
  import { forwardRef as forwardRef8 } from "react";
1179
1252
  import { jsx as jsx15 } from "react/jsx-runtime";
1180
1253
  var ContentPartPrimitiveImage = forwardRef8((props, forwardedRef) => {
1181
- const image = useContentPartImage();
1254
+ const {
1255
+ part: { image }
1256
+ } = useContentPartImage();
1182
1257
  return /* @__PURE__ */ jsx15(Primitive5.img, { src: image, ...props, ref: forwardedRef });
1183
1258
  });
1184
1259
  ContentPartPrimitiveImage.displayName = "ContentPartPrimitive.Image";
1185
1260
 
1186
1261
  // src/primitives/contentPart/ContentPartDisplay.tsx
1187
1262
  var ContentPartPrimitiveDisplay = () => {
1188
- const display = useContentPartDisplay();
1263
+ const {
1264
+ part: { display }
1265
+ } = useContentPartDisplay();
1189
1266
  return display ?? null;
1190
1267
  };
1191
1268
  ContentPartPrimitiveDisplay.displayName = "ContentPartPrimitive.Display";
@@ -1331,7 +1408,7 @@ import { Slot } from "@radix-ui/react-slot";
1331
1408
  import {
1332
1409
  forwardRef as forwardRef11,
1333
1410
  useCallback as useCallback15,
1334
- useEffect as useEffect8,
1411
+ useEffect as useEffect9,
1335
1412
  useRef as useRef4
1336
1413
  } from "react";
1337
1414
  import TextareaAutosize from "react-textarea-autosize";
@@ -1375,7 +1452,7 @@ var ComposerPrimitiveInput = forwardRef11(
1375
1452
  textareaRef.current.value.length
1376
1453
  );
1377
1454
  }, [autoFocusEnabled]);
1378
- useEffect8(() => focus(), [focus]);
1455
+ useEffect9(() => focus(), [focus]);
1379
1456
  useOnComposerFocus(() => {
1380
1457
  if (type === "new") {
1381
1458
  focus();
@@ -1536,11 +1613,11 @@ var useOnResizeContent = (callback) => {
1536
1613
 
1537
1614
  // src/utils/hooks/useOnScrollToBottom.tsx
1538
1615
  import { useCallbackRef as useCallbackRef3 } from "@radix-ui/react-use-callback-ref";
1539
- import { useEffect as useEffect9 } from "react";
1616
+ import { useEffect as useEffect10 } from "react";
1540
1617
  var useOnScrollToBottom = (callback) => {
1541
1618
  const callbackRef = useCallbackRef3(callback);
1542
1619
  const { useViewport } = useThreadContext();
1543
- useEffect9(() => {
1620
+ useEffect10(() => {
1544
1621
  return useViewport.getState().onScrollToBottom(() => {
1545
1622
  callbackRef();
1546
1623
  });
@@ -1615,7 +1692,7 @@ ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
1615
1692
  import { memo as memo3 } from "react";
1616
1693
 
1617
1694
  // src/context/providers/MessageProvider.tsx
1618
- import { useEffect as useEffect10, useState as useState5 } from "react";
1695
+ import { useEffect as useEffect11, useState as useState6 } from "react";
1619
1696
  import { create as create12 } from "zustand";
1620
1697
 
1621
1698
  // src/context/stores/EditComposer.ts
@@ -1677,7 +1754,7 @@ var syncMessage = (messages, getBranches, useMessage, messageIndex) => {
1677
1754
  };
1678
1755
  var useMessageContext2 = (messageIndex) => {
1679
1756
  const { useThreadMessages, useThreadActions } = useThreadContext();
1680
- const [context] = useState5(() => {
1757
+ const [context] = useState6(() => {
1681
1758
  const useMessage = create12(() => ({}));
1682
1759
  const useMessageUtils = makeMessageUtilsStore();
1683
1760
  const useEditComposer = makeEditComposerStore({
@@ -1714,7 +1791,7 @@ var useMessageContext2 = (messageIndex) => {
1714
1791
  );
1715
1792
  return { useMessage, useMessageUtils, useEditComposer };
1716
1793
  });
1717
- useEffect10(() => {
1794
+ useEffect11(() => {
1718
1795
  return useThreadMessages.subscribe((thread) => {
1719
1796
  syncMessage(
1720
1797
  thread,
@@ -1797,7 +1874,7 @@ var ThreadPrimitiveSuggestion = createActionButton(
1797
1874
  );
1798
1875
 
1799
1876
  // src/runtime/local/useLocalRuntime.tsx
1800
- import { useInsertionEffect as useInsertionEffect3, useState as useState6 } from "react";
1877
+ import { useInsertionEffect as useInsertionEffect3, useState as useState7 } from "react";
1801
1878
 
1802
1879
  // src/runtime/utils/idUtils.tsx
1803
1880
  import { customAlphabet } from "nanoid/non-secure";
@@ -2139,7 +2216,7 @@ var LocalThreadRuntime = class {
2139
2216
 
2140
2217
  // src/runtime/local/useLocalRuntime.tsx
2141
2218
  var useLocalRuntime = (adapter) => {
2142
- const [runtime] = useState6(() => new LocalRuntime(adapter));
2219
+ const [runtime] = useState7(() => new LocalRuntime(adapter));
2143
2220
  useInsertionEffect3(() => {
2144
2221
  runtime.adapter = adapter;
2145
2222
  });
@@ -2151,7 +2228,8 @@ var internal_exports = {};
2151
2228
  __export(internal_exports, {
2152
2229
  BaseAssistantRuntime: () => BaseAssistantRuntime,
2153
2230
  MessageRepository: () => MessageRepository,
2154
- ProxyConfigProvider: () => ProxyConfigProvider
2231
+ ProxyConfigProvider: () => ProxyConfigProvider,
2232
+ useSmooth: () => useSmooth
2155
2233
  });
2156
2234
  export {
2157
2235
  actionBar_exports as ActionBarPrimitive,