@povio/ui 2.3.2 → 2.3.3
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.
|
@@ -22,9 +22,9 @@ var translation_default = {
|
|
|
22
22
|
"thisAndLastWeek": "Ta in prejšnji teden",
|
|
23
23
|
"thisMonth": "Ta mesec",
|
|
24
24
|
"thisAndLastMonth": "Ta in prejšnji mesec",
|
|
25
|
-
"thisYear": "
|
|
25
|
+
"thisYear": "To leto",
|
|
26
26
|
"lastYear": "Prejšnje leto",
|
|
27
|
-
"thisAndLastYear": "
|
|
27
|
+
"thisAndLastYear": "To in prejšnje leto",
|
|
28
28
|
"soFar": "Od začetka"
|
|
29
29
|
},
|
|
30
30
|
"navigation": {
|
|
@@ -23,7 +23,7 @@ import { useDateRangePickerState, useRangeCalendarState } from "react-stately";
|
|
|
23
23
|
var DateRangePickerBase = (props) => {
|
|
24
24
|
const ui = UIConfig.useConfig();
|
|
25
25
|
const { t } = useTranslation();
|
|
26
|
-
const { ref, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, onChange, value, disableDropdown, className, hideSidebar, placeholder, inputClassName, hideLabel = ui.input.hideLabel, variant = ui.input.variant, as = ui.input.as, size = ui.input.size, isClearable = ui.input.isClearable, todayIcon = ui.dateInput.todayIcon, shouldForceLeadingZeros = ui.dateInput.shouldForceLeadingZeros, disableManualEntry = ui.dateInput.disableManualEntry, autoFixYear = ui.dateInput.autoFixYear, ...rest } = props;
|
|
26
|
+
const { ref, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, onChange, value, disableDropdown, className, hideSidebar, placeholder, inputClassName, hideLabel = ui.input.hideLabel, variant = ui.input.variant, as = ui.input.as, size = ui.input.size, isClearable = ui.input.isClearable, todayIcon = ui.dateInput.todayIcon, shouldForceLeadingZeros = ui.dateInput.shouldForceLeadingZeros, disableManualEntry = ui.dateInput.disableManualEntry, autoFixYear = ui.dateInput.autoFixYear, minValue, maxValue, ...rest } = props;
|
|
27
27
|
const [validationRangeError, setValidationRangeError] = useState();
|
|
28
28
|
const datePickerInputRef = useRef(null);
|
|
29
29
|
const dateRangePickerRef = useMemo(() => ({ get current() {
|
|
@@ -33,12 +33,16 @@ var DateRangePickerBase = (props) => {
|
|
|
33
33
|
...rest,
|
|
34
34
|
value,
|
|
35
35
|
shouldCloseOnSelect: false,
|
|
36
|
-
shouldForceLeadingZeros
|
|
36
|
+
shouldForceLeadingZeros,
|
|
37
|
+
minValue,
|
|
38
|
+
maxValue
|
|
37
39
|
});
|
|
38
40
|
const state = useDateRangePickerState({
|
|
39
41
|
...rest,
|
|
40
42
|
shouldForceLeadingZeros,
|
|
41
43
|
value,
|
|
44
|
+
minValue,
|
|
45
|
+
maxValue,
|
|
42
46
|
onChange: (newValue) => {
|
|
43
47
|
if (isValidRange(newValue)) return;
|
|
44
48
|
onChange?.(newValue);
|
|
@@ -49,12 +53,16 @@ var DateRangePickerBase = (props) => {
|
|
|
49
53
|
const { groupProps, labelProps, startFieldProps, endFieldProps, buttonProps, dialogProps } = useDateRangePicker({
|
|
50
54
|
...rest,
|
|
51
55
|
label,
|
|
52
|
-
shouldForceLeadingZeros
|
|
56
|
+
shouldForceLeadingZeros,
|
|
57
|
+
minValue,
|
|
58
|
+
maxValue
|
|
53
59
|
}, state, dateRangePickerRef);
|
|
54
60
|
const { calendarProps } = useDateRangePicker({
|
|
55
61
|
...rest,
|
|
56
62
|
label,
|
|
57
|
-
shouldForceLeadingZeros
|
|
63
|
+
shouldForceLeadingZeros,
|
|
64
|
+
minValue,
|
|
65
|
+
maxValue
|
|
58
66
|
}, dialogState, dateRangePickerRef);
|
|
59
67
|
const { locale } = useLocale$1();
|
|
60
68
|
useImperativeHandle(ref, () => ({ clear: () => {
|
|
@@ -79,8 +87,8 @@ var DateRangePickerBase = (props) => {
|
|
|
79
87
|
createCalendar,
|
|
80
88
|
pageBehavior: "single",
|
|
81
89
|
visibleDuration: { months: 1 },
|
|
82
|
-
minValue
|
|
83
|
-
maxValue
|
|
90
|
+
minValue,
|
|
91
|
+
maxValue
|
|
84
92
|
});
|
|
85
93
|
const rightCalendarState = useRangeCalendarState({
|
|
86
94
|
...calendarProps,
|
|
@@ -89,8 +97,8 @@ var DateRangePickerBase = (props) => {
|
|
|
89
97
|
pageBehavior: "single",
|
|
90
98
|
visibleDuration: { months: 1 },
|
|
91
99
|
defaultFocusedValue: today(getLocalTimeZone()).add({ months: 1 }),
|
|
92
|
-
minValue
|
|
93
|
-
maxValue
|
|
100
|
+
minValue,
|
|
101
|
+
maxValue
|
|
94
102
|
});
|
|
95
103
|
const [activePreset, setActivePreset] = useState(null);
|
|
96
104
|
const [rangeSelection, setRangeSelection] = useState({
|
|
@@ -110,6 +118,32 @@ var DateRangePickerBase = (props) => {
|
|
|
110
118
|
className: headerClassName,
|
|
111
119
|
labelProps
|
|
112
120
|
};
|
|
121
|
+
const isDateOutsideBounds = useCallback((date) => {
|
|
122
|
+
if (minValue && date.compare(minValue) < 0) return true;
|
|
123
|
+
if (maxValue && date.compare(maxValue) > 0) return true;
|
|
124
|
+
return false;
|
|
125
|
+
}, [minValue, maxValue]);
|
|
126
|
+
const clampRangeToBounds = useCallback((range) => {
|
|
127
|
+
if (range === null) return null;
|
|
128
|
+
if (minValue && maxValue && minValue.compare(maxValue) > 0) return null;
|
|
129
|
+
let startDate = range.start;
|
|
130
|
+
let endDate = range.end;
|
|
131
|
+
if (minValue && endDate.compare(minValue) < 0 || maxValue && startDate.compare(maxValue) > 0) return null;
|
|
132
|
+
if (minValue && startDate.compare(minValue) < 0) startDate = minValue;
|
|
133
|
+
if (maxValue && startDate.compare(maxValue) > 0) startDate = maxValue;
|
|
134
|
+
if (minValue && endDate.compare(minValue) < 0) endDate = minValue;
|
|
135
|
+
if (maxValue && endDate.compare(maxValue) > 0) endDate = maxValue;
|
|
136
|
+
if (startDate.compare(endDate) > 0) return null;
|
|
137
|
+
return {
|
|
138
|
+
start: startDate,
|
|
139
|
+
end: endDate
|
|
140
|
+
};
|
|
141
|
+
}, [minValue, maxValue]);
|
|
142
|
+
const isRangeWithinBounds = useCallback((range) => {
|
|
143
|
+
if (minValue && range.start.compare(minValue) < 0) return false;
|
|
144
|
+
if (maxValue && range.end.compare(maxValue) > 0) return false;
|
|
145
|
+
return true;
|
|
146
|
+
}, [minValue, maxValue]);
|
|
113
147
|
const isValidRange = useCallback((newValue) => {
|
|
114
148
|
if (newValue?.start && newValue?.end) {
|
|
115
149
|
const startDate = newValue.start;
|
|
@@ -123,18 +157,20 @@ var DateRangePickerBase = (props) => {
|
|
|
123
157
|
}, [t]);
|
|
124
158
|
const handleCalendarStatesChange = (newValue) => {
|
|
125
159
|
if (newValue) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
160
|
+
const clampedValue = clampRangeToBounds(newValue);
|
|
161
|
+
if (!clampedValue) return;
|
|
162
|
+
if (isValidRange(clampedValue)) return;
|
|
163
|
+
dialogState.setValue(clampedValue);
|
|
164
|
+
const startDate = clampedValue.start;
|
|
165
|
+
const endDate = clampedValue.end;
|
|
130
166
|
leftCalendarState.setFocusedDate(startDate);
|
|
131
167
|
if (startDate.year === endDate.year && startDate.month === endDate.month) rightCalendarState.setFocusedDate(startDate.add({ months: 1 }));
|
|
132
168
|
else rightCalendarState.setFocusedDate(endDate);
|
|
133
|
-
leftCalendarState.setValue(
|
|
134
|
-
rightCalendarState.setValue(
|
|
169
|
+
leftCalendarState.setValue(clampedValue);
|
|
170
|
+
rightCalendarState.setValue(clampedValue);
|
|
135
171
|
setRangeSelection({
|
|
136
|
-
start:
|
|
137
|
-
end:
|
|
172
|
+
start: clampedValue.start,
|
|
173
|
+
end: clampedValue.end,
|
|
138
174
|
isSelecting: false
|
|
139
175
|
});
|
|
140
176
|
setHoverDate(null);
|
|
@@ -176,6 +212,7 @@ var DateRangePickerBase = (props) => {
|
|
|
176
212
|
leftCalendarState.setFocusedDate(date.subtract({ months: 1 }));
|
|
177
213
|
}
|
|
178
214
|
}
|
|
215
|
+
if (isDateOutsideBounds(date)) return;
|
|
179
216
|
if (!rangeSelection.isSelecting || !rangeSelection.start) {
|
|
180
217
|
setRangeSelection({
|
|
181
218
|
start: date,
|
|
@@ -188,18 +225,17 @@ var DateRangePickerBase = (props) => {
|
|
|
188
225
|
} else {
|
|
189
226
|
const { start } = rangeSelection;
|
|
190
227
|
const end = date;
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
dialogState.setValue(newRange);
|
|
228
|
+
const clampedRange = clampRangeToBounds({
|
|
229
|
+
start: start.compare(end) <= 0 ? start : end,
|
|
230
|
+
end: start.compare(end) <= 0 ? end : start
|
|
231
|
+
});
|
|
232
|
+
if (!clampedRange) return;
|
|
233
|
+
leftCalendarState.setValue(clampedRange);
|
|
234
|
+
rightCalendarState.setValue(clampedRange);
|
|
235
|
+
dialogState.setValue(clampedRange);
|
|
200
236
|
setRangeSelection({
|
|
201
|
-
start:
|
|
202
|
-
end:
|
|
237
|
+
start: clampedRange.start,
|
|
238
|
+
end: clampedRange.end,
|
|
203
239
|
isSelecting: false
|
|
204
240
|
});
|
|
205
241
|
setHoverDate(null);
|
|
@@ -209,7 +245,9 @@ var DateRangePickerBase = (props) => {
|
|
|
209
245
|
rangeSelection,
|
|
210
246
|
leftCalendarState,
|
|
211
247
|
rightCalendarState,
|
|
212
|
-
dialogState
|
|
248
|
+
dialogState,
|
|
249
|
+
isDateOutsideBounds,
|
|
250
|
+
clampRangeToBounds
|
|
213
251
|
]);
|
|
214
252
|
const handleKeyboardNavigation = useCallback((event, date, calendarSide) => {
|
|
215
253
|
const currentState = calendarSide === "left" ? leftCalendarState : rightCalendarState;
|
|
@@ -295,18 +333,28 @@ var DateRangePickerBase = (props) => {
|
|
|
295
333
|
handleDateSelection
|
|
296
334
|
]);
|
|
297
335
|
const syncCalendarStates = useCallback((newValue) => {
|
|
298
|
-
if (
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
336
|
+
if (newValue === null) {
|
|
337
|
+
setValidationRangeError(void 0);
|
|
338
|
+
leftCalendarState.setValue(null);
|
|
339
|
+
rightCalendarState.setValue(null);
|
|
340
|
+
dialogState.setValue(null);
|
|
341
|
+
setRangeSelection({
|
|
342
|
+
start: null,
|
|
343
|
+
end: null,
|
|
344
|
+
isSelecting: false
|
|
345
|
+
});
|
|
346
|
+
setHoverDate(null);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
const clampedValue = clampRangeToBounds(newValue);
|
|
350
|
+
if (!clampedValue) return;
|
|
351
|
+
if (isValidRange(clampedValue)) return;
|
|
352
|
+
leftCalendarState.setValue(clampedValue);
|
|
353
|
+
rightCalendarState.setValue(clampedValue);
|
|
354
|
+
dialogState.setValue(clampedValue);
|
|
355
|
+
setRangeSelection({
|
|
356
|
+
start: clampedValue.start,
|
|
357
|
+
end: clampedValue.end,
|
|
310
358
|
isSelecting: false
|
|
311
359
|
});
|
|
312
360
|
setHoverDate(null);
|
|
@@ -314,24 +362,32 @@ var DateRangePickerBase = (props) => {
|
|
|
314
362
|
isValidRange,
|
|
315
363
|
leftCalendarState,
|
|
316
364
|
rightCalendarState,
|
|
317
|
-
dialogState
|
|
365
|
+
dialogState,
|
|
366
|
+
clampRangeToBounds
|
|
318
367
|
]);
|
|
319
368
|
const onApply = () => {
|
|
320
|
-
|
|
369
|
+
let valueToApply = dialogState.value;
|
|
370
|
+
if (rangeSelection.start && rangeSelection.end) valueToApply = {
|
|
321
371
|
start: rangeSelection.start,
|
|
322
372
|
end: rangeSelection.end
|
|
323
|
-
}
|
|
324
|
-
|
|
373
|
+
};
|
|
374
|
+
const clampedValue = clampRangeToBounds(valueToApply);
|
|
375
|
+
if (clampedValue) state.setValue(clampedValue);
|
|
325
376
|
state.toggle();
|
|
326
377
|
};
|
|
327
378
|
const onTodayPress = () => {
|
|
328
379
|
const todayDate = today(getLocalTimeZone());
|
|
329
|
-
|
|
330
|
-
rightCalendarState.setFocusedDate(todayDate.add({ months: 1 }));
|
|
331
|
-
syncCalendarStates({
|
|
380
|
+
const clampedTodayRange = clampRangeToBounds({
|
|
332
381
|
start: todayDate,
|
|
333
382
|
end: todayDate
|
|
334
383
|
});
|
|
384
|
+
if (!clampedTodayRange) return;
|
|
385
|
+
const startDate = clampedTodayRange.start;
|
|
386
|
+
const endDate = clampedTodayRange.end;
|
|
387
|
+
leftCalendarState.setFocusedDate(startDate);
|
|
388
|
+
if (startDate.year === endDate.year && startDate.month === endDate.month) rightCalendarState.setFocusedDate(startDate.add({ months: 1 }));
|
|
389
|
+
else rightCalendarState.setFocusedDate(endDate);
|
|
390
|
+
syncCalendarStates(clampedTodayRange);
|
|
335
391
|
};
|
|
336
392
|
const onOpenChange = (isOpen) => {
|
|
337
393
|
state.toggle();
|
|
@@ -387,59 +443,84 @@ var DateRangePickerBase = (props) => {
|
|
|
387
443
|
end: thisMonthEnd
|
|
388
444
|
};
|
|
389
445
|
};
|
|
446
|
+
const createPreset = (params) => {
|
|
447
|
+
let clampedValue = clampRangeToBounds(params.getValue());
|
|
448
|
+
let isDisabled = false;
|
|
449
|
+
if (params.keepEnabledUnlessFutureMin) {
|
|
450
|
+
let minDateIsInFuture = false;
|
|
451
|
+
if (minValue && minValue.compare(todayDate) > 0) minDateIsInFuture = true;
|
|
452
|
+
if (minDateIsInFuture) {
|
|
453
|
+
isDisabled = true;
|
|
454
|
+
clampedValue = null;
|
|
455
|
+
} else if (!clampedValue && maxValue) clampedValue = {
|
|
456
|
+
start: maxValue,
|
|
457
|
+
end: maxValue
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
if (!clampedValue) isDisabled = true;
|
|
461
|
+
if (clampedValue && !isRangeWithinBounds(clampedValue)) isDisabled = true;
|
|
462
|
+
return {
|
|
463
|
+
label: params.label,
|
|
464
|
+
getValue: params.getValue,
|
|
465
|
+
clampedValue,
|
|
466
|
+
isDisabled
|
|
467
|
+
};
|
|
468
|
+
};
|
|
390
469
|
const presets = [
|
|
391
|
-
{
|
|
470
|
+
createPreset({
|
|
392
471
|
label: t(($) => $.ui.datePicker.presets.thisWeek, { ns: "ui" }),
|
|
393
472
|
getValue: getThisWeekRange
|
|
394
|
-
},
|
|
395
|
-
{
|
|
473
|
+
}),
|
|
474
|
+
createPreset({
|
|
396
475
|
label: t(($) => $.ui.datePicker.presets.lastWeek, { ns: "ui" }),
|
|
397
476
|
getValue: getLastWeekRange
|
|
398
|
-
},
|
|
399
|
-
{
|
|
477
|
+
}),
|
|
478
|
+
createPreset({
|
|
400
479
|
label: t(($) => $.ui.datePicker.presets.thisAndLastWeek, { ns: "ui" }),
|
|
401
480
|
getValue: getThisAndLastWeekRange
|
|
402
|
-
},
|
|
403
|
-
{
|
|
481
|
+
}),
|
|
482
|
+
createPreset({
|
|
404
483
|
label: t(($) => $.ui.datePicker.presets.thisMonth, { ns: "ui" }),
|
|
405
484
|
getValue: getThisMonthRange
|
|
406
|
-
},
|
|
407
|
-
{
|
|
485
|
+
}),
|
|
486
|
+
createPreset({
|
|
408
487
|
label: t(($) => $.ui.datePicker.presets.thisAndLastMonth, { ns: "ui" }),
|
|
409
488
|
getValue: getThisAndLastMonthRange
|
|
410
|
-
},
|
|
411
|
-
{
|
|
489
|
+
}),
|
|
490
|
+
createPreset({
|
|
412
491
|
label: t(($) => $.ui.datePicker.presets.thisYear, { ns: "ui" }),
|
|
413
492
|
getValue: () => ({
|
|
414
493
|
start: startOfYear(todayDate),
|
|
415
494
|
end: todayDate
|
|
416
495
|
})
|
|
417
|
-
},
|
|
418
|
-
{
|
|
496
|
+
}),
|
|
497
|
+
createPreset({
|
|
419
498
|
label: t(($) => $.ui.datePicker.presets.lastYear, { ns: "ui" }),
|
|
420
499
|
getValue: () => ({
|
|
421
500
|
start: startOfYear(todayDate.subtract({ years: 1 })),
|
|
422
501
|
end: endOfYear(todayDate.subtract({ years: 1 }))
|
|
423
502
|
})
|
|
424
|
-
},
|
|
425
|
-
{
|
|
503
|
+
}),
|
|
504
|
+
createPreset({
|
|
426
505
|
label: t(($) => $.ui.datePicker.presets.thisAndLastYear, { ns: "ui" }),
|
|
427
506
|
getValue: () => ({
|
|
428
507
|
start: startOfYear(todayDate.subtract({ years: 1 })),
|
|
429
508
|
end: todayDate
|
|
430
509
|
})
|
|
431
|
-
},
|
|
432
|
-
{
|
|
510
|
+
}),
|
|
511
|
+
createPreset({
|
|
433
512
|
label: t(($) => $.ui.datePicker.presets.soFar, { ns: "ui" }),
|
|
434
513
|
getValue: () => ({
|
|
435
514
|
start: startOfYear(todayDate),
|
|
436
515
|
end: todayDate
|
|
437
|
-
})
|
|
438
|
-
|
|
516
|
+
}),
|
|
517
|
+
keepEnabledUnlessFutureMin: true
|
|
518
|
+
})
|
|
439
519
|
];
|
|
440
520
|
const selectPreset = (preset) => {
|
|
521
|
+
if (preset.isDisabled || !preset.clampedValue) return;
|
|
441
522
|
setActivePreset(preset.label);
|
|
442
|
-
const presetValue = preset.
|
|
523
|
+
const presetValue = preset.clampedValue;
|
|
443
524
|
syncCalendarStates(presetValue);
|
|
444
525
|
const startDate = presetValue.start;
|
|
445
526
|
leftCalendarState.setFocusedDate(startDate);
|
|
@@ -486,8 +567,9 @@ var DateRangePickerBase = (props) => {
|
|
|
486
567
|
sidebar: /* @__PURE__ */ jsx("div", {
|
|
487
568
|
className: "flex w-full flex-row overflow-auto border-elevation-outline-default-1 border-solid [-ms-overflow-style:none] [scrollbar-width:none] md:w-[156px] md:flex-col md:border-r [&::-webkit-scrollbar]:hidden",
|
|
488
569
|
children: presets.map((preset) => /* @__PURE__ */ jsx(Button, {
|
|
570
|
+
isDisabled: preset.isDisabled,
|
|
489
571
|
onClick: () => selectPreset(preset),
|
|
490
|
-
className: clsx("w-full px-2 py-1 text-left md:px-list-side-item-left md:py-list-height-item", activePreset !== preset.label && "text-interactive-text-secondary-idle hover:text-interactive-text-secondary-hover", activePreset === preset.label && "bg-interactive-contained-primary-idle text-interactive-text-secondary-idle-inverted"),
|
|
572
|
+
className: clsx("w-full px-2 py-1 text-left md:px-list-side-item-left md:py-list-height-item disabled:text-interactive-text-secondary-disabled!", activePreset !== preset.label && "text-interactive-text-secondary-idle hover:text-interactive-text-secondary-hover", activePreset === preset.label && "bg-interactive-contained-primary-idle text-interactive-text-secondary-idle-inverted"),
|
|
491
573
|
children: /* @__PURE__ */ jsx(Typography, {
|
|
492
574
|
size: "label-2",
|
|
493
575
|
sizeMobile: "label-3",
|