@hef2024/llmasaservice-ui 0.22.0 → 0.22.1

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.js CHANGED
@@ -4334,11 +4334,22 @@ var AIChatPanel = ({
4334
4334
  thumbsDownClick(callId);
4335
4335
  }
4336
4336
  }), [thumbsDownClick, interactionClicked]);
4337
- const scrollToBottom = (0, import_react12.useCallback)(() => {
4337
+ const scrollToBottom = (0, import_react12.useCallback)((force = false) => {
4338
4338
  var _a2;
4339
4339
  if (scrollRAFRef.current) {
4340
4340
  cancelAnimationFrame(scrollRAFRef.current);
4341
4341
  }
4342
+ if (!force && responseAreaRef.current) {
4343
+ const scrollViewport = responseAreaRef.current.querySelector("[data-radix-scroll-area-viewport]");
4344
+ const scrollElement = scrollViewport || responseAreaRef.current;
4345
+ const scrollTop = scrollElement.scrollTop;
4346
+ const scrollHeight = scrollElement.scrollHeight;
4347
+ const clientHeight = scrollElement.clientHeight;
4348
+ const isNearBottom = scrollHeight - scrollTop - clientHeight < 100;
4349
+ if (!isNearBottom) {
4350
+ return;
4351
+ }
4352
+ }
4342
4353
  const now = Date.now();
4343
4354
  if (now - lastScrollTimeRef.current < 100) {
4344
4355
  scrollRAFRef.current = requestAnimationFrame(() => {
@@ -4382,7 +4393,7 @@ var AIChatPanel = ({
4382
4393
  setLastPrompt(promptToSend.trim());
4383
4394
  setLastKey(promptKey);
4384
4395
  setTimeout(() => {
4385
- scrollToBottom();
4396
+ scrollToBottom(true);
4386
4397
  }, 0);
4387
4398
  console.log("AIChatPanel.continueChat - about to call ensureConversation");
4388
4399
  ensureConversation().then((convId) => {
@@ -4562,7 +4573,7 @@ var AIChatPanel = ({
4562
4573
  (0, import_react12.useEffect)(() => {
4563
4574
  const shouldAutoScroll = scrollToEnd || !userHasScrolled;
4564
4575
  if (!idle && shouldAutoScroll && response) {
4565
- scrollToBottom();
4576
+ scrollToBottom(false);
4566
4577
  }
4567
4578
  }, [response, scrollToBottom, idle, userHasScrolled, scrollToEnd]);
4568
4579
  const idleRef = (0, import_react12.useRef)(idle);
@@ -4722,7 +4733,7 @@ var AIChatPanel = ({
4722
4733
  const AgentSuggestionCard = import_react12.default.memo(({ agentId, agentName, reason }) => {
4723
4734
  (0, import_react12.useEffect)(() => {
4724
4735
  const timer = setTimeout(() => {
4725
- scrollToBottom();
4736
+ scrollToBottom(true);
4726
4737
  }, 100);
4727
4738
  return () => clearTimeout(timer);
4728
4739
  }, []);
@@ -4769,7 +4780,7 @@ var AIChatPanel = ({
4769
4780
  onClick: () => {
4770
4781
  onAgentChange(agentId);
4771
4782
  setTimeout(() => {
4772
- scrollToBottom();
4783
+ scrollToBottom(true);
4773
4784
  }, 100);
4774
4785
  }
4775
4786
  },
package/dist/index.mjs CHANGED
@@ -4301,11 +4301,22 @@ var AIChatPanel = ({
4301
4301
  thumbsDownClick(callId);
4302
4302
  }
4303
4303
  }), [thumbsDownClick, interactionClicked]);
4304
- const scrollToBottom = useCallback2(() => {
4304
+ const scrollToBottom = useCallback2((force = false) => {
4305
4305
  var _a2;
4306
4306
  if (scrollRAFRef.current) {
4307
4307
  cancelAnimationFrame(scrollRAFRef.current);
4308
4308
  }
4309
+ if (!force && responseAreaRef.current) {
4310
+ const scrollViewport = responseAreaRef.current.querySelector("[data-radix-scroll-area-viewport]");
4311
+ const scrollElement = scrollViewport || responseAreaRef.current;
4312
+ const scrollTop = scrollElement.scrollTop;
4313
+ const scrollHeight = scrollElement.scrollHeight;
4314
+ const clientHeight = scrollElement.clientHeight;
4315
+ const isNearBottom = scrollHeight - scrollTop - clientHeight < 100;
4316
+ if (!isNearBottom) {
4317
+ return;
4318
+ }
4319
+ }
4309
4320
  const now = Date.now();
4310
4321
  if (now - lastScrollTimeRef.current < 100) {
4311
4322
  scrollRAFRef.current = requestAnimationFrame(() => {
@@ -4349,7 +4360,7 @@ var AIChatPanel = ({
4349
4360
  setLastPrompt(promptToSend.trim());
4350
4361
  setLastKey(promptKey);
4351
4362
  setTimeout(() => {
4352
- scrollToBottom();
4363
+ scrollToBottom(true);
4353
4364
  }, 0);
4354
4365
  console.log("AIChatPanel.continueChat - about to call ensureConversation");
4355
4366
  ensureConversation().then((convId) => {
@@ -4529,7 +4540,7 @@ var AIChatPanel = ({
4529
4540
  useEffect7(() => {
4530
4541
  const shouldAutoScroll = scrollToEnd || !userHasScrolled;
4531
4542
  if (!idle && shouldAutoScroll && response) {
4532
- scrollToBottom();
4543
+ scrollToBottom(false);
4533
4544
  }
4534
4545
  }, [response, scrollToBottom, idle, userHasScrolled, scrollToEnd]);
4535
4546
  const idleRef = useRef5(idle);
@@ -4689,7 +4700,7 @@ var AIChatPanel = ({
4689
4700
  const AgentSuggestionCard = React12.memo(({ agentId, agentName, reason }) => {
4690
4701
  useEffect7(() => {
4691
4702
  const timer = setTimeout(() => {
4692
- scrollToBottom();
4703
+ scrollToBottom(true);
4693
4704
  }, 100);
4694
4705
  return () => clearTimeout(timer);
4695
4706
  }, []);
@@ -4736,7 +4747,7 @@ var AIChatPanel = ({
4736
4747
  onClick: () => {
4737
4748
  onAgentChange(agentId);
4738
4749
  setTimeout(() => {
4739
- scrollToBottom();
4750
+ scrollToBottom(true);
4740
4751
  }, 100);
4741
4752
  }
4742
4753
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hef2024/llmasaservice-ui",
3
- "version": "0.22.0",
3
+ "version": "0.22.1",
4
4
  "description": "Prebuilt UI components for LLMAsAService.io",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -1470,12 +1470,28 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
1470
1470
  }, [thumbsDownClick, interactionClicked]);
1471
1471
 
1472
1472
  // Scroll to bottom - throttled using RAF to prevent layout thrashing
1473
- const scrollToBottom = useCallback(() => {
1473
+ const scrollToBottom = useCallback((force: boolean = false) => {
1474
1474
  // Cancel any pending scroll
1475
1475
  if (scrollRAFRef.current) {
1476
1476
  cancelAnimationFrame(scrollRAFRef.current);
1477
1477
  }
1478
1478
 
1479
+ // Check if we should scroll - only if user is near bottom or force is true
1480
+ if (!force && responseAreaRef.current) {
1481
+ const scrollViewport = responseAreaRef.current.querySelector('[data-radix-scroll-area-viewport]') as HTMLElement;
1482
+ const scrollElement = scrollViewport || responseAreaRef.current;
1483
+
1484
+ const scrollTop = scrollElement.scrollTop;
1485
+ const scrollHeight = scrollElement.scrollHeight;
1486
+ const clientHeight = scrollElement.clientHeight;
1487
+ const isNearBottom = scrollHeight - scrollTop - clientHeight < 100;
1488
+
1489
+ // If user is not near bottom, don't scroll (prevents scroll on layout changes like toast)
1490
+ if (!isNearBottom) {
1491
+ return;
1492
+ }
1493
+ }
1494
+
1479
1495
  // Throttle to max once per 100ms to prevent performance issues during streaming
1480
1496
  const now = Date.now();
1481
1497
  if (now - lastScrollTimeRef.current < 100) {
@@ -1551,8 +1567,9 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
1551
1567
 
1552
1568
  // Scroll to bottom immediately to show the new prompt
1553
1569
  // Use setTimeout to ensure the DOM has updated
1570
+ // Force scroll since this is a user-initiated action
1554
1571
  setTimeout(() => {
1555
- scrollToBottom();
1572
+ scrollToBottom(true);
1556
1573
  }, 0);
1557
1574
 
1558
1575
  // Now proceed with API calls in the background (conversation creation + LLM call)
@@ -1808,7 +1825,8 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
1808
1825
  // 3. We have content to show (response exists)
1809
1826
  const shouldAutoScroll = scrollToEnd || !userHasScrolled;
1810
1827
  if (!idle && shouldAutoScroll && response) {
1811
- scrollToBottom();
1828
+ // Use non-forced scroll - will only scroll if near bottom
1829
+ scrollToBottom(false);
1812
1830
  }
1813
1831
  }, [response, scrollToBottom, idle, userHasScrolled, scrollToEnd]); // Removed history dependency
1814
1832
 
@@ -2037,8 +2055,9 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
2037
2055
  // Auto-scroll when the agent suggestion card appears
2038
2056
  useEffect(() => {
2039
2057
  // Small delay to ensure the card is fully rendered in the DOM
2058
+ // Force scroll since this is new content being added
2040
2059
  const timer = setTimeout(() => {
2041
- scrollToBottom();
2060
+ scrollToBottom(true);
2042
2061
  }, 100);
2043
2062
  return () => clearTimeout(timer);
2044
2063
  }, []); // Empty deps - only run on mount
@@ -2158,8 +2177,9 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
2158
2177
  onClick={() => {
2159
2178
  onAgentChange(agentId);
2160
2179
  // Scroll to bottom after a brief delay to let React re-render
2180
+ // Force scroll since this is a user-initiated action
2161
2181
  setTimeout(() => {
2162
- scrollToBottom();
2182
+ scrollToBottom(true);
2163
2183
  }, 100);
2164
2184
  }}
2165
2185
  >