antd 組件 RangePicker 擴展,支持預選範圍回填選中

最近在做和時間段範圍相關的,預設常用的日期範圍可以提高用戶體驗。可以說 antd 的組件是很不錯的,但是美中不足的是,不支持預設範圍回填選中,怎麼辦?

在此基礎上封裝一下好了。

先來看下效果圖:

未選中:

選中回填:

看了下渲染出來的 html 內容,用的是 Tag 實現的。那我也這麼實現好了。

主要是利用 RangePickerrenderExtraFooter 進行處理。如果回填值和預設值一致,就設置選中,否則就不選中。

還有一個關鍵的點:就是選中預設的 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章