-
Notifications
You must be signed in to change notification settings - Fork 0
/
range-picker.tsx
87 lines (75 loc) · 2.45 KB
/
range-picker.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
import { DatePicker, Select } from 'antd'
import React, { ComponentProps, FC, useEffect, useState } from 'react'
import moment, { Moment } from 'moment'
import styled from '@emotion/styled'
type SelectProps = ComponentProps<typeof Select>
type RangeProps = ComponentProps<typeof DatePicker.RangePicker>
type RangeParam1Type = Parameters<NonNullable<RangeProps['onChange']>>[0]
export type OptionType = { label: string; value: [Moment, Moment] }
const StyledDiv = styled.div`
display: flex;
flex-direction: column;
`
export const CUSTOM = 'CUSTOM'
const format = 'MM/DD/YYYY'
export type GrubRangePickerProps = {
selectProps?: Omit<SelectProps, 'onChange' | 'options' | 'value' | 'defaultValue'>
pickerProps?: Omit<RangeProps, 'onChange' | 'value' | 'defaultValue'>
onChange: (val: RangeParam1Type) => void
options: OptionType[]
dateRange: { from: string; to: string }
}
const GrubRangePicker: FC<GrubRangePickerProps> = (props) => {
const { onChange, options, selectProps, pickerProps, dateRange } = props
const { from, to } = dateRange
const [visible, setVisible] = useState<boolean>(false)
const [selectVal, setSelectVal] = useState<string>()
const _onChange: SelectProps['onChange'] = (val) => {
if (val === CUSTOM) {
setVisible(true)
return
}
const selected = options.find((op) => op.label === val) as OptionType
onChange(selected.value)
}
const _rangeChange: RangeProps['onChange'] = (dates) => {
onChange(dates)
}
useEffect(() => {
const option = options.find((item) => {
const { value } = item
return value[0].format(format) === from && value[1].format(format) === to
})
if (option) {
setSelectVal(option.label)
setVisible(false)
} else {
setSelectVal(CUSTOM)
setVisible(true)
}
}, [from, to, options])
return (
<StyledDiv>
<Select {...selectProps} onChange={_onChange} value={selectVal}>
{options.map((op) => {
return (
<Select.Option key={op.label} value={op.label}>
{op.label}
</Select.Option>
)
})}
<Select.Option key={CUSTOM} value={CUSTOM}>
Custom Date Range
</Select.Option>
</Select>
{visible && (
<DatePicker.RangePicker
{...pickerProps}
onChange={_rangeChange}
value={[moment(from, 'MM/DD/YYYY'), moment(to, 'MM/DD/YYYY')]}
/>
)}
</StyledDiv>
)
}
export default GrubRangePicker