import * as Haptics from 'expo-haptics'; import { Platform, Pressable, StyleSheet, View, type StyleProp, type ViewStyle } from 'react-native'; import { AppText } from './app-text'; import { colors, radius, spacing } from './tokens'; import { formatDayHeading, formatWeekdayShort } from '@/lib/date'; export type WeekDay = { date: Date; disabled?: boolean; marker?: 'none' | 'success' | 'warning' | 'danger' | 'neutral' }; type Props = { days: WeekDay[]; selectedDateKey: string; onSelect: (date: Date) => void; todayDateKey?: string; style?: StyleProp; accessibilityLabel?: string; }; const dateKey = (date: Date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; const markerColor = { none: 'transparent', success: colors.semantic.success.solid, warning: colors.semantic.warning.solid, danger: colors.semantic.danger.solid, neutral: colors.neutral.textMuted } as const; /** The shared selected-date control: coral selection, cobalt today signal, semantic status dot. */ export function WeekStrip({ days, selectedDateKey, onSelect, todayDateKey, style, accessibilityLabel = 'Choose a day' }: Props) { return {days.map(({ date, disabled = false, marker = 'none' }) => { const key = dateKey(date); const selected = key === selectedDateKey; const today = key === todayDateKey; const weekday = formatWeekdayShort(date).slice(0, 3).toLowerCase(); const fullDate = formatDayHeading(date); return { if (Platform.OS !== 'web') void Haptics.selectionAsync(); onSelect(date); }} style={({ pressed }) => [styles.day, selected && styles.selected, disabled && styles.disabled, pressed && !disabled && styles.pressed]}> {weekday} {date.getDate()} ; })} ; } const styles = StyleSheet.create({ strip: { flexDirection: 'row', gap: spacing[1], padding: spacing[2], borderRadius: radius.feature, borderCurve: 'continuous', backgroundColor: colors.brand.skySoft }, day: { flex: 1, minHeight: 64, alignItems: 'center', justifyContent: 'center', borderRadius: radius.control, borderCurve: 'continuous', paddingVertical: spacing[2] }, selected: { backgroundColor: colors.brand.coral }, disabled: { opacity: 0.42 }, pressed: { opacity: 0.78 }, weekday: { fontSize: 11, lineHeight: 14, fontWeight: '600' }, number: { fontSize: 18, lineHeight: 22, fontWeight: '800', marginTop: 2, fontVariant: ['tabular-nums'] }, indicatorRow: { height: 6, marginTop: 3, justifyContent: 'center' }, dot: { width: 4, height: 4, borderRadius: 2, backgroundColor: 'transparent' }, todayDot: { width: 5, height: 5, borderRadius: 2.5, backgroundColor: colors.brand.cobalt }, });