import React, { useCallback } from 'react'; import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'; import { MaterialIcons } from '@expo/vector-icons'; import { Gesture, GestureDetector } from 'react-native-gesture-handler'; import Animated, { useSharedValue, useAnimatedStyle, withSpring, runOnJS } from 'react-native-reanimated'; const PANEL_HEIGHT = 300; const PANEL_HEADER_VISIBLE = 80; interface SelectionPanelProps { selectedCount: number; onClose: () => void; onDelete?: () => void; onEdit?: () => void; onTags?: () => void; onFolder?: () => void; onMove?: () => void; insetsBottom: number; } export function SelectionPanel({ selectedCount, onClose, onDelete, onEdit, onTags, onFolder, onMove, insetsBottom, }: SelectionPanelProps) { const panelOffset = useSharedValue(PANEL_HEIGHT - PANEL_HEADER_VISIBLE); const panelStartY = useSharedValue(0); const isPanelExpanded = useSharedValue(false); const [panelExpanded, setPanelExpanded] = React.useState(false); const togglePanelJS = useCallback(() => { if (isPanelExpanded.value) { panelOffset.value = withSpring(PANEL_HEIGHT - PANEL_HEADER_VISIBLE); isPanelExpanded.value = false; setPanelExpanded(false); } else { panelOffset.value = withSpring(0); isPanelExpanded.value = true; setPanelExpanded(true); } }, []); const panGesture = Gesture.Pan() .onStart(() => { panelStartY.value = panelOffset.value; }) .onUpdate((event) => { const offset = Math.max(0, Math.min(PANEL_HEIGHT - PANEL_HEADER_VISIBLE, panelStartY.value + event.translationY)); panelOffset.value = offset; }) .onEnd(() => { if (panelOffset.value > (PANEL_HEIGHT - PANEL_HEADER_VISIBLE) / 2) { panelOffset.value = withSpring(PANEL_HEIGHT - PANEL_HEADER_VISIBLE); isPanelExpanded.value = false; runOnJS(setPanelExpanded)(false); } else { panelOffset.value = withSpring(0); isPanelExpanded.value = true; runOnJS(setPanelExpanded)(true); } }); const panelAnimatedStyle = useAnimatedStyle(() => ({ transform: [{ translateY: panelOffset.value }], })); return ( {selectedCount} sélectionnée{selectedCount > 1 ? 's' : ''} Tout {onDelete && ( Supprimer )} {onEdit && ( Éditer )} {onTags && ( Tags )} {onFolder && ( Dossier )} {onMove && ( Déplacer )} ); } const styles = StyleSheet.create({ panel: { position: 'absolute', bottom: 0, left: 0, right: 0, backgroundColor: '#fff', borderTopLeftRadius: 20, borderTopRightRadius: 20, paddingHorizontal: 20, paddingTop: 12, height: PANEL_HEIGHT, shadowColor: '#000', shadowOffset: { width: 0, height: -2 }, shadowOpacity: 0.1, shadowRadius: 8, elevation: 10, }, panelHandle: { width: 36, height: 4, borderRadius: 2, backgroundColor: '#ddd', alignSelf: 'center', marginBottom: 12, }, panelHeader: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16, }, closeBtn: { padding: 4, }, selectionCount: { fontSize: 16, fontWeight: '700', color: '#333', }, selectAllBtn: { paddingHorizontal: 8, paddingVertical: 4, }, selectAllText: { fontSize: 14, color: '#1976D2', fontWeight: '600', }, panelBody: { flex: 1, }, actionsGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: 10, }, actionBtn: { width: '47%', flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 10, paddingVertical: 14, borderRadius: 12, backgroundColor: '#f5f5f5', }, actionLabel: { fontSize: 15, fontWeight: '600', }, deleteBtn: {}, editBtn: {}, tagBtn: {}, folderBtn: {}, moveBtn: {}, });