Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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' |
Expand All @@ -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

Expand Down
1 change: 1 addition & 0 deletions examples/recentTime.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
placeholder
101 changes: 101 additions & 0 deletions examples/recentTime.tsx
Original file line number Diff line number Diff line change
@@ -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<any, any> {
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 (<div style={{ margin: '10px 30px' }}>
<h2>date picker</h2>

<select value={this.state.mode} onChange={this.changeMode}>
<option>datetime</option>
<option>date</option>
<option>time</option>
<option>month</option>
<option>year</option>
<option>recentTime</option>
</select>

<div>
<span>{date && format(date) || format(now)}</span>
<DatePicker
rootNativeProps={{'data-xx': 'yy'}}
defaultDate={date || now}
mode={mode}
locale={props.locale}
maxDate={maxDate}
minDate={now}
onDateChange={this.onDateChange}
onValueChange={this.onValueChange}
formatRecentDate={this.formatRecentDate}
/>
</div>
</div>);
}
}

ReactDOM.render(<Demo />, document.getElementById('__react-content'));
91 changes: 85 additions & 6 deletions src/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 + '';
}
Expand All @@ -26,6 +30,7 @@ const smallPickerItem = {
};

const DATETIME = 'datetime';
const RECENT_TIME = 'recentTime';
const DATE = 'date';
const TIME = 'time';
const MONTH = 'month';
Expand Down Expand Up @@ -61,11 +66,40 @@ class DatePicker extends React.Component<IDatePickerProps, any> {
}

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);
Expand Down Expand Up @@ -154,7 +188,7 @@ class DatePicker extends React.Component<IDatePickerProps, any> {
}

getDate() {
return this.state.date || this.getDefaultMinDate();
return this.clipDate(this.state.date || this.getDefaultMinDate());
}

// used by rmc-picker/lib/PopupMixin.js
Expand Down Expand Up @@ -278,6 +312,46 @@ class DatePicker extends React.Component<IDatePickerProps, any> {
];
}

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) {
Expand All @@ -304,7 +378,7 @@ class DatePicker extends React.Component<IDatePickerProps, any> {
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();
Expand Down Expand Up @@ -376,7 +450,7 @@ class DatePicker extends React.Component<IDatePickerProps, any> {
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);
}
Expand Down Expand Up @@ -428,12 +502,17 @@ class DatePicker extends React.Component<IDatePickerProps, any> {
};
}

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() + ''];
Expand Down
1 change: 1 addition & 0 deletions src/IDatePickerProps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down