onekijs-ui 0.21.1 → 0.21.2

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.
@@ -2,5 +2,6 @@ import { DateRangeAdapter } from '../typings';
2
2
  declare const useDateRangeAdapter: () => DateRangeAdapter<{
3
3
  from: Date | null;
4
4
  to: Date | null;
5
+ label?: string | null | undefined;
5
6
  }>;
6
7
  export default useDateRangeAdapter;
@@ -1,4 +1,4 @@
1
1
  import { AnonymousObject } from 'onekijs-framework';
2
- import { DateQuickRange, DateStringRange, DefaultQuickRange } from '../typings';
3
- declare const useQuickRanges: (ranges: DateQuickRange | DefaultQuickRange | ((DateQuickRange | DefaultQuickRange)[])) => AnonymousObject<DateStringRange>;
2
+ import { DateStringRange, QuickRange } from '../typings';
3
+ declare const useQuickRanges: (ranges: QuickRange | QuickRange[]) => AnonymousObject<DateStringRange>;
4
4
  export default useQuickRanges;
@@ -2,5 +2,6 @@ import { DateRangeAdapter } from '../typings';
2
2
  declare const useTimestampRangeAdapter: (format?: 'seconds' | 'milliseconds') => DateRangeAdapter<{
3
3
  from: number | null;
4
4
  to: number | null;
5
+ label?: string | null | undefined;
5
6
  }>;
6
7
  export default useTimestampRangeAdapter;
@@ -2,10 +2,12 @@
2
2
  import { AnonymousObject } from 'onekijs-framework';
3
3
  import { StylableProps } from '../../styles/typings';
4
4
  import { DropdownWidthModifier } from '../dropdown/typings';
5
+ import { Placement } from '@popperjs/core';
5
6
  export type BasePickerProps = StylableProps & {
6
7
  animationMs?: number;
7
8
  attachDropdownToBody?: boolean;
8
9
  autoFocus?: boolean;
10
+ combo?: boolean;
9
11
  disabled?: boolean;
10
12
  dropdownWidthModifier?: DropdownWidthModifier;
11
13
  nullable?: boolean;
@@ -13,11 +15,13 @@ export type BasePickerProps = StylableProps & {
13
15
  onFocus?: () => void;
14
16
  openOnFocus?: boolean;
15
17
  placeholder?: string;
18
+ placement?: Placement;
16
19
  };
17
20
  export type CalendarComponentProps = StylableProps & {
18
21
  from: DatePickerDate;
19
22
  maxDate?: Date;
20
23
  minDate?: Date;
24
+ nextSelectEdge: 'from' | 'to';
21
25
  onChange: (formDate: string | undefined, toDate?: string) => void;
22
26
  type: DatePickerType;
23
27
  to: DatePickerDate;
@@ -65,20 +69,23 @@ export type DatePickerType = {
65
69
  };
66
70
  export type DateQuickRange = {
67
71
  label: string;
68
- from: Date;
69
- to: Date;
72
+ from: Date | (() => Date);
73
+ to: Date | (() => Date);
70
74
  };
71
75
  export type DateRange = {
72
76
  from: Date | null;
73
77
  to: Date | null;
78
+ label?: string | null;
74
79
  };
75
80
  export type DateStringRange = {
76
81
  from: string | null;
77
82
  to: string | null;
83
+ label?: string | null;
78
84
  };
79
85
  export type TimestampRange = {
80
86
  from: number | null;
81
87
  to: number | null;
88
+ label?: string | null;
82
89
  };
83
90
  export type DateRangeAdapter<T extends any = any> = {
84
91
  fromDateRange: (range: DateStringRange) => T;
@@ -86,9 +93,10 @@ export type DateRangeAdapter<T extends any = any> = {
86
93
  };
87
94
  export type DateRangePickerProps<T extends any = any> = BasePickerProps & {
88
95
  adapter?: DateRangeAdapter<T>;
89
- value?: T | null;
96
+ closeOnQuickSelect?: boolean;
90
97
  onChange?: (value: T | null) => void;
91
98
  quickRanges?: AnonymousObject<DateStringRange>;
99
+ value?: T | null;
92
100
  };
93
101
  export type DateTimePickerProps<T extends any = any> = DatePickerProps<T> & DisplayTime;
94
102
  export type DateTimeRangePickerProps<T extends any = any> = DateRangePickerProps<T> & DisplayTime;
@@ -99,13 +107,16 @@ export type DisplayTime = {
99
107
  displaySeconds?: boolean;
100
108
  };
101
109
  export type PickerComponentProps = BasePickerProps & DisplayTime & {
110
+ closeOnQuickSelect?: boolean;
102
111
  type: DatePickerType;
103
112
  quickRanges?: AnonymousObject<DateStringRange>;
104
113
  value?: string | null;
105
- onChange?: (value: string | null) => void;
114
+ onChange?: (value: string | null, label?: string | null) => void;
115
+ label?: string | null;
106
116
  };
117
+ export type QuickRange = DefaultQuickRange | DateQuickRange;
107
118
  export type QuickTimeRangeComponentProps = {
108
- currentQuickRangeLabel?: string;
119
+ currentQuickRangeLabel?: string | null;
109
120
  quickRanges: AnonymousObject<DateStringRange>;
110
121
  onChange: (quickRangeLabel: string) => void;
111
122
  };
@@ -1,7 +1,7 @@
1
1
  import { AnonymousObject } from 'onekijs-framework';
2
- import { DateStringRange } from './typings';
3
- export declare const dateToString: (d: Date | string) => string;
4
- export declare const toDateRange: (value: string | null) => DateStringRange | null;
5
- export declare const qr: (quickRange: string) => DateStringRange | null;
6
- export declare const defaultQuickRanges: () => AnonymousObject<DateStringRange>;
2
+ import { DateQuickRange, DateStringRange, DefaultQuickRange } from './typings';
3
+ export declare const dateToString: (d: Date | string | (() => Date)) => string;
4
+ export declare const toDateRange: (value: string | null, label?: string | null) => DateStringRange | null;
5
+ export declare const qr: (quickRange: DefaultQuickRange) => DateQuickRange;
6
+ export declare const defaultQuickRanges: () => AnonymousObject<DateQuickRange>;
7
7
  export declare const findQuickRangeLabel: (quickRanges: AnonymousObject<DateStringRange> | undefined, dateRange: DateStringRange | string | null | undefined) => string | undefined;
package/dist/index.js CHANGED
@@ -885,7 +885,7 @@ const TogglerIcon = styled(IconComponent$b) `
885
885
  const AccordionPanelTitle = ({ title, active, onClick }) => {
886
886
  return (React.createElement("div", { className: "o-accordion-panel-title", onClick: onClick },
887
887
  React.createElement(TogglerIcon, { open: active }),
888
- React.createElement("span", null, `${title}`)));
888
+ React.createElement("span", null, title)));
889
889
  };
890
890
 
891
891
  const AccordionPanel = ({ title, initialActive, initialExpand, children, Component = AccordionPanelTitle, link, }) => {
@@ -12005,6 +12005,12 @@ const datePickerStyle = () => {
12005
12005
  }
12006
12006
  }
12007
12007
 
12008
+ .o-datepicker-input {
12009
+ input:read-only {
12010
+ ${cursor('pointer')}
12011
+ }
12012
+ }
12013
+
12008
12014
 
12009
12015
  .o-datepicker-icon {
12010
12016
  ${cursor('pointer')}
@@ -12199,72 +12205,6 @@ const useDatePickerContext = () => {
12199
12205
  return React.useContext(DefaultDatePickerContext);
12200
12206
  };
12201
12207
 
12202
- const dateToString = (d) => {
12203
- if (typeof d === 'string') {
12204
- d = new Date(d);
12205
- }
12206
- return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`;
12207
- };
12208
- const toDateRange = (value) => {
12209
- if (value) {
12210
- const [from, to] = value.trim().split(/ to\s*/);
12211
- return {
12212
- from: from && from.trim() ? from.trim() : null,
12213
- to: to && to.trim() ? to.trim() : null,
12214
- };
12215
- }
12216
- else {
12217
- return null;
12218
- }
12219
- };
12220
- const qr = (quickRange) => {
12221
- if (typeof quickRange === 'string') {
12222
- const from = new Date();
12223
- const to = new Date();
12224
- switch (quickRange) {
12225
- case 'Last hour':
12226
- from.setHours(from.getHours() - 1);
12227
- break;
12228
- case 'Last day':
12229
- from.setDate(from.getDate() - 1);
12230
- break;
12231
- case 'Last week':
12232
- from.setDate(from.getDate() - 7);
12233
- break;
12234
- case 'Last month':
12235
- from.setMonth(from.getMonth() - 1);
12236
- break;
12237
- case 'Last year':
12238
- from.setFullYear(from.getFullYear() - 1);
12239
- break;
12240
- default: return null;
12241
- }
12242
- return { from: dateToString(from), to: dateToString(to) };
12243
- }
12244
- return quickRange;
12245
- };
12246
- const defaultQuickRanges = () => {
12247
- return ['Last hour', 'Last day', 'Last week', 'Last month', 'Last year'].reduce((accumulator, label) => {
12248
- const quickRange = qr(label);
12249
- if (quickRange) {
12250
- accumulator[label] = quickRange;
12251
- }
12252
- return accumulator;
12253
- }, {});
12254
- };
12255
- const findQuickRangeLabel = (quickRanges, dateRange) => {
12256
- if (!quickRanges || !dateRange)
12257
- return;
12258
- const dr = typeof dateRange === 'string' ? toDateRange(dateRange) : dateRange;
12259
- if (dr === null)
12260
- return;
12261
- if (!dr.from || !dr.to)
12262
- return;
12263
- return Object.keys(quickRanges).find((label) => {
12264
- return dr.from === quickRanges[label].from && dr.to === quickRanges[label].to;
12265
- });
12266
- };
12267
-
12268
12208
  const isCurrent = (d, year, month, day) => {
12269
12209
  return d.getFullYear() === year && d.getMonth() === month && d.getDate() === day;
12270
12210
  };
@@ -12319,7 +12259,7 @@ const defaultMinDate = new Date();
12319
12259
  defaultMinDate.setFullYear(1900);
12320
12260
  const defaultMaxDate = new Date();
12321
12261
  defaultMaxDate.setFullYear(2100);
12322
- const CalendarComponent = ({ from, to, type, minDate = defaultMinDate, maxDate = defaultMaxDate, className, onChange, }) => {
12262
+ const CalendarComponent = ({ from, to, type, minDate = defaultMinDate, maxDate = defaultMaxDate, nextSelectEdge, className, onChange, }) => {
12323
12263
  const maxYear = maxDate.getFullYear();
12324
12264
  const minYear = minDate.getFullYear();
12325
12265
  const years = React.useRef([...Array(maxYear).keys()].slice(minYear));
@@ -12461,23 +12401,44 @@ const CalendarComponent = ({ from, to, type, minDate = defaultMinDate, maxDate =
12461
12401
  calendarDays.map((calendarDay, index) => (React.createElement("div", { key: `${fromDay}-${index}`, className: `o-calendar-day${calendarDay.endRange
12462
12402
  ? ` o-calendar-day-${isInversed ? 'start' : 'end'}-range${transientTo ? '-transient' : ''}`
12463
12403
  : ''}${calendarDay.startRange ? ` o-calendar-day-${isInversed ? 'end' : 'start'}-range` : ''}${calendarDay.active ? ' o-calendar-day-active' : ''}${calendarDay.inRange ? ` o-calendar-day-in-range${transientTo ? '-transient' : ''}` : ''}${calendarDay.month === currentMonth ? ' o-calendar-day-in-month' : ''}${calendarDay.current ? ' o-calendar-day-current' : ''}`, onClick: () => {
12464
- const currentDateString = `${calendarDay.year}-${String(calendarDay.month + 1).padStart(2, '0')}-${String(calendarDay.day).padStart(2, '0')}`;
12404
+ const nextDateString = `${calendarDay.year}-${String(calendarDay.month + 1).padStart(2, '0')}-${String(calendarDay.day).padStart(2, '0')}`;
12465
12405
  if (type.range && from.year !== undefined && from.month !== undefined && from.day !== undefined) {
12466
- // we assume we change the "to" date
12467
- // if the new "to" date is before the "from" date, we need to switch
12406
+ // It's a date range and not the first selection
12407
+ // We must determine if it's a change for the from or the to
12468
12408
  const fromDateString = `${from.year}-${from.month.padStart(2, '0')}-${String(from.day).padStart(2, '0')}`;
12469
12409
  const fromDate = new Date(fromDateString);
12470
- const endDate = new Date(currentDateString);
12471
- if (fromDate <= endDate) {
12472
- onChange(undefined, currentDateString);
12410
+ let endDate = undefined;
12411
+ let endDateString = undefined;
12412
+ if (to.year !== undefined && to.month !== undefined && to.day !== undefined) {
12413
+ // it's not the second click
12414
+ endDateString = `${to.year}-${to.month.padStart(2, '0')}-${String(to.day).padStart(2, '0')}`;
12415
+ endDate = new Date(endDateString);
12416
+ }
12417
+ const nextDate = new Date(nextDateString);
12418
+ if (endDate) {
12419
+ if (nextDate <= fromDate) {
12420
+ onChange(nextDateString, endDateString);
12421
+ }
12422
+ else if (nextDate >= endDate) {
12423
+ onChange(fromDateString, nextDateString);
12424
+ }
12425
+ else if (nextSelectEdge === 'from') {
12426
+ onChange(nextDateString, endDateString);
12427
+ }
12428
+ else {
12429
+ onChange(fromDateString, nextDateString);
12430
+ }
12431
+ }
12432
+ else if (nextDate <= fromDate) {
12433
+ onChange(nextDateString, fromDateString);
12473
12434
  }
12474
12435
  else {
12475
- onChange(currentDateString, fromDateString);
12436
+ onChange(fromDateString, nextDateString);
12476
12437
  }
12477
12438
  }
12478
12439
  else {
12479
12440
  // we assume that it's not a range or the first selection of the range
12480
- onChange(currentDateString);
12441
+ onChange(nextDateString);
12481
12442
  }
12482
12443
  }, onMouseEnter: () => {
12483
12444
  if (transientTo) {
@@ -12716,11 +12677,10 @@ const formatDate = (type, fromDate, fromTime, toDate, toTime) => {
12716
12677
  }
12717
12678
  return result;
12718
12679
  };
12719
- const PickerComponent = ({ animationMs = 200, attachDropdownToBody = true, autoFocus, className, disabled, dropdownWidthModifier = 'min', nullable = false, onBlur: forwardBlur, onChange: forwardChange, onFocus: forwardFocus, openOnFocus = false, placeholder, quickRanges, type, displayHours = true, displayMinutes = true, displaySeconds = true, value: externalValue, }) => {
12680
+ const PickerComponent = ({ animationMs = 200, attachDropdownToBody = true, autoFocus, className, closeOnQuickSelect = true, combo = false, disabled, dropdownWidthModifier = 'min', label, nullable = false, onBlur: forwardBlur, onChange: forwardChange, onFocus: forwardFocus, openOnFocus = false, placeholder, placement = 'bottom-start', quickRanges, type, displayHours = true, displayMinutes = true, displaySeconds = true, value: externalValue, }) => {
12720
12681
  const containerRef = React.useRef(null);
12721
12682
  const stateRef = React.useRef({});
12722
12683
  const dropdownRef = React.useRef(null);
12723
- const quickRangesRef = React.useRef(quickRanges);
12724
12684
  const lastExternalValueRef = React.useRef();
12725
12685
  const currentValueRef = React.useRef(null);
12726
12686
  const [open, setOpen] = React.useState(false);
@@ -12732,12 +12692,6 @@ const PickerComponent = ({ animationMs = 200, attachDropdownToBody = true, autoF
12732
12692
  value = currentValueRef.current;
12733
12693
  }
12734
12694
  const [fromString, toString] = value ? value.split(/ to\s*/) : [];
12735
- const [label, setLabel] = React.useState(() => {
12736
- if (type.range) {
12737
- return findQuickRangeLabel(quickRangesRef.current, value);
12738
- }
12739
- return;
12740
- });
12741
12695
  const validFromRef = React.useRef();
12742
12696
  const validToRef = React.useRef();
12743
12697
  if (!fromString || /\s*/.test(fromString)) {
@@ -12746,6 +12700,8 @@ const PickerComponent = ({ animationMs = 200, attachDropdownToBody = true, autoF
12746
12700
  if (!toString || /\s*/.test(toString)) {
12747
12701
  validToRef.current = undefined;
12748
12702
  }
12703
+ // this setting is used to detect if the user changes the from or the to
12704
+ const nextSelectEdgeRef = React.useRef('to');
12749
12705
  const from = parseDate(fromString?.trim());
12750
12706
  const previousFrom = parseDate(validFromRef.current);
12751
12707
  if (!type['date'] || !isValidDate(`${from['day']}-${from['month']}-${from['year']}`)) {
@@ -12823,14 +12779,13 @@ const PickerComponent = ({ animationMs = 200, attachDropdownToBody = true, autoF
12823
12779
  }
12824
12780
  }
12825
12781
  }, [open, forwardBlur, setOpen, focus]);
12826
- const onChange = React.useCallback((nextValue) => {
12782
+ const onChange = React.useCallback((nextValue, label) => {
12827
12783
  currentValueRef.current = nextValue;
12828
- setLabel(undefined);
12829
12784
  // check if the nextValue is a valid value
12830
12785
  // if it's not a valid value, we keep it internally
12831
12786
  if (forwardChange && isValidValue(nextValue, type)) {
12832
12787
  setInternalValue(null);
12833
- forwardChange(nextValue);
12788
+ forwardChange(nextValue, label);
12834
12789
  }
12835
12790
  else {
12836
12791
  setInternalValue(nextValue);
@@ -12843,8 +12798,17 @@ const PickerComponent = ({ animationMs = 200, attachDropdownToBody = true, autoF
12843
12798
  if (toDate === undefined) {
12844
12799
  toDate = to['date'];
12845
12800
  }
12801
+ if (fromDate !== from['date']) {
12802
+ nextSelectEdgeRef.current = 'to';
12803
+ }
12804
+ else {
12805
+ nextSelectEdgeRef.current = 'from';
12806
+ }
12846
12807
  onChange(formatDate(type, fromDate, from['time'], toDate, to['time']));
12847
12808
  };
12809
+ const removeLabel = () => {
12810
+ onChangeDate();
12811
+ };
12848
12812
  const onChangeTime = (nextTime, edge) => {
12849
12813
  if (edge === 'from') {
12850
12814
  onChange(formatDate(type, from['date'], nextTime, to['date'], to['time']));
@@ -12854,11 +12818,13 @@ const PickerComponent = ({ animationMs = 200, attachDropdownToBody = true, autoF
12854
12818
  }
12855
12819
  };
12856
12820
  const onChangeQuickRange = (quickRangeLabel) => {
12857
- if (quickRangesRef.current) {
12858
- const quickRange = quickRangesRef.current[quickRangeLabel];
12821
+ if (quickRanges) {
12822
+ const quickRange = quickRanges[quickRangeLabel];
12859
12823
  if (quickRange) {
12860
- onChange(`${quickRange.from} to ${quickRange.to}`);
12861
- setLabel(quickRangeLabel);
12824
+ onChange(`${quickRange.from} to ${quickRange.to}`, quickRangeLabel);
12825
+ }
12826
+ if (closeOnQuickSelect) {
12827
+ setOpen(false);
12862
12828
  }
12863
12829
  }
12864
12830
  };
@@ -12882,14 +12848,6 @@ const PickerComponent = ({ animationMs = 200, attachDropdownToBody = true, autoF
12882
12848
  onChange,
12883
12849
  };
12884
12850
  }, [open, setOpen, triggerRef, nullable, onChange]);
12885
- React.useEffect(() => {
12886
- if (type.range && !label) {
12887
- const quickRangeLabel = findQuickRangeLabel(quickRangesRef.current, value);
12888
- if (quickRangeLabel) {
12889
- setLabel(quickRangeLabel);
12890
- }
12891
- }
12892
- }, [value]);
12893
12851
  React.useEffect(() => {
12894
12852
  if (forwardChange && lastExternalValueRef.current !== undefined && externalValue !== undefined && externalValue !== lastExternalValueRef.current) {
12895
12853
  // case when we block the onChange due to a wrong internal value
@@ -12900,20 +12858,23 @@ const PickerComponent = ({ animationMs = 200, attachDropdownToBody = true, autoF
12900
12858
  });
12901
12859
  return (React.createElement(DefaultDatePickerContext.Provider, { value: context },
12902
12860
  React.createElement("div", { className: addClassname('o-datepicker', className), ref: containerRef, onMouseDown: () => (stateRef.current.keepFocus = true), onMouseUp: () => (stateRef.current.keepFocus = false) },
12903
- React.createElement(Dropdown, { attachToBody: attachDropdownToBody, open: open, distance: 0, animationTimeout: animationMs, onDropStart: onOpen, onCollapseDone: onClosed, placement: "bottom-start", widthModifier: dropdownWidthModifier, className: className, zIndex: attachDropdownToBody ? 2000 : undefined },
12861
+ React.createElement(Dropdown, { attachToBody: attachDropdownToBody, open: open, distance: 0, animationTimeout: animationMs, onDropStart: onOpen, onCollapseDone: onClosed, placement: placement, widthModifier: dropdownWidthModifier, className: className, zIndex: attachDropdownToBody ? 2000 : undefined },
12904
12862
  React.createElement("div", { ref: dropdownRef, className: `o-datepicker-dropdown-content${type['range'] ? ' o-datepicker-range' : ''}${validFromRef.current !== undefined ? ' o-datepicker-active' : ''}` },
12905
- type['range'] && quickRangesRef.current && Object.keys(quickRangesRef.current).length > 0 && (React.createElement(QuickTimeRangeComponent, { key: "quick_range", quickRanges: quickRangesRef.current, onChange: onChangeQuickRange, currentQuickRangeLabel: label })),
12863
+ type['range'] && quickRanges && Object.keys(quickRanges).length > 0 && (React.createElement(QuickTimeRangeComponent, { key: "quick_range", quickRanges: quickRanges, onChange: onChangeQuickRange, currentQuickRangeLabel: label })),
12906
12864
  type['date'] && (React.createElement("div", { className: "o-calendar", key: "calendar" },
12907
- React.createElement(CalendarComponent, { from: from, to: to, type: type, onChange: onChangeDate }))),
12865
+ React.createElement(CalendarComponent, { from: from, to: to, type: type, onChange: onChangeDate, nextSelectEdge: nextSelectEdgeRef.current }))),
12908
12866
  type['time'] && (React.createElement("div", { className: "o-time", key: "time" },
12909
12867
  React.createElement(TimeComponent, { from: from, to: to, type: type, onChange: onChangeTime, displayHours: displayHours, displayMinutes: displayMinutes, displaySeconds: displaySeconds }))))),
12910
12868
  React.createElement("span", { ref: triggerRef, key: "input" },
12911
- React.createElement(Input, { placeholder: placeholder, onChange: (e) => onChange(e.target.value), value: label ? label : !value ? '' : value, onFocus: onFocus, onBlur: onBlur, autoFocus: autoFocus, disabled: disabled, SuffixComponent: IconComponent, onClick: () => {
12869
+ React.createElement(Input, { className: "o-datepicker-input", placeholder: placeholder, onChange: (e) => onChange(e.target.value), value: label ? label : !value ? '' : value, onFocus: onFocus, onBlur: onBlur, autoFocus: autoFocus, disabled: disabled, SuffixComponent: IconComponent, readOnly: !combo, onClick: () => {
12912
12870
  if (!open) {
12913
12871
  setOpen(true);
12914
12872
  }
12873
+ else if (combo) {
12874
+ removeLabel();
12875
+ }
12915
12876
  else {
12916
- setLabel(undefined);
12877
+ setOpen(false);
12917
12878
  }
12918
12879
  } })))));
12919
12880
  };
@@ -12937,6 +12898,77 @@ const DatePickerComponent = (props) => {
12937
12898
  return React.createElement(PickerComponent, { ...datePickerProps, value: value, onChange: onChange, type: type$5 });
12938
12899
  };
12939
12900
 
12901
+ const dateToString = (d) => {
12902
+ if (typeof d === 'function') {
12903
+ d = d();
12904
+ }
12905
+ if (typeof d === 'string') {
12906
+ d = new Date(d);
12907
+ }
12908
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`;
12909
+ };
12910
+ const toDateRange = (value, label) => {
12911
+ if (value) {
12912
+ const [from, to] = value.trim().split(/ to\s*/);
12913
+ return {
12914
+ from: from && from.trim() ? from.trim() : null,
12915
+ to: to && to.trim() ? to.trim() : null,
12916
+ label,
12917
+ };
12918
+ }
12919
+ else {
12920
+ return null;
12921
+ }
12922
+ };
12923
+ const qr = (quickRange) => {
12924
+ return {
12925
+ label: quickRange,
12926
+ from: () => {
12927
+ const d = new Date();
12928
+ switch (quickRange) {
12929
+ case 'Last hour':
12930
+ d.setHours(d.getHours() - 1);
12931
+ break;
12932
+ case 'Last day':
12933
+ d.setDate(d.getDate() - 1);
12934
+ break;
12935
+ case 'Last week':
12936
+ d.setDate(d.getDate() - 7);
12937
+ break;
12938
+ case 'Last month':
12939
+ d.setMonth(d.getMonth() - 1);
12940
+ break;
12941
+ case 'Last year':
12942
+ d.setFullYear(d.getFullYear() - 1);
12943
+ break;
12944
+ }
12945
+ return d;
12946
+ },
12947
+ to: () => new Date(),
12948
+ };
12949
+ };
12950
+ const defaultQuickRanges = () => {
12951
+ return ['Last hour', 'Last day', 'Last week', 'Last month', 'Last year'].reduce((accumulator, label) => {
12952
+ const quickRange = qr(label);
12953
+ if (quickRange) {
12954
+ accumulator[label] = quickRange;
12955
+ }
12956
+ return accumulator;
12957
+ }, {});
12958
+ };
12959
+ const findQuickRangeLabel = (quickRanges, dateRange) => {
12960
+ if (!quickRanges || !dateRange)
12961
+ return;
12962
+ const dr = typeof dateRange === 'string' ? toDateRange(dateRange) : dateRange;
12963
+ if (dr === null)
12964
+ return;
12965
+ if (!dr.from || !dr.to)
12966
+ return;
12967
+ return Object.keys(quickRanges).find((label) => {
12968
+ return dr.from === quickRanges[label].from && dr.to === quickRanges[label].to;
12969
+ });
12970
+ };
12971
+
12940
12972
  const type$4 = {
12941
12973
  date: true,
12942
12974
  time: false,
@@ -12944,8 +12976,8 @@ const type$4 = {
12944
12976
  };
12945
12977
  const DateRangePickerComponent = (props) => {
12946
12978
  const { onChange: forwardChange, value: externalValue, adapter, ...datePickerProps } = props;
12947
- const onChange = forwardChange ? (value) => {
12948
- const dateRange = toDateRange(value);
12979
+ const onChange = forwardChange ? (value, label) => {
12980
+ const dateRange = toDateRange(value, label);
12949
12981
  if (dateRange === null || !adapter) {
12950
12982
  forwardChange(dateRange);
12951
12983
  }
@@ -12954,16 +12986,19 @@ const DateRangePickerComponent = (props) => {
12954
12986
  }
12955
12987
  } : undefined;
12956
12988
  let value = null;
12989
+ let valueLabel;
12957
12990
  if (externalValue) {
12958
12991
  if (adapter) {
12959
- const { from, to } = adapter.toDateRange(externalValue);
12992
+ const { from, to, label } = adapter.toDateRange(externalValue);
12960
12993
  value = `${from || ''} to ${to || ''}`;
12994
+ valueLabel = label;
12961
12995
  }
12962
12996
  else {
12963
12997
  value = `${externalValue.from || ''} to ${externalValue.to || ''}`;
12998
+ valueLabel = externalValue.label;
12964
12999
  }
12965
13000
  }
12966
- return React.createElement(PickerComponent, { ...datePickerProps, value: value, onChange: onChange, type: type$4 });
13001
+ return React.createElement(PickerComponent, { ...datePickerProps, value: value, onChange: onChange, type: type$4, label: valueLabel });
12967
13002
  };
12968
13003
 
12969
13004
  const type$3 = {
@@ -12992,8 +13027,8 @@ const type$2 = {
12992
13027
  };
12993
13028
  const DateTimeRangePickerComponent = (props) => {
12994
13029
  const { onChange: forwardChange, value: externalValue, adapter, ...datePickerProps } = props;
12995
- const onChange = forwardChange ? (value) => {
12996
- const dateRange = toDateRange(value);
13030
+ const onChange = forwardChange ? (value, label) => {
13031
+ const dateRange = toDateRange(value, label);
12997
13032
  if (dateRange === null || !adapter) {
12998
13033
  forwardChange(dateRange);
12999
13034
  }
@@ -13002,16 +13037,19 @@ const DateTimeRangePickerComponent = (props) => {
13002
13037
  }
13003
13038
  } : undefined;
13004
13039
  let value = null;
13040
+ let valueLabel;
13005
13041
  if (externalValue) {
13006
13042
  if (adapter) {
13007
- const { from, to } = adapter.toDateRange(externalValue);
13043
+ const { from, to, label } = adapter.toDateRange(externalValue);
13008
13044
  value = `${from || ''} to ${to || ''}`;
13045
+ valueLabel = label;
13009
13046
  }
13010
13047
  else {
13011
13048
  value = `${externalValue.from || ''} to ${externalValue.to || ''}`;
13049
+ valueLabel = externalValue.label;
13012
13050
  }
13013
13051
  }
13014
- return React.createElement(PickerComponent, { ...datePickerProps, value: value, onChange: onChange, type: type$2 });
13052
+ return React.createElement(PickerComponent, { ...datePickerProps, value: value, onChange: onChange, type: type$2, label: valueLabel });
13015
13053
  };
13016
13054
 
13017
13055
  const type$1 = {
@@ -13052,11 +13090,11 @@ const TimeRangePicker = styled(TimeRangePickerComponent) `
13052
13090
  `;
13053
13091
 
13054
13092
  const useQuickRanges = (ranges) => {
13055
- const ref = onekijsFramework.useLazyRef(() => {
13093
+ const result = onekijsFramework.useLazyRef(() => {
13056
13094
  if (!Array.isArray(ranges)) {
13057
13095
  ranges = [ranges];
13058
13096
  }
13059
- return ranges.reduce((accumulator, range) => {
13097
+ const quickRanges = ranges.reduce((accumulator, range) => {
13060
13098
  if (typeof (range) === 'string') {
13061
13099
  if (range === 'all') {
13062
13100
  accumulator = Object.assign(accumulator, defaultQuickRanges());
@@ -13069,15 +13107,36 @@ const useQuickRanges = (ranges) => {
13069
13107
  }
13070
13108
  }
13071
13109
  else {
13072
- accumulator[range.label] = {
13073
- from: dateToString(range.from),
13074
- to: dateToString(range.to),
13075
- };
13110
+ accumulator[range.label] = range;
13076
13111
  }
13077
13112
  return accumulator;
13078
13113
  }, {});
13114
+ const target = Object.keys(quickRanges).reduce((accumulator, label) => {
13115
+ accumulator[label] = {
13116
+ from: null,
13117
+ to: null,
13118
+ label
13119
+ };
13120
+ return accumulator;
13121
+ }, {});
13122
+ const handler = {
13123
+ get: function (_, prop) {
13124
+ if (typeof prop === 'string') {
13125
+ const quickRange = quickRanges[prop];
13126
+ if (quickRange) {
13127
+ return {
13128
+ from: dateToString(quickRange.from),
13129
+ to: dateToString(quickRange.to),
13130
+ label: quickRange.label,
13131
+ };
13132
+ }
13133
+ }
13134
+ return undefined;
13135
+ }
13136
+ };
13137
+ return new Proxy(target, handler);
13079
13138
  });
13080
- return ref.current;
13139
+ return result.current;
13081
13140
  };
13082
13141
 
13083
13142
  const useDateRangeAdapter = () => {
@@ -13086,12 +13145,14 @@ const useDateRangeAdapter = () => {
13086
13145
  return {
13087
13146
  from: range.from === null ? null : new Date(range.from),
13088
13147
  to: range.to === null ? null : new Date(range.to),
13148
+ label: range.label,
13089
13149
  };
13090
13150
  },
13091
13151
  toDateRange: (value) => {
13092
13152
  return {
13093
13153
  from: !value.from ? null : dateToString(value.from),
13094
13154
  to: !value.to ? null : dateToString(value.to),
13155
+ label: value.label,
13095
13156
  };
13096
13157
  }
13097
13158
  });
@@ -13124,12 +13185,14 @@ const useTimestampRangeAdapter = (format = 'milliseconds') => {
13124
13185
  return {
13125
13186
  from: toTimestamp(range.from),
13126
13187
  to: toTimestamp(range.to),
13188
+ label: range.label,
13127
13189
  };
13128
13190
  },
13129
13191
  toDateRange: (value) => {
13130
13192
  return {
13131
13193
  from: fromTimestamp(value.from),
13132
13194
  to: fromTimestamp(value.to),
13195
+ label: value.label,
13133
13196
  };
13134
13197
  }
13135
13198
  });