Browse Source

fix(ui): refine keyboard shift and focus synchronization logic

Update `use-sheet-scroll-lock` to improve how the keyboard shift property
and body classes are applied during input focus events.

- Change `syncKeyboardShift` to accept a boolean state instead of height
- Add check to ensure focus synchronization only triggers for active
  question snap items
- Improve cleanup logic in `handleFocusOut` and `useEffect` to
  correctly reset the `--question-keyboard-shift` CSS variable
Dev
mortezaei 1 week ago
parent
commit
4e2a8b46e0
  1. 17
      src/components/Componentes/use-sheet-scroll-lock.ts

17
src/components/Componentes/use-sheet-scroll-lock.ts

@ -87,16 +87,16 @@ function isKeyboardInputTarget(target: EventTarget | null): boolean {
} }
function syncQuestionInputOpenClass() { function syncQuestionInputOpenClass() {
if (hasFocusedKeyboardInput && keyboardHeight > 0) {
if (hasFocusedKeyboardInput) {
document.body.classList.add("question-keyboard-open"); document.body.classList.add("question-keyboard-open");
} else { } else {
document.body.classList.remove("question-keyboard-open"); document.body.classList.remove("question-keyboard-open");
} }
} }
function syncKeyboardShift(height: number) {
function syncKeyboardShift(isOpen: boolean) {
const root = document.documentElement; const root = document.documentElement;
if (height <= 0) {
if (!isOpen) {
root.style.setProperty("--question-keyboard-shift", "0px"); root.style.setProperty("--question-keyboard-shift", "0px");
return; return;
} }
@ -110,10 +110,7 @@ function syncKeyboardShift(height: number) {
const contentTop = activeContent.getBoundingClientRect().top; const contentTop = activeContent.getBoundingClientRect().top;
const targetTop = snapList.getBoundingClientRect().top + 8; const targetTop = snapList.getBoundingClientRect().top + 8;
const requiredShift = Math.max(0, contentTop - targetTop); const requiredShift = Math.max(0, contentTop - targetTop);
root.style.setProperty(
"--question-keyboard-shift",
`${requiredShift}px`,
);
root.style.setProperty("--question-keyboard-shift", `${requiredShift}px`);
} }
/** /**
@ -124,14 +121,18 @@ export function useQuestionInputFocusSync() {
useEffect(() => { useEffect(() => {
const handleFocusIn = (event: FocusEvent) => { const handleFocusIn = (event: FocusEvent) => {
if (!isKeyboardInputTarget(event.target)) return; if (!isKeyboardInputTarget(event.target)) return;
const target = event.target as HTMLElement;
if (!target.closest('.question-snap-item[aria-current="step"]')) return;
hasFocusedKeyboardInput = true; hasFocusedKeyboardInput = true;
syncQuestionInputOpenClass(); syncQuestionInputOpenClass();
window.requestAnimationFrame(() => syncKeyboardShift(true));
}; };
const handleFocusOut = (event: FocusEvent) => { const handleFocusOut = (event: FocusEvent) => {
if (!isKeyboardInputTarget(event.target)) return; if (!isKeyboardInputTarget(event.target)) return;
window.setTimeout(() => { window.setTimeout(() => {
hasFocusedKeyboardInput = isKeyboardInputTarget(document.activeElement); hasFocusedKeyboardInput = isKeyboardInputTarget(document.activeElement);
syncQuestionInputOpenClass(); syncQuestionInputOpenClass();
if (!hasFocusedKeyboardInput) syncKeyboardShift(false);
}, 0); }, 0);
}; };
@ -142,7 +143,7 @@ export function useQuestionInputFocusSync() {
hasFocusedKeyboardInput = false; hasFocusedKeyboardInput = false;
} }
syncQuestionInputOpenClass(); syncQuestionInputOpenClass();
window.requestAnimationFrame(() => syncKeyboardShift(keyboardHeight));
if (keyboardHeight === 0) syncKeyboardShift(false);
}); });
const initialViewportHeight = window.visualViewport?.height ?? 0; const initialViewportHeight = window.visualViewport?.height ?? 0;

Loading…
Cancel
Save