{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "drawer",
  "type": "registry:ui",
  "title": "Drawer",
  "description": "A drawer component for React Native applications.",
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/drawer/drawer.tsx",
      "content": "import { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\nimport {\n  Animated,\n  Dimensions,\n  Easing,\n  KeyboardAvoidingView,\n  Modal,\n  PanResponder,\n  Platform,\n  StyleSheet,\n  Text,\n  TouchableWithoutFeedback,\n  View,\n} from \"react-native\";\nimport { SafeAreaView } from \"react-native-safe-area-context\";\n\n// Animation config constants\nconst ANIMATION = {\n  OPEN: {\n    BACKDROP_DURATION: 180,\n    SPRING_VELOCITY: 3,\n    SPRING_TENSION: 120,\n    SPRING_FRICTION: 22,\n  },\n  CLOSE: {\n    SPRING_FRICTION: 26,\n    SPRING_TENSION: 100,\n    SPRING_VELOCITY: 0.5,\n    BACKDROP_DURATION: 280,\n    BACKDROP_DELAY: 100,\n  },\n  SNAP: {\n    SPRING_TENSION: 120,\n    SPRING_FRICTION: 22,\n  },\n};\n\n// Drag behavior constants\nconst DRAG = {\n  THRESHOLD: 5,\n  CLOSE_DISTANCE: 100,\n  VELOCITY_THRESHOLD: {\n    UP: 0.3,\n    DOWN: 0.5,\n  },\n  RESISTANCE: 0.1,\n};\n\n// Drawer sizes - Definition of preset snap points\nconst DRAWER_SIZES = {\n  SMALL: [0.3, 0.5], // Small drawer that can be extended to 50%\n  MEDIUM: [0.5, 0.8], // Medium drawer that can be extended to 80%\n  LARGE: [0.6, 0.8, 0.95], // Large drawer with size options\n  FULL: [0.8, 0.95], // Full screen with reduced option\n};\n\nconst { height: SCREEN_HEIGHT } = Dimensions.get(\"window\");\n\nexport type DrawerSize = \"small\" | \"medium\" | \"large\" | \"full\" | number[];\n\nconst resolveSnapPoints = (size: DrawerSize): number[] => {\n  if (Array.isArray(size)) return size;\n\n  switch (size) {\n    case \"small\":\n      return DRAWER_SIZES.SMALL;\n    case \"medium\":\n      return DRAWER_SIZES.MEDIUM;\n    case \"large\":\n      return DRAWER_SIZES.LARGE;\n    case \"full\":\n      return DRAWER_SIZES.FULL;\n    default:\n      return DRAWER_SIZES.MEDIUM;\n  }\n};\n\ninterface DrawerProps {\n  open: boolean;\n  onClose: () => void;\n  children: React.ReactNode;\n  title?: string;\n  size?: DrawerSize;\n  initialSnapIndex?: number;\n  snapPoints?: number[];\n  contentClassName?: string;\n  avoidKeyboard?: boolean;\n  closeOnBackdropPress?: boolean;\n  disableBackHandler?: boolean;\n}\n\ninterface DrawerContextValue {\n  close: () => void;\n  snapTo: (index: number) => void;\n  currentSnapIndex: number;\n  snapPoints: number[];\n  isClosing: boolean;\n  isAnimating: boolean;\n  position: Animated.Value;\n}\n\nexport const DrawerContext = React.createContext<DrawerContextValue>({\n  close: () => { },\n  snapTo: () => { },\n  currentSnapIndex: 0,\n  snapPoints: DRAWER_SIZES.MEDIUM,\n  isClosing: false,\n  isAnimating: false,\n  position: new Animated.Value(0),\n});\n\nexport const useDrawer = () => React.useContext(DrawerContext);\n\nconst Drawer = React.forwardRef<View, DrawerProps>(\n  (\n    {\n      open,\n      onClose,\n      children,\n      title,\n      size = \"medium\",\n      initialSnapIndex = 0,\n      snapPoints: providedSnapPoints,\n      contentClassName,\n      avoidKeyboard = true,\n      closeOnBackdropPress = true,\n      disableBackHandler = false,\n    },\n    ref\n  ) => {\n    const [isVisible, setIsVisible] = React.useState(false);\n    const snapPoints = React.useMemo(\n      () => providedSnapPoints || resolveSnapPoints(size),\n      [size, providedSnapPoints]\n    );\n    const snapPointsPixels = React.useMemo(\n      () => snapPoints.map((point) => SCREEN_HEIGHT - SCREEN_HEIGHT * point),\n      [snapPoints]\n    );\n\n    const activeSnapIndex = React.useRef(initialSnapIndex);\n    const translateY = React.useRef(new Animated.Value(SCREEN_HEIGHT)).current;\n    const backdropOpacity = React.useRef(new Animated.Value(0)).current;\n    const isClosing = React.useRef(false);\n    const isAnimating = React.useRef(false);\n    const hasInitializedOpen = React.useRef(false);\n\n    const animateOpen = React.useCallback(() => {\n      if (isAnimating.current) {\n        translateY.stopAnimation();\n        backdropOpacity.stopAnimation();\n      }\n\n      isAnimating.current = true;\n      translateY.setValue(SCREEN_HEIGHT);\n      backdropOpacity.setValue(0);\n      isClosing.current = false;\n\n      Animated.timing(backdropOpacity, {\n        toValue: 1,\n        duration: ANIMATION.OPEN.BACKDROP_DURATION,\n        useNativeDriver: true,\n        easing: Easing.out(Easing.ease),\n      }).start();\n\n      Animated.spring(translateY, {\n        toValue: snapPointsPixels[initialSnapIndex],\n        useNativeDriver: true,\n        velocity: ANIMATION.OPEN.SPRING_VELOCITY,\n        tension: ANIMATION.OPEN.SPRING_TENSION,\n        friction: ANIMATION.OPEN.SPRING_FRICTION,\n      }).start(() => {\n        isAnimating.current = false;\n        activeSnapIndex.current = initialSnapIndex;\n      });\n    }, [backdropOpacity, translateY, snapPointsPixels, initialSnapIndex]);\n\n    const animateClose = React.useCallback(() => {\n      if (isClosing.current) return;\n\n      isClosing.current = true;\n\n      if (isAnimating.current) {\n        translateY.stopAnimation();\n        backdropOpacity.stopAnimation();\n      }\n\n      isAnimating.current = true;\n\n      Animated.spring(translateY, {\n        toValue: SCREEN_HEIGHT,\n        useNativeDriver: true,\n        friction: ANIMATION.CLOSE.SPRING_FRICTION,\n        tension: ANIMATION.CLOSE.SPRING_TENSION,\n        velocity: ANIMATION.CLOSE.SPRING_VELOCITY,\n      }).start();\n\n      Animated.timing(backdropOpacity, {\n        toValue: 0,\n        duration: ANIMATION.CLOSE.BACKDROP_DURATION,\n        easing: Easing.out(Easing.ease),\n        useNativeDriver: true,\n        delay: ANIMATION.CLOSE.BACKDROP_DELAY,\n      }).start(() => {\n        requestAnimationFrame(() => {\n          setIsVisible(false);\n          isClosing.current = false;\n          isAnimating.current = false;\n          hasInitializedOpen.current = false;\n          onClose();\n        });\n      });\n    }, [backdropOpacity, translateY, onClose]);\n\n    React.useEffect(() => {\n      if (open && !isVisible) {\n        setIsVisible(true);\n        return;\n      }\n\n      if (\n        open &&\n        isVisible &&\n        !hasInitializedOpen.current &&\n        !isClosing.current\n      ) {\n        animateOpen();\n        hasInitializedOpen.current = true;\n        return;\n      }\n\n      if (!open && isVisible && !isClosing.current) {\n        animateClose();\n      }\n    }, [open, isVisible, animateOpen, animateClose]);\n\n    const handleBackdropPress = React.useCallback(() => {\n      if (closeOnBackdropPress && !isClosing.current) {\n        isClosing.current = true;\n        isAnimating.current = true;\n\n        Animated.spring(translateY, {\n          toValue: SCREEN_HEIGHT,\n          useNativeDriver: true,\n          friction: ANIMATION.CLOSE.SPRING_FRICTION,\n          tension: ANIMATION.CLOSE.SPRING_TENSION,\n          velocity: ANIMATION.CLOSE.SPRING_VELOCITY,\n        }).start();\n\n        Animated.timing(backdropOpacity, {\n          toValue: 0,\n          duration: ANIMATION.CLOSE.BACKDROP_DURATION,\n          easing: Easing.out(Easing.ease),\n          useNativeDriver: true,\n          delay: ANIMATION.CLOSE.BACKDROP_DELAY,\n        }).start(() => {\n          requestAnimationFrame(() => {\n            setIsVisible(false);\n            isClosing.current = false;\n            isAnimating.current = false;\n            hasInitializedOpen.current = false;\n            onClose();\n          });\n        });\n      }\n    }, [backdropOpacity, translateY, onClose, closeOnBackdropPress]);\n\n    const animateToSnapPoint = React.useCallback(\n      (index: number, velocity = 0) => {\n        if (\n          index < 0 ||\n          index >= snapPointsPixels.length ||\n          isAnimating.current\n        )\n          return;\n\n        isAnimating.current = true;\n        activeSnapIndex.current = index;\n\n        Animated.spring(translateY, {\n          toValue: snapPointsPixels[index],\n          useNativeDriver: true,\n          velocity: velocity,\n          tension: ANIMATION.SNAP.SPRING_TENSION,\n          friction: ANIMATION.SNAP.SPRING_FRICTION,\n        }).start(() => {\n          isAnimating.current = false;\n        });\n      },\n      [snapPointsPixels]\n    );\n\n    const getTargetSnapIndex = React.useCallback(\n      (currentY: number, velocity: number, dragDirection: \"up\" | \"down\") => {\n        const isDraggingDown = dragDirection === \"down\";\n\n        if (\n          activeSnapIndex.current === snapPointsPixels.length - 1 &&\n          isDraggingDown\n        ) {\n          return snapPointsPixels.length - 2 >= 0\n            ? snapPointsPixels.length - 2\n            : 0;\n        }\n\n        if (\n          activeSnapIndex.current === 1 &&\n          isDraggingDown &&\n          velocity > DRAG.VELOCITY_THRESHOLD.UP\n        ) {\n          return 0;\n        }\n\n        if (\n          activeSnapIndex.current === 0 &&\n          isDraggingDown &&\n          velocity > DRAG.VELOCITY_THRESHOLD.DOWN\n        ) {\n          return -1;\n        }\n\n        if (currentY > snapPointsPixels[0] + DRAG.CLOSE_DISTANCE) {\n          return -1;\n        }\n\n        if (dragDirection === \"up\" && velocity > DRAG.VELOCITY_THRESHOLD.UP) {\n          const nextIndex = Math.min(\n            activeSnapIndex.current + 1,\n            snapPointsPixels.length - 1\n          );\n          return nextIndex;\n        }\n\n        let closestIndex = 0;\n        let minDistance = Math.abs(currentY - snapPointsPixels[0]);\n\n        for (let i = 1; i < snapPointsPixels.length; i++) {\n          const distance = Math.abs(currentY - snapPointsPixels[i]);\n          if (distance < minDistance) {\n            minDistance = distance;\n            closestIndex = i;\n          }\n        }\n\n        return closestIndex;\n      },\n      [snapPointsPixels]\n    );\n\n    const panResponder = React.useMemo(() => {\n      let startY = 0;\n      const maxDragPoint = snapPointsPixels.length\n        ? snapPointsPixels[snapPointsPixels.length - 1]\n        : 0;\n\n      return PanResponder.create({\n        onStartShouldSetPanResponder: () =>\n          !isClosing.current && !isAnimating.current,\n        onMoveShouldSetPanResponder: (_, { dy }) =>\n          !isClosing.current &&\n          !isAnimating.current &&\n          Math.abs(dy) > DRAG.THRESHOLD,\n\n        onPanResponderGrant: (_, { y0 }) => {\n          startY = y0;\n          translateY.stopAnimation();\n          isAnimating.current = false;\n        },\n\n        onPanResponderMove: (_, { dy }) => {\n          if (isClosing.current) return;\n\n          const currentSnapY = snapPointsPixels[activeSnapIndex.current];\n          let newY = currentSnapY + dy;\n\n          if (newY < maxDragPoint) {\n            const overscroll = maxDragPoint - newY;\n            const resistedOverscroll =\n              -Math.log10(1 + overscroll * DRAG.RESISTANCE) * 10;\n            newY = maxDragPoint + resistedOverscroll;\n          }\n\n          translateY.setValue(newY);\n        },\n\n        onPanResponderRelease: (_, { dy, vy }) => {\n          if (isClosing.current) return;\n\n          const dragDirection = dy > 0 ? \"down\" : \"up\";\n          const currentY = snapPointsPixels[activeSnapIndex.current] + dy;\n          const absVelocity = Math.abs(vy);\n\n          const targetIndex = getTargetSnapIndex(\n            currentY,\n            absVelocity,\n            dragDirection\n          );\n\n          if (targetIndex === -1) {\n            animateClose();\n          } else {\n            animateToSnapPoint(targetIndex, vy);\n          }\n        },\n      });\n    }, [\n      snapPointsPixels,\n      animateClose,\n      animateToSnapPoint,\n      getTargetSnapIndex,\n    ]);\n\n    const contextValue = React.useMemo(\n      () => ({\n        close: animateClose,\n        snapTo: animateToSnapPoint,\n        currentSnapIndex: activeSnapIndex.current,\n        snapPoints,\n        isClosing: isClosing.current,\n        isAnimating: isAnimating.current,\n        position: translateY,\n      }),\n      [animateClose, animateToSnapPoint, snapPoints, translateY]\n    );\n\n    const renderContent = React.useCallback(\n      () => (\n        <View className=\"flex-1\">\n          <Animated.View\n            style={[styles.backdrop, { opacity: backdropOpacity }]}\n          >\n            {closeOnBackdropPress && (\n              <TouchableWithoutFeedback onPress={handleBackdropPress}>\n                <View style={StyleSheet.absoluteFillObject} />\n              </TouchableWithoutFeedback>\n            )}\n          </Animated.View>\n\n          <Animated.View\n            style={[styles.drawerContainer, { transform: [{ translateY }] }]}\n            className={cn(\n              \"absolute bottom-0 left-0 right-0 bg-popover rounded-t-xl overflow-hidden\",\n              Platform.OS === \"ios\" ? \"ios:shadow-xl\" : \"android:elevation-24\",\n              contentClassName\n            )}\n          >\n\n            <View {...panResponder.panHandlers}>\n              <View className=\"w-full items-center py-2\">\n                <View className=\"w-10 h-1 rounded-full bg-muted-foreground/30\" />\n              </View>\n\n              {title && (\n                <View className=\"px-4 pt-1 pb-3 border-b border-border\">\n                  <Text className=\"text-xl font-medium text-center text-foreground\">\n                    {title}\n                  </Text>\n                </View>\n              )}\n            </View>\n\n            <SafeAreaView className=\"flex-1\" edges={[\"bottom\"]}>\n              <View ref={ref} className=\"flex-1\">\n                {children}\n              </View>\n            </SafeAreaView>\n          </Animated.View>\n        </View>\n      ),\n      [\n        animateClose,\n        backdropOpacity,\n        closeOnBackdropPress,\n        contentClassName,\n        panResponder.panHandlers,\n        title,\n        translateY,\n        children,\n        ref,\n      ]\n    );\n\n    if (!isVisible) return null;\n\n    return (\n      <DrawerContext.Provider value={contextValue}>\n        <Modal\n          visible={isVisible}\n          transparent\n          animationType=\"none\"\n          statusBarTranslucent\n          onRequestClose={disableBackHandler ? undefined : animateClose}\n        >\n          {avoidKeyboard && Platform.OS === \"ios\" ? (\n            <KeyboardAvoidingView\n              behavior=\"padding\"\n              style={{ flex: 1 }}\n              keyboardVerticalOffset={10}\n            >\n              {renderContent()}\n            </KeyboardAvoidingView>\n          ) : (\n            renderContent()\n          )}\n        </Modal>\n      </DrawerContext.Provider>\n    );\n  }\n);\n\nconst styles = StyleSheet.create({\n  backdrop: {\n    ...StyleSheet.absoluteFillObject,\n    backgroundColor: \"rgba(0, 0, 0, 0.4)\",\n  },\n  drawerContainer: {\n    height: SCREEN_HEIGHT,\n    shadowColor: \"#000\",\n    shadowOffset: { width: 0, height: -3 },\n    shadowOpacity: 0.15,\n    shadowRadius: 8,\n    elevation: 24,\n  },\n});\n\nDrawer.displayName = \"Drawer\";\n\nexport { Drawer };\n",
      "type": "registry:ui"
    }
  ],
  "changelog": [],
  "customUsage": "import { Drawer } from \"@/components/ui/drawer\";\nimport * as React from \"react\";\nimport {\n    Text,\n    View\n} from \"react-native\";\n\nexport default function DrawerExampleScreen() {\n    const [drawerOpen, setDrawerOpen] = React.useState(false);\n\n    return (\n        <Drawer\n            open={drawerOpen}\n            onClose={closeBasicDrawer}\n            title=\"Drawer Example\"\n            size={[0.4, 0.8]}\n            initialSnapIndex={0}\n        >\n            <View className=\"p-4\">\n                <Text className=\"text-base mb-4 text-foreground\">\n                    This is an example of drawer content. You can drag this\n                    drawer up to see more content.\n                </Text>\n\n                <View className=\"h-px bg-border w-full my-4\" />\n\n                <Text className=\"text-sm text-muted-foreground\">\n                    Try dragging this drawer up and down.\n                </Text>\n            </View>\n        </Drawer>\n    );\n}\n",
  "customPreview": "import { ThemeToggle } from \"@/components/theme-toggle\";\nimport { Button } from \"@/components/ui/button\";\nimport { Drawer, useDrawer } from \"@/components/ui/drawer\";\nimport { Input } from \"@/components/ui/input\";\nimport { Ionicons } from \"@expo/vector-icons\";\nimport { Stack } from \"expo-router\";\nimport * as React from \"react\";\nimport {\n    Keyboard,\n    KeyboardAvoidingView,\n    Platform,\n    ScrollView,\n    Text,\n    TouchableWithoutFeedback,\n    View,\n} from \"react-native\";\nimport { SafeAreaView } from \"react-native-safe-area-context\";\n\ntype IoniconName = React.ComponentProps<typeof Ionicons>[\"name\"];\n\nconst FeedbackForm = () => {\n    const [selectedRating, setSelectedRating] = React.useState<number | null>(\n        null\n    );\n    const [feedbackText, setFeedbackText] = React.useState(\"\");\n    const { close } = useDrawer();\n\n    const handleSubmit = () => {\n        console.log({ rating: selectedRating, feedback: feedbackText });\n        close();\n    };\n\n    return (\n        <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>\n            <ScrollView className=\"p-4\">\n                <Text className=\"text-base mb-4 text-foreground\">\n                    We'd love to hear your thoughts on our application.\n                </Text>\n\n                <View className=\"mb-4\">\n                    <Text className=\"text-sm font-medium mb-2 text-foreground\">\n                        How would you rate your experience?\n                    </Text>\n                    <View className=\"flex-row justify-between\">\n                        {[1, 2, 3, 4, 5].map((rating) => (\n                            <Button\n                                key={rating}\n                                variant={selectedRating === rating ? \"default\" : \"outline\"}\n                                size=\"icon\"\n                                className=\"w-10 h-10 rounded-full\"\n                                onPress={() => setSelectedRating(rating)}\n                            >\n                                <Text\n                                    className={\n                                        selectedRating === rating\n                                            ? \"text-primary-foreground\"\n                                            : \"text-foreground\"\n                                    }\n                                >\n                                    {rating}\n                                </Text>\n                            </Button>\n                        ))}\n                    </View>\n                </View>\n\n                <View className=\"mb-4\">\n                    <Text className=\"text-sm font-medium mb-2 text-foreground\">\n                        Your comments\n                    </Text>\n                    <Input\n                        multiline\n                        textAlignVertical=\"top\"\n                        numberOfLines={4}\n                        className=\"h-24 py-2\"\n                        placeholder=\"Type your feedback here...\"\n                        value={feedbackText}\n                        onChangeText={setFeedbackText}\n                    />\n                </View>\n\n                <Button onPress={handleSubmit}>\n                    <Text className=\"text-primary-foreground\">Submit</Text>\n                </Button>\n            </ScrollView>\n        </TouchableWithoutFeedback>\n    );\n};\n\nconst SettingsList = () => {\n    const [language, setLanguage] = React.useState(\"\");\n\n    return (\n        <ScrollView>\n            {[\n                { icon: \"person-outline\" as IoniconName, label: \"My Account\" },\n                {\n                    icon: \"notifications-outline\" as IoniconName,\n                    label: \"Notifications\",\n                },\n                { icon: \"lock-closed-outline\" as IoniconName, label: \"Privacy\" },\n                { icon: \"moon-outline\" as IoniconName, label: \"Theme\" },\n                {\n                    icon: \"globe-outline\" as IoniconName,\n                    label: \"Language\",\n                    hasSelect: true,\n                },\n                { icon: \"help-circle-outline\" as IoniconName, label: \"Help & Support\" },\n                { icon: \"information-circle-outline\" as IoniconName, label: \"About\" },\n                { icon: \"log-out-outline\" as IoniconName, label: \"Logout\" },\n            ].map((item, index) => (\n                <View key={index}>\n                    <Button\n                        variant=\"ghost\"\n                        className=\"flex-row h-14 items-center px-4 py-2 border-b border-border rounded-none justify-start\"\n                    >\n                        <Ionicons\n                            name={item.icon}\n                            size={22}\n                            color=\"#6B7280\"\n                            style={{ marginRight: 12 }}\n                        />\n                        <Text className=\"text-base text-foreground\">{item.label}</Text>\n                        <Ionicons\n                            name=\"chevron-forward\"\n                            size={16}\n                            color=\"#6B7280\"\n                            style={{ marginLeft: \"auto\" }}\n                        />\n                    </Button>\n                </View>\n            ))}\n        </ScrollView>\n    );\n};\n\n// Composant pour le grand drawer avec contenu complexe\nconst LargeDrawerContent = () => {\n    const { close } = useDrawer();\n\n    return (\n        <ScrollView contentContainerStyle={{ paddingBottom: 200 }}>\n            <View className=\"p-4\">\n                <Text className=\"text-xl font-bold mb-4 text-foreground\">\n                    Section Title\n                </Text>\n\n                <Text className=\"text-base mb-4 text-foreground\">\n                    This drawer has three snap points and opens initially at the middle\n                    point. Drag it up to see all content, or down for a reduced view.\n                </Text>\n\n                <View className=\"bg-accent/20 rounded-lg p-4 mb-4\">\n                    <Text className=\"text-sm font-medium text-foreground mb-2\">Tip</Text>\n                    <Text className=\"text-sm text-muted-foreground\">\n                        For a better user experience, the drawer uses fluid animations and\n                        progressive resistance when you try to drag beyond the limits.\n                    </Text>\n                </View>\n\n                <View className=\"h-px bg-border w-full my-4\" />\n\n                <Text className=\"text-base font-bold mb-2 text-foreground\">\n                    Features:\n                </Text>\n\n                {[\n                    \"Multiple configurable snap points\",\n                    \"Fluid spring animations\",\n                    \"Responsive drag behavior\",\n                    \"Close by dragging down or touching the backdrop\",\n                    \"Support for complex scrollable content\",\n                    \"Easy customization via classes\",\n                ].map((feature, index) => (\n                    <View key={index} className=\"flex-row items-center py-2\">\n                        <View className=\"w-2 h-2 rounded-full bg-primary mr-2\" />\n                        <Text className=\"text-base text-foreground\">{feature}</Text>\n                    </View>\n                ))}\n\n                <View className=\"h-px bg-border w-full my-4\" />\n\n                <Text className=\"text-base font-bold mb-2 text-foreground\">\n                    Demo Content:\n                </Text>\n\n                {Array(15)\n                    .fill(0)\n                    .map((_, i) => (\n                        <View key={i} className=\"py-3 border-b border-border\">\n                            <Text className=\"text-base text-foreground\">\n                                Content item {i + 1}\n                            </Text>\n                            <Text className=\"text-sm text-muted-foreground\">\n                                Additional description for this content item\n                            </Text>\n                        </View>\n                    ))}\n\n                <Button variant=\"outline\" className=\"mt-6 mb-10\" onPress={close}>\n                    <Text className=\"text-foreground\">Close Drawer</Text>\n                </Button>\n            </View>\n        </ScrollView>\n    );\n};\n\nexport default function DrawerExampleScreen() {\n    const [drawerOpen, setDrawerOpen] = React.useState(false);\n    const [feedbackDrawerOpen, setFeedbackDrawerOpen] = React.useState(false);\n    const [settingsDrawerOpen, setSettingsDrawerOpen] = React.useState(false);\n    const [largeDrawerOpen, setLargeDrawerOpen] = React.useState(false);\n\n    // Simplifier l'implémentation pour éviter le double-tap\n    const openBasicDrawer = React.useCallback(() => setDrawerOpen(true), []);\n    const closeBasicDrawer = React.useCallback(() => setDrawerOpen(false), []);\n\n    const openFeedbackDrawer = React.useCallback(\n        () => setFeedbackDrawerOpen(true),\n        []\n    );\n    const closeFeedbackDrawer = React.useCallback(\n        () => setFeedbackDrawerOpen(false),\n        []\n    );\n\n    const openSettingsDrawer = React.useCallback(\n        () => setSettingsDrawerOpen(true),\n        []\n    );\n    const closeSettingsDrawer = React.useCallback(\n        () => setSettingsDrawerOpen(false),\n        []\n    );\n\n    const openLargeDrawer = React.useCallback(() => setLargeDrawerOpen(true), []);\n    const closeLargeDrawer = React.useCallback(\n        () => setLargeDrawerOpen(false),\n        []\n    );\n\n    return (\n        <>\n            <Stack.Screen\n                options={{\n                    title: \"Drawer\",\n                    headerRight: () => <ThemeToggle />,\n                }}\n            />\n\n            <SafeAreaView className=\"flex-1 bg-background\" edges={[\"bottom\"]}>\n                <KeyboardAvoidingView\n                    behavior={Platform.OS === \"ios\" ? \"padding\" : \"height\"}\n                    style={{ flex: 1 }}\n                    keyboardVerticalOffset={100}\n                >\n                    <ScrollView className=\"p-4\">\n                        <View className=\"mb-6\">\n                            <Text className=\"text-2xl font-bold mb-2 text-foreground\">\n                                Drawer\n                            </Text>\n                            <Text className=\"text-base mb-6 text-muted-foreground\">\n                                A bottom sheet component that can be dragged up and down with\n                                snap points.\n                            </Text>\n                        </View>\n\n                        <View className=\"mb-8\">\n                            <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                                Basic Drawer\n                            </Text>\n                            <Button onPress={openBasicDrawer}>\n                                <Text className=\"text-primary-foreground\">Open Drawer</Text>\n                            </Button>\n\n                            <Drawer\n                                open={drawerOpen}\n                                onClose={closeBasicDrawer}\n                                title=\"Drawer Example\"\n                                size={[0.4, 0.8]}\n                                initialSnapIndex={0}\n                            >\n                                <View className=\"p-4\">\n                                    <Text className=\"text-base mb-4 text-foreground\">\n                                        This is an example of drawer content. You can drag this\n                                        drawer up to see more content.\n                                    </Text>\n\n                                    <View className=\"h-px bg-border w-full my-4\" />\n\n                                    <Text className=\"text-sm text-muted-foreground\">\n                                        Try dragging this drawer up and down.\n                                    </Text>\n                                </View>\n                            </Drawer>\n                        </View>\n\n                        <View className=\"mb-8\">\n                            <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                                Drawer with Form\n                            </Text>\n                            <Button\n                                variant=\"outline\"\n                                onPress={openFeedbackDrawer}\n                                className=\"bg-primary/10\"\n                            >\n                                <Ionicons\n                                    name=\"chatbubble-outline\"\n                                    size={20}\n                                    color=\"#4F46E5\"\n                                    style={{ marginRight: 8 }}\n                                />\n                                <Text className=\"text-base font-medium text-primary\">\n                                    Leave Feedback\n                                </Text>\n                            </Button>\n\n                            <Drawer\n                                open={feedbackDrawerOpen}\n                                onClose={closeFeedbackDrawer}\n                                title=\"Feedback\"\n                                size=\"medium\"\n                                initialSnapIndex={0}\n                            >\n                                <FeedbackForm />\n                            </Drawer>\n                        </View>\n\n                        <View className=\"mb-8\">\n                            <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                                Drawer with List\n                            </Text>\n                            <Button\n                                variant=\"outline\"\n                                onPress={openSettingsDrawer}\n                                className=\"justify-between\"\n                            >\n                                <View className=\"flex-row items-center\">\n                                    <Ionicons\n                                        name=\"settings-outline\"\n                                        size={20}\n                                        color=\"#6B7280\"\n                                        style={{ marginRight: 8 }}\n                                    />\n                                    <Text className=\"text-base text-foreground\">Settings</Text>\n                                </View>\n                                <Ionicons name=\"chevron-up\" size={16} color=\"#6B7280\" />\n                            </Button>\n\n                            <Drawer\n                                open={settingsDrawerOpen}\n                                onClose={closeSettingsDrawer}\n                                title=\"Settings\"\n                                size=\"large\"\n                                initialSnapIndex={0}\n                            >\n                                <SettingsList />\n                            </Drawer>\n                        </View>\n\n                        <View className=\"mb-8\">\n                            <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                                Large Drawer with Complex Content\n                            </Text>\n                            <Button variant=\"secondary\" onPress={openLargeDrawer}>\n                                <Text className=\"text-accent-foreground\">\n                                    View More Information\n                                </Text>\n                            </Button>\n\n                            <Drawer\n                                open={largeDrawerOpen}\n                                onClose={closeLargeDrawer}\n                                title=\"Detailed Information\"\n                                size={[0.3, 0.7, 0.95]}\n                                initialSnapIndex={1}\n                            >\n                                <LargeDrawerContent />\n                            </Drawer>\n                        </View>\n                    </ScrollView>\n                </KeyboardAvoidingView>\n            </SafeAreaView>\n        </>\n    );\n}\n"
}