Skip to content

Commit

Permalink
feat(calendar): support first-day-of-week property
Browse files Browse the repository at this point in the history
  • Loading branch information
LeeJim committed Sep 24, 2022
1 parent cb8763f commit a944036
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 80 deletions.
2 changes: 1 addition & 1 deletion src/calendar/calendar.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/calendar/calendar.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
54 changes: 37 additions & 17 deletions src/calendar/calendar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
>
Expand All @@ -44,7 +44,11 @@
</template>
</div>
<div class="t-calendar__footer">
<t-button block theme="primary" @click="handleConfirm">{{ confirmBtn }}</t-button>
<slot name="confirmBtn">
<template v-if="confirmBtn">
<t-button v-bind="confirmBtn" block theme="primary" @click="handleConfirm" />
</template>
</slot>
</div>
</div>
</t-popup>
Expand All @@ -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`;
Expand All @@ -82,9 +87,20 @@ const getYearMonthDay = (date: Date) => {
const popup = ref<boolean>(props.visible);
const valueRef = ref(props.value);
const selectedDate = ref();
const firstDayOfWeek = computed(() => props.firstDayOfWeek);
const type = computed(() => props.type);
const days = ref<string[]>(['日', '一', '二', '三', '四', '五', '六']);
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
Expand All @@ -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);
Expand All @@ -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,
Expand All @@ -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'];
Expand All @@ -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') {
Expand All @@ -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),
Expand All @@ -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) => {
Expand Down
2 changes: 1 addition & 1 deletion src/calendar/demos/base.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<script lang="ts" setup>
import { ref } from 'vue';
const visible = ref(false);
const visible = ref(true);
const handleConfirm = (val: string) => {
console.log(val);
};
Expand Down
19 changes: 0 additions & 19 deletions src/calendar/demos/cell.vue

This file was deleted.

12 changes: 0 additions & 12 deletions src/calendar/demos/color.vue

This file was deleted.

14 changes: 0 additions & 14 deletions src/calendar/demos/head.vue

This file was deleted.

13 changes: 0 additions & 13 deletions src/calendar/demos/value.vue

This file was deleted.

6 changes: 4 additions & 2 deletions src/calendar/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

0 comments on commit a944036

Please sign in to comment.