Skip to content

Commit

Permalink
Feat calendar range (#1256)
Browse files Browse the repository at this point in the history
* feat: 日历只展示传入范围内的日期

* feat: 日历只展示传入范围内的日期

* feat: 日历只展示传入范围内的日期
  • Loading branch information
rayhomie authored Aug 2, 2024
1 parent 18715c6 commit d8e1dd1
Show file tree
Hide file tree
Showing 28 changed files with 253 additions and 89 deletions.
1 change: 1 addition & 0 deletions compiled/alipay/demo/pages/Calendar/index.axml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
<view slot="content">
<ant-calendar
monthRange="{{demo8.monthRange}}"
showSelectableDatesOnly
onFormatter="{{demo8Formatter ? demo8Formatter : 'demo8Formatter'}}"
onMonthFormatter="{{demo8MonthFormatter ? demo8MonthFormatter : 'demo8MonthFormatter'}}"
></ant-calendar>
Expand Down
5 changes: 1 addition & 4 deletions compiled/alipay/demo/pages/Calendar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ function demo8Formatter(cell) {
topClassName = isOdd ? 'odd' : 'even';
}
return {
className: dayjs(cell.time).isAfter(dayjs().add(1, 'M'), 'd')
? 'hidden'
: '',
top: {
className: topClassName,
label: isOdd ? '奇数' : '偶数',
Expand All @@ -30,7 +27,7 @@ function demo8Formatter(cell) {
}
function demo8MonthFormatter(month) {
return {
className: dayjs(month).isAfter(dayjs()) ? 'shrink' : '',
...month,
};
}
function demoFormatter(cell, value) {
Expand Down
33 changes: 29 additions & 4 deletions compiled/alipay/src/Calendar/helper.sjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ function keys(obj) {
return Object.keys(obj);
}
}
function getClassName(value, index) {
function getClassName(value, index, showSelectableDatesOnly) {
var isSelected = value.isSelected,
isSelectedBegin = value.isSelectedBegin,
isSelectedEnd = value.isSelectedEnd,
Expand All @@ -12,7 +12,8 @@ function getClassName(value, index) {
inThisMonth = value.inThisMonth,
isToday = value.isToday,
disabled = value.disabled,
className = value.className;
className = value.className,
isRange = value.isRange;
var classNames = {
disabled: disabled,
today: inThisMonth && isToday,
Expand All @@ -21,7 +22,7 @@ function getClassName(value, index) {
'selected-end': inThisMonth && isSelectedEnd,
'selected-row-begin': inThisMonth && isRowBegin && isSelected,
'selected-row-end': inThisMonth && isRowEnd && isSelected,
hidden: !inThisMonth,
hidden: !inThisMonth || showSelectableDatesOnly && !isRange,
'row-end': index % 7 === 6
};
var result = "ant-calendar-cell ".concat(className || '');
Expand Down Expand Up @@ -54,8 +55,32 @@ function getMarkCellClassName(index, items) {
}
return 'ant-calendar-mark-cell';
}
function isDisplay(index, items) {
// 找到需要当前月需要展示的日期最大最小索引
var _items$reduce = items.reduce(function (res, item) {
// !item.inThisMonth 被隐藏掉的日期
// !item.isRange 不在传入范围内的日期
if (!(!item.inThisMonth || !item.isRange)) {
if (res.minIndex === null || res.maxIndex === null) {
res.minIndex = item.index;
res.maxIndex = item.index;
}
res.minIndex = Math.min(res.minIndex, item.index);
res.maxIndex = Math.max(res.maxIndex, item.index);
}
return res;
}, {
minIndex: null,
maxIndex: null
}),
minIndex = _items$reduce.minIndex,
maxIndex = _items$reduce.maxIndex;
if (maxIndex === null || maxIndex === null) return true;
return index >= Math.floor(minIndex / 7) * 7 && index < Math.ceil(maxIndex / 7) * 7;
}
export default {
getSpaceClassName: getSpaceClassName,
getClassName: getClassName,
getMarkCellClassName: getMarkCellClassName
getMarkCellClassName: getMarkCellClassName,
isDisplay: isDisplay
};
9 changes: 6 additions & 3 deletions compiled/alipay/src/Calendar/index.axml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@
a:for-index="index"
a:for-item="currentMonth"
>
<view class="ant-calendar-body-container {{currentMonth.className || ''}}">
<view
class="ant-calendar-body-container {{currentMonth.className || ''}}"
style="{{currentMonth.style || ''}}"
>
<view class="ant-calendar-title-container">
<slot name="calendarTitle">
<view class="ant-calendar-title">{{currentMonth.title}}</view>
Expand All @@ -64,9 +67,9 @@
a:for-index="index"
a:for-item="item"
>
<block>
<block a:if="{{helper.isDisplay(index, currentMonth.cells)}}">
<view
class="{{helper.getClassName(item, index)}}"
class="{{helper.getClassName(item, index, showSelectableDatesOnly)}}"
id="id_{{item.time}}"
data-time="{{item}}"
onTap="clickCell"
Expand Down
1 change: 1 addition & 0 deletions compiled/alipay/src/Calendar/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -170,5 +170,6 @@

&-cell-hidden {
opacity: 0;
pointer-events: none;
}
}
25 changes: 13 additions & 12 deletions compiled/alipay/src/Calendar/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,19 @@ toc: 'content'

以下为日历组件的属性及描述:

| 属性 | 说明 | 类型 | 默认值 |
| --------------------- | ---------------------------------------------- | ----------------------------------------------------------- | ----------- |
| defaultValue | 初始值 | CalendarValue ||
| value | 日历选择的日期,传入后即为受控模式 | CalendarValue ||
| selectionMode | 设置选择模式,单选或者连续区间,默认为 `range` | `single` \| `range` | `range` |
| monthRange | 月份范围,默认为最近 3 个月 | `[number, number]` | 最近 3 个月 |
| weekStartsOn | 星期栏,以周几作为第一天显示。默认为 `Sunday` | `Sunday` \| `Monday` | `Sunday` |
| onChange | 日期变化回调 | (date: CalendarValue) => void ||
| onFormatter | 用于设置单元格的自定义数据 | (cell: CellState, currentValue: CalendarValue) => CellState ||
| onMonthFormatter | 用于设置月份的自定义数据 | (month: any) => CellState ||
| localeText | 国际化文案 | Partial`<LocaleText>` ||
| changedScrollIntoView | 选中值改变后是否滚动视图 | boolean ||
| 属性 | 说明 | 类型 | 默认值 |
| ----------------------- | ---------------------------------------------- | ----------------------------------------------------------- | ----------- |
| defaultValue | 初始值 | CalendarValue ||
| value | 日历选择的日期,传入后即为受控模式 | CalendarValue ||
| selectionMode | 设置选择模式,单选或者连续区间,默认为 `range` | `single` \| `range` | `range` |
| monthRange | 月份范围,默认为最近 3 个月 | `[number, number]` | 最近 3 个月 |
| weekStartsOn | 星期栏,以周几作为第一天显示。默认为 `Sunday` | `Sunday` \| `Monday` | `Sunday` |
| onChange | 日期变化回调 | (date: CalendarValue) => void ||
| onFormatter | 用于设置单元格的自定义数据 | (cell: CellState, currentValue: CalendarValue) => CellState ||
| onMonthFormatter | 用于设置月份的自定义数据 | (month: any) => CellState ||
| localeText | 国际化文案 | Partial`<LocaleText>` ||
| changedScrollIntoView | 选中值改变后是否滚动视图 | boolean ||
| showSelectableDatesOnly | 只展示在可选范围内的日期 | boolean | false |

### 类型

Expand Down
21 changes: 16 additions & 5 deletions compiled/alipay/src/Calendar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,20 @@ Component(
if (item) markItems.unshift(item);
}
const value = this.getValue();
const monthList = getMonthListFromRange(
dayjs(monthRange?.[0]),
dayjs(monthRange?.[1])
).map((p) => {
let cells = renderCells(p, weekStartsOn, value, localeText);
const start = dayjs(monthRange?.[0]).startOf('d');
const end = dayjs(monthRange?.[1]).startOf('d');
const monthRangeList = getMonthListFromRange(start, end);
const monthList = monthRangeList.map((p) => {
let cells = renderCells(
p,
weekStartsOn,
value,
localeText,
// 如果monthRange传入异常,用内置的时间范围
start.isAfter(end) || start.isSame(end)
? [monthRangeList[0], dayjs(monthRangeList[1]).endOf('month')]
: [start, end]
);
if (onFormatter && typeof onFormatter === 'function') {
cells = cells.map((o): CellState => {
const {
Expand All @@ -153,6 +162,7 @@ Component(
isSelectedEnd,
isSelected,
className,
isRange,
} = o;
const newState =
onFormatter(
Expand All @@ -165,6 +175,7 @@ Component(
isSelectedEnd,
isSelected,
className,
isRange,
},
value
) ?? {};
Expand Down
10 changes: 10 additions & 0 deletions compiled/alipay/src/Calendar/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ export interface CellState {
isRowBegin: boolean;
isRowEnd: boolean;
inThisMonth: boolean;
/**
* 是否在传入范围内
*/
isRange: boolean;
index: number;
}

export type CalendarValue = number | number[];
Expand Down Expand Up @@ -123,6 +128,10 @@ export interface ICalendarProps extends IBaseProps {
* 选中值改变后滚动视图
*/
changedScrollIntoView?: boolean;
/**
* 只展示在可选范围内的日期
*/
showSelectableDatesOnly?: boolean;
/**
* 日期变化回调
*/
Expand Down Expand Up @@ -165,4 +174,5 @@ export const CalendarDefaultProps = {
onFormatter: null,
onMonthFormatter: null,
changedScrollIntoView: null,
showSelectableDatesOnly: false,
};
17 changes: 14 additions & 3 deletions compiled/alipay/src/Calendar/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ export function renderCells(
cellsMonth: Dayjs,
weekStartsOn: string,
value: CalendarValue,
localeText: LocaleText
localeText: LocaleText,
monthRangeList: Dayjs[]
): CellState[] {
const [rangeStartDate, rangeEndDate] = monthRangeList;

let rowBeginDay = 0;
let rowEndDay = 6;
if (weekStartsOn === 'Monday') {
Expand All @@ -64,7 +67,7 @@ export function renderCells(
}
const dates = getDate(cellsMonth, weekStartsOn);
if (!value) {
return dates.map((d): CellState => {
return dates.map((d, index): CellState => {
const isToday = dayjs().isSame(d, 'day');
const isRowBegin =
d.isSame(cellsMonth.startOf('month'), 'date') ||
Expand All @@ -80,6 +83,7 @@ export function renderCells(
}

return {
index,
disabled: false,
time: d.toDate().getTime(),
date: d.get('date'),
Expand All @@ -90,6 +94,9 @@ export function renderCells(
inThisMonth: d.month() === cellsMonth.month(),
isRowBegin,
isRowEnd,
isRange:
(d.isSame(rangeStartDate) || d.isAfter(rangeStartDate)) &&
(d.isSame(rangeEndDate) || d.isBefore(rangeEndDate)),
};
});
}
Expand All @@ -105,7 +112,7 @@ export function renderCells(
selectEnd = dayjs(value);
}

return dates.map((d): CellState => {
return dates.map((d, index): CellState => {
const isToday = dayjs().isSame(d, 'day');
const isRowBegin =
d.isSame(cellsMonth.startOf('month'), 'date') || d.day() === rowBeginDay;
Expand Down Expand Up @@ -136,6 +143,7 @@ export function renderCells(
}

return {
index,
disabled: false,
time,
date: d.get('date'),
Expand All @@ -146,6 +154,9 @@ export function renderCells(
inThisMonth,
isRowBegin,
isRowEnd,
isRange:
(d.isSame(rangeStartDate) || d.isAfter(rangeStartDate)) &&
(d.isSame(rangeEndDate) || d.isBefore(rangeEndDate)),
};
});
}
Expand Down
5 changes: 1 addition & 4 deletions compiled/wechat/demo/pages/Calendar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ function demo8Formatter(cell) {
topClassName = isOdd ? 'odd' : 'even';
}
return {
className: dayjs(cell.time).isAfter(dayjs().add(1, 'M'), 'd')
? 'hidden'
: '',
top: {
className: topClassName,
label: isOdd ? '奇数' : '偶数',
Expand All @@ -30,7 +27,7 @@ function demo8Formatter(cell) {
}
function demo8MonthFormatter(month) {
return {
className: dayjs(month).isAfter(dayjs()) ? 'shrink' : '',
...month,
};
}
function demoFormatter(cell, value) {
Expand Down
1 change: 1 addition & 0 deletions compiled/wechat/demo/pages/Calendar/index.wxml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
<view slot="content">
<ant-calendar
monthRange="{{demo8.monthRange}}"
showSelectableDatesOnly
onFormatter="{{demo8Formatter ? demo8Formatter : 'demo8Formatter'}}"
onMonthFormatter="{{demo8MonthFormatter ? demo8MonthFormatter : 'demo8MonthFormatter'}}"
></ant-calendar>
Expand Down
33 changes: 29 additions & 4 deletions compiled/wechat/src/Calendar/helper.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ function keys(obj) {
return item.split(':')[0];
});
}
function getClassName(value, index) {
function getClassName(value, index, showSelectableDatesOnly) {
var isSelected = value.isSelected,
isSelectedBegin = value.isSelectedBegin,
isSelectedEnd = value.isSelectedEnd,
Expand All @@ -12,7 +12,8 @@ function getClassName(value, index) {
inThisMonth = value.inThisMonth,
isToday = value.isToday,
disabled = value.disabled,
className = value.className;
className = value.className,
isRange = value.isRange;
var classNames = {
disabled: disabled,
today: inThisMonth && isToday,
Expand All @@ -21,7 +22,7 @@ function getClassName(value, index) {
'selected-end': inThisMonth && isSelectedEnd,
'selected-row-begin': inThisMonth && isRowBegin && isSelected,
'selected-row-end': inThisMonth && isRowEnd && isSelected,
hidden: !inThisMonth,
hidden: !inThisMonth || showSelectableDatesOnly && !isRange,
'row-end': index % 7 === 6
};
var result = "ant-calendar-cell ".concat(className || '');
Expand Down Expand Up @@ -54,8 +55,32 @@ function getMarkCellClassName(index, items) {
}
return 'ant-calendar-mark-cell';
}
function isDisplay(index, items) {
// 找到需要当前月需要展示的日期最大最小索引
var _items$reduce = items.reduce(function (res, item) {
// !item.inThisMonth 被隐藏掉的日期
// !item.isRange 不在传入范围内的日期
if (!(!item.inThisMonth || !item.isRange)) {
if (res.minIndex === null || res.maxIndex === null) {
res.minIndex = item.index;
res.maxIndex = item.index;
}
res.minIndex = Math.min(res.minIndex, item.index);
res.maxIndex = Math.max(res.maxIndex, item.index);
}
return res;
}, {
minIndex: null,
maxIndex: null
}),
minIndex = _items$reduce.minIndex,
maxIndex = _items$reduce.maxIndex;
if (maxIndex === null || maxIndex === null) return true;
return index >= Math.floor(minIndex / 7) * 7 && index < Math.ceil(maxIndex / 7) * 7;
}
module.exports = {
getSpaceClassName: getSpaceClassName,
getClassName: getClassName,
getMarkCellClassName: getMarkCellClassName
getMarkCellClassName: getMarkCellClassName,
isDisplay: isDisplay
};
Loading

0 comments on commit d8e1dd1

Please sign in to comment.