React Native Glow UI v1 is out now!
Logo
Components

Calendar View

A flexible and beautiful calendar component for React Native with custom themeing.

Installation

npx rn-glow add calendar

🧩 CalendarViewProps

PropTypeDefault
sheetSizes?
(string | number)[]
-
hideTrigger?
boolean
-
renderTrigger?
(params: { selectedValue: string; onPress: () => void; isRangeMode: boolean }) => React.ReactNode
-
disabledDates?
string[]
-
maxDate?
string
-
minDate?
string
-
dateFormat?
string
-
onModeChange?
(mode: CalendarMode) => void
-
onTimeSelect?
(time: { hour: number; minute: number; period: "AM" | "PM" }) => void
-
onRangeSelect?
(range: DateRange) => void
-
onDateSelect?
(date: string) => void
-
theme?
Partial<typeof darkTheme>
-
showRangeToggle?
boolean
-
showModeSelector?
boolean
-
enableRangeMode?
boolean
-
initialMode?
"date" | "month" | "year" | "month-year" | "time"
-
initialDate?
string
-

📡 CalendarViewRef

PropTypeDefault
setRange?
(range: DateRange) => void
-
setDate?
(date: string) => void
-
getValue?
() => string | DateRange
-
goToToday?
() => void
-
reset?
() => void
-
close?
() => void
-
open?
() => void
-

🚀 Example

// EnhancedCalendarExample.tsx
import React, {
  useRef,
  useState,
  useCallback,
  useMemo,
  useEffect,
} from "react";
import {
  View,
  Text,
  StyleSheet,
  SafeAreaView,
  ScrollView,
  Pressable,
  StatusBar,
  Platform,
  Alert,
  Vibration,
} from "react-native";
import { LinearGradient } from "expo-linear-gradient";
import { SFSymbol, SymbolView } from "expo-symbols";
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
  withTiming,
  FadeInDown,
  FadeInUp,
  FadeIn,
  withSequence,
  withRepeat,
  interpolateColor,
} from "react-native-reanimated";
import {
  CalendarView,
  CalendarViewRef,
  DateRange,
} from "@/components/molecules/Calendar/index";

const theme = {
  background: "#0a0a0a",
  card: "#0f0f0f",
  cardHover: "#171717",
  foreground: "#fafafa",
  muted: "#171717",
  mutedForeground: "#737373",
  border: "#262626",
  primary: "#fafafa",
  primaryForeground: "#0a0a0a",
  secondary: "#1a1a1a",
  accent: "#fafafa",
  accentForeground: "#0a0a0a",
  success: "#22c55e",
  warning: "#f59e0b",
  destructive: "#ef4444",
  info: "#06b6d4",
  purple: "#8b5cf6",
  orange: "#f97316",
  alarm: "#ff6b6b",
  alarmLight: "#ff8e8e",
  gradients: {
    primary: ["#0a0a0a", "#171717"],
    accent: ["#fafafa", "#a3a3a3"],
    success: ["#22c55e", "#16a34a"],
    purple: ["#8b5cf6", "#7c3aed"],
    orange: ["#f97316", "#ea580c"],
    blue: ["#3b82f6", "#1d4ed8"],
    alarm: ["black", "black"],
    alarmDark: ["#2c2c2c", "#1a1a1a"],
  },
};

interface CalendarDemo {
  id: string;
  title: string;
  description: string;
  icon: string;
  color: string;
  config: any;
}

interface AlertItem {
  id: string;
  date: string;
  time?: string;
  title: string;
  type: "reminder" | "event" | "deadline" | "meeting";
  isActive: boolean;
}

const calendarDemos: CalendarDemo[] = [
  {
    id: "date",
    title: "Date Picker",
    description: "Single date selection with alarm alerts",
    icon: "calendar.circle.fill",
    color: theme.accent,
    config: {
      initialMode: "date",
      enableRangeMode: false,
      showModeSelector: false,
      showRangeToggle: false,
    },
  },
  {
    id: "range",
    title: "Date Range",
    description: "Period selection with smart notifications",
    icon: "calendar.badge.plus",
    color: theme.success,
    config: {
      initialMode: "date",
      enableRangeMode: true,
      showModeSelector: false,
      showRangeToggle: false,
    },
  },
  {
    id: "time",
    title: "Date & Time",
    description: "Precision scheduling with alarm system",
    icon: "alarm.fill",
    color: theme.alarm,
    config: {
      initialMode: "time",
      enableRangeMode: false,
      showModeSelector: false,
      showRangeToggle: false,
    },
  },
  {
    id: "full",
    title: "Smart Scheduler",
    description: "Complete alarm & notification system",
    icon: "bell.badge.fill",
    color: theme.orange,
    config: {
      initialMode: "date",
      enableRangeMode: false,
      showModeSelector: true,
      showRangeToggle: true,
    },
  },
];

const DemoCard = React.memo<{
  demo: CalendarDemo;
  index: number;
  isSelected: boolean;
  onSelect: (id: string) => void;
}>(({ demo, index, isSelected, onSelect }) => {
  const pulseAnim = useSharedValue(1);
  const glowAnim = useSharedValue(0);

  useEffect(() => {
    if (isSelected) {
      pulseAnim.value = withRepeat(
        withSequence(
          withTiming(1.02, { duration: 1000 }),
          withTiming(1, { duration: 1000 }),
        ),
        -1,
        true,
      );
      glowAnim.value = withRepeat(
        withSequence(
          withTiming(1, { duration: 2000 }),
          withTiming(0, { duration: 2000 }),
        ),
        -1,
        true,
      );
    } else {
      pulseAnim.value = withTiming(1);
      glowAnim.value = withTiming(0);
    }
  }, [isSelected]);

  const handlePress = useCallback(() => {
    onSelect(demo.id);
    Vibration.vibrate(50);
  }, [demo.id, onSelect]);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ scale: pulseAnim.value }],
    shadowOpacity: 0.1 + glowAnim.value * 0.3,
  }));

  const glowStyle = useAnimatedStyle(() => ({
    opacity: glowAnim.value * 0.3,
    backgroundColor: interpolateColor(
      glowAnim.value,
      [0, 1],
      ["transparent", demo.color + "20"],
    ),
  }));

  return (
    <Animated.View
      entering={FadeInDown.delay(index * 100)}
      style={[
        styles.demoCard,
        animatedStyle,
        {
          borderColor: isSelected ? demo.color : theme.border,
          borderWidth: isSelected ? 2 : 1,
        },
      ]}
    >
      {isSelected && <Animated.View style={[styles.cardGlow, glowStyle]} />}
      <Pressable style={styles.cardContent} onPress={handlePress}>
        <View style={styles.cardHeader}>
          <View
            style={[
              styles.iconContainer,
              { backgroundColor: demo.color + "20" },
            ]}
          >
            <SymbolView
              name={demo.icon as SFSymbol}
              size={24}
              type="hierarchical"
              tintColor={demo.color}
            />
          </View>
          <Text style={[styles.cardTitle, { color: theme.foreground }]}>
            {demo.title}
          </Text>
        </View>
        <Text
          style={[styles.cardDescription, { color: theme.mutedForeground }]}
        >
          {demo.description}
        </Text>

        {isSelected && (
          <Animated.View
            entering={FadeIn.duration(200)}
            style={styles.selectedIndicator}
          >
            <SymbolView
              name="checkmark.circle.fill"
              size={20}
              type="hierarchical"
              tintColor={demo.color}
            />
          </Animated.View>
        )}
      </Pressable>
    </Animated.View>
  );
});

const AlertCard = React.memo<{
  alert: AlertItem;
  onToggle: (id: string) => void;
  onDelete: (id: string) => void;
}>(({ alert, onToggle, onDelete }) => {
  const pulseAnim = useSharedValue(1);

  useEffect(() => {
    if (alert.isActive) {
      pulseAnim.value = withRepeat(
        withSequence(
          withTiming(1.01, { duration: 1500 }),
          withTiming(1, { duration: 1500 }),
        ),
        -1,
        true,
      );
    } else {
      pulseAnim.value = withTiming(1);
    }
  }, [alert.isActive]);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ scale: pulseAnim.value }],
  }));

  const getAlertIcon = () => {
    switch (alert.type) {
      case "reminder":
        return "bell.fill";
      case "event":
        return "calendar.circle.fill";
      case "deadline":
        return "exclamationmark.triangle.fill";
      case "meeting":
        return "person.2.fill";
      default:
        return "bell.fill";
    }
  };

  const getAlertColor = () => {
    switch (alert.type) {
      case "reminder":
        return theme.info;
      case "event":
        return theme.success;
      case "deadline":
        return theme.alarm;
      case "meeting":
        return theme.purple;
      default:
        return theme.info;
    }
  };

  return (
    <Animated.View style={[styles.alertCard, animatedStyle]}>
      <LinearGradient
        colors={
          alert.isActive
            ? theme.gradients.alarm
            : (theme.gradients.alarmDark as any)
        }
        style={styles.alertGradient}
      >
        <View style={styles.alertContent}>
          <View style={styles.alertLeft}>
            <View
              style={[
                styles.alertIcon,
                { backgroundColor: getAlertColor() + "20" },
              ]}
            >
              <SymbolView
                name={getAlertIcon() as SFSymbol}
                size={18}
                type="hierarchical"
                tintColor={getAlertColor()}
              />
            </View>
            <View style={styles.alertTextContainer}>
              <Text style={[styles.alertTitle, { color: theme.foreground }]}>
                {alert.title}
              </Text>
              <Text
                style={[styles.alertDate, { color: theme.mutedForeground }]}
              >
                {alert.date} {alert.time && `at ${alert.time}`}
              </Text>
            </View>
          </View>
          <View style={styles.alertActions}>
            <Pressable
              style={[
                styles.alertToggle,
                {
                  backgroundColor: alert.isActive
                    ? theme.success + "20"
                    : theme.muted,
                },
              ]}
              onPress={() => onToggle(alert.id)}
            >
              <SymbolView
                name={alert.isActive ? "bell.fill" : "bell.slash.fill"}
                size={14}
                type="hierarchical"
                tintColor={
                  alert.isActive ? theme.success : theme.mutedForeground
                }
              />
            </Pressable>
            <Pressable
              style={[
                styles.alertDelete,
                { backgroundColor: theme.destructive + "20" },
              ]}
              onPress={() => onDelete(alert.id)}
            >
              <SymbolView
                name="trash.fill"
                size={14}
                type="hierarchical"
                tintColor={theme.destructive}
              />
            </Pressable>
          </View>
        </View>
      </LinearGradient>
    </Animated.View>
  );
});

const ActionButton = React.memo<{
  title: string;
  icon: string;
  onPress: () => void;
  variant?: "default" | "destructive" | "success" | "alarm";
}>(({ title, icon, onPress, variant = "default" }) => {
  const colors = useMemo(
    () => ({
      default: {
        bg: theme.secondary,
        text: theme.foreground,
        icon: theme.foreground,
      },
      destructive: {
        bg: theme.destructive + "15",
        text: theme.destructive,
        icon: theme.destructive,
      },
      success: {
        bg: theme.success + "15",
        text: theme.success,
        icon: theme.success,
      },
      alarm: {
        bg: theme.alarm + "15",
        text: theme.alarm,
        icon: theme.alarm,
      },
    }),
    [],
  );

  const buttonStyle = useMemo(
    () => [
      styles.actionButton,
      {
        backgroundColor: colors[variant].bg,
        borderColor: colors[variant].text + "20",
      },
    ],
    [colors, variant],
  );

  return (
    <Pressable style={buttonStyle} onPress={onPress}>
      <SymbolView
        name={icon as SFSymbol}
        size={14}
        type="hierarchical"
        tintColor={colors[variant].icon}
      />
      <Text style={[styles.actionButtonText, { color: colors[variant].text }]}>
        {title}
      </Text>
    </Pressable>
  );
});

const EnhancedCalendarExample: React.FC = () => {
  const calendarRefs = useRef<{ [key: string]: CalendarViewRef | null }>({});
  const [selectedValues, setSelectedValues] = useState<{
    [key: string]: string;
  }>({});
  const [selectedDemo, setSelectedDemo] = useState<string>("date");
  const [alerts, setAlerts] = useState<AlertItem[]>([
    {
      id: "1",
      date: "Today",
      time: "10:30 AM",
      title: "Team Meeting",
      type: "meeting",
      isActive: true,
    },
    {
      id: "2",
      date: "Tomorrow",
      title: "Project Deadline",
      type: "deadline",
      isActive: true,
    },
  ]);

  const headerScale = useSharedValue(1);
  const alarmPulse = useSharedValue(1);

  useEffect(() => {
    alarmPulse.value = withRepeat(
      withSequence(
        withTiming(1.1, { duration: 1000 }),
        withTiming(1, { duration: 1000 }),
      ),
      -1,
      true,
    );
  }, []);

  const handleDemoSelect = useCallback((demoId: string) => {
    setSelectedDemo(demoId);
    Vibration.vibrate(50);
  }, []);

  const handleDateSelect = useCallback(
    (demoId: string) => (date: string) => {
      setSelectedValues((prev) => ({ ...prev, [demoId]: date }));

      Alert.alert("📅 Date Selected", `Selected date: ${date}`, [
        {
          text: "Set Reminder",
          onPress: () => addAlert(date, "reminder"),
        },
        {
          text: "OK",
          style: "default",
        },
      ]);

      headerScale.value = withSpring(1.01, { damping: 20 }, () => {
        headerScale.value = withSpring(1);
      });
      Vibration.vibrate(100);
    },
    [],
  );

  const handleRangeSelect = useCallback(
    (demoId: string) => (range: DateRange) => {
      const rangeText = range.start
        ? `${range.start}${range.end ? ` to ${range.end}` : " (select end)"}`
        : "No range selected";
      setSelectedValues((prev) => ({ ...prev, [demoId]: rangeText }));

      if (range.start && range.end) {
        Alert.alert(
          "📊 Range Selected",
          `Period: ${range.start} to ${range.end}`,
          [
            {
              text: "Set Period Alert",
              onPress: () => addAlert(rangeText, "event"),
            },
            {
              text: "OK",
              style: "default",
            },
          ],
        );
        Vibration.vibrate([100, 50, 100]);
      }
    },
    [],
  );

  const handleTimeSelect = useCallback(
    (demoId: string) =>
      (time: { hour: number; minute: number; period: string }) => {
        const timeText = `${time.hour}:${time.minute.toString().padStart(2, "0")} ${time.period}`;
        const fullDateTime = `${selectedValues[demoId]?.split(" at ")[0] || "Today"} at ${timeText}`;
        setSelectedValues((prev) => ({
          ...prev,
          [demoId]: fullDateTime,
        }));

        Alert.alert("⏰ Time Set", `Scheduled for: ${fullDateTime}`, [
          {
            text: "Set Alarm",
            onPress: () => addAlert("Today", "reminder", timeText),
          },
          {
            text: "OK",
            style: "default",
          },
        ]);
        Vibration.vibrate([50, 100, 50]);
      },
    [selectedValues],
  );

  const addAlert = useCallback(
    (date: string, type: AlertItem["type"], time?: string) => {
      const newAlert: AlertItem = {
        id: Date.now().toString(),
        date,
        time,
        title: `${type.charAt(0).toUpperCase() + type.slice(1)} for ${date}`,
        type,
        isActive: true,
      };
      setAlerts((prev) => [...prev, newAlert]);
      Vibration.vibrate(200);
    },
    [],
  );

  const toggleAlert = useCallback((id: string) => {
    setAlerts((prev) =>
      prev.map((alert) =>
        alert.id === id ? { ...alert, isActive: !alert.isActive } : alert,
      ),
    );
    Vibration.vibrate(50);
  }, []);

  const deleteAlert = useCallback((id: string) => {
    Alert.alert("Delete Alert", "Are you sure you want to delete this alert?", [
      { text: "Cancel", style: "cancel" },
      {
        text: "Delete",
        style: "destructive",
        onPress: () => {
          setAlerts((prev) => prev.filter((alert) => alert.id !== id));
          Vibration.vibrate(100);
        },
      },
    ]);
  }, []);

  const openCalendar = useCallback(() => {
    calendarRefs.current[selectedDemo]?.open();
    Vibration.vibrate(50);
  }, [selectedDemo]);

  const goToToday = useCallback(() => {
    calendarRefs.current[selectedDemo]?.goToToday();
    Vibration.vibrate(50);
  }, [selectedDemo]);

  const resetCalendar = useCallback(() => {
    calendarRefs.current[selectedDemo]?.reset();
    setSelectedValues((prev) => ({ ...prev, [selectedDemo]: "" }));
    Vibration.vibrate(100);
  }, [selectedDemo]);

  const selectedDemoConfig = useMemo(
    () => calendarDemos.find((d) => d.id === selectedDemo),
    [selectedDemo],
  );

  const animatedHeaderStyle = useAnimatedStyle(() => ({
    transform: [{ scale: headerScale.value }],
  }));

  const animatedAlarmStyle = useAnimatedStyle(() => ({
    transform: [{ scale: alarmPulse.value }],
  }));

  const renderCustomTrigger = useCallback(
    ({
      selectedValue,
      onPress,
      isRangeMode,
    }: {
      selectedValue: string;
      onPress: () => void;
      isRangeMode: boolean;
    }) => (
      <Pressable
        style={[
          styles.customTrigger,
          {
            backgroundColor: theme.card,
            borderColor: selectedDemoConfig?.color || theme.border,
          },
        ]}
        onPress={onPress}
      >
        <LinearGradient
          colors={theme.gradients.alarmDark as any}
          style={styles.triggerGradient}
        >
          <View style={styles.triggerContent}>
            <View style={styles.triggerLeft}>
              <View
                style={[
                  styles.triggerIcon,
                  {
                    backgroundColor:
                      selectedDemoConfig?.color + "20" || theme.muted,
                  },
                ]}
              >
                <SymbolView
                  name={(selectedDemoConfig?.icon as SFSymbol) || "calendar"}
                  size={18}
                  type="hierarchical"
                  tintColor={selectedDemoConfig?.color || theme.accent}
                />
              </View>
              <View style={styles.triggerTextContainer}>
                <Text
                  style={[
                    styles.triggerLabel,
                    { color: theme.mutedForeground },
                  ]}
                >
                  {isRangeMode
                    ? "DATE RANGE"
                    : selectedDemoConfig?.title.toUpperCase()}
                </Text>
                <Text
                  style={[styles.triggerValue, { color: theme.foreground }]}
                >
                  {selectedValue || "Select date..."}
                </Text>
              </View>
            </View>
            <SymbolView
              name="chevron.right"
              size={14}
              type="hierarchical"
              tintColor={theme.mutedForeground}
            />
          </View>
        </LinearGradient>
      </Pressable>
    ),
    [selectedDemoConfig],
  );

  const features = useMemo(
    () => [
      {
        icon: "bell.badge.fill",
        title: "Smart Alerts",
        desc: "Intelligent notification system",
      },
      {
        icon: "alarm.fill",
        title: "Precision Timing",
        desc: "Exact time scheduling",
      },
      {
        icon: "calendar.badge.plus",
        title: "Range Selection",
        desc: "Intuitive date range picking",
      },
      {
        icon: "paintbrush.fill",
        title: "Alarm Theme",
        desc: "Beautiful dark alarm aesthetic",
      },
      {
        icon: "wand.and.rays",
        title: "Smooth Animations",
        desc: "Reanimated 3 transitions",
      },
      {
        icon: "hand.tap.fill",
        title: "Haptic Feedback",
        desc: "Rich tactile responses",
      },
    ],
    [],
  );

  return (
    <ScrollView
      showsVerticalScrollIndicator={false}
      contentContainerStyle={{ flexGrow: 1 }}
      style={{ flex: 1 }}
      scrollEnabled={true}
      contentInsetAdjustmentBehavior="always"
    >
      <SafeAreaView
        style={[styles.container, { backgroundColor: theme.background }]}
      >
        <StatusBar
          barStyle="light-content"
          backgroundColor={theme.background}
        />

        <Animated.View entering={FadeInUp} style={styles.header}>
          <LinearGradient
            colors={theme?.gradients?.alarm as any}
            style={styles.headerGradient}
          >
            <Animated.View style={[styles.headerContent, animatedHeaderStyle]}>
              <View style={styles.headerTitleContainer}>
                <Animated.View
                  style={[styles.headerIconContainer, animatedAlarmStyle]}
                >
                  <SymbolView
                    name="alarm.fill"
                    size={28}
                    type="hierarchical"
                    tintColor={"white"}
                  />
                </Animated.View>
                <View>
                  <Text style={[styles.headerTitle, { color: "white" }]}>
                    Smart Calendar
                  </Text>
                  <Text
                    style={[
                      styles.headerSubtitle,
                      { color: theme.mutedForeground },
                    ]}
                  >
                    Intelligent scheduling with alerts
                  </Text>
                </View>
              </View>
            </Animated.View>
          </LinearGradient>
        </Animated.View>

        <ScrollView
          showsHorizontalScrollIndicator={false}
          style={styles.scrollView}
          contentContainerStyle={styles.scrollContent}
          showsVerticalScrollIndicator={false}
        >
          <Animated.View entering={FadeInUp.delay(100)} style={styles.section}>
            <View style={styles.sectionHeader}>
              <SymbolView
                name="bell.badge.fill"
                size={20}
                type="hierarchical"
                tintColor={theme.alarm}
              />
              <Text style={[styles.sectionTitle, { color: theme.foreground }]}>
                Active Alerts ({alerts.filter((a) => a.isActive).length})
              </Text>
            </View>

            <View style={styles.alertsList}>
              {alerts.map((alert) => (
                <AlertCard
                  key={alert.id}
                  alert={alert}
                  onToggle={toggleAlert}
                  onDelete={deleteAlert}
                />
              ))}
              {alerts.length === 0 && (
                <View style={styles.emptyState}>
                  <SymbolView
                    name="bell.slash"
                    size={32}
                    type="hierarchical"
                    tintColor={theme.mutedForeground}
                  />
                  <Text
                    style={[styles.emptyText, { color: theme.mutedForeground }]}
                  >
                    No alerts set
                  </Text>
                </View>
              )}
            </View>
          </Animated.View>

          <Animated.View entering={FadeInUp.delay(200)} style={styles.section}>
            <View style={styles.sectionHeader}>
              <SymbolView
                name="square.grid.2x2.fill"
                size={20}
                type="hierarchical"
                tintColor={theme.accent}
              />
              <Text style={[styles.sectionTitle, { color: theme.foreground }]}>
                Choose Demo
              </Text>
            </View>

            <View style={styles.demoGrid}>
              {calendarDemos.map((demo, index) => (
                <DemoCard
                  key={demo.id}
                  demo={demo}
                  index={index}
                  isSelected={selectedDemo === demo.id}
                  onSelect={handleDemoSelect}
                />
              ))}
            </View>
          </Animated.View>

          {selectedDemoConfig && (
            <Animated.View
              entering={FadeInUp.delay(300)}
              style={styles.section}
            >
              <View style={styles.sectionHeader}>
                <SymbolView
                  name="slider.horizontal.3"
                  size={20}
                  type="hierarchical"
                  tintColor={selectedDemoConfig.color}
                />
                <Text
                  style={[styles.sectionTitle, { color: theme.foreground }]}
                >
                  {selectedDemoConfig.title} Demo
                </Text>
              </View>

              <View
                style={[
                  styles.calendarContainer,
                  {
                    backgroundColor: theme.card,
                    borderColor: theme.border,
                  },
                ]}
              >
                <CalendarView
                  ref={(ref) => (calendarRefs.current[selectedDemo] = ref)}
                  {...selectedDemoConfig.config}
                  onDateSelect={handleDateSelect(selectedDemo)}
                  onRangeSelect={handleRangeSelect(selectedDemo)}
                  onTimeSelect={handleTimeSelect(selectedDemo)}
                  theme={{
                    accent: selectedDemoConfig.color,
                    primary: selectedDemoConfig.color,
                    info: selectedDemoConfig.color,
                  }}
                  maxDate=""
                  renderTrigger={renderCustomTrigger}
                />

                {/* Enhanced Action Buttons */}
                <View style={styles.actionGrid}>
                  <ActionButton
                    title="Open"
                    icon="calendar"
                    onPress={openCalendar}
                  />
                  <ActionButton
                    title="Today"
                    icon="location.fill"
                    onPress={goToToday}
                    variant="success"
                  />
                  <ActionButton
                    title="Alert"
                    icon="bell.badge.fill"
                    onPress={() => addAlert("Today", "reminder")}
                    variant="alarm"
                  />
                  <ActionButton
                    title="Reset"
                    icon="arrow.counterclockwise"
                    onPress={resetCalendar}
                    variant="destructive"
                  />
                </View>
              </View>
            </Animated.View>
          )}

          <Animated.View entering={FadeInUp.delay(400)} style={styles.section}>
            <View style={styles.sectionHeader}>
              <SymbolView
                name="star.fill"
                size={20}
                type="hierarchical"
                tintColor={theme.warning}
              />
              <Text style={[styles.sectionTitle, { color: theme.foreground }]}>
                Features
              </Text>
            </View>

            <View style={styles.featuresList}>
              {features.map((feature, index) => (
                <Animated.View
                  key={feature.title}
                  entering={FadeInUp.delay(600 + index * 50)}
                  style={[
                    styles.featureItem,
                    {
                      backgroundColor: theme.card,
                      borderColor: theme.border,
                    },
                  ]}
                >
                  <View
                    style={[
                      styles.featureIcon,
                      { backgroundColor: theme.accent + "15" },
                    ]}
                  >
                    <SymbolView
                      name={feature.icon as SFSymbol}
                      size={18}
                      type="hierarchical"
                      tintColor={theme.accent}
                    />
                  </View>
                  <View style={styles.featureContent}>
                    <Text
                      style={[styles.featureTitle, { color: theme.foreground }]}
                    >
                      {feature.title}
                    </Text>
                    <Text
                      style={[
                        styles.featureDesc,
                        { color: theme.mutedForeground },
                      ]}
                    >
                      {feature.desc}
                    </Text>
                  </View>
                </Animated.View>
              ))}
            </View>
          </Animated.View>

          <Animated.View entering={FadeInUp.delay(500)} style={styles.section}>
            <View style={styles.sectionHeader}>
              <SymbolView
                name="doc.text.fill"
                size={20}
                type="hierarchical"
                tintColor={theme.info}
              />
              <Text style={[styles.sectionTitle, { color: theme.foreground }]}>
                Usage Example
              </Text>
            </View>

            <View
              style={[
                styles.codeContainer,
                {
                  backgroundColor: theme.card,
                  borderColor: theme.border,
                },
              ]}
            >
              <Text style={[styles.codeText, { color: theme.mutedForeground }]}>
                {`import { EnhancedCalendarView } from '@/components';

<EnhancedCalendarView
  initialMode="date"
  enableAlerts={true}
  onDateSelect={(date) => showAlert(date)}
  onAlertCreate={(alert) => console.log(alert)}
  theme={{
    accent: "#ff6b6b",
    alarmColor: "#ff4757"
  }}
/>`}
              </Text>
            </View>
          </Animated.View>
        </ScrollView>
      </SafeAreaView>
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },

  header: {
    marginBottom: 8,
  },
  headerGradient: {
    paddingTop: 20,
    paddingBottom: 30,
    paddingHorizontal: 24,
  },
  headerContent: {
    gap: 16,
  },
  headerTitleContainer: {
    flexDirection: "row",
    alignItems: "center",
    gap: 16,
  },
  headerIconContainer: {
    width: 56,
    height: 56,
    borderRadius: 16,
    backgroundColor: "rgba(255, 255, 255, 0.1)",
    justifyContent: "center",
    alignItems: "center",
    shadowColor: "#000",
    shadowOffset: { width: 0, height: 4 },
    shadowOpacity: 0.3,
    shadowRadius: 8,
    elevation: 8,
  },
  headerTitle: {
    fontSize: 28,
    fontWeight: "900",
    letterSpacing: -0.5,
  },
  headerSubtitle: {
    fontSize: 15,
    fontWeight: "500",
    marginTop: 2,
  },

  scrollView: {
    flex: 1,
  },
  scrollContent: {
    paddingHorizontal: 24,
    paddingBottom: 40,
  },

  section: {
    marginBottom: 32,
    marginTop: 16,
  },
  sectionHeader: {
    flexDirection: "row",
    alignItems: "center",
    gap: 12,
    marginBottom: 20,
  },
  sectionTitle: {
    fontSize: 20,
    fontWeight: "800",
    letterSpacing: 0.3,
  },

  alertsList: {
    gap: 12,
  },
  alertCard: {
    borderRadius: 16,
    overflow: "hidden",
    shadowColor: "#000",
    shadowOffset: { width: 0, height: 4 },
    shadowOpacity: 0.15,
    shadowRadius: 12,
    elevation: 8,
  },
  alertGradient: {
    padding: 16,
  },
  alertContent: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
  },
  alertLeft: {
    flexDirection: "row",
    alignItems: "center",
    gap: 12,
    flex: 1,
  },
  alertIcon: {
    width: 40,
    height: 40,
    borderRadius: 12,
    justifyContent: "center",
    alignItems: "center",
  },
  alertTextContainer: {
    flex: 1,
  },
  alertTitle: {
    fontSize: 16,
    fontWeight: "600",
    marginBottom: 2,
  },
  alertDate: {
    fontSize: 14,
    fontWeight: "500",
  },
  alertActions: {
    flexDirection: "row",
    gap: 8,
  },
  alertToggle: {
    width: 36,
    height: 36,
    borderRadius: 10,
    justifyContent: "center",
    alignItems: "center",
  },
  alertDelete: {
    width: 36,
    height: 36,
    borderRadius: 10,
    justifyContent: "center",
    alignItems: "center",
  },

  emptyState: {
    alignItems: "center",
    justifyContent: "center",
    paddingVertical: 40,
    gap: 12,
  },
  emptyText: {
    fontSize: 16,
    fontWeight: "500",
  },

  demoGrid: {
    flexDirection: "row",
    flexWrap: "wrap",
    gap: 16,
  },
  demoCard: {
    width: "47%",
    borderRadius: 18,
    overflow: "hidden",
    shadowColor: "#000",
    shadowOffset: { width: 0, height: 6 },
    shadowOpacity: 0.15,
    shadowRadius: 16,
    elevation: 8,
    position: "relative",
  },
  cardGlow: {
    position: "absolute",
    top: -2,
    left: -2,
    right: -2,
    bottom: -2,
    borderRadius: 20,
    zIndex: -1,
  },

  cardContent: {
    backgroundColor: "#0a0a0a",
    padding: 20,
    borderRadius: 16,
    minHeight: 130,
    position: "relative",
  },
  cardHeader: {
    flexDirection: "row",
    alignItems: "center",
    gap: 12,
    marginBottom: 8,
  },
  iconContainer: {
    width: 42,
    height: 42,
    borderRadius: 12,
    justifyContent: "center",
    alignItems: "center",
  },
  cardTitle: {
    fontSize: 16,
    fontWeight: "700",
    letterSpacing: 0.3,
    flex: 1,
  },
  cardDescription: {
    fontSize: 14,
    lineHeight: 20,
    marginTop: 4,
  },
  selectedIndicator: {
    position: "absolute",
    top: 16,
    right: 16,
  },

  calendarContainer: {
    borderRadius: 18,
    borderWidth: 1,
    padding: 24,
    shadowColor: "#000",
    shadowOffset: { width: 0, height: 6 },
    shadowOpacity: 0.15,
    shadowRadius: 16,
    elevation: 8,
  },

  customTrigger: {
    borderRadius: 14,
    borderWidth: 2,
    marginBottom: 20,
    overflow: "hidden",
  },
  triggerGradient: {
    padding: 18,
  },
  triggerContent: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
  },
  triggerLeft: {
    flexDirection: "row",
    alignItems: "center",
    gap: 14,
    flex: 1,
  },
  triggerIcon: {
    width: 40,
    height: 40,
    borderRadius: 12,
    justifyContent: "center",
    alignItems: "center",
  },
  triggerTextContainer: {
    flex: 1,
  },
  triggerLabel: {
    fontSize: 13,
    fontWeight: "600",
    marginBottom: 3,
    textTransform: "uppercase",
    letterSpacing: 0.5,
  },
  triggerValue: {
    fontSize: 16,
    fontWeight: "600",
  },

  actionGrid: {
    flexDirection: "row",
    gap: 10,
    marginTop: 8,
  },
  actionButton: {
    flex: 1,
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
    gap: 8,
    paddingVertical: 12,
    paddingHorizontal: 16,
    borderRadius: 12,
    borderWidth: 1.5,
  },
  actionButtonText: {
    fontSize: 13,
    fontWeight: "700",
    letterSpacing: 0.3,
  },

  featuresList: {
    gap: 12,
  },
  featureItem: {
    flexDirection: "row",
    alignItems: "center",
    padding: 18,
    borderRadius: 16,
    borderWidth: 1,
    shadowColor: "#000",
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 8,
    elevation: 4,
  },
  featureIcon: {
    width: 40,
    height: 40,
    borderRadius: 12,
    justifyContent: "center",
    alignItems: "center",
    marginRight: 16,
  },
  featureContent: {
    flex: 1,
  },
  featureTitle: {
    fontSize: 16,
    fontWeight: "700",
    marginBottom: 4,
    letterSpacing: 0.2,
  },
  featureDesc: {
    fontSize: 13,
    lineHeight: 18,
    fontWeight: "500",
  },

  codeContainer: {
    borderRadius: 16,
    borderWidth: 1,
    padding: 20,
    backgroundColor: "#050505",
  },
  codeText: {
    fontFamily: Platform.OS === "ios" ? "Menlo" : "monospace",
    fontSize: 13,
    lineHeight: 20,
    color: "#a3a3a3",
  },
});

export default EnhancedCalendarExample;