-
Notifications
You must be signed in to change notification settings - Fork 58
/
TimeSlider.tsx
119 lines (108 loc) · 3.13 KB
/
TimeSlider.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { Slider, SliderSingleProps } from 'antd';
import _isArray from 'lodash/isArray';
import moment from 'moment';
import React, { CSSProperties, ReactNode } from 'react';
import { CSS_PREFIX } from '../../constants';
interface Mark {
style?: CSSProperties;
label?: ReactNode;
}
export type SliderMarks = {
[key: number]: ReactNode | Mark;
};
interface OwnProps {
useRange?: boolean;
defaultValue: string | [string, string];
min: string;
max: string;
onChange: (val: string | [string, string]) => void;
value: string | [string, string];
formatString: string;
className?: string;
marks: SliderSingleProps['marks'];
}
export type TimeSliderProps = OwnProps;
const TimeSlider: React.FC<TimeSliderProps> = ({
useRange = false,
defaultValue = moment().toISOString(),
min = moment().subtract(1, 'hour').toISOString(),
max = moment().toISOString(),
onChange = () => undefined,
value = moment().toISOString(),
formatString = 'DD.MM. HH:mm',
className,
marks,
...passThroughProps
}) => {
const convert = (val: string[] | string): number | [number, number] => {
return _isArray(val)
? ((val as Array<string>).map(iso => moment(iso).unix()) as [
number,
number
])
: (moment(val).unix() as number);
};
const convertMarks = (
mks: SliderSingleProps['marks']
): SliderSingleProps['marks'] => {
if (!mks) {
return;
}
let convertedMks: SliderSingleProps['marks'] = {};
Object.keys(mks).forEach((key: string) => {
if (!convertedMks) {
return;
}
const convertedKey = convert([key]) as number; // Assuming key is ISOString
convertedMks[convertedKey] = mks[key];
});
return convertedMks;
};
const formatTimestamp = (unix: number): string => {
return unix ? moment(unix * 1000).format(formatString) : '';
};
const valueUpdated = (val: number | number[]) => {
onChange(
_isArray(val)
? [
moment(val[0] * 1000).toISOString(),
moment(val[1] * 1000).toISOString()
]
: moment(val * 1000).toISOString()
);
};
const finalClassName = className
? `${className} ${CSS_PREFIX}timeslider`
: `${CSS_PREFIX}timeslider`;
const convertedMarks = convertMarks(marks);
return useRange ? (
<Slider
className={finalClassName}
defaultValue={convert(defaultValue) as [number, number]}
range={true}
min={moment(min).unix()}
max={moment(max).unix()}
tooltip={{ formatter: val => formatTimestamp(val as number) }}
onChange={(val: number[]) => valueUpdated(val)}
value={convert(value) as [number, number]}
marks={convertedMarks}
{...passThroughProps}
/>
) : (
<Slider
className={finalClassName}
defaultValue={convert(defaultValue) as number}
range={false}
min={moment(min).unix()}
max={moment(max).unix()}
tooltip={{
formatter: val => formatTimestamp(val as number)
}}
onChange={(val: number) => valueUpdated(val as number)}
value={convert(value) as number}
marks={convertedMarks}
{...passThroughProps}
/>
);
};
export default TimeSlider;