diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 68359a308..3c91eaa8f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -:raised_hands::tada: First off all, thanks for taking the time to contribute! :tada::raised_hands: +:raised_hands::tada: First of all, thanks for taking the time to contribute! :tada::raised_hands: The following is a set of guidelines for contributing to @material-ui/pickers. The purpose of these guidelines is to maintain a high quality of code _and_ traceability. Please respect these @@ -8,19 +8,19 @@ guidelines. ## Setting up -Please make sure that we are using `next` branch for active development. So your branches must be created from _develop_ and not from the ~~master~~. Here is a short step-by-step guide how to get started +Please make sure that we are using the `next` branch for active development. So your branches must be created from _next_ and not from ~~master~~. Here is a short step-by-step guide on how to get started: 1. Fork the @material-ui/pickers repository on Github 2. Clone your fork to your local machine `git clone git@github.com:/@material-ui/pickers.git` 3. Checkout next `git checkout next` 4. Create a branch `git checkout -b feature/my-topic-branch` -5. Make your changes, lint, run tests, then push to to GitHub with `git push --set-upstream origin my-topic-branch`. +5. Make your changes, lint, run tests, then push to GitHub with `git push --set-upstream origin my-topic-branch`. 6. Visit GitHub and make your pull request. If you have an existing local repository, please update it before you start, to minimise the chance of merge conflicts. ```sh -Ugit remote add upstream git@github.com:mui-org/@material-ui/pickers.git +git remote add upstream git@github.com:mui-org/@material-ui/pickers.git git checkout next git pull upstream next git checkout -b my-topic-branch @@ -35,13 +35,12 @@ yarn yarn dev ``` -To start development environment and be sure the `lib` folder is linked properly to the `docs` and your changes will be applied to the docs website. +to start the development environment and to be sure the `lib` folder is linked properly to the `docs` and your changes will be applied to the docs website. ## General -This repository use tests and a linter as automatic tools to maintain the quality of the code. -These two tasks are run locally on your machine before every commit (as a pre-commit git hook), -if any test fail or the linter gives an error the commit will not be created. They are also run on +This repository uses tests and a linter as automatic tools to maintain the quality of the code. +These two tasks are run locally on your machine before every commit (as a pre-commit git hook). If any test fails or the linter gives an error the commit will not be created. They are also run on a Travis CI machine when you create a pull request, and the PR will not be merged unless Travis says all tests and the linting pass. diff --git a/README.md b/README.md index 416e21932..009f1c6c1 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Accessible, customizable, delightful date & time pickers for [@material-ui/core] ### Installation -Note that this package reqiures `@material-ui/core` **v4**. It will not work with the old v3. Please read the [migration guide](https://material-ui-pickers.dev/guides/upgrading-to-v3) if you are updating from v2 +Note that this package requires `@material-ui/core` **v4**. It will not work with the old v3. Please read the [migration guide](https://material-ui-pickers.dev/guides/upgrading-to-v3) if you are updating from v2 ```sh // via npm @@ -31,7 +31,7 @@ npm i @material-ui/pickers yarn add @material-ui/pickers ``` -Now choose the library that pickers will use to work with date. We are providing interfaces for [moment](https://momentjs.com/), [luxon](https://moment.github.io/luxon/), [dayjs](https://github.com/iamkun/dayjs) and [date-fns v2](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 or luxon, because they are much lighter and will be correctly tree-shaked from the bundle. Note, that we are fully relying on [date-io](https://github.com/dmtrKovalenko/date-io) for supporting different libraries. +Now choose the library that pickers will use to work with date. We are providing interfaces for [moment](https://momentjs.com/), [luxon](https://moment.github.io/luxon/), [dayjs](https://github.com/iamkun/dayjs) and [date-fns v2](https://date-fns.org/). If you are not using moment in the project (or don’t have it in the bundle already) we suggest using date-fns or luxon, because they are much lighter and will be correctly tree-shaked from the bundle. Note, that we are fully relying on [date-io](https://github.com/dmtrKovalenko/date-io) for supporting different libraries. ```sh npm i date-fns@next @date-io/date-fns diff --git a/docs/pages/demo/datepicker/index.mdx b/docs/pages/demo/datepicker/index.mdx index 9a7711fab..e97d03885 100644 --- a/docs/pages/demo/datepicker/index.mdx +++ b/docs/pages/demo/datepicker/index.mdx @@ -27,7 +27,7 @@ color and type weight. #### Keyboard Input -It is recommended to use keyboard input with mask for better desktop experience. Make sure that mask will be automatically +It is recommended to use keyboard input with mask for a better desktop experience. Make sure that mask will be automatically generated from passed `format`. It's recommended to use only robust formats for keyboard input. > Make sure that `onChange` have second parameter here. So if you will not do `onChange={date => handleDateChange(date)}` you will get console warning [useState hook dose not accept a second callback argument](https://github.com/facebook/react/issues/14174) @@ -50,7 +50,7 @@ Thus you can easily create #### Static mode -It is possible to render any picker inline. This will be really helpful to build cutom popover/modal containers. +It is possible to render any picker inline. This will be really helpful to build custom popover/modal containers. For that use `variant="static"`. @@ -63,7 +63,7 @@ The displaying of dates is heavily cusomizable. Thus you can add badges or fully #### Dynamic data -Sometimes it's required to displaying additional info right in calendar. +Sometimes it's required to display additional info right in the calendar. For this just return `Promise` in `onMonthChange`. diff --git a/docs/pages/demo/datetime-picker/index.mdx b/docs/pages/demo/datetime-picker/index.mdx index 08965d0ed..936c75e12 100644 --- a/docs/pages/demo/datetime-picker/index.mdx +++ b/docs/pages/demo/datetime-picker/index.mdx @@ -25,7 +25,7 @@ This component combines Material Design date & time selection components. It all #### Customization -Applied mostly all customization, that available for date & time pickers +Applied almost all customizations, that are available for date & time pickers diff --git a/docs/pages/demo/timepicker/index.mdx b/docs/pages/demo/timepicker/index.mdx index e93637077..944df55fc 100644 --- a/docs/pages/demo/timepicker/index.mdx +++ b/docs/pages/demo/timepicker/index.mdx @@ -34,7 +34,7 @@ A time picker should adjust to a user’s preferred time setting, i.e. the 12-ho #### Static mode -It is possible to render any picker inline. This will be really helpful to build cutom popover/modal containers. +It is possible to render any picker inline. This will be really helpful to build custom popover/modal containers. For that use `variant="static"`. diff --git a/docs/pages/getting-started/installation.mdx b/docs/pages/getting-started/installation.mdx index 0789ebaee..2823ff6ae 100644 --- a/docs/pages/getting-started/installation.mdx +++ b/docs/pages/getting-started/installation.mdx @@ -20,7 +20,7 @@ yarn add @material-ui/pickers @material-ui/pickers was designed to use the date management library of your choice. We are providing interfaces for [moment](https://momentjs.com/), [date-fns 2](https://date-fns.org/), [luxon](https://moment.github.io/luxon/) and [dayjs](https://github.com/iamkun/dayjs). -**Important:**: we only support date-fns versions `v2` upwards. +**Important:** we only support date-fns versions `v2` upwards. ``` npm i @date-io/date-fns date-fns@next diff --git a/docs/pages/guides/Formik.example.jsx b/docs/pages/guides/Formik.example.jsx index 1012b142f..6884b1571 100644 --- a/docs/pages/guides/Formik.example.jsx +++ b/docs/pages/guides/Formik.example.jsx @@ -6,6 +6,7 @@ import { KeyboardDatePicker } from '@material-ui/pickers'; const DatePickerField = ({ field, form, ...other }) => { const currentError = form.errors[field.name]; + return ( { format="dd/MM/yyyy" helperText={currentError} error={Boolean(currentError)} - onError={(_, error) => form.setFieldError(field.name, error)} - onChange={date => date && form.setFieldValue(field.name, date, true)} + onError={error => { + // handle as a side effect + if (error !== currentError) { + form.setFieldError(field.name, error); + } + }} + // if you are using custom validation schema you probably want to pass `true` as third argument + onChange={date => form.setFieldValue(field.name, date, false)} {...other} /> ); diff --git a/docs/pages/guides/css-overrides.mdx b/docs/pages/guides/css-overrides.mdx index 8527c1573..244a0df18 100644 --- a/docs/pages/guides/css-overrides.mdx +++ b/docs/pages/guides/css-overrides.mdx @@ -23,7 +23,7 @@ You can customize the material-ui theme, that is passed to `ThemeProvider` and t #### Override example -*Date/Time pickers are quite simple controls from UX perspective, so most people just use the default appearence* +*Date/Time pickers are quite simple controls from UX perspective, so most people just use the default appearance* That's why we are not providing any for-component classes api to override stylesheets for any particular component. The only way to override existing stylesheets are with the use of global material-ui theme diff --git a/docs/prop-types.json b/docs/prop-types.json index d53959d49..d0ff46f78 100644 --- a/docs/prop-types.json +++ b/docs/prop-types.json @@ -288,7 +288,7 @@ }, "onError": { "defaultValue": null, - "description": "Callback fired when new error should be displayed", + "description": "Callback fired when new error should be displayed\n(!! This is a side effect. Be careful if you want to rerender the component)", "name": "onError", "parent": { "fileName": "material-ui-pickers/lib/src/typings/BasePicker.tsx", @@ -812,7 +812,7 @@ }, "onError": { "defaultValue": null, - "description": "Callback fired when new error should be displayed", + "description": "Callback fired when new error should be displayed\n(!! This is a side effect. Be careful if you want to rerender the component)", "name": "onError", "parent": { "fileName": "material-ui-pickers/lib/src/typings/BasePicker.tsx", @@ -1556,7 +1556,7 @@ }, "onError": { "defaultValue": null, - "description": "Callback fired when new error should be displayed", + "description": "Callback fired when new error should be displayed\n(!! This is a side effect. Be careful if you want to rerender the component)", "name": "onError", "parent": { "fileName": "material-ui-pickers/lib/src/typings/BasePicker.tsx", @@ -1888,7 +1888,7 @@ }, "onError": { "defaultValue": null, - "description": "Callback fired when new error should be displayed", + "description": "Callback fired when new error should be displayed\n(!! This is a side effect. Be careful if you want to rerender the component)", "name": "onError", "parent": { "fileName": "material-ui-pickers/lib/src/typings/BasePicker.tsx", @@ -2440,7 +2440,7 @@ }, "onError": { "defaultValue": null, - "description": "Callback fired when new error should be displayed", + "description": "Callback fired when new error should be displayed\n(!! This is a side effect. Be careful if you want to rerender the component)", "name": "onError", "parent": { "fileName": "material-ui-pickers/lib/src/typings/BasePicker.tsx", @@ -3033,7 +3033,7 @@ }, "onError": { "defaultValue": null, - "description": "Callback fired when new error should be displayed", + "description": "Callback fired when new error should be displayed\n(!! This is a side effect. Be careful if you want to rerender the component)", "name": "onError", "parent": { "fileName": "material-ui-pickers/lib/src/typings/BasePicker.tsx", diff --git a/lib/package.json b/lib/package.json index f55fce236..219d71ada 100644 --- a/lib/package.json +++ b/lib/package.json @@ -1,6 +1,6 @@ { "name": "@material-ui/pickers", - "version": "3.2.3", + "version": "3.2.5", "private": true, "description": "React components, that implements material design pickers for material-ui v1", "main": "./src/index.ts", @@ -64,8 +64,7 @@ "build:typescript": "tsc --project tsconfig.json", "build": "npm run build:typescript && npm run build:bundle && npm run build:copy", "build:analyze": "npm run build", - "release": "yarn test && yarn version && yarn build && yarn publish --non-interactive build", - "publish": "npm publish build" + "release": "yarn test && yarn version && yarn build && yarn publish --non-interactive build" }, "devDependencies": { "@babel/core": "^7.6.0", diff --git a/lib/src/MuiPickersUtilsProvider.tsx b/lib/src/MuiPickersUtilsProvider.tsx index 752cba4b4..707dec7d3 100644 --- a/lib/src/MuiPickersUtilsProvider.tsx +++ b/lib/src/MuiPickersUtilsProvider.tsx @@ -18,7 +18,7 @@ export const MuiPickersUtilsProvider: React.FC = ( locale, libInstance, }) => { - const utils = React.useMemo(() => new Utils({ locale, moment: libInstance }), [ + const utils = React.useMemo(() => new Utils({ locale, instance: libInstance }), [ Utils, libInstance, locale, diff --git a/lib/src/Picker/makePickerWithState.tsx b/lib/src/Picker/makePickerWithState.tsx index b3f504763..4a5206315 100644 --- a/lib/src/Picker/makePickerWithState.tsx +++ b/lib/src/Picker/makePickerWithState.tsx @@ -4,8 +4,8 @@ import { Picker, ToolbarComponentProps } from './Picker'; import { ExtendWrapper, Wrapper } from '../wrappers/Wrapper'; import { PureDateInputProps } from '../_shared/PureDateInput'; import { DateValidationProps } from '../_helpers/text-field-helper'; +import { KeyboardDateInputProps } from '../_shared/KeyboardDateInput'; import { StateHookOptions, usePickerState } from '../_shared/hooks/usePickerState'; -import { KeyboardDateInput, KeyboardDateInputProps } from '../_shared/KeyboardDateInput'; import { BaseKeyboardPickerProps, useKeyboardPickerState, @@ -20,7 +20,7 @@ export type WithPureInputProps = DateValidationProps & ExtendWrapper; export interface MakePickerOptions { - Input: KeyboardDateInput | PureDateInputProps; + Input: any; useState: typeof usePickerState | typeof useKeyboardPickerState; useOptions: (props: any) => StateHookOptions; getCustomProps?: (props: T) => Partial; diff --git a/lib/src/_helpers/text-field-helper.ts b/lib/src/_helpers/text-field-helper.ts index f8162b8eb..45b1c071f 100644 --- a/lib/src/_helpers/text-field-helper.ts +++ b/lib/src/_helpers/text-field-helper.ts @@ -1,3 +1,4 @@ +import { Omit } from './utils'; import { DatePickerProps } from '..'; import { IUtils } from '@date-io/core/IUtils'; import { ParsableDate } from '../constants/prop-types'; diff --git a/lib/src/_helpers/utils.ts b/lib/src/_helpers/utils.ts index 1eb5197d4..ec7c02d08 100644 --- a/lib/src/_helpers/utils.ts +++ b/lib/src/_helpers/utils.ts @@ -6,3 +6,5 @@ export function arrayIncludes(array: T[], itemOrItems: T | T[]) { return array.indexOf(itemOrItems) !== -1; } + +export type Omit = Pick>; diff --git a/lib/src/_shared/KeyboardDateInput.tsx b/lib/src/_shared/KeyboardDateInput.tsx index 9e4f5667a..1f696c37a 100644 --- a/lib/src/_shared/KeyboardDateInput.tsx +++ b/lib/src/_shared/KeyboardDateInput.tsx @@ -11,7 +11,7 @@ export interface KeyboardDateInputProps extends ExtendMui { format: string; onChange: (value: string | null) => void; - openPicker?: () => void; + openPicker: () => void; validationError?: React.ReactNode; inputValue: string; inputProps?: TextFieldProps['inputProps']; diff --git a/lib/src/_shared/ModalDialog.tsx b/lib/src/_shared/ModalDialog.tsx index 87db586f8..f8d94999c 100644 --- a/lib/src/_shared/ModalDialog.tsx +++ b/lib/src/_shared/ModalDialog.tsx @@ -4,7 +4,7 @@ import Button from '@material-ui/core/Button'; import DialogActions from '@material-ui/core/DialogActions'; import DialogContent from '@material-ui/core/DialogContent'; import Dialog, { DialogProps } from '@material-ui/core/Dialog'; -import { DIALOG_WIDTH } from '../constants/dimensions'; +import { DIALOG_WIDTH, DIALOG_WIDTH_WIDER } from '../constants/dimensions'; import { createStyles, WithStyles, withStyles } from '@material-ui/core/styles'; export interface ModalDialogProps extends DialogProps { @@ -90,10 +90,9 @@ ModalDialog.displayName = 'ModalDialog'; export const styles = createStyles({ dialogRoot: { minWidth: DIALOG_WIDTH, - // maxWidth: DIALOG_WIDTH_WIDER, }, dialogRootWider: { - // minWidth: DIALOG_WIDTH_WIDER, + minWidth: DIALOG_WIDTH_WIDER, }, dialog: { '&:first-child': { diff --git a/lib/src/_shared/WithUtils.tsx b/lib/src/_shared/WithUtils.tsx index 774870ccb..382239c95 100644 --- a/lib/src/_shared/WithUtils.tsx +++ b/lib/src/_shared/WithUtils.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { Omit } from '../_helpers/utils'; import { useUtils } from './hooks/useUtils'; import { IUtils } from '@date-io/core/IUtils'; import { MaterialUiPickersDate } from '../typings/date'; diff --git a/lib/src/_shared/hooks/useKeyboardPickerState.ts b/lib/src/_shared/hooks/useKeyboardPickerState.ts index 93c96f02d..bca347f18 100644 --- a/lib/src/_shared/hooks/useKeyboardPickerState.ts +++ b/lib/src/_shared/hooks/useKeyboardPickerState.ts @@ -1,4 +1,5 @@ import { useUtils } from './useUtils'; +import { Omit } from '../../_helpers/utils'; import { IUtils } from '@date-io/core/IUtils'; import { BasePickerProps } from '../../typings/BasePicker'; import { MaterialUiPickersDate } from '../../typings/date'; diff --git a/lib/src/_shared/hooks/usePickerState.ts b/lib/src/_shared/hooks/usePickerState.ts index 362d22be4..12de6c3c0 100644 --- a/lib/src/_shared/hooks/usePickerState.ts +++ b/lib/src/_shared/hooks/usePickerState.ts @@ -92,7 +92,7 @@ export function usePickerState(props: BasePickerProps, options: StateHookOptions const validationError = validate(value, utils, props); useEffect(() => { - if (validationError && onError) { + if (onError) { onError(validationError, value); } }, [onError, validationError, value]); diff --git a/lib/src/typings/BasePicker.tsx b/lib/src/typings/BasePicker.tsx index c31be6eac..111a981ea 100644 --- a/lib/src/typings/BasePicker.tsx +++ b/lib/src/typings/BasePicker.tsx @@ -33,7 +33,9 @@ export interface BasePickerProps { emptyLabel?: string; /** Callback fired when date is accepted @DateIOType */ onAccept?: (date: MaterialUiPickersDate) => void; - /** Callback fired when new error should be displayed @DateIOType */ + /** Callback fired when new error should be displayed + * (!! This is a side effect. Be careful if you want to rerender the component) @DateIOType + */ onError?: (error: React.ReactNode, value: MaterialUiPickersDate | ParsableDate) => void; /** On open callback */ onOpen?: () => void; diff --git a/lib/src/typings/extendMui.ts b/lib/src/typings/extendMui.ts index 51a9bbb58..49f5225f2 100644 --- a/lib/src/typings/extendMui.ts +++ b/lib/src/typings/extendMui.ts @@ -1,3 +1,5 @@ +import { Omit } from '../_helpers/utils'; + /** * All standard components exposed by `material-ui` are `StyledComponents` with * certain `classes`, on which one can also set a top-level `className` and inline diff --git a/lib/src/wrappers/ModalWrapper.tsx b/lib/src/wrappers/ModalWrapper.tsx index 5b493002e..7618ee76b 100644 --- a/lib/src/wrappers/ModalWrapper.tsx +++ b/lib/src/wrappers/ModalWrapper.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; import * as PropTypes from 'prop-types'; import ModalDialog from '../_shared/ModalDialog'; -import { Omit } from '@material-ui/core'; import { WrapperProps } from './Wrapper'; +import { Omit } from '../_helpers/utils'; import { useKeyDown } from '../_shared/hooks/useKeyDown'; import { DialogProps as MuiDialogProps } from '@material-ui/core/Dialog'; diff --git a/lib/src/wrappers/Wrapper.tsx b/lib/src/wrappers/Wrapper.tsx index 1e863d99d..e190b837e 100644 --- a/lib/src/wrappers/Wrapper.tsx +++ b/lib/src/wrappers/Wrapper.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Omit } from '@material-ui/core'; +import { Omit } from '../_helpers/utils'; import { StaticWrapper } from './StaticWrapper'; import { ModalWrapper, ModalWrapperProps } from './ModalWrapper'; import { InlineWrapper, InlineWrapperProps } from './InlineWrapper'; diff --git a/package.json b/package.json index e258a21e4..fca05c99d 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "scripts": { "start": "yarn dev", "dev": "yarn workspace docs dev", - "release": "yarn workspace @material-ui/pickers release || git push && git push --tags", + "release": "yarn workspace @material-ui/pickers release && git push && git push --tags", "e2e:open": "cypress open", "e2e:run": "cypress run", "docgen": "node docs/scripts/docgen.js", diff --git a/yarn.lock b/yarn.lock index 19ced2faa..2d4493f9d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5411,14 +5411,16 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3: estraverse "^4.1.1" eslint-utils@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" - integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + version "1.4.2" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" + integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== + dependencies: + eslint-visitor-keys "^1.0.0" eslint-visitor-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" - integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^5.16.0: version "5.16.0" @@ -8784,9 +8786,9 @@ mississippi@^3.0.0: through2 "^2.0.0" mixin-deep@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== dependencies: for-in "^1.0.2" is-extendable "^1.0.1"