Skip to content

Commit

Permalink
fix(comp:date-picker): disabledDate error on year and month panel (#1514
Browse files Browse the repository at this point in the history
)
  • Loading branch information
sallerli1 committed Mar 27, 2023
1 parent 3fe76f2 commit 06c546c
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,19 @@ exports[`DatePanel > date type disabledDate work 1`] = `
<div class=\\"ix-date-panel-cell-trigger\\">9</div>
</div>
</td>
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">10</div>
</div>
</td>
</tr>
<tr role=\\"row\\" class=\\"ix-date-panel-row\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">11</div>
</div>
</td>
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">12</div>
</div>
Expand All @@ -133,123 +133,123 @@ exports[`DatePanel > date type disabledDate work 1`] = `
<div class=\\"ix-date-panel-cell-trigger\\">15</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">16</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">17</div>
</div>
</td>
</tr>
<tr role=\\"row\\" class=\\"ix-date-panel-row\\">
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">18</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">19</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">20</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">21</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">22</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">23</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">24</div>
</div>
</td>
</tr>
<tr role=\\"row\\" class=\\"ix-date-panel-row\\">
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">25</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">26</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">27</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">28</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">29</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">30</div>
</div>
</td>
<td class=\\"ix-date-panel-cell\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">31</div>
</div>
</td>
</tr>
<tr role=\\"row\\" class=\\"ix-date-panel-row\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">1</div>
</div>
</td>
<td class=\\"ix-date-panel-cell ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">2</div>
</div>
</td>
<td class=\\"ix-date-panel-cell ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">3</div>
</div>
</td>
<td class=\\"ix-date-panel-cell ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">4</div>
</div>
</td>
<td class=\\"ix-date-panel-cell ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">5</div>
</div>
</td>
<td class=\\"ix-date-panel-cell ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">6</div>
</div>
</td>
<td class=\\"ix-date-panel-cell ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<td class=\\"ix-date-panel-cell ix-date-panel-cell-disabled ix-date-panel-cell-out-view\\" role=\\"gridcell\\">
<div class=\\"ix-date-panel-cell-inner\\">
<div class=\\"ix-date-panel-cell-trigger\\">7</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { MountingOptions, VueWrapper, mount } from '@vue/test-utils'
import { isArray } from 'lodash-es'

import { renderWork } from '@tests'
import { endOfWeek, startOfWeek } from 'date-fns'
import { endOfWeek, isAfter, isBefore, startOfWeek } from 'date-fns'

import DatePanel from '../src/DatePanel'
import PanelCell from '../src/panel-body/PanelCell'
Expand Down Expand Up @@ -163,17 +163,45 @@ describe('DatePanel', () => {
type: 'date',
value: new Date('2021-10-01'),
activeDate: new Date('2021-10-1'),
disabledDate: date => date.getMonth() === 9 && [10, 11, 12].includes(date.getDate()),
disabledDate: date => isBefore(date, new Date('2021-09-20')) || isAfter(date, new Date('2021-10-15')),
},
})

expect(findCell(wrapper, '9')?.classes()).not.toContain('ix-date-panel-cell-disabled')
expect(findCell(wrapper, '10')?.classes()).toContain('ix-date-panel-cell-disabled')
expect(findCell(wrapper, '11')?.classes()).toContain('ix-date-panel-cell-disabled')
expect(findCell(wrapper, '12')?.classes()).toContain('ix-date-panel-cell-disabled')
expect(findCell(wrapper, '13')?.classes()).not.toContain('ix-date-panel-cell-disabled')

expect(wrapper.html()).toMatchSnapshot()

for (let num = 16; num <= 26; num++) {
expect(findCell(wrapper, `${num}`)?.classes()).toContain('ix-date-panel-cell-disabled')
}
for (let num = 1; num <= 15; num++) {
expect(findCell(wrapper, `${num}`)?.classes()).not.toContain('ix-date-panel-cell-disabled')
}

await wrapper.find('.ix-date-panel-header').findAll('button')[2].trigger('click')

expect(findCell(wrapper, '2020')?.classes()).toContain('ix-date-panel-cell-disabled')
expect(findCell(wrapper, '2021')?.classes()).not.toContain('ix-date-panel-cell-disabled')
expect(findCell(wrapper, '2022')?.classes()).toContain('ix-date-panel-cell-disabled')

await findCell(wrapper, '2021')?.trigger('click')

await wrapper.find('.ix-date-panel-header').findAll('button')[3].trigger('click')

expect(findCell(wrapper, '8月')?.classes()).toContain('ix-date-panel-cell-disabled')
expect(findCell(wrapper, '9月')?.classes()).not.toContain('ix-date-panel-cell-disabled')
expect(findCell(wrapper, '10月')?.classes()).not.toContain('ix-date-panel-cell-disabled')
expect(findCell(wrapper, '11月')?.classes()).toContain('ix-date-panel-cell-disabled')

await findCell(wrapper, '9月')?.trigger('click')
await wrapper.setProps({
activeDate: new Date('2021-9-1'),
})

for (let num = 1; num <= 19; num++) {
expect(findCell(wrapper, `${num}`)?.classes()).toContain('ix-date-panel-cell-disabled')
}
for (let num = 21; num <= 29; num++) {
expect(findCell(wrapper, `${num}`)?.classes()).not.toContain('ix-date-panel-cell-disabled')
}
})

test('month type disabledDate work', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import { IxTooltip } from '@idux/components/tooltip'

import { datePanelToken } from '../token'
import { panelCellProps } from '../types'
import { getPanelCellDisabled, getPanelCellType } from '../utils'

const dayTypes: DatePanelType[] = ['date', 'week']
const labelFormat: Record<DatePanelType, string> = {
date: 'd',
week: 'd',
Expand Down Expand Up @@ -44,30 +44,31 @@ export default defineComponent({

const offsetIndex = computed(() => props.rowIndex! * maxCellIndex.value + props.cellIndex!)
const cellDate = computed(() => {
const currType = activeType.value
const offsetUnit = dayTypes.includes(currType) ? 'day' : currType
return dateConfig.add(startActiveDate.value, offsetIndex.value, offsetUnit as 'day')
return dateConfig.add(startActiveDate.value, offsetIndex.value, getPanelCellType(activeType.value))
})

const startDate = computed(() => getDateValue(dateConfig, panelProps.value, activeType.value, true))
const endDate = computed(() => getDateValue(dateConfig, panelProps.value, activeType.value, false))

const isDisabled = computed(() => panelProps.disabledDate?.(cellDate.value))
const isDisabled = computed(() => {
const disabledDate = panelProps.disabledDate
if (!disabledDate) {
return false
}

return getPanelCellDisabled(cellDate.value, activeType.value, dateConfig, disabledDate)
})
const cellTooltip = computed(() =>
panelProps.cellTooltip?.({ value: cellDate.value, disabled: !!isDisabled.value }),
)
const isStart = computed(() => startDate.value && dateConfig.isSame(startDate.value, cellDate.value, 'date'))
const isEnd = computed(() => endDate.value && dateConfig.isSame(endDate.value, cellDate.value, 'date'))
const isCurrent = computed(() =>
dateConfig.isSame(
cellDate.value,
dateConfig.now(),
dayTypes.includes(activeType.value) ? 'day' : activeType.value,
),
dateConfig.isSame(cellDate.value, dateConfig.now(), getPanelCellType(activeType.value)),
)
const outView = computed(() => {
const currType = activeType.value
if (dayTypes.includes(activeType.value)) {
if (getPanelCellType(activeType.value) === 'date') {
return !dateConfig.isSame(cellDate.value, activeDate.value, 'month')
}
if (currType === 'year') {
Expand All @@ -81,7 +82,7 @@ export default defineComponent({
return false
}

const compareType = dayTypes.includes(activeType.value) ? 'date' : activeType.value
const compareType = getPanelCellType(activeType.value)

if (panelProps.isSelecting) {
return startDate.value && dateConfig.isSame(startDate.value, cellDate.value, compareType)
Expand All @@ -93,7 +94,7 @@ export default defineComponent({
)
})
const isInRange = computed(() => {
const compareType = dayTypes.includes(activeType.value) ? 'date' : activeType.value
const compareType = getPanelCellType(activeType.value)
const cellDateValue = dateConfig.startOf(cellDate.value, compareType).valueOf()

return (
Expand Down
64 changes: 64 additions & 0 deletions packages/components/_private/date-panel/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* @license
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import type { DatePanelType } from './types'
import type { DateConfig } from '@idux/components/config'

export type PanelCellType = Exclude<DatePanelType, 'week'>

export function getPanelCellType(type: DatePanelType): PanelCellType {
return type === 'week' ? 'date' : type
}

export function getPanelCellDisabled(
cellDate: Date,
panelType: DatePanelType,
dateConfig: DateConfig,
disabledDate: (date: Date) => boolean,
): boolean {
const cellType = getPanelCellType(panelType)
if (cellType === 'date') {
return disabledDate(cellDate)
}

const scopesMap: Record<PanelCellType, 'date' | 'month' | 'quarter' | undefined> = {
date: undefined,
month: 'date',
quarter: 'month',
year: 'quarter',
}

const stack: { date: Date; type: PanelCellType }[] = []
const pushStacks = (date: Date, type: PanelCellType) => {
const scope = scopesMap[type]
if (!scope) {
return
}

const [start, end] = (['startOf', 'endOf'] as const).map(fn => dateConfig.get(dateConfig[fn](date, type), scope))
for (let i = start; i <= end; i++) {
stack.push({
date: dateConfig.set(date, i, scope),
type: scope,
})
}
}

pushStacks(cellDate, cellType)

while (stack.length) {
const item = stack.pop()!

if (!disabledDate(item.date)) {
return false
}

pushStacks(item.date, item.type)
}

return true
}

0 comments on commit 06c546c

Please sign in to comment.