Skip to content

Commit

Permalink
Merge pull request #233 from dmtrKovalenko/develop
Browse files Browse the repository at this point in the history
Release 1.0.0-rc.1
  • Loading branch information
dmtrKovalenko authored Mar 2, 2018
2 parents 5a1f2af + b0366cc commit dd46ce2
Show file tree
Hide file tree
Showing 86 changed files with 2,230 additions and 857 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"react/no-find-dom-node": 0,
"no-param-reassign": 0,
"import/no-named-as-default": 0,
"import/no-extraneous-dependencies": 0
"import/no-extraneous-dependencies": 0,
"class-methods-use-this": 0
},
"globals": {
"document": true
Expand Down
88 changes: 46 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,35 @@
Changelog available [here](https://github.com/dmtrKovalenko/material-ui-pickers/releases)

### Installation
Available as npm package. Please note that we are using moment as a peer dependency
Available as npm package.
```sh
npm install moment material-ui-pickers -S
npm install material-ui-pickers -S
```
Now choose the library that pickers will use to work with date. We are providing interfaces for [moment](https://momentjs.com/) and [date-fns](https://date-fns.org/). If you are not using moment in the project (or dont have it in the bundle already) we suggest using date-fns, because it much more lightweight and will be correctly tree-shaked from the bundle.

We are using material-ui-icons font to display icons. Just add this to your html
Teach pickers how to use one of that library using `MuiPickersUtilsProvider`. This component takes an utils property, and makes it available down the React tree thanks to React context. It should preferably be used at the root of your component tree.

```jsx
import { MuiPickersUtilsProvider } from 'material-ui-pickers';
import MomentUtils from 'material-ui-pickers/utils/moment-utils';
import DateFnsUtils from 'material-ui-picker/utils/date-fns-utils'

function App() {
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Root />
</MuiPickersUtilsProvider>
);
}

render(<App />, document.querySelector('#app'));
```

We are using material-ui-icons icon font to display icons. Just add this to your html
```html
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
```

If you dont want to use icon font, or you are already use `material-ui-icons` you can pass any icon to the components with the following props
* leftArrowIcon - arrow left for datepicker
* rightArrowIcon - arrow right for datepicker
* dateRangeIcon - date tab icon for datetimepicker
* timeIcon - time tab icon for datetimepicker
* keyboardIcon - icon for keyboard end adornmentic
If you dont want to use icon font, or you are already use `material-ui-icons` you can pass any icon to the components with [corresponding props](https://github.com/dmtrKovalenko/material-ui-pickers#props-documentation)

### Usage
Here is a quick example of how to use this package
Expand Down Expand Up @@ -83,12 +96,12 @@ Here is a list of available props
**Note:** Any prop not recognized by the pickers and their sub-components are passed down to material-ui [TextField](https://material-ui-next.com/api/text-field/#props) component.

#### Datepicker
* date - string, number, Date object, Moment object ([anything](https://momentjs.com/docs/#/parsing/), that can be parsed by moment)
* date - string, number, Date object or Moment object (if you are using moment utils)

Prop | Type | Default | Definition
------------ | ------------- | ------------- | -------------
value | date | new Date() | Datepicker value
format | string | 'MMMM Do' | Moment format string for input
format | string | 'MMMM Do' | Format string for input
autoOk | boolean | false | Auto accept date on selection
disablePast | boolean | false | Disable past dates
disableFuture | boolean | false | Disable future dates
Expand All @@ -97,7 +110,6 @@ openToYearSelection | boolean | false | Open datepicker from year selection
minDate | date | '1900-01-01' | Minimum selectable date
maxDate | date | '2100-01-01' | Maximum selectable date
onChange | func | required | Callback firing when date accepted
returnMoment | boolean | true | Will return moment object in onChange
invalidLabel | string | 'Unknown' | Displayed string if date cant be parsed
emptyLabel | string | '' | Displayed string if date is `null` (e.g. after clear)
okLabel | string | 'OK' | The label for the ok button
Expand All @@ -112,9 +124,12 @@ keyboard | boolean | false | Allow to manual input date to the text field
keyboardIcon | react node | `<Icon>event</Icon>` | Keyboard adornment icon
maxDateMessage | string | 'Date should not be after maximal date' | Maximum date error message for keyboard input
minDateMessage | string | 'Date should not be before minimal date' | Minimum date error message for keyboard input
mask | text mask (read more [here](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#readme)) | undefined | Text mask
mask | text mask (read more [here](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#readme)) | undefined | Text mask for keyboard-mode
clearable | boolean | false | If `true`, clear button will be displayed
TextFieldComponent | func, string | undefined | Component that should replace the default Material-UI TextField
InputAdornmentProps | object | {} | Props to pass to keyboard input adornment
inputAdornmentPosition | enum 'start', 'end' | 'end' | Specifies position of keyboard adornment


#### Timepicker
Prop | Type | Default | Definition
Expand All @@ -123,7 +138,6 @@ value | date | new Date() | Timepicker value
format | string | 'MMMM Do' | Moment format string for input
autoOk | boolean | false | Auto accept time on selection
onChange | func | required | Callback firing when date accepted
returnMoment | boolean | true | Will return moment object in onChange
invalidLabel | string | 'Unknown' | Displayed string if date cant be parsed
emptyLabel | string | '' | Displayed string if date is `null` (e.g. after clear)
okLabel | string | 'OK' | The label for the ok button
Expand All @@ -133,9 +147,11 @@ labelFunc | func | null | Allow to specify dynamic label for text field `labelFu
ampm | boolean | true | 12h/24h view for hour selection clock
keyboard | boolean | false | Allow to manual input date to the text field
keyboardIcon | react node | `<Icon>event</Icon>` | Keyboard adornment icon
mask | text mask (read more [here](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#readme)) | undefined | Text mask
mask | text mask (read more [here](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#readme)) | undefined | Text mask for keyboard-mode
clearable | boolean | false | If `true`, clear button will be displayed
TextFieldComponent | func, string | undefined | Component that should replace the default Material-UI TextField
InputAdornmentProps | object | {} | Props to pass to keyboard input adornment
inputAdornmentPosition | enum 'start', 'end' | 'end' | Specifies position of keyboard adornment

#### DateTimepicker
Prop | Type | Default | Definition
Expand All @@ -152,7 +168,6 @@ animateYearScrolling | boolean | false | Will animate year selection
minDate | date | '1900-01-01' | Minimum selectable date
maxDate | date | '2100-01-01' | Maximum selectable date
onChange | func | required | Callback firing when date accepted
returnMoment | boolean | true | Will return moment object in onChangeg
invalidLabel | string | 'Unknown' | Displayed string if date cant be parsed
emptyLabel | string | '' | Displayed string if date is `null` (e.g. after clear)
okLabel | string | 'OK' | The label for the ok button
Expand All @@ -165,25 +180,20 @@ rightArrowIcon | react node | `<Icon>keyboard_arrow_right</Icon>`| Right arrow i
dateRangeIcon | react node | `<Icon>date_range</Icon>`| Date tab icon
timeIcon | react node | `<Icon>access_time</Icon>`| Time tab icon
ampm | boolean | true | 12h/24h view for hour selection clock
shouldDisableDate | (date: Moment) => boolean | () => false | Allow to disable custom date in calendar
shouldDisableDate | (date: Moment | Date) => boolean | () => false | Allow to disable custom date in calendar
keyboard | boolean | false | Allow to manual input date to the text field
keyboardIcon | react node | `<Icon>event</Icon>` | Keyboard adornment icon
maxDateMessage | string | 'Date should not be after maximal date' | Maximum date error message for keyboard input
minDateMessage | string | 'Date should not be before minimal date' | Minimum date error message for keyboard input
invalidDateMessage | string | 'Invalid Date Format' | Message, appearing when date cannot be parsed
mask | text mask (read more [here](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#readme)) | undefined | Text mask
mask | text mask (read more [here](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#readme)) | undefined | Text mask for keyboard-mode
clearable | boolean | false | If `true`, clear button will be displayed
TextFieldComponent | func, string | undefined | Component that should replace the default Material-UI TextField
InputAdornmentProps | object | {} | Props to pass to keyboard input adornment
inputAdornmentPosition | enum 'start', 'end' | 'end' | Specifies position of keyboard adornment

### l10n
For l10n texts we're currently relying on moment which is stateful. To change the locale you have to import your langauge specific files an change the locale manually via `moment.locale(language)`.
```
import moment from 'moment'
import 'moment/locale/fr';
moment.locale('fr')
```

<!-- Delay support of material-ui-pickers probably to rc-2
### Jalali Calendar
We are fully supporting Jalali calendar system and [right-to-left](https://material-ui-next.com/guides/right-to-left/) material-ui api. Special thanks to @alitaheri.
Here is a little example of how to use it
Expand All @@ -195,23 +205,17 @@ npm install material-ui-pickers-jalali-utils
```
```jsx
import { TimePicker, DateTimePicker, DatePicker } from 'material-ui-pickers';
import { MuiPickersUtilsProvider } from 'material-ui-pickers';
import jalaliUtils from 'material-ui-pickers-jalali-utils';
jMoment.loadPersian({ dialect: 'persian-modern', usePersianDigits: true });

<DateTimePicker
okLabel="تأیید"
cancelLabel="لغو"
labelFunc={date => date === null ? '' : jMoment(date).format('jYYYY/jMM/jDD hh:mm A')}
value={selectedDate}
onChange={this.handleDateChange}
utils={jalaliUtils}
/>
```

### Migrate to date-fns?
If you are interested of using moment or date-fns as the peer of this project, please mention that in [this issue](https://github.com/dmtrKovalenko/material-ui-pickers/issues/61), we need to know which library if more useful to be in the peer dependencies of this project. Thank you.
function App() {
return (
<MuiPickersUtilsProvider utils={jalaliUtils}>
<Root />
</MuiPickersUtilsProvider>
);
}
``` -->

### Contributing
For information about how to contribute, see the [CONTRIBUTING](https://github.com/dmtrKovalenko/material-ui-pickers/blob/master/CONTRIBUTING.md) file.
Expand Down
5 changes: 5 additions & 0 deletions docs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"classnames": "^2.2.5",
"date-fns": "^2.0.0-alpha.7",
"eslint-config-react-app": "^2.1.0",
"jss": "^9.8.0",
"jss-preset-default": "^4.3.0",
Expand Down
24 changes: 16 additions & 8 deletions docs/src/App.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { MuiThemeProvider, createMuiTheme } from 'material-ui';

import Demo from './Demo/Demo';
import { setPrismTheme } from './utils/prism';
import { MuiPickersUtilsProvider, dateFnsUtils, momentUtils } from 'material-ui-pickers';

import { create } from 'jss';
import preset from 'jss-preset-default';
import rtl from 'jss-rtl';
import JssProvider from 'react-jss/lib/JssProvider';
import createGenerateClassName from 'material-ui/styles/createGenerateClassName';

import Demo from './Demo/Demo';
import { setPrismTheme } from './utils/prism';

const jss = create({ plugins: [...preset().plugins, rtl()] });
jss.options.createGenerateClassName = createGenerateClassName;

export default class App extends Component {
static propTypes = {
toggleFrench: PropTypes.func.isRequired,
}

state = {
type: 'light',
direction: 'ltr',
Expand Down Expand Up @@ -50,11 +56,13 @@ export default class App extends Component {
<div className="root">
<JssProvider jss={jss}>
<MuiThemeProvider theme={this.getMuiTheme()}>
<Demo
toggleDirection={this.toggleDirection}
toggleThemeType={this.toggleThemeType}
toggleFrench={this.props.toggleFrench}
/>
<MuiPickersUtilsProvider utils={dateFnsUtils}>
<Demo
toggleDirection={this.toggleDirection}
toggleThemeType={this.toggleThemeType}
toggleFrench={this.props.toggleFrench}
/>
</MuiPickersUtilsProvider>
</MuiThemeProvider>
</JssProvider>
</div>
Expand Down
6 changes: 3 additions & 3 deletions docs/src/Demo/Demo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import SourcablePanel from './components/SourcablePanel';
import BasicUsage from './Examples/BasicUsage';
import CustomElements from './Examples/CustomElements';
import DateTimePickers from './Examples/DateTimePickers';
import PersianPickers from './Examples/PersianPickers';
// import PersianPickers from './Examples/PersianPickers';
import './Demo.css';

class Demo extends Component {
Expand Down Expand Up @@ -111,7 +111,7 @@ class Demo extends Component {
<CustomElements />
</SourcablePanel>

<SourcablePanel
{/* <SourcablePanel
title="Persian Pickers"
description={
<p key="persian-desc">
Expand All @@ -123,7 +123,7 @@ class Demo extends Component {
sourceFile="PersianPickers.jsx"
>
<PersianPickers />
</SourcablePanel>
</SourcablePanel> */}
</div>
</main>
);
Expand Down
3 changes: 1 addition & 2 deletions docs/src/Demo/Examples/BasicUsage.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React, { Fragment, Component } from 'react';
import moment from 'moment';
import { Typography } from 'material-ui';
import { TimePicker, DatePicker } from 'material-ui-pickers';

export default class BasicUsage extends Component {
state = {
selectedDate: moment(),
selectedDate: new Date(),
}

handleDateChange = (date) => {
Expand Down
46 changes: 28 additions & 18 deletions docs/src/Demo/Examples/CustomElements.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ import PropTypes from 'prop-types';
import { IconButton, Typography, withStyles } from 'material-ui';
import classNames from 'classnames';
import { DateTimePicker, DatePicker } from 'material-ui-pickers';
import moment from 'moment';

import isValid from 'date-fns/isValid';
import format from 'date-fns/format';
import isSameDay from 'date-fns/isSameDay';
import startOfWeek from 'date-fns/startOfWeek';
import endOfWeek from 'date-fns/endOfWeek';
import isWithinInterval from 'date-fns/isWithinInterval';

class CustomElements extends Component {
static propTypes = {
Expand All @@ -26,17 +34,20 @@ class CustomElements extends Component {
return '';
}

return date && date.isValid() ?
`Week of ${date.clone().startOf('week').format('MMM Do')}`
:
invalidLabel;
if (date instanceof moment) {
date = date.toDate();
}

return date && isValid(date)
? `Week of ${format(startOfWeek(date), 'MMM Do')}`
: invalidLabel;
}

renderCustomDayForDateTime = (date, selectedDate, dayInCurrentMonth, dayComponent) => {
const { classes } = this.props;

const dayClassName = classNames({
[classes.customDayHighlight]: date.isSame(selectedDate, 'day'),
[classes.customDayHighlight]: isSameDay(date, selectedDate),
});

return (
Expand All @@ -50,22 +61,21 @@ class CustomElements extends Component {
renderWrappedDefaultDay = (date, selectedDate, dayInCurrentMonth) => {
const { classes } = this.props;

const startDate = selectedDate.clone().day(0).startOf('day');
const endDate = selectedDate.clone().day(6).endOf('day');
if (date instanceof moment) {
date = date.toDate();
}

const dayIsBetween = (
date.isSame(startDate) ||
date.isSame(endDate) ||
(date.isAfter(startDate) && date.isBefore(endDate))
);
const start = startOfWeek(selectedDate);
const end = endOfWeek(selectedDate);

const firstDay = date.isSame(startDate, 'day');
const lastDay = date.isSame(endDate, 'day');
const dayIsBetween = isWithinInterval(date, { start, end });
const isFirstDay = isSameDay(date, start);
const isLastDay = isSameDay(date, end);

const wrapperClassName = classNames({
[classes.highlight]: dayIsBetween,
[classes.firstHighlight]: firstDay,
[classes.endHighlight]: lastDay,
[classes.firstHighlight]: isFirstDay,
[classes.endHighlight]: isLastDay,
});

const dayClassName = classNames(classes.day, {
Expand All @@ -76,7 +86,7 @@ class CustomElements extends Component {
return (
<div className={wrapperClassName}>
<IconButton className={dayClassName}>
<span> { date.format('D')} </span>
<span> { format(date, 'D')} </span>
</IconButton>
</div>
);
Expand Down Expand Up @@ -134,7 +144,7 @@ const styles = theme => ({
bottom: 0,
left: '2px',
right: '2px',
border: `2px solid ${theme.palette.primary[100]}`,
border: `1px solid ${theme.palette.secondary.main}`,
borderRadius: '50%',
},
nonCurrentMonthDay: {
Expand Down
1 change: 0 additions & 1 deletion docs/src/Demo/Examples/DateTimePickers.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { Fragment, Component } from 'react';
import { DateTimePicker } from 'material-ui-pickers';
import { IconButton, Typography, Icon, InputAdornment } from 'material-ui';
import moment from 'moment';

export default class BasicUsage extends Component {
state = {
Expand Down
Loading

0 comments on commit dd46ce2

Please sign in to comment.