{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "date-time-picker",
  "type": "registry:ui",
  "title": "Date-time-picker",
  "description": "A date-time-picker component for React Native applications.",
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/date-time-picker/date-time-picker.tsx",
      "content": "import { Calendar } from \"@/components/ui/calendar\";\nimport { cn } from \"@/lib/utils\";\nimport { Ionicons } from \"@expo/vector-icons\";\nimport { format } from \"date-fns\";\nimport { enUS } from \"date-fns/locale\";\nimport * as React from \"react\";\nimport { Animated, Modal, Pressable, Text, View } from \"react-native\";\n\ninterface DateRange {\n  from: Date;\n  to: Date;\n}\n\ninterface TimeConfig {\n  minuteInterval?: 1 | 5 | 10 | 15 | 30;\n  minTime?: string;\n  maxTime?: string;\n  disabledTimes?: string[];\n}\n\ninterface DateTimePickerProps {\n  mode?: \"single\" | \"range\" | \"datetime\";\n  value?: Date | Date[] | DateRange;\n  onValueChange?: (value: Date | Date[] | DateRange | undefined) => void;\n  placeholder?: string;\n  disabled?: boolean;\n  className?: string;\n  showOutsideDays?: boolean;\n  disabledDates?: (date: Date) => boolean;\n  disableWeekends?: boolean;\n  fromDate?: Date;\n  toDate?: Date;\n  timeConfig?: TimeConfig;\n  firstDayOfWeek?: 0 | 1;\n  enableQuickMonthYear?: boolean;\n  variant?: \"default\" | \"outline\";\n  size?: \"sm\" | \"md\" | \"lg\";\n}\n\nconst isDateRange = (value: any): value is DateRange => {\n  return value && typeof value === \"object\" && \"from\" in value && \"to\" in value;\n};\n\nconst formatDisplayValue = (\n  value: Date | Date[] | DateRange | undefined,\n  mode: \"single\" | \"range\" | \"datetime\",\n  placeholder: string\n): string => {\n  if (!value) return placeholder;\n\n  switch (mode) {\n    case \"single\":\n      if (value instanceof Date) {\n        return format(value, \"PPP\", { locale: enUS });\n      }\n      break;\n    case \"datetime\":\n      if (value instanceof Date) {\n        return format(value, \"PPP 'at' HH:mm\", { locale: enUS });\n      }\n      break;\n    case \"range\":\n      if (isDateRange(value)) {\n        const fromFormatted = format(value.from, \"PP\", { locale: enUS });\n        const toFormatted = format(value.to, \"PP\", { locale: enUS });\n        return `${fromFormatted} - ${toFormatted}`;\n      }\n      break;\n  }\n  return placeholder;\n};\n\nconst getInputIcon = (mode: \"single\" | \"range\" | \"datetime\") => {\n  switch (mode) {\n    case \"datetime\":\n      return \"calendar-outline\";\n    case \"range\":\n      return \"calendar-outline\";\n    default:\n      return \"calendar-outline\";\n  }\n};\n\nconst DateTimePicker = React.forwardRef<View, DateTimePickerProps>(\n  (\n    {\n      mode = \"single\",\n      value,\n      onValueChange,\n      placeholder = \"Select date\",\n      disabled = false,\n      className,\n      showOutsideDays = true,\n      disabledDates,\n      disableWeekends = false,\n      fromDate,\n      toDate,\n      timeConfig,\n      firstDayOfWeek = 1,\n      enableQuickMonthYear = false,\n      variant = \"default\",\n      size = \"md\",\n      ...props\n    },\n    ref\n  ) => {\n    const [isOpen, setIsOpen] = React.useState(false);\n    const [isFocused, setIsFocused] = React.useState(false);\n    const fadeAnim = React.useRef(new Animated.Value(0)).current;\n    const scaleAnim = React.useRef(new Animated.Value(0.95)).current;\n\n    const displayValue = formatDisplayValue(value, mode, placeholder);\n    const iconName = getInputIcon(mode);\n\n    const sizeClasses = {\n      sm: \"h-10 px-3 text-sm\",\n      md: \"h-12 px-3 text-base\",\n      lg: \"h-14 px-4 text-lg\",\n    };\n\n    const iconSizes = {\n      sm: 18,\n      md: 20,\n      lg: 22,\n    };\n\n    const openPicker = React.useCallback(() => {\n      if (disabled) return;\n      setIsOpen(true);\n\n      Animated.parallel([\n        Animated.timing(fadeAnim, {\n          toValue: 1,\n          duration: 300,\n          useNativeDriver: true,\n        }),\n        Animated.timing(scaleAnim, {\n          toValue: 1,\n          duration: 300,\n          useNativeDriver: true,\n        }),\n      ]).start();\n    }, [disabled, fadeAnim, scaleAnim]);\n\n    const closePicker = React.useCallback(() => {\n      Animated.parallel([\n        Animated.timing(fadeAnim, {\n          toValue: 0,\n          duration: 250,\n          useNativeDriver: true,\n        }),\n        Animated.timing(scaleAnim, {\n          toValue: 0.95,\n          duration: 250,\n          useNativeDriver: true,\n        }),\n      ]).start(() => {\n        setIsOpen(false);\n        setIsFocused(false);\n      });\n    }, [fadeAnim, scaleAnim]);\n\n    const handleSelect = React.useCallback(\n      (selectedValue: Date | Date[] | DateRange | undefined) => {\n        onValueChange?.(selectedValue);\n        if (\n          mode === \"single\" ||\n          (mode === \"range\" &&\n            isDateRange(selectedValue) &&\n            selectedValue.from !== selectedValue.to)\n        ) {\n          closePicker();\n        }\n      },\n      [onValueChange, mode, closePicker]\n    );\n\n    return (\n      <>\n        <Pressable\n          ref={ref}\n          onPress={openPicker}\n          disabled={disabled}\n          className={cn(\n            \"w-full rounded-md border border-input bg-transparent flex-row items-center justify-between\",\n            sizeClasses[size],\n            isFocused ? \"border-ring ring-1 ring-ring\" : \"\",\n            value ? \"border-primary\" : \"\",\n            disabled ? \"opacity-50 cursor-not-allowed\" : \"active:bg-accent/5\",\n            className\n          )}\n          {...props}\n        >\n          <View className=\"ml-3 mr-2\">\n            <Ionicons\n              name={iconName as any}\n              size={iconSizes[size]}\n              color={disabled ? \"#999\" : \"#666\"}\n            />\n          </View>\n          <Text\n            className={cn(\n              \"flex-1\",\n              value ? \"text-primary\" : \"text-muted-foreground\"\n            )}\n            numberOfLines={1}\n          >\n            {displayValue}\n          </Text>\n        </Pressable>\n\n        <Modal\n          visible={isOpen}\n          transparent\n          animationType=\"none\"\n          onRequestClose={closePicker}\n          statusBarTranslucent\n        >\n          <Animated.View\n            style={{\n              flex: 1,\n              justifyContent: \"center\",\n              alignItems: \"center\",\n              backgroundColor: \"rgba(0, 0, 0, 0.4)\",\n              padding: 16,\n              opacity: fadeAnim,\n            }}\n          >\n            <Pressable\n              style={{ flex: 1, width: \"100%\" }}\n              onPress={closePicker}\n            />\n\n            <Animated.View\n              style={{\n                width: \"100%\",\n                maxWidth: 400,\n                transform: [{ scale: scaleAnim }],\n              }}\n            >\n              <View className=\"bg-background rounded-t-2xl border-b border-border\">\n                <View className=\"flex-row justify-between items-center px-4 py-3\">\n                  <Pressable\n                    onPress={closePicker}\n                    className=\"opacity-60 active:opacity-100 py-1\"\n                  >\n                    <Text className=\"text-primary text-base\">Cancel</Text>\n                  </Pressable>\n\n                  <Text className=\"text-lg font-semibold text-foreground\">\n                    {mode === \"range\"\n                      ? \"Select dates\"\n                      : mode === \"datetime\"\n                        ? \"Select date & time\"\n                        : \"Select date\"}\n                  </Text>\n\n                  <Pressable\n                    onPress={closePicker}\n                    className=\"opacity-60 active:opacity-100 py-1\"\n                  >\n                    <Text className=\"text-primary font-semibold text-base\">\n                      Done\n                    </Text>\n                  </Pressable>\n                </View>\n              </View>\n\n              <Calendar\n                mode={mode}\n                selected={value}\n                onSelect={handleSelect}\n                showOutsideDays={showOutsideDays}\n                disabled={disabledDates}\n                disableWeekends={disableWeekends}\n                fromDate={fromDate}\n                toDate={toDate}\n                timeConfig={timeConfig}\n                firstDayOfWeek={firstDayOfWeek}\n                enableQuickMonthYear={enableQuickMonthYear}\n                showTime={mode === \"datetime\"}\n                className=\"rounded-none rounded-b-2xl\"\n              />\n            </Animated.View>\n\n            <Pressable\n              style={{ flex: 1, width: \"100%\" }}\n              onPress={closePicker}\n            />\n          </Animated.View>\n        </Modal>\n      </>\n    );\n  }\n);\n\nDateTimePicker.displayName = \"DateTimePicker\";\n\nexport { DateTimePicker, type DateTimePickerProps };\n",
      "type": "registry:ui"
    }
  ],
  "changelog": [],
  "customUsage": "import { DateTimePicker } from \"@/components/ui/date-time-picker\";\nimport * as React from \"react\";\n\ninterface DateRange {\n    from: Date;\n    to: Date;\n}\n\nexport default function DateTimePickerExample() {\n    const [singleDate, setSingleDate] = React.useState<Date | undefined>(\n        undefined\n    );\n\n    const handleSingleDateChange = (\n        value: Date | Date[] | DateRange | undefined\n    ) => {\n        if (value instanceof Date || value === undefined) {\n            setSingleDate(value);\n        }\n    };\n\n    return (\n        <DateTimePicker\n            mode=\"single\"\n            value={singleDate}\n            onValueChange={handleSingleDateChange}\n            placeholder=\"Select a date\"\n            enableQuickMonthYear={true}\n        />\n    );\n}\n",
  "customPreview": "import { Button } from \"@/components/ui/button\";\nimport { DateTimePicker } from \"@/components/ui/date-time-picker\";\nimport { addDays, format } from \"date-fns\";\nimport * as React from \"react\";\nimport {\n    Alert,\n    KeyboardAvoidingView,\n    Platform,\n    ScrollView,\n    Text,\n    View,\n} from \"react-native\";\nimport { SafeAreaView } from \"react-native-safe-area-context\";\n\ninterface DateRange {\n    from: Date;\n    to: Date;\n}\n\nexport default function DateTimePickerExample() {\n    const [singleDate, setSingleDate] = React.useState<Date | undefined>(\n        undefined\n    );\n\n    const [dateTimeValue, setDateTimeValue] = React.useState<Date | undefined>(\n        new Date()\n    );\n\n    const [dateRange, setDateRange] = React.useState<DateRange | undefined>(\n        undefined\n    );\n\n    const [restrictedDate, setRestrictedDate] = React.useState<Date | undefined>(\n        undefined\n    );\n\n    const [businessDate, setBusinessDate] = React.useState<Date | undefined>(\n        undefined\n    );\n\n    const [smallDate, setSmallDate] = React.useState<Date | undefined>(undefined);\n    const [mediumDate, setMediumDate] = React.useState<Date | undefined>(undefined);\n    const [largeDate, setLargeDate] = React.useState<Date | undefined>(undefined);\n    const [customTimeDate, setCustomTimeDate] = React.useState<Date | undefined>(undefined);\n\n    const isWeekend = (date: Date) => {\n        const day = date.getDay();\n        return day === 0 || day === 6;\n    };\n\n    const isPastDate = (date: Date) => {\n        const today = new Date();\n        today.setHours(0, 0, 0, 0);\n        return date < today;\n    };\n\n    const showSelectedValue = (label: string, value: any) => {\n        let message = `${label}:\\n`;\n\n        if (!value) {\n            message += \"No date selected\";\n        } else if (value instanceof Date) {\n            message += format(value, \"PPP 'at' HH:mm\");\n        } else if (value.from && value.to) {\n            message += `From: ${format(value.from, \"PPP\")}\\nTo: ${format(\n                value.to,\n                \"PPP\"\n            )}`;\n        }\n\n        Alert.alert(\"Selected Value\", message);\n    };\n\n    const handleSingleDateChange = (\n        value: Date | Date[] | DateRange | undefined\n    ) => {\n        if (value instanceof Date || value === undefined) {\n            setSingleDate(value);\n        }\n    };\n\n    const handleDateTimeChange = (\n        value: Date | Date[] | DateRange | undefined\n    ) => {\n        if (value instanceof Date || value === undefined) {\n            setDateTimeValue(value);\n        }\n    };\n\n    const handleDateRangeChange = (\n        value: Date | Date[] | DateRange | undefined\n    ) => {\n        if (\n            value &&\n            typeof value === \"object\" &&\n            \"from\" in value &&\n            \"to\" in value\n        ) {\n            setDateRange(value as DateRange);\n        } else if (value === undefined) {\n            setDateRange(undefined);\n        }\n    };\n\n    const handleRestrictedDateChange = (\n        value: Date | Date[] | DateRange | undefined\n    ) => {\n        if (value instanceof Date || value === undefined) {\n            setRestrictedDate(value);\n        }\n    };\n\n    const handleBusinessDateChange = (\n        value: Date | Date[] | DateRange | undefined\n    ) => {\n        if (value instanceof Date || value === undefined) {\n            setBusinessDate(value);\n        }\n    };\n\n    const handleSmallDateChange = (value: Date | Date[] | DateRange | undefined) => {\n        if (value instanceof Date || value === undefined) {\n            setSmallDate(value);\n        }\n    };\n\n    const handleMediumDateChange = (value: Date | Date[] | DateRange | undefined) => {\n        if (value instanceof Date || value === undefined) {\n            setMediumDate(value);\n        }\n    };\n\n    const handleLargeDateChange = (value: Date | Date[] | DateRange | undefined) => {\n        if (value instanceof Date || value === undefined) {\n            setLargeDate(value);\n        }\n    };\n\n    const handleCustomTimeChange = (value: Date | Date[] | DateRange | undefined) => {\n        if (value instanceof Date || value === undefined) {\n            setCustomTimeDate(value);\n        }\n    };\n\n    return (\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\n                    className=\"p-4\"\n                    keyboardShouldPersistTaps=\"handled\"\n                    keyboardDismissMode=\"on-drag\"\n                >\n                    <View className=\"mb-6\">\n                        <Text className=\"text-2xl font-bold mb-2 text-foreground\">\n                            Date Time Picker\n                        </Text>\n                        <Text className=\"text-base mb-6 text-muted-foreground\">\n                            A combination of Input and Calendar components for selecting\n                            dates and times with an input-like interface.\n                        </Text>\n                    </View>\n\n                    {/* Single Date Picker */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-2 text-foreground\">\n                            Single Date\n                        </Text>\n                        <Text className=\"text-sm mb-4 text-muted-foreground\">\n                            Select a single date with a clean input interface.\n                        </Text>\n                        <DateTimePicker\n                            mode=\"single\"\n                            value={singleDate}\n                            onValueChange={handleSingleDateChange}\n                            placeholder=\"Select a date\"\n                            enableQuickMonthYear={true}\n                        />\n                        <Button\n                            variant=\"outline\"\n                            className=\"mt-2\"\n                            onPress={() => showSelectedValue(\"Single Date\", singleDate)}\n                        >\n                            <Text className=\"text-foreground\">Show Selected Value</Text>\n                        </Button>\n                    </View>\n\n                    {/* Date Time Picker */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-2 text-foreground\">\n                            Date & Time\n                        </Text>\n                        <Text className=\"text-sm mb-4 text-muted-foreground\">\n                            Select both date and time in one picker.\n                        </Text>\n                        <DateTimePicker\n                            mode=\"datetime\"\n                            value={dateTimeValue}\n                            onValueChange={handleDateTimeChange}\n                            placeholder=\"Select date and time\"\n                            enableQuickMonthYear={true}\n                            timeConfig={{\n                                minuteInterval: 15,\n                            }}\n                        />\n                        <Button\n                            variant=\"outline\"\n                            className=\"mt-2\"\n                            onPress={() => showSelectedValue(\"Date & Time\", dateTimeValue)}\n                        >\n                            <Text className=\"text-foreground\">Show Selected Value</Text>\n                        </Button>\n                    </View>\n\n                    {/* Date Range Picker */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-2 text-foreground\">\n                            Date Range\n                        </Text>\n                        <Text className=\"text-sm mb-4 text-muted-foreground\">\n                            Select a range of dates for bookings, events, etc.\n                        </Text>\n                        <DateTimePicker\n                            mode=\"range\"\n                            value={dateRange}\n                            onValueChange={handleDateRangeChange}\n                            placeholder=\"Select date range\"\n                            enableQuickMonthYear={true}\n                        />\n                        <Button\n                            variant=\"outline\"\n                            className=\"mt-2\"\n                            onPress={() => showSelectedValue(\"Date Range\", dateRange)}\n                        >\n                            <Text className=\"text-foreground\">Show Selected Value</Text>\n                        </Button>\n                    </View>\n\n                    {/* Restricted Date Picker */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-2 text-foreground\">\n                            Restricted Dates\n                        </Text>\n                        <Text className=\"text-sm mb-4 text-muted-foreground\">\n                            Only future dates allowed (no past dates).\n                        </Text>\n                        <DateTimePicker\n                            mode=\"single\"\n                            value={restrictedDate}\n                            onValueChange={handleRestrictedDateChange}\n                            placeholder=\"Select future date\"\n                            fromDate={new Date()}\n                            disabledDates={isPastDate}\n                            enableQuickMonthYear={true}\n                        />\n                        <Button\n                            variant=\"outline\"\n                            className=\"mt-2\"\n                            onPress={() =>\n                                showSelectedValue(\"Restricted Date\", restrictedDate)\n                            }\n                        >\n                            <Text className=\"text-foreground\">Show Selected Value</Text>\n                        </Button>\n                    </View>\n\n                    {/* Business Days Only */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-2 text-foreground\">\n                            Business Days Only\n                        </Text>\n                        <Text className=\"text-sm mb-4 text-muted-foreground\">\n                            Weekends are disabled for business appointments.\n                        </Text>\n                        <DateTimePicker\n                            mode=\"single\"\n                            value={businessDate}\n                            onValueChange={handleBusinessDateChange}\n                            placeholder=\"Select business day\"\n                            disableWeekends={true}\n                            disabledDates={isWeekend}\n                            enableQuickMonthYear={true}\n                        />\n                        <Button\n                            variant=\"outline\"\n                            className=\"mt-2\"\n                            onPress={() => showSelectedValue(\"Business Date\", businessDate)}\n                        >\n                            <Text className=\"text-foreground\">Show Selected Value</Text>\n                        </Button>\n                    </View>\n\n                    {/* Different Sizes */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                            Different Sizes\n                        </Text>\n\n                        <View className=\"mb-4\">\n                            <Text className=\"text-sm font-medium mb-2 text-foreground\">\n                                Small Size\n                            </Text>\n                            <DateTimePicker\n                                mode=\"single\"\n                                size=\"sm\"\n                                value={smallDate}\n                                onValueChange={handleSmallDateChange}\n                                placeholder=\"Small date picker\"\n                            />\n                        </View>\n\n                        <View className=\"mb-4\">\n                            <Text className=\"text-sm font-medium mb-2 text-foreground\">\n                                Medium Size (Default)\n                            </Text>\n                            <DateTimePicker\n                                mode=\"single\"\n                                size=\"md\"\n                                value={mediumDate}\n                                onValueChange={handleMediumDateChange}\n                                placeholder=\"Medium date picker\"\n                            />\n                        </View>\n\n                        <View className=\"mb-4\">\n                            <Text className=\"text-sm font-medium mb-2 text-foreground\">\n                                Large Size\n                            </Text>\n                            <DateTimePicker\n                                mode=\"single\"\n                                size=\"lg\"\n                                value={largeDate}\n                                onValueChange={handleLargeDateChange}\n                                placeholder=\"Large date picker\"\n                            />\n                        </View>\n                    </View>\n\n                    {/* Disabled State */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-2 text-foreground\">\n                            Disabled State\n                        </Text>\n                        <Text className=\"text-sm mb-4 text-muted-foreground\">\n                            Disabled picker that cannot be interacted with.\n                        </Text>\n                        <DateTimePicker\n                            mode=\"single\"\n                            disabled={true}\n                            placeholder=\"This picker is disabled\"\n                            value={new Date()}\n                        />\n                    </View>\n\n                    {/* Custom Time Config */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-2 text-foreground\">\n                            Custom Time Configuration\n                        </Text>\n                        <Text className=\"text-sm mb-4 text-muted-foreground\">\n                            DateTime picker with 30-minute intervals.\n                        </Text>\n                        <DateTimePicker\n                            mode=\"datetime\"\n                            value={customTimeDate}\n                            onValueChange={handleCustomTimeChange}\n                            placeholder=\"Select with 30min intervals\"\n                            timeConfig={{\n                                minuteInterval: 30,\n                            }}\n                            enableQuickMonthYear={true}\n                        />\n                    </View>\n\n                    {/* Action Buttons */}\n                    <View className=\"mb-8 pt-4 border-t border-border\">\n                        <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                            Quick Actions\n                        </Text>\n\n                        <View className=\"flex-row flex-wrap gap-2\">\n                            <Button\n                                variant=\"outline\"\n                                onPress={() => {\n                                    const today = new Date();\n                                    setSingleDate(today);\n                                    setSmallDate(today);\n                                    setMediumDate(today);\n                                    setLargeDate(today);\n                                }}\n                                className=\"mb-2\"\n                            >\n                                <Text className=\"text-foreground\">Set Today</Text>\n                            </Button>\n\n                            <Button\n                                variant=\"outline\"\n                                onPress={() => {\n                                    const nextWeek = addDays(new Date(), 7);\n                                    setSingleDate(nextWeek);\n                                    setSmallDate(nextWeek);\n                                    setMediumDate(nextWeek);\n                                    setLargeDate(nextWeek);\n                                }}\n                                className=\"mb-2\"\n                            >\n                                <Text className=\"text-foreground\">Set Next Week</Text>\n                            </Button>\n\n                            <Button\n                                variant=\"outline\"\n                                onPress={() => {\n                                    const today = new Date();\n                                    setDateRange({\n                                        from: today,\n                                        to: addDays(today, 7),\n                                    });\n                                }}\n                                className=\"mb-2\"\n                            >\n                                <Text className=\"text-foreground\">Set Week Range</Text>\n                            </Button>\n\n                            <Button\n                                variant=\"destructive\"\n                                onPress={() => {\n                                    setSingleDate(undefined);\n                                    setDateTimeValue(undefined);\n                                    setDateRange(undefined);\n                                    setRestrictedDate(undefined);\n                                    setBusinessDate(undefined);\n                                    setSmallDate(undefined);\n                                    setMediumDate(undefined);\n                                    setLargeDate(undefined);\n                                    setCustomTimeDate(undefined);\n                                }}\n                                className=\"mb-2\"\n                            >\n                                <Text className=\"text-primary-foreground\">Clear All</Text>\n                            </Button>\n                        </View>\n                    </View>\n                </ScrollView>\n            </KeyboardAvoidingView>\n        </SafeAreaView>\n    );\n}\n"
}