Files
Bahla-Frontend/src/components/ui/Screen.tsx
2026-09-08 19:50:28 +02:00

75 lines
2.3 KiB
TypeScript

/* ------------------------------------------------------------------ *
* Screen — enveloppe d'écran. Fond, zone sûre, padding de tab bar.
* ------------------------------------------------------------------ */
import { ReactNode } from 'react';
import { ScrollView, StyleSheet, View, ViewStyle } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { colors } from '@/theme/colors';
/** Hauteur de la tab bar custom, hors safe-area. Source unique. */
import { TAB_BAR_BASE_HEIGHT } from '@/components/navigation/BahlaTabBar';
export const TAB_BAR_HEIGHT = TAB_BAR_BASE_HEIGHT;
type Props = {
children: ReactNode;
/** `scroll` enveloppe dans un ScrollView, `static` en View simple. */
layout?: 'scroll' | 'static';
/** Applique le padding haut de la zone sûre. false pour un écran à image plein bord. */
edgeToEdge?: boolean;
/** Réserve la hauteur de la tab bar en bas. false sur les écrans modaux / (org)/create. */
tabBar?: boolean;
/** Halo violet décoratif en haut à gauche (B1, C1). */
halo?: boolean;
/** Padding horizontal des enfants. 20 par défaut, 0 pour du plein bord. */
gutter?: number;
contentContainerStyle?: ViewStyle;
};
export function Screen({
children,
layout = 'scroll',
edgeToEdge = false,
tabBar = true,
halo = false,
gutter = 20,
contentContainerStyle,
}: Props) {
const insets = useSafeAreaInsets();
const padding: ViewStyle = {
paddingTop: edgeToEdge ? 0 : insets.top,
paddingHorizontal: gutter,
paddingBottom: tabBar ? TAB_BAR_HEIGHT + insets.bottom + 24 : insets.bottom + 24,
};
return (
<View style={styles.root}>
{halo && <View pointerEvents="none" style={styles.halo} />}
{layout === 'scroll' ? (
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={[padding, contentContainerStyle]}
>
{children}
</ScrollView>
) : (
<View style={[styles.flex, padding, contentContainerStyle]}>{children}</View>
)}
</View>
);
}
const styles = StyleSheet.create({
root: { flex: 1, backgroundColor: colors.deepBackground },
flex: { flex: 1 },
halo: {
position: 'absolute',
width: 380,
height: 380,
borderRadius: 190,
top: -140,
left: -60,
backgroundColor: colors.secondarySoft,
},
});