From a944036e77e126458c930bfaf76ce24859d3db90 Mon Sep 17 00:00:00 2001 From: leejimqiu Date: Sat, 24 Sep 2022 23:49:16 +0800 Subject: [PATCH] feat(calendar): support first-day-of-week property --- src/calendar/calendar.en-US.md | 2 +- src/calendar/calendar.md | 2 +- src/calendar/calendar.vue | 54 +++++++++++++++++++++++----------- src/calendar/demos/base.vue | 2 +- src/calendar/demos/cell.vue | 19 ------------ src/calendar/demos/color.vue | 12 -------- src/calendar/demos/head.vue | 14 --------- src/calendar/demos/value.vue | 13 -------- src/calendar/type.ts | 6 ++-- 9 files changed, 44 insertions(+), 80 deletions(-) delete mode 100644 src/calendar/demos/cell.vue delete mode 100644 src/calendar/demos/color.vue delete mode 100644 src/calendar/demos/head.vue delete mode 100644 src/calendar/demos/value.vue diff --git a/src/calendar/calendar.en-US.md b/src/calendar/calendar.en-US.md index 6c539744b..62860e266 100644 --- a/src/calendar/calendar.en-US.md +++ b/src/calendar/calendar.en-US.md @@ -7,7 +7,7 @@ name | type | default | description | required -- | -- | -- | -- | -- confirmBtn | String / Object / Slot / Function | '' | Typescript:`string | TNode | ButtonProps | null`,[Button API Documents](./button?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts)。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts) | N firstDayOfWeek | Number | 7 | \- | N -format | Function | - | Typescript:`(day: TDate) => TDate` `type TDateType = 'selected' | 'disabled' | 'start' | 'centre' | 'end'; ` `interface TDate { date: Date; day: number; type: TDateType; className: string; }`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts) | N +format | Function | - | Typescript:`(day: TDate) => TDate` `type TDateType = 'selected' | 'disabled' | 'start' | 'centre' | 'end' | ''; ` `interface TDate { date: Date; day: number; type: TDateType; className?: string; prefix?: string; suffix?: string; }`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts) | N maxDate | Number / Date | - | Typescript:`number | Date` | N minDate | Number / Date | - | Typescript:`number | Date` | N title | String / Slot / Function | - | Typescript:`string | TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N diff --git a/src/calendar/calendar.md b/src/calendar/calendar.md index 1a03e90b9..c41d9441e 100644 --- a/src/calendar/calendar.md +++ b/src/calendar/calendar.md @@ -7,7 +7,7 @@ -- | -- | -- | -- | -- confirmBtn | String / Object / Slot / Function | '' | 确认按钮。值为 null 则不显示确认按钮。值类型为字符串,则表示自定义按钮文本,值类型为 Object 则表示透传 Button 组件属性。。TS 类型:`string | TNode | ButtonProps | null`,[Button API Documents](./button?tab=api)。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts) | N firstDayOfWeek | Number | 7 | 第一天从星期几开始,默认周日 | N -format | Function | - | 用于格式化日期的函数。TS 类型:`(day: TDate) => TDate` `type TDateType = 'selected' | 'disabled' | 'start' | 'centre' | 'end'; ` `interface TDate { date: Date; day: number; type: TDateType; className: string; }`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts) | N +format | Function | - | 用于格式化日期的函数。TS 类型:`(day: TDate) => TDate` `type TDateType = 'selected' | 'disabled' | 'start' | 'centre' | 'end' | ''; ` `interface TDate { date: Date; day: number; type: TDateType; className?: string; prefix?: string; suffix?: string; }`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/calendar/type.ts) | N maxDate | Number / Date | - | 最大可选的日期,不传则默认半年后。TS 类型:`number | Date` | N minDate | Number / Date | - | 最小可选的日期,不传则默认今天。TS 类型:`number | Date` | N title | String / Slot / Function | - | 标题,不传默认为“请选择日期”。TS 类型:`string | TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N diff --git a/src/calendar/calendar.vue b/src/calendar/calendar.vue index 10011252f..25b4016fa 100644 --- a/src/calendar/calendar.vue +++ b/src/calendar/calendar.vue @@ -18,10 +18,10 @@ :class="{ [`${name}__dates-item`]: true, [`${name}__dates-item--${dateItem.type}`]: !!dateItem.type, - [`${dateItem.classname ?? ''}`]: true, + [`${dateItem.className ?? ''}`]: true, }" :style="{ - marginLeft: dateIndex === 0 ? `${49 * item.weekdayOfFirstDay}px` : 0, + marginLeft: dateIndex === 0 ? `${49 * ((item.weekdayOfFirstDay - firstDayOfWeek + 7) % 7)}px` : 0, }" @click="handleSelect(item.year, item.month, dateItem.day, dateItem)" > @@ -44,7 +44,11 @@ @@ -57,6 +61,7 @@ import { CloseIcon } from 'tdesign-icons-vue-next'; import config from '../config'; import calendarProps from './props'; +import { TDate, TDateType } from './type'; const { prefix } = config; const name = `${prefix}-calendar`; @@ -82,9 +87,20 @@ const getYearMonthDay = (date: Date) => { const popup = ref(props.visible); const valueRef = ref(props.value); const selectedDate = ref(); - +const firstDayOfWeek = computed(() => props.firstDayOfWeek); const type = computed(() => props.type); -const days = ref(['日', '一', '二', '三', '四', '五', '六']); +const days = computed(() => { + const raw = '日一二三四五六'; + const ans = []; + let i = firstDayOfWeek.value % 7; + + while (ans.length < 7) { + ans.push(raw[i]); + i = (i + 1) % 7; + } + + return ans; +}); const today = new Date(); const minDate = props.minDate ? new Date(props.minDate) : today; const maxDate = props.maxDate @@ -93,11 +109,9 @@ const maxDate = props.maxDate // 获取日期 const getDate = (year: number, month: number, day: number) => new Date(year, month, day); -interface TDateItem { - type: 'selected' | 'disabled' | 'start' | 'centre' | 'end'; -} + // 选择日期 -const handleSelect = (year: number, month: number, date: number, dateItem: TDateItem) => { +const handleSelect = (year: number, month: number, date: number, dateItem: TDate) => { if (dateItem.type === 'disabled') return; const selected = new Date(year, month, date); @@ -114,18 +128,19 @@ const handleSelect = (year: number, month: number, date: number, dateItem: TDate } else { selectedDate.value = selected; } - props.onSelect?.({ value: selectedDate.value }); + props.onSelect?.(selectedDate.value); }; // 确认 const handleConfirm = () => { popup.value = false; - props.onConfirm?.({ value: selectedDate.value }); + props.onConfirm?.(selectedDate.value); }; const getMonthDates = (date: Date) => { const { year, month } = getYearMonthDay(date); const firstDay = getDate(year, month, 1); const weekdayOfFirstDay = firstDay.getDay(); - const lastDate = new Date(+getDate(year, month + 1, 1) - 24 * 3600).getDate(); + const lastDate = new Date(+getDate(year, month + 1, 1) - 24 * 3600 * 1000).getDate(); + console.log(lastDate); return { year, @@ -134,8 +149,8 @@ const getMonthDates = (date: Date) => { lastDate, }; }; -type TDate = Date | number | { year: number; month: number; date: number }; -const isSameDate = (date1: TDate, date2: TDate) => { +type CompareDate = Date | number | { year: number; month: number; date: number }; +const isSameDate = (date1: CompareDate, date2: CompareDate) => { if (date1 instanceof Date) date1 = getYearMonthDay(date1); if (date2 instanceof Date) date2 = getYearMonthDay(date2); const keys = ['year', 'month', 'date']; @@ -146,7 +161,7 @@ const months = computed(() => { const ans = []; let { year: minYear, month: minMonth } = getYearMonthDay(minDate); const { year: maxYear, month: maxMonth } = getYearMonthDay(maxDate); - const calcType = (year: number, month: number, date: number) => { + const calcType = (year: number, month: number, date: number): TDateType => { const curDate = new Date(year, month, date, 23, 59, 59); if (type.value === 'single') { @@ -171,10 +186,10 @@ const months = computed(() => { while (minYear < maxYear || (minYear === maxYear && minMonth <= maxMonth)) { const target = getMonthDates(getDate(minYear, minMonth, 1)); - const months = []; + const months: TDate[] = []; for (let i = 1; i <= 31; i++) { if (i > target.lastDate) break; - const dateObj = { + const dateObj: TDate = { date: getDate(minYear, minMonth, i), day: i, type: calcType(minYear, minMonth, i), @@ -195,6 +210,11 @@ const months = computed(() => { return ans; }); +const confirmBtn = computed(() => { + if (props.confirmBtn === 'string') return { content: props.confirmBtn }; + return props.confirmBtn; +}); + watch( () => props.visible, (val) => { diff --git a/src/calendar/demos/base.vue b/src/calendar/demos/base.vue index 765836139..2a4e3b7a1 100644 --- a/src/calendar/demos/base.vue +++ b/src/calendar/demos/base.vue @@ -8,7 +8,7 @@ diff --git a/src/calendar/demos/color.vue b/src/calendar/demos/color.vue deleted file mode 100644 index 142fd6772..000000000 --- a/src/calendar/demos/color.vue +++ /dev/null @@ -1,12 +0,0 @@ - - - diff --git a/src/calendar/demos/head.vue b/src/calendar/demos/head.vue deleted file mode 100644 index 0ee0a6aa4..000000000 --- a/src/calendar/demos/head.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/src/calendar/demos/value.vue b/src/calendar/demos/value.vue deleted file mode 100644 index 82db1a794..000000000 --- a/src/calendar/demos/value.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - diff --git a/src/calendar/type.ts b/src/calendar/type.ts index 6c31b04a9..30e9aa6bc 100644 --- a/src/calendar/type.ts +++ b/src/calendar/type.ts @@ -58,13 +58,15 @@ export interface TdCalendarProps { onSelect?: (value: Date) => void; } -export type TDateType = 'selected' | 'disabled' | 'start' | 'centre' | 'end'; +export type TDateType = 'selected' | 'disabled' | 'start' | 'centre' | 'end' | ''; export interface TDate { date: Date; day: number; type: TDateType; - className: string; + className?: string; + prefix?: string; + suffix?: string; } export type TCalendarValue = number | Date;