Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(date-picker): 增加季度选择 #2704

Merged
merged 5 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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