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.
- package/dist/components/datetime/FormDatePicker.d.ts +28 -0
- package/dist/components/datetime/FormDateRangePicker.d.ts +28 -0
- package/dist/components/datetime/FormDateTimePicker.d.ts +21 -0
- package/dist/components/datetime/FormDateTimeRangePicker.d.ts +21 -0
- package/dist/components/datetime/hooks/useDateAdapter.d.ts +4 -0
- package/dist/components/datetime/hooks/useDateRangeAdapter.d.ts +5 -0
- package/dist/components/datetime/hooks/useTimestampAdapter.d.ts +8 -0
- package/dist/components/datetime/hooks/useTimestampRangeAdapter.d.ts +17 -2
- package/dist/components/datetime/index.d.ts +8 -8
- package/dist/components/datetime/typings.d.ts +55 -9
- package/dist/components/select/SelectService.d.ts +3 -3
- package/dist/components/wizard/WizardModal.d.ts +2 -2
- package/dist/components/wizard/index.d.ts +2 -2
- package/dist/index.d.ts +73 -70
- package/dist/index.js +2290 -2102
- package/dist/index.js.map +1 -1
- package/dist/index.module.js +2284 -2104
- package/dist/index.module.js.map +1 -1
- package/package.json +3 -3
- package/src/components/button/components/DropdownButtonComponent.tsx +6 -3
- package/src/components/datetime/FormDatePicker.tsx +79 -0
- package/src/components/datetime/FormDateRangePicker.tsx +79 -0
- package/src/components/datetime/FormDateTimePicker.tsx +43 -0
- package/src/components/datetime/FormDateTimeRangePicker.tsx +38 -0
- package/src/components/datetime/components/DatePickerComponent.tsx +8 -4
- package/src/components/datetime/components/DateRangePickerComponent.tsx +8 -4
- package/src/components/datetime/components/DateTimePickerComponent.tsx +8 -4
- package/src/components/datetime/components/DateTimeRangePickerComponent.tsx +8 -4
- package/src/components/datetime/components/TimeComponent.tsx +3 -0
- package/src/components/datetime/components/TimeRangeComponent.tsx +4 -2
- package/src/components/datetime/components/TimeSelectorComponent.tsx +5 -4
- package/src/components/datetime/components/TimeSelectorPartComponent.tsx +16 -1
- package/src/components/datetime/hooks/useDateAdapter.ts +14 -0
- package/src/components/datetime/hooks/useDateRangeAdapter.ts +11 -11
- package/src/components/datetime/hooks/useTimestampAdapter.ts +37 -0
- package/src/components/datetime/hooks/useTimestampRangeAdapter.ts +15 -26
- package/src/components/datetime/style.ts +14 -3
- package/src/components/datetime/typings.ts +66 -10
- 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
|
+
"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.
|
|
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": "
|
|
53
|
+
"gitHead": "f808b045ca1aa271ae0b80f0257b4bca4321ab98"
|
|
54
54
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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
|
-
{
|
|
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 || !
|
|
20
|
+
if (value === null || !_adapter) {
|
|
17
21
|
forwardChange(value);
|
|
18
22
|
} else {
|
|
19
|
-
forwardChange(
|
|
23
|
+
forwardChange(_adapter.fromDate(value));
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
: undefined;
|
|
23
27
|
|
|
24
28
|
let value: PickerComponentProps['value'] = externalValue
|
|
25
|
-
?
|
|
26
|
-
?
|
|
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 || !
|
|
22
|
+
if (dateRange === null || !_adapter) {
|
|
19
23
|
forwardChange(dateRange);
|
|
20
24
|
} else {
|
|
21
|
-
forwardChange(
|
|
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 (
|
|
30
|
-
const { from, to, label } =
|
|
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 || !
|
|
20
|
+
if (value === null || !_adapter) {
|
|
17
21
|
forwardChange(value);
|
|
18
22
|
} else {
|
|
19
|
-
forwardChange(
|
|
23
|
+
forwardChange(_adapter.fromDate(value));
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
: undefined;
|
|
23
27
|
|
|
24
28
|
let value: PickerComponentProps['value'] = externalValue
|
|
25
|
-
?
|
|
26
|
-
?
|
|
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 || !
|
|
22
|
+
if (dateRange === null || !_adapter) {
|
|
19
23
|
forwardChange(dateRange);
|
|
20
24
|
} else {
|
|
21
|
-
forwardChange(
|
|
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 (
|
|
30
|
-
const { from, to, label } =
|
|
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
|
|
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
|
|
6
|
-
const ref = useRef({
|
|
4
|
+
export const dateRangeAdapter = {
|
|
7
5
|
fromDateRange: (range) => {
|
|
8
6
|
return {
|
|
9
|
-
from: range
|
|
10
|
-
to: range
|
|
11
|
-
label: range
|
|
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
|
|
17
|
-
to: !value
|
|
18
|
-
label: value
|
|
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
|
-
|
|
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;
|