Date 支持配置 overlayPlacement

This commit is contained in:
2betop 2020-01-02 11:02:07 +08:00
parent 8f77a1e6f6
commit 2b0168176a
4 changed files with 107 additions and 98 deletions

View File

@ -2,14 +2,16 @@
表单项集合中,默认都是一行一个,如果想要一行多个,请用 Group 包裹起来。
- `type` 请设置成 `group`
- `controls` 表单项集合。
- `mode` 展示默认,跟 [Form](./Form.md) 中的模式一样,选择: `normal`、`horizontal`或者`inline`。
- `horizontal` 当为水平模式时,用来控制左右占比。
- `horizontal.label` 左边 label 的宽度占比。
- `horizontal.right` 右边控制器的宽度占比。
- `horizontal.offset` 当没有设置 label 时,右边控制器的偏移量。
- `className` CSS 类名。
- `type` 请设置成 `group`
- `controls` 表单项集合。
- `mode` 展示默认,跟 [Form](./Form.md) 中的模式一样,选择: `normal`、`horizontal`或者`inline`。
- `direction` 可以配置水平展示还是垂直展示。对应的配置项分别是:`vertical`、`horizontal`
- `horizontal` 当为水平模式时,用来控制左右占比。
- `horizontal.label` 左边 label 的宽度占比。
- `horizontal.right` 右边控制器的宽度占比。
- `horizontal.offset` 当没有设置 label 时,右边控制器的偏移量。
- `className` CSS 类名。
- `label` Group 也可以配置个 label 来展示标题。
```schema:height="360" scope="body"
{

View File

@ -225,7 +225,8 @@
max-width: unset;
margin: px2rem(30px);
.#{$ns}Modal-body {
> .#{$ns}Modal-body {
height: 0;
overflow: auto;
}
}

View File

@ -4,85 +4,85 @@
* @author fex
*/
import React from 'react';
import cx from 'classnames';
import moment from 'moment';
import 'moment/locale/zh-cn';
import {Icon} from './icons';
import PopOver from './PopOver';
import Overlay from './Overlay';
import {ClassNamesFn, themeable} from '../theme';
import {PlainObject} from '../types';
import Calendar from './calendar/Calendar';
import React from "react";
import cx from "classnames";
import moment from "moment";
import "moment/locale/zh-cn";
import { Icon } from "./icons";
import PopOver from "./PopOver";
import Overlay from "./Overlay";
import { ClassNamesFn, themeable } from "../theme";
import { PlainObject } from "../types";
import Calendar from "./calendar/Calendar";
const availableShortcuts: {[propName: string]: any} = {
const availableShortcuts: { [propName: string]: any } = {
today: {
label: '今天',
label: "今天",
date: (now: moment.Moment) => {
return now.startOf('day');
return now.startOf("day");
}
},
yesterday: {
label: '昨天',
label: "昨天",
date: (now: moment.Moment) => {
return now.add(-1, 'days').startOf('day');
return now.add(-1, "days").startOf("day");
}
},
thisweek: {
label: '本周一',
label: "本周一",
date: (now: moment.Moment) => {
return now.startOf('week').add(-1, 'weeks');
return now.startOf("week").add(-1, "weeks");
}
},
thismonth: {
label: '本月初',
label: "本月初",
date: (now: moment.Moment) => {
return now.startOf('month');
return now.startOf("month");
}
},
prevmonth: {
label: '上个月初',
label: "上个月初",
date: (now: moment.Moment) => {
return now.startOf('month').add(-1, 'month');
return now.startOf("month").add(-1, "month");
}
},
prevquarter: {
label: '上个季节初',
label: "上个季节初",
date: (now: moment.Moment) => {
return now.startOf('quarter').add(-1, 'quarter');
return now.startOf("quarter").add(-1, "quarter");
}
},
thisquarter: {
label: '本季度初',
label: "本季度初",
date: (now: moment.Moment) => {
return now.startOf('quarter');
return now.startOf("quarter");
}
},
tomorrow: {
label: '明天',
label: "明天",
date: (now: moment.Moment) => {
return now.add(1, 'days').startOf('day');
return now.add(1, "days").startOf("day");
}
},
endofthisweek: {
label: '本周日',
label: "本周日",
date: (now: moment.Moment) => {
return now.endOf('week');
return now.endOf("week");
}
},
endofthismonth: {
label: '本月底',
label: "本月底",
date: (now: moment.Moment) => {
return now.endOf('month');
return now.endOf("month");
}
}
};
@ -94,7 +94,7 @@ const advancedShortcuts = [
return {
label: `${days}天前`,
date: (now: moment.Moment) => {
return now.subtract(days, 'days');
return now.subtract(days, "days");
}
};
}
@ -105,7 +105,7 @@ const advancedShortcuts = [
return {
label: `${days}天后`,
date: (now: moment.Moment) => {
return now.add(days, 'days');
return now.add(days, "days");
}
};
}
@ -116,7 +116,7 @@ const advancedShortcuts = [
return {
label: `${weeks}周前`,
date: (now: moment.Moment) => {
return now.subtract(weeks, 'weeks');
return now.subtract(weeks, "weeks");
}
};
}
@ -127,7 +127,7 @@ const advancedShortcuts = [
return {
label: `${weeks}周后`,
date: (now: moment.Moment) => {
return now.add(weeks, 'weeks');
return now.add(weeks, "weeks");
}
};
}
@ -138,7 +138,7 @@ const advancedShortcuts = [
return {
label: `${months}月前`,
date: (now: moment.Moment) => {
return now.subtract(months, 'months');
return now.subtract(months, "months");
}
};
}
@ -149,7 +149,7 @@ const advancedShortcuts = [
return {
label: `${months}月后`,
date: (now: moment.Moment) => {
return now.add(months, 'months');
return now.add(months, "months");
}
};
}
@ -160,7 +160,7 @@ const advancedShortcuts = [
return {
label: `${quarters}季度前`,
date: (now: moment.Moment) => {
return now.subtract(quarters, 'quarters');
return now.subtract(quarters, "quarters");
}
};
}
@ -171,7 +171,7 @@ const advancedShortcuts = [
return {
label: `${quarters}季度后`,
date: (now: moment.Moment) => {
return now.add(quarters, 'quarters');
return now.add(quarters, "quarters");
}
};
}
@ -198,7 +198,7 @@ export type ShortCuts =
| ShortCutDateRange;
export interface DateProps {
viewMode: 'years' | 'months' | 'days' | 'time';
viewMode: "years" | "months" | "days" | "time";
className?: string;
classPrefix: string;
classnames: ClassNamesFn;
@ -219,6 +219,7 @@ export interface DateProps {
onChange: (value: any) => void;
value: any;
shortcuts: string | Array<ShortCuts>;
overlayPlacement: string;
[propName: string]: any;
}
@ -231,11 +232,12 @@ export interface DatePickerState {
export class DatePicker extends React.Component<DateProps, DatePickerState> {
static defaultProps: Pick<
DateProps,
'viewMode' | 'shortcuts' | 'closeOnSelect'
"viewMode" | "shortcuts" | "closeOnSelect" | "overlayPlacement"
> = {
viewMode: 'days',
shortcuts: '',
closeOnSelect: true
viewMode: "days",
shortcuts: "",
closeOnSelect: true,
overlayPlacement: "auto"
};
state: DatePickerState = {
isOpened: false,
@ -302,7 +304,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
}
handleKeyPress(e: React.KeyboardEvent) {
if (e.key === ' ') {
if (e.key === " ") {
this.handleClick();
}
}
@ -336,7 +338,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
e.preventDefault();
e.stopPropagation();
const onChange = this.props.onChange;
onChange('');
onChange("");
}
handleChange(value: moment.Moment) {
@ -354,9 +356,9 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
return;
}
if (minTime && value && value.isBefore(minTime, 'second')) {
if (minTime && value && value.isBefore(minTime, "second")) {
value = minTime;
} else if (maxTime && value && value.isAfter(maxTime, 'second')) {
} else if (maxTime && value && value.isAfter(maxTime, "second")) {
value = maxTime;
}
@ -368,7 +370,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
}
selectRannge(item: any) {
const {closeOnSelect} = this.props;
const { closeOnSelect } = this.props;
const now = moment();
this.handleChange(item.date(now));
@ -376,11 +378,11 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
}
checkIsValidDate(currentDate: moment.Moment) {
const {minDate, maxDate} = this.props;
const { minDate, maxDate } = this.props;
if (minDate && currentDate.isBefore(minDate, 'day')) {
if (minDate && currentDate.isBefore(minDate, "day")) {
return false;
} else if (maxDate && currentDate.isAfter(maxDate, 'day')) {
} else if (maxDate && currentDate.isAfter(maxDate, "day")) {
return false;
}
@ -420,10 +422,10 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
if (!shortcuts) {
return null;
}
const {classPrefix: ns} = this.props;
const { classPrefix: ns } = this.props;
let shortcutArr: Array<string | ShortCuts>;
if (typeof shortcuts === 'string') {
shortcutArr = shortcuts.split(',');
if (typeof shortcuts === "string") {
shortcutArr = shortcuts.split(",");
} else {
shortcutArr = shortcuts;
}
@ -434,7 +436,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
return null;
}
let shortcut: PlainObject = {};
if (typeof item === 'string') {
if (typeof item === "string") {
shortcut = this.getAvailableShortcuts(item);
shortcut.key = item;
} else if ((item as ShortCutDate).date) {
@ -473,7 +475,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
clearable,
shortcuts,
utc,
closeOnSelect
overlayPlacement
} = this.props;
const isOpened = this.state.isOpened;
@ -488,8 +490,8 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
className={cx(
`${ns}DatePicker`,
{
'is-disabled': disabled,
'is-focused': this.state.isFocused
"is-disabled": disabled,
"is-focused": this.state.isFocused
},
className
)}
@ -517,6 +519,7 @@ export class DatePicker extends React.Component<DateProps, DatePickerState> {
target={this.getTarget}
container={popOverContainer || this.getParent}
rootClose={false}
placement={overlayPlacement}
show
>
<PopOver

View File

@ -1,10 +1,10 @@
import React from 'react';
import {FormItem, FormControlProps} from './Item';
import cx from 'classnames';
import {filterDate} from '../../utils/tpl-builtin';
import moment from 'moment';
import 'moment/locale/zh-cn';
import DatePicker from '../../components/DatePicker';
import React from "react";
import { FormItem, FormControlProps } from "./Item";
import cx from "classnames";
import { filterDate } from "../../utils/tpl-builtin";
import moment from "moment";
import "moment/locale/zh-cn";
import DatePicker from "../../components/DatePicker";
export interface DateProps extends FormControlProps {
placeholder?: string;
@ -22,18 +22,21 @@ interface DateControlState {
maxDate?: moment.Moment;
}
export default class DateControl extends React.PureComponent<DateProps> {
export default class DateControl extends React.PureComponent<
DateProps,
DateControlState
> {
static defaultProps = {
format: 'X',
viewMode: 'days',
inputFormat: 'YYYY-MM-DD',
format: "X",
viewMode: "days",
inputFormat: "YYYY-MM-DD",
timeConstrainst: {
minutes: {
step: 1
}
},
clearable: true,
iconClassName: 'fa fa-calendar'
iconClassName: "fa fa-calendar"
};
componentWillMount() {
@ -85,60 +88,60 @@ export default class DateControl extends React.PureComponent<DateProps> {
render() {
const {
className,
classPrefix: ns,
defaultValue,
defaultData,
classnames: cx,
...rest
} = this.props;
return (
<div className={cx(`${ns}DateControl`, className)}>
<DatePicker {...rest} {...this.state} classPrefix={ns} />
<div className={cx(`DateControl`, className)}>
<DatePicker {...rest} {...this.state} classnames={cx} />
</div>
);
}
}
@FormItem({
type: 'date',
type: "date",
weight: -150
})
export class DateControlRenderer extends DateControl {
static defaultProps = {
...DateControl.defaultProps,
placeholder: '请选择日期',
dateFormat: 'YYYY-MM-DD',
timeFormat: '',
placeholder: "请选择日期",
dateFormat: "YYYY-MM-DD",
timeFormat: "",
strictMode: false
};
}
@FormItem({
type: 'datetime'
type: "datetime"
})
export class DatetimeControlRenderer extends DateControl {
static defaultProps = {
...DateControl.defaultProps,
placeholder: '请选择日期以及时间',
inputFormat: 'YYYY-MM-DD HH:mm:ss',
dateFormat: 'LL',
timeFormat: 'HH:mm:ss',
placeholder: "请选择日期以及时间",
inputFormat: "YYYY-MM-DD HH:mm:ss",
dateFormat: "LL",
timeFormat: "HH:mm:ss",
closeOnSelect: false,
strictMode: false
};
}
@FormItem({
type: 'time'
type: "time"
})
export class TimeControlRenderer extends DateControl {
static defaultProps = {
...DateControl.defaultProps,
placeholder: '请选择时间',
inputFormat: 'HH:mm',
dateFormat: '',
timeFormat: 'HH:mm',
viewMode: 'time',
placeholder: "请选择时间",
inputFormat: "HH:mm",
dateFormat: "",
timeFormat: "HH:mm",
viewMode: "time",
closeOnSelect: false
};
}