@mastra/playground-ui 27.0.0-alpha.5 → 27.0.0-alpha.6

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @mastra/playground-ui
2
2
 
3
+ ## 27.0.0-alpha.6
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed Studio streaming render behavior for interleaved reasoning and improved chat autoscroll during rapid output. ([#16331](https://github.com/mastra-ai/mastra/pull/16331))
8
+
9
+ - Updated dependencies [[`b560d6f`](https://github.com/mastra-ai/mastra/commit/b560d6f88b9b904b15c10f75c949eb145bc27684), [`f176145`](https://github.com/mastra-ai/mastra/commit/f1761458eaa602f59c5499bd0855ae7a5fd9baf3), [`d416efd`](https://github.com/mastra-ai/mastra/commit/d416efdee26c1755328e21cc62584f8566e21432), [`36b3bbf`](https://github.com/mastra-ai/mastra/commit/36b3bbf5a8d59f7e23d47e29340e76c681b4929c), [`b275631`](https://github.com/mastra-ai/mastra/commit/b275631dc10541a482b2e2d4a3e3cfa843bd5fa1)]:
10
+ - @mastra/core@1.33.0-alpha.6
11
+ - @mastra/react@0.2.36-alpha.6
12
+ - @mastra/client-js@1.18.0-alpha.6
13
+
3
14
  ## 27.0.0-alpha.5
4
15
 
5
16
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -8230,18 +8230,30 @@ function PickMultiMenuItem({ field, tokens, onChange, open, onToggle, onClose })
8230
8230
  );
8231
8231
  }
8232
8232
 
8233
+ const SCROLL_END_THRESHOLD = 8;
8233
8234
  const useAutoscroll = (ref, { enabled = true }) => {
8234
8235
  const shouldScrollRef = React.useRef(enabled);
8236
+ const scrollFrameRef = React.useRef(null);
8237
+ const userScrollIntentRef = React.useRef(false);
8238
+ const userScrollIntentTimeoutRef = React.useRef(null);
8235
8239
  React.useEffect(() => {
8236
8240
  if (!enabled) return;
8237
8241
  if (!ref?.current) return;
8238
8242
  const area = ref.current;
8239
- const observer = new MutationObserver(() => {
8240
- if (shouldScrollRef.current) {
8241
- area.scrollTo({ top: area.scrollHeight, behavior: "smooth" });
8243
+ const scrollToEnd = () => {
8244
+ if (!shouldScrollRef.current) return;
8245
+ if (scrollFrameRef.current !== null) {
8246
+ cancelAnimationFrame(scrollFrameRef.current);
8242
8247
  }
8243
- });
8244
- observer.observe(area, {
8248
+ scrollFrameRef.current = requestAnimationFrame(() => {
8249
+ if (shouldScrollRef.current) {
8250
+ area.scrollTop = area.scrollHeight;
8251
+ }
8252
+ scrollFrameRef.current = null;
8253
+ });
8254
+ };
8255
+ const mutationObserver = new MutationObserver(scrollToEnd);
8256
+ mutationObserver.observe(area, {
8245
8257
  childList: true,
8246
8258
  // observe direct children changes
8247
8259
  subtree: true,
@@ -8249,21 +8261,73 @@ const useAutoscroll = (ref, { enabled = true }) => {
8249
8261
  characterData: true
8250
8262
  // observe text content changes
8251
8263
  });
8264
+ const resizeObserver = new ResizeObserver(scrollToEnd);
8265
+ resizeObserver.observe(area);
8266
+ const cancelPendingScroll = () => {
8267
+ if (scrollFrameRef.current !== null) {
8268
+ cancelAnimationFrame(scrollFrameRef.current);
8269
+ scrollFrameRef.current = null;
8270
+ }
8271
+ };
8272
+ const stopFollowing = () => {
8273
+ shouldScrollRef.current = false;
8274
+ cancelPendingScroll();
8275
+ };
8276
+ const registerUserScrollIntent = () => {
8277
+ userScrollIntentRef.current = true;
8278
+ if (userScrollIntentTimeoutRef.current !== null) {
8279
+ window.clearTimeout(userScrollIntentTimeoutRef.current);
8280
+ }
8281
+ userScrollIntentTimeoutRef.current = window.setTimeout(() => {
8282
+ userScrollIntentRef.current = false;
8283
+ userScrollIntentTimeoutRef.current = null;
8284
+ }, 250);
8285
+ };
8286
+ const handleWheel = (event) => {
8287
+ registerUserScrollIntent();
8288
+ if (event.deltaY < 0) {
8289
+ stopFollowing();
8290
+ }
8291
+ };
8292
+ const handleKeyDown = (event) => {
8293
+ registerUserScrollIntent();
8294
+ if (["ArrowUp", "PageUp", "Home"].includes(event.key)) {
8295
+ stopFollowing();
8296
+ }
8297
+ };
8252
8298
  const handleScroll = (e) => {
8253
8299
  const scrollElement = e.target;
8254
8300
  const currentPosition = scrollElement.scrollTop + scrollElement.clientHeight;
8255
8301
  const totalHeight = scrollElement.scrollHeight;
8256
- const isAtEnd = currentPosition >= totalHeight - 1;
8302
+ const isAtEnd = currentPosition >= totalHeight - SCROLL_END_THRESHOLD;
8257
8303
  if (isAtEnd) {
8258
8304
  shouldScrollRef.current = true;
8259
- } else {
8305
+ return;
8306
+ }
8307
+ if (userScrollIntentRef.current) {
8260
8308
  shouldScrollRef.current = false;
8309
+ cancelPendingScroll();
8261
8310
  }
8262
8311
  };
8312
+ area.addEventListener("wheel", handleWheel, { passive: true });
8313
+ area.addEventListener("touchmove", registerUserScrollIntent, { passive: true });
8314
+ area.addEventListener("pointerdown", registerUserScrollIntent);
8315
+ area.addEventListener("keydown", handleKeyDown);
8263
8316
  area.addEventListener("scroll", handleScroll);
8317
+ scrollToEnd();
8264
8318
  return () => {
8319
+ area.removeEventListener("wheel", handleWheel);
8320
+ area.removeEventListener("touchmove", registerUserScrollIntent);
8321
+ area.removeEventListener("pointerdown", registerUserScrollIntent);
8322
+ area.removeEventListener("keydown", handleKeyDown);
8265
8323
  area.removeEventListener("scroll", handleScroll);
8266
- observer.disconnect();
8324
+ mutationObserver.disconnect();
8325
+ resizeObserver.disconnect();
8326
+ cancelPendingScroll();
8327
+ if (userScrollIntentTimeoutRef.current !== null) {
8328
+ window.clearTimeout(userScrollIntentTimeoutRef.current);
8329
+ userScrollIntentTimeoutRef.current = null;
8330
+ }
8267
8331
  };
8268
8332
  }, [enabled, ref]);
8269
8333
  };