Skip to content

Commit

Permalink
feat: calendar组件支持配置面板 & 支持click,hover事件 (#8518)
Browse files Browse the repository at this point in the history
  • Loading branch information
chengjinyang0 committed Nov 3, 2023
1 parent b91704e commit 8af9fe5
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 8 deletions.
9 changes: 6 additions & 3 deletions docs/zh-CN/components/calendar.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,12 @@ order: 36

当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`${事件参数名}`来获取事件产生的数据(`< 2.3.2 及以下版本 为 ${event.data.[事件参数名]}`),详细请查看[事件动作](../../docs/concepts/event-action)

| 事件名称 | 事件参数 | 说明 |
| -------- | ------------------------ | ---------------- |
| change | `value: string` 组件的值 | 时间值变化时触发 |
| 事件名称 | 事件参数 | 说明 |
| ---------- | ------------------------ | ------------------ |
| change | `value: string` 组件的值 | 时间值变化时触发 |
| click | `value: string` 组件的值 | 点击日期时触发 |
| mouseenter | `value: string` 组件的值 | 鼠标移入日期时触发 |
| mouseleave | `value: string` 组件的值 | 鼠标移出日期时触发 |

## 动作表

Expand Down
195 changes: 195 additions & 0 deletions packages/amis-editor/src/plugin/Calendar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import {registerEditorPlugin, RendererPluginEvent} from 'amis-editor-core';
import {BaseEventContext, BasePlugin, tipedLabel} from 'amis-editor-core';
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
import {getEventControlConfig} from '../renderer/event-control';
import {FormulaDateType} from '../renderer/FormulaControl';
import type {Schema} from 'amis';

export class CalendarPlugin extends BasePlugin {
static id = 'CalendarPlugin';
// 关联渲染器名字
rendererName = 'calendar';
$schema = '/schemas/Calendar.json';

// 组件名称
name = '日历日程';
isBaseComponent = true;
icon = 'fa fa-calendar';
pluginIcon = 'inputDatetime';

panelTitle = '日历日程';

description = '展示日历及日程。';
docLink = '/amis/zh-CN/components/calendor';
tags = ['展示'];

scaffold = {
type: 'page',
body: {
type: 'calendar',
value: ''
}
};
previewSchema = {
...this.scaffold
};

// 事件定义
events: RendererPluginEvent[] = [
{
eventName: 'change',
eventLabel: '值变化',
description: '时间值变化时触发',
dataSchema: [
{
type: 'object',
properties: {
data: {
type: 'object',
title: '数据',
properties: {
value: {
type: 'string',
title: '当前日期'
}
}
}
}
}
]
},
{
eventName: 'click',
eventLabel: '点击',
description: '点击时触发',
dataSchema: [
{
type: 'object',
properties: {
data: {
type: 'object',
title: '数据',
properties: {
value: {
type: 'string',
title: '当前日期'
}
}
}
}
}
]
},
{
eventName: 'mouseenter',
eventLabel: '鼠标移入',
description: '鼠标移入时触发',
dataSchema: [
{
type: 'object',
properties: {
data: {
type: 'object',
title: '数据',
properties: {
value: {
type: 'string',
title: '当前日期'
}
}
}
}
}
]
},
{
eventName: 'mouseleave',
eventLabel: '鼠标移出',
description: '鼠标移出时触发',
dataSchema: [
{
type: 'object',
properties: {
data: {
type: 'object',
title: '数据',
properties: {
value: {
type: 'string',
title: '当前日期'
}
}
}
}
}
]
}
];

actions = [
{
actionType: 'clear',
actionLabel: '清空',
description: '清空'
},
{
actionType: 'reset',
actionLabel: '重置',
description: '将值重置为resetValue,若没有配置resetValue,则清空'
},
{
actionType: 'setValue',
actionLabel: '赋值',
description: '触发组件数据更新'
}
];

panelJustify = true;
panelBodyCreator = (context: BaseEventContext) => {
return [
getSchemaTpl('tabs', [
{
title: '属性',
body: getSchemaTpl('collapseGroup', [
{
title: '基本',
body: [
getSchemaTpl('valueFormula', {
rendererSchema: {
type: 'input-date'
},
placeholder: '请选择静态值',
header: '表达式或相对值',
DateTimeType: FormulaDateType.IsDate,
label: '默认值'
})
]
},
getSchemaTpl('status')
])
},

{
title: '外观',
body: getSchemaTpl('collapseGroup', [
getSchemaTpl('style:classNames', {
isFormItem: false
})
])
},
{
title: '事件',
className: 'p-none',
body: [
getSchemaTpl('eventControl', {
name: 'onEvent',
...getEventControlConfig(this.manager, context)
})
]
}
])
];
};
}

registerEditorPlugin(CalendarPlugin);
1 change: 1 addition & 0 deletions packages/amis-editor/src/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export * from './Images'; // 图片集
export * from './Time'; // 时间展示
export * from './Date'; // 日期展示
export * from './Datetime'; // 日期时间展示
export * from './Calendar'; // 日历日程展示
export * from './Tag'; // 标签
export * from './Json'; // JSON展示
export * from './Progress'; // 进度展示
Expand Down
17 changes: 16 additions & 1 deletion packages/amis-ui/src/components/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ export interface DateProps extends LocaleProps, ThemeProps {
isEndDate?: boolean;

disabledDate?: (date: moment.Moment) => any;
onClick?: (date: moment.Moment) => any;
onMouseEnter?: (date: moment.Moment) => any;
onMouseLeave?: (date: moment.Moment) => any;
}

export interface DatePickerState {
Expand Down Expand Up @@ -844,7 +847,10 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
onScheduleClick,
mobileCalendarMode,
label,
env
env,
onClick,
onMouseEnter,
onMouseLeave
} = this.props;

const __ = this.props.translate;
Expand Down Expand Up @@ -937,6 +943,9 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
embed={embed}
mobileUI={mobileUI}
isEndDate={isEndDate}
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
/>
</div>
);
Expand Down Expand Up @@ -1027,6 +1036,9 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
maxDate={maxDate}
mobileUI={mobileUI}
isEndDate={isEndDate}
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
// utc={utc}
/>
</PopOver>
Expand Down Expand Up @@ -1066,6 +1078,9 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
minDate={minDate}
maxDate={maxDate}
mobileUI={mobileUI}
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
// utc={utc}
/>
</PopUp>
Expand Down
35 changes: 32 additions & 3 deletions packages/amis-ui/src/components/calendar/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ interface BaseDatePickerProps {
) => boolean;
onViewModeChange?: (type: string) => void;
requiredConfirm?: boolean;
onClick?: (date: moment.Moment) => any;
onMouseEnter?: (date: moment.Moment) => any;
onMouseLeave?: (date: moment.Moment) => any;
onClose?: () => void;
onChange?: (value: any, viewMode?: Extract<ViewMode, 'time'>) => void;
isEndDate?: boolean;
Expand Down Expand Up @@ -351,6 +354,9 @@ class BaseDatePicker extends React.Component<
: this.props.viewMode || 'time';

this.state = state;
this.onClick = this.onClick.bind(this);
this.onMouseEnter = this.onMouseEnter.bind(this);
this.onMouseLeave = this.onMouseLeave.bind(this);
}

getUpdateOn = (formats: any) => {
Expand Down Expand Up @@ -385,7 +391,10 @@ class BaseDatePicker extends React.Component<
'subtractTime',
'updateSelectedDate',
'localMoment',
'handleClickOutside'
'handleClickOutside',
'onClick',
'onMouseEnter',
'onMouseLeave'
]
};

Expand Down Expand Up @@ -517,8 +526,7 @@ class BaseDatePicker extends React.Component<
};
};

updateSelectedDate = (e: React.MouseEvent, close?: boolean) => {
const that: any = this;
getTargetDate = (e: React.MouseEvent) => {
let target = e.currentTarget,
modifier = 0,
viewDate = this.state.viewDate,
Expand Down Expand Up @@ -557,6 +565,12 @@ class BaseDatePicker extends React.Component<
.minutes(currentDate.minutes())
.seconds(currentDate.seconds())
.milliseconds(currentDate.milliseconds());
return date;
};

updateSelectedDate = (e: React.MouseEvent, close?: boolean) => {
const that: any = this;
const date = that.getTargetDate(e);

if (!this.props.value) {
var open = !(this.props.closeOnSelect && close);
Expand Down Expand Up @@ -664,6 +678,21 @@ class BaseDatePicker extends React.Component<
this.props.onClose && this.props.onClose();
};

onClick(e: React.MouseEvent) {
const date = this.getTargetDate(e);
this.props.onClick && this.props.onClick(date);
}

onMouseEnter(e: React.MouseEvent) {
const date = this.getTargetDate(e);
this.props.onMouseEnter && this.props.onMouseEnter(date);
}

onMouseLeave(e: React.MouseEvent) {
const date = this.getTargetDate(e);
this.props.onMouseLeave && this.props.onMouseLeave(date);
}

render() {
const {viewMode, timeFormat, dateFormat, timeRangeHeader, mobileUI} =
this.props;
Expand Down
16 changes: 15 additions & 1 deletion packages/amis-ui/src/components/calendar/DaysView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ interface CustomDaysViewProps extends LocaleProps {
value: moment.Moment,
viewMode?: Extract<ViewMode, 'time'>
) => void;
onClick: (event: React.MouseEvent<any>) => void;
onMouseEnter: (event: React.MouseEvent<any>) => void;
onMouseLeave: (event: React.MouseEvent<any>) => void;
onConfirm?: (value: number[], types: DateType[]) => void;
setDateTimeState: (state: any) => void;
showTime: () => void;
Expand Down Expand Up @@ -188,7 +191,18 @@ export class CustomDaysView extends React.Component<CustomDaysViewProps> {
classes.includes('rdtToday') ? {todayActiveStyle} : {}
);

if (!isDisabled) (dayProps as any).onClick = this.updateSelectedDate;
if (!isDisabled) {
(dayProps as any).onClick = (event: React.MouseEvent<any>) => {
this.props.onClick(event);
this.updateSelectedDate(event);
};
(dayProps as any).onMouseEnter = (event: React.MouseEvent<any>) => {
this.props.onMouseEnter(event);
};
(dayProps as any).onMouseLeave = (event: React.MouseEvent<any>) => {
this.props.onMouseLeave(event);
};
}

days.push(renderer(dayProps, currentDate, selected));

Expand Down
Loading

0 comments on commit 8af9fe5

Please sign in to comment.