@hef2024/llmasaservice-ui 0.22.3 → 0.22.4

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
@@ -3895,6 +3895,8 @@ var AIChatPanel = ({
3895
3895
  const scrollRAFRef = (0, import_react12.useRef)(null);
3896
3896
  const lastScrollTimeRef = (0, import_react12.useRef)(0);
3897
3897
  const prevResponseLengthRef = (0, import_react12.useRef)(0);
3898
+ const scrollToEndRef = (0, import_react12.useRef)(scrollToEnd || false);
3899
+ const userHasScrolledRef = (0, import_react12.useRef)(userHasScrolled);
3898
3900
  const prevIdleRef = (0, import_react12.useRef)(true);
3899
3901
  const hasNotifiedCompletionRef = (0, import_react12.useRef)(true);
3900
3902
  const latestHistoryRef = (0, import_react12.useRef)(initialHistory);
@@ -4574,6 +4576,16 @@ var AIChatPanel = ({
4574
4576
  }
4575
4577
  }, [idle]);
4576
4578
  (0, import_react12.useEffect)(() => {
4579
+ scrollToEndRef.current = scrollToEnd || false;
4580
+ }, [scrollToEnd]);
4581
+ (0, import_react12.useEffect)(() => {
4582
+ userHasScrolledRef.current = userHasScrolled;
4583
+ }, [userHasScrolled]);
4584
+ (0, import_react12.useEffect)(() => {
4585
+ if (idle) {
4586
+ console.log("AIChatPanel - Auto-scroll effect: SKIPPED (idle)");
4587
+ return;
4588
+ }
4577
4589
  const currentResponseLength = response.length;
4578
4590
  const responseGotLonger = currentResponseLength > prevResponseLengthRef.current;
4579
4591
  console.log("AIChatPanel - Auto-scroll effect:", {
@@ -4581,20 +4593,18 @@ var AIChatPanel = ({
4581
4593
  currentResponseLength,
4582
4594
  prevLength: prevResponseLengthRef.current,
4583
4595
  responseGotLonger,
4584
- userHasScrolled,
4585
- scrollToEnd
4596
+ userHasScrolled: userHasScrolledRef.current,
4597
+ scrollToEnd: scrollToEndRef.current
4586
4598
  });
4587
4599
  prevResponseLengthRef.current = currentResponseLength;
4588
- const shouldAutoScroll = scrollToEnd || !userHasScrolled;
4589
- if (!idle && shouldAutoScroll && response && responseGotLonger) {
4600
+ const shouldAutoScroll = scrollToEndRef.current || !userHasScrolledRef.current;
4601
+ if (shouldAutoScroll && response && responseGotLonger) {
4590
4602
  console.log("AIChatPanel - Calling scrollToBottom");
4591
4603
  scrollToBottom(false);
4592
4604
  }
4593
- }, [response, scrollToBottom, idle, userHasScrolled, scrollToEnd]);
4605
+ }, [response, idle]);
4594
4606
  const idleRef = (0, import_react12.useRef)(idle);
4595
4607
  idleRef.current = idle;
4596
- const userHasScrolledRef = (0, import_react12.useRef)(userHasScrolled);
4597
- userHasScrolledRef.current = userHasScrolled;
4598
4608
  (0, import_react12.useEffect)(() => {
4599
4609
  const scrollArea = responseAreaRef.current;
4600
4610
  if (!scrollArea) return;
package/dist/index.mjs CHANGED
@@ -3862,6 +3862,8 @@ var AIChatPanel = ({
3862
3862
  const scrollRAFRef = useRef5(null);
3863
3863
  const lastScrollTimeRef = useRef5(0);
3864
3864
  const prevResponseLengthRef = useRef5(0);
3865
+ const scrollToEndRef = useRef5(scrollToEnd || false);
3866
+ const userHasScrolledRef = useRef5(userHasScrolled);
3865
3867
  const prevIdleRef = useRef5(true);
3866
3868
  const hasNotifiedCompletionRef = useRef5(true);
3867
3869
  const latestHistoryRef = useRef5(initialHistory);
@@ -4541,6 +4543,16 @@ var AIChatPanel = ({
4541
4543
  }
4542
4544
  }, [idle]);
4543
4545
  useEffect7(() => {
4546
+ scrollToEndRef.current = scrollToEnd || false;
4547
+ }, [scrollToEnd]);
4548
+ useEffect7(() => {
4549
+ userHasScrolledRef.current = userHasScrolled;
4550
+ }, [userHasScrolled]);
4551
+ useEffect7(() => {
4552
+ if (idle) {
4553
+ console.log("AIChatPanel - Auto-scroll effect: SKIPPED (idle)");
4554
+ return;
4555
+ }
4544
4556
  const currentResponseLength = response.length;
4545
4557
  const responseGotLonger = currentResponseLength > prevResponseLengthRef.current;
4546
4558
  console.log("AIChatPanel - Auto-scroll effect:", {
@@ -4548,20 +4560,18 @@ var AIChatPanel = ({
4548
4560
  currentResponseLength,
4549
4561
  prevLength: prevResponseLengthRef.current,
4550
4562
  responseGotLonger,
4551
- userHasScrolled,
4552
- scrollToEnd
4563
+ userHasScrolled: userHasScrolledRef.current,
4564
+ scrollToEnd: scrollToEndRef.current
4553
4565
  });
4554
4566
  prevResponseLengthRef.current = currentResponseLength;
4555
- const shouldAutoScroll = scrollToEnd || !userHasScrolled;
4556
- if (!idle && shouldAutoScroll && response && responseGotLonger) {
4567
+ const shouldAutoScroll = scrollToEndRef.current || !userHasScrolledRef.current;
4568
+ if (shouldAutoScroll && response && responseGotLonger) {
4557
4569
  console.log("AIChatPanel - Calling scrollToBottom");
4558
4570
  scrollToBottom(false);
4559
4571
  }
4560
- }, [response, scrollToBottom, idle, userHasScrolled, scrollToEnd]);
4572
+ }, [response, idle]);
4561
4573
  const idleRef = useRef5(idle);
4562
4574
  idleRef.current = idle;
4563
- const userHasScrolledRef = useRef5(userHasScrolled);
4564
- userHasScrolledRef.current = userHasScrolled;
4565
4575
  useEffect7(() => {
4566
4576
  const scrollArea = responseAreaRef.current;
4567
4577
  if (!scrollArea) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hef2024/llmasaservice-ui",
3
- "version": "0.22.3",
3
+ "version": "0.22.4",
4
4
  "description": "Prebuilt UI components for LLMAsAService.io",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -847,6 +847,8 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
847
847
  const scrollRAFRef = useRef<number | null>(null);
848
848
  const lastScrollTimeRef = useRef<number>(0);
849
849
  const prevResponseLengthRef = useRef<number>(0);
850
+ const scrollToEndRef = useRef<boolean>(scrollToEnd || false);
851
+ const userHasScrolledRef = useRef<boolean>(userHasScrolled);
850
852
 
851
853
  // === NEW: Clean history management refs ===
852
854
  // Track previous idle state to detect transitions (false→true = completion)
@@ -1821,10 +1823,26 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
1821
1823
  }
1822
1824
  }, [idle]); // ONLY depends on idle - no history, no callbacks in deps
1823
1825
 
1826
+ // Keep refs in sync
1827
+ useEffect(() => {
1828
+ scrollToEndRef.current = scrollToEnd || false;
1829
+ }, [scrollToEnd]);
1830
+
1831
+ useEffect(() => {
1832
+ userHasScrolledRef.current = userHasScrolled;
1833
+ }, [userHasScrolled]);
1834
+
1824
1835
  // Auto-scroll to bottom - only while streaming and user hasn't manually scrolled
1836
+ // CRITICAL: Only depends on response and idle to avoid re-running on layout changes
1825
1837
  useEffect(() => {
1838
+ // CRITICAL: Skip entirely if idle - no scrolling when not streaming
1839
+ if (idle) {
1840
+ console.log('AIChatPanel - Auto-scroll effect: SKIPPED (idle)');
1841
+ return;
1842
+ }
1843
+
1826
1844
  // Only auto-scroll if:
1827
- // 1. We're actively streaming (!idle)
1845
+ // 1. We're actively streaming (!idle) - checked above
1828
1846
  // 2. User hasn't manually scrolled up during this response (or scrollToEnd prop is true)
1829
1847
  // 3. We have content to show (response exists)
1830
1848
  // 4. The response actually got longer (not just a re-render from layout change)
@@ -1836,30 +1854,25 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
1836
1854
  currentResponseLength,
1837
1855
  prevLength: prevResponseLengthRef.current,
1838
1856
  responseGotLonger,
1839
- userHasScrolled,
1840
- scrollToEnd,
1857
+ userHasScrolled: userHasScrolledRef.current,
1858
+ scrollToEnd: scrollToEndRef.current,
1841
1859
  });
1842
1860
 
1843
1861
  prevResponseLengthRef.current = currentResponseLength;
1844
1862
 
1845
- // CRITICAL: Only auto-scroll during active streaming when response grows
1846
- // This prevents scroll on layout changes (toast, context updates, etc.)
1847
- const shouldAutoScroll = scrollToEnd || !userHasScrolled;
1848
- if (!idle && shouldAutoScroll && response && responseGotLonger) {
1863
+ // Only scroll if response actually grew - use refs to avoid unnecessary effect runs
1864
+ const shouldAutoScroll = scrollToEndRef.current || !userHasScrolledRef.current;
1865
+ if (shouldAutoScroll && response && responseGotLonger) {
1849
1866
  console.log('AIChatPanel - Calling scrollToBottom');
1850
1867
  // Use non-forced scroll - will only scroll if near bottom
1851
1868
  scrollToBottom(false);
1852
1869
  }
1853
- }, [response, scrollToBottom, idle, userHasScrolled, scrollToEnd]);
1870
+ }, [response, idle]); // ONLY response and idle - no other dependencies!
1854
1871
 
1855
1872
  // Ref to track idle state for scroll handler (avoids stale closure)
1856
1873
  const idleRef = useRef(idle);
1857
1874
  idleRef.current = idle;
1858
1875
 
1859
- // Ref to track userHasScrolled to avoid redundant state updates
1860
- const userHasScrolledRef = useRef(userHasScrolled);
1861
- userHasScrolledRef.current = userHasScrolled;
1862
-
1863
1876
  // Detect user scroll to disable auto-scroll
1864
1877
  useEffect(() => {
1865
1878
  const scrollArea = responseAreaRef.current;