@dreamstack-us/kaal 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/module/components/CalendarGrid/CalendarGrid.js +112 -0
- package/lib/module/components/CalendarGrid/CalendarGrid.js.map +1 -0
- package/lib/module/components/CalendarGrid/CalendarGrid.styles.js +46 -0
- package/lib/module/components/CalendarGrid/CalendarGrid.styles.js.map +1 -0
- package/lib/module/components/CalendarGrid/DayCell.js +96 -0
- package/lib/module/components/CalendarGrid/DayCell.js.map +1 -0
- package/lib/module/components/CalendarGrid/index.js +4 -0
- package/lib/module/components/CalendarGrid/index.js.map +1 -0
- package/lib/module/components/DatePicker/DatePicker.android.js +66 -0
- package/lib/module/components/DatePicker/DatePicker.android.js.map +1 -0
- package/lib/module/components/DatePicker/DatePicker.ios.js +74 -0
- package/lib/module/components/DatePicker/DatePicker.ios.js.map +1 -0
- package/lib/module/components/DatePicker/DatePicker.js +9 -0
- package/lib/module/components/DatePicker/DatePicker.js.map +1 -0
- package/lib/module/components/DatePicker/DatePicker.styles.js +35 -0
- package/lib/module/components/DatePicker/DatePicker.styles.js.map +1 -0
- package/lib/module/components/DatePicker/DatePicker.web.js +32 -0
- package/lib/module/components/DatePicker/DatePicker.web.js.map +1 -0
- package/lib/module/components/DatePicker/index.js +4 -0
- package/lib/module/components/DatePicker/index.js.map +1 -0
- package/lib/module/components/TimePicker/ClockFace.js +194 -0
- package/lib/module/components/TimePicker/ClockFace.js.map +1 -0
- package/lib/module/components/TimePicker/MaterialTimePicker.js +122 -0
- package/lib/module/components/TimePicker/MaterialTimePicker.js.map +1 -0
- package/lib/module/components/TimePicker/TimePicker.android.js +77 -0
- package/lib/module/components/TimePicker/TimePicker.android.js.map +1 -0
- package/lib/module/components/TimePicker/TimePicker.ios.js +83 -0
- package/lib/module/components/TimePicker/TimePicker.ios.js.map +1 -0
- package/lib/module/components/TimePicker/TimePicker.js +34 -0
- package/lib/module/components/TimePicker/TimePicker.js.map +1 -0
- package/lib/module/components/TimePicker/TimePicker.styles.js +180 -0
- package/lib/module/components/TimePicker/TimePicker.styles.js.map +1 -0
- package/lib/module/components/TimePicker/TimePicker.web.js +37 -0
- package/lib/module/components/TimePicker/TimePicker.web.js.map +1 -0
- package/lib/module/components/TimePicker/TimeWheelPicker.js +178 -0
- package/lib/module/components/TimePicker/TimeWheelPicker.js.map +1 -0
- package/lib/module/components/TimePicker/index.js +7 -0
- package/lib/module/components/TimePicker/index.js.map +1 -0
- package/lib/module/components/WheelPicker/WheelPicker.js +5 -0
- package/lib/module/components/WheelPicker/WheelPicker.js.map +1 -0
- package/lib/module/components/WheelPicker/WheelPicker.styles.js +41 -0
- package/lib/module/components/WheelPicker/WheelPicker.styles.js.map +1 -0
- package/lib/module/components/WheelPicker/WheelPicker.web.js +190 -0
- package/lib/module/components/WheelPicker/WheelPicker.web.js.map +1 -0
- package/lib/module/components/WheelPicker/index.js +4 -0
- package/lib/module/components/WheelPicker/index.js.map +1 -0
- package/lib/module/components/index.js +7 -0
- package/lib/module/components/index.js.map +1 -0
- package/lib/module/hooks/index.js +6 -0
- package/lib/module/hooks/index.js.map +1 -0
- package/lib/module/hooks/useCalendar.js +44 -0
- package/lib/module/hooks/useCalendar.js.map +1 -0
- package/lib/module/hooks/useDatePicker.js +30 -0
- package/lib/module/hooks/useDatePicker.js.map +1 -0
- package/lib/module/hooks/useTimePicker.js +125 -0
- package/lib/module/hooks/useTimePicker.js.map +1 -0
- package/lib/module/index.js +22 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/types/datepicker.js +2 -0
- package/lib/module/types/datepicker.js.map +1 -0
- package/lib/module/types/index.js +5 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/types/timepicker.js +2 -0
- package/lib/module/types/timepicker.js.map +1 -0
- package/lib/module/unistyles.js +9 -0
- package/lib/module/unistyles.js.map +1 -0
- package/lib/module/utils/date.js +205 -0
- package/lib/module/utils/date.js.map +1 -0
- package/lib/module/utils/index.js +5 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/module/utils/validation.js +61 -0
- package/lib/module/utils/validation.js.map +1 -0
- package/lib/typescript/components/CalendarGrid/CalendarGrid.d.ts +12 -0
- package/lib/typescript/components/CalendarGrid/CalendarGrid.d.ts.map +1 -0
- package/lib/typescript/components/CalendarGrid/CalendarGrid.styles.d.ts +45 -0
- package/lib/typescript/components/CalendarGrid/CalendarGrid.styles.d.ts.map +1 -0
- package/lib/typescript/components/CalendarGrid/DayCell.d.ts +12 -0
- package/lib/typescript/components/CalendarGrid/DayCell.d.ts.map +1 -0
- package/lib/typescript/components/CalendarGrid/index.d.ts +2 -0
- package/lib/typescript/components/CalendarGrid/index.d.ts.map +1 -0
- package/lib/typescript/components/DatePicker/DatePicker.android.d.ts +4 -0
- package/lib/typescript/components/DatePicker/DatePicker.android.d.ts.map +1 -0
- package/lib/typescript/components/DatePicker/DatePicker.d.ts +15 -0
- package/lib/typescript/components/DatePicker/DatePicker.d.ts.map +1 -0
- package/lib/typescript/components/DatePicker/DatePicker.ios.d.ts +4 -0
- package/lib/typescript/components/DatePicker/DatePicker.ios.d.ts.map +1 -0
- package/lib/typescript/components/DatePicker/DatePicker.styles.d.ts +29 -0
- package/lib/typescript/components/DatePicker/DatePicker.styles.d.ts.map +1 -0
- package/lib/typescript/components/DatePicker/DatePicker.web.d.ts +4 -0
- package/lib/typescript/components/DatePicker/DatePicker.web.d.ts.map +1 -0
- package/lib/typescript/components/DatePicker/index.d.ts +3 -0
- package/lib/typescript/components/DatePicker/index.d.ts.map +1 -0
- package/lib/typescript/components/TimePicker/ClockFace.d.ts +12 -0
- package/lib/typescript/components/TimePicker/ClockFace.d.ts.map +1 -0
- package/lib/typescript/components/TimePicker/MaterialTimePicker.d.ts +12 -0
- package/lib/typescript/components/TimePicker/MaterialTimePicker.d.ts.map +1 -0
- package/lib/typescript/components/TimePicker/TimePicker.android.d.ts +4 -0
- package/lib/typescript/components/TimePicker/TimePicker.android.d.ts.map +1 -0
- package/lib/typescript/components/TimePicker/TimePicker.d.ts +29 -0
- package/lib/typescript/components/TimePicker/TimePicker.d.ts.map +1 -0
- package/lib/typescript/components/TimePicker/TimePicker.ios.d.ts +4 -0
- package/lib/typescript/components/TimePicker/TimePicker.ios.d.ts.map +1 -0
- package/lib/typescript/components/TimePicker/TimePicker.styles.d.ts +168 -0
- package/lib/typescript/components/TimePicker/TimePicker.styles.d.ts.map +1 -0
- package/lib/typescript/components/TimePicker/TimePicker.web.d.ts +10 -0
- package/lib/typescript/components/TimePicker/TimePicker.web.d.ts.map +1 -0
- package/lib/typescript/components/TimePicker/TimeWheelPicker.d.ts +11 -0
- package/lib/typescript/components/TimePicker/TimeWheelPicker.d.ts.map +1 -0
- package/lib/typescript/components/TimePicker/index.d.ts +6 -0
- package/lib/typescript/components/TimePicker/index.d.ts.map +1 -0
- package/lib/typescript/components/WheelPicker/WheelPicker.d.ts +2 -0
- package/lib/typescript/components/WheelPicker/WheelPicker.d.ts.map +1 -0
- package/lib/typescript/components/WheelPicker/WheelPicker.styles.d.ts +40 -0
- package/lib/typescript/components/WheelPicker/WheelPicker.styles.d.ts.map +1 -0
- package/lib/typescript/components/WheelPicker/WheelPicker.web.d.ts +10 -0
- package/lib/typescript/components/WheelPicker/WheelPicker.web.d.ts.map +1 -0
- package/lib/typescript/components/WheelPicker/index.d.ts +2 -0
- package/lib/typescript/components/WheelPicker/index.d.ts.map +1 -0
- package/lib/typescript/components/index.d.ts +5 -0
- package/lib/typescript/components/index.d.ts.map +1 -0
- package/lib/typescript/hooks/index.d.ts +4 -0
- package/lib/typescript/hooks/index.d.ts.map +1 -0
- package/lib/typescript/hooks/useCalendar.d.ts +10 -0
- package/lib/typescript/hooks/useCalendar.d.ts.map +1 -0
- package/lib/typescript/hooks/useDatePicker.d.ts +15 -0
- package/lib/typescript/hooks/useDatePicker.d.ts.map +1 -0
- package/lib/typescript/hooks/useTimePicker.d.ts +52 -0
- package/lib/typescript/hooks/useTimePicker.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +12 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/types/datepicker.d.ts +15 -0
- package/lib/typescript/types/datepicker.d.ts.map +1 -0
- package/lib/typescript/types/index.d.ts +3 -0
- package/lib/typescript/types/index.d.ts.map +1 -0
- package/lib/typescript/types/timepicker.d.ts +54 -0
- package/lib/typescript/types/timepicker.d.ts.map +1 -0
- package/lib/typescript/unistyles.d.ts +3 -0
- package/lib/typescript/unistyles.d.ts.map +1 -0
- package/lib/typescript/utils/date.d.ts +94 -0
- package/lib/typescript/utils/date.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +3 -0
- package/lib/typescript/utils/index.d.ts.map +1 -0
- package/lib/typescript/utils/validation.d.ts +40 -0
- package/lib/typescript/utils/validation.d.ts.map +1 -0
- package/package.json +101 -0
- package/src/components/CalendarGrid/CalendarGrid.styles.ts +44 -0
- package/src/components/CalendarGrid/CalendarGrid.tsx +151 -0
- package/src/components/CalendarGrid/DayCell.tsx +108 -0
- package/src/components/CalendarGrid/index.ts +1 -0
- package/src/components/DatePicker/DatePicker.android.tsx +69 -0
- package/src/components/DatePicker/DatePicker.ios.tsx +78 -0
- package/src/components/DatePicker/DatePicker.styles.ts +35 -0
- package/src/components/DatePicker/DatePicker.tsx +21 -0
- package/src/components/DatePicker/DatePicker.web.tsx +36 -0
- package/src/components/DatePicker/index.ts +2 -0
- package/src/components/TimePicker/ClockFace.tsx +233 -0
- package/src/components/TimePicker/MaterialTimePicker.tsx +169 -0
- package/src/components/TimePicker/TimePicker.android.tsx +80 -0
- package/src/components/TimePicker/TimePicker.ios.tsx +88 -0
- package/src/components/TimePicker/TimePicker.styles.ts +209 -0
- package/src/components/TimePicker/TimePicker.tsx +35 -0
- package/src/components/TimePicker/TimePicker.web.tsx +35 -0
- package/src/components/TimePicker/TimeWheelPicker.tsx +211 -0
- package/src/components/TimePicker/index.ts +5 -0
- package/src/components/WheelPicker/WheelPicker.styles.ts +39 -0
- package/src/components/WheelPicker/WheelPicker.tsx +2 -0
- package/src/components/WheelPicker/WheelPicker.web.tsx +237 -0
- package/src/components/WheelPicker/index.ts +1 -0
- package/src/components/index.ts +11 -0
- package/src/hooks/index.ts +9 -0
- package/src/hooks/useCalendar.ts +59 -0
- package/src/hooks/useDatePicker.ts +40 -0
- package/src/hooks/useTimePicker.ts +152 -0
- package/src/index.ts +77 -0
- package/src/types/datepicker.ts +17 -0
- package/src/types/index.ts +2 -0
- package/src/types/timepicker.ts +59 -0
- package/src/unistyles.ts +6 -0
- package/src/utils/date.ts +217 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/validation.ts +76 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Date utilities using native Date and Intl APIs
|
|
3
|
+
* Replaces @js-temporal/polyfill for lighter bundle size
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Converts a Date to ISO date string (YYYY-MM-DD)
|
|
8
|
+
*/
|
|
9
|
+
export const toISODateString = (date: Date): string => {
|
|
10
|
+
const year = date.getUTCFullYear();
|
|
11
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
|
12
|
+
const day = String(date.getUTCDate()).padStart(2, '0');
|
|
13
|
+
return `${year}-${month}-${day}`;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Converts a Date to ISO datetime string with timezone
|
|
18
|
+
*/
|
|
19
|
+
export const toISODateTimeString = (date: Date, timeZone?: string): string => {
|
|
20
|
+
const tz = timeZone ?? getUserTimezone();
|
|
21
|
+
const formatter = new Intl.DateTimeFormat('en-CA', {
|
|
22
|
+
timeZone: tz,
|
|
23
|
+
year: 'numeric',
|
|
24
|
+
month: '2-digit',
|
|
25
|
+
day: '2-digit',
|
|
26
|
+
hour: '2-digit',
|
|
27
|
+
minute: '2-digit',
|
|
28
|
+
second: '2-digit',
|
|
29
|
+
hour12: false,
|
|
30
|
+
});
|
|
31
|
+
const parts = formatter.formatToParts(date);
|
|
32
|
+
const get = (type: string) => parts.find((p) => p.type === type)?.value ?? '';
|
|
33
|
+
return `${get('year')}-${get('month')}-${get('day')}T${get('hour')}:${get('minute')}:${get('second')}`;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Parses an ISO date string (YYYY-MM-DD) to Date
|
|
38
|
+
*/
|
|
39
|
+
export const parseISODate = (iso: string): Date => {
|
|
40
|
+
const parts = iso.split('-').map(Number) as [number, number, number];
|
|
41
|
+
return new Date(Date.UTC(parts[0], parts[1] - 1, parts[2]));
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @deprecated Alias for parseISODate for backward compatibility
|
|
46
|
+
*/
|
|
47
|
+
export const fromISODateString = parseISODate;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Parses an ISO datetime string to Date
|
|
51
|
+
*/
|
|
52
|
+
export const parseISODateTime = (iso: string): Date => {
|
|
53
|
+
return new Date(iso);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @deprecated Alias for parseISODateTime for backward compatibility
|
|
58
|
+
*/
|
|
59
|
+
export const fromISODateTimeString = parseISODateTime;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Gets all dates in a range (inclusive)
|
|
63
|
+
*/
|
|
64
|
+
export const getDateRange = (start: Date, end: Date): Date[] => {
|
|
65
|
+
const dates: Date[] = [];
|
|
66
|
+
const current = new Date(start.getTime());
|
|
67
|
+
|
|
68
|
+
while (current.getTime() <= end.getTime()) {
|
|
69
|
+
dates.push(new Date(current.getTime()));
|
|
70
|
+
current.setUTCDate(current.getUTCDate() + 1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return dates;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Checks if a date is within the given range
|
|
78
|
+
*/
|
|
79
|
+
export const isDateInRange = (
|
|
80
|
+
date: Date,
|
|
81
|
+
minDate?: Date,
|
|
82
|
+
maxDate?: Date,
|
|
83
|
+
): boolean => {
|
|
84
|
+
const time = date.getTime();
|
|
85
|
+
if (minDate && time < minDate.getTime()) return false;
|
|
86
|
+
if (maxDate && time > maxDate.getTime()) return false;
|
|
87
|
+
return true;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Gets the user's timezone
|
|
92
|
+
*/
|
|
93
|
+
export const getUserTimezone = (): string => {
|
|
94
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Adds days to a date
|
|
99
|
+
*/
|
|
100
|
+
export const addDays = (date: Date, days: number): Date => {
|
|
101
|
+
const result = new Date(date.getTime());
|
|
102
|
+
result.setUTCDate(result.getUTCDate() + days);
|
|
103
|
+
return result;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Adds months to a date, handling month overflow
|
|
108
|
+
*/
|
|
109
|
+
export const addMonths = (date: Date, months: number): Date => {
|
|
110
|
+
const result = new Date(date.getTime());
|
|
111
|
+
const dayOfMonth = result.getUTCDate();
|
|
112
|
+
result.setUTCDate(1);
|
|
113
|
+
result.setUTCMonth(result.getUTCMonth() + months);
|
|
114
|
+
const daysInMonth = new Date(
|
|
115
|
+
Date.UTC(result.getUTCFullYear(), result.getUTCMonth() + 1, 0),
|
|
116
|
+
).getUTCDate();
|
|
117
|
+
result.setUTCDate(Math.min(dayOfMonth, daysInMonth));
|
|
118
|
+
return result;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Compares two dates
|
|
123
|
+
* @returns negative if a < b, positive if a > b, 0 if equal
|
|
124
|
+
*/
|
|
125
|
+
export const compareDates = (a: Date, b: Date): number => {
|
|
126
|
+
return a.getTime() - b.getTime();
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Checks if two dates are the same day
|
|
131
|
+
*/
|
|
132
|
+
export const isSameDay = (a: Date, b: Date): boolean => {
|
|
133
|
+
return toISODateString(a) === toISODateString(b);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Checks if two dates are the same month
|
|
138
|
+
*/
|
|
139
|
+
export const isSameMonth = (a: Date, b: Date): boolean => {
|
|
140
|
+
return (
|
|
141
|
+
a.getUTCFullYear() === b.getUTCFullYear() &&
|
|
142
|
+
a.getUTCMonth() === b.getUTCMonth()
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Gets all days in a month
|
|
148
|
+
*/
|
|
149
|
+
export const getMonthDays = (year: number, month: number): Date[] => {
|
|
150
|
+
const days: Date[] = [];
|
|
151
|
+
const daysInMonth = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
|
|
152
|
+
for (let day = 1; day <= daysInMonth; day++) {
|
|
153
|
+
days.push(new Date(Date.UTC(year, month, day)));
|
|
154
|
+
}
|
|
155
|
+
return days;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Gets the first day of the month
|
|
160
|
+
*/
|
|
161
|
+
export const getFirstDayOfMonth = (date: Date): Date => {
|
|
162
|
+
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1));
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Gets the last day of the month
|
|
167
|
+
*/
|
|
168
|
+
export const getLastDayOfMonth = (date: Date): Date => {
|
|
169
|
+
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 0));
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Gets the day of week (0 = Sunday, 6 = Saturday)
|
|
174
|
+
*/
|
|
175
|
+
export const getDayOfWeek = (date: Date): number => {
|
|
176
|
+
return date.getUTCDay();
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Formats a month name
|
|
181
|
+
*/
|
|
182
|
+
export const formatMonth = (
|
|
183
|
+
date: Date,
|
|
184
|
+
locale = 'en-US',
|
|
185
|
+
style: 'long' | 'short' | 'narrow' = 'long',
|
|
186
|
+
): string => {
|
|
187
|
+
return new Intl.DateTimeFormat(locale, { month: style }).format(date);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Formats a weekday name
|
|
192
|
+
*/
|
|
193
|
+
export const formatWeekday = (
|
|
194
|
+
date: Date,
|
|
195
|
+
locale = 'en-US',
|
|
196
|
+
style: 'long' | 'short' | 'narrow' = 'short',
|
|
197
|
+
): string => {
|
|
198
|
+
return new Intl.DateTimeFormat(locale, { weekday: style }).format(date);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Formats year and month
|
|
203
|
+
*/
|
|
204
|
+
export const formatYearMonth = (date: Date, locale = 'en-US'): string => {
|
|
205
|
+
return new Intl.DateTimeFormat(locale, {
|
|
206
|
+
month: 'long',
|
|
207
|
+
year: 'numeric',
|
|
208
|
+
}).format(date);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Gets today's date at midnight UTC
|
|
213
|
+
*/
|
|
214
|
+
export const today = (): Date => {
|
|
215
|
+
const now = new Date();
|
|
216
|
+
return new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate()));
|
|
217
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Helper to parse ISO date string parts
|
|
5
|
+
* Assumes input is already validated by regex pattern
|
|
6
|
+
*/
|
|
7
|
+
const parseISOParts = (val: string): [number, number, number] => {
|
|
8
|
+
const parts = val.split('-').map(Number) as [number, number, number];
|
|
9
|
+
return parts;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Validates an ISO 8601 date string (YYYY-MM-DD)
|
|
14
|
+
*/
|
|
15
|
+
export const isoDateSchema = v.pipe(
|
|
16
|
+
v.string(),
|
|
17
|
+
v.regex(/^\d{4}-\d{2}-\d{2}$/, 'Must be in YYYY-MM-DD format'),
|
|
18
|
+
v.check((val) => {
|
|
19
|
+
const [year, month, day] = parseISOParts(val);
|
|
20
|
+
const date = new Date(Date.UTC(year, month - 1, day));
|
|
21
|
+
return (
|
|
22
|
+
date.getUTCFullYear() === year &&
|
|
23
|
+
date.getUTCMonth() === month - 1 &&
|
|
24
|
+
date.getUTCDate() === day
|
|
25
|
+
);
|
|
26
|
+
}, 'Invalid ISO 8601 date format'),
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Validates an ISO 8601 datetime string with timezone offset
|
|
31
|
+
*/
|
|
32
|
+
export const isoDateTimeSchema = v.pipe(v.string(), v.isoTimestamp());
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Validates a date range where start <= end
|
|
36
|
+
*/
|
|
37
|
+
export const dateRangeSchema = v.pipe(
|
|
38
|
+
v.object({
|
|
39
|
+
start: isoDateSchema,
|
|
40
|
+
end: isoDateSchema,
|
|
41
|
+
}),
|
|
42
|
+
v.check((data) => {
|
|
43
|
+
return data.start <= data.end;
|
|
44
|
+
}, 'Start date must be before or equal to end date'),
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Validates date picker configuration
|
|
49
|
+
*/
|
|
50
|
+
export const datePickerValueSchema = v.object({
|
|
51
|
+
selectedDate: isoDateSchema,
|
|
52
|
+
minDate: v.optional(isoDateSchema),
|
|
53
|
+
maxDate: v.optional(isoDateSchema),
|
|
54
|
+
disabledDates: v.optional(v.array(isoDateSchema)),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Parses an ISO date string to a Date object
|
|
59
|
+
* @deprecated Use parseISODate from date utils instead. Kept for backward compatibility.
|
|
60
|
+
*/
|
|
61
|
+
export const dateSchema = v.pipe(
|
|
62
|
+
v.string(),
|
|
63
|
+
v.regex(/^\d{4}-\d{2}-\d{2}$/, 'Must be in YYYY-MM-DD format'),
|
|
64
|
+
v.transform((val) => {
|
|
65
|
+
const [year, month, day] = parseISOParts(val);
|
|
66
|
+
return new Date(Date.UTC(year, month - 1, day));
|
|
67
|
+
}),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @deprecated Alias for dateSchema for backward compatibility
|
|
72
|
+
*/
|
|
73
|
+
export const temporalDateSchema = dateSchema;
|
|
74
|
+
|
|
75
|
+
export type DatePickerValue = v.InferOutput<typeof datePickerValueSchema>;
|
|
76
|
+
export type DateRange = v.InferOutput<typeof dateRangeSchema>;
|