// components/ui/Sheet.native.tsx
import React from 'react';
import {
Modal,
View,
TouchableOpacity,
Platform,
Dimensions,
ScrollView,
StyleSheet,
Animated,
BackHandler
} from 'react-native';
import { Text } from '../text';
import { CloseButton } from './CloseButton';
import type { SheetProps, SheetContentProps, SheetHeaderProps, SheetTitleProps } from './Sheet.types';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const { height: SCREEN_HEIGHT } = Dimensions.get('window');
const SHEET_HEIGHT = SCREEN_HEIGHT * 0.7;
export function Sheet({ isOpen, onClose, children }: SheetProps) {
const translateY = React.useRef(new Animated.Value(SCREEN_HEIGHT)).current;
const [isVisible, setIsVisible] = React.useState(false);
// Handle back button on Android
React.useEffect(() => {
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
if (isOpen) {
onClose();
return true;
}
return false;
});
return () => backHandler.remove();
}, [isOpen, onClose]);
React.useEffect(() => {
if (isOpen) {
setIsVisible(true);
Animated.spring(translateY, {
toValue: SCREEN_HEIGHT - SHEET_HEIGHT,
useNativeDriver: true,
damping: 25,
mass: 0.7,
stiffness: 300,
}).start();
} else {
Animated.timing(translateY, {
toValue: SCREEN_HEIGHT,
duration: 200,
useNativeDriver: true,
}).start(() => {
setIsVisible(false);
});
}
}, [isOpen]);
if (!isVisible && !isOpen) return null;
return (
{/* Handle indicator */}
{children}
);
}
export function SheetHeader({ children }: SheetHeaderProps) {
return (
{children}
);
}
export function SheetTitle({ children }: SheetTitleProps) {
return {children};
}
export function SheetContent({ children }: SheetContentProps) {
const insets = useSafeAreaInsets();
return (
{children}
);
}
const styles = StyleSheet.create({
backdrop: {
backgroundColor: 'rgba(0,0,0,0.25)',
},
sheetContainer: {
height: SHEET_HEIGHT,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: -2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
});