@trackunit/react-date-and-time-hooks 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/README.md +22 -0
- package/index.cjs.d.ts +1 -0
- package/index.cjs.js +507 -0
- package/index.esm.d.ts +1 -0
- package/index.esm.js +500 -0
- package/package.json +29 -0
- package/src/generated/graphql-api/fragment-masking.d.ts +15 -0
- package/src/generated/graphql-api/gql.d.ts +36 -0
- package/src/generated/graphql-api/graphql.d.ts +134 -0
- package/src/generated/graphql-api/index.d.ts +2 -0
- package/src/generated/graphql-api/mock.d.ts +5 -0
- package/src/index.d.ts +4 -0
- package/src/localeUtils.d.ts +7 -0
- package/src/test/index.d.ts +1 -0
- package/src/test/mocks/mockAssetTimezone.d.ts +15 -0
- package/src/useDateAndTime.d.ts +35 -0
- package/src/useLocale.d.ts +4 -0
- package/src/useTimezone.d.ts +27 -0
package/index.esm.js
ADDED
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
import { Temporal } from '@js-temporal/polyfill';
|
|
2
|
+
import { getTimeZone, toZonedDateTimeUtil, toDateUtil, formatDateUtil, formatRangeUtil, subtractYearsUtil, subtractMonthsUtil, subtractWeeksUtil, subtractDaysUtil, subtractHoursUtil, subtractMinutesUtil, addYearsUtil, addMonthsUtil, addWeeksUtil, addDaysUtil, addHoursUtil, addMinutesUtil, startOfMonthUtil, startOfWeekUtil, startOfDayUtil, startOfHourUtil, startOfMinuteUtil, endOfMonthUtil, endOfWeekUtil, endOfDayUtil, endOfHourUtil, endOfMinuteUtil, differenceInMonthsUtil, differenceInWeeksUtil, differenceInDaysUtil, differenceInHoursUtil, differenceInMinutesUtil, isBetweenUtil, isTodayUtil, isFutureUtil, isPastUtil, isSameYearUtil, isSameMonthUtil, isSameWeekUtil, isSameDayUtil, timeSinceInYears, timeSinceInMonths, timeSinceInDays, timeSinceInHours, timeSinceInMinutes, timeSinceInSeconds, timeSinceAuto, toDuration, getDurationFormat, dayNameUtil, daysUtil, monthNameUtil, monthsUtil, isEqualUtil } from '@trackunit/date-and-time-utils';
|
|
3
|
+
import { exhaustiveCheck } from '@trackunit/shared-utils';
|
|
4
|
+
import { useMemo, useCallback } from 'react';
|
|
5
|
+
import { useQuery } from '@apollo/client';
|
|
6
|
+
import { useLocalStorage } from '@trackunit/react-components';
|
|
7
|
+
import { TimeZonePreference } from '@trackunit/react-core-contexts-api';
|
|
8
|
+
import { useCurrentUserTimeZonePreference } from '@trackunit/react-core-hooks';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Try to convert to ISO standard. ex. en becomes en-GB if its in United Kingdom.
|
|
13
|
+
* Still looking at the base id.
|
|
14
|
+
*
|
|
15
|
+
* @param userPreferenceLanguage 2 letter language code from the persisted language selection.
|
|
16
|
+
*/
|
|
17
|
+
const convertToLocale = (userPreferenceLanguage) => {
|
|
18
|
+
const browserLanguage = navigator.language;
|
|
19
|
+
if (browserLanguage.indexOf("-") !== -1 && browserLanguage.startsWith(userPreferenceLanguage)) {
|
|
20
|
+
return browserLanguage;
|
|
21
|
+
}
|
|
22
|
+
return userPreferenceLanguage;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
var _a;
|
|
26
|
+
const LANG_STORAGE_KEY = "i18nextLng";
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
28
|
+
const BrowserLocale = (_a = navigator.language) !== null && _a !== void 0 ? _a : "en";
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
*/
|
|
32
|
+
const useLocale = () => {
|
|
33
|
+
const savedLanguage = localStorage.getItem(LANG_STORAGE_KEY);
|
|
34
|
+
const selectedLanguage = savedLanguage || BrowserLocale || "en";
|
|
35
|
+
const userLocale = convertToLocale(selectedLanguage);
|
|
36
|
+
return userLocale || BrowserLocale;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const GetAssetTimezoneDocument = {
|
|
40
|
+
kind: "Document",
|
|
41
|
+
definitions: [
|
|
42
|
+
{
|
|
43
|
+
kind: "OperationDefinition",
|
|
44
|
+
operation: "query",
|
|
45
|
+
name: { kind: "Name", value: "GetAssetTimezone" },
|
|
46
|
+
variableDefinitions: [
|
|
47
|
+
{
|
|
48
|
+
kind: "VariableDefinition",
|
|
49
|
+
variable: { kind: "Variable", name: { kind: "Name", value: "assetId" } },
|
|
50
|
+
type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "ID" } } },
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
selectionSet: {
|
|
54
|
+
kind: "SelectionSet",
|
|
55
|
+
selections: [
|
|
56
|
+
{
|
|
57
|
+
kind: "Field",
|
|
58
|
+
name: { kind: "Name", value: "asset" },
|
|
59
|
+
arguments: [
|
|
60
|
+
{
|
|
61
|
+
kind: "Argument",
|
|
62
|
+
name: { kind: "Name", value: "id" },
|
|
63
|
+
value: { kind: "Variable", name: { kind: "Name", value: "assetId" } },
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
selectionSet: {
|
|
67
|
+
kind: "SelectionSet",
|
|
68
|
+
selections: [
|
|
69
|
+
{
|
|
70
|
+
kind: "Field",
|
|
71
|
+
name: { kind: "Name", value: "locations" },
|
|
72
|
+
selectionSet: {
|
|
73
|
+
kind: "SelectionSet",
|
|
74
|
+
selections: [
|
|
75
|
+
{
|
|
76
|
+
kind: "Field",
|
|
77
|
+
name: { kind: "Name", value: "latest" },
|
|
78
|
+
selectionSet: {
|
|
79
|
+
kind: "SelectionSet",
|
|
80
|
+
selections: [
|
|
81
|
+
{
|
|
82
|
+
kind: "Field",
|
|
83
|
+
name: { kind: "Name", value: "properties" },
|
|
84
|
+
selectionSet: {
|
|
85
|
+
kind: "SelectionSet",
|
|
86
|
+
selections: [{ kind: "Field", name: { kind: "Name", value: "timeZone" } }],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
*
|
|
106
|
+
*/
|
|
107
|
+
const useTimezone = ({ assetId } = {}) => {
|
|
108
|
+
var _a, _b, _c, _d;
|
|
109
|
+
const { timeZonePreference } = useCurrentUserTimeZonePreference();
|
|
110
|
+
const [customTimezone, setCustomTimezone] = useLocalStorage({
|
|
111
|
+
key: "customTimeZone",
|
|
112
|
+
defaultState: null,
|
|
113
|
+
schema: z.string().nullable(),
|
|
114
|
+
});
|
|
115
|
+
const { data: timeZoneData } = useQuery(GetAssetTimezoneDocument, {
|
|
116
|
+
variables: {
|
|
117
|
+
// eslint-disable-next-line local-rules/no-typescript-assertion
|
|
118
|
+
assetId: assetId,
|
|
119
|
+
},
|
|
120
|
+
skip: !assetId,
|
|
121
|
+
fetchPolicy: "cache-first",
|
|
122
|
+
});
|
|
123
|
+
const assetTimeZone = useMemo(() => {
|
|
124
|
+
var _a, _b, _c, _d;
|
|
125
|
+
const timezone = (_d = (_c = (_b = (_a = timeZoneData === null || timeZoneData === void 0 ? void 0 : timeZoneData.asset) === null || _a === void 0 ? void 0 : _a.locations) === null || _b === void 0 ? void 0 : _b.latest) === null || _c === void 0 ? void 0 : _c.properties) === null || _d === void 0 ? void 0 : _d.timeZone;
|
|
126
|
+
if (!timezone) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
return getTimeZone(timezone);
|
|
130
|
+
}, [(_d = (_c = (_b = (_a = timeZoneData === null || timeZoneData === void 0 ? void 0 : timeZoneData.asset) === null || _a === void 0 ? void 0 : _a.locations) === null || _b === void 0 ? void 0 : _b.latest) === null || _c === void 0 ? void 0 : _c.properties) === null || _d === void 0 ? void 0 : _d.timeZone]);
|
|
131
|
+
const current = useMemo(() => {
|
|
132
|
+
const id = Temporal.Now.timeZoneId();
|
|
133
|
+
if (timeZonePreference === TimeZonePreference.CustomTimeZone && customTimezone) {
|
|
134
|
+
return getTimeZone(customTimezone);
|
|
135
|
+
}
|
|
136
|
+
return getTimeZone(id);
|
|
137
|
+
}, [customTimezone, timeZonePreference]);
|
|
138
|
+
const preferred = useMemo(() => {
|
|
139
|
+
if (timeZonePreference === TimeZonePreference.MachineTimeZone && assetTimeZone) {
|
|
140
|
+
return assetTimeZone;
|
|
141
|
+
}
|
|
142
|
+
return current;
|
|
143
|
+
}, [timeZonePreference, current, assetTimeZone]);
|
|
144
|
+
return {
|
|
145
|
+
current,
|
|
146
|
+
assetTimeZone,
|
|
147
|
+
preferred,
|
|
148
|
+
setCustomTimezone,
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
*
|
|
154
|
+
*/
|
|
155
|
+
const useDateAndTime = () => {
|
|
156
|
+
const currentLocale = useLocale();
|
|
157
|
+
const { current, assetTimeZone, preferred } = useTimezone();
|
|
158
|
+
const currentTimeZone = current.id || preferred.id || (assetTimeZone === null || assetTimeZone === void 0 ? void 0 : assetTimeZone.id);
|
|
159
|
+
const currentDate = toZonedDateTimeUtil(Temporal.Now.instant(), currentTimeZone);
|
|
160
|
+
/**
|
|
161
|
+
* Returns the current date and time.
|
|
162
|
+
*
|
|
163
|
+
* @returns {Date}
|
|
164
|
+
*/
|
|
165
|
+
const nowDate = toDateUtil(currentDate);
|
|
166
|
+
/**
|
|
167
|
+
* Formats a date using the current locale and time zone.
|
|
168
|
+
*
|
|
169
|
+
* @param {Date} date
|
|
170
|
+
* @param {TemporalFormat} format
|
|
171
|
+
* @returns {string}
|
|
172
|
+
*/
|
|
173
|
+
const formatDate = useCallback((date, format) => {
|
|
174
|
+
return formatDateUtil(date, format, currentTimeZone, currentLocale);
|
|
175
|
+
}, [currentLocale, currentTimeZone]);
|
|
176
|
+
/**
|
|
177
|
+
* Formats a date using the custom locale and custom timezone.
|
|
178
|
+
*
|
|
179
|
+
* @param {Date} date
|
|
180
|
+
* @param {TemporalFormat} format
|
|
181
|
+
* @param {string} timezone
|
|
182
|
+
* @param {string} locale
|
|
183
|
+
* @returns {string}
|
|
184
|
+
*/
|
|
185
|
+
const formatDateWithTimezone = useCallback((date, format, timezone, locale) => {
|
|
186
|
+
return formatDateUtil(date, format, timezone !== null && timezone !== void 0 ? timezone : currentTimeZone, locale !== null && locale !== void 0 ? locale : currentLocale);
|
|
187
|
+
}, [currentLocale, currentTimeZone]);
|
|
188
|
+
/**
|
|
189
|
+
* Formats a date range using the current locale and time zone.
|
|
190
|
+
*
|
|
191
|
+
* @param {Date} start
|
|
192
|
+
* @param {Date} end
|
|
193
|
+
* @param {Intl.DateTimeFormatOptions} format
|
|
194
|
+
* @returns {string}
|
|
195
|
+
*/
|
|
196
|
+
const formatRange = useCallback((range, format) => formatRangeUtil(range, currentLocale, format), [currentLocale]);
|
|
197
|
+
/**
|
|
198
|
+
* Subtracts a given amount of time from a date.
|
|
199
|
+
*
|
|
200
|
+
* @param {TemporalDate} date
|
|
201
|
+
* @param {number} amount
|
|
202
|
+
* @param {TemporalArithmeticType} type
|
|
203
|
+
* @returns {Date}
|
|
204
|
+
*/
|
|
205
|
+
const subtract = useCallback((date, amount, type) => {
|
|
206
|
+
let returnFn;
|
|
207
|
+
switch (type) {
|
|
208
|
+
case "minutes":
|
|
209
|
+
returnFn = subtractMinutesUtil(date, amount, currentTimeZone);
|
|
210
|
+
break;
|
|
211
|
+
case "hours":
|
|
212
|
+
returnFn = subtractHoursUtil(date, amount, currentTimeZone);
|
|
213
|
+
break;
|
|
214
|
+
case "days":
|
|
215
|
+
returnFn = subtractDaysUtil(date, amount, currentTimeZone);
|
|
216
|
+
break;
|
|
217
|
+
case "weeks":
|
|
218
|
+
returnFn = subtractWeeksUtil(date, amount, currentTimeZone);
|
|
219
|
+
break;
|
|
220
|
+
case "months":
|
|
221
|
+
returnFn = subtractMonthsUtil(date, amount, currentTimeZone);
|
|
222
|
+
break;
|
|
223
|
+
case "years":
|
|
224
|
+
returnFn = subtractYearsUtil(date, amount, currentTimeZone);
|
|
225
|
+
break;
|
|
226
|
+
default:
|
|
227
|
+
return exhaustiveCheck(type);
|
|
228
|
+
}
|
|
229
|
+
return toDateUtil(returnFn);
|
|
230
|
+
}, [currentTimeZone]);
|
|
231
|
+
/**
|
|
232
|
+
* Adds a given amount of time to a date.
|
|
233
|
+
*
|
|
234
|
+
* @param {TemporalDate} date
|
|
235
|
+
* @param {number} amount
|
|
236
|
+
* @param {TemporalArithmeticType} type
|
|
237
|
+
*/
|
|
238
|
+
const add = useCallback((date, amount, type) => {
|
|
239
|
+
let returnFn;
|
|
240
|
+
switch (type) {
|
|
241
|
+
case "minutes":
|
|
242
|
+
returnFn = addMinutesUtil(date, amount, currentTimeZone);
|
|
243
|
+
break;
|
|
244
|
+
case "hours":
|
|
245
|
+
returnFn = addHoursUtil(date, amount, currentTimeZone);
|
|
246
|
+
break;
|
|
247
|
+
case "days":
|
|
248
|
+
returnFn = addDaysUtil(date, amount, currentTimeZone);
|
|
249
|
+
break;
|
|
250
|
+
case "weeks":
|
|
251
|
+
returnFn = addWeeksUtil(date, amount, currentTimeZone);
|
|
252
|
+
break;
|
|
253
|
+
case "months":
|
|
254
|
+
returnFn = addMonthsUtil(date, amount, currentTimeZone);
|
|
255
|
+
break;
|
|
256
|
+
case "years":
|
|
257
|
+
returnFn = addYearsUtil(date, amount, currentTimeZone);
|
|
258
|
+
break;
|
|
259
|
+
default:
|
|
260
|
+
return exhaustiveCheck(type);
|
|
261
|
+
}
|
|
262
|
+
return toDateUtil(returnFn);
|
|
263
|
+
}, [currentTimeZone]);
|
|
264
|
+
/**
|
|
265
|
+
* Returns the start of a given time period.
|
|
266
|
+
*
|
|
267
|
+
* @param {TemporalDate} date
|
|
268
|
+
* @param {TemporalEdgeOfType} type
|
|
269
|
+
* @returns {Date}
|
|
270
|
+
*/
|
|
271
|
+
const startOf = useCallback((date, type) => {
|
|
272
|
+
let returnFn;
|
|
273
|
+
switch (type) {
|
|
274
|
+
case "minute":
|
|
275
|
+
returnFn = startOfMinuteUtil(date, currentTimeZone);
|
|
276
|
+
break;
|
|
277
|
+
case "hour":
|
|
278
|
+
returnFn = startOfHourUtil(date, currentTimeZone);
|
|
279
|
+
break;
|
|
280
|
+
case "day":
|
|
281
|
+
returnFn = startOfDayUtil(date, currentTimeZone);
|
|
282
|
+
break;
|
|
283
|
+
case "week":
|
|
284
|
+
returnFn = startOfWeekUtil(date, currentTimeZone);
|
|
285
|
+
break;
|
|
286
|
+
case "month":
|
|
287
|
+
returnFn = startOfMonthUtil(date, currentTimeZone);
|
|
288
|
+
break;
|
|
289
|
+
default:
|
|
290
|
+
return exhaustiveCheck(type);
|
|
291
|
+
}
|
|
292
|
+
return toDateUtil(returnFn);
|
|
293
|
+
}, [currentTimeZone]);
|
|
294
|
+
/**
|
|
295
|
+
* Returns the end of a given time period.
|
|
296
|
+
*
|
|
297
|
+
* @param {TemporalDate} date
|
|
298
|
+
* @param {TemporalEdgeOfType} type
|
|
299
|
+
* @returns {Date}
|
|
300
|
+
*/
|
|
301
|
+
const endOf = useCallback((date, type) => {
|
|
302
|
+
let returnFn;
|
|
303
|
+
switch (type) {
|
|
304
|
+
case "minute":
|
|
305
|
+
returnFn = endOfMinuteUtil(date, currentTimeZone);
|
|
306
|
+
break;
|
|
307
|
+
case "hour":
|
|
308
|
+
returnFn = endOfHourUtil(date, currentTimeZone);
|
|
309
|
+
break;
|
|
310
|
+
case "day":
|
|
311
|
+
returnFn = endOfDayUtil(date, currentTimeZone);
|
|
312
|
+
break;
|
|
313
|
+
case "week":
|
|
314
|
+
returnFn = endOfWeekUtil(date, currentTimeZone);
|
|
315
|
+
break;
|
|
316
|
+
case "month":
|
|
317
|
+
returnFn = endOfMonthUtil(date, currentTimeZone);
|
|
318
|
+
break;
|
|
319
|
+
default:
|
|
320
|
+
return exhaustiveCheck(type);
|
|
321
|
+
}
|
|
322
|
+
return toDateUtil(returnFn);
|
|
323
|
+
}, [currentTimeZone]);
|
|
324
|
+
/**
|
|
325
|
+
* Returns the difference between two dates.
|
|
326
|
+
*
|
|
327
|
+
* @param {TemporalDate} from
|
|
328
|
+
* @param {TemporalDate} to
|
|
329
|
+
* @param {TemporalDifferenceType} type
|
|
330
|
+
* @returns {number}
|
|
331
|
+
*/
|
|
332
|
+
const difference = useCallback((from, to, type) => {
|
|
333
|
+
switch (type) {
|
|
334
|
+
case "minute":
|
|
335
|
+
return differenceInMinutesUtil(from, to);
|
|
336
|
+
case "hour":
|
|
337
|
+
return differenceInHoursUtil(from, to);
|
|
338
|
+
case "day":
|
|
339
|
+
return differenceInDaysUtil(from, to);
|
|
340
|
+
case "week":
|
|
341
|
+
return differenceInWeeksUtil(from, to);
|
|
342
|
+
case "month":
|
|
343
|
+
return differenceInMonthsUtil(from, to);
|
|
344
|
+
default:
|
|
345
|
+
return exhaustiveCheck(type);
|
|
346
|
+
}
|
|
347
|
+
}, []);
|
|
348
|
+
/**
|
|
349
|
+
* Returns whether a date is in the past, present or future.
|
|
350
|
+
*
|
|
351
|
+
* @param {TemporalDate} date
|
|
352
|
+
* @param {TemporalIsType} type
|
|
353
|
+
* @returns {boolean}
|
|
354
|
+
*/
|
|
355
|
+
const dateIs = useCallback((date, type, betweenDates) => {
|
|
356
|
+
switch (type) {
|
|
357
|
+
case "past":
|
|
358
|
+
return isPastUtil(date);
|
|
359
|
+
case "future":
|
|
360
|
+
return isFutureUtil(date);
|
|
361
|
+
case "present":
|
|
362
|
+
return isTodayUtil(date);
|
|
363
|
+
case "between":
|
|
364
|
+
return isBetweenUtil(date, betweenDates === null || betweenDates === void 0 ? void 0 : betweenDates.start, betweenDates === null || betweenDates === void 0 ? void 0 : betweenDates.end);
|
|
365
|
+
default:
|
|
366
|
+
return exhaustiveCheck(type);
|
|
367
|
+
}
|
|
368
|
+
}, []);
|
|
369
|
+
/**
|
|
370
|
+
* Returns whether a date is same day/week/month or year.
|
|
371
|
+
*
|
|
372
|
+
* @param {TemporalDate} date
|
|
373
|
+
* @param {TemporalSameType} type
|
|
374
|
+
* @returns {boolean}
|
|
375
|
+
*/
|
|
376
|
+
const same = useCallback((date, type) => {
|
|
377
|
+
switch (type) {
|
|
378
|
+
case "day":
|
|
379
|
+
return isSameDayUtil(date);
|
|
380
|
+
case "week":
|
|
381
|
+
return isSameWeekUtil(date);
|
|
382
|
+
case "month":
|
|
383
|
+
return isSameMonthUtil(date);
|
|
384
|
+
case "year":
|
|
385
|
+
return isSameYearUtil(date);
|
|
386
|
+
default:
|
|
387
|
+
return exhaustiveCheck(type);
|
|
388
|
+
}
|
|
389
|
+
}, []);
|
|
390
|
+
/**
|
|
391
|
+
* Returns the time since a given date.
|
|
392
|
+
*
|
|
393
|
+
* @param {TemporalDate} from
|
|
394
|
+
* @param {TemporalDate} to
|
|
395
|
+
* @param {TemporalSinceType} type
|
|
396
|
+
* @returns {string}
|
|
397
|
+
*/
|
|
398
|
+
const since = useCallback((from, to, type) => {
|
|
399
|
+
switch (type) {
|
|
400
|
+
case "auto":
|
|
401
|
+
return timeSinceAuto(from, to, currentTimeZone, currentLocale);
|
|
402
|
+
case "seconds":
|
|
403
|
+
return timeSinceInSeconds(from, to, currentTimeZone, currentLocale);
|
|
404
|
+
case "minutes":
|
|
405
|
+
return timeSinceInMinutes(from, to, currentTimeZone, currentLocale);
|
|
406
|
+
case "hours":
|
|
407
|
+
return timeSinceInHours(from, to, currentTimeZone, currentLocale);
|
|
408
|
+
case "days":
|
|
409
|
+
return timeSinceInDays(from, to, currentTimeZone, currentLocale);
|
|
410
|
+
case "months":
|
|
411
|
+
return timeSinceInMonths(from, to, currentTimeZone, currentLocale);
|
|
412
|
+
case "years":
|
|
413
|
+
return timeSinceInYears(from, to, currentTimeZone, currentLocale);
|
|
414
|
+
default:
|
|
415
|
+
return exhaustiveCheck(type);
|
|
416
|
+
}
|
|
417
|
+
}, [currentLocale, currentTimeZone]);
|
|
418
|
+
/**
|
|
419
|
+
* Returns a duration from a number
|
|
420
|
+
*
|
|
421
|
+
* @param {Duration} from
|
|
422
|
+
* @param {TemporalDurationType} type
|
|
423
|
+
* @param {TemporalFormat["dayFormat"]} format
|
|
424
|
+
* @example type: "hours", { hours: 230, minutes: 27 } = 230 hours, 27 minutes
|
|
425
|
+
* @example type: "hours", 230.45 = 230 hours, 27 minutes
|
|
426
|
+
* @returns {string}
|
|
427
|
+
*/
|
|
428
|
+
const duration = useCallback((from, type, format, roundAt) => {
|
|
429
|
+
const durationValue = typeof from === "number"
|
|
430
|
+
? toDuration(from, type, roundAt)
|
|
431
|
+
: Temporal.Duration.from(from).round({ smallestUnit: roundAt !== null && roundAt !== void 0 ? roundAt : "minute" });
|
|
432
|
+
return getDurationFormat(durationValue, currentLocale, format);
|
|
433
|
+
}, [currentLocale]);
|
|
434
|
+
/**
|
|
435
|
+
* Returns the name of a day.
|
|
436
|
+
*
|
|
437
|
+
* @param {TemporalDate} date
|
|
438
|
+
* @param {TemporalFormatStyle} format
|
|
439
|
+
* @returns {string}
|
|
440
|
+
*/
|
|
441
|
+
const dayName = useCallback((date, format) => {
|
|
442
|
+
return dayNameUtil(date, format, currentLocale);
|
|
443
|
+
}, [currentLocale]);
|
|
444
|
+
const days = useCallback((format) => {
|
|
445
|
+
return daysUtil(format, currentLocale);
|
|
446
|
+
}, [currentLocale]);
|
|
447
|
+
/**
|
|
448
|
+
* Returns the name of a month.
|
|
449
|
+
*
|
|
450
|
+
* @param {TemporalDate} date
|
|
451
|
+
* @param {TemporalFormatStyle} format
|
|
452
|
+
* @returns {string}
|
|
453
|
+
*/
|
|
454
|
+
const monthName = useCallback((date, format) => {
|
|
455
|
+
return monthNameUtil(date, format, currentLocale);
|
|
456
|
+
}, [currentLocale]);
|
|
457
|
+
const months = useCallback((format) => {
|
|
458
|
+
return monthsUtil(format, currentLocale);
|
|
459
|
+
}, [currentLocale]);
|
|
460
|
+
return useMemo(() => ({
|
|
461
|
+
nowDate,
|
|
462
|
+
formatDate,
|
|
463
|
+
formatDateWithTimezone,
|
|
464
|
+
formatRange,
|
|
465
|
+
startOf,
|
|
466
|
+
endOf,
|
|
467
|
+
add,
|
|
468
|
+
subtract,
|
|
469
|
+
difference,
|
|
470
|
+
since,
|
|
471
|
+
same,
|
|
472
|
+
duration,
|
|
473
|
+
dateIs,
|
|
474
|
+
isEqual: isEqualUtil,
|
|
475
|
+
monthName,
|
|
476
|
+
months,
|
|
477
|
+
dayName,
|
|
478
|
+
days,
|
|
479
|
+
}), [
|
|
480
|
+
add,
|
|
481
|
+
dateIs,
|
|
482
|
+
dayName,
|
|
483
|
+
days,
|
|
484
|
+
difference,
|
|
485
|
+
duration,
|
|
486
|
+
endOf,
|
|
487
|
+
formatDate,
|
|
488
|
+
formatDateWithTimezone,
|
|
489
|
+
formatRange,
|
|
490
|
+
monthName,
|
|
491
|
+
months,
|
|
492
|
+
nowDate,
|
|
493
|
+
same,
|
|
494
|
+
since,
|
|
495
|
+
startOf,
|
|
496
|
+
subtract,
|
|
497
|
+
]);
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
export { convertToLocale, useDateAndTime, useLocale, useTimezone };
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trackunit/react-date-and-time-hooks",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"repository": "https://github.com/Trackunit/manager",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=20.x"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"date-fns": "^2.30.0",
|
|
11
|
+
"@graphql-codegen/cli": "^5.0.0",
|
|
12
|
+
"@trackunit/iris-app-build-utilities": "*",
|
|
13
|
+
"@graphql-typed-document-node/core": "^3.2.0",
|
|
14
|
+
"graphql": "^15.8.0",
|
|
15
|
+
"@trackunit/iris-app-api": "*",
|
|
16
|
+
"@apollo/client": "^3.7.10",
|
|
17
|
+
"@trackunit/react-core-contexts-test": "*",
|
|
18
|
+
"@js-temporal/polyfill": "^0.4.4",
|
|
19
|
+
"@trackunit/date-and-time-utils": "*",
|
|
20
|
+
"@trackunit/shared-utils": "*",
|
|
21
|
+
"react": "^18.2.0",
|
|
22
|
+
"@trackunit/react-components": "*",
|
|
23
|
+
"@trackunit/react-core-contexts-api": "*",
|
|
24
|
+
"@trackunit/react-core-hooks": "*",
|
|
25
|
+
"zod": "3.22.4"
|
|
26
|
+
},
|
|
27
|
+
"module": "./index.esm.js",
|
|
28
|
+
"main": "./index.cjs.js"
|
|
29
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ResultOf, DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
2
|
+
import { Incremental } from './graphql';
|
|
3
|
+
export type FragmentType<TDocumentType extends DocumentTypeDecoration<any, any>> = TDocumentType extends DocumentTypeDecoration<infer TType, any> ? [TType] extends [{
|
|
4
|
+
' $fragmentName'?: infer TKey;
|
|
5
|
+
}] ? TKey extends string ? {
|
|
6
|
+
' $fragmentRefs'?: {
|
|
7
|
+
[key in TKey]: TType;
|
|
8
|
+
};
|
|
9
|
+
} : never : never : never;
|
|
10
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>): TType;
|
|
11
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined): TType | null | undefined;
|
|
12
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>): ReadonlyArray<TType>;
|
|
13
|
+
export declare function getFragmentData<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined): ReadonlyArray<TType> | null | undefined;
|
|
14
|
+
export declare function makeFragmentData<F extends DocumentTypeDecoration<any, any>, FT extends ResultOf<F>>(data: FT, _fragment: F): FragmentType<F>;
|
|
15
|
+
export declare function isFragmentReady<TQuery, TFrag>(queryNode: DocumentTypeDecoration<TQuery, any>, fragmentNode: TypedDocumentNode<TFrag>, data: FragmentType<TypedDocumentNode<Incremental<TFrag>, any>> | null | undefined): data is FragmentType<typeof fragmentNode>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as types from './graphql';
|
|
2
|
+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
|
3
|
+
/**
|
|
4
|
+
* Map of all GraphQL operations in the project.
|
|
5
|
+
*
|
|
6
|
+
* This map has several performance disadvantages:
|
|
7
|
+
* 1. It is not tree-shakeable, so it will include all operations in the project.
|
|
8
|
+
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
|
|
9
|
+
* 3. It does not support dead code elimination, so it will add unused operations.
|
|
10
|
+
*
|
|
11
|
+
* Therefore it is highly recommended to use the babel or swc plugin for production.
|
|
12
|
+
*/
|
|
13
|
+
declare const documents: {
|
|
14
|
+
"query GetAssetTimezone($assetId: ID!) {\n asset(id: $assetId) {\n locations {\n latest {\n properties {\n timeZone\n }\n }\n }\n }\n}": DocumentNode<types.GetAssetTimezoneQuery, types.Exact<{
|
|
15
|
+
assetId: string;
|
|
16
|
+
}>>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
20
|
+
*
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const query = graphql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* The query argument is unknown!
|
|
28
|
+
* Please regenerate the types.
|
|
29
|
+
*/
|
|
30
|
+
export declare function graphql(source: string): unknown;
|
|
31
|
+
/**
|
|
32
|
+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
33
|
+
*/
|
|
34
|
+
export declare function graphql(source: "query GetAssetTimezone($assetId: ID!) {\n asset(id: $assetId) {\n locations {\n latest {\n properties {\n timeZone\n }\n }\n }\n }\n}"): (typeof documents)["query GetAssetTimezone($assetId: ID!) {\n asset(id: $assetId) {\n locations {\n latest {\n properties {\n timeZone\n }\n }\n }\n }\n}"];
|
|
35
|
+
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode<infer TType, any> ? TType : never;
|
|
36
|
+
export {};
|