- 부가서비스 각 요청 페이지 키패드 높이 만큼 패딩 삽입 hook 추가
- 각 요청 페이지 자동 패딩 적용
This commit is contained in:
@@ -2,4 +2,4 @@ export * from './use-navigate';
|
||||
export * from './use-fix-scroll-view-safari';
|
||||
export * from './use-navigate';
|
||||
export * from './use-router-listener';
|
||||
|
||||
export * from './use-keyboard-aware';
|
||||
|
||||
88
src/shared/lib/hooks/use-keyboard-aware.ts
Normal file
88
src/shared/lib/hooks/use-keyboard-aware.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { useEffect, useState, useMemo, CSSProperties } from 'react';
|
||||
|
||||
export interface UseKeyboardAwareOptions {
|
||||
defaultPadding?: number;
|
||||
heightRatio?: number;
|
||||
maxPadding?: number;
|
||||
transition?: string;
|
||||
}
|
||||
|
||||
export const useKeyboardAware = (options?: UseKeyboardAwareOptions) => {
|
||||
const {
|
||||
defaultPadding = 60,
|
||||
heightRatio = 0.7,
|
||||
maxPadding = 300,
|
||||
transition = 'padding-bottom 0.2s ease'
|
||||
} = options || {};
|
||||
|
||||
const [keyboardHeight, setKeyboardHeight] = useState<number>(0);
|
||||
|
||||
useEffect(() => {
|
||||
let focusedElement: HTMLInputElement | null = null;
|
||||
let isKeyboardOpen = false;
|
||||
|
||||
// 네이티브에서 호출할 전역 함수 등록
|
||||
(window as any).onKeyboardShow = (height: number) => {
|
||||
console.log('Keyboard shown, height:', height);
|
||||
const wasKeyboardOpen = isKeyboardOpen;
|
||||
isKeyboardOpen = true;
|
||||
setKeyboardHeight(height);
|
||||
|
||||
// 키보드가 새로 열릴 때만 스크롤 (이미 열려있으면 스크롤 안함)
|
||||
if (!wasKeyboardOpen && focusedElement) {
|
||||
setTimeout(() => {
|
||||
focusedElement?.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}, 250);
|
||||
}
|
||||
};
|
||||
|
||||
(window as any).onKeyboardHide = () => {
|
||||
console.log('Keyboard hidden');
|
||||
isKeyboardOpen = false;
|
||||
setKeyboardHeight(0);
|
||||
focusedElement = null;
|
||||
};
|
||||
|
||||
// focus된 요소를 추적하기 위한 함수
|
||||
(window as any).setFocusedElement = (element: HTMLInputElement) => {
|
||||
focusedElement = element;
|
||||
|
||||
// 키보드가 이미 열려있으면 즉시 스크롤
|
||||
if (isKeyboardOpen) {
|
||||
setTimeout(() => {
|
||||
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
return () => {
|
||||
delete (window as any).onKeyboardShow;
|
||||
delete (window as any).onKeyboardHide;
|
||||
delete (window as any).setFocusedElement;
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 모든 input에서 사용할 공통 핸들러
|
||||
const handleInputFocus = (e: React.FocusEvent<HTMLInputElement>) => {
|
||||
// focus된 요소를 저장
|
||||
(window as any).setFocusedElement?.(e.target);
|
||||
};
|
||||
|
||||
// 동적 패딩 스타일 계산
|
||||
const keyboardAwarePadding: CSSProperties = useMemo(() => {
|
||||
const calculatedPadding = keyboardHeight > 0
|
||||
? Math.min(keyboardHeight * heightRatio, maxPadding)
|
||||
: defaultPadding;
|
||||
|
||||
return {
|
||||
paddingBottom: `${calculatedPadding}px`,
|
||||
transition
|
||||
};
|
||||
}, [keyboardHeight, defaultPadding, heightRatio, maxPadding, transition]);
|
||||
|
||||
return {
|
||||
keyboardHeight,
|
||||
handleInputFocus,
|
||||
keyboardAwarePadding
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user