onekijs-ui 1.0.4 → 1.0.6

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.
Files changed (39) hide show
  1. package/dist/components/datetime/FormDatePicker.d.ts +28 -0
  2. package/dist/components/datetime/FormDateRangePicker.d.ts +28 -0
  3. package/dist/components/datetime/FormDateTimePicker.d.ts +21 -0
  4. package/dist/components/datetime/FormDateTimeRangePicker.d.ts +21 -0
  5. package/dist/components/datetime/hooks/useDateAdapter.d.ts +4 -0
  6. package/dist/components/datetime/hooks/useDateRangeAdapter.d.ts +5 -0
  7. package/dist/components/datetime/hooks/useTimestampAdapter.d.ts +8 -0
  8. package/dist/components/datetime/hooks/useTimestampRangeAdapter.d.ts +17 -2
  9. package/dist/components/datetime/index.d.ts +8 -8
  10. package/dist/components/datetime/typings.d.ts +55 -9
  11. package/dist/components/select/SelectService.d.ts +3 -3
  12. package/dist/components/wizard/WizardModal.d.ts +2 -2
  13. package/dist/components/wizard/index.d.ts +2 -2
  14. package/dist/index.d.ts +73 -70
  15. package/dist/index.js +2290 -2102
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.module.js +2284 -2104
  18. package/dist/index.module.js.map +1 -1
  19. package/package.json +3 -3
  20. package/src/components/button/components/DropdownButtonComponent.tsx +6 -3
  21. package/src/components/datetime/FormDatePicker.tsx +79 -0
  22. package/src/components/datetime/FormDateRangePicker.tsx +79 -0
  23. package/src/components/datetime/FormDateTimePicker.tsx +43 -0
  24. package/src/components/datetime/FormDateTimeRangePicker.tsx +38 -0
  25. package/src/components/datetime/components/DatePickerComponent.tsx +8 -4
  26. package/src/components/datetime/components/DateRangePickerComponent.tsx +8 -4
  27. package/src/components/datetime/components/DateTimePickerComponent.tsx +8 -4
  28. package/src/components/datetime/components/DateTimeRangePickerComponent.tsx +8 -4
  29. package/src/components/datetime/components/TimeComponent.tsx +3 -0
  30. package/src/components/datetime/components/TimeRangeComponent.tsx +4 -2
  31. package/src/components/datetime/components/TimeSelectorComponent.tsx +5 -4
  32. package/src/components/datetime/components/TimeSelectorPartComponent.tsx +16 -1
  33. package/src/components/datetime/hooks/useDateAdapter.ts +14 -0
  34. package/src/components/datetime/hooks/useDateRangeAdapter.ts +11 -11
  35. package/src/components/datetime/hooks/useTimestampAdapter.ts +37 -0
  36. package/src/components/datetime/hooks/useTimestampRangeAdapter.ts +15 -26
  37. package/src/components/datetime/style.ts +14 -3
  38. package/src/components/datetime/typings.ts +66 -10
  39. package/src/index.ts +96 -130
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "onekijs-ui",
3
3
  "private": false,
4
- "version": "1.0.4",
4
+ "version": "1.0.6",
5
5
  "description": "Advanced React Web Components",
6
6
  "source": "src/index.ts",
7
7
  "main": "dist/index.js",
@@ -35,7 +35,7 @@
35
35
  "@floating-ui/react": "^0.27.20",
36
36
  "@popperjs/core": "^2.11.8",
37
37
  "@reach/observe-rect": "^1.2.0",
38
- "onekijs-framework": "^1.0.3",
38
+ "onekijs-framework": "^1.0.6",
39
39
  "react-virtualized-auto-sizer": "^2.0.3",
40
40
  "react-window": "^2.2.7",
41
41
  "react-window-infinite-loader": "^2.0.1",
@@ -50,5 +50,5 @@
50
50
  "react-dom": "^19.2.7"
51
51
  },
52
52
  "sideEffects": false,
53
- "gitHead": "5445ab48458ab994b8e76660fa897af57e34f51a"
53
+ "gitHead": "f808b045ca1aa271ae0b80f0257b4bca4321ab98"
54
54
  }
@@ -1,4 +1,4 @@
1
- import React, { FC, useRef } from 'react';
1
+ import { FC, useRef } from 'react';
2
2
  import Button from '..';
3
3
  import { useClickOutside } from '../../../utils/event';
4
4
  import { addClassname } from '../../../utils/style';
@@ -34,8 +34,9 @@ const DropdownButtonComponent: FC<DropDownButtonProps> = ({
34
34
  const ref = useRef<HTMLSpanElement | null>(null);
35
35
 
36
36
  const [Dropdown, triggerRef] = useDropdown();
37
+ const dropdownRef = useRef<HTMLDivElement>(null);
37
38
 
38
- useClickOutside(ref, () => onCollapse && onCollapse());
39
+ useClickOutside([ref, dropdownRef], () => onCollapse && onCollapse());
39
40
 
40
41
  return (
41
42
  <span ref={ref}>
@@ -76,7 +77,9 @@ const DropdownButtonComponent: FC<DropDownButtonProps> = ({
76
77
  placement={placement}
77
78
  animationTimeout={animationTimeout}
78
79
  >
79
- {listElement}
80
+ <div ref={dropdownRef}>
81
+ {listElement}
82
+ </div>
80
83
  </Dropdown>
81
84
  </span>
82
85
  );
@@ -0,0 +1,79 @@
1
+ import { FormDisplayerProps, FormFieldValueDisplayerProps, isNull, useForm } from 'onekijs-framework';
2
+ import React, { FC } from 'react';
3
+ import { DatePicker } from '.';
4
+ import { titlelize } from '../../utils/misc';
5
+ import FieldDisplayer from '../field/FieldDisplayer';
6
+ import FieldLayout from '../field/FieldLayout';
7
+ import useFieldLayout from '../field/hooks/useFieldLayout';
8
+ import { dateAdapter } from './hooks/useDateAdapter';
9
+ import { timestampMilliSecondAdapter } from './hooks/useTimestampAdapter';
10
+ import { FormDatePickerProps } from './typings';
11
+
12
+ export const FormDateValueDisplayer: React.FC<FormFieldValueDisplayerProps> = ({ value }) => {
13
+ return <span className="o-date-picker-displayer-value">{value ?? ''}</span>;
14
+ };
15
+
16
+ export const formDateDisplayerProps = (props: FormDatePickerProps<any>) => ({
17
+ defaultValue: props.defaultValue === undefined ? null : props.defaultValue,
18
+ isUndefined:
19
+ props.isUndefined === undefined ? (value: any) => value === undefined || value === null : props.isUndefined,
20
+ Displayer:
21
+ props.Displayer === undefined
22
+ ? (displayerProps: FormDisplayerProps) => {
23
+ const form = useForm();
24
+ let value = form.getValue(displayerProps.name) ?? null;
25
+ const ValueDisplayer = props.ValueDisplayer ?? FormDateValueDisplayer;
26
+ const adapter =
27
+ props.adapter === 'timestamp'
28
+ ? timestampMilliSecondAdapter
29
+ : props.adapter === 'date'
30
+ ? dateAdapter
31
+ : props.adapter;
32
+ if (adapter) {
33
+ value = adapter.toDate(value);
34
+ }
35
+ return (
36
+ <FieldDisplayer
37
+ label={displayerProps.label ?? titlelize(displayerProps.name)}
38
+ help={props.help}
39
+ first={displayerProps.first}
40
+ last={displayerProps.last}
41
+ value={<ValueDisplayer value={value} />}
42
+ format={displayerProps.format}
43
+ />
44
+ );
45
+ }
46
+ : props.Displayer,
47
+ });
48
+
49
+ /**
50
+ * `<FormDatePicker/>` is a DataPicker component designed to be managed by a Form.
51
+ * It must therefore be a nested component of a Form
52
+ *
53
+ * Some properties are handled entirely by a form controller.
54
+ * * value
55
+ * * onChange
56
+ * * onFocus
57
+ * * onBlur
58
+ * * validations
59
+ * * visibility
60
+ * * disabled
61
+ * The value is synchronized in both directions (it can be modified manually by the user or by the controller).
62
+ *
63
+ * @group Form
64
+ * @category Components
65
+ */
66
+ const FormDatePicker: FC<FormDatePickerProps<any>> = React.memo((props) => {
67
+ const [fieldLayoutProps, fieldComponentProps] = useFieldLayout<FormDatePickerProps<any>>(
68
+ Object.assign({}, props, formDateDisplayerProps(props)),
69
+ );
70
+
71
+ return (
72
+ <FieldLayout {...fieldLayoutProps} required={props.required}>
73
+ <DatePicker {...fieldComponentProps} />
74
+ </FieldLayout>
75
+ );
76
+ });
77
+
78
+ FormDatePicker.displayName = 'FormDatePicker';
79
+ export default FormDatePicker;
@@ -0,0 +1,79 @@
1
+ import { FormDisplayerProps, FormFieldValueDisplayerProps, useForm } from 'onekijs-framework';
2
+ import React, { FC } from 'react';
3
+ import { DateRangePicker } from '.';
4
+ import { titlelize } from '../../utils/misc';
5
+ import FieldDisplayer from '../field/FieldDisplayer';
6
+ import FieldLayout from '../field/FieldLayout';
7
+ import useFieldLayout from '../field/hooks/useFieldLayout';
8
+ import { dateRangeAdapter } from './hooks/useDateRangeAdapter';
9
+ import { timestampMilliSecondRangeAdapter } from './hooks/useTimestampRangeAdapter';
10
+ import { FormDateRangePickerProps } from './typings';
11
+
12
+ export const FormDateRangeValueDisplayer: React.FC<FormFieldValueDisplayerProps> = ({ value }) => {
13
+ return <span className="o-date-picker-range-displayer-value">{value ? `${value.from} - ${value.to}` : ''}</span>;
14
+ };
15
+
16
+ export const formDateRangeDisplayerProps = (props: FormDateRangePickerProps<any>) => ({
17
+ defaultValue: props.defaultValue === undefined ? null : props.defaultValue,
18
+ isUndefined:
19
+ props.isUndefined === undefined ? (value: any) => value === undefined || value === null : props.isUndefined,
20
+ Displayer:
21
+ props.Displayer === undefined
22
+ ? (displayerProps: FormDisplayerProps) => {
23
+ const form = useForm();
24
+ let value = form.getValue(displayerProps.name) ?? null;
25
+ const ValueDisplayer = props.ValueDisplayer ?? FormDateRangeValueDisplayer;
26
+ const adapter =
27
+ props.adapter === 'timestamp'
28
+ ? timestampMilliSecondRangeAdapter
29
+ : props.adapter === 'date'
30
+ ? dateRangeAdapter
31
+ : props.adapter;
32
+ if (adapter) {
33
+ value = adapter.toDateRange(value);
34
+ }
35
+ return (
36
+ <FieldDisplayer
37
+ label={displayerProps.label ?? titlelize(displayerProps.name)}
38
+ help={props.help}
39
+ first={displayerProps.first}
40
+ last={displayerProps.last}
41
+ value={<ValueDisplayer value={value} />}
42
+ format={displayerProps.format}
43
+ />
44
+ );
45
+ }
46
+ : props.Displayer,
47
+ });
48
+
49
+ /**
50
+ * `<FormDateRangePicker/>` is a DataPicker component designed to be managed by a Form.
51
+ * It must therefore be a nested component of a Form
52
+ *
53
+ * Some properties are handled entirely by a form controller.
54
+ * * value
55
+ * * onChange
56
+ * * onFocus
57
+ * * onBlur
58
+ * * validations
59
+ * * visibility
60
+ * * disabled
61
+ * The value is synchronized in both directions (it can be modified manually by the user or by the controller).
62
+ *
63
+ * @group Form
64
+ * @category Components
65
+ */
66
+ const FormDateRangePicker: FC<FormDateRangePickerProps<any>> = React.memo((props) => {
67
+ const [fieldLayoutProps, fieldComponentProps] = useFieldLayout<FormDateRangePickerProps<any>>(
68
+ Object.assign({}, props, formDateRangeDisplayerProps(props)),
69
+ );
70
+
71
+ return (
72
+ <FieldLayout {...fieldLayoutProps} required={props.required}>
73
+ <DateRangePicker {...fieldComponentProps} />
74
+ </FieldLayout>
75
+ );
76
+ });
77
+
78
+ FormDateRangePicker.displayName = 'FormDateRangePicker';
79
+ export default FormDateRangePicker;
@@ -0,0 +1,43 @@
1
+ import { FormDisplayerProps, FormFieldValueDisplayerProps, isNull, useForm } from 'onekijs-framework';
2
+ import React, { FC } from 'react';
3
+ import { titlelize } from '../../utils/misc';
4
+ import FieldDisplayer from '../field/FieldDisplayer';
5
+ import FieldLayout from '../field/FieldLayout';
6
+ import useFieldLayout from '../field/hooks/useFieldLayout';
7
+ import { FormDateTimePickerProps } from './typings';
8
+ import { DateTimePicker } from '.';
9
+ import { timestampMilliSecondAdapter } from './hooks/useTimestampAdapter';
10
+ import { dateAdapter } from './hooks/useDateAdapter';
11
+ import { formDateDisplayerProps } from './FormDatePicker';
12
+
13
+ /**
14
+ * `<FormDateTimePicker/>` is a DataTimePicker component designed to be managed by a Form.
15
+ * It must therefore be a nested component of a Form
16
+ *
17
+ * Some properties are handled entirely by a form controller.
18
+ * * value
19
+ * * onChange
20
+ * * onFocus
21
+ * * onBlur
22
+ * * validations
23
+ * * visibility
24
+ * * disabled
25
+ * The value is synchronized in both directions (it can be modified manually by the user or by the controller).
26
+ *
27
+ * @group Form
28
+ * @category Components
29
+ */
30
+ const FormDateTimePicker: FC<FormDateTimePickerProps<any>> = React.memo((props) => {
31
+ const [fieldLayoutProps, fieldComponentProps] = useFieldLayout<FormDateTimePickerProps<any>>(
32
+ Object.assign({}, props, formDateDisplayerProps(props)),
33
+ );
34
+
35
+ return (
36
+ <FieldLayout {...fieldLayoutProps} required={props.required}>
37
+ <DateTimePicker {...fieldComponentProps} />
38
+ </FieldLayout>
39
+ );
40
+ });
41
+
42
+ FormDateTimePicker.displayName = 'FormDateTimePicker';
43
+ export default FormDateTimePicker;
@@ -0,0 +1,38 @@
1
+ import React, { FC } from 'react';
2
+ import { DateTimeRangePicker } from '.';
3
+ import FieldLayout from '../field/FieldLayout';
4
+ import useFieldLayout from '../field/hooks/useFieldLayout';
5
+ import { formDateRangeDisplayerProps } from './FormDateRangePicker';
6
+ import { FormDateTimeRangePickerProps } from './typings';
7
+
8
+ /**
9
+ * `<FormDateTimeRangePicker/>` is a DataTimeRangePicker component designed to be managed by a Form.
10
+ * It must therefore be a nested component of a Form
11
+ *
12
+ * Some properties are handled entirely by a form controller.
13
+ * * value
14
+ * * onChange
15
+ * * onFocus
16
+ * * onBlur
17
+ * * validations
18
+ * * visibility
19
+ * * disabled
20
+ * The value is synchronized in both directions (it can be modified manually by the user or by the controller).
21
+ *
22
+ * @group Form
23
+ * @category Components
24
+ */
25
+ const FormDateTimeRangePicker: FC<FormDateTimeRangePickerProps<any>> = React.memo((props) => {
26
+ const [fieldLayoutProps, fieldComponentProps] = useFieldLayout<FormDateTimeRangePickerProps<any>>(
27
+ Object.assign({}, props, formDateRangeDisplayerProps(props)),
28
+ );
29
+
30
+ return (
31
+ <FieldLayout {...fieldLayoutProps} required={props.required}>
32
+ <DateTimeRangePicker {...fieldComponentProps} />
33
+ </FieldLayout>
34
+ );
35
+ });
36
+
37
+ FormDateTimeRangePicker.displayName = 'FormDateTimeRangePicker';
38
+ export default FormDateTimeRangePicker;
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
2
  import { DatePickerProps, DatePickerType, PickerComponentProps } from '../typings';
3
3
  import PickerComponent from './PickerComponent';
4
+ import { timestampMilliSecondAdapter } from '../hooks/useTimestampAdapter';
5
+ import { dateAdapter } from '../hooks/useDateAdapter';
4
6
 
5
7
  const type: DatePickerType = {
6
8
  date: true,
@@ -11,19 +13,21 @@ const type: DatePickerType = {
11
13
  const DatePickerComponent: React.FC<DatePickerProps> = (props) => {
12
14
  const { onChange: forwardChange, value: externalValue, adapter, ...datePickerProps } = props;
13
15
 
16
+ const _adapter = adapter === 'timestamp' ? timestampMilliSecondAdapter : adapter === 'date' ? dateAdapter : adapter;
17
+
14
18
  const onChange: PickerComponentProps['onChange'] = forwardChange
15
19
  ? (value) => {
16
- if (value === null || !adapter) {
20
+ if (value === null || !_adapter) {
17
21
  forwardChange(value);
18
22
  } else {
19
- forwardChange(adapter.fromDate(value));
23
+ forwardChange(_adapter.fromDate(value));
20
24
  }
21
25
  }
22
26
  : undefined;
23
27
 
24
28
  let value: PickerComponentProps['value'] = externalValue
25
- ? adapter
26
- ? adapter.toDate(externalValue)
29
+ ? _adapter
30
+ ? _adapter.toDate(externalValue)
27
31
  : externalValue
28
32
  : null;
29
33
 
@@ -2,6 +2,8 @@ import React from 'react';
2
2
  import { DatePickerType, DateRangePickerProps, PickerComponentProps } from '../typings';
3
3
  import { toDateRange } from '../util';
4
4
  import PickerComponent from './PickerComponent';
5
+ import { timestampMilliSecondRangeAdapter } from '../hooks/useTimestampRangeAdapter';
6
+ import { dateRangeAdapter } from '../hooks/useDateRangeAdapter';
5
7
 
6
8
  const type: DatePickerType = {
7
9
  date: true,
@@ -12,13 +14,15 @@ const type: DatePickerType = {
12
14
  const DateRangePickerComponent: React.FC<DateRangePickerProps> = (props) => {
13
15
  const { onChange: forwardChange, value: externalValue, adapter, ...datePickerProps } = props;
14
16
 
17
+ const _adapter = adapter === 'timestamp' ? timestampMilliSecondRangeAdapter : adapter === 'date' ? dateRangeAdapter : adapter;
18
+
15
19
  const onChange: PickerComponentProps['onChange'] = forwardChange
16
20
  ? (value, label) => {
17
21
  const dateRange = toDateRange(value, label);
18
- if (dateRange === null || !adapter) {
22
+ if (dateRange === null || !_adapter) {
19
23
  forwardChange(dateRange);
20
24
  } else {
21
- forwardChange(adapter.fromDateRange(dateRange));
25
+ forwardChange(_adapter.fromDateRange(dateRange));
22
26
  }
23
27
  }
24
28
  : undefined;
@@ -26,8 +30,8 @@ const DateRangePickerComponent: React.FC<DateRangePickerProps> = (props) => {
26
30
  let value: PickerComponentProps['value'] = null;
27
31
  let valueLabel: string | null | undefined;
28
32
  if (externalValue) {
29
- if (adapter) {
30
- const { from, to, label } = adapter.toDateRange(externalValue);
33
+ if (_adapter) {
34
+ const { from, to, label } = _adapter.toDateRange(externalValue);
31
35
  value = `${from || ''} to ${to || ''}`;
32
36
  valueLabel = label;
33
37
  } else {
@@ -1,4 +1,6 @@
1
1
  import React from 'react';
2
+ import { dateAdapter } from '../hooks/useDateAdapter';
3
+ import { timestampMilliSecondAdapter } from '../hooks/useTimestampAdapter';
2
4
  import { DatePickerType, DateTimePickerProps, PickerComponentProps } from '../typings';
3
5
  import PickerComponent from './PickerComponent';
4
6
 
@@ -11,19 +13,21 @@ const type: DatePickerType = {
11
13
  const DateTimePickerComponent: React.FC<DateTimePickerProps> = (props) => {
12
14
  const { onChange: forwardChange, value: externalValue, adapter, ...datePickerProps } = props;
13
15
 
16
+ const _adapter = adapter === 'timestamp' ? timestampMilliSecondAdapter : adapter === 'date' ? dateAdapter : adapter;
17
+
14
18
  const onChange: PickerComponentProps['onChange'] = forwardChange
15
19
  ? (value) => {
16
- if (value === null || !adapter) {
20
+ if (value === null || !_adapter) {
17
21
  forwardChange(value);
18
22
  } else {
19
- forwardChange(adapter.fromDate(value));
23
+ forwardChange(_adapter.fromDate(value));
20
24
  }
21
25
  }
22
26
  : undefined;
23
27
 
24
28
  let value: PickerComponentProps['value'] = externalValue
25
- ? adapter
26
- ? adapter.toDate(externalValue)
29
+ ? _adapter
30
+ ? _adapter.toDate(externalValue)
27
31
  : externalValue
28
32
  : null;
29
33
 
@@ -2,6 +2,8 @@ import React from 'react';
2
2
  import { DatePickerType, DateTimeRangePickerProps, PickerComponentProps } from '../typings';
3
3
  import { toDateRange } from '../util';
4
4
  import PickerComponent from './PickerComponent';
5
+ import { timestampMilliSecondRangeAdapter } from '../hooks/useTimestampRangeAdapter';
6
+ import { dateRangeAdapter } from '../hooks/useDateRangeAdapter';
5
7
 
6
8
  const type: DatePickerType = {
7
9
  date: true,
@@ -12,13 +14,15 @@ const type: DatePickerType = {
12
14
  const DateTimeRangePickerComponent: React.FC<DateTimeRangePickerProps> = (props) => {
13
15
  const { onChange: forwardChange, value: externalValue, adapter, ...datePickerProps } = props;
14
16
 
17
+ const _adapter = adapter === 'timestamp' ? timestampMilliSecondRangeAdapter : adapter === 'date' ? dateRangeAdapter : adapter;
18
+
15
19
  const onChange: PickerComponentProps['onChange'] = forwardChange
16
20
  ? (value, label) => {
17
21
  const dateRange = toDateRange(value, label);
18
- if (dateRange === null || !adapter) {
22
+ if (dateRange === null || !_adapter) {
19
23
  forwardChange(dateRange);
20
24
  } else {
21
- forwardChange(adapter.fromDateRange(dateRange));
25
+ forwardChange(_adapter.fromDateRange(dateRange));
22
26
  }
23
27
  }
24
28
  : undefined;
@@ -26,8 +30,8 @@ const DateTimeRangePickerComponent: React.FC<DateTimeRangePickerProps> = (props)
26
30
  let value: PickerComponentProps['value'] = null;
27
31
  let valueLabel: string | null | undefined;
28
32
  if (externalValue) {
29
- if (adapter) {
30
- const { from, to, label } = adapter.toDateRange(externalValue);
33
+ if (_adapter) {
34
+ const { from, to, label } = _adapter.toDateRange(externalValue);
31
35
  value = `${from || ''} to ${to || ''}`;
32
36
  valueLabel = label;
33
37
  } else {
@@ -25,6 +25,7 @@ const TimeComponent: React.FC<TimeComponentProps> = ({
25
25
  displayHours={displayHours}
26
26
  displayMinutes={displayMinutes}
27
27
  displaySeconds={displaySeconds}
28
+ displayHeaders={false}
28
29
  />
29
30
  <TimeRangeComponent
30
31
  type={type}
@@ -34,6 +35,7 @@ const TimeComponent: React.FC<TimeComponentProps> = ({
34
35
  displayHours={displayHours}
35
36
  displayMinutes={displayMinutes}
36
37
  displaySeconds={displaySeconds}
38
+ displayHeaders={false}
37
39
  />
38
40
  </div>
39
41
  );
@@ -50,6 +52,7 @@ const TimeComponent: React.FC<TimeComponentProps> = ({
50
52
  displayHours={displayHours}
51
53
  displayMinutes={displayMinutes}
52
54
  displaySeconds={displaySeconds}
55
+ displayHeaders={true}
53
56
  />
54
57
  </div>
55
58
  );
@@ -1,8 +1,8 @@
1
+ import { ucfirst } from 'onekijs-framework';
1
2
  import React from 'react';
2
- import { TimeRangeComponentProps } from '../typings';
3
3
  import { isValidDate } from '../../../utils/date';
4
+ import { TimeRangeComponentProps } from '../typings';
4
5
  import TimeSelectorComponent from './TimeSelectorComponent';
5
- import { ucfirst } from 'onekijs-framework';
6
6
 
7
7
  const TimeRangeComponent: React.FC<TimeRangeComponentProps> = ({
8
8
  edge,
@@ -11,6 +11,7 @@ const TimeRangeComponent: React.FC<TimeRangeComponentProps> = ({
11
11
  displayHours,
12
12
  displayMinutes,
13
13
  displaySeconds,
14
+ displayHeaders,
14
15
  }) => {
15
16
  const valid = isValidDate(`${value.day}-${value.month}-${value.year}`);
16
17
  let d: Date | undefined;
@@ -43,6 +44,7 @@ const TimeRangeComponent: React.FC<TimeRangeComponentProps> = ({
43
44
  displayHours={displayHours}
44
45
  displayMinutes={displayMinutes}
45
46
  displaySeconds={displaySeconds}
47
+ displayHeaders={displayHeaders}
46
48
  />
47
49
  </div>
48
50
  )}
@@ -12,7 +12,7 @@ const getValue = (candidate: string | number | undefined, max: number, defaultVa
12
12
  return candidate;
13
13
  };
14
14
 
15
- const TimeSelectorComponent: React.FC<TimeSelectorComponentProps> = ({
15
+ const TimeSelectorComponent: React.FC<TimeSelectorComponentProps> = ({
16
16
  value,
17
17
  onChange,
18
18
  size,
@@ -20,6 +20,7 @@ const TimeSelectorComponent: React.FC<TimeSelectorComponentProps> = ({
20
20
  displayHours,
21
21
  displayMinutes,
22
22
  displaySeconds,
23
+ displayHeaders,
23
24
  }) => {
24
25
  const d = new Date();
25
26
  const hourInt = getValue(value.hour, 23, displayHours ? d.getHours() : 0);
@@ -84,7 +85,7 @@ const TimeSelectorComponent: React.FC<TimeSelectorComponentProps> = ({
84
85
  return (
85
86
  <div className="o-time-selector">
86
87
  {displayHours && (
87
- <TimeSelectorPartComponent key="hour" type="hour" value={hour} onChange={onChangeHour} size={size} />
88
+ <TimeSelectorPartComponent key="hour" type="hour" value={hour} onChange={onChangeHour} size={size} displayHeaders={displayHeaders} />
88
89
  )}
89
90
  {displayHours && (displayMinutes || displaySeconds) && (
90
91
  <span key="sep1" className="o-time-separator">
@@ -92,7 +93,7 @@ const TimeSelectorComponent: React.FC<TimeSelectorComponentProps> = ({
92
93
  </span>
93
94
  )}
94
95
  {displayMinutes && (
95
- <TimeSelectorPartComponent key="minute" type="minute" value={minute} onChange={onChangeMinute} size={size} />
96
+ <TimeSelectorPartComponent key="minute" type="minute" value={minute} onChange={onChangeMinute} size={size} displayHeaders={displayHeaders} />
96
97
  )}
97
98
  {displaySeconds && (displayHours || displayMinutes) && (
98
99
  <span key="sep2" className="o-time-separator">
@@ -100,7 +101,7 @@ const TimeSelectorComponent: React.FC<TimeSelectorComponentProps> = ({
100
101
  </span>
101
102
  )}
102
103
  {displaySeconds && (
103
- <TimeSelectorPartComponent key="second" type="second" value={second} onChange={onChangeSecond} size={size} />
104
+ <TimeSelectorPartComponent key="second" type="second" value={second} onChange={onChangeSecond} size={size} displayHeaders={displayHeaders} />
104
105
  )}
105
106
  </div>
106
107
  );
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import { isValidHour, isValidMinuteOrSecond } from '../../../utils/date';
3
3
  import TogglerIcon from '../../icon/TogglerIcon';
4
- import { TimeSelectorPartComponentProps } from '../typings';
5
4
  import Input from '../../input';
5
+ import { TimeSelectorPartComponentProps } from '../typings';
6
6
 
7
7
  const getNextValue = (value: string | number, max: number, type: 'next' | 'previous') => {
8
8
  const valueInt = parseInt(`${value}`);
@@ -34,11 +34,25 @@ const isMax = (value: string | number, type: TimeSelectorPartComponentProps['typ
34
34
  return type === 'hour' ? parseInt(`${value}`) === 23 : parseInt(`${value}`) === 59;
35
35
  };
36
36
 
37
+ const headerValue = (type: TimeSelectorPartComponentProps['type']): string => {
38
+ switch (type) {
39
+ case 'hour':
40
+ return 'HH';
41
+ case 'minute':
42
+ return 'MM';
43
+ case 'second':
44
+ return 'SS';
45
+ default:
46
+ return '';
47
+ }
48
+ };
49
+
37
50
  const TimeSelectorPartComponent: React.FC<TimeSelectorPartComponentProps> = ({
38
51
  onChange,
39
52
  type,
40
53
  value,
41
54
  size = 'large',
55
+ displayHeaders = false,
42
56
  }) => {
43
57
  const onValueChange = (e: React.ChangeEvent<HTMLInputElement>) => {
44
58
  let value = e.target.value;
@@ -53,6 +67,7 @@ const TimeSelectorPartComponent: React.FC<TimeSelectorPartComponentProps> = ({
53
67
 
54
68
  return (
55
69
  <div className={`o-time-selector-part o-time-selector-part-${size} o-time-${type}`}>
70
+ {displayHeaders && <div className="o-time-selector-part-header">{headerValue(type)}</div>}
56
71
  <TogglerIcon
57
72
  className={isMin(value, type) ? 'o-time-selector-part-icon-disabled' : undefined}
58
73
  key="previous"
@@ -0,0 +1,14 @@
1
+ import { useRef } from 'react';
2
+ import { DateAdapter } from '../typings';
3
+ import { dateToString } from '../util';
4
+
5
+ export const dateAdapter = {
6
+ fromDate: (date) => date === null ? null : new Date(date),
7
+ toDate: (value) => !value ? null : dateToString(value),
8
+ } as DateAdapter<Date | null>;
9
+
10
+ const useDateAdapter = () => {
11
+ return dateAdapter;
12
+ };
13
+
14
+ export default useDateAdapter;
@@ -1,25 +1,25 @@
1
- import { useRef } from 'react';
2
1
  import { DateRangeAdapter } from '../typings';
3
2
  import { dateToString } from '../util';
4
3
 
5
- const useDateRangeAdapter = () => {
6
- const ref = useRef({
4
+ export const dateRangeAdapter = {
7
5
  fromDateRange: (range) => {
8
6
  return {
9
- from: range.from === null ? null : new Date(range.from),
10
- to: range.to === null ? null : new Date(range.to),
11
- label: range.label,
7
+ from: range?.from === null ? null : new Date(range.from),
8
+ to: range?.to === null ? null : new Date(range.to),
9
+ label: range?.label,
12
10
  };
13
11
  },
14
12
  toDateRange: (value) => {
15
13
  return {
16
- from: !value.from ? null : dateToString(value.from),
17
- to: !value.to ? null : dateToString(value.to),
18
- label: value.label,
14
+ from: !value?.from ? null : dateToString(value.from),
15
+ to: !value?.to ? null : dateToString(value.to),
16
+ label: value?.label,
19
17
  };
20
18
  },
21
- } as DateRangeAdapter<{ from: Date | null; to: Date | null; label?: string | null }>);
22
- return ref.current;
19
+ } as DateRangeAdapter<{ from: Date | null; to: Date | null; label?: string | null }>
20
+
21
+ const useDateRangeAdapter = () => {
22
+ return dateRangeAdapter;
23
23
  };
24
24
 
25
25
  export default useDateRangeAdapter;
@@ -0,0 +1,37 @@
1
+ import { useRef } from 'react';
2
+ import { DateAdapter, TimestampFormat } from '../typings';
3
+ import { dateToString } from '../util';
4
+
5
+ export const toTimestamp = (date: string | undefined | null, format: TimestampFormat): number | null => {
6
+ if (!date) return null;
7
+ const d = new Date(date);
8
+ if (isNaN(d as any)) return null;
9
+ const timestamp = d.getTime();
10
+ return format === 'milliseconds' ? timestamp : Math.floor(timestamp / 1000);
11
+ };
12
+
13
+ export const fromTimestamp = (timestamp: number | undefined | null, format: TimestampFormat) => {
14
+ if (timestamp === null || timestamp === undefined) return null;
15
+ if (format === 'seconds') {
16
+ timestamp = timestamp * 1000;
17
+ }
18
+ const d = new Date(timestamp);
19
+ if (isNaN(d as any)) return null;
20
+ return dateToString(d);
21
+ };
22
+
23
+ export const timestampAdapter = (format: TimestampFormat = 'milliseconds') => ({
24
+ fromDate: (date) => toTimestamp(date, format),
25
+ toDate: (value) => fromTimestamp(value, format),
26
+ } as DateAdapter<number | null>
27
+ )
28
+
29
+ export const timestampSecondAdapter = timestampAdapter('seconds');
30
+ export const timestampMilliSecondAdapter = timestampAdapter('milliseconds');
31
+
32
+ const useTimestampAdapter = (format: TimestampFormat = 'milliseconds') => {
33
+ const ref = useRef(timestampAdapter(format));
34
+ return ref.current;
35
+ };
36
+
37
+ export default useTimestampAdapter;