diff --git a/docs/zh-CN/components/calendar.md b/docs/zh-CN/components/calendar.md index 3faeb5abd..6fd96cb89 100644 --- a/docs/zh-CN/components/calendar.md +++ b/docs/zh-CN/components/calendar.md @@ -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` | `['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` | | 今日激活时的自定义样式 | ## 事件表 diff --git a/packages/amis-ui/src/components/DatePicker.tsx b/packages/amis-ui/src/components/DatePicker.tsx index 025241483..035d1d627 100644 --- a/packages/amis-ui/src/components/DatePicker.tsx +++ b/packages/amis-ui/src/components/DatePicker.tsx @@ -288,6 +288,7 @@ export interface DateProps extends LocaleProps, ThemeProps { }>; scheduleClassNames?: Array; largeMode?: boolean; + todayActiveStyle?: React.CSSProperties; onScheduleClick?: (scheduleData: any) => void; useMobileUI?: boolean; // 在移动端日期展示有多种形式,一种是picker 滑动选择,一种是日历展开选择,mobileCalendarMode为calendar表示日历展开选择 @@ -665,6 +666,7 @@ export class DatePicker extends React.Component { schedules, largeMode, scheduleClassNames, + todayActiveStyle, onScheduleClick, mobileCalendarMode, label @@ -754,6 +756,7 @@ export class DatePicker extends React.Component { // utc={utc} schedules={schedulesData} largeMode={largeMode} + todayActiveStyle={todayActiveStyle} onScheduleClick={onScheduleClick} embed={embed} useMobileUI={useMobileUI} diff --git a/packages/amis-ui/src/components/DateRangePicker.tsx b/packages/amis-ui/src/components/DateRangePicker.tsx index fcfe6b4aa..2545733f9 100644 --- a/packages/amis-ui/src/components/DateRangePicker.tsx +++ b/packages/amis-ui/src/components/DateRangePicker.tsx @@ -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 ( diff --git a/packages/amis-ui/src/components/calendar/Calendar.tsx b/packages/amis-ui/src/components/calendar/Calendar.tsx index 27f5024b5..d03d09538 100644 --- a/packages/amis-ui/src/components/calendar/Calendar.tsx +++ b/packages/amis-ui/src/components/calendar/Calendar.tsx @@ -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' : '' )} diff --git a/packages/amis-ui/src/components/calendar/DaysView.tsx b/packages/amis-ui/src/components/calendar/DaysView.tsx index a0d7580bb..e3a251952 100644 --- a/packages/amis-ui/src/components/calendar/DaysView.tsx +++ b/packages/amis-ui/src/components/calendar/DaysView.tsx @@ -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 { 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 { 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 { }; 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 { } }); 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 { ); return (
{ ); }); return ( - +
{currentDate.date()} @@ -486,8 +513,8 @@ export class CustomDaysView extends React.Component { > ); return ( - - + + {currentDate.date()} {ScheduleIcon} @@ -495,9 +522,12 @@ export class CustomDaysView extends React.Component { ); } } + return ( - - {currentDate.date()} + + + {currentDate.date()} + ); }; diff --git a/packages/amis/src/renderers/Calendar.tsx b/packages/amis/src/renderers/Calendar.tsx index 20d4e72f2..01ae274b4 100644 --- a/packages/amis/src/renderers/Calendar.tsx +++ b/packages/amis/src/renderers/Calendar.tsx @@ -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({