antd 元件 RangePicker 擴充套件,支援預選範圍回填選中
阿新 • • 發佈:2021-06-26
最近在做和時間段範圍相關的,預設常用的日期範圍可以提高使用者體驗。可以說 antd 的元件是很不錯的,但是美中不足的是,不支援預設範圍回填選中,怎麼辦?
在此基礎上封裝一下好了。
先來看下效果圖:
未選中:
選中回填:
看了下渲染出來的 html 內容,用的是 Tag
實現的。那我也這麼實現好了。
主要是利用 RangePicker
的 renderExtraFooter
進行處理。如果回填值和預設值一致,就設定選中,否則就不選中。
還有一個關鍵的點:就是選中預設的 tag
後,需要關閉日期選擇彈窗。所以還需要額外的處理 open
。
具體實現看下面程式碼:
// rangePicker.tsx import React, { forwardRef } from 'react' import { Tag, DatePicker } from 'antd'; import { useState } from 'react'; import { RangePickerProps, RangePickerValue } from 'antd/lib/date-picker/interface'; const { RangePicker } = DatePicker const Index = ({value, ranges = {}, onChange, open, format = "YYYY-MM-DD", ...props}: RangePickerProps, ref: any) => { const [val, setVal] = useState(value) const [show, setShow] = useState(open) const isDateSame = (key: string) => { const [start, end] = ranges[key] as RangePickerValue return val && val.length && start && end ? start.isSame(val[0]) && end.isSame(val[1]) : false } const tagCheck = (key: string) => () => { setVal(ranges[key]) const [start, end] = ranges[key] as RangePickerValue onChange && onChange(ranges[key] as RangePickerValue, [start ? start.format(format as string) : '', end ? end.format(format as string) : '']) setShow(false) } const footRanges = () => ( <div className="range-quick-selector"> {Object.keys(ranges).map(key => ( <Tag key={key} onClick={tagCheck(key)} color={isDateSame(key) ? 'blue' : ''}>{key}</Tag> ))} </div> ) const onOpenChange = (status: boolean) => { setShow(status) } const onChangeFn = (dates: RangePickerValue, dateStrings: [string, string]) => { onChange && onChange(dates, dateStrings) setVal(dates) } return ( <RangePicker renderExtraFooter={footRanges} value={val} onChange={onChangeFn} onOpenChange={onOpenChange} open={show} format={format} {...props} /> ) } export default forwardRef(Index)
怎麼用呢?原來怎麼使用,現在就怎麼使用:
import React, { useState } from 'react' import moment from 'moment'; import { RangePickerValue, RangePickerPresetRange } from 'antd/lib/date-picker/interface'; import RangePicker from './rangePicker' const ranges: { [range: string]: RangePickerPresetRange } = { '今天': [moment(), moment()], '昨天': [moment().subtract('days', 1), moment().subtract('days', 1)], '近一週': [moment().subtract('days', 7), moment()], '近兩週': [moment().subtract('days', 14), moment()], '近一個月': [moment().subtract('days', 30), moment()], '近三個月': [moment().subtract('days', 90), moment()], '近半年': [moment().subtract('days', 182), moment()], // 一年的一半 '近一年': [moment().subtract('days', 365), moment()], '當月': [moment().startOf('month'), moment()], '當季': [moment().startOf('quarter'), moment()], '當年': [moment().startOf('year'), moment()], } const demo = () => { const [dateRange, setDateRange] = useState<RangePickerValue>([]) const rangePickerChange = (dates: RangePickerValue, dateStrings: [string, string]) => { console.log({dates, dateStrings}); setDateRange(dates) } return <RangePicker value={dateRange} onChange={rangePickerChange} ranges={ranges} /> } export default demo