Skip to content

Commit

Permalink
Merge pull request #2704 from XiaoMi/feature/2695(date-picker)
Browse files Browse the repository at this point in the history
feat(date-picker): 增加季度选择
  • Loading branch information
solarjoker authored Jan 5, 2024
2 parents 2da8269 + 5451cd2 commit bbc3998
Show file tree
Hide file tree
Showing 23 changed files with 197 additions and 36 deletions.
5 changes: 5 additions & 0 deletions .changeset/shaggy-rules-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hi-ui/locale-context": patch
---

chore: 补充日期语言包
7 changes: 7 additions & 0 deletions .changeset/small-mangos-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@hi-ui/hiui": patch
---

feat(date-picker): 支持季度选择
feat(date-picker): add onPanelChange api
chore(locale-context): 补充日期语言包
6 changes: 6 additions & 0 deletions .changeset/sour-apples-look.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@hi-ui/date-picker": minor
---

feat: 支持季度选择
feat: add onPanelChange api
8 changes: 5 additions & 3 deletions packages/ui/date-picker/src/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const DatePicker = forwardRef<HTMLDivElement | null, DatePickerProps>(
maxDate: max = null,
minDate: min = null,
onSelect: propsOnSelectOriginal,
onPanelChange,
theme,
disabledHours = DEFAULT_DISABLED_FUNCTION,
disabledMinutes = DEFAULT_DISABLED_FUNCTION,
Expand Down Expand Up @@ -229,8 +230,8 @@ export const DatePicker = forwardRef<HTMLDivElement | null, DatePickerProps>(
end: _dates[1]?.toDate(),
}
returnDateStr = {
start: _dates[0]?.format(realFormat),
end: _dates[1]?.format(realFormat),
start: _dates[0]?.format(realFormat).toLocaleUpperCase(),
end: _dates[1]?.format(realFormat).toLocaleUpperCase(),
}
compareNumber = 2
} else if (type.includes('week')) {
Expand Down Expand Up @@ -259,7 +260,7 @@ export const DatePicker = forwardRef<HTMLDivElement | null, DatePickerProps>(
: getWeekString(_dates[0])
} else {
returnDate = _dates[0]?.toDate()
returnDateStr = _dates[0]?.format(realFormat)
returnDateStr = _dates[0]?.format(realFormat).toLocaleUpperCase()
}

// 只有发生了改变,才会去通知外部
Expand Down Expand Up @@ -416,6 +417,7 @@ export const DatePicker = forwardRef<HTMLDivElement | null, DatePickerProps>(
value,
disabledDate,
onSelect,
onPanelChange,
prefixCls,
showPanel,
isInDateRangeTimeMode,
Expand Down
6 changes: 5 additions & 1 deletion packages/ui/date-picker/src/components/calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ const Calendar = ({
_date.add(1, 'months')
}

if (type.includes('quarter')) {
_date.quarter(clickVal)
}

_date[view](clickVal)
} else {
// 点击的上个月的部分,鼠标还在本月的panel上,则视作,鼠标正在本月第一天
Expand Down Expand Up @@ -213,7 +217,7 @@ const Calendar = ({
}, 2000) as any
}
const renderAltCalendar = (cell: CalendarColInfo, isBelongFullOutOfRange: string) => {
if (view.includes('year') || view.includes('month')) return
if (view.includes('year') || view.includes('month') || view.includes('quarter')) return
if (
Object.keys(altCalendarPresetData).length > 0 ||
Object.keys(dateMarkPresetData).length > 0 ||
Expand Down
6 changes: 3 additions & 3 deletions packages/ui/date-picker/src/components/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const getHeaderCenterContent = (
if (view === 'year') {
return year - 4 + '~' + (year + 7)
}
if (view === 'month') {
if (view === 'month' || view === 'quarter') {
return year
}

Expand Down Expand Up @@ -71,7 +71,7 @@ const Header = ({
>
<DirectionLeftOutlined />
</span>
{view !== 'year' && view !== 'month' && (
{view !== 'year' && view !== 'month' && view !== 'quarter' && (
<span
className={`${prefixCls}__header-icon`}
onClick={() => headerChangeDateEvent('months', -1)}
Expand All @@ -91,7 +91,7 @@ const Header = ({
</span>
{
<div className={`${prefixCls}__header-btns`}>
{view !== 'year' && view !== 'month' && (
{view !== 'year' && view !== 'month' && view !== 'quarter' && (
<span
onClick={() => headerChangeDateEvent('months', 1)}
className={`${prefixCls}__header-icon`}
Expand Down
4 changes: 4 additions & 0 deletions packages/ui/date-picker/src/components/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ const Input = ({
}
}

if (type.includes('quarter') && vals) {
vals = vals?.toLocaleUpperCase()
}

setValue(vals)

cacheValues.current = vals
Expand Down
13 changes: 11 additions & 2 deletions packages/ui/date-picker/src/components/panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const Panel = (props: PanelProps) => {
weekOffset,
locale,
onSelect,
onPanelChange,
hourStep,
minuteStep,
secondStep,
Expand Down Expand Up @@ -74,6 +75,12 @@ const Panel = (props: PanelProps) => {
)
return
}

if (type === 'quarter') {
onPick([date], false)
return
}

if (type === 'week' && view === 'date') {
// week picker
// 根据偏移判断当前使用的周格式
Expand All @@ -87,6 +94,9 @@ const Panel = (props: PanelProps) => {
if (view === 'year') {
_view = 'month'
}
if (view === 'quarter') {
_view = 'quarter'
}
if (view === 'month') {
_view = 'date'
}
Expand Down Expand Up @@ -135,8 +145,7 @@ const Panel = (props: PanelProps) => {
const _innerDates = genNewDates(calRenderDates, date)
if (type.includes('range') && _innerDates[0] >= _innerDates[1]) return
setCalRenderDates(_innerDates)
// 左右切换年或月时触发 onSelect 回调
onSelect(date.toDate(), true)
onPanelChange?.(date.toDate())
}

return (
Expand Down
6 changes: 5 additions & 1 deletion packages/ui/date-picker/src/components/range-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const RangePanel = () => {
theme,
locale,
onSelect,
onPanelChange,
hourStep,
minuteStep,
secondStep,
Expand Down Expand Up @@ -173,6 +174,9 @@ const RangePanel = () => {
if (views[uIndex] === 'year' && !type.includes('year')) {
_views[uIndex] = 'month'
}
if (views[uIndex] === 'quarter' && !type.includes('quarter')) {
_views[uIndex] = 'quarter'
}
setViews(_views)
}

Expand Down Expand Up @@ -217,7 +221,7 @@ const RangePanel = () => {
return
}
setCalRenderDates(_innerDates)
onSelect(date as any, !calendarClickIsEnd.current)
onPanelChange?.(date.toDate())
}
const onTimePeriodPick = useCallback(
(ts1: string, ts2: string) => {
Expand Down
1 change: 1 addition & 0 deletions packages/ui/date-picker/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,6 @@ export interface DPContextData extends ExtendsType {
value: DatePickerValueV3
// 内部现在暂时使用 v3 的数据格式
altCalendar?: CalendarItemV3[]
onPanelChange?: (data: Date) => void
}
export default DPContext
62 changes: 61 additions & 1 deletion packages/ui/date-picker/src/hooks/useCalenderData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,63 @@ const getYearOrMonthRows = ({
formatRange.end = temp
}

if (type.includes('quarter')) {
const quarterColData: CalendarColInfo[] = []
for (let i = 0; i < 4; i++) {
const value = i + 1
const col = {
type: 'normal',
text: `Q${i + 1}`,
range: false,
value,
} as CalendarColInfo

if (current.year() === renderDate?.year() && originDate?.quarter() === value) {
col.type = 'selected'
}

if (current.year() === renderDate?.year() && current.quarter() === value) {
col.type = 'today'
}

if (disabledDate?.(_date.quarter(value).toDate(), 'quarter')) {
col.type = 'disabled'
}

const currentYM = (_date as any)[view](value)

if (
range?.start &&
range?.end &&
(currentYM.isBetween(formatRange.start, formatRange.end) ||
currentYM.isBetween(formatRange.end, formatRange.start))
) {
col.range = true
}
if (formatRange?.start && currentYM.isSame(formatRange.start, view)) {
col.type = 'selected'
col.range = false
col.rangeStart = true
// 当前,存在开始,结束不存在,范围选择现在只选择了一个值,视作,开始结束为同一个
if (!formatRange.end) {
col.rangeEnd = true
}
}
if (formatRange?.end && currentYM.isSame(formatRange.end, view)) {
col.type = 'selected'
col.range = false
col.rangeEnd = true
// 当前,存在结束,开始不存在,范围选择现在只选择了一个值,视作,开始结束为同一个
if (!formatRange.start) {
col.rangeEnd = true
}
}

quarterColData.push(col)
}
return [quarterColData] as CalendarRowInfo[]
}

const monthText = i18n.get('datePicker.month')

for (let i = 0; i < 4; i++) {
Expand Down Expand Up @@ -188,6 +245,7 @@ const getYearOrMonthRows = ({
}
}
}

return trs
}
const getTime = (week: number, y: number, m: number) => {
Expand Down Expand Up @@ -422,9 +480,10 @@ const useDate = ({
range?: CalenderSelectedRange
}) => {
const [rows, setRows] = useState<CalendarRowInfo[]>([])

useEffect(() => {
const _rows =
view.includes('month') || view.includes('year')
view.includes('month') || view.includes('year') || view.includes('quarter')
? getYearOrMonthRows({
originDate,
renderDate,
Expand All @@ -446,6 +505,7 @@ const useDate = ({
renderDate,
disabledDate,
})

setRows(_rows)
}, [renderDate, view, range, type, disabledDate, i18n, max, min, weekOffset, originDate])

Expand Down
2 changes: 1 addition & 1 deletion packages/ui/date-picker/src/hooks/useFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const useFormat = (config: UseFormatConfig) => {
const { type, showTime, format, locale = 'zh-CN' } = config

return useMemo(() => {
let realFormat = format || getLocaleTypeFormatMap(locale)[type]
let realFormat = format || getLocaleTypeFormatMap(locale)[type] || ''
if (showTime && !/[H|h|m|s]/.test(realFormat)) {
realFormat += ' HH:mm:ss'
}
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/date-picker/src/hooks/useTimePickerFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useMemo } from 'react'
import { TimePickerFormat } from '@hi-ui/time-picker'

export const useTimePickerFormat = (original: string) => {
const timeFormat = original.split(' ')[1] ?? ''
const timeFormat = original?.split(' ')[1] ?? ''

return useMemo(() => {
let result = ''
Expand Down
8 changes: 8 additions & 0 deletions packages/ui/date-picker/src/styles/date-picker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,14 @@ $calendar-large-background-border-radius: $calendar-large-indicator-border-radiu
}
}
}

&--quarter {
.#{$prefix}__cell {
&-text {
width: 52px;
}
}
}
}

&__cell {
Expand Down
8 changes: 7 additions & 1 deletion packages/ui/date-picker/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { TimePickerPanelType } from '@hi-ui/time-picker'
import { CalendarColInfo } from './hooks/useCalenderData'
import { Moment } from 'moment'

export type CalendarViewEnum = 'date' | 'year' | 'month'
export type CalendarViewEnum = 'date' | 'year' | 'month' | 'quarter'

export interface DateRange {
start: Date | string | number | undefined | null
Expand Down Expand Up @@ -93,10 +93,12 @@ export type DatePickerTypeEnum =
| 'year'
| 'month'
| 'week'
| 'quarter'
| 'weekrange'
| 'timeperiod'
| 'yearrange'
| 'monthrange'
| 'quarterrange'

export type DatePickerAltCalendarPresetEnum = 'zh-CN' | 'id-ID'

Expand Down Expand Up @@ -235,6 +237,10 @@ export interface DatePickerProps extends Omit<HiBaseHTMLProps<'div'>, 'placehold
* 选择后的回调,(date: 选中的日期,dateStr: 选中的日期字符串) => void
*/
onChange?: (date: Date | Date[] | null, dateStr: string | string[] | null) => void
/**
* 日期面板改变时的回调函数
*/
onPanelChange?: (data: Date) => void
/**
* 不同 UI 外观
* @default 'line'
Expand Down
7 changes: 7 additions & 0 deletions packages/ui/date-picker/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export const GranularityMap: {
weekrange: 'date',
month: 'month',
monthrange: 'month',
quarter: 'quarter',
quarterrange: 'quarter',
timeperiod: 'second',
}
/**
Expand All @@ -26,6 +28,7 @@ export const getLocaleTypeFormatMap = (locale: string) => {
? {
date: 'YYYY-MM-DD',
month: 'YYYY-MM',
quarter: 'YYYY-qQ',
year: 'YYYY',
time: 'HH:mm:ss',
timerange: 'HH:mm:ss',
Expand All @@ -34,6 +37,7 @@ export const getLocaleTypeFormatMap = (locale: string) => {
weekrange: 'YYYY-WW',
timeperiod: 'YYYY-MM-DD HH:mm:ss',
monthrange: 'YYYY-MM',
quarterrange: 'YYYY-qQ',
yearrange: 'YYYY',
}
: {
Expand All @@ -47,13 +51,15 @@ export const getLocaleTypeFormatMap = (locale: string) => {
weekrange: 'wo/YYYY',
timeperiod: 'MM/DD/YYYY HH:mm:ss',
monthrange: 'MM/YYYY',
quarterrange: 'qQ/YYYY',
yearrange: 'YYYY',
}
}

export const INPUTTYPES = {
date: 'normal',
month: 'normal',
quarter: 'normal',
year: 'normal',
time: 'normal',
timerange: 'range',
Expand All @@ -62,5 +68,6 @@ export const INPUTTYPES = {
weekrange: 'range',
timeperiod: 'range',
monthrange: 'range',
quarterrange: 'range',
yearrange: 'range',
}
Loading

0 comments on commit bbc3998

Please sign in to comment.