victor HF Staff commited on
Commit
24b24f4
·
1 Parent(s): 604b9db

Improve textarea focus handling in ChatInput

Browse files

Refactors focus logic into a dedicated async function with animation frame waits for smoother focusing. Ensures textarea is focused after navigation and on mount, improving user experience and reliability.

src/lib/components/chat/ChatInput.svelte CHANGED
@@ -1,6 +1,8 @@
1
  <script lang="ts">
2
  import { onMount, tick } from "svelte";
3
 
 
 
4
  import HoverTooltip from "$lib/components/HoverTooltip.svelte";
5
  import IconPaperclip from "$lib/components/icons/IconPaperclip.svelte";
6
  import { page } from "$app/state";
@@ -46,10 +48,35 @@
46
  let textareaElement: HTMLTextAreaElement | undefined = $state();
47
  let isCompositionOn = $state(false);
48
 
49
- onMount(() => {
50
- if (!isVirtualKeyboard()) {
51
- textareaElement?.focus();
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
 
 
 
 
 
 
 
 
 
 
 
 
53
  function onFormSubmit() {
54
  adjustTextareaHeight();
55
  }
@@ -61,6 +88,10 @@
61
  };
62
  });
63
 
 
 
 
 
64
  function adjustTextareaHeight() {
65
  if (!textareaElement) {
66
  return;
 
1
  <script lang="ts">
2
  import { onMount, tick } from "svelte";
3
 
4
+ import { afterNavigate } from "$app/navigation";
5
+
6
  import HoverTooltip from "$lib/components/HoverTooltip.svelte";
7
  import IconPaperclip from "$lib/components/icons/IconPaperclip.svelte";
8
  import { page } from "$app/state";
 
48
  let textareaElement: HTMLTextAreaElement | undefined = $state();
49
  let isCompositionOn = $state(false);
50
 
51
+ const waitForAnimationFrame = () =>
52
+ typeof requestAnimationFrame === "function"
53
+ ? new Promise<void>((resolve) => {
54
+ requestAnimationFrame(() => resolve());
55
+ })
56
+ : Promise.resolve();
57
+
58
+ async function focusTextarea() {
59
+ if (!textareaElement || textareaElement.disabled || isVirtualKeyboard()) return;
60
+ if (typeof document !== "undefined" && document.activeElement === textareaElement) return;
61
+
62
+ await tick();
63
+
64
+ if (typeof requestAnimationFrame === "function") {
65
+ await waitForAnimationFrame();
66
+ await waitForAnimationFrame();
67
  }
68
+
69
+ if (!textareaElement || textareaElement.disabled || isVirtualKeyboard()) return;
70
+
71
+ try {
72
+ textareaElement.focus({ preventScroll: true });
73
+ } catch {
74
+ textareaElement.focus();
75
+ }
76
+ }
77
+
78
+ onMount(() => {
79
+ void focusTextarea();
80
  function onFormSubmit() {
81
  adjustTextareaHeight();
82
  }
 
88
  };
89
  });
90
 
91
+ afterNavigate(() => {
92
+ void focusTextarea();
93
+ });
94
+
95
  function adjustTextareaHeight() {
96
  if (!textareaElement) {
97
  return;