@superdispatch/dates 0.21.13 → 0.21.16
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/LICENSE +21 -0
- package/{pkg/dist-node → dist-node}/index.js +3 -3
- package/{pkg/dist-node → dist-node}/index.js.map +1 -1
- package/{pkg/dist-src → dist-src}/date-time-utils/DateTimeUtils.js +3 -3
- package/{pkg/dist-web → dist-web}/index.js +3 -3
- package/{pkg/dist-web → dist-web}/index.js.map +1 -1
- package/package.json +13 -39
- package/.babelrc.js +0 -5
- package/.turbo/turbo-version.log +0 -26
- package/pkg/README.md +0 -10
- package/pkg/package.json +0 -32
- package/playroom.ts +0 -10
- package/src/__tests__/index.spec.ts +0 -48
- package/src/base-date-picker/BaseDatePicker.tsx +0 -145
- package/src/calendar/Calendar.playroom.tsx +0 -28
- package/src/calendar/Calendar.spec.tsx +0 -531
- package/src/calendar/Calendar.stories.tsx +0 -50
- package/src/calendar/Calendar.tsx +0 -534
- package/src/calendar/CalendarQuickSelection.tsx +0 -34
- package/src/calendar/InternalCalendarComponents.tsx +0 -79
- package/src/date-config/DateConfig.spec.tsx +0 -23
- package/src/date-config/DateConfig.tsx +0 -60
- package/src/date-field/DateField.playroom.tsx +0 -21
- package/src/date-field/DateField.spec.tsx +0 -350
- package/src/date-field/DateField.stories.tsx +0 -47
- package/src/date-field/DateField.tsx +0 -155
- package/src/date-range-field/DateRangeField.playroom.tsx +0 -24
- package/src/date-range-field/DateRangeField.spec.tsx +0 -318
- package/src/date-range-field/DateRangeField.stories.tsx +0 -51
- package/src/date-range-field/DateRangeField.tsx +0 -277
- package/src/date-time-utils/DateTimeUtils.spec.ts +0 -652
- package/src/date-time-utils/DateTimeUtils.ts +0 -339
- package/src/date-utils/DateUtils.spec.ts +0 -234
- package/src/date-utils/DateUtils.ts +0 -333
- package/src/formatted-date/FormattedDate.spec.tsx +0 -103
- package/src/formatted-date/FormattedDate.ts +0 -42
- package/src/formatted-relative-time/FormattedRelativeTime.spec.tsx +0 -93
- package/src/formatted-relative-time/FormattedRelativeTime.ts +0 -60
- package/src/index.ts +0 -12
- package/src/time-field/TimeField.playroom.tsx +0 -21
- package/src/time-field/TimeField.stories.tsx +0 -35
- package/src/time-field/TimeField.tsx +0 -221
- package/src/use-date-time/useDateTime.spec.ts +0 -45
- package/src/use-date-time/useDateTime.ts +0 -31
- package/src/use-date-time-range/useDateTimeRange.spec.ts +0 -53
- package/src/use-date-time-range/useDateTimeRange.ts +0 -24
- package/tsconfig.json +0 -19
- /package/{pkg/dist-src → dist-src}/base-date-picker/BaseDatePicker.js +0 -0
- /package/{pkg/dist-src → dist-src}/calendar/Calendar.js +0 -0
- /package/{pkg/dist-src → dist-src}/calendar/CalendarQuickSelection.js +0 -0
- /package/{pkg/dist-src → dist-src}/calendar/InternalCalendarComponents.js +0 -0
- /package/{pkg/dist-src → dist-src}/date-config/DateConfig.js +0 -0
- /package/{pkg/dist-src → dist-src}/date-field/DateField.js +0 -0
- /package/{pkg/dist-src → dist-src}/date-range-field/DateRangeField.js +0 -0
- /package/{pkg/dist-src → dist-src}/date-utils/DateUtils.js +0 -0
- /package/{pkg/dist-src → dist-src}/formatted-date/FormattedDate.js +0 -0
- /package/{pkg/dist-src → dist-src}/formatted-relative-time/FormattedRelativeTime.js +0 -0
- /package/{pkg/dist-src → dist-src}/index.js +0 -0
- /package/{pkg/dist-src → dist-src}/time-field/TimeField.js +0 -0
- /package/{pkg/dist-src → dist-src}/use-date-time/useDateTime.js +0 -0
- /package/{pkg/dist-src → dist-src}/use-date-time-range/useDateTimeRange.js +0 -0
- /package/{pkg/dist-types → dist-types}/index.d.ts +0 -0
|
@@ -1,333 +0,0 @@
|
|
|
1
|
-
import { DateTime } from 'luxon';
|
|
2
|
-
import { useMemo } from 'react';
|
|
3
|
-
|
|
4
|
-
/** @deprecated */
|
|
5
|
-
export type DateUnit =
|
|
6
|
-
| 'year'
|
|
7
|
-
| 'month'
|
|
8
|
-
| 'day'
|
|
9
|
-
| 'hour'
|
|
10
|
-
| 'minute'
|
|
11
|
-
| 'second'
|
|
12
|
-
| 'millisecond';
|
|
13
|
-
/** @deprecated */
|
|
14
|
-
export type DateDurationUnit = DateUnit | 'quarter' | 'week';
|
|
15
|
-
|
|
16
|
-
/** @deprecated */
|
|
17
|
-
export type DateObject = Record<DateUnit, number>;
|
|
18
|
-
|
|
19
|
-
/** @deprecated */
|
|
20
|
-
export type NullableDate = null | undefined | Date;
|
|
21
|
-
/** @deprecated */
|
|
22
|
-
export type DateLike = number | Date;
|
|
23
|
-
/** @deprecated */
|
|
24
|
-
export type NullableDateLike = null | undefined | DateLike;
|
|
25
|
-
/** @deprecated */
|
|
26
|
-
export type DateRange = [Date?, Date?];
|
|
27
|
-
/** @deprecated */
|
|
28
|
-
export type DateRangeLike = [DateLike?, DateLike?];
|
|
29
|
-
/** @deprecated */
|
|
30
|
-
export type NullableDateRange =
|
|
31
|
-
| null
|
|
32
|
-
| undefined
|
|
33
|
-
| [NullableDate?, NullableDate?];
|
|
34
|
-
|
|
35
|
-
/** @deprecated */
|
|
36
|
-
export type NullableDateRangeLike =
|
|
37
|
-
| null
|
|
38
|
-
| undefined
|
|
39
|
-
| [NullableDateLike?, NullableDateLike?];
|
|
40
|
-
|
|
41
|
-
/** @deprecated */
|
|
42
|
-
function toDateTime(value: DateLike): DateTime {
|
|
43
|
-
return typeof value === 'number'
|
|
44
|
-
? DateTime.fromMillis(value)
|
|
45
|
-
: DateTime.fromJSDate(value);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** @deprecated */
|
|
49
|
-
export function isDate(value: unknown): value is Date {
|
|
50
|
-
return value != null && value instanceof Date;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** @deprecated */
|
|
54
|
-
export function isDateLike(value: unknown): value is DateLike {
|
|
55
|
-
return (
|
|
56
|
-
isDate(value) || (typeof value === 'number' && Number.isInteger(value))
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** @deprecated */
|
|
61
|
-
export function isValidDate(value: unknown): value is Date {
|
|
62
|
-
return isDate(value) && Number.isFinite(value.getTime());
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** @deprecated */
|
|
66
|
-
function checkRange(
|
|
67
|
-
range: unknown,
|
|
68
|
-
validator: (value: unknown) => boolean,
|
|
69
|
-
): boolean {
|
|
70
|
-
if (!Array.isArray(range) || range.length > 2) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const [start, finish] = range as unknown[];
|
|
75
|
-
|
|
76
|
-
return (
|
|
77
|
-
(start == null || validator(start)) && (finish == null || validator(finish))
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** @deprecated */
|
|
82
|
-
export function isDateRange(range: unknown): range is DateRange {
|
|
83
|
-
return checkRange(range, isDate);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/** @deprecated */
|
|
87
|
-
export function isDateRangeLike(range: unknown): range is DateRangeLike {
|
|
88
|
-
return checkRange(range, isDateLike);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/** @deprecated */
|
|
92
|
-
export function isValidDateRange(range: unknown): range is DateRange {
|
|
93
|
-
return checkRange(range, isValidDate);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/** @deprecated */
|
|
97
|
-
export function toDate(value: NullableDateLike): Date {
|
|
98
|
-
return !isDateLike(value) ? new Date(NaN) : new Date(value);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/** @deprecated */
|
|
102
|
-
export function toDateRange(range: NullableDateRangeLike): DateRange {
|
|
103
|
-
if (range == null || !isDateRangeLike(range)) {
|
|
104
|
-
return [];
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return range
|
|
108
|
-
.filter((x) => x != null)
|
|
109
|
-
.map((x) => (x == null ? undefined : toDate(x)))
|
|
110
|
-
.sort((a, b) =>
|
|
111
|
-
!isValidDate(a) ? -1 : !isValidDate(b) ? 1 : a.valueOf() - b.valueOf(),
|
|
112
|
-
) as DateRange;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/** @deprecated */
|
|
116
|
-
export type DateFormatVariant = 'date' | 'shortDate' | 'time' | 'dateTime';
|
|
117
|
-
/** @deprecated */
|
|
118
|
-
export type DateFormatOptions = Omit<
|
|
119
|
-
Intl.DateTimeFormatOptions,
|
|
120
|
-
'timeZone' | 'timeZoneName'
|
|
121
|
-
>;
|
|
122
|
-
|
|
123
|
-
/** @deprecated */
|
|
124
|
-
export type RelativeTimeFormatStyle = 'narrow' | 'short' | 'long';
|
|
125
|
-
/** @deprecated */
|
|
126
|
-
export interface RelativeTimeFormatOptions {
|
|
127
|
-
style?: RelativeTimeFormatStyle;
|
|
128
|
-
compare?: DateLike;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/** @deprecated */
|
|
132
|
-
export class DateUtils {
|
|
133
|
-
/** @deprecated */
|
|
134
|
-
toObject(value: DateLike): DateObject {
|
|
135
|
-
const {
|
|
136
|
-
year = NaN,
|
|
137
|
-
month = NaN,
|
|
138
|
-
day = NaN,
|
|
139
|
-
hour = NaN,
|
|
140
|
-
minute = NaN,
|
|
141
|
-
second = NaN,
|
|
142
|
-
millisecond = NaN,
|
|
143
|
-
} = toDateTime(value).toObject({
|
|
144
|
-
includeConfig: false,
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
return { year, month, day, hour, minute, second, millisecond };
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/** @deprecated */
|
|
151
|
-
fromObject({
|
|
152
|
-
year = 0,
|
|
153
|
-
month = 1,
|
|
154
|
-
day = 1,
|
|
155
|
-
hour = 0,
|
|
156
|
-
minute = 0,
|
|
157
|
-
second = 0,
|
|
158
|
-
millisecond = 0,
|
|
159
|
-
}: Partial<DateObject>): Date {
|
|
160
|
-
if (
|
|
161
|
-
Number.isNaN(year) ||
|
|
162
|
-
Number.isNaN(month) ||
|
|
163
|
-
Number.isNaN(day) ||
|
|
164
|
-
Number.isNaN(hour) ||
|
|
165
|
-
Number.isNaN(minute) ||
|
|
166
|
-
Number.isNaN(second) ||
|
|
167
|
-
Number.isNaN(millisecond)
|
|
168
|
-
) {
|
|
169
|
-
return new Date(NaN);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return DateTime.fromObject({
|
|
173
|
-
year,
|
|
174
|
-
month,
|
|
175
|
-
day,
|
|
176
|
-
hour,
|
|
177
|
-
minute,
|
|
178
|
-
second,
|
|
179
|
-
millisecond,
|
|
180
|
-
}).toJSDate();
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/** @deprecated */
|
|
184
|
-
update(value: DateLike, values: Partial<DateObject>): Date {
|
|
185
|
-
return toDateTime(value).set(values).toJSDate();
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/** @deprecated */
|
|
189
|
-
mergeDateAndTime(date: DateLike, time: DateLike): Date {
|
|
190
|
-
const { hour, minute, second, millisecond } = this.toObject(time);
|
|
191
|
-
|
|
192
|
-
if (
|
|
193
|
-
Number.isNaN(hour) ||
|
|
194
|
-
Number.isNaN(minute) ||
|
|
195
|
-
Number.isNaN(second) ||
|
|
196
|
-
Number.isNaN(millisecond)
|
|
197
|
-
) {
|
|
198
|
-
return new Date(NaN);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
return this.update(date, { hour, minute, second, millisecond });
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/** @deprecated */
|
|
205
|
-
startOf(value: DateLike, unit: DateDurationUnit): Date {
|
|
206
|
-
return toDateTime(value).startOf(unit).toJSDate();
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/** @deprecated */
|
|
210
|
-
endOf(value: DateLike, unit: DateDurationUnit): Date {
|
|
211
|
-
return toDateTime(value).endOf(unit).toJSDate();
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/** @deprecated */
|
|
215
|
-
plus(value: DateLike, values: Partial<DateObject>): Date {
|
|
216
|
-
return toDateTime(value).plus(values).toJSDate();
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/** @deprecated */
|
|
220
|
-
minus(value: DateLike, values: Partial<DateObject>): Date {
|
|
221
|
-
return toDateTime(value).minus(values).toJSDate();
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/** @deprecated */
|
|
225
|
-
isSameDate(
|
|
226
|
-
value: NullableDateLike,
|
|
227
|
-
compare: NullableDateLike,
|
|
228
|
-
unit: DateUnit = 'millisecond',
|
|
229
|
-
): boolean {
|
|
230
|
-
if (value == null && compare == null) {
|
|
231
|
-
return true;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (value == null || compare == null) {
|
|
235
|
-
return false;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const dateTimeValue = toDateTime(value);
|
|
239
|
-
const dateTimeCompare = toDateTime(compare);
|
|
240
|
-
|
|
241
|
-
return (
|
|
242
|
-
dateTimeValue.isValid &&
|
|
243
|
-
dateTimeCompare.isValid &&
|
|
244
|
-
dateTimeValue.startOf(unit).equals(dateTimeCompare.startOf(unit))
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/** @deprecated */
|
|
249
|
-
isSameDateRange(
|
|
250
|
-
value: NullableDateRangeLike,
|
|
251
|
-
compare: NullableDateRangeLike,
|
|
252
|
-
unit?: DateUnit,
|
|
253
|
-
): boolean {
|
|
254
|
-
const range1 = toDateRange(value);
|
|
255
|
-
const range2 = toDateRange(compare);
|
|
256
|
-
|
|
257
|
-
return !range1.some(
|
|
258
|
-
(date, idx) => !this.isSameDate(date, range2[idx], unit),
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/** @deprecated */
|
|
263
|
-
diff(value: DateLike, compare: DateLike, unit: DateUnit): number {
|
|
264
|
-
const valueDateTime = toDateTime(value);
|
|
265
|
-
const compareDateTime = toDateTime(compare);
|
|
266
|
-
|
|
267
|
-
return valueDateTime.diff(compareDateTime, unit).as(unit);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/** @deprecated */
|
|
271
|
-
toLocaleString(value: DateLike, options?: DateFormatOptions): string {
|
|
272
|
-
return toDateTime(value).toLocaleString(options);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/** @deprecated */
|
|
276
|
-
format(value: DateLike, variant: DateFormatVariant): string {
|
|
277
|
-
return this.toLocaleString(
|
|
278
|
-
value,
|
|
279
|
-
variant === 'date'
|
|
280
|
-
? { day: '2-digit', month: 'short', year: 'numeric' }
|
|
281
|
-
: variant === 'shortDate'
|
|
282
|
-
? { day: '2-digit', month: 'short' }
|
|
283
|
-
: variant === 'time'
|
|
284
|
-
? { hour: 'numeric', minute: 'numeric' }
|
|
285
|
-
: {
|
|
286
|
-
day: '2-digit',
|
|
287
|
-
month: 'short',
|
|
288
|
-
year: 'numeric',
|
|
289
|
-
hour: 'numeric',
|
|
290
|
-
minute: 'numeric',
|
|
291
|
-
},
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/** @deprecated */
|
|
296
|
-
formatRange(value: NullableDateRangeLike, emptyText = ''): string {
|
|
297
|
-
const range = toDateRange(value);
|
|
298
|
-
|
|
299
|
-
if (!isValidDateRange(range)) {
|
|
300
|
-
return 'Invalid Date Range';
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
const [start, finish] = range;
|
|
304
|
-
|
|
305
|
-
if (!start) {
|
|
306
|
-
return emptyText;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const startText = this.format(
|
|
310
|
-
start,
|
|
311
|
-
!this.isSameDate(start, finish, 'year') ? 'date' : 'shortDate',
|
|
312
|
-
);
|
|
313
|
-
|
|
314
|
-
const finishText = !finish ? '…' : this.format(finish, 'date');
|
|
315
|
-
|
|
316
|
-
return `${startText} - ${finishText}`;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
/** @deprecated */
|
|
320
|
-
formatRelativeTime(
|
|
321
|
-
value: DateLike,
|
|
322
|
-
{ style = 'long', compare = Date.now() }: RelativeTimeFormatOptions = {},
|
|
323
|
-
): string {
|
|
324
|
-
const valueDateTime = toDateTime(value);
|
|
325
|
-
const compareDateTime = toDateTime(compare);
|
|
326
|
-
|
|
327
|
-
return valueDateTime.toRelative({ style, base: compareDateTime }) as string;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
export function useDateUtils(): DateUtils {
|
|
332
|
-
return useMemo(() => new DateUtils(), []);
|
|
333
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { Typography } from '@material-ui/core';
|
|
2
|
-
import { mockDate, renderComponent } from '@superdispatch/ui-testutils';
|
|
3
|
-
import { renderHook } from '@testing-library/react-hooks';
|
|
4
|
-
import { NullableDateInput } from '../date-time-utils/DateTimeUtils';
|
|
5
|
-
import {
|
|
6
|
-
FormattedDate,
|
|
7
|
-
FormattedDateConfig,
|
|
8
|
-
useFormattedDate,
|
|
9
|
-
} from './FormattedDate';
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
mockDate();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
describe('useFormattedDate', () => {
|
|
16
|
-
interface HookProps extends FormattedDateConfig {
|
|
17
|
-
input: NullableDateInput;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
test('basic', () => {
|
|
21
|
-
const { result, rerender } = renderHook(
|
|
22
|
-
({ input, ...options }: HookProps) => useFormattedDate(input, options),
|
|
23
|
-
{ initialProps: { input: Date.now(), variant: 'DateTime' } },
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
expect(result.current).toBe('May 24, 2019, 7:13 AM');
|
|
27
|
-
|
|
28
|
-
rerender({ input: Date.now(), variant: 'Date' });
|
|
29
|
-
|
|
30
|
-
expect(result.current).toBe('May 24, 2019');
|
|
31
|
-
|
|
32
|
-
rerender({ input: Date.now(), variant: 'ShortDate' });
|
|
33
|
-
|
|
34
|
-
expect(result.current).toBe('May 24');
|
|
35
|
-
|
|
36
|
-
rerender({ input: Date.now(), variant: 'Time' });
|
|
37
|
-
|
|
38
|
-
expect(result.current).toBe('7:13 AM');
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test('invalid', () => {
|
|
42
|
-
const { result, rerender } = renderHook(
|
|
43
|
-
({ input, ...options }: HookProps) => useFormattedDate(input, options),
|
|
44
|
-
{ initialProps: { input: NaN, variant: 'DateTime' } },
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
expect(result.current).toBe('Invalid Date');
|
|
48
|
-
|
|
49
|
-
rerender({
|
|
50
|
-
input: NaN,
|
|
51
|
-
variant: 'DateTime',
|
|
52
|
-
fallback: 'Custom Empty Text',
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
expect(result.current).toBe('Custom Empty Text');
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe('FormattedDate', () => {
|
|
60
|
-
test('basic', () => {
|
|
61
|
-
const { container } = renderComponent(
|
|
62
|
-
<>
|
|
63
|
-
<FormattedDate date={Date.now()} variant="DateTime" />
|
|
64
|
-
<FormattedDate date={Date.now()} variant="Date" />
|
|
65
|
-
<FormattedDate date={Date.now()} variant="Time" />
|
|
66
|
-
<FormattedDate date={Date.now()} variant="ShortDate" />
|
|
67
|
-
</>,
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
expect(container).toMatchInlineSnapshot(`
|
|
71
|
-
<div>
|
|
72
|
-
May 24, 2019, 7:13 AM
|
|
73
|
-
May 24, 2019
|
|
74
|
-
7:13 AM
|
|
75
|
-
May 24
|
|
76
|
-
</div>
|
|
77
|
-
`);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
test('invalid', () => {
|
|
81
|
-
const { container } = renderComponent(
|
|
82
|
-
<>
|
|
83
|
-
<FormattedDate date={NaN} variant="Date" />
|
|
84
|
-
<FormattedDate
|
|
85
|
-
date={NaN}
|
|
86
|
-
variant="Date"
|
|
87
|
-
fallback={<Typography color="textSecondary">N/A</Typography>}
|
|
88
|
-
/>
|
|
89
|
-
</>,
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
expect(container).toMatchInlineSnapshot(`
|
|
93
|
-
<div>
|
|
94
|
-
Invalid Date
|
|
95
|
-
<p
|
|
96
|
-
class="MuiTypography-root MuiTypography-body2 MuiTypography-colorTextSecondary"
|
|
97
|
-
>
|
|
98
|
-
N/A
|
|
99
|
-
</p>
|
|
100
|
-
</div>
|
|
101
|
-
`);
|
|
102
|
-
});
|
|
103
|
-
});
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { renderChildren } from '@superdispatch/ui';
|
|
2
|
-
import { ReactElement, ReactNode, useMemo } from 'react';
|
|
3
|
-
import { DateConfig, useDateConfig } from '../date-config/DateConfig';
|
|
4
|
-
import {
|
|
5
|
-
formatDate,
|
|
6
|
-
FormatDateConfig,
|
|
7
|
-
NullableDateInput,
|
|
8
|
-
} from '../date-time-utils/DateTimeUtils';
|
|
9
|
-
import { useDateTime } from '../use-date-time/useDateTime';
|
|
10
|
-
|
|
11
|
-
export interface FormattedDateConfig
|
|
12
|
-
extends Partial<DateConfig>,
|
|
13
|
-
FormatDateConfig {}
|
|
14
|
-
|
|
15
|
-
export function useFormattedDate(
|
|
16
|
-
input: NullableDateInput,
|
|
17
|
-
{ variant, fallback, ...dateConfig }: FormattedDateConfig,
|
|
18
|
-
): string {
|
|
19
|
-
const config = useDateConfig(dateConfig);
|
|
20
|
-
const date = useDateTime(input, config);
|
|
21
|
-
|
|
22
|
-
return useMemo(
|
|
23
|
-
() => formatDate(date, { variant, fallback }, config),
|
|
24
|
-
[date, config, variant, fallback],
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface FormattedDateProps
|
|
29
|
-
extends Omit<FormattedDateConfig, 'fallback'> {
|
|
30
|
-
fallback?: ReactNode;
|
|
31
|
-
date: NullableDateInput;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function FormattedDate({
|
|
35
|
-
date,
|
|
36
|
-
fallback = 'Invalid Date',
|
|
37
|
-
...options
|
|
38
|
-
}: FormattedDateProps): null | ReactElement {
|
|
39
|
-
const formatted = useFormattedDate(date, { ...options, fallback: '' });
|
|
40
|
-
|
|
41
|
-
return renderChildren(formatted || fallback);
|
|
42
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { Typography } from '@material-ui/core';
|
|
2
|
-
import { mockDate, renderComponent } from '@superdispatch/ui-testutils';
|
|
3
|
-
import { DateTime } from 'luxon';
|
|
4
|
-
import { FormattedRelativeTime } from '../formatted-relative-time/FormattedRelativeTime';
|
|
5
|
-
|
|
6
|
-
beforeEach(() => {
|
|
7
|
-
mockDate();
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
describe('FormattedRelativeTime', () => {
|
|
11
|
-
test('basic', () => {
|
|
12
|
-
const now = DateTime.fromMillis(Date.now());
|
|
13
|
-
const { container } = renderComponent(
|
|
14
|
-
<>
|
|
15
|
-
<FormattedRelativeTime date={now} />
|
|
16
|
-
<FormattedRelativeTime date={now.startOf('minute')} />
|
|
17
|
-
<FormattedRelativeTime date={now.endOf('minute')} />
|
|
18
|
-
<FormattedRelativeTime date={now.startOf('hour')} />
|
|
19
|
-
<FormattedRelativeTime date={now.endOf('hour')} />
|
|
20
|
-
<FormattedRelativeTime date={now.startOf('day')} />
|
|
21
|
-
<FormattedRelativeTime date={now.endOf('day')} />
|
|
22
|
-
<FormattedRelativeTime date={now.startOf('week')} />
|
|
23
|
-
<FormattedRelativeTime date={now.endOf('week')} />
|
|
24
|
-
<FormattedRelativeTime date={now.startOf('month')} />
|
|
25
|
-
<FormattedRelativeTime date={now.endOf('month')} />
|
|
26
|
-
<FormattedRelativeTime date={now.startOf('year')} />
|
|
27
|
-
<FormattedRelativeTime date={now.endOf('year')} />
|
|
28
|
-
<FormattedRelativeTime date={now.minus({ year: 1 })} />
|
|
29
|
-
</>,
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
expect(container).toMatchInlineSnapshot(`
|
|
33
|
-
<div>
|
|
34
|
-
in 0s
|
|
35
|
-
14s ago
|
|
36
|
-
in 45s
|
|
37
|
-
13m ago
|
|
38
|
-
in 46m
|
|
39
|
-
7h ago
|
|
40
|
-
in 16h
|
|
41
|
-
4d ago
|
|
42
|
-
in 2d
|
|
43
|
-
23d ago
|
|
44
|
-
in 7d
|
|
45
|
-
4mo ago
|
|
46
|
-
in 7mo
|
|
47
|
-
1y ago
|
|
48
|
-
</div>
|
|
49
|
-
`);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test('base', () => {
|
|
53
|
-
const now = DateTime.fromMillis(Date.now());
|
|
54
|
-
const { container } = renderComponent(
|
|
55
|
-
<FormattedRelativeTime
|
|
56
|
-
date={now.plus({ days: 10 })}
|
|
57
|
-
base={now.minus({ days: 10 })}
|
|
58
|
-
/>,
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
expect(container).toMatchInlineSnapshot(`
|
|
62
|
-
<div>
|
|
63
|
-
in 20d
|
|
64
|
-
</div>
|
|
65
|
-
`);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
test('invalid', () => {
|
|
69
|
-
const now = DateTime.fromMillis(Date.now());
|
|
70
|
-
const { container } = renderComponent(
|
|
71
|
-
<>
|
|
72
|
-
<FormattedRelativeTime date={NaN} />
|
|
73
|
-
<FormattedRelativeTime date={now.startOf('month')} base={NaN} />
|
|
74
|
-
<FormattedRelativeTime
|
|
75
|
-
date={NaN}
|
|
76
|
-
fallback={<Typography color="textSecondary">N/A</Typography>}
|
|
77
|
-
/>
|
|
78
|
-
</>,
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
expect(container).toMatchInlineSnapshot(`
|
|
82
|
-
<div>
|
|
83
|
-
Invalid Date
|
|
84
|
-
Invalid Date
|
|
85
|
-
<p
|
|
86
|
-
class="MuiTypography-root MuiTypography-body2 MuiTypography-colorTextSecondary"
|
|
87
|
-
>
|
|
88
|
-
N/A
|
|
89
|
-
</p>
|
|
90
|
-
</div>
|
|
91
|
-
`);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { renderChildren } from '@superdispatch/ui';
|
|
2
|
-
import { ReactElement, ReactNode, useMemo } from 'react';
|
|
3
|
-
import { DateConfig, useDateConfig } from '../date-config/DateConfig';
|
|
4
|
-
import {
|
|
5
|
-
formatRelativeTime,
|
|
6
|
-
FormatRelativeTimeOptions,
|
|
7
|
-
NullableDateInput,
|
|
8
|
-
} from '../date-time-utils/DateTimeUtils';
|
|
9
|
-
import { useDateTime } from '../use-date-time/useDateTime';
|
|
10
|
-
|
|
11
|
-
export interface FormattedRelativeTimeOptions
|
|
12
|
-
extends Partial<DateConfig>,
|
|
13
|
-
FormatRelativeTimeOptions {}
|
|
14
|
-
|
|
15
|
-
export function useFormattedRelativeTime(
|
|
16
|
-
input: NullableDateInput,
|
|
17
|
-
{
|
|
18
|
-
unit,
|
|
19
|
-
round,
|
|
20
|
-
padding,
|
|
21
|
-
fallback,
|
|
22
|
-
|
|
23
|
-
base: baseOption,
|
|
24
|
-
...dateConfig
|
|
25
|
-
}: FormattedRelativeTimeOptions = {},
|
|
26
|
-
): string {
|
|
27
|
-
const config = useDateConfig(dateConfig);
|
|
28
|
-
const date = useDateTime(input, config);
|
|
29
|
-
const baseOptionDate = useDateTime(baseOption, config);
|
|
30
|
-
const base = baseOption == null ? undefined : baseOptionDate;
|
|
31
|
-
|
|
32
|
-
return useMemo(
|
|
33
|
-
() =>
|
|
34
|
-
formatRelativeTime(
|
|
35
|
-
date,
|
|
36
|
-
{ base, unit, round, padding, fallback },
|
|
37
|
-
config,
|
|
38
|
-
),
|
|
39
|
-
[base, date, unit, round, config, padding, fallback],
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface FormattedRelativeTimeProps
|
|
44
|
-
extends Omit<FormattedRelativeTimeOptions, 'fallback'> {
|
|
45
|
-
date: NullableDateInput;
|
|
46
|
-
fallback?: ReactNode;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function FormattedRelativeTime({
|
|
50
|
-
date,
|
|
51
|
-
fallback = 'Invalid Date',
|
|
52
|
-
...options
|
|
53
|
-
}: FormattedRelativeTimeProps): null | ReactElement {
|
|
54
|
-
const formatted = useFormattedRelativeTime(date, {
|
|
55
|
-
...options,
|
|
56
|
-
fallback: '',
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
return renderChildren(formatted || fallback);
|
|
60
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export * from './calendar/Calendar';
|
|
2
|
-
export * from './calendar/CalendarQuickSelection';
|
|
3
|
-
export * from './date-config/DateConfig';
|
|
4
|
-
export * from './date-field/DateField';
|
|
5
|
-
export * from './date-range-field/DateRangeField';
|
|
6
|
-
export * from './date-time-utils/DateTimeUtils';
|
|
7
|
-
export * from './date-utils/DateUtils';
|
|
8
|
-
export * from './formatted-date/FormattedDate';
|
|
9
|
-
export * from './formatted-relative-time/FormattedRelativeTime';
|
|
10
|
-
export * from './time-field/TimeField';
|
|
11
|
-
export * from './use-date-time-range/useDateTimeRange';
|
|
12
|
-
export * from './use-date-time/useDateTime';
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { forwardRef, useState } from 'react';
|
|
2
|
-
import { NullableDateInput } from '../date-time-utils/DateTimeUtils';
|
|
3
|
-
import { TimeField as SDTimeField, TimeFieldProps } from './TimeField';
|
|
4
|
-
|
|
5
|
-
export const TimeField = forwardRef<HTMLDivElement, TimeFieldProps>(
|
|
6
|
-
({ value, onChange, ...props }, ref) => {
|
|
7
|
-
const [state, setState] = useState<NullableDateInput>();
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
<SDTimeField
|
|
11
|
-
{...props}
|
|
12
|
-
ref={ref}
|
|
13
|
-
value={value || state}
|
|
14
|
-
onChange={(date) => {
|
|
15
|
-
onChange?.(date);
|
|
16
|
-
setState(date.stringValue);
|
|
17
|
-
}}
|
|
18
|
-
/>
|
|
19
|
-
);
|
|
20
|
-
},
|
|
21
|
-
);
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { InputAdornment } from '@material-ui/core';
|
|
2
|
-
import { Meta } from '@storybook/react';
|
|
3
|
-
import { TimeField } from './TimeField.playroom';
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
title: 'Dates/TimeField',
|
|
7
|
-
component: TimeField,
|
|
8
|
-
} as Meta;
|
|
9
|
-
|
|
10
|
-
export const basic = () => <TimeField />;
|
|
11
|
-
|
|
12
|
-
export const advanced = () => (
|
|
13
|
-
<TimeField label="Label" placeholder="Placeholder" helperText="Helper Text" />
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
export const errorState = () => (
|
|
17
|
-
<TimeField
|
|
18
|
-
label="Label"
|
|
19
|
-
error={true}
|
|
20
|
-
placeholder="Placeholder"
|
|
21
|
-
helperText="Error Text"
|
|
22
|
-
/>
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
export const adornment = () => (
|
|
26
|
-
<TimeField
|
|
27
|
-
InputProps={{
|
|
28
|
-
startAdornment: (
|
|
29
|
-
<InputAdornment position="start">Start Adornment:</InputAdornment>
|
|
30
|
-
),
|
|
31
|
-
}}
|
|
32
|
-
/>
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
export const disabled = () => <TimeField disabled={true} />;
|