diff --git a/README.md b/README.md index 234fef2..c4e9a77 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ react-native run-ios |pickerPrefixCls(web) | picker prefix class | String | 'rmc-picker' | |defaultDate | default selected date. | Date | | |date | The currently selected date. | Date | | -|mode | The date picker mode. | String | 'date' enum('date', 'time', 'datetime', 'year', 'month') | +|mode | The date picker mode. | String | 'date' enum('date', 'time', 'datetime', 'year', 'month', 'recenttime') | |minDate | min date | Date | 2000-1-1 | |maxDate | max date | Date | 2030-1-1 | |locale | the locale of area | Object | import from 'rmc-date-picker/lib/locale/en_US' | @@ -97,6 +97,8 @@ react-native run-ios |onValueChange | fire when picker change | (vals: any, index: number) => void | | |formatMonth | Customize display value of months | (month:number, current:Date) => React.Node | | |formatDay | Customize display value of days | (day:number, current:Date) => React.Node | | +|formatRecentDate | only use in `recenttime` mode. Customize display value of recent date | (year: number, month: number, day:number, current:Date) => React.Node | | + ### rmc-date-picker/lib/Popup props diff --git a/examples/recentTime.html b/examples/recentTime.html new file mode 100644 index 0000000..b3a4252 --- /dev/null +++ b/examples/recentTime.html @@ -0,0 +1 @@ +placeholder \ No newline at end of file diff --git a/examples/recentTime.tsx b/examples/recentTime.tsx new file mode 100644 index 0000000..6403884 --- /dev/null +++ b/examples/recentTime.tsx @@ -0,0 +1,101 @@ +/* tslint:disable:no-console */ + +import 'rmc-picker/assets/index.css'; +import 'rmc-date-picker/assets/index.less'; +import DatePicker from '../src/index'; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import enUS from '../src/locale/en_US'; +import zhCn from '../src/locale/zh_CN'; +import { cn, format, now } from './utils'; + +const maxDate = new Date(2017, 10, 1, 23, 49, 59); +const ONE_DAY = 24 * 60 * 60 * 1000; + +class Demo extends React.Component { + static defaultProps = { + locale: cn ? zhCn : enUS , + }; + + constructor(props) { + super(props); + this.state = { + date: now, + mode: 'recentTime', + }; + } + + onDateChange = (date) => { + console.log('onChange', format(date)); + this.setState({ + date, + }); + } + + onValueChange = (values, index) => { + console.log(values, index); + } + + changeMode = (e) => { + this.setState({ + mode: e.target.value, + }); + } + + formatRecentDate = (year, month, day) => { + + const gap = this.getTimeGap(year, month, day); + + if ( gap === 0 ) { + return '今天'; + } else if (gap === 1) { + return '明天'; + } else if (gap === 2) { + return '后天'; + } else { + return `${month + 1}月${day}日`; + } + } + + getTimeGap = (year, month, day) => { + const displayTime = new Date(year, month, day).getTime(); + const today = now.getTime(); + + return Math.ceil((displayTime - today) / ONE_DAY); + } + + render() { + const props = this.props; + const { date, mode } = this.state; + + return (
+

date picker

+ + + +
+ {date && format(date) || format(now)} + +
+
); + } +} + +ReactDOM.render(, document.getElementById('__react-content')); diff --git a/src/DatePicker.tsx b/src/DatePicker.tsx index 3c19f40..b75b072 100644 --- a/src/DatePicker.tsx +++ b/src/DatePicker.tsx @@ -8,6 +8,10 @@ function getDaysInMonth(date) { return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate(); } +function increaseDay(date) { + return new Date(date.getTime() + ONE_DAY); +} + function pad(n) { return n < 10 ? `0${n}` : n + ''; } @@ -26,6 +30,7 @@ const smallPickerItem = { }; const DATETIME = 'datetime'; +const RECENT_TIME = 'recentTime'; const DATE = 'date'; const TIME = 'time'; const MONTH = 'month'; @@ -61,11 +66,40 @@ class DatePicker extends React.Component { } onValueChange = (values, index) => { - const value = parseInt(values[index], 10); const props = this.props; const { mode } = props; let newValue = cloneDate(this.getDate()); - if (mode === DATETIME || mode === DATE || mode === YEAR || mode === MONTH) { + + const value = parseInt(values[index], 10); + + if (mode === RECENT_TIME) { + + switch (index) { + case 0: + const mixValue = values[0].split('-'); + const year = parseInt(mixValue[0], 10); + const month = parseInt(mixValue[1], 10); + const day = parseInt(mixValue[2], 10); + + newValue.setFullYear(year); + setMonth(newValue, month); + newValue.setDate(day); + break; + case 1: + this.setHours(newValue, value); + break; + case 2: + newValue.setMinutes(value); + break; + case 3: + this.setAmPm(newValue, value); + break; + default: + break; + } + + } else if (mode === DATETIME || mode === DATE || mode === YEAR || mode === MONTH) { + switch (index) { case 0: newValue.setFullYear(value); @@ -154,7 +188,7 @@ class DatePicker extends React.Component { } getDate() { - return this.state.date || this.getDefaultMinDate(); + return this.clipDate(this.state.date || this.getDefaultMinDate()); } // used by rmc-picker/lib/PopupMixin.js @@ -278,6 +312,46 @@ class DatePicker extends React.Component { ]; } + getRecentDateData() { + const {formatRecentDate, locale, formatMonth, formatDay} = this.props; + const recent: any[] = []; + const date = this.getDate(); + const minDate = this.getMinDate(); + const maxDate = this.getMaxDate(); + + for (let d = minDate; d <= maxDate; d = increaseDay(d)) { + const year = d.getFullYear(); + const month = d.getMonth(); + const day = d.getDate(); + + const yValue = year + ''; + const yLabel = year + locale.year + ''; + const mValue = month + ''; + const mLabel = formatMonth ? formatMonth(month, date) : (month + 1 + locale.month + ''); + const dValue = day + ''; + const dLabel = formatDay ? formatDay(day, date) : (day + locale.day + ''); + + const value = `${yValue}-${mValue}-${dValue}`; + const label = formatRecentDate ? + formatRecentDate(year, month, day, date) : + `${yLabel}${mLabel}${dLabel}`; + + recent.push({ + value, + label, + }); + } + + return [ + { + key: 'mix', + props: { + children: recent, + }, + }, + ]; + } + getDisplayHour(rawHour) { // 12 hour am (midnight 00:00) -> 12 hour pm (noon 12:00) -> 12 hour am (midnight 00:00) if (this.props.use12Hours) { @@ -304,7 +378,7 @@ class DatePicker extends React.Component { const minDateHour = this.getMinHour(); const maxDateHour = this.getMaxHour(); const hour = date.getHours(); - if (mode === DATETIME) { + if (mode === DATETIME || mode === RECENT_TIME) { const year = date.getFullYear(); const month = date.getMonth(); const day = date.getDate(); @@ -376,7 +450,7 @@ class DatePicker extends React.Component { const { mode } = this.props; const minDate = this.getMinDate(); const maxDate = this.getMaxDate(); - if (mode === DATETIME) { + if (mode === DATETIME || mode === RECENT_TIME) { if (date < minDate) { return cloneDate(minDate); } @@ -428,12 +502,17 @@ class DatePicker extends React.Component { }; } + if (mode === RECENT_TIME) { + cols = this.getRecentDateData(); + value = [`${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`]; + } + if (mode === DATETIME || mode === DATE) { cols = this.getDateData(); value = [date.getFullYear() + '', date.getMonth() + '', date.getDate() + '']; } - if (mode === DATETIME || mode === TIME) { + if (mode === RECENT_TIME || mode === DATETIME || mode === TIME) { cols = cols.concat(this.getTimeData()); const hour = date.getHours(); let dtValue = [hour + '', date.getMinutes() + '']; diff --git a/src/IDatePickerProps.tsx b/src/IDatePickerProps.tsx index 017f458..df0fdcf 100644 --- a/src/IDatePickerProps.tsx +++ b/src/IDatePickerProps.tsx @@ -9,6 +9,7 @@ interface IDatePickerProps { minuteStep?: number; formatMonth?: (month: number, date?: any) => any; formatDay?: (day: number, date?: any) => any; + formatRecentDate?: (year: number, month: number, day: number, date?: any) => any; onDateChange?: (date: any) => void; onValueChange?: (vals: any, index: number) => void; style?: any;