feat: Calendar组件今日高亮样式支持自定义 (#5186)

This commit is contained in:
RUNZE LU 2022-08-19 15:36:02 +08:00 committed by GitHub
parent 9077668616
commit 07a4fea5e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 34 deletions

View File

@ -54,26 +54,6 @@ order: 36
}
```
```schema: scope="body"
{
"type": "calendar",
"value": "1638288000",
"scheduleClassNames": ["bg-success", "bg-info"],
"schedules": [
{
"startTime": "2021-12-11 05:14:00",
"endTime": "2021-12-11 06:14:00",
"content": "这是一个日程1"
},
{
"startTime": "2021-12-21 05:14:00",
"endTime": "2021-12-22 05:14:00",
"content": "这是一个日程2"
}
]
}
```
## 自定义日程展示
```schema: scope="body"
@ -191,6 +171,35 @@ order: 36
}
```
## 今日高亮样式自定义
> 2.1.1 及以上版本
```schema: scope="body"
{
"type": "calendar",
"value": "NOW()",
"todayActiveStyle": {
"backgroundColor": "#ef4444 !important",
"color": "#f8f9fa",
"border": "none",
"borderRadius": "15px"
},
"schedules": [
{
"startTime": "2021-12-11 05:14:00",
"endTime": "2021-12-11 06:14:00",
"content": "这是一个日程1"
},
{
"startTime": "2021-12-21 05:14:00",
"endTime": "2021-12-22 05:14:00",
"content": "这是一个日程2"
}
]
}
```
## Calendar 属性表
| 属性名 | 类型 | 默认值 | 说明 |
@ -200,6 +209,7 @@ order: 36
| scheduleClassNames | `Array<string>` | `['bg-warning', 'bg-danger', 'bg-success', 'bg-info', 'bg-secondary']` | 日历中展示日程的颜色,参考[背景色](https://baidu.gitee.io/amis/zh-CN/style/background/background-color) |
| scheduleAction | `SchemaNode` | | 自定义日程展示 |
| largeMode | `boolean` | `false` | 放大模式 |
| todayActiveStyle | `Record<string, any>` | | 今日激活时的自定义样式 |
## 事件表

View File

@ -288,6 +288,7 @@ export interface DateProps extends LocaleProps, ThemeProps {
}>;
scheduleClassNames?: Array<string>;
largeMode?: boolean;
todayActiveStyle?: React.CSSProperties;
onScheduleClick?: (scheduleData: any) => void;
useMobileUI?: boolean;
// 在移动端日期展示有多种形式一种是picker 滑动选择一种是日历展开选择mobileCalendarMode为calendar表示日历展开选择
@ -665,6 +666,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
schedules,
largeMode,
scheduleClassNames,
todayActiveStyle,
onScheduleClick,
mobileCalendarMode,
label
@ -754,6 +756,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
// utc={utc}
schedules={schedulesData}
largeMode={largeMode}
todayActiveStyle={todayActiveStyle}
onScheduleClick={onScheduleClick}
embed={embed}
useMobileUI={useMobileUI}

View File

@ -6,6 +6,7 @@
import React from 'react';
import moment from 'moment';
import omit from 'lodash/omit';
import {findDOMNode} from 'react-dom';
import {Icon} from './icons';
import {Overlay} from 'amis-core';
@ -1166,6 +1167,7 @@ export class DateRangePicker extends React.Component<
renderDay(props: any, currentDate: moment.Moment) {
let {startDate, endDate} = this.state;
// 剔除掉 DaysView 中传递的参数
props = omit(props, ['todayActiveStyle']);
props.className = props.className.replace('rdtActive', '');
if (

View File

@ -89,6 +89,7 @@ interface BaseDatePickerProps {
color?: string;
}>;
largeMode?: boolean;
todayActiveStyle?: React.CSSProperties;
onScheduleClick?: (scheduleData: any) => void;
hideHeader?: boolean;
updateOn?: string;
@ -410,6 +411,7 @@ class BaseDatePicker extends React.Component<
'maxDate',
'schedules',
'largeMode',
'todayActiveStyle',
'onScheduleClick',
'hideHeader',
'updateOn',
@ -693,7 +695,9 @@ class BaseDatePicker extends React.Component<
: dateFormat && !timeFormat
? 'rdtPickerDate'
: '',
viewMode === 'months' || viewMode === 'years' || viewMode === 'quarters'
viewMode === 'months' ||
viewMode === 'years' ||
viewMode === 'quarters'
? 'rdtPickerNotDays'
: ''
)}

View File

@ -4,7 +4,11 @@ import moment from 'moment';
import React from 'react';
import Downshift from 'downshift';
import findIndex from 'lodash/findIndex';
import extend from 'lodash/extend';
import merge from 'lodash/merge';
import omit from 'lodash/omit';
import each from 'lodash/each';
import kebabCase from 'lodash/kebabCase';
import {
LocaleProps,
localeable,
@ -70,6 +74,7 @@ interface CustomDaysViewProps extends LocaleProps {
className?: string;
}>;
largeMode?: boolean;
todayActiveStyle?: React.CSSProperties;
onScheduleClick?: (scheduleData: any) => void;
hideHeader?: boolean;
getColumns: (types: DateType[], dateBoundary: void) => any;
@ -138,6 +143,7 @@ export class CustomDaysView extends React.Component<CustomDaysViewProps> {
isDisabled,
dayProps,
currentDate;
const {todayActiveStyle = {}} = this.props;
// Go to the last week of the previous month
prevMonth.date(prevMonth.daysInMonth()).startOf('week');
@ -168,11 +174,14 @@ export class CustomDaysView extends React.Component<CustomDaysViewProps> {
isDisabled = !isValid(currentDate, selected);
if (isDisabled) classes += ' rdtDisabled';
dayProps = {
'key': prevMonth.format('M_D'),
'data-value': prevMonth.date(),
'className': classes
};
dayProps = extend(
{
'key': prevMonth.format('M_D'),
'data-value': prevMonth.date(),
'className': classes
},
classes.includes('rdtToday') ? {todayActiveStyle} : {}
);
if (!isDisabled) (dayProps as any).onClick = this.updateSelectedDate;
@ -348,6 +357,26 @@ export class CustomDaysView extends React.Component<CustomDaysViewProps> {
};
renderDay = (props: any, currentDate: moment.Moment) => {
const {todayActiveStyle} = props; /** 只有today才会传入这个属性 */
const {classnames: cx, translate: __} = this.props;
const injectedProps = omit(props, ['todayActiveStyle']);
/** 某些情况下需要用inline style覆盖动态class需要hack important的样式 */
const todayDomRef = (node: HTMLSpanElement | null) => {
if (todayActiveStyle && node) {
each(todayActiveStyle, (value, key) => {
if (typeof value === 'string' && !!~value.indexOf('!important')) {
node?.style?.setProperty?.(
kebabCase(key),
String(value)
.replace(/\!important/, '')
.trim(),
'important'
);
}
});
}
};
if (this.props.schedules) {
let schedule: any[] = [];
this.props.schedules.forEach((item: any) => {
@ -361,8 +390,6 @@ export class CustomDaysView extends React.Component<CustomDaysViewProps> {
}
});
if (schedule.length > 0) {
const cx = this.props.classnames;
const __ = this.props.translate;
// 日程数据
const scheduleData = {
scheduleData: schedule.map((item: any) => {
@ -441,7 +468,7 @@ export class CustomDaysView extends React.Component<CustomDaysViewProps> {
);
return (
<div
key={props.key + 'content' + index}
key={injectedProps.key + 'content' + index}
className={cx(
'ScheduleCalendar-large-schedule-content',
item.className
@ -459,7 +486,7 @@ export class CustomDaysView extends React.Component<CustomDaysViewProps> {
);
});
return (
<td {...props}>
<td {...injectedProps}>
<div className={cx('ScheduleCalendar-large-day-wrap')}>
<div className={cx('ScheduleCalendar-large-schedule-header')}>
<span>{currentDate.date()}</span>
@ -486,8 +513,8 @@ export class CustomDaysView extends React.Component<CustomDaysViewProps> {
></span>
);
return (
<td {...props}>
<span>
<td {...injectedProps}>
<span style={todayActiveStyle} ref={todayDomRef}>
{currentDate.date()}
{ScheduleIcon}
</span>
@ -495,9 +522,12 @@ export class CustomDaysView extends React.Component<CustomDaysViewProps> {
);
}
}
return (
<td {...props}>
<span>{currentDate.date()}</span>
<td {...injectedProps}>
<span style={todayActiveStyle} ref={todayDomRef}>
{currentDate.date()}
</span>
</td>
);
};

View File

@ -2,6 +2,7 @@ import React from 'react';
import {Renderer} from 'amis-core';
import {SchemaObject, BaseSchema} from '../Schema';
import {DateControlRenderer} from './Form/InputDate';
import type {SchemaClassName} from 'amis-core';
interface scheduleItem {
startTime: string;
@ -30,6 +31,18 @@ export interface CalendarSchema extends BaseSchema {
*
*/
scheduleAction?: SchemaObject;
/**
*
*/
largeMode?: boolean;
/**
*
*/
todayActiveStyle?: {
[propName: string]: any;
};
}
@Renderer({