Skip to content

Commit

Permalink
Merge pull request #4 from bojant987/master
Browse files Browse the repository at this point in the history
Pulled from upstream
  • Loading branch information
MilosRasic authored Feb 9, 2018
2 parents 09186cd + 850174d commit 6b58458
Show file tree
Hide file tree
Showing 17 changed files with 2,258 additions and 137 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ script:
- npm run test:all
before_install:
- export TZ=Europe/Stockholm
notifications:
email: false
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
Changelog
=========
## 2.13.0
* Use more appropriate cursor for empty space in time picker and in day texts
* Add `viewDate` prop that sets a value when opening the calendar when there is no selected date
* Make `disableOnClickOutside` work as intended
* Better touch support for tapping and holding
* Use static property `defaultProps` instead of `getDefaultProps`

## 2.12.0
* The `renderInput` prop now receives `closeCalendar` function as well

## 2.11.1
* The open prop should now work as intended

## 2.11.0
* onFocus now receives the browser event
* Do not open browser menu on right click of arrows in time view
Expand Down
5 changes: 5 additions & 0 deletions DateTime.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ declare namespace ReactDatetimeClass {
This prop is parsed by moment.js, so it is possible to use a date string or a moment.js date.
*/
defaultValue?: Date | string | Moment;
/*
Represents the month which is viewed on opening the calendar when there is no selected date.
This prop is parsed by Moment.js, so it is possible to use a date `string` or a `moment` object.
*/
viewDate?: Date | string | Moment;
/*
Defines the format for the date. It accepts any moment.js date format.
If true the date will be displayed using the defaults for the current locale.
Expand Down
73 changes: 41 additions & 32 deletions DateTime.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var Datetime = createClass({
propTypes: {
// value: TYPES.object | TYPES.string,
// defaultValue: TYPES.object | TYPES.string,
// viewDate: TYPES.object | TYPES.string,
onFocus: TYPES.func,
onBlur: TYPES.func,
onChange: TYPES.func,
Expand All @@ -32,27 +33,6 @@ var Datetime = createClass({
closeOnTab: TYPES.bool
},

getDefaultProps: function() {
var nof = function() {};
return {
className: '',
defaultValue: '',
inputProps: {},
input: true,
onFocus: nof,
onBlur: nof,
onChange: nof,
onViewModeChange: nof,
timeFormat: true,
timeConstraints: {},
dateFormat: true,
strictParsing: true,
closeOnSelect: false,
closeOnTab: true,
utc: false
};
},

getInitialState: function() {
var state = this.getStateFromProps( this.props );

Expand All @@ -64,24 +44,33 @@ var Datetime = createClass({
return state;
},

parseDate: function (date, formats) {
var parsedDate;

if (date && typeof date === 'string')
parsedDate = this.localMoment(date, formats.datetime);
else if (date)
parsedDate = this.localMoment(date);

if (parsedDate && !parsedDate.isValid())
parsedDate = null;

return parsedDate;
},

getStateFromProps: function( props ) {
var formats = this.getFormats( props ),
date = props.value || props.defaultValue,
selectedDate, viewDate, updateOn, inputValue
;

if ( date && typeof date === 'string' )
selectedDate = this.localMoment( date, formats.datetime );
else if ( date )
selectedDate = this.localMoment( date );
selectedDate = this.parseDate(date, formats);

if ( selectedDate && !selectedDate.isValid() )
selectedDate = null;
viewDate = this.parseDate(props.viewDate, formats);

viewDate = selectedDate ?
selectedDate.clone().startOf('month') :
this.localMoment().startOf('month')
;
viewDate ? viewDate.clone().startOf('month') : this.localMoment().startOf('month');

updateOn = this.getUpdateOn(formats);

Expand Down Expand Up @@ -152,7 +141,9 @@ var Datetime = createClass({
}

if ( updatedState.open === undefined ) {
if ( this.props.closeOnSelect && this.state.currentView !== 'time' ) {
if ( typeof nextProps.open !== 'undefined' ) {
updatedState.open = nextProps.open;
} else if ( this.props.closeOnSelect && this.state.currentView !== 'time' ) {
updatedState.open = false;
} else {
updatedState.open = this.state.open;
Expand Down Expand Up @@ -376,7 +367,7 @@ var Datetime = createClass({
},

handleClickOutside: function() {
if ( this.props.input && this.state.open && !this.props.open ) {
if ( this.props.input && this.state.open && !this.props.open && !this.props.disableOnClickOutside ) {
this.setState({ open: false }, function() {
this.props.onBlur( this.state.selectedDate || this.state.inputValue );
});
Expand Down Expand Up @@ -462,7 +453,7 @@ var Datetime = createClass({
value: this.state.inputValue,
}, this.props.inputProps);
if ( this.props.renderInput ) {
children = [ React.createElement('div', { key: 'i' }, this.props.renderInput( finalInputProps, this.openCalendar )) ];
children = [ React.createElement('div', { key: 'i' }, this.props.renderInput( finalInputProps, this.openCalendar, this.closeCalendar )) ];
} else {
children = [ React.createElement('input', assign({ key: 'i' }, finalInputProps ))];
}
Expand All @@ -482,6 +473,24 @@ var Datetime = createClass({
}
});

Datetime.defaultProps = {
className: '',
defaultValue: '',
inputProps: {},
input: true,
onFocus: function() {},
onBlur: function() {},
onChange: function() {},
onViewModeChange: function() {},
timeFormat: true,
timeConstraints: {},
dateFormat: true,
strictParsing: true,
closeOnSelect: false,
closeOnTab: true,
utc: false
};

// Make moment accessible through the Datetime class
Datetime.moment = moment;

Expand Down
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
.PHONY: all clean install test
.PHONY: all clean dev install snapshot test test-watch

clean:
rm -rf node_modules

dev:
npm run dev

install:
npm install

snapshot:
npm run test:snapshot:update

test:
npm run test

Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ render: function() {
| ------------ | ------- | ------- | ----------- |
| **value** | `Date` | `new Date()` | Represents the selected date by the component, in order to use it as a [controlled component](https://facebook.github.io/react/docs/forms.html#controlled-components). This prop is parsed by Moment.js, so it is possible to use a date `string` or a `moment` object. |
| **defaultValue** | `Date` | `new Date()` | Represents the selected date for the component to use it as a [uncontrolled component](https://facebook.github.io/react/docs/uncontrolled-components.html). This prop is parsed by Moment.js, so it is possible to use a date `string` or a `moment` object. |
| **viewDate** | `Date` | `new Date()` | Represents the month which is viewed on opening the calendar when there is no selected date. This prop is parsed by Moment.js, so it is possible to use a date `string` or a `moment` object. |
| **dateFormat** | `boolean` or `string` | `true` | Defines the format for the date. It accepts any [Moment.js date format](http://momentjs.com/docs/#/displaying/format/) (not in localized format). If `true` the date will be displayed using the defaults for the current locale. If `false` the datepicker is disabled and the component can be used as timepicker, see [available units docs](#specify-available-units). |
| **timeFormat** | `boolean` or `string` | `true` | Defines the format for the time. It accepts any [Moment.js time format](http://momentjs.com/docs/#/displaying/format/) (not in localized format). If `true` the time will be displayed using the defaults for the current locale. If `false` the timepicker is disabled and the component can be used as datepicker, see [available units docs](#specify-available-units). |
| **input** | `boolean` | `true` | Whether to show an input field to edit the date manually. |
Expand All @@ -56,12 +57,12 @@ render: function() {
| **viewMode** | `string` or `number` | `'days'` | The default view to display when the picker is shown (`'years'`, `'months'`, `'days'`, `'time'`). |
| **className** | `string` or `string array` | `''` | Extra class name for the outermost markup element. |
| **inputProps** | `object` | `undefined` | Defines additional attributes for the input element of the component. For example: `onClick`, `placeholder`, `disabled`, `required`, `name` and `className` (`className` *sets* the class attribute for the input element). See [Customize the Input Appearance](#customize-the-input-appearance). |
| **renderInput** | `function` | `undefined` | Replace the rendering of the input element. The accepted function has `openCalendar` (a function which opens the calendar) and the default calculated `props` for the input. Must return a React component or `null`. See [Customize the Input Appearance](#customize-the-input-appearance). |
| **isValidDate** | `function` | `() => true` | Define the dates that can be selected. The function receives `(currentDate, selectedDate)` and shall return a `true` or `false` whether the `currentDate` is valid or not. See [selectable dates](#selectable-dates).|
| **renderInput** | `function` | `undefined` | Replace the rendering of the input element. The function has the following arguments: the default calculated `props` for the input, `openCalendar` (a function which opens the calendar) and `closeCalendar` (a function which closes the calendar). Must return a React component or `null`. See [Customize the Input Appearance](#customize-the-input-appearance). |
| **renderDay** | `function` | `DOM.td(day)` | Customize the way that the days are shown in the daypicker. The accepted function has the `selectedDate`, the current date and the default calculated `props` for the cell, and must return a React component. See [Customize the Datepicker Appearance](#customize-the-datepicker-appearance). |
| **renderMonth** | `function` | `DOM.td(month)` | Customize the way that the months are shown in the monthpicker. The accepted function has the `selectedDate`, the current date and the default calculated `props` for the cell, the `month` and the `year` to be shown, and must return a React component. See [Customize the Datepicker Appearance](#customize-the-datepicker-appearance). |
| **renderYear** | `function` | `DOM.td(year)` | Customize the way that the years are shown in the year picker. The accepted function has the `selectedDate`, the current date and the default calculated `props` for the cell, the `year` to be shown, and must return a React component. See [Customize the Datepicker Appearance](#customize-the-datepicker-appearance). |
| **strictParsing** | `boolean` | `false` | Whether to use Moment.js's [strict parsing](http://momentjs.com/docs/#/parsing/string-format/) when parsing input.
| **strictParsing** | `boolean` | `true` | Whether to use Moment.js's [strict parsing](http://momentjs.com/docs/#/parsing/string-format/) when parsing input.
| **closeOnSelect** | `boolean` | `false` | When `true`, once the day has been selected, the datepicker will be automatically closed.
| **closeOnTab** | `boolean` | `true` | When `true` and the input is focused, pressing the `tab` key will close the datepicker.
| **timeConstraints** | `object` | `null` | Add some constraints to the timepicker. It accepts an `object` with the format `{ hours: { min: 9, max: 15, step: 2 }}`, this example means the hours can't be lower than `9` and higher than `15`, and it will change adding or subtracting `2` hours everytime the buttons are clicked. The constraints can be added to the `hours`, `minutes`, `seconds` and `milliseconds`.
Expand All @@ -88,7 +89,7 @@ If there are multiple locales loaded, you can use the prop `locale` to define wh
It is possible to customize the way that the input is displayed. The simplest is to supply `inputProps` which get assigned to the default `<input />` element within the component.

```js
<DateTime inputProps={{ placeholder: 'N/A', disabled: true }}>
<Datetime inputProps={{ placeholder: 'N/A', disabled: true }}>
```

Alternatively, if you need to render different content than an `<input />` element, you may supply a `renderInput` function which is called instead.
Expand All @@ -98,14 +99,15 @@ var MyDTPicker = React.createClass({
render: function(){
return <Datetime renderInput={ this.renderInput } />;
},
renderInput: function( props, openCalendar ){
renderInput: function( props, openCalendar, closeCalendar ){
function clear(){
props.onChange({target: {value: ''}});
}
return (
<div>
<input {...props} />
<button onClick={openCalendar}>open calendar</button>
<button onClick={closeCalendar}>close calendar</button>
<button onClick={clear}>clear</button>
</div>
);
Expand Down Expand Up @@ -145,7 +147,7 @@ var MyDTPicker = React.createClass({

## Specify Available Units
You can filter out what you want the user to be able to pick by using `dateFormat` and `timeFormat`, e.g. to create a timepicker, yearpicker etc.

In this example the component is being used as a *timepicker* and can *only be used for selecting a time*.
```js
<Datetime dateFormat={false} />
Expand Down
7 changes: 6 additions & 1 deletion css/react-datetime.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
.rdtPicker .dow {
width: 14.2857%;
border-bottom: none;
cursor: default;
}
.rdtPicker th.rdtSwitch {
width: 100px;
Expand Down Expand Up @@ -230,4 +231,8 @@ td.rdtYear:hover {
.rdtTodayButton.rdtDisabled {
color: #999999;
cursor: not-allowed;
}
}

.rdtTime td {
cursor: default;
}
Loading

0 comments on commit 6b58458

Please sign in to comment.