Skip to content

Commit

Permalink
feat(date-picker): support type="week" (#5061)
Browse files Browse the repository at this point in the history
* feat(date-picker): add demo for week type

* feat(date-picker): add localized placeholders & format

* feat(date-picker): add weekFormat for zhCN

* feat(data-picker): add css variable for calendarLeftPaddingWeek & calendarRightPaddingWeek

* feat(date-picker): adjust format for zhCN

* feat(date-picker): implement basic week

* feat(date-picker): add style to hovered week

* fix(date-picker): fix style issue

* fix(date-picker): make hover effect correct

* feat(date-picker): add enUS demo

* chore(date-picker): add changelog

* doc(date-picker): add demo to index of enUS doc

* feat(date-picker): remove confirm for week type

* fix(date-picker): remove single-day hover for week picker

* chore(date-picker): add weekPlaceholder to locales

* chore(date-picker): add weekFormat to locales

* fix(date-picker): fix wrong firstDayOfWeek

* fix(date-picker): remove console.log

---------

Co-authored-by: 07akioni <[email protected]>
  • Loading branch information
suica and 07akioni authored Dec 18, 2023
1 parent b34beb6 commit 6de711c
Show file tree
Hide file tree
Showing 36 changed files with 316 additions and 22 deletions.
1 change: 1 addition & 0 deletions src/date-picker/demos/enUS/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ year.vue
yearrange.vue
quarter.vue
quarterrange.vue
week.vue
size.vue
default-time.vue
disabled.vue
Expand Down
20 changes: 20 additions & 0 deletions src/date-picker/demos/enUS/week.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<markdown>
# Week
</markdown>

<template>
<n-date-picker v-model:value="timestamp" type="week" clearable />
<pre>{{ JSON.stringify(timestamp) }}</pre>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue'
export default defineComponent({
setup () {
return {
timestamp: ref(1183135260000)
}
}
})
</script>
1 change: 1 addition & 0 deletions src/date-picker/demos/zhCN/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ year.vue
yearrange.vue
quarter.vue
quarterrange.vue
week.vue
size.vue
default-time.vue
disabled.vue
Expand Down
20 changes: 20 additions & 0 deletions src/date-picker/demos/zhCN/week.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<markdown>
# 周
</markdown>

<template>
<n-date-picker v-model:value="timestamp" type="week" clearable />
<pre>{{ JSON.stringify(timestamp) }}</pre>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue'
export default defineComponent({
setup () {
return {
timestamp: ref(1183135260000)
}
}
})
</script>
11 changes: 9 additions & 2 deletions src/date-picker/src/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ export default defineComponent({
case 'quarter':
case 'quarterrange':
return localeRef.value.quarterFormat
case 'week':
return localeRef.value.weekFormat
}
})
const mergedValueFormatRef = computed(() => {
Expand Down Expand Up @@ -316,6 +318,8 @@ export default defineComponent({
return localeRef.value.yearPlaceholder
case 'quarter':
return localeRef.value.quarterPlaceholder
case 'week':
return localeRef.value.weekPlaceholder
default:
return ''
}
Expand Down Expand Up @@ -357,7 +361,8 @@ export default defineComponent({
if (actions !== undefined) return actions
const result = clearable ? ['clear'] : []
switch (type) {
case 'date': {
case 'date':
case 'week': {
result.push('now')
return result
}
Expand Down Expand Up @@ -1030,7 +1035,9 @@ export default defineComponent({
type === 'quarterrange' ? (
<MonthRangePanel {...commonPanelProps} type={type} />
) : (
<DatePanel {...commonPanelProps}>{$slots}</DatePanel>
<DatePanel {...commonPanelProps} type={type}>
{$slots}
</DatePanel>
)
}
if (this.panel) {
Expand Down
1 change: 1 addition & 0 deletions src/date-picker/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export type DatePickerType =
| 'monthrange'
| 'quarterrange'
| 'yearrange'
| 'week'
21 changes: 17 additions & 4 deletions src/date-picker/src/panel/date.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { h, defineComponent, watchEffect } from 'vue'
import { h, defineComponent, watchEffect, type PropType } from 'vue'
import {
BackwardIcon,
FastBackwardIcon,
Expand All @@ -19,7 +19,13 @@ import PanelHeader from './panelHeader'
*/
export default defineComponent({
name: 'DatePanel',
props: useCalendarProps,
props: {
...useCalendarProps,
type: {
type: String as PropType<'date' | 'week'>,
required: false
}
},
setup (props) {
if (__DEV__) {
watchEffect(() => {
Expand All @@ -31,7 +37,7 @@ export default defineComponent({
}
})
}
return useCalendar(props, 'date')
return useCalendar(props, props.type ?? 'date')
},
render () {
const { mergedClsPrefix, mergedTheme, shortcuts, onRender, $slots } = this
Expand Down Expand Up @@ -109,12 +115,19 @@ export default defineComponent({
[`${mergedClsPrefix}-date-panel-date--excluded`]:
!dateItem.inCurrentMonth,
[`${mergedClsPrefix}-date-panel-date--disabled`]:
this.mergedIsDateDisabled(dateItem.ts)
this.mergedIsDateDisabled(dateItem.ts),
[`${mergedClsPrefix}-date-panel-date--slightly-covered`]:
this.isSlightlyCovered(dateItem),
[`${mergedClsPrefix}-date-panel-date--heavily-covered`]:
dateItem.inHeavySpan
}
]}
onClick={() => {
this.handleDateClick(dateItem)
}}
onMouseenter={() => {
this.handleDateMouseEnter(dateItem)
}}
>
<div class={`${mergedClsPrefix}-date-panel-date__trigger`} />
{dateItem.dateObject.date}
Expand Down
44 changes: 41 additions & 3 deletions src/date-picker/src/panel/use-calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
startOfMonth,
startOfYear,
startOfQuarter,
startOfWeek,
setQuarter,
setYear,
setMonth
Expand All @@ -37,6 +38,7 @@ import {
quarterArray
} from '../utils'
import type {
FirstDayOfWeek,
IsSingleDateDisabled,
PanelChildComponentRefs,
Shortcuts
Expand All @@ -57,7 +59,7 @@ const useCalendarProps = {
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
function useCalendar (
props: ExtractPropTypes<typeof useCalendarProps>,
type: 'date' | 'datetime' | 'month' | 'year' | 'quarter'
type: 'date' | 'datetime' | 'month' | 'year' | 'quarter' | 'week'
) {
const panelCommon = usePanelCommon(props)
const {
Expand Down Expand Up @@ -106,7 +108,9 @@ function useCalendar (
calendarValueRef.value,
props.value,
nowRef.value,
firstDayOfWeekRef.value ?? localeRef.value.firstDayOfWeek
firstDayOfWeekRef.value ?? localeRef.value.firstDayOfWeek,
false,
type === 'week'
)
})
const monthArrayRef = computed(() => {
Expand Down Expand Up @@ -175,11 +179,26 @@ function useCalendar (
}
}
)

function sanitizeValue (value: number): number {
if (type === 'datetime') return getTime(startOfSecond(value))
if (type === 'month') return getTime(startOfMonth(value))
if (type === 'year') return getTime(startOfYear(value))
if (type === 'quarter') return getTime(startOfQuarter(value))
if (type === 'week') {
// refer to makeWeekMatcher
const weekStartsOn = (((firstDayOfWeekRef.value ??
localeRef.value.firstDayOfWeek) +
1) %
7) as FirstDayOfWeek
console.log(firstDayOfWeekRef.value, localeRef.value.firstDayOfWeek)

return getTime(
startOfWeek(value, {
weekStartsOn
})
)
}
return getTime(startOfDay(value))
}
function mergedIsDateDisabled (ts: number): boolean {
Expand Down Expand Up @@ -261,6 +280,22 @@ function useCalendar (
justifyColumnsScrollState(now)
}
}
const hoveredWeekRef = ref<number | null>(null)
function handleDateMouseEnter (
dateItem: DateItem | MonthItem | YearItem | QuarterItem
): void {
if (dateItem.type === 'date' && type === 'week') {
hoveredWeekRef.value = sanitizeValue(getTime(dateItem.ts))
}
}
function isSlightlyCovered (
dateItem: DateItem | MonthItem | YearItem | QuarterItem
): boolean {
if (dateItem.type === 'date' && type === 'week') {
return sanitizeValue(getTime(dateItem.ts)) === hoveredWeekRef.value
}
return false
}
function handleDateClick (
dateItem: DateItem | MonthItem | YearItem | QuarterItem
): void {
Expand Down Expand Up @@ -293,10 +328,11 @@ function useCalendar (
)
panelCommon.doUpdateValue(
sanitizeValue(newValue),
props.panel || type === 'date' || type === 'year'
props.panel || type === 'date' || type === 'week' || type === 'year'
)
switch (type) {
case 'date':
case 'week':
panelCommon.doClose()
break
case 'year':
Expand Down Expand Up @@ -464,6 +500,8 @@ function useCalendar (
handleDateClick,
handleDateInputBlur,
handleDateInput,
handleDateMouseEnter,
isSlightlyCovered,
handleTimePickerChange,
clearSelectedDateTime,
virtualListContainer,
Expand Down
54 changes: 51 additions & 3 deletions src/date-picker/src/styles/index.cssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,13 @@ export default c([
`),
cNotM('disabled', [
cNotM('selected', [
c('&:hover', {
backgroundColor: 'var(--n-item-color-hover)'
})
cNotM('slightly-covered', [
cNotM('heavily-covered', [
c('&:hover', {
backgroundColor: 'var(--n-item-color-hover)'
})
])
])
])
]),
cM('current', [
Expand Down Expand Up @@ -371,6 +375,7 @@ export default c([
border-radius: inherit;
transition: background-color .3s var(--n-bezier);
`),

cM('covered, start, end', [
cNotM('excluded', [
c('&::before', `
Expand Down Expand Up @@ -439,6 +444,49 @@ export default c([
backgroundColor: 'var(--n-item-color-disabled)'
})
])
]),
cM('slightly-covered', [
c('&::before', `
content: "";
z-index: -2;
position: absolute;
left: calc((var(--n-item-size) - var(--n-item-cell-width)) / 2);
right: calc((var(--n-item-size) - var(--n-item-cell-width)) / 2);
top: 0;
bottom: 0;
background-color: var(--n-item-color-included);
`),
c('&:nth-child(7n + 1)::before', {
borderTopLeftRadius: 'var(--n-item-border-radius)',
borderBottomLeftRadius: 'var(--n-item-border-radius)'
}),
c('&:nth-child(7n + 7)::before', {
borderTopRightRadius: 'var(--n-item-border-radius)',
borderBottomRightRadius: 'var(--n-item-border-radius)'
})
]),
cM('heavily-covered', [
c('&', `
color: var(--n-item-text-color-active)
`),
c('&::before', `
content: "";
z-index: -2;
position: absolute;
left: calc((var(--n-item-size) - var(--n-item-cell-width)) / 2);
right: calc((var(--n-item-size) - var(--n-item-cell-width)) / 2);
top: 0;
bottom: 0;
background-color: var(--n-item-color-active);
`),
c('&:nth-child(7n + 1)::before', {
borderTopLeftRadius: 'var(--n-item-border-radius)',
borderBottomLeftRadius: 'var(--n-item-border-radius)'
}),
c('&:nth-child(7n + 7)::before', {
borderTopRightRadius: 'var(--n-item-border-radius)',
borderBottomRightRadius: 'var(--n-item-border-radius)'
})
])
])
]),
Expand Down
Loading

0 comments on commit 6de711c

Please sign in to comment.