OS_Wrapper System: - Simplify API: Remove PageWrapper, merge keyboard props into OS_Wrapper - Add auto-scroll when keyboard appears (Android only) - Add tap-to-dismiss keyboard for both Static and List modes - Fix contentPaddingBottom default to 250px (prevent keyboard overlap) - Change default contentPadding to 0 (per-screen control) - Remove Platform.OS checks from IOSWrapper and AndroidWrapper Constants: - Add PADDING_INLINE constant (16px) for consistent inline padding - Add OS_PADDING_TOP constants for tab layouts Job Screens Migration (9 files): - Apply PADDING_INLINE to all Job screens: - ScreenBeranda, ScreenBeranda2 - ScreenArchive, ScreenArchive2 - MainViewStatus, MainViewStatus2 - ScreenJobCreate, ScreenJobEdit - Job detail screen Keyboard Handling: - Simplified useKeyboardForm hook - Auto-scroll by keyboard height when keyboard appears - Track scroll position for accurate scroll targets - TouchableWithoutFeedback wraps all content for tap-to-dismiss Documentation: - Update TASK-005 with Phase 1 completion status - Update Quick Reference with unified API examples Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
76 lines
2.1 KiB
TypeScript
76 lines
2.1 KiB
TypeScript
// FormWrapper.tsx - Reusable wrapper untuk form dengan keyboard handling
|
|
import { MainColor } from "@/constants/color-palet";
|
|
import { Keyboard, KeyboardAvoidingView, Platform, ScrollView, TouchableWithoutFeedback, View } from "react-native";
|
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
import { ReactNode } from "react";
|
|
import { useKeyboardForm } from "@/hooks/useKeyboardForm";
|
|
|
|
interface FormWrapperProps {
|
|
children: ReactNode;
|
|
footerComponent?: ReactNode;
|
|
/**
|
|
* Offset scroll saat keyboard muncul (default: 100)
|
|
*/
|
|
scrollOffset?: number;
|
|
/**
|
|
* Padding bottom untuk content (default: 100)
|
|
*/
|
|
contentPaddingBottom?: number;
|
|
/**
|
|
* Padding untuk content container (default: 16)
|
|
*/
|
|
contentPadding?: number;
|
|
}
|
|
|
|
export function FormWrapper({
|
|
children,
|
|
footerComponent,
|
|
scrollOffset = 100,
|
|
contentPaddingBottom = 100,
|
|
contentPadding = 16,
|
|
}: FormWrapperProps) {
|
|
const { scrollViewRef, handleScroll } = useKeyboardForm(scrollOffset);
|
|
|
|
return (
|
|
<KeyboardAvoidingView
|
|
behavior={Platform.OS === "ios" ? "padding" : undefined}
|
|
style={{ flex: 1, backgroundColor: MainColor.darkblue }}
|
|
>
|
|
<ScrollView
|
|
ref={scrollViewRef}
|
|
onScroll={handleScroll}
|
|
scrollEventThrottle={16}
|
|
style={{ flex: 1 }}
|
|
contentContainerStyle={{
|
|
flexGrow: 1,
|
|
paddingBottom: contentPaddingBottom,
|
|
}}
|
|
keyboardShouldPersistTaps="handled"
|
|
showsVerticalScrollIndicator={false}
|
|
>
|
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
|
<View style={{ flex: 1, padding: contentPadding }}>
|
|
{children}
|
|
</View>
|
|
</TouchableWithoutFeedback>
|
|
</ScrollView>
|
|
|
|
{/* Footer - Fixed di bawah */}
|
|
{footerComponent && (
|
|
<SafeAreaView
|
|
edges={["bottom"]}
|
|
style={{
|
|
backgroundColor: MainColor.darkblue,
|
|
position: 'absolute',
|
|
bottom: 0,
|
|
left: 0,
|
|
right: 0,
|
|
}}
|
|
>
|
|
{footerComponent}
|
|
</SafeAreaView>
|
|
)}
|
|
</KeyboardAvoidingView>
|
|
);
|
|
}
|