From 31948f71dbe2920c1a645a866007eaa91bb28bbf Mon Sep 17 00:00:00 2001 From: bagasbanuna Date: Thu, 26 Mar 2026 12:28:07 +0800 Subject: [PATCH] Fix: NewWrapper footer position dengan SafeAreaView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: - Footer component tertutup atau scroll melebihi layar - Tabs tidak bisa diklik karena footer floating - Height OS_HEIGHT tidak konsisten di berbagai device Solution: ✅ Footer menggunakan position: absolute untuk stay di bawah ✅ Konten ScrollView/FlatList mendapat paddingBottom: OS_HEIGHT ✅ SafeAreaView hanya untuk area aman, bukan height control ✅ Footer tetap visible di semua ukuran layar Changes: - Add styles.footerContainer dengan position: absolute - Add paddingBottom ke contentContainerStyle (ScrollView & FlatList) - Remove height: OS_HEIGHT dari SafeAreaView - Footer stay di bottom dengan proper safe area handling Result: - Footer selalu terlihat di bawah layar - Konten tidak tertutup footer (ada padding) - Tabs bisa diklik dengan baik - Konsisten di iOS & Android - Respect safe area insets Co-authored-by: Qwen-Coder --- components/_ShareComponent/NewWrapper.tsx | 80 ++++++++++++++--------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/components/_ShareComponent/NewWrapper.tsx b/components/_ShareComponent/NewWrapper.tsx index 512ac15..eb3862a 100644 --- a/components/_ShareComponent/NewWrapper.tsx +++ b/components/_ShareComponent/NewWrapper.tsx @@ -84,7 +84,7 @@ const NewWrapper = (props: NewWrapperProps) => { return {content}; }; - // 🔹 Mode Dinamis + // 🔹 Mode Dinamis (FlatList) if ("listData" in props) { const listProps = props as ListModeProps; @@ -96,7 +96,7 @@ const NewWrapper = (props: NewWrapperProps) => { {headerComponent && ( {headerComponent} )} - + { return `fallback-${index}-${JSON.stringify(item)}`; } - // Gabungkan ID dengan indeks untuk mencegah duplikasi return `${String(item.id)}-${index}`; }) } - refreshControl={refreshControl} // ✅ dari BaseProps + refreshControl={refreshControl} onEndReached={listProps.onEndReached} onEndReachedThreshold={0.5} ListHeaderComponent={listProps.ListHeaderComponent} ListFooterComponent={listProps.ListFooterComponent} ListEmptyComponent={listProps.ListEmptyComponent} - contentContainerStyle={{ flexGrow: 1 }} + contentContainerStyle={{ + flexGrow: 1, + paddingBottom: footerComponent && !hideFooter ? OS_HEIGHT : 0 + }} keyboardShouldPersistTaps="handled" /> - {footerComponent ? ( - - {footerComponent} - - ) : hideFooter ? null : ( + {/* Footer dengan position absolute untuk stay di bawah */} + {footerComponent && !hideFooter && ( + + + {footerComponent} + + + )} + + {!footerComponent && !hideFooter && ( { ); } - // 🔹 Mode Statis + // 🔹 Mode Statis (ScrollView) const staticProps = props as StaticModeProps; return ( @@ -158,7 +165,10 @@ const NewWrapper = (props: NewWrapperProps) => { @@ -168,24 +178,19 @@ const NewWrapper = (props: NewWrapperProps) => { - {/* - - {renderContainer(staticProps.children)} - - */} + {/* Footer dengan position absolute untuk stay di bawah */} + {footerComponent && !hideFooter && ( + + + {footerComponent} + + + )} - {footerComponent ? ( - - {footerComponent} - - ) : hideFooter ? null : ( + {!footerComponent && !hideFooter && ( { ); }; +// Styles untuk footer dengan position absolute +const styles = { + footerContainer: { + position: "absolute" as const, + bottom: 0, + left: 0, + right: 0, + backgroundColor: MainColor.darkblue, + }, +}; + export default NewWrapper;