+
({
alignItems: 'center',
paddingLeft: 16,
paddingRight: 16,
+ justifyContent: 'space-around',
},
separator: {
margin: '0 4px 0 2px',
@@ -132,7 +132,6 @@ const styles = () => ({
flexDirection: 'row-reverse',
},
dateHeader: {
- width: '42%',
height: 65,
},
timeHeader: {
@@ -143,4 +142,4 @@ const styles = () => ({
},
});
-export default withStyles(styles, { withTheme: true })(DateTimePickerHeader);
+export default withStyles(styles, { withTheme: true })(withUtils()(DateTimePickerHeader));
diff --git a/lib/src/DateTimePicker/DateTimePickerWrapper.d.ts b/lib/src/DateTimePicker/index.d.ts
similarity index 85%
rename from lib/src/DateTimePicker/DateTimePickerWrapper.d.ts
rename to lib/src/DateTimePicker/index.d.ts
index 36d669df1..53f201f62 100644
--- a/lib/src/DateTimePicker/DateTimePickerWrapper.d.ts
+++ b/lib/src/DateTimePicker/index.d.ts
@@ -1,10 +1,10 @@
import { ComponentClass, ReactNode } from 'react';
import { DateTimePickerView } from '../constants/date-picker-view';
import { DateType } from '../constants/prop-types';
-import { Utils } from '../utils/utils';
+import { Utils } from '../../typings/utils';
import { RenderDay } from '../DatePicker/Calendar';
import { ModalWrapperProps } from '../wrappers/ModalWrapper';
-import { Moment } from 'moment';
+import { MaterialUiPickersDate } from '../../typings/date'
import { PickerBaseProps } from '../_shared/PickerBase'
import { Omit } from 'material-ui'
@@ -24,7 +24,7 @@ export interface DateTimePickerWrapperProps extends PickerBaseProps,
timeIcon?: ReactNode;
renderDay?: RenderDay;
utils?: Utils;
- shouldDisableDate?: (day: Moment) => boolean;
+ shouldDisableDate?: (day: MaterialUiPickersDate) => boolean;
}
declare const DateTimePickerWrapper: ComponentClass;
diff --git a/lib/src/DateTimePicker/DateTimePickerWrapper.jsx b/lib/src/DateTimePicker/index.jsx
similarity index 94%
rename from lib/src/DateTimePicker/DateTimePickerWrapper.jsx
rename to lib/src/DateTimePicker/index.jsx
index 4e3deb9eb..41c665524 100644
--- a/lib/src/DateTimePicker/DateTimePickerWrapper.jsx
+++ b/lib/src/DateTimePicker/index.jsx
@@ -7,7 +7,7 @@ import DomainPropTypes from '../constants/prop-types';
import ModalWrapper from '../wrappers/ModalWrapper';
import DateTimePicker from './DateTimePicker';
import PickerBase from '../_shared/PickerBase';
-import * as defaultUtils from '../utils/utils';
+import withUtils from '../_shared/WithUtils';
export class DateTimePickerWrapper extends PickerBase {
static propTypes = {
@@ -22,7 +22,6 @@ export class DateTimePickerWrapper extends PickerBase {
minDate: DomainPropTypes.date,
maxDate: DomainPropTypes.date,
showTabs: PropTypes.bool,
- returnMoment: PropTypes.bool,
invalidLabel: PropTypes.string,
leftArrowIcon: PropTypes.node,
rightArrowIcon: PropTypes.node,
@@ -30,7 +29,7 @@ export class DateTimePickerWrapper extends PickerBase {
timeIcon: PropTypes.node,
renderDay: PropTypes.func,
labelFunc: PropTypes.func,
- utils: PropTypes.object,
+ utils: PropTypes.func.isRequired,
ampm: PropTypes.bool,
shouldDisableDate: PropTypes.func,
animateYearScrolling: PropTypes.bool,
@@ -46,7 +45,6 @@ export class DateTimePickerWrapper extends PickerBase {
minDate: undefined,
maxDate: undefined,
showTabs: true,
- returnMoment: true,
invalidLabel: undefined,
leftArrowIcon: undefined,
rightArrowIcon: undefined,
@@ -54,7 +52,6 @@ export class DateTimePickerWrapper extends PickerBase {
timeIcon: undefined,
renderDay: undefined,
labelFunc: undefined,
- utils: defaultUtils,
ampm: true,
shouldDisableDate: undefined,
animateYearScrolling: false,
@@ -77,7 +74,6 @@ export class DateTimePickerWrapper extends PickerBase {
autoSubmit,
disablePast,
disableFuture,
- returnMoment,
invalidLabel,
leftArrowIcon,
rightArrowIcon,
@@ -141,5 +137,5 @@ const styles = {
},
};
-export default withStyles(styles, { name: 'MuiPickerDTPickerModal' })(DateTimePickerWrapper);
+export default withStyles(styles, { name: 'MuiPickerDTPickerModal' })(withUtils()(DateTimePickerWrapper));
diff --git a/lib/src/TimePicker/Clock.jsx b/lib/src/TimePicker/Clock.jsx
index 0d7d4066b..945139557 100644
--- a/lib/src/TimePicker/Clock.jsx
+++ b/lib/src/TimePicker/Clock.jsx
@@ -4,7 +4,7 @@ import withStyles from 'material-ui/styles/withStyles';
import ClockPointer from './ClockPointer';
import * as clockType from '../constants/clock-types';
-import { getMinutes, getHours } from '../utils/time-utils';
+import { getMinutes, getHours } from '../_helpers/time-utils';
export class Clock extends Component {
static propTypes = {
diff --git a/lib/src/TimePicker/HourView.d.ts b/lib/src/TimePicker/HourView.d.ts
index f3f570652..884197f18 100644
--- a/lib/src/TimePicker/HourView.d.ts
+++ b/lib/src/TimePicker/HourView.d.ts
@@ -1,10 +1,10 @@
import { ComponentClass } from 'react';
-import { Utils } from '../utils/utils';
-import { Moment } from 'moment';
+import { Utils } from '../../typings/utils';
+import { MaterialUiPickersDate } from '../../typings/date'
export interface HourViewProps {
- date: Moment;
- onChange: (date: Moment, isFinished?: boolean) => void;
+ date: MaterialUiPickersDate;
+ onChange: (date: MaterialUiPickersDate, isFinished?: boolean) => void;
ampm?: boolean;
utils?: Utils;
}
diff --git a/lib/src/TimePicker/HourView.jsx b/lib/src/TimePicker/HourView.jsx
index 59cbd6ad2..c280f7138 100644
--- a/lib/src/TimePicker/HourView.jsx
+++ b/lib/src/TimePicker/HourView.jsx
@@ -3,26 +3,23 @@ import PropTypes from 'prop-types';
import Clock from './Clock';
import { HOURS } from '../constants/clock-types';
import ClockNumber from './ClockNumber';
-import * as defaultUtils from '../utils/utils';
+import withUtils from '../_shared/WithUtils';
-
-export default class HourView extends PureComponent {
+export class HourView extends PureComponent {
static propTypes = {
date: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
- utils: PropTypes.object,
+ utils: PropTypes.func.isRequired,
ampm: PropTypes.bool,
}
static defaultProps = {
- utils: defaultUtils,
ampm: true,
}
-
getHourNumbers = () => {
const { ampm, utils, date } = this.props;
- const currentHours = date.get('hours');
+ const currentHours = utils.getHours(date);
const hourNumbers = [];
const startHour = ampm ? 1 : 0;
@@ -40,7 +37,6 @@ export default class HourView extends PureComponent {
return currentHours === hour;
};
-
for (let hour = startHour; hour <= endHour; hour += 1) {
let label = hour.toString();
@@ -62,14 +58,15 @@ export default class HourView extends PureComponent {
}
handleChange = (hours, isFinish) => {
- const updatedTime = this.props.date.clone().hour(hours);
+ const { date, utils } = this.props;
+ const updatedTime = utils.setHours(date, hours);
this.props.onChange(updatedTime, isFinish);
}
render() {
- const { date, ampm } = this.props;
- const value = date.get('hours');
+ const { date, ampm, utils } = this.props;
+ const value = utils.getHours(date);
return (
void;
+ date: MaterialUiPickersDate;
+ onChange: (date: MaterialUiPickersDate, isFinished?: boolean) => void;
utils?: Utils;
}
diff --git a/lib/src/TimePicker/MinutesView.jsx b/lib/src/TimePicker/MinutesView.jsx
index 6b066fb25..2b280fefd 100644
--- a/lib/src/TimePicker/MinutesView.jsx
+++ b/lib/src/TimePicker/MinutesView.jsx
@@ -3,21 +3,21 @@ import PropTypes from 'prop-types';
import Clock from './Clock';
import { MINUTES } from '../constants/clock-types';
import ClockNumber from './ClockNumber';
-import * as defaultUtils from '../utils/utils';
+import withUtils from '../_shared/WithUtils';
-export default class MinutesView extends Component {
+export class MinutesView extends Component {
static propTypes = {
date: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
- utils: PropTypes.object,
+ utils: PropTypes.func.isRequired,
}
static defaultProps = {
- utils: defaultUtils,
}
handleChange = (minutes, isFinish) => {
- const updatedDate = this.props.date.clone().minutes(minutes);
+ const { date, utils } = this.props;
+ const updatedDate = utils.setMinutes(date, minutes);
this.props.onChange(updatedDate, isFinish);
}
@@ -25,7 +25,7 @@ export default class MinutesView extends Component {
const { date, utils } = this.props;
const f = utils.formatNumber;
- const value = date.get('minutes');
+ const value = utils.getMinutes(date);
return (
void;
+ date: MaterialUiPickersDate;
+ onChange: (date: MaterialUiPickersDate, isFinished?: boolean) => void;
ampm?: boolean;
utils?: Utils;
}
diff --git a/lib/src/TimePicker/TimePicker.jsx b/lib/src/TimePicker/TimePicker.jsx
index 07fb52126..eb44b51de 100644
--- a/lib/src/TimePicker/TimePicker.jsx
+++ b/lib/src/TimePicker/TimePicker.jsx
@@ -5,8 +5,8 @@ import PickerToolbar from '../_shared/PickerToolbar';
import ToolbarButton from '../_shared/ToolbarButton';
import HourView from './HourView';
import MinutesView from './MinutesView';
-import { convertToMeridiem } from '../utils/time-utils';
-import * as defaultUtils from '../utils/utils';
+import { convertToMeridiem } from '../_helpers/time-utils';
+import withUtils from '../_shared/WithUtils';
export class TimePicker extends Component {
static propTypes = {
@@ -15,19 +15,18 @@ export class TimePicker extends Component {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
children: PropTypes.node,
- utils: PropTypes.object,
+ utils: PropTypes.func.isRequired,
ampm: PropTypes.bool,
}
static defaultProps = {
children: null,
- utils: defaultUtils,
ampm: true,
}
state = {
isHourViewShown: true,
- meridiemMode: this.props.date.hours() >= 12 ? 'pm' : 'am',
+ meridiemMode: this.props.utils.getHours(this.props.date) >= 12 ? 'pm' : 'am',
}
setMeridiemMode = mode => () => {
@@ -38,7 +37,12 @@ export class TimePicker extends Component {
}
handleChange(time, isFinish, openMinutes) {
- const withMeridiem = convertToMeridiem(time, this.state.meridiemMode, this.props.ampm);
+ const withMeridiem = convertToMeridiem(
+ time,
+ this.state.meridiemMode,
+ this.props.ampm,
+ this.props.utils,
+ );
if (isFinish) {
if (!openMinutes) {
@@ -186,4 +190,4 @@ const styles = () => ({
export default withStyles(
styles,
{ withTheme: true, name: 'MuiPickersTimePicker' },
-)(TimePicker);
+)(withUtils()(TimePicker));
diff --git a/lib/src/TimePicker/TimePickerWrapper.d.ts b/lib/src/TimePicker/index.d.ts
similarity index 90%
rename from lib/src/TimePicker/TimePickerWrapper.d.ts
rename to lib/src/TimePicker/index.d.ts
index 1e93b6edd..a2b9071d4 100644
--- a/lib/src/TimePicker/TimePickerWrapper.d.ts
+++ b/lib/src/TimePicker/index.d.ts
@@ -1,5 +1,5 @@
import { ComponentClass } from 'react';
-import { Utils } from '../utils/utils';
+import { Utils } from '../../typings/utils';
import { ModalWrapperProps } from '../wrappers/ModalWrapper';
import { PickerBaseProps } from '../_shared/PickerBase'
import { Omit } from 'material-ui'
diff --git a/lib/src/TimePicker/TimePickerWrapper.jsx b/lib/src/TimePicker/index.jsx
similarity index 80%
rename from lib/src/TimePicker/TimePickerWrapper.jsx
rename to lib/src/TimePicker/index.jsx
index 6e91555d1..0957cfbc4 100644
--- a/lib/src/TimePicker/TimePickerWrapper.jsx
+++ b/lib/src/TimePicker/index.jsx
@@ -4,9 +4,9 @@ import PropTypes from 'prop-types';
import ModalWrapper from '../wrappers/ModalWrapper';
import TimePicker from './TimePicker';
import PickerBase from '../_shared/PickerBase';
-import * as defaultUtils from '../utils/utils';
+import withUtils from '../_shared/WithUtils';
-export default class TimePickerWrapper extends PickerBase {
+export class TimePickerWrapper extends PickerBase {
static propTypes = {
value: PropTypes.oneOfType([
PropTypes.object,
@@ -17,9 +17,8 @@ export default class TimePickerWrapper extends PickerBase {
format: PropTypes.string,
onChange: PropTypes.func.isRequired,
autoOk: PropTypes.bool,
- returnMoment: PropTypes.bool,
invalidLabel: PropTypes.string,
- utils: PropTypes.object,
+ utils: PropTypes.func.isRequired,
ampm: PropTypes.bool,
}
@@ -27,9 +26,7 @@ export default class TimePickerWrapper extends PickerBase {
value: new Date(),
format: undefined,
autoOk: false,
- returnMoment: true,
invalidLabel: undefined,
- utils: defaultUtils,
ampm: true,
}
@@ -39,8 +36,7 @@ export default class TimePickerWrapper extends PickerBase {
render() {
const { date } = this.state;
const {
- value, format, autoOk, onChange, returnMoment, invalidLabel,
- utils, ampm, ...other
+ value, format, autoOk, onChange, invalidLabel, utils, ampm, ...other
} = this.props;
return (
@@ -65,3 +61,6 @@ export default class TimePickerWrapper extends PickerBase {
);
}
}
+
+export default withUtils()(TimePickerWrapper);
+
diff --git a/lib/src/utils/time-utils.js b/lib/src/_helpers/time-utils.js
similarity index 83%
rename from lib/src/utils/time-utils.js
rename to lib/src/_helpers/time-utils.js
index 4dedf4552..affd5f17b 100644
--- a/lib/src/utils/time-utils.js
+++ b/lib/src/_helpers/time-utils.js
@@ -54,15 +54,15 @@ export const getMinutes = (offsetX, offsetY, step = 6) => {
return value;
};
-export const convertToMeridiem = (time, meridiem, ampm) => {
+export const convertToMeridiem = (time, meridiem, ampm, utils) => {
if (ampm) {
- const currentMeridiem = time.hours() >= 12 ? 'pm' : 'am';
+ const currentMeridiem = utils.getHours(time) >= 12 ? 'pm' : 'am';
if (currentMeridiem !== meridiem) {
const hours = meridiem === 'am'
- ? time.hours() - 12
- : time.hours() + 12;
+ ? utils.getHours(time) - 12
+ : utils.getHours(time) + 12;
- return time.clone().hours(hours);
+ return utils.setHours(time, hours);
}
}
diff --git a/lib/src/_shared/DateTextField.jsx b/lib/src/_shared/DateTextField.jsx
index 2823907d4..d0a9aaf24 100644
--- a/lib/src/_shared/DateTextField.jsx
+++ b/lib/src/_shared/DateTextField.jsx
@@ -1,7 +1,6 @@
/* eslint-disable react/sort-comp */
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
-import moment from 'moment';
import Icon from 'material-ui/Icon';
import InputAdornment from 'material-ui/Input/InputAdornment';
import TextField from 'material-ui/TextField';
@@ -10,8 +9,9 @@ import withStyles from 'material-ui/styles/withStyles';
import DomainPropTypes from '../constants/prop-types';
import MaskedInput from './MaskedInput';
+import withUtils from '../_shared/WithUtils';
-class DateTextField extends PureComponent {
+export class DateTextField extends PureComponent {
static propTypes = {
classes: PropTypes.shape({}).isRequired,
value: PropTypes.oneOfType([
@@ -41,6 +41,9 @@ class DateTextField extends PureComponent {
invalidDateMessage: PropTypes.string,
clearable: PropTypes.bool,
TextFieldComponent: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
+ utils: PropTypes.func.isRequired,
+ InputAdornmentProps: PropTypes.object,
+ adornmentPosition: PropTypes.oneOf(['start', 'end']),
}
static defaultProps = {
@@ -64,15 +67,17 @@ class DateTextField extends PureComponent {
minDateMessage: 'Date should not be before minimal date',
maxDateMessage: 'Date should not be after maximal date',
TextFieldComponent: TextField,
+ InputAdornmentProps: {},
+ adornmentPosition: 'end',
}
getDisplayDate = (props) => {
const {
- value, format, invalidLabel, emptyLabel, labelFunc,
+ utils, value, format, invalidLabel, emptyLabel, labelFunc,
} = props;
const isEmpty = value === null;
- const date = moment(value);
+ const date = utils.date(value);
if (labelFunc) {
return labelFunc(isEmpty ? null : date, invalidLabel);
@@ -82,13 +87,14 @@ class DateTextField extends PureComponent {
return emptyLabel;
}
- return date.isValid()
- ? date.format(format)
+ return utils.isValid(date)
+ ? utils.format(date, format)
: invalidLabel;
}
- getError = (value) => {
+ getError = (value, props = this.props) => {
const {
+ utils,
maxDate,
minDate,
disablePast,
@@ -96,26 +102,26 @@ class DateTextField extends PureComponent {
maxDateMessage,
minDateMessage,
invalidDateMessage,
- } = this.props;
+ } = props;
- if (!value.isValid()) {
+ if (!utils.isValid(value)) {
// if null - do not show error
- if (value.parsingFlags().nullInput) {
+ if (utils.isNull(value)) {
return '';
}
return invalidDateMessage;
}
if (
- (maxDate && value.isAfter(maxDate)) ||
- (disableFuture && value.isAfter(moment().endOf('day')))
+ (maxDate && utils.isAfter(value, maxDate)) ||
+ (disableFuture && utils.isAfter(value, utils.endOfDay(utils.date())))
) {
return maxDateMessage;
}
if (
- (minDate && value.isBefore(minDate)) ||
- (disablePast && value.isBefore(moment().startOf('day')))
+ (minDate && utils.isBefore(value, minDate)) ||
+ (disablePast && utils.isBefore(value, utils.startOfDay(utils.date())))
) {
return minDateMessage;
}
@@ -126,7 +132,7 @@ class DateTextField extends PureComponent {
updateState = (props = this.props) => ({
value: props.value,
displayValue: this.getDisplayDate(props),
- error: this.getError(moment(props.value)),
+ error: this.getError(props.utils.date(props.value)),
})
state = this.updateState()
@@ -134,7 +140,9 @@ class DateTextField extends PureComponent {
componentWillReceiveProps(nextProps) {
if (
nextProps.value !== this.state.value ||
- nextProps.format !== this.props.format
+ nextProps.format !== this.props.format ||
+ nextProps.maxDate !== this.props.maxDate ||
+ nextProps.minDate !== this.props.minDate
) {
this.setState(this.updateState(nextProps));
}
@@ -147,9 +155,10 @@ class DateTextField extends PureComponent {
handleChange = (e) => {
const {
- format,
clearable,
onClear,
+ utils,
+ format,
} = this.props;
if (clearable && e.target.value === '') {
@@ -162,8 +171,9 @@ class DateTextField extends PureComponent {
return;
}
- const oldValue = moment(this.state.value);
- const newValue = moment(e.target.value, format, true);
+ const oldValue = utils.date(this.state.value);
+ const newValue = utils.parse(e.target.value, format);
+
const error = this.getError(newValue);
this.setState({
@@ -171,8 +181,8 @@ class DateTextField extends PureComponent {
value: error ? newValue : oldValue,
error,
}, () => {
- if (!error && newValue.format('LLLL') !== oldValue.format('LLLL')) {
- this.props.onChange(newValue, true);
+ if (!error && utils.format(newValue, 'LLLL') !== utils.format(oldValue, 'LLLL')) {
+ this.props.onChange(newValue);
}
});
}
@@ -187,7 +197,6 @@ class DateTextField extends PureComponent {
}
e.target.blur();
-
this.openPicker(e);
}
@@ -207,6 +216,7 @@ class DateTextField extends PureComponent {
render() {
const {
+ utils,
format,
classes,
disabled,
@@ -229,22 +239,24 @@ class DateTextField extends PureComponent {
maxDateMessage,
minDateMessage,
TextFieldComponent,
+ InputAdornmentProps,
+ adornmentPosition,
...other
} = this.props;
- const { displayValue, error } = this.state;
+ const { displayValue, error } = this.state;
const localInputProps = {
inputComponent: MaskedInput,
inputProps: {
- mask: value === null ? null : mask,
+ mask: !keyboard ? null : mask,
readOnly: !keyboard,
},
className: classes.input,
};
if (keyboard) {
- localInputProps.endAdornment = (
-
+ localInputProps[`${adornmentPosition}Adornment`] = (
+
{keyboardIcon}
);
@@ -273,4 +285,4 @@ const styles = {
},
};
-export default withStyles(styles)(DateTextField);
+export default withStyles(styles)(withUtils()(DateTextField));
diff --git a/lib/src/_shared/ModalDialog.d.ts b/lib/src/_shared/ModalDialog.d.ts
index 2fb32508b..c457e958d 100644
--- a/lib/src/_shared/ModalDialog.d.ts
+++ b/lib/src/_shared/ModalDialog.d.ts
@@ -1,6 +1,6 @@
import { ComponentClass, ReactNode } from 'react';
import { DateType } from '../constants/prop-types';
-import { Utils } from '../utils/utils';
+import { Utils } from '../../typings/utils';
import { DialogProps } from 'material-ui/Dialog';
import { ButtonProps } from 'material-ui/Button';
diff --git a/lib/src/_shared/PickerBase.d.ts b/lib/src/_shared/PickerBase.d.ts
index b112ccec4..05944a47c 100644
--- a/lib/src/_shared/PickerBase.d.ts
+++ b/lib/src/_shared/PickerBase.d.ts
@@ -1,8 +1,8 @@
import {Moment} from 'moment'
+import { DateTextFieldProps } from './ModalDialog';
export interface PickerBaseProps {
onChange: (date: Date | Moment) => void;
autoOk?: boolean;
- returnMoment?: boolean;
ampm?: boolean;
}
\ No newline at end of file
diff --git a/lib/src/_shared/PickerBase.jsx b/lib/src/_shared/PickerBase.jsx
index 3bfdc9b37..08160acac 100644
--- a/lib/src/_shared/PickerBase.jsx
+++ b/lib/src/_shared/PickerBase.jsx
@@ -1,33 +1,25 @@
import { PureComponent } from 'react';
import PropTypes from 'prop-types';
-import moment from 'moment';
import DomainPropTypes from '../constants/prop-types';
/* eslint-disable react/sort-comp */
+/* eslint-disable react/require-default-props */
export default class PickerBase extends PureComponent {
static propTypes = {
value: DomainPropTypes.date,
onChange: PropTypes.func.isRequired,
autoOk: PropTypes.bool,
- returnMoment: PropTypes.bool,
format: PropTypes.string,
labelFunc: PropTypes.func,
ampm: PropTypes.bool,
+ utils: PropTypes.func.isRequired,
}
- static defaultProps = {
- value: new Date(),
- autoOk: false,
- returnMoment: false,
- labelFunc: undefined,
- format: undefined,
- ampm: true,
- }
-
- getValidDateOrCurrent = (props = this.props) => {
- const date = moment(props.value);
+ getValidDateOrCurrent = () => {
+ const { utils, value } = this.props;
+ const date = utils.date(value);
- return date.isValid() ? date : moment();
+ return utils.isValid(date) ? date : utils.date();
}
state = {
@@ -35,7 +27,7 @@ export default class PickerBase extends PureComponent {
}
componentWillReceiveProps(nextProps) {
- if (this.props.value !== nextProps.value) {
+ if (!this.props.utils.isEqual(this.state.date, nextProps.value)) {
this.setState({ date: this.getValidDateOrCurrent(nextProps) });
}
}
@@ -57,11 +49,7 @@ export default class PickerBase extends PureComponent {
}
handleAccept = () => {
- const dateToReturn = this.props.returnMoment
- ? this.state.date
- : this.state.date.toDate();
-
- this.props.onChange(dateToReturn);
+ this.props.onChange(this.state.date);
}
handleDismiss = () => {
diff --git a/lib/src/_shared/WithUtils.jsx b/lib/src/_shared/WithUtils.jsx
new file mode 100644
index 000000000..19aa069f8
--- /dev/null
+++ b/lib/src/_shared/WithUtils.jsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const withUtils = () => (Component) => {
+ const WithUtils = (props, context) => {
+ if (!context.muiPickersDateUtils) {
+ // eslint-disable-next-line no-console
+ console.error('Utils should be provided');
+ }
+
+ return ;
+ };
+
+ WithUtils.contextTypes = {
+ muiPickersDateUtils: PropTypes.func,
+ };
+
+ WithUtils.displayName = `withUtils${Component.displayName || Component.name}`;
+
+ return WithUtils;
+};
+
+export default withUtils;
diff --git a/lib/src/index.d.ts b/lib/src/index.d.ts
index 50298e750..b8d24c1b2 100644
--- a/lib/src/index.d.ts
+++ b/lib/src/index.d.ts
@@ -1,5 +1,6 @@
-export { Utils } from './utils/utils';
+export { default as dateFnsUtils } from './utils/date-fns-utils'
+export { default as momentUtils } from './utils/moment-utils'
-export { default as DatePicker } from './DatePicker/DatePickerWrapper';
-export { default as TimePicker } from './TimePicker/TimePickerWrapper';
-export { default as DateTimePicker } from './DateTimePicker/DateTimePickerWrapper';
+export { default as DatePicker } from './DatePicker';
+export { default as TimePicker } from './TimePicker';
+export { default as DateTimePicker } from './DateTimePicker';
diff --git a/lib/src/index.js b/lib/src/index.js
index 173f5b6cc..28cf64ebe 100644
--- a/lib/src/index.js
+++ b/lib/src/index.js
@@ -1,5 +1,11 @@
-export { default as DatePicker } from './DatePicker/DatePickerWrapper';
+export { default as DatePicker } from './DatePicker';
-export { default as TimePicker } from './TimePicker/TimePickerWrapper';
+export { default as TimePicker } from './TimePicker';
-export { default as DateTimePicker } from './DateTimePicker/DateTimePickerWrapper';
+export { default as DateTimePicker } from './DateTimePicker';
+
+export { default as MuiPickersUtilsProvider } from './utils/MuiPickersUtilsProvider';
+
+export { default as dateFnsUtils } from './utils/date-fns-utils';
+
+export { default as momentUtils } from './utils/moment-utils';
diff --git a/lib/src/utils/MuiPickersUtilsProvider.d.ts b/lib/src/utils/MuiPickersUtilsProvider.d.ts
new file mode 100644
index 000000000..9f7d2b2af
--- /dev/null
+++ b/lib/src/utils/MuiPickersUtilsProvider.d.ts
@@ -0,0 +1,12 @@
+import { ComponentClass, ReactNode } from 'react';
+import { DateTimePickerView } from '../constants/date-picker-view';
+import { Utils } from '../../typings/utils';
+
+export interface MuiPickersUtilsProviderProps {
+ utils: Utils;
+ children: ReactNode;
+}
+
+declare const MuiPickersUtilsProvider: ComponentClass;
+
+export default MuiPickersUtilsProvider;
diff --git a/lib/src/utils/MuiPickersUtilsProvider.jsx b/lib/src/utils/MuiPickersUtilsProvider.jsx
new file mode 100644
index 000000000..1ae3fb50b
--- /dev/null
+++ b/lib/src/utils/MuiPickersUtilsProvider.jsx
@@ -0,0 +1,23 @@
+import { PureComponent } from 'react';
+import PropTypes from 'prop-types';
+
+export default class MuiPickersUtilsProvider extends PureComponent {
+ static propTypes = {
+ utils: PropTypes.func.isRequired,
+ children: PropTypes.element.isRequired,
+ }
+
+ static childContextTypes = {
+ muiPickersDateUtils: PropTypes.func,
+ }
+
+ getChildContext() {
+ return {
+ muiPickersDateUtils: this.props.utils,
+ };
+ }
+
+ render() {
+ return this.props.children;
+ }
+}
diff --git a/lib/src/utils/date-fns-utils.d.ts b/lib/src/utils/date-fns-utils.d.ts
new file mode 100644
index 000000000..d99f7eead
--- /dev/null
+++ b/lib/src/utils/date-fns-utils.d.ts
@@ -0,0 +1,4 @@
+import { Utils } from '../../typings/utils'
+
+declare const DateFnsUtils: Utils;
+export default DateFnsUtils
\ No newline at end of file
diff --git a/lib/src/utils/date-fns-utils.js b/lib/src/utils/date-fns-utils.js
new file mode 100644
index 000000000..5b6512d06
--- /dev/null
+++ b/lib/src/utils/date-fns-utils.js
@@ -0,0 +1,167 @@
+import parse from 'date-fns/parse';
+import addDays from 'date-fns/addDays';
+import addMonths from 'date-fns/addMonths';
+import addYears from 'date-fns/addYears';
+import endOfDay from 'date-fns/endOfDay';
+import endOfMonth from 'date-fns/endOfMonth';
+import endOfWeek from 'date-fns/endOfWeek';
+import endOfYear from 'date-fns/endOfYear';
+import format from 'date-fns/format';
+import isAfter from 'date-fns/isAfter';
+import isBefore from 'date-fns/isBefore';
+import isSameDay from 'date-fns/isSameDay';
+import isValid from 'date-fns/isValid';
+import setDay from 'date-fns/setDay';
+import setHours from 'date-fns/setHours';
+import setMinutes from 'date-fns/setMinutes';
+import setYear from 'date-fns/setYear';
+import startOfDay from 'date-fns/startOfDay';
+import startOfMonth from 'date-fns/startOfMonth';
+import startOfWeek from 'date-fns/startOfWeek';
+import startOfYear from 'date-fns/startOfYear';
+import getHours from 'date-fns/getHours';
+import getYear from 'date-fns/getYear';
+import isEqual from 'date-fns/isEqual';
+
+export default class DateFnsUtils {
+ static date = value => new Date(value)
+
+ static parse = (value, formatString) => parse(value, formatString, new Date())
+
+ static addDays = addDays
+
+ static isValid = isValid
+
+ static isEqual = isEqual
+
+ static isNull(date) {
+ return date == null;
+ }
+
+ static isAfter = isAfter
+
+ static isBefore = isBefore
+
+ static isAfterDay(date, value) {
+ return isAfter(endOfDay(date), value);
+ }
+
+ static isBeforeDay(date, value) {
+ return isBefore(date, startOfDay(value));
+ }
+
+ static isBeforeYear(date, value) {
+ return isBefore(date, startOfYear(value));
+ }
+
+ static isAfterYear(date, value) {
+ return isAfter(endOfYear(date), value);
+ }
+
+ static startOfDay = startOfDay
+
+ static endOfDay = endOfDay
+
+ static format = format
+
+ static formatNumber(num) {
+ return num;
+ }
+
+ static getHours = getHours
+
+ static setHours = setHours
+
+ static getMinutes(date) {
+ return date.getMinutes();
+ }
+
+ static setMinutes = setMinutes
+
+ static getMonth(date) {
+ return date.getMonth();
+ }
+
+ static isSameDay = isSameDay;
+
+ static getMeridiemText(ampm) {
+ return ampm === 'am' ? 'AM' : 'PM';
+ }
+
+ static getStartOfMonth = startOfMonth
+
+ static getNextMonth(date) {
+ return addMonths(date, 1);
+ }
+
+ static getPreviousMonth(date) {
+ return addMonths(date, -1);
+ }
+
+ static getYear = getYear
+
+ static setYear = setYear;
+
+ static getWeekdays() {
+ return [0, 1, 2, 3, 4, 5, 6].map(dayOfWeek => format(setDay(new Date(), dayOfWeek), 'dd'));
+ }
+
+ static getWeekArray(date) {
+ const start = startOfWeek(startOfMonth(date));
+ const end = endOfWeek(endOfMonth(date));
+
+ const nestedWeeks = [];
+ let count = 0;
+ let current = start;
+ while (isBefore(current, end)) {
+ const weekNumber = Math.floor(count / 7);
+ nestedWeeks[weekNumber] = nestedWeeks[weekNumber] || [];
+ nestedWeeks[weekNumber].push(current);
+ current = addDays(current, 1);
+ count += 1;
+ }
+
+ return nestedWeeks;
+ }
+
+ static getYearRange(start, end) {
+ const startDate = new Date(start);
+ const endDate = new Date(end);
+ const years = [];
+ let current = startDate;
+ while (isBefore(current, endDate)) {
+ years.push(current);
+ current = addYears(current, 1);
+ }
+ return years;
+ }
+
+ // displaying methpds
+ static getCalendarHeaderText(date) {
+ return format(date, 'MMMM YYYY');
+ }
+
+ static getYearText(date) {
+ return format(date, 'YYYY');
+ }
+
+ static getDatePickerHeaderText(date) {
+ return format(date, 'ddd, MMM D');
+ }
+
+ static getDateTimePickerHeaderText(date) {
+ return format(date, 'MMM D');
+ }
+
+ static getDayText(date) {
+ return format(date, 'D');
+ }
+
+ static getHourText(date, ampm) {
+ return format(date, ampm ? 'hh' : 'HH');
+ }
+
+ static getMinuteText(date) {
+ return format(date, 'mm');
+ }
+}
diff --git a/lib/src/utils/moment-utils.d.ts b/lib/src/utils/moment-utils.d.ts
new file mode 100644
index 000000000..2140e1e97
--- /dev/null
+++ b/lib/src/utils/moment-utils.d.ts
@@ -0,0 +1,4 @@
+import { Utils } from '../../typings/utils'
+
+declare const MomentUtils: Utils;
+export default MomentUtils
\ No newline at end of file
diff --git a/lib/src/utils/moment-utils.js b/lib/src/utils/moment-utils.js
new file mode 100644
index 000000000..a499e3ea0
--- /dev/null
+++ b/lib/src/utils/moment-utils.js
@@ -0,0 +1,180 @@
+import moment from 'moment';
+
+export default class MomentUtils {
+ static parse = moment
+
+ static date(value, formatString) {
+ return moment(value, formatString);
+ }
+
+ static isValid(date) {
+ return date.isValid();
+ }
+
+ static isNull(date) {
+ return date.parsingFlags().nullInput;
+ }
+
+ static isAfter(date, value) {
+ return date.isAfter(value);
+ }
+
+ static isBefore(date, value) {
+ return date.isBefore(value);
+ }
+
+ static isAfterDay(date, value) {
+ return date.isAfter(value, 'day');
+ }
+
+ static isBeforeDay(date, value) {
+ return date.isBefore(value, 'day');
+ }
+
+ static isBeforeYear(date, value) {
+ return date.isBefore(value, 'year');
+ }
+
+ static isAfterYear(date, value) {
+ return date.isAfter(value, 'year');
+ }
+
+ static startOfDay(date) {
+ return date.startOf('day');
+ }
+
+ static endOfDay(date) {
+ return date.endOf('day');
+ }
+
+ static format(date, formatString) {
+ return date.format(formatString);
+ }
+
+ static formatNumber(num) {
+ return num;
+ }
+
+ static getHours(date) {
+ return date.get('hours');
+ }
+
+ static addDays(date, count) {
+ return count < 0
+ ? date.clone().subtract(Math.abs(count), 'days')
+ : date.clone().add(count, 'days');
+ }
+
+ static setHours(date, value) {
+ return date.clone().hours(value);
+ }
+
+ static getMinutes(date) {
+ return date.get('minutes');
+ }
+
+ static setMinutes(date, value) {
+ return date.clone().minutes(value);
+ }
+
+ static getMonth(date) {
+ return date.get('month');
+ }
+
+ static isSameDay(date, comparing) {
+ return date.isSame(comparing, 'day');
+ }
+
+ static getMeridiemText(ampm) {
+ return ampm === 'am' ? 'AM' : 'PM';
+ }
+
+ static getStartOfMonth(date) {
+ return date.clone().startOf('month');
+ }
+
+ static getNextMonth(date) {
+ return date.clone().add(1, 'month');
+ }
+
+ static getPreviousMonth(date) {
+ return date.clone().subtract(1, 'month');
+ }
+
+ static getYear(date) {
+ return date.get('year');
+ }
+
+ static setYear(date, year) {
+ return date.clone().set('year', year);
+ }
+
+ static getWeekdays() {
+ return [0, 1, 2, 3, 4, 5, 6].map(dayOfWeek => moment().weekday(dayOfWeek).format('dd')[0]);
+ }
+
+ static isEqual(value, comparing) {
+ return moment(value).isSame(comparing);
+ }
+
+ static getWeekArray(date) {
+ const start = date.clone().startOf('month').startOf('week');
+ const end = date.clone().endOf('month').endOf('week');
+
+ const nestedWeeks = [];
+ let count = 0;
+ let current = start;
+ while (current.isBefore(end)) {
+ const weekNumber = Math.floor(count / 7);
+ nestedWeeks[weekNumber] = nestedWeeks[weekNumber] || [];
+ nestedWeeks[weekNumber].push(current);
+ current = current.clone().add(1, 'day');
+ count += 1;
+ }
+
+ return nestedWeeks;
+ }
+
+ static getYearRange(start, end) {
+ const startDate = moment(start);
+ const endDate = moment(end);
+ const years = [];
+
+ let current = startDate;
+ while (current.isBefore(endDate)) {
+ years.push(current);
+ current = current.clone().add(1, 'year');
+ }
+
+ return years;
+ }
+
+ // displaying methods
+ static getCalendarHeaderText(date) {
+ return date.format('MMMM YYYY');
+ }
+
+ static getYearText(date) {
+ return date.format('YYYY');
+ }
+
+ static getDatePickerHeaderText(date) {
+ return date.format('ddd, MMM D');
+ }
+
+ static getDateTimePickerHeaderText(date) {
+ return date.format('MMM D');
+ }
+
+ static getDayText(date) {
+ return date.format('D');
+ }
+
+ static getHourText(date, ampm) {
+ return date.format(ampm ? 'hh' : 'HH');
+ }
+
+ static getMinuteText(date) {
+ return date.format('mm');
+ }
+}
diff --git a/lib/src/utils/utils.d.ts b/lib/src/utils/utils.d.ts
deleted file mode 100644
index 9d008ffce..000000000
--- a/lib/src/utils/utils.d.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-export declare function formatNumber(num: string): string;
-export declare function getCalendarHeaderText(date: any): string;
-export declare function getDatePickerHeaderText(date: any): string;
-export declare function getDateTimePickerHeaderText(date: any): string;
-export declare function getDayText(date: any): string;
-export declare function getHourText(date: any): string;
-export declare function getMinuteText(date: any): string;
-export declare function getMeridiemText(ampm: 'am' | 'pm'): string;
-export declare function getYearText(date: any): string;
-export declare function getMonthNumber(date: any): number;
-export declare function getStartOfMonth(date: any): any;
-export declare function getNextMonth(date: any): any;
-export declare function getPreviousMonth(date: any): any;
-export declare function getYear(date: any): any;
-export declare function setYear(date: any, year: number): any;
-export declare function getWeekdays(): string[];
-export declare function getWeekArray(date: any): any[][];
-
-export interface Utils {
- formatNumber: typeof formatNumber;
- getCalendarHeaderText: typeof getCalendarHeaderText;
- getDatePickerHeaderText: typeof getDatePickerHeaderText;
- getDateTimePickerHeaderText: typeof getDateTimePickerHeaderText;
- getDayText: typeof getDayText;
- getHourText: typeof getHourText;
- getMinuteText: typeof getMinuteText;
- getMeridiemText: typeof getMeridiemText;
- getYearText: typeof getYearText;
- getMonthNumber: typeof getMonthNumber;
- getStartOfMonth: typeof getStartOfMonth;
- getNextMonth: typeof getNextMonth;
- getPreviousMonth: typeof getPreviousMonth;
- getYear: typeof getYear;
- setYear: typeof setYear;
- getWeekdays: typeof getWeekdays;
- getWeekArray: typeof getWeekArray;
-}
diff --git a/lib/src/utils/utils.js b/lib/src/utils/utils.js
deleted file mode 100644
index b29549cf6..000000000
--- a/lib/src/utils/utils.js
+++ /dev/null
@@ -1,84 +0,0 @@
-import Moment from 'moment';
-import { extendMoment } from 'moment-range';
-
-const moment = extendMoment(Moment);
-
-export function formatNumber(num) {
- return num;
-}
-
-export function getCalendarHeaderText(date) {
- return date.format('MMMM YYYY');
-}
-
-export function getDatePickerHeaderText(date) {
- return date.format('ddd, MMM D');
-}
-
-export function getDateTimePickerHeaderText(date) {
- return date.format('MMM D');
-}
-
-export function getDayText(date) {
- return date.format('D');
-}
-
-export function getHourText(date, ampm) {
- return date.format(ampm ? 'hh' : 'HH');
-}
-
-export function getMinuteText(date) {
- return date.format('mm');
-}
-
-export function getMeridiemText(ampm) {
- return ampm === 'am' ? 'AM' : 'PM';
-}
-
-export function getYearText(date) {
- return date.format('YYYY');
-}
-
-export function getMonthNumber(date) {
- return date.get('month');
-}
-
-export function getStartOfMonth(date) {
- return date.clone().startOf('month');
-}
-
-export function getNextMonth(date) {
- return date.clone().add(1, 'month');
-}
-
-export function getPreviousMonth(date) {
- return date.clone().subtract(1, 'month');
-}
-
-export function getYear(date) {
- return date.get('year');
-}
-
-export function setYear(date, year) {
- return date.clone().set('year', year);
-}
-
-export function getWeekdays() {
- return [0, 1, 2, 3, 4, 5, 6].map(dayOfWeek => moment().weekday(dayOfWeek).format('dd')[0]);
-}
-
-export function getWeekArray(date) {
- const start = date.clone().startOf('month').startOf('week');
- const end = date.clone().endOf('month').endOf('week');
-
- const weeks = Array.from(moment.range(start, end).by('week'));
-
- const nestedWeeks = [];
-
- weeks.forEach((week) => {
- const endOfWeek = week.clone().endOf('week');
- nestedWeeks.push(Array.from(moment.range(week, endOfWeek).by('day')));
- });
-
- return nestedWeeks;
-}
diff --git a/lib/typings/date.ts b/lib/typings/date.ts
new file mode 100644
index 000000000..d60b25bab
--- /dev/null
+++ b/lib/typings/date.ts
@@ -0,0 +1,4 @@
+import { Moment } from 'moment';
+
+// 21.02.2018 - TODO type date, if there would be any way to dynamicly type Moment | Date
+export type MaterialUiPickersDate = any
\ No newline at end of file
diff --git a/lib/typings/utils.ts b/lib/typings/utils.ts
new file mode 100644
index 000000000..27daab0d9
--- /dev/null
+++ b/lib/typings/utils.ts
@@ -0,0 +1,42 @@
+import { MaterialUiPickersDate } from './date'
+
+export interface Utils {
+ date(value: any): MaterialUiPickersDate;
+ addDays(value: MaterialUiPickersDate, count: number): MaterialUiPickersDate;
+ isValid(value: MaterialUiPickersDate): boolean;
+ isEqual(value: MaterialUiPickersDate, comparing: MaterialUiPickersDate): boolean;
+ isNull(value: MaterialUiPickersDate): boolean;
+ isAfter(value: MaterialUiPickersDate, comparing: MaterialUiPickersDate): boolean;
+ isAfterDay(value: MaterialUiPickersDate, comparing: MaterialUiPickersDate): boolean;
+ isBeforeDay(value: MaterialUiPickersDate, comparing: MaterialUiPickersDate): boolean;
+ isBeforeYear(value: MaterialUiPickersDate, comparing: MaterialUiPickersDate): boolean;
+ isAfterYear(value: MaterialUiPickersDate, comparing: MaterialUiPickersDate): boolean;
+ startOfDay(value: MaterialUiPickersDate): MaterialUiPickersDate;
+ endOfDay(value: MaterialUiPickersDate): MaterialUiPickersDate;
+ format(value: MaterialUiPickersDate, formatString: string): string;
+ formatNumber(number: number): string;
+ getHours(value: MaterialUiPickersDate): number;
+ setHours(value: MaterialUiPickersDate, count: number): MaterialUiPickersDate;
+ getMinutes(value: MaterialUiPickersDate): number;
+ setMinutes(value: MaterialUiPickersDate, count: number): MaterialUiPickersDate
+ getMonth(value: MaterialUiPickersDate): number;
+ isSameDay(value: MaterialUiPickersDate, comparing: MaterialUiPickersDate): boolean
+ getStartOfMonth(value: MaterialUiPickersDate): MaterialUiPickersDate;
+ getNextMonth(value: MaterialUiPickersDate): MaterialUiPickersDate;
+ getPreviousMonth(value: MaterialUiPickersDate): MaterialUiPickersDate;
+ getYear(value: MaterialUiPickersDate): number;
+ setYear(value: MaterialUiPickersDate): MaterialUiPickersDate;
+ getWeekDays(): string[];
+ getWeekArray(): MaterialUiPickersDate[];
+ getYearRange(): MaterialUiPickersDate[];
+
+ // displaying methods
+ getMeridiemText(ampm: boolean): string;
+ getCalendarHeaderText(date: MaterialUiPickersDate): string;
+ getDatePickerHeaderText(date: MaterialUiPickersDate): string;
+ getDateTimePickerHeaderText(date: MaterialUiPickersDate): string;
+ getDayText(date: MaterialUiPickersDate): string;
+ getHourText(date: MaterialUiPickersDate, ampm: boolean): string;
+ getMinuteText(date: MaterialUiPickersDate): string;
+ getYearText(date: MaterialUiPickersDate): string;
+}
\ No newline at end of file