Skip to content
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
2 changes: 1 addition & 1 deletion packages/ccui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"coverage": "vitest run --coverage"
},
"dependencies": {
"dayjs": "^1.11.19",
"theme": "workspace:*",
"vue": "^3.5.22"
},
Expand All @@ -39,7 +40,6 @@
"@vue/test-utils": "^2.4.6",
"c8": "^10.1.3",
"jsdom": "^27.1.0",
"moment": "^2.30.1",
"sass": "^1.93.3",
"typescript": "^5.9.3",
"vite": "^7.1.12",
Expand Down
38 changes: 21 additions & 17 deletions packages/ccui/ui/calendar/src/calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Ref } from 'vue'
import type { CalendarProps, dateItem } from './calendar-types'
import moment from 'moment'
import dayjs from 'dayjs'
import { computed, defineComponent, ref, watch } from 'vue'
import { useNamespace } from '../../shared/hooks/use-namespace'
import { calendarProps } from './calendar-types'
Expand All @@ -16,12 +16,16 @@ export default defineComponent({
// 当前天 选中天
const currentDate = ref(
props.modelValue
? moment(props.modelValue).format('YYYY-MM-DD')
: moment().format('YYYY-MM-DD'),
? dayjs(props.modelValue).format('YYYY-MM-DD')
: dayjs().format('YYYY-MM-DD'),
)

// 当前月
const currentMonth = ref(moment().format('YYYY-MM'))
const currentMonth = ref(
props.modelValue
? dayjs(props.modelValue).format('YYYY-MM')
: dayjs().format('YYYY-MM'),
)

// 当前展示的日期列表
const curDateList: Ref<dateItem[]> = ref([])
Expand All @@ -30,10 +34,10 @@ export default defineComponent({
// 根据月份计算当前展示日期的数组
const generatedDate = (month?: string) => {
// 获取当月第一天是周几
const whichDay = moment(month).startOf('month').weekday()
const whichDay = dayjs(month).startOf('month').day()
// 计算开始开始日期 7 减去当月第一天是周几(获取到的周几是 0123456, 其中0代表周日)
const startDate = moment(
moment(month).subtract(7 - whichDay, 'days'),
const startDate = dayjs(
dayjs(month).subtract(7 - whichDay, 'day'),
).format('YYYY-MM-DD')

// 整理数据
Expand All @@ -42,13 +46,13 @@ export default defineComponent({
.map((item, index) => index)
.reduce((acc: Array<dateItem>, index: number) => {
// 获取展示的日期
const date = moment(startDate)
.add(index + 1, 'days')
const date = dayjs(startDate)
.add(index + 1, 'day')
.format('YYYY-MM-DD')
// 分割日期 用于获取是 几号 如 123456
const dateList = date.split('-')
// 获取周几
const week = moment(date).weekday()
const week = dayjs(date).day()

// 将需要的数据 放进数组
acc.push({
Expand All @@ -67,10 +71,10 @@ export default defineComponent({

// 设置当前天、选中天, 生成对应月份
const setCurrentDate = (date: string) => {
currentDate.value = moment(date).format('YYYY-MM-DD')
currentDate.value = dayjs(date).format('YYYY-MM-DD')
// 月份不同 重新生成日历
if (!date.includes(currentMonth.value)) {
currentMonth.value = moment(date).format('YYYY-MM')
currentMonth.value = dayjs(date).format('YYYY-MM')
generatedDate(currentMonth.value)
}

Expand All @@ -83,12 +87,12 @@ export default defineComponent({
let month = ''
// 下个月
if (type === 'nextMonth') {
month = moment(currentMonth.value).add(1, 'month').format('YYYY-MM')
month = dayjs(currentMonth.value).add(1, 'month').format('YYYY-MM')
}

// 上个月
if (type === 'lastMonth') {
month = moment(currentMonth.value)
month = dayjs(currentMonth.value)
.subtract(1, 'month')
.format('YYYY-MM')
}
Expand All @@ -101,10 +105,10 @@ export default defineComponent({
watch(
() => props.modelValue,
() => {
currentDate.value = moment(props.modelValue).format('YYYY-MM-DD')
currentDate.value = dayjs(props.modelValue).format('YYYY-MM-DD')
// 月份不同 重新生成日历
if (!currentDate.value.includes(currentMonth.value)) {
currentMonth.value = moment(props.modelValue).format('YYYY-MM')
currentMonth.value = dayjs(props.modelValue).format('YYYY-MM')
generatedDate(currentMonth.value)
}
},
Expand Down Expand Up @@ -166,7 +170,7 @@ export default defineComponent({
type="primary"
plain={true}
onClick={() => {
setCurrentDate(moment().format('YYYY-MM-DD'))
setCurrentDate(dayjs().format('YYYY-MM-DD'))
}}
>
今天
Expand Down
169 changes: 162 additions & 7 deletions packages/ccui/ui/calendar/test/calendar.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import { shallowMount } from '@vue/test-utils'
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import { Button } from '../../button/index'
import { useNamespace } from '../../shared/hooks/use-namespace'
import { Calendar } from '../index'

const ns = useNamespace('calendar', true)
const baseClass = ns.b()
const dayClass = ns.em('day-box', 'day')
const currentDateClass = '.current-date'
const headerClass = ns.e('header')

describe('button', () => {
describe('calendar', () => {
it('dom', () => {
const wrapper = shallowMount(Calendar, {
const wrapper = mount(Calendar, {
props: { modelValue: new Date() },
global: {
components: {
CButton: Button,
},
},
})

// 元素是否存在
Expand All @@ -24,25 +31,36 @@ describe('button', () => {
})

it('props', async () => {
const wrapper = shallowMount(Calendar, {
const wrapper = mount(Calendar, {
props: { modelValue: new Date() },
global: {
components: {
CButton: Button,
},
},
})

await wrapper.setProps({ modelValue: '2022-10-10' })
const testDate = new Date(2022, 9, 10) // 2022-10-10
await wrapper.setProps({ modelValue: testDate })

expect(wrapper.find(currentDateClass).text()).toBe('10')

wrapper.unmount()
})

it('slots', async () => {
const wrapper = shallowMount(Calendar, {
const wrapper = mount(Calendar, {
props: { modelValue: new Date() },
slots: {
dateCell: `<template #dateCell="{isSelected, date, day}">
{{isSelected ? '当前选中日期' : day}}
</template>`,
},
global: {
components: {
CButton: Button,
},
},
})

// slot 元素正确加载
Expand All @@ -55,8 +73,13 @@ describe('button', () => {
})

it('event', async () => {
const wrapper = shallowMount(Calendar, {
const wrapper = mount(Calendar, {
props: { modelValue: new Date() },
global: {
components: {
CButton: Button,
},
},
})

// 断言 change 事件是否正确触发
Expand All @@ -74,4 +97,136 @@ describe('button', () => {

wrapper.unmount()
})

it('switches to next month', async () => {
const testDate = new Date(2022, 9, 10) // 2022-10-10
const expectedNextMonth = '2022-11'

const wrapper = mount(Calendar, {
props: { modelValue: testDate },
global: {
components: {
CButton: Button,
},
},
})

// 点击下个月按钮 (第三个按钮)
const buttons = wrapper.find(headerClass).findAllComponents(Button)
await buttons[2].trigger('click')

// 验证月份是否正确更新
expect(wrapper.find(headerClass).text()).toContain(expectedNextMonth)

wrapper.unmount()
})

it('switches to previous month', async () => {
const testDate = new Date(2022, 9, 10) // 2022-10-10
const expectedPrevMonth = '2022-09'

const wrapper = mount(Calendar, {
props: { modelValue: testDate },
global: {
components: {
CButton: Button,
},
},
})

// 点击上个月按钮 (第一个按钮)
const buttons = wrapper.find(headerClass).findAllComponents(Button)
await buttons[0].trigger('click')

// 验证月份是否正确更新
expect(wrapper.find(headerClass).text()).toContain(expectedPrevMonth)

wrapper.unmount()
})

it('navigates to today', async () => {
const testDate = new Date(2022, 9, 10) // 2022-10-10
const today = new Date()
const todayMonth = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}`

const wrapper = mount(Calendar, {
props: { modelValue: testDate },
global: {
components: {
CButton: Button,
},
},
})

// 点击今天按钮 (第二个按钮)
const buttons = wrapper.find(headerClass).findAllComponents(Button)
await buttons[1].trigger('click')

// 验证月份是否正确更新为当前月份
expect(wrapper.find(headerClass).text()).toContain(todayMonth)

wrapper.unmount()
})

it('highlights current date', async () => {
const today = new Date()
const wrapper = mount(Calendar, {
props: { modelValue: today },
global: {
components: {
CButton: Button,
},
},
})

// 验证当前日期是否有高亮类
expect(wrapper.find(currentDateClass).exists()).toBeTruthy()

wrapper.unmount()
})

it('works in read-only mode', async () => {
const wrapper = mount(Calendar, {
props: {
modelValue: new Date(2022, 9, 10), // 2022-10-10
readOnly: true,
},
global: {
components: {
CButton: Button,
},
},
})

// 验证是否应用了只读属性
expect(wrapper.props().readOnly).toBe(true)

wrapper.unmount()
})

it('renders correct dates for month', async () => {
const testDate = new Date(2022, 9, 10) // 2022-10-10
const wrapper = mount(Calendar, {
props: { modelValue: testDate },
global: {
components: {
CButton: Button,
},
},
})

// 验证10月份有31天
const days = wrapper.findAll(dayClass)
expect(days.length).toBe(42) // 6周 x 7天

// 验证10月1日存在
const firstDay = days.find(day => day.text() === '1')
expect(firstDay).toBeTruthy()

// 验证10月31日存在
const lastDay = days.find(day => day.text() === '31')
expect(lastDay).toBeTruthy()

wrapper.unmount()
})
})
Loading