{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "calendar",
  "type": "registry:ui",
  "title": "Calendar",
  "description": "A calendar component for React Native applications.",
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/calendar/calendar.tsx",
      "content": "import { cn } from \"@/lib/utils\";\nimport { Ionicons } from \"@expo/vector-icons\";\nimport DateTimePicker from \"@react-native-community/datetimepicker\";\nimport {\n  addMonths,\n  eachDayOfInterval,\n  endOfDay,\n  endOfMonth,\n  format,\n  getMonth,\n  isAfter,\n  isBefore,\n  isSameDay,\n  isSameMonth,\n  isToday,\n  isWithinInterval,\n  setHours,\n  setMinutes,\n  startOfDay,\n  startOfMonth,\n  subMonths,\n} from \"date-fns\";\nimport { enUS } from \"date-fns/locale\";\nimport * as React from \"react\";\nimport {\n  Animated,\n  Dimensions,\n  Modal,\n  Platform,\n  Pressable,\n  Text,\n  View,\n} from \"react-native\";\n\nconst MONTHS = [\n  \"January\",\n  \"February\",\n  \"March\",\n  \"April\",\n  \"May\",\n  \"June\",\n  \"July\",\n  \"August\",\n  \"September\",\n  \"October\",\n  \"November\",\n  \"December\",\n];\n\nconst WEEKDAYS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\ninterface DateRange {\n  from: Date;\n  to: Date;\n}\n\ninterface TimeConfig {\n  minuteInterval?: 1 | 5 | 10 | 15 | 30;\n  minTime?: string; // format \"HH:mm\"\n  maxTime?: string; // format \"HH:mm\"\n  disabledTimes?: string[]; // format [\"HH:mm\"]\n}\n\ninterface CalendarProps {\n  mode?: \"single\" | \"range\" | \"datetime\";\n  selected?: Date | Date[] | DateRange;\n  onSelect?: (date: Date | Date[] | DateRange | undefined) => void;\n  className?: string;\n  showOutsideDays?: boolean;\n  showTime?: boolean;\n  disabled?: (date: Date) => boolean;\n  disableWeekends?: boolean;\n  fromDate?: Date;\n  toDate?: Date;\n  timeConfig?: TimeConfig;\n  firstDayOfWeek?: 0 | 1; // 0 for Sunday, 1 for Monday\n  enableQuickMonthYear?: boolean;\n}\n\nconst SCREEN_WIDTH = Dimensions.get(\"window\").width;\nconst DAY_SIZE = Math.min(Math.floor((SCREEN_WIDTH - 48) / 7), 50);\n\nconst isDateRange = (value: any): value is DateRange => {\n  return value && typeof value === \"object\" && \"from\" in value && \"to\" in value;\n};\n\nconst isInRange = (date: Date, range: DateRange) => {\n  return isWithinInterval(date, { start: range.from, end: range.to });\n};\n\nconst isRangeStart = (date: Date, range: DateRange) => {\n  return isSameDay(date, range.from);\n};\n\nconst isRangeEnd = (date: Date, range: DateRange) => {\n  return isSameDay(date, range.to);\n};\n\nconst CalendarHeader = React.memo(({\n  currentDate,\n  onPrevMonth,\n  onNextMonth,\n  onHeaderPress,\n  enableQuickMonthYear,\n}: {\n  currentDate: Date;\n  onPrevMonth: () => void;\n  onNextMonth: () => void;\n  onHeaderPress?: () => void;\n  enableQuickMonthYear?: boolean;\n}) => (\n  <View className=\"flex-row items-center justify-between mb-4\">\n    <Pressable\n      onPress={onPrevMonth}\n      className=\"p-2 rounded-full bg-muted active:scale-90 transition-transform\"\n    >\n      <Ionicons name=\"chevron-back\" size={24} className=\"color-primary\" />\n    </Pressable>\n\n    {enableQuickMonthYear ? (\n      <Pressable\n        onPress={onHeaderPress}\n        className=\"flex-row items-center space-x-1 px-3 py-2 rounded-lg active:bg-muted\"\n      >\n        <Text className=\"text-xl font-semibold text-foreground\">\n          {format(currentDate, \"MMMM yyyy\", { locale: enUS })}\n        </Text>\n        <Ionicons name=\"chevron-down\" size={20} className=\"color-primary\" />\n      </Pressable>\n    ) : (\n      <Text className=\"text-xl font-semibold text-foreground\">\n        {format(currentDate, \"MMMM yyyy\", { locale: enUS })}\n      </Text>\n    )}\n\n    <Pressable\n      onPress={onNextMonth}\n      className=\"p-2 rounded-full bg-muted active:scale-90 transition-transform\"\n    >\n      <Ionicons name=\"chevron-forward\" size={24} className=\"color-primary\" />\n    </Pressable>\n  </View>\n));\n\nconst WeekdaysRow = React.memo(({ orderedWeekdays }: { orderedWeekdays: string[] }) => (\n  <View className=\"flex-row justify-between mb-2\">\n    {orderedWeekdays.map((day) => (\n      <View\n        key={day}\n        style={{ width: DAY_SIZE }}\n        className=\"items-center justify-center\"\n      >\n        <Text className=\"text-sm font-medium text-muted-foreground\">\n          {day}\n        </Text>\n      </View>\n    ))}\n  </View>\n));\n\nconst CalendarDay = React.memo(({\n  date,\n  currentDate,\n  mode,\n  selected,\n  isSelected,\n  isDisabled,\n  onPress,\n}: {\n  date: Date;\n  currentDate: Date;\n  mode: \"single\" | \"range\" | \"datetime\";\n  selected: Date | Date[] | DateRange | undefined;\n  isSelected: boolean;\n  isDisabled: boolean;\n  onPress: () => void;\n}) => {\n  const isCurrentMonth = isSameMonth(date, currentDate);\n  const isTodayDate = isToday(date);\n\n  let rangeStyles = \"\";\n  if (mode === \"range\" && selected && isDateRange(selected)) {\n    const isInCurrentRange = isInRange(date, selected);\n    const isStart = isRangeStart(date, selected);\n    const isEnd = isRangeEnd(date, selected);\n\n    if (isInCurrentRange) {\n      rangeStyles = \"bg-primary/20\";\n    }\n    if (isStart) {\n      rangeStyles += \" rounded-l-lg\";\n    }\n    if (isEnd) {\n      rangeStyles += \" rounded-r-lg\";\n    }\n    if (isStart || isEnd) {\n      rangeStyles += \" bg-primary\";\n    }\n  }\n\n  return (\n    <Pressable\n      onPress={onPress}\n      disabled={isDisabled}\n      style={{ width: DAY_SIZE, height: DAY_SIZE }}\n      className={cn(\n        \"items-center justify-center\",\n        mode !== \"range\" && isSelected && \"bg-primary rounded-lg\",\n        mode !== \"range\" && isTodayDate && isSelected && \"bg-accent rounded-lg\",\n        isDisabled && \"opacity-50\",\n        rangeStyles\n      )}\n    >\n      <Text\n        className={cn(\n          \"text-base\",\n          (isSelected &&\n            mode === \"range\" &&\n            isDateRange(selected) &&\n            (isRangeStart(date, selected) || isRangeEnd(date, selected))) ||\n            (isSelected && mode !== \"range\")\n            ? \"text-primary-foreground\"\n            : !isCurrentMonth\n              ? \"text-muted-foreground\"\n              : \"text-foreground\",\n          isDisabled && \"opacity-50\"\n        )}\n      >\n        {format(date, \"d\")}\n      </Text>\n    </Pressable>\n  );\n});\n\nconst TimeSelector = React.memo(({\n  selectedDate,\n  showTimePicker,\n  onToggleTimePicker,\n}: {\n  selectedDate: Date;\n  showTimePicker: boolean;\n  onToggleTimePicker: () => void;\n}) => (\n  <View className=\"px-4 pb-4\">\n    <Pressable\n      onPress={onToggleTimePicker}\n      className=\"flex-row items-center justify-between bg-muted/50 rounded-xl p-4\"\n    >\n      <View className=\"flex-row items-center\">\n        <View className=\"bg-primary/10 p-2 rounded-full mr-4\">\n          <Ionicons name=\"time-outline\" size={22} className=\"text-foreground\" />\n        </View>\n        <Text className=\"text-base font-medium text-foreground\">\n          {format(selectedDate, \"HH:mm\")}\n        </Text>\n      </View>\n      <View className=\"flex-row items-center space-x-2\">\n        <Text className=\"text-sm text-muted-foreground\">\n          {showTimePicker ? \"Tap to close\" : \"Tap to change\"}\n        </Text>\n        <Ionicons\n          name={showTimePicker ? \"chevron-down\" : \"chevron-forward\"}\n          size={16}\n          className=\"text-muted-foreground\"\n        />\n      </View>\n    </Pressable>\n  </View>\n));\n\nconst MonthYearPickerHeader = React.memo(({\n  activeTab,\n  onClose,\n}: {\n  activeTab: \"month\" | \"year\";\n  setActiveTab: (tab: \"month\" | \"year\") => void;\n  onClose: () => void;\n}) => (\n  <View className=\"border-b border-border\">\n    <View className=\"flex-row justify-between items-center px-4 py-3\">\n      <Pressable onPress={onClose} className=\"opacity-60 active:opacity-100\">\n        <Text className=\"text-grey\">Cancel</Text>\n      </Pressable>\n      <Text className=\"text-lg font-semibold text-black\">\n        {activeTab === \"month\" ? \"Select month\" : \"Select year\"}\n      </Text>\n      <Pressable onPress={onClose} className=\"opacity-60 active:opacity-100\">\n        <Text className=\"text-grey font-semibold\">Done</Text>\n      </Pressable>\n    </View>\n  </View>\n));\n\nconst MonthPicker = React.memo(({\n  currentDate,\n  onMonthSelect,\n  onYearChange,\n  onTabChange,\n  fromDate,\n  toDate,\n}: {\n  currentDate: Date;\n  onMonthSelect: (month: number) => void;\n  onYearChange: (year: number) => void;\n  onTabChange: () => void;\n  fromDate?: Date;\n  toDate?: Date;\n}) => {\n  const currentYear = currentDate.getFullYear();\n  const isPrevYearDisabled = fromDate && currentYear <= fromDate.getFullYear();\n  const isNextYearDisabled = toDate && currentYear >= toDate.getFullYear();\n\n  return (\n    <View className=\"py-4\">\n      <View className=\"px-4 mb-6\">\n        <View className=\"flex-row justify-between items-center mb-4\">\n          <Pressable\n            onPress={() => onYearChange(currentYear - 1)}\n            disabled={isPrevYearDisabled}\n            className={cn(\n              \"p-2 rounded-full active:scale-90 transition-transform\",\n              isPrevYearDisabled && \"opacity-50\"\n            )}\n          >\n            <Ionicons name=\"chevron-back\" size={24} className=\"text-black\" />\n          </Pressable>\n\n          <Pressable\n            onPress={onTabChange}\n            className=\"flex-row items-center px-4 py-2 rounded-lg active:opacity-60\"\n          >\n            <Text className=\"text-xl font-semibold text-black\">\n              {currentYear}\n            </Text>\n            <View className=\"ml-2\">\n              <Ionicons name=\"chevron-forward\" size={20} className=\"text-black\" />\n            </View>\n          </Pressable>\n\n          <Pressable\n            onPress={() => onYearChange(currentYear + 1)}\n            disabled={isNextYearDisabled}\n            className={cn(\n              \"p-2 rounded-full active:scale-90 transition-transform\",\n              isNextYearDisabled && \"opacity-50\"\n            )}\n          >\n            <Ionicons name=\"chevron-forward\" size={24} className=\"text-black\" />\n          </Pressable>\n        </View>\n        <View className=\"flex-row flex-wrap justify-between\">\n          {MONTHS.map((month, index) => {\n            const isDisabled =\n              (fromDate && (\n                currentYear === fromDate.getFullYear() &&\n                index < fromDate.getMonth()\n              )) ||\n              (toDate && (\n                currentYear === toDate.getFullYear() &&\n                index > toDate.getMonth()\n              ));\n\n            return (\n              <Pressable\n                key={month}\n                onPress={() => onMonthSelect(index)}\n                disabled={isDisabled}\n                className={cn(\n                  \"w-[30%] py-3 rounded-lg mb-3 active:scale-95 transition-transform\",\n                  getMonth(currentDate) === index ? \"bg-black\" : \"bg-grey\",\n                  isDisabled && \"opacity-50\"\n                )}\n              >\n                <Text\n                  className={cn(\n                    \"text-base text-center\",\n                    getMonth(currentDate) === index\n                      ? \"text-white font-medium\"\n                      : \"text-black\",\n                    isDisabled && \"opacity-50\"\n                  )}\n                >\n                  {month}\n                </Text>\n              </Pressable>\n            );\n          })}\n        </View>\n      </View>\n    </View>\n  );\n});\n\nconst YearPicker = React.memo(({\n  currentDate,\n  onYearSelect,\n  onYearNavigate,\n  fromDate,\n  toDate,\n}: {\n  currentDate: Date;\n  onYearSelect: (year: number) => void;\n  onYearNavigate: (year: number) => void;\n  fromDate?: Date;\n  toDate?: Date;\n}) => {\n  const startYear = currentDate.getFullYear() - 10;\n  const years = Array.from({ length: 20 }, (_, i) => startYear + i);\n\n  const minYear = fromDate ? fromDate.getFullYear() : undefined;\n  const maxYear = toDate ? toDate.getFullYear() : undefined;\n  const isPrevDisabled = minYear !== undefined && startYear - 20 < minYear;\n  const isNextDisabled = maxYear !== undefined && startYear + 20 > maxYear;\n\n  return (\n    <View className=\"py-4\">\n      <View className=\"px-4\">\n        <View className=\"flex-row justify-between items-center mb-4\">\n          <Pressable\n            onPress={() => onYearNavigate(startYear - 20)}\n            disabled={isPrevDisabled}\n            className={cn(\n              \"p-2 rounded-full active:scale-90 transition-transform\",\n              isPrevDisabled && \"opacity-50\"\n            )}\n          >\n            <Ionicons name=\"chevron-back\" size={24} className=\"text-black\" />\n          </Pressable>\n          <Text className=\"text-xl font-semibold text-black\">\n            {`${startYear} - ${startYear + 19}`}\n          </Text>\n          <Pressable\n            onPress={() => onYearNavigate(startYear + 20)}\n            disabled={isNextDisabled}\n            className={cn(\n              \"p-2 rounded-full active:scale-90 transition-transform\",\n              isNextDisabled && \"opacity-50\"\n            )}\n          >\n            <Ionicons name=\"chevron-forward\" size={24} className=\"text-black\" />\n          </Pressable>\n        </View>\n\n        <View className=\"flex-row flex-wrap justify-between\">\n          {years.map((year) => {\n            const isDisabled =\n              (minYear !== undefined && year < minYear) ||\n              (maxYear !== undefined && year > maxYear);\n\n            return (\n              <Pressable\n                key={year}\n                onPress={() => onYearSelect(year)}\n                disabled={isDisabled}\n                className={cn(\n                  \"w-[23%] py-3 rounded-lg mb-3 active:scale-95 transition-transform\",\n                  currentDate.getFullYear() === year ? \"bg-black\" : \"bg-grey\",\n                  isDisabled && \"opacity-50\"\n                )}\n              >\n                <Text\n                  className={cn(\n                    \"text-base text-center\",\n                    currentDate.getFullYear() === year\n                      ? \"text-white font-medium\"\n                      : \"text-black\",\n                    isDisabled && \"opacity-50\"\n                  )}\n                >\n                  {year}\n                </Text>\n              </Pressable>\n            );\n          })}\n        </View>\n      </View>\n    </View>\n  );\n});\n\nexport function Calendar({\n  mode = \"single\",\n  selected,\n  onSelect,\n  className,\n  showOutsideDays = true,\n  disabled,\n  fromDate,\n  toDate,\n  timeConfig,\n  firstDayOfWeek = 1,\n  enableQuickMonthYear = false,\n}: CalendarProps) {\n  const [currentDate, setCurrentDate] = React.useState(() => {\n    if (selected instanceof Date) {\n      return selected;\n    }\n    return new Date();\n  });\n  const [showTimePicker, setShowTimePicker] = React.useState(false);\n  const [showMonthYearPicker, setShowMonthYearPicker] = React.useState(false);\n  const [activeTab, setActiveTab] = React.useState<\"month\" | \"year\">(\"month\");\n  const [tempSelectedDate, setTempSelectedDate] = React.useState<Date | null>(null);\n\n  const fadeAnim = React.useRef(new Animated.Value(0)).current;\n\n  const orderedWeekdays = React.useMemo(() => {\n    const days = [...WEEKDAYS];\n    const firstDays = days.splice(0, firstDayOfWeek);\n    return [...days, ...firstDays];\n  }, [firstDayOfWeek]);\n\n  const getDaysInMonth = React.useCallback((date: Date) => {\n    const start = startOfMonth(date);\n    const end = endOfMonth(date);\n    const days = eachDayOfInterval({ start, end });\n\n    // Add days from previous month to fill the first week\n    const firstDayOfMonth = (start.getDay() - firstDayOfWeek + 7) % 7;\n    if (showOutsideDays && firstDayOfMonth > 0) {\n      const prevMonthDays = eachDayOfInterval({\n        start: subMonths(start, 1),\n        end: subMonths(end, 1),\n      }).slice(-firstDayOfMonth);\n      days.unshift(...prevMonthDays);\n    }\n\n    // Add days from next month to fill the last week\n    if (showOutsideDays && days.length < 42) {\n      const remainingDays = 42 - days.length;\n      const nextMonthDays = eachDayOfInterval({\n        start: addMonths(start, 1),\n        end: addMonths(end, 1),\n      }).slice(0, remainingDays);\n      days.push(...nextMonthDays);\n    }\n\n    return days;\n  }, [firstDayOfWeek, showOutsideDays]);\n\n  const isSelected = React.useCallback((date: Date) => {\n    if (!selected) return false;\n    if (selected instanceof Date) {\n      return isSameDay(selected, date);\n    }\n    if (Array.isArray(selected)) {\n      return selected.some((s) => isSameDay(s, date));\n    }\n    if (isDateRange(selected)) {\n      return (\n        isSameDay(selected.from, date) ||\n        isSameDay(selected.to, date) ||\n        isWithinInterval(date, { start: selected.from, end: selected.to })\n      );\n    }\n    return false;\n  }, [selected]);\n\n  const isDisabled = React.useCallback((date: Date) => {\n    if (fromDate && isBefore(date, startOfDay(fromDate))) return true;\n    if (toDate && isAfter(date, endOfDay(toDate))) return true;\n    if (typeof disabled === \"function\") return disabled(date);\n    return false;\n  }, [fromDate, toDate, disabled]);\n\n  const showPicker = React.useCallback(() => {\n    setShowMonthYearPicker(true);\n    Animated.timing(fadeAnim, {\n      toValue: 1,\n      duration: 200,\n      useNativeDriver: true,\n    }).start();\n  }, [fadeAnim]);\n\n  const hidePicker = React.useCallback(() => {\n    Animated.timing(fadeAnim, {\n      toValue: 0,\n      duration: 200,\n      useNativeDriver: true,\n    }).start(() => {\n      setShowMonthYearPicker(false);\n    });\n  }, [fadeAnim]);\n\n  const handleMonthSelect = React.useCallback((month: number) => {\n    const newDate = new Date(currentDate);\n    newDate.setMonth(month);\n    setCurrentDate(newDate);\n    setShowMonthYearPicker(false);\n  }, [currentDate]);\n\n  const handleYearChange = React.useCallback((year: number) => {\n    const newDate = new Date(currentDate);\n    newDate.setFullYear(year);\n    setCurrentDate(newDate);\n  }, [currentDate]);\n\n  const handleYearSelect = React.useCallback((year: number) => {\n    handleYearChange(year);\n    setActiveTab(\"month\");\n  }, [handleYearChange]);\n\n  const handleYearNavigate = React.useCallback((year: number) => {\n    handleYearChange(year);\n    // Ne pas changer d'onglet, rester en mode année\n  }, [handleYearChange]);\n\n  const handleDateSelect = React.useCallback((date: Date) => {\n    if (isDisabled(date)) return;\n\n    let newSelected: Date | Date[] | DateRange | undefined;\n\n    switch (mode) {\n      case \"single\":\n        newSelected = date;\n        break;\n      case \"range\":\n        if (!selected || !isDateRange(selected)) {\n          newSelected = { from: date, to: date };\n        } else {\n          if (isSameDay(selected.from, selected.to)) {\n            if (isBefore(date, selected.from)) {\n              newSelected = { from: date, to: selected.from };\n            } else {\n              newSelected = { from: selected.from, to: date };\n            }\n          } else {\n            newSelected = { from: date, to: date };\n          }\n        }\n        break;\n      case \"datetime\":\n        setTempSelectedDate(date);\n        if (selected instanceof Date) {\n          const newDate = setMinutes(\n            setHours(date, selected.getHours()),\n            selected.getMinutes()\n          );\n          onSelect?.(newDate);\n        } else {\n          onSelect?.(date);\n        }\n        return;\n      default:\n        newSelected = date;\n    }\n\n    onSelect?.(newSelected);\n  }, [mode, selected, onSelect, isDisabled]);\n\n  const handleTimeChange = React.useCallback((event: any, selectedTime?: Date) => {\n    if (Platform.OS === \"android\") {\n      setShowTimePicker(false);\n      if (event.type === \"dismissed\") return;\n    }\n\n    if (selectedTime && selected instanceof Date) {\n      const newDate = setMinutes(\n        setHours(selected, selectedTime.getHours()),\n        selectedTime.getMinutes()\n      );\n      onSelect?.(newDate);\n    }\n  }, [selected, onSelect]);\n\n  const handlePrevMonth = React.useCallback(() => {\n    setCurrentDate(subMonths(currentDate, 1));\n  }, [currentDate]);\n\n  const handleNextMonth = React.useCallback(() => {\n    setCurrentDate(addMonths(currentDate, 1));\n  }, [currentDate]);\n\n  const handleToggleTimePicker = React.useCallback(() => {\n    setShowTimePicker(!showTimePicker);\n  }, [showTimePicker]);\n\n  return (\n    <View className={cn(\"bg-background rounded-2xl\", className)}>\n      <View className=\"p-4\">\n        <CalendarHeader\n          currentDate={currentDate}\n          onPrevMonth={handlePrevMonth}\n          onNextMonth={handleNextMonth}\n          onHeaderPress={showPicker}\n          enableQuickMonthYear={enableQuickMonthYear}\n        />\n\n        <Modal\n          visible={showMonthYearPicker && enableQuickMonthYear}\n          transparent\n          animationType=\"none\"\n          onRequestClose={hidePicker}\n        >\n          <Animated.View\n            style={{\n              flex: 1,\n              justifyContent: \"center\",\n              alignItems: \"center\",\n              backgroundColor: \"rgba(0, 0, 0, 0.25)\",\n              padding: 16,\n              opacity: fadeAnim,\n            }}\n          >\n            <View\n              style={{\n                backgroundColor: \"white\",\n                borderRadius: 24,\n                overflow: \"hidden\",\n                width: \"90%\",\n                maxWidth: 400,\n              }}\n            >\n              <MonthYearPickerHeader\n                activeTab={activeTab}\n                setActiveTab={setActiveTab}\n                onClose={hidePicker}\n              />\n\n              {activeTab === \"month\" ? (\n                <MonthPicker\n                  currentDate={currentDate}\n                  onMonthSelect={handleMonthSelect}\n                  onYearChange={handleYearChange}\n                  onTabChange={() => setActiveTab(\"year\")}\n                  fromDate={fromDate}\n                  toDate={toDate}\n                />\n              ) : (\n                <YearPicker\n                  currentDate={currentDate}\n                  onYearSelect={handleYearSelect}\n                  onYearNavigate={handleYearNavigate}\n                  fromDate={fromDate}\n                  toDate={toDate}\n                />\n              )}\n            </View>\n          </Animated.View>\n        </Modal>\n\n        <WeekdaysRow orderedWeekdays={orderedWeekdays} />\n\n        <View className=\"flex-row flex-wrap\">\n          {getDaysInMonth(currentDate).map((date, index) => (\n            <CalendarDay\n              key={index}\n              date={date}\n              currentDate={currentDate}\n              mode={mode}\n              selected={selected}\n              isSelected={isSelected(date)}\n              isDisabled={isDisabled(date)}\n              onPress={() => handleDateSelect(date)}\n            />\n          ))}\n        </View>\n      </View>\n\n      {mode === \"datetime\" && selected instanceof Date && (\n        <TimeSelector\n          selectedDate={selected}\n          showTimePicker={showTimePicker}\n          onToggleTimePicker={handleToggleTimePicker}\n        />\n      )}\n\n      {showTimePicker &&\n        selected instanceof Date &&\n        (Platform.OS === \"ios\" ? (\n          <View className=\"px-4 pb-4\">\n            <View className=\"bg-muted rounded-xl overflow-hidden\">\n              <DateTimePicker\n                value={selected}\n                mode=\"time\"\n                is24Hour={true}\n                display=\"spinner\"\n                onChange={handleTimeChange}\n                textColor={undefined}\n                minuteInterval={timeConfig?.minuteInterval}\n                locale=\"en\"\n              />\n            </View>\n          </View>\n        ) : (\n          <DateTimePicker\n            value={selected}\n            mode=\"time\"\n            is24Hour={true}\n            display=\"default\"\n            onChange={handleTimeChange}\n            minuteInterval={timeConfig?.minuteInterval}\n            locale=\"en\"\n          />\n        ))}\n    </View>\n  );\n}\n",
      "type": "registry:ui"
    }
  ],
  "changelog": [],
  "customUsage": "import { Calendar } from \"@/components/ui/calendar\";\nimport * as React from \"react\";\n\nexport default function CalendarExample() {\n    const [quickPickerDate, setQuickPickerDate] = React.useState<Date>();\n\n    return (\n        <Calendar\n            mode=\"single\"\n            selected={quickPickerDate}\n            onSelect={(date) => setQuickPickerDate(date as Date)}\n            className=\"border border-border\"\n            enableQuickMonthYear={true}\n            fromDate={new Date(2020, 0, 1)}\n            toDate={new Date(2050, 11, 31)}\n        />\n    );\n}\n",
  "customPreview": "import { Calendar } from \"@/components/ui/calendar\";\nimport * as React from \"react\";\nimport { ScrollView, Text, View } from \"react-native\";\nimport { SafeAreaView } from \"react-native-safe-area-context\";\n\nexport default function CalendarExample() {\n    const [singleDate, setSingleDate] = React.useState<Date>();\n    const [dateRange, setDateRange] = React.useState<{\n        from: Date;\n        to: Date;\n    }>();\n    const [dateTime, setDateTime] = React.useState<Date>();\n    const [dateTime5min, setDateTime5min] = React.useState<Date>();\n    const [disabledDate, setDisabledDate] = React.useState<Date>();\n    const [quickPickerDate, setQuickPickerDate] = React.useState<Date>();\n\n    return (\n        <>\n            <SafeAreaView className=\"flex-1 bg-background\" edges={[\"bottom\"]}>\n                <ScrollView className=\"flex-1 p-4\">\n                    <View className=\"mb-6\">\n                        <Text className=\"text-2xl font-bold mb-2 text-foreground\">\n                            Calendar\n                        </Text>\n                        <Text className=\"text-base text-muted-foreground mb-6\">\n                            A date picker component with single date, date range, and\n                            date-time selection modes.\n                        </Text>\n                    </View>\n\n                    {/* Quick Month/Year Selection - English */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                            Quick Month/Year Selection (English)\n                        </Text>\n                        <Calendar\n                            mode=\"single\"\n                            selected={quickPickerDate}\n                            onSelect={(date) => setQuickPickerDate(date as Date)}\n                            className=\"border border-border\"\n                            enableQuickMonthYear={true}\n                            fromDate={new Date(2020, 0, 1)}\n                            toDate={new Date(2050, 11, 31)}\n                        />\n                        <Text className=\"mt-2 text-sm text-muted-foreground\">\n                            Tap on the month/year to open native month/year picker\n                        </Text>\n                        <Text className=\"mt-1 text-sm text-muted-foreground\">\n                            Selected date: {quickPickerDate?.toLocaleDateString(\"fr\")}\n                        </Text>\n                    </View>\n\n                    {/* Single Date Selection */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                            Single Date (Sunday First)\n                        </Text>\n                        <Calendar\n                            mode=\"single\"\n                            selected={singleDate}\n                            onSelect={(date) => setSingleDate(date as Date)}\n                            className=\"border border-border\"\n                            firstDayOfWeek={0}\n                        />\n                        <Text className=\"mt-2 text-sm text-muted-foreground\">\n                            Selected date: {singleDate?.toLocaleDateString()}\n                        </Text>\n                    </View>\n\n                    {/* Date Range Selection */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                            Date Range\n                        </Text>\n                        <Calendar\n                            mode=\"range\"\n                            selected={dateRange}\n                            onSelect={(range) =>\n                                setDateRange(range as { from: Date; to: Date })\n                            }\n                            className=\"border border-border\"\n                        />\n                        <Text className=\"mt-2 text-sm text-muted-foreground\">\n                            Selected range:{\" \"}\n                            {dateRange\n                                ? `${dateRange.from.toLocaleDateString()} - ${dateRange.to.toLocaleDateString()}`\n                                : \"No range selected\"}\n                        </Text>\n                    </View>\n\n                    {/* Date Time Selection */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                            Date & Time (Default)\n                        </Text>\n                        <Calendar\n                            mode=\"datetime\"\n                            selected={dateTime}\n                            onSelect={(date) => setDateTime(date as Date)}\n                            showTime\n                            className=\"border border-border\"\n                        />\n                        <Text className=\"mt-2 text-sm text-muted-foreground\">\n                            Selected date & time:{\" \"}\n                            {dateTime\n                                ? `${dateTime.toLocaleDateString()} ${dateTime.toLocaleTimeString()}`\n                                : \"No date/time selected\"}\n                        </Text>\n                    </View>\n\n                    {/* Date Time with 5min intervals */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                            Date & Time (5min intervals)\n                        </Text>\n                        <Calendar\n                            mode=\"datetime\"\n                            selected={dateTime5min}\n                            onSelect={(date) => setDateTime5min(date as Date)}\n                            showTime\n                            timeConfig={{\n                                minuteInterval: 5,\n                            }}\n                            className=\"border border-border\"\n                        />\n                        <Text className=\"mt-2 text-sm text-muted-foreground\">\n                            Selected date & time:{\" \"}\n                            {dateTime5min\n                                ? `${dateTime5min.toLocaleDateString()} ${dateTime5min.toLocaleTimeString()}`\n                                : \"No date/time selected\"}\n                        </Text>\n                    </View>\n\n                    {/* Disabled Dates Example */}\n                    <View className=\"mb-8\">\n                        <Text className=\"text-xl font-semibold mb-4 text-foreground\">\n                            With Disabled Dates\n                        </Text>\n                        <Calendar\n                            mode=\"single\"\n                            selected={disabledDate}\n                            onSelect={(date) => setDisabledDate(date as Date)}\n                            fromDate={new Date()}\n                            disabled={\n                                (date) => date.getDay() === 0 || date.getDay() === 6 // Disable weekends\n                            }\n                            className=\"border border-border\"\n                        />\n                        <Text className=\"mt-2 text-sm text-muted-foreground\">\n                            Selected date:{\" \"}\n                            {disabledDate?.toLocaleDateString() || \"No date selected\"}\n                        </Text>\n                    </View>\n\n                    <View className=\"h-20\" />\n                </ScrollView>\n            </SafeAreaView>\n        </>\n    );\n}\n"
}