@zag-js/date-utils 0.69.0 → 0.71.0

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/src/pagination.ts DELETED
@@ -1,301 +0,0 @@
1
- import {
2
- type DateDuration,
3
- type DateValue,
4
- endOfMonth,
5
- endOfWeek,
6
- startOfMonth,
7
- startOfWeek,
8
- } from "@internationalized/date"
9
- import { isDateInvalid } from "./assertion"
10
- import { alignEnd, alignStart, constrainStart, constrainValue } from "./constrain"
11
- import { getEndDate, getUnitDuration } from "./duration"
12
-
13
- export interface AdjustDateParams {
14
- startDate: DateValue
15
- focusedDate: DateValue
16
- }
17
-
18
- export interface AdjustDateReturn extends AdjustDateParams {
19
- endDate: DateValue
20
- }
21
-
22
- export function getAdjustedDateFn(
23
- visibleDuration: DateDuration,
24
- locale: string,
25
- minValue?: DateValue,
26
- maxValue?: DateValue,
27
- ) {
28
- return function getDate(options: AdjustDateParams): AdjustDateReturn {
29
- const { startDate, focusedDate } = options
30
- const endDate = getEndDate(startDate, visibleDuration)
31
-
32
- // If the focused date was moved to an invalid value, it can't be focused, so constrain it.
33
- if (isDateInvalid(focusedDate, minValue, maxValue)) {
34
- return {
35
- startDate,
36
- focusedDate: constrainValue(focusedDate, minValue, maxValue),
37
- endDate,
38
- }
39
- }
40
-
41
- if (focusedDate.compare(startDate) < 0) {
42
- return {
43
- startDate: alignEnd(focusedDate, visibleDuration, locale, minValue, maxValue),
44
- focusedDate: constrainValue(focusedDate, minValue, maxValue),
45
- endDate,
46
- }
47
- }
48
-
49
- if (focusedDate.compare(endDate) > 0) {
50
- return {
51
- startDate: alignStart(focusedDate, visibleDuration, locale, minValue, maxValue),
52
- endDate,
53
- focusedDate: constrainValue(focusedDate, minValue, maxValue),
54
- }
55
- }
56
-
57
- return {
58
- startDate,
59
- endDate,
60
- focusedDate: constrainValue(focusedDate, minValue, maxValue),
61
- }
62
- }
63
- }
64
-
65
- /* -----------------------------------------------------------------------------
66
- * Get next and previous page (for date range)
67
- * -----------------------------------------------------------------------------*/
68
-
69
- export function getNextPage(
70
- focusedDate: DateValue,
71
- startDate: DateValue,
72
- visibleDuration: DateDuration,
73
- locale: string,
74
- minValue?: DateValue,
75
- maxValue?: DateValue,
76
- ) {
77
- const adjust = getAdjustedDateFn(visibleDuration, locale, minValue, maxValue)
78
- const start = startDate.add(visibleDuration)
79
-
80
- return adjust({
81
- focusedDate: focusedDate.add(visibleDuration),
82
- startDate: alignStart(
83
- constrainStart(focusedDate, start, visibleDuration, locale, minValue, maxValue),
84
- visibleDuration,
85
- locale,
86
- ),
87
- })
88
- }
89
-
90
- export function getPreviousPage(
91
- focusedDate: DateValue,
92
- startDate: DateValue,
93
- visibleDuration: DateDuration,
94
- locale: string,
95
- minValue?: DateValue,
96
- maxValue?: DateValue,
97
- ) {
98
- const adjust = getAdjustedDateFn(visibleDuration, locale, minValue, maxValue)
99
- let start = startDate.subtract(visibleDuration)
100
-
101
- return adjust({
102
- focusedDate: focusedDate.subtract(visibleDuration),
103
- startDate: alignStart(
104
- constrainStart(focusedDate, start, visibleDuration, locale, minValue, maxValue),
105
- visibleDuration,
106
- locale,
107
- ),
108
- })
109
- }
110
-
111
- /* -----------------------------------------------------------------------------
112
- * Get the next and previous row (for date range)
113
- * -----------------------------------------------------------------------------*/
114
-
115
- export function getNextRow(
116
- focusedDate: DateValue,
117
- startDate: DateValue,
118
- visibleDuration: DateDuration,
119
- locale: string,
120
- minValue?: DateValue,
121
- maxValue?: DateValue,
122
- ) {
123
- const adjust = getAdjustedDateFn(visibleDuration, locale, minValue, maxValue)
124
-
125
- if (visibleDuration.days) {
126
- return getNextPage(focusedDate, startDate, visibleDuration, locale, minValue, maxValue)
127
- }
128
-
129
- if (visibleDuration.weeks || visibleDuration.months || visibleDuration.years) {
130
- return adjust({
131
- focusedDate: focusedDate.add({ weeks: 1 }),
132
- startDate,
133
- })
134
- }
135
- }
136
-
137
- export function getPreviousRow(
138
- focusedDate: DateValue,
139
- startDate: DateValue,
140
- visibleDuration: DateDuration,
141
- locale: string,
142
- minValue?: DateValue,
143
- maxValue?: DateValue,
144
- ) {
145
- const adjust = getAdjustedDateFn(visibleDuration, locale, minValue, maxValue)
146
-
147
- if (visibleDuration.days) {
148
- return getPreviousPage(focusedDate, startDate, visibleDuration, locale, minValue, maxValue)
149
- }
150
-
151
- if (visibleDuration.weeks || visibleDuration.months || visibleDuration.years) {
152
- return adjust({
153
- focusedDate: focusedDate.subtract({ weeks: 1 }),
154
- startDate,
155
- })
156
- }
157
- }
158
-
159
- /* -----------------------------------------------------------------------------
160
- * Get start and end date for a date section
161
- * -----------------------------------------------------------------------------*/
162
-
163
- export function getSectionStart(
164
- focusedDate: DateValue,
165
- startDate: DateValue,
166
- visibleDuration: DateDuration,
167
- locale: string,
168
- minValue?: DateValue,
169
- maxValue?: DateValue,
170
- ) {
171
- const adjust = getAdjustedDateFn(visibleDuration, locale, minValue, maxValue)
172
-
173
- if (visibleDuration.days) {
174
- return adjust({
175
- focusedDate: startDate,
176
- startDate,
177
- })
178
- }
179
-
180
- if (visibleDuration.weeks) {
181
- return adjust({
182
- focusedDate: startOfWeek(focusedDate, locale),
183
- startDate,
184
- })
185
- }
186
-
187
- if (visibleDuration.months || visibleDuration.years) {
188
- return adjust({
189
- focusedDate: startOfMonth(focusedDate),
190
- startDate,
191
- })
192
- }
193
- }
194
-
195
- export function getSectionEnd(
196
- focusedDate: DateValue,
197
- startDate: DateValue,
198
- visibleDuration: DateDuration,
199
- locale: string,
200
- minValue?: DateValue,
201
- maxValue?: DateValue,
202
- ) {
203
- const adjust = getAdjustedDateFn(visibleDuration, locale, minValue, maxValue)
204
- const endDate = getEndDate(startDate, visibleDuration)
205
-
206
- if (visibleDuration.days) {
207
- return adjust({
208
- focusedDate: endDate,
209
- startDate,
210
- })
211
- }
212
-
213
- if (visibleDuration.weeks) {
214
- return adjust({
215
- //@ts-expect-error - endOfWeek is loosely typed
216
- focusedDate: endOfWeek(focusedDate, locale),
217
- startDate,
218
- })
219
- }
220
-
221
- if (visibleDuration.months || visibleDuration.years) {
222
- return adjust({
223
- focusedDate: endOfMonth(focusedDate),
224
- startDate,
225
- })
226
- }
227
- }
228
-
229
- export function getNextSection(
230
- focusedDate: DateValue,
231
- startDate: DateValue,
232
- larger: boolean,
233
- visibleDuration: DateDuration,
234
- locale: string,
235
- minValue?: DateValue,
236
- maxValue?: DateValue,
237
- ) {
238
- const adjust = getAdjustedDateFn(visibleDuration, locale, minValue, maxValue)
239
-
240
- if (!larger && !visibleDuration.days) {
241
- return adjust({
242
- focusedDate: focusedDate.add(getUnitDuration(visibleDuration)),
243
- startDate,
244
- })
245
- }
246
-
247
- if (visibleDuration.days) {
248
- return getNextPage(focusedDate, startDate, visibleDuration, locale, minValue, maxValue)
249
- }
250
-
251
- if (visibleDuration.weeks) {
252
- return adjust({
253
- focusedDate: focusedDate.add({ months: 1 }),
254
- startDate,
255
- })
256
- }
257
-
258
- if (visibleDuration.months || visibleDuration.years) {
259
- return adjust({
260
- focusedDate: focusedDate.add({ years: 1 }),
261
- startDate,
262
- })
263
- }
264
- }
265
-
266
- export function getPreviousSection(
267
- focusedDate: DateValue,
268
- startDate: DateValue,
269
- larger: boolean,
270
- visibleDuration: DateDuration,
271
- locale: string,
272
- minValue?: DateValue,
273
- maxValue?: DateValue,
274
- ) {
275
- const adjust = getAdjustedDateFn(visibleDuration, locale, minValue, maxValue)
276
-
277
- if (!larger && !visibleDuration.days) {
278
- return adjust({
279
- focusedDate: focusedDate.subtract(getUnitDuration(visibleDuration)),
280
- startDate,
281
- })
282
- }
283
-
284
- if (visibleDuration.days) {
285
- return getPreviousPage(focusedDate, startDate, visibleDuration, locale, minValue, maxValue)
286
- }
287
-
288
- if (visibleDuration.weeks) {
289
- return adjust({
290
- focusedDate: focusedDate.subtract({ months: 1 }),
291
- startDate,
292
- })
293
- }
294
-
295
- if (visibleDuration.months || visibleDuration.years) {
296
- return adjust({
297
- focusedDate: focusedDate.subtract({ years: 1 }),
298
- startDate,
299
- })
300
- }
301
- }
package/src/parse-date.ts DELETED
@@ -1,73 +0,0 @@
1
- import { CalendarDate, DateFormatter, type DateValue } from "@internationalized/date"
2
- import { normalizeYear } from "./normalize-year"
3
-
4
- const isValidYear = (year: string | null | undefined): year is string => year != null && year.length === 4
5
- const isValidMonth = (month: string | null | undefined): month is string => month != null && parseFloat(month) <= 12
6
- const isValidDay = (day: string | null | undefined): day is string => day != null && parseFloat(day) <= 31
7
-
8
- export function parseDateString(date: string, locale: string, timeZone: string): DateValue | undefined {
9
- const regex = createRegex(locale, timeZone)
10
-
11
- let { year, month, day } = extract(regex, date) ?? {}
12
-
13
- const hasMatch = year != null || month != null || day != null
14
-
15
- if (hasMatch) {
16
- const curr = new Date()
17
- year ||= curr.getFullYear().toString()
18
- month ||= (curr.getMonth() + 1).toString()
19
- day ||= curr.getDate().toString()
20
- }
21
-
22
- if (!isValidYear(year)) {
23
- year = normalizeYear(year)
24
- }
25
-
26
- if (isValidYear(year) && isValidMonth(month) && isValidDay(day)) {
27
- return new CalendarDate(+year, +month, +day)
28
- }
29
-
30
- // We should never get here, but just in case
31
- const time = Date.parse(date)
32
- if (!isNaN(time)) {
33
- const date = new Date(time)
34
- return new CalendarDate(date.getFullYear(), date.getMonth() + 1, date.getDate())
35
- }
36
- }
37
-
38
- function createRegex(locale: string, timeZone: string) {
39
- const formatter = new DateFormatter(locale, { day: "numeric", month: "numeric", year: "numeric", timeZone })
40
- const parts = formatter.formatToParts(new Date(2000, 11, 25))
41
- return parts.map(({ type, value }) => (type === "literal" ? `${value}?` : `((?!=<${type}>)\\d+)?`)).join("")
42
- }
43
-
44
- interface DateParts {
45
- year: string | null
46
- month: string | null
47
- day: string | null
48
- }
49
-
50
- type DatePart = keyof DateParts
51
-
52
- function extract(pattern: string | RegExp, str: string) {
53
- const matches = str.match(pattern)
54
- return pattern
55
- .toString()
56
- .match(/<(.+?)>/g)
57
- ?.map((group) => {
58
- const groupMatches = group.match(/<(.+)>/)
59
- if (!groupMatches || groupMatches.length <= 0) {
60
- return null
61
- }
62
- return group.match(/<(.+)>/)?.[1]
63
- })
64
- .reduce((acc, curr, index) => {
65
- if (!curr) return acc
66
- if (matches && matches.length > index) {
67
- acc[curr as DatePart] = matches[index + 1]
68
- } else {
69
- acc[curr as DatePart] = null
70
- }
71
- return acc
72
- }, {} as DateParts)
73
- }
package/src/preset.ts DELETED
@@ -1,63 +0,0 @@
1
- import {
2
- endOfMonth,
3
- endOfWeek,
4
- endOfYear,
5
- now,
6
- startOfMonth,
7
- startOfWeek,
8
- startOfYear,
9
- type DateValue,
10
- } from "@internationalized/date"
11
-
12
- export type DateRangePreset =
13
- | "thisWeek"
14
- | "lastWeek"
15
- | "thisMonth"
16
- | "lastMonth"
17
- | "thisQuarter"
18
- | "lastQuarter"
19
- | "thisYear"
20
- | "lastYear"
21
- | "last3Days"
22
- | "last7Days"
23
- | "last14Days"
24
- | "last30Days"
25
- | "last90Days"
26
-
27
- export function getDateRangePreset(preset: DateRangePreset, locale: string, timeZone: string): [DateValue, DateValue] {
28
- const today = now(timeZone)
29
-
30
- switch (preset) {
31
- case "thisWeek":
32
- return [startOfWeek(today, locale), endOfWeek(today, locale)]
33
- case "thisMonth":
34
- return [startOfMonth(today), today]
35
- case "thisQuarter":
36
- return [startOfMonth(today).add({ months: -today.month % 3 }), today]
37
- case "thisYear":
38
- return [startOfYear(today), today]
39
- case "last3Days":
40
- return [today.add({ days: -2 }), today]
41
- case "last7Days":
42
- return [today.add({ days: -6 }), today]
43
- case "last14Days":
44
- return [today.add({ days: -13 }), today]
45
- case "last30Days":
46
- return [today.add({ days: -29 }), today]
47
- case "last90Days":
48
- return [today.add({ days: -89 }), today]
49
- case "lastMonth":
50
- return [startOfMonth(today.add({ months: -1 })), endOfMonth(today.add({ months: -1 }))]
51
- case "lastQuarter":
52
- return [
53
- startOfMonth(today.add({ months: (-today.month % 3) - 3 })),
54
- endOfMonth(today.add({ months: (-today.month % 3) - 1 })),
55
- ]
56
- case "lastWeek":
57
- return [startOfWeek(today, locale).add({ weeks: -1 }), endOfWeek(today, locale).add({ weeks: -1 })]
58
- case "lastYear":
59
- return [startOfYear(today.add({ years: -1 })), endOfYear(today.add({ years: -1 }))]
60
- default:
61
- throw new Error(`Invalid date range preset: ${preset}`)
62
- }
63
- }
package/src/types.ts DELETED
@@ -1,14 +0,0 @@
1
- import type { DateFormatter, DateValue } from "@internationalized/date"
2
-
3
- export type DateGranularity = "day" | "hour" | "minute" | "second" | "year" | "month"
4
- export type DateAlignment = "start" | "end" | "center"
5
-
6
- export type GetFormatterFn = (options: Intl.DateTimeFormatOptions) => DateFormatter
7
- export type DateAvailableFn = (date: DateValue, locale: string) => boolean
8
- export type GetPlaceholderFn = (options: { field: string; locale: string }) => string
9
- export type DateAdjustFn = (options: { startDate: DateValue; focusedDate: DateValue }) => {
10
- startDate: DateValue
11
- focusedDate: DateValue
12
- endDate: DateValue
13
- }
14
- export type DateFormatOptions = Intl.ResolvedDateTimeFormatOptions