tangjinzhou
7 years ago
8 changed files with 286 additions and 297 deletions
@ -0,0 +1,194 @@
|
||||
|
||||
import * as moment from 'moment' |
||||
import MonthCalendar from '../vc-calendar/src/MonthCalendar' |
||||
import VcDatePicker from '../vc-calendar/src/Picker' |
||||
import classNames from 'classnames' |
||||
import Icon from '../icon' |
||||
import callMoment from '../_util/callMoment' |
||||
import BaseMixin from '../_util/BaseMixin' |
||||
import { hasProp, getOptionProps } from '../_util/props-util' |
||||
|
||||
// export const PickerProps = {
|
||||
// value?: moment.Moment;
|
||||
// prefixCls: string;
|
||||
// }
|
||||
function noop () {} |
||||
export default function createPicker (TheCalendar) { |
||||
return { |
||||
// static defaultProps = {
|
||||
// prefixCls: 'ant-calendar',
|
||||
// allowClear: true,
|
||||
// showToday: true,
|
||||
// };
|
||||
|
||||
// private input: any;
|
||||
mixins: [BaseMixin], |
||||
data () { |
||||
const value = this.value || this.defaultValue |
||||
if (value && !moment.isMoment(value)) { |
||||
throw new Error( |
||||
'The value/defaultValue of DatePicker or MonthPicker must be ' + |
||||
'a moment object', |
||||
) |
||||
} |
||||
return { |
||||
sValue: value, |
||||
showDate: value, |
||||
} |
||||
}, |
||||
watch: { |
||||
value (val) { |
||||
this.setState({ |
||||
sValue: val, |
||||
showDate: val, |
||||
}) |
||||
}, |
||||
}, |
||||
methods: { |
||||
renderFooter (...args) { |
||||
const { prefixCls, renderExtraFooter } = this |
||||
return renderExtraFooter ? ( |
||||
<div class={`${prefixCls}-footer-extra`}> |
||||
{renderExtraFooter(...args)} |
||||
</div> |
||||
) : null |
||||
}, |
||||
|
||||
clearSelection (e) { |
||||
e.preventDefault() |
||||
e.stopPropagation() |
||||
this.handleChange(null) |
||||
}, |
||||
|
||||
handleChange (value) { |
||||
if (!hasProp(this, 'value')) { |
||||
this.setState({ |
||||
sValue: value, |
||||
showDate: value, |
||||
}) |
||||
} |
||||
this.$emit('change', value, (value && value.format(this.format)) || '') |
||||
}, |
||||
|
||||
handleCalendarChange (value) { |
||||
this.setState({ showDate: value }) |
||||
}, |
||||
|
||||
focus () { |
||||
this.$refs.input.focus() |
||||
}, |
||||
|
||||
blur () { |
||||
this.$refs.input.blur() |
||||
}, |
||||
}, |
||||
|
||||
render () { |
||||
const { sValue: value, showDate, $listeners } = this |
||||
const { panelChange = noop, focus = noop, blur = noop, ok = noop } = $listeners |
||||
const props = getOptionProps(this) |
||||
const { prefixCls, locale, localeCode } = props |
||||
|
||||
const placeholder = ('placeholder' in props) |
||||
? props.placeholder : locale.lang.placeholder |
||||
|
||||
const disabledTime = props.showTime ? props.disabledTime : null |
||||
|
||||
const calendarClassName = classNames({ |
||||
[`${prefixCls}-time`]: props.showTime, |
||||
[`${prefixCls}-month`]: MonthCalendar === TheCalendar, |
||||
}) |
||||
|
||||
if (value && localeCode) { |
||||
value.locale(localeCode) |
||||
} |
||||
|
||||
const pickerProps = { props: {}, on: {}} |
||||
const calendarProps = { props: {}, on: {}} |
||||
if (props.showTime) { |
||||
// fix https://github.com/ant-design/ant-design/issues/1902
|
||||
calendarProps.on.select = this.handleChange |
||||
} else { |
||||
pickerProps.on.change = this.handleChange |
||||
} |
||||
if ('mode' in props) { |
||||
calendarProps.props.mode = props.mode |
||||
} |
||||
|
||||
const calendar = ( |
||||
<TheCalendar |
||||
{...calendarProps} |
||||
disabledDate={props.disabledDate} |
||||
disabledTime={disabledTime} |
||||
locale={locale.lang} |
||||
timePicker={props.timePicker} |
||||
defaultValue={props.defaultPickerValue || callMoment(moment)} |
||||
dateInputPlaceholder={placeholder} |
||||
prefixCls={prefixCls} |
||||
class={calendarClassName} |
||||
onOk={ok} |
||||
dateRender={props.dateRender} |
||||
format={props.format} |
||||
showToday={props.showToday} |
||||
monthCellContentRender={props.monthCellContentRender} |
||||
renderFooter={this.renderFooter} |
||||
onPanelChange={panelChange} |
||||
onChange={this.handleCalendarChange} |
||||
value={showDate} |
||||
/> |
||||
) |
||||
|
||||
const clearIcon = (!props.disabled && props.allowClear && value) ? ( |
||||
<Icon |
||||
type='cross-circle' |
||||
class={`${prefixCls}-picker-clear`} |
||||
onClick={this.clearSelection} |
||||
/> |
||||
) : null |
||||
|
||||
const input = ({ value: inputValue }) => ( |
||||
<div> |
||||
<input |
||||
ref='input' |
||||
disabled={props.disabled} |
||||
readOnly |
||||
value={(inputValue && inputValue.format(props.format)) || ''} |
||||
placeholder={placeholder} |
||||
class={props.pickerInputClass} |
||||
onFocus={focus} |
||||
onBlur={blur} |
||||
/> |
||||
{clearIcon} |
||||
<span class={`${prefixCls}-picker-icon`} /> |
||||
</div> |
||||
) |
||||
const vcDatePickerProps = { |
||||
props: { |
||||
...props, |
||||
...pickerProps.props, |
||||
calendar, |
||||
value, |
||||
prefixCls: `${prefixCls}-picker-container`, |
||||
}, |
||||
on: { |
||||
...$listeners, |
||||
...pickerProps.on, |
||||
}, |
||||
style: props.popupStyle, |
||||
} |
||||
return ( |
||||
<span |
||||
class={props.pickerClass} |
||||
// onFocus={focus}
|
||||
// onBlur={blur}
|
||||
> |
||||
<VcDatePicker |
||||
{...vcDatePickerProps} |
||||
> |
||||
{input} |
||||
</VcDatePicker> |
||||
</span> |
||||
) |
||||
}, |
||||
} |
||||
} |
@ -1,196 +0,0 @@
|
||||
import * as React from 'react'; |
||||
import * as moment from 'moment'; |
||||
import MonthCalendar from 'rc-calendar/lib/MonthCalendar'; |
||||
import RcDatePicker from 'rc-calendar/lib/Picker'; |
||||
import classNames from 'classnames'; |
||||
import omit from 'omit.js'; |
||||
import Icon from '../icon'; |
||||
import warning from '../_util/warning'; |
||||
import callMoment from '../_util/callMoment'; |
||||
|
||||
export interface PickerProps { |
||||
value?: moment.Moment; |
||||
prefixCls: string; |
||||
} |
||||
|
||||
export default function createPicker(TheCalendar: React.ComponentClass): any { |
||||
return class CalenderWrapper extends React.Component<any, any> { |
||||
static defaultProps = { |
||||
prefixCls: 'ant-calendar', |
||||
allowClear: true, |
||||
showToday: true, |
||||
}; |
||||
|
||||
private input: any; |
||||
|
||||
constructor(props: any) { |
||||
super(props); |
||||
const value = props.value || props.defaultValue; |
||||
if (value && !moment.isMoment(value)) { |
||||
throw new Error( |
||||
'The value/defaultValue of DatePicker or MonthPicker must be ' + |
||||
'a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value', |
||||
); |
||||
} |
||||
this.state = { |
||||
value, |
||||
showDate: value, |
||||
}; |
||||
} |
||||
|
||||
componentWillReceiveProps(nextProps: PickerProps) { |
||||
if ('value' in nextProps) { |
||||
this.setState({ |
||||
value: nextProps.value, |
||||
showDate: nextProps.value, |
||||
}); |
||||
} |
||||
} |
||||
|
||||
renderFooter = (...args: any[]) => { |
||||
const { prefixCls, renderExtraFooter } = this.props; |
||||
return renderExtraFooter ? ( |
||||
<div className={`${prefixCls}-footer-extra`}> |
||||
{renderExtraFooter(...args)} |
||||
</div> |
||||
) : null; |
||||
} |
||||
|
||||
clearSelection = (e: React.MouseEvent<HTMLElement>) => { |
||||
e.preventDefault(); |
||||
e.stopPropagation(); |
||||
this.handleChange(null); |
||||
} |
||||
|
||||
handleChange = (value: moment.Moment | null) => { |
||||
const props = this.props; |
||||
if (!('value' in props)) { |
||||
this.setState({ |
||||
value, |
||||
showDate: value, |
||||
}); |
||||
} |
||||
props.onChange(value, (value && value.format(props.format)) || ''); |
||||
} |
||||
|
||||
handleCalendarChange = (value: moment.Moment) => { |
||||
this.setState({ showDate: value }); |
||||
} |
||||
|
||||
focus() { |
||||
this.input.focus(); |
||||
} |
||||
|
||||
blur() { |
||||
this.input.blur(); |
||||
} |
||||
|
||||
saveInput = (node: any) => { |
||||
this.input = node; |
||||
} |
||||
|
||||
render() { |
||||
const { value, showDate } = this.state; |
||||
const props = omit(this.props, ['onChange']); |
||||
const { prefixCls, locale, localeCode } = props; |
||||
|
||||
const placeholder = ('placeholder' in props) |
||||
? props.placeholder : locale.lang.placeholder; |
||||
|
||||
const disabledTime = props.showTime ? props.disabledTime : null; |
||||
|
||||
const calendarClassName = classNames({ |
||||
[`${prefixCls}-time`]: props.showTime, |
||||
[`${prefixCls}-month`]: MonthCalendar === TheCalendar, |
||||
}); |
||||
|
||||
if (value && localeCode) { |
||||
value.locale(localeCode); |
||||
} |
||||
|
||||
let pickerProps: Object = {}; |
||||
let calendarProps: any = {}; |
||||
if (props.showTime) { |
||||
calendarProps = { |
||||
// fix https://github.com/ant-design/ant-design/issues/1902
|
||||
onSelect: this.handleChange, |
||||
}; |
||||
} else { |
||||
pickerProps = { |
||||
onChange: this.handleChange, |
||||
}; |
||||
} |
||||
if ('mode' in props) { |
||||
calendarProps.mode = props.mode; |
||||
} |
||||
|
||||
warning(!('onOK' in props), 'It should be `DatePicker[onOk]` or `MonthPicker[onOk]`, instead of `onOK`!'); |
||||
const calendar = ( |
||||
<TheCalendar |
||||
{...calendarProps} |
||||
disabledDate={props.disabledDate} |
||||
disabledTime={disabledTime} |
||||
locale={locale.lang} |
||||
timePicker={props.timePicker} |
||||
defaultValue={props.defaultPickerValue || callMoment(moment)} |
||||
dateInputPlaceholder={placeholder} |
||||
prefixCls={prefixCls} |
||||
className={calendarClassName} |
||||
onOk={props.onOk} |
||||
dateRender={props.dateRender} |
||||
format={props.format} |
||||
showToday={props.showToday} |
||||
monthCellContentRender={props.monthCellContentRender} |
||||
renderFooter={this.renderFooter} |
||||
onPanelChange={props.onPanelChange} |
||||
onChange={this.handleCalendarChange} |
||||
value={showDate} |
||||
/> |
||||
); |
||||
|
||||
const clearIcon = (!props.disabled && props.allowClear && value) ? ( |
||||
<Icon |
||||
type="cross-circle" |
||||
className={`${prefixCls}-picker-clear`} |
||||
onClick={this.clearSelection} |
||||
/> |
||||
) : null; |
||||
|
||||
const input = ({ value: inputValue }: { value: moment.Moment | null }) => ( |
||||
<div> |
||||
<input |
||||
ref={this.saveInput} |
||||
disabled={props.disabled} |
||||
readOnly |
||||
value={(inputValue && inputValue.format(props.format)) || ''} |
||||
placeholder={placeholder} |
||||
className={props.pickerInputClass} |
||||
/> |
||||
{clearIcon} |
||||
<span className={`${prefixCls}-picker-icon`} /> |
||||
</div> |
||||
); |
||||
|
||||
return ( |
||||
<span |
||||
id={props.id} |
||||
className={classNames(props.className, props.pickerClass)} |
||||
style={props.style} |
||||
onFocus={props.onFocus} |
||||
onBlur={props.onBlur} |
||||
> |
||||
<RcDatePicker |
||||
{...props} |
||||
{...pickerProps} |
||||
calendar={calendar} |
||||
value={value} |
||||
prefixCls={`${prefixCls}-picker-container`} |
||||
style={props.popupStyle} |
||||
> |
||||
{input} |
||||
</RcDatePicker> |
||||
</span> |
||||
); |
||||
} |
||||
}; |
||||
} |
@ -0,0 +1,80 @@
|
||||
import * as moment from 'moment' |
||||
import { TimePickerProps } from '../time-picker' |
||||
import PropTypes from '../_util/vue-types' |
||||
|
||||
export const MomentType = { |
||||
type: Object, |
||||
validator: function (value) { |
||||
return moment.isMoment(value) |
||||
}, |
||||
} |
||||
|
||||
export const PickerProps = () => ({ |
||||
prefixCls: PropTypes.string, |
||||
inputPrefixCls: PropTypes.string, |
||||
format: PropTypes.string, |
||||
disabled: PropTypes.boolean, |
||||
allowClear: PropTypes.boolean, |
||||
popupStyle: PropTypes.object, |
||||
locale: PropTypes.any, |
||||
size: PropTypes.oneOf(['large', 'small', 'default']), |
||||
getCalendarContainer: PropTypes.func, |
||||
open: PropTypes.boolean, |
||||
// onOpenChange: PropTypes.(status: boolean) => void,
|
||||
disabledDate: PropTypes.func, |
||||
renderExtraFooter: PropTypes.any, |
||||
dateRender: PropTypes.any, // (current: moment.Moment, today: moment.Moment) => React.ReactNode,
|
||||
}) |
||||
|
||||
export const SinglePickerProps = () => ({ |
||||
value: MomentType, |
||||
defaultValue: MomentType, |
||||
defaultPickerValue: MomentType, |
||||
// onChange?: (date: moment.Moment, dateString: string) => void;
|
||||
}) |
||||
|
||||
export const DatePickerProps = () => ({ |
||||
...PickerProps(), ...SinglePickerProps(), |
||||
showTime: PropTypes.oneOfType([PropTypes.shape(TimePickerProps()).loose, PropTypes.bool]), |
||||
showToday: PropTypes.bool, |
||||
open: PropTypes.bool, |
||||
disabledTime: PropTypes.func, |
||||
// onOpenChange?: (status: boolean) => void;
|
||||
// onOk?: (selectedTime: moment.Moment) => void;
|
||||
placeholder: PropTypes.string, |
||||
}) |
||||
|
||||
export const MonthPickerProps = () => ({ |
||||
...PickerProps(), ...SinglePickerProps(), |
||||
placeholder: PropTypes.string, |
||||
}) |
||||
|
||||
export const RangePickerValue = PropTypes.arrayOf(PropTypes.oneOfType([undefined, MomentType])) |
||||
export const RangePickerPresetRange = PropTypes.oneOfType([RangePickerValue, PropTypes.func]) |
||||
|
||||
export const RangePickerProps = () => ({ |
||||
...PickerProps(), |
||||
value: RangePickerValue, |
||||
defaultValue: RangePickerValue, |
||||
defaultPickerValue: RangePickerValue, |
||||
// onChange?: (dates: RangePickerValue, dateStrings: [string, string]) => void;
|
||||
// onCalendarChange?: (dates: RangePickerValue, dateStrings: [string, string]) => void;
|
||||
// onOk?: (selectedTime: moment.Moment) => void;
|
||||
showTime: PropTypes.oneOfType([PropTypes.shape(TimePickerProps()).loose, PropTypes.bool]), |
||||
ranges: PropTypes.objectOf(String), |
||||
placeholder: PropTypes.oneOfType(String), |
||||
mode: PropTypes.oneOfType([PropTypes.string, PropTypes.oneOfType(String)]), |
||||
disabledTime: PropTypes.func, |
||||
// onPanelChange?: (value?: RangePickerValue, mode?: string | string[]) => void;
|
||||
}) |
||||
|
||||
export const WeexPickerProps = () => ({ |
||||
...PickerProps(), ...SinglePickerProps(), |
||||
placeholder: PropTypes.string, |
||||
}) |
||||
|
||||
// export interface DatePickerDecorator extends React.ClassicComponentClass<DatePickerProps> {
|
||||
// RangePicker: React.ClassicComponentClass<RangePickerProps>;
|
||||
// MonthPicker: React.ClassicComponentClass<MonthPickerProps>;
|
||||
// WeekPicker: React.ClassicComponentClass<WeexPickerProps>;
|
||||
// }
|
@ -1,90 +0,0 @@
|
||||
import * as React from 'react'; |
||||
import * as moment from 'moment'; |
||||
import { TimePickerProps } from '../time-picker'; |
||||
|
||||
export interface PickerProps { |
||||
id?: number | string; |
||||
prefixCls?: string; |
||||
inputPrefixCls?: string; |
||||
format?: string; |
||||
disabled?: boolean; |
||||
allowClear?: boolean; |
||||
className?: string; |
||||
style?: React.CSSProperties; |
||||
popupStyle?: React.CSSProperties; |
||||
locale?: any; |
||||
size?: 'large' | 'small' | 'default'; |
||||
getCalendarContainer?: (triggerNode: Element) => HTMLElement; |
||||
open?: boolean; |
||||
onOpenChange?: (status: boolean) => void; |
||||
disabledDate?: (current: moment.Moment) => boolean; |
||||
renderExtraFooter?: () => React.ReactNode; |
||||
dateRender?: (current: moment.Moment, today: moment.Moment) => React.ReactNode; |
||||
} |
||||
|
||||
export interface SinglePickerProps { |
||||
value?: moment.Moment; |
||||
defaultValue?: moment.Moment; |
||||
defaultPickerValue?: moment.Moment; |
||||
onChange?: (date: moment.Moment, dateString: string) => void; |
||||
} |
||||
|
||||
export interface DatePickerProps extends PickerProps, SinglePickerProps { |
||||
className?: string; |
||||
showTime?: TimePickerProps | boolean; |
||||
showToday?: boolean; |
||||
open?: boolean; |
||||
disabledTime?: (current: moment.Moment) => { |
||||
disabledHours?: () => number[], |
||||
disabledMinutes?: () => number[], |
||||
disabledSeconds?: () => number[], |
||||
}; |
||||
onOpenChange?: (status: boolean) => void; |
||||
onOk?: (selectedTime: moment.Moment) => void; |
||||
placeholder?: string; |
||||
} |
||||
|
||||
export interface MonthPickerProps extends PickerProps, SinglePickerProps { |
||||
className?: string; |
||||
placeholder?: string; |
||||
} |
||||
|
||||
export type RangePickerValue = |
||||
undefined[] | |
||||
[moment.Moment] | |
||||
[undefined, moment.Moment] | |
||||
[moment.Moment, moment.Moment]; |
||||
export type RangePickerPresetRange = RangePickerValue | (() => RangePickerValue); |
||||
|
||||
export interface RangePickerProps extends PickerProps { |
||||
className?: string; |
||||
value?: RangePickerValue; |
||||
defaultValue?: RangePickerValue; |
||||
defaultPickerValue?: RangePickerValue; |
||||
onChange?: (dates: RangePickerValue, dateStrings: [string, string]) => void; |
||||
onCalendarChange?: (dates: RangePickerValue, dateStrings: [string, string]) => void; |
||||
onOk?: (selectedTime: moment.Moment) => void; |
||||
showTime?: TimePickerProps | boolean; |
||||
ranges?: { |
||||
[range: string]: RangePickerPresetRange, |
||||
}; |
||||
placeholder?: [string, string]; |
||||
mode?: string | string[]; |
||||
disabledTime?: (current: moment.Moment, type: string) => { |
||||
disabledHours?: () => number[], |
||||
disabledMinutes?: () => number[], |
||||
disabledSeconds?: () => number[], |
||||
}; |
||||
onPanelChange?: (value?: RangePickerValue, mode?: string | string[]) => void; |
||||
} |
||||
|
||||
export interface WeexPickerProps extends PickerProps, SinglePickerProps { |
||||
className?: string; |
||||
placeholder?: string; |
||||
} |
||||
|
||||
export interface DatePickerDecorator extends React.ClassicComponentClass<DatePickerProps> { |
||||
RangePicker: React.ClassicComponentClass<RangePickerProps>; |
||||
MonthPicker: React.ClassicComponentClass<MonthPickerProps>; |
||||
WeekPicker: React.ClassicComponentClass<WeexPickerProps>; |
||||
} |
Loading…
Reference in new issue