@docsvision/material-ui-pickers 3.2.0-beta.24 → 3.2.0-beta.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/.size-snapshot.json +11 -11
  2. package/9db1cba1a61cb58db53f38425bbd1f95.7z +0 -0
  3. package/build/DatePicker/DatePicker.d.ts +2 -2
  4. package/build/DatePicker/DatePicker.js +1 -1
  5. package/build/DateTimePicker/DateTimePicker.js +1 -1
  6. package/build/Picker/Picker.js +1 -1
  7. package/build/TimePicker/TimePicker.js +1 -1
  8. package/build/_helpers/text-field-helper.d.ts +1 -1
  9. package/build/_shared/KeyboardDateInput.js +1 -1
  10. package/build/_shared/ModalDialog.d.ts +2 -2
  11. package/build/_shared/PureDateInput.js +1 -1
  12. package/build/_shared/ToolbarButton.d.ts +2 -2
  13. package/build/_shared/hooks/useKeyboardPickerState.js +2 -2
  14. package/build/constants/prop-types.js +2 -2
  15. package/build/dist/material-ui-pickers.esm.js +12 -12
  16. package/build/dist/material-ui-pickers.esm.js.map +1 -1
  17. package/build/dist/material-ui-pickers.js +62 -62
  18. package/build/dist/material-ui-pickers.js.map +1 -1
  19. package/build/dist/material-ui-pickers.umd.js +5790 -4511
  20. package/build/dist/material-ui-pickers.umd.min.js +1 -1
  21. package/build/package.json +1 -1
  22. package/build/views/Calendar/Calendar.js +2 -2
  23. package/build/views/Clock/Clock.d.ts +1 -1
  24. package/build/views/Clock/ClockPointer.d.ts +1 -1
  25. package/package.json +1 -1
  26. package/src/DatePicker/DatePicker.tsx +91 -0
  27. package/src/DatePicker/DatePickerToolbar.tsx +75 -0
  28. package/src/DatePicker/index.ts +7 -0
  29. package/src/DateTimePicker/DateTimePicker.tsx +72 -0
  30. package/src/DateTimePicker/DateTimePickerTabs.tsx +86 -0
  31. package/src/DateTimePicker/DateTimePickerToolbar.tsx +123 -0
  32. package/src/DateTimePicker/index.ts +7 -0
  33. package/src/MuiPickersUtilsProvider.tsx +39 -0
  34. package/src/Picker/Picker.tsx +275 -0
  35. package/src/Picker/WrappedKeyboardPicker.tsx +136 -0
  36. package/src/Picker/WrappedPurePicker.tsx +128 -0
  37. package/src/Rifm/Rifm.ts +213 -0
  38. package/src/TimePicker/TimePicker.tsx +67 -0
  39. package/src/TimePicker/TimePickerToolbar.tsx +180 -0
  40. package/src/TimePicker/index.tsx +7 -0
  41. package/src/__tests__/DatePicker/Calendar.test.tsx +51 -0
  42. package/src/__tests__/DatePicker/Month.test.tsx +36 -0
  43. package/src/__tests__/DatePicker/MonthSelection.test.tsx +37 -0
  44. package/src/__tests__/MuiPickersUtilsProvider.test.tsx +21 -0
  45. package/src/__tests__/TimePicker/Clock.test.tsx +68 -0
  46. package/src/__tests__/_helpers/date-utils.test.tsx +197 -0
  47. package/src/__tests__/_helpers/text-field-helper.test.tsx +34 -0
  48. package/src/__tests__/_shared/ModalDialog.test.tsx +109 -0
  49. package/src/__tests__/e2e/DatePicker.test.tsx +233 -0
  50. package/src/__tests__/e2e/DatePickerProps.test.tsx +18 -0
  51. package/src/__tests__/e2e/DatePickerRoot.test.tsx +154 -0
  52. package/src/__tests__/e2e/DateTimePicker.test.tsx +86 -0
  53. package/src/__tests__/e2e/DateTimePickerRoot.test.tsx +72 -0
  54. package/src/__tests__/e2e/KeyboardDatePicker.test.tsx +140 -0
  55. package/src/__tests__/e2e/KeyboardDateTimePicker.test.tsx +48 -0
  56. package/src/__tests__/e2e/Theme.test.tsx +30 -0
  57. package/src/__tests__/e2e/TimePicker.test.tsx +121 -0
  58. package/src/__tests__/e2e/commands.tsx +8 -0
  59. package/src/__tests__/setup.js +26 -0
  60. package/src/__tests__/test-utils.tsx +45 -0
  61. package/src/__tests__/tsconfig.json +5 -0
  62. package/src/_helpers/date-utils.ts +92 -0
  63. package/src/_helpers/text-field-helper.ts +239 -0
  64. package/src/_helpers/time-utils.ts +83 -0
  65. package/src/_helpers/utils.ts +8 -0
  66. package/src/_shared/KeyboardDateInput.tsx +161 -0
  67. package/src/_shared/ModalDialog.tsx +114 -0
  68. package/src/_shared/PickerToolbar.tsx +52 -0
  69. package/src/_shared/PureDateInput.tsx +45 -0
  70. package/src/_shared/ToolbarButton.tsx +63 -0
  71. package/src/_shared/ToolbarText.tsx +49 -0
  72. package/src/_shared/WithUtils.tsx +19 -0
  73. package/src/_shared/hooks/useIsLandscape.tsx +27 -0
  74. package/src/_shared/hooks/useKeyDown.ts +34 -0
  75. package/src/_shared/hooks/useKeyboardPickerState.ts +72 -0
  76. package/src/_shared/hooks/useOpenState.ts +22 -0
  77. package/src/_shared/hooks/usePickerState.ts +134 -0
  78. package/src/_shared/hooks/useUtils.ts +20 -0
  79. package/src/_shared/hooks/useViews.tsx +31 -0
  80. package/src/_shared/icons/ArrowLeftIcon.tsx +11 -0
  81. package/src/_shared/icons/ArrowRightIcon.tsx +11 -0
  82. package/src/_shared/icons/DateRangeIcon.tsx +11 -0
  83. package/src/_shared/icons/KeyboardIcon.tsx +11 -0
  84. package/src/_shared/icons/TimeIcon.tsx +12 -0
  85. package/src/constants/ClockType.ts +11 -0
  86. package/src/constants/dimensions.ts +5 -0
  87. package/src/constants/prop-types.ts +37 -0
  88. package/src/index.ts +48 -0
  89. package/src/typings/BasePicker.tsx +60 -0
  90. package/src/typings/date.ts +3 -0
  91. package/src/typings/extendMui.ts +10 -0
  92. package/src/typings/overrides.ts +44 -0
  93. package/src/views/Calendar/Calendar.tsx +361 -0
  94. package/src/views/Calendar/CalendarHeader.tsx +141 -0
  95. package/src/views/Calendar/Day.tsx +97 -0
  96. package/src/views/Calendar/DayWrapper.tsx +33 -0
  97. package/src/views/Calendar/SlideTransition.tsx +100 -0
  98. package/src/views/Clock/Clock.tsx +172 -0
  99. package/src/views/Clock/ClockNumber.tsx +91 -0
  100. package/src/views/Clock/ClockNumbers.tsx +76 -0
  101. package/src/views/Clock/ClockPointer.tsx +104 -0
  102. package/src/views/Clock/ClockView.tsx +105 -0
  103. package/src/views/Month/Month.tsx +76 -0
  104. package/src/views/Month/MonthView.tsx +94 -0
  105. package/src/views/Year/Year.tsx +77 -0
  106. package/src/views/Year/YearView.tsx +91 -0
  107. package/src/wrappers/InlineWrapper.tsx +80 -0
  108. package/src/wrappers/ModalWrapper.tsx +113 -0
  109. package/src/wrappers/StaticWrapper.tsx +22 -0
  110. package/src/wrappers/Wrapper.tsx +75 -0
  111. package/coverage/clover.xml +0 -601
  112. package/coverage/coverage-final.json +0 -22
  113. package/coverage/lcov-report/base.css +0 -224
  114. package/coverage/lcov-report/block-navigation.js +0 -79
  115. package/coverage/lcov-report/index.html +0 -201
  116. package/coverage/lcov-report/prettify.css +0 -1
  117. package/coverage/lcov-report/prettify.js +0 -2
  118. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  119. package/coverage/lcov-report/sorter.js +0 -170
  120. package/coverage/lcov-report/src/MuiPickersUtilsProvider.tsx.html +0 -186
  121. package/coverage/lcov-report/src/_helpers/date-utils.ts.html +0 -345
  122. package/coverage/lcov-report/src/_helpers/index.html +0 -123
  123. package/coverage/lcov-report/src/_helpers/time-utils.ts.html +0 -318
  124. package/coverage/lcov-report/src/_helpers/utils.ts.html +0 -93
  125. package/coverage/lcov-report/src/_shared/ModalDialog.tsx.html +0 -411
  126. package/coverage/lcov-report/src/_shared/WithUtils.tsx.html +0 -126
  127. package/coverage/lcov-report/src/_shared/hooks/index.html +0 -110
  128. package/coverage/lcov-report/src/_shared/hooks/useKeyDown.ts.html +0 -171
  129. package/coverage/lcov-report/src/_shared/hooks/useUtils.ts.html +0 -129
  130. package/coverage/lcov-report/src/_shared/icons/ArrowLeftIcon.tsx.html +0 -102
  131. package/coverage/lcov-report/src/_shared/icons/ArrowRightIcon.tsx.html +0 -102
  132. package/coverage/lcov-report/src/_shared/icons/index.html +0 -110
  133. package/coverage/lcov-report/src/_shared/index.html +0 -110
  134. package/coverage/lcov-report/src/constants/ClockType.ts.html +0 -102
  135. package/coverage/lcov-report/src/constants/dimensions.ts.html +0 -84
  136. package/coverage/lcov-report/src/constants/index.html +0 -110
  137. package/coverage/lcov-report/src/index.html +0 -97
  138. package/coverage/lcov-report/src/views/Calendar/Calendar.tsx.html +0 -1152
  139. package/coverage/lcov-report/src/views/Calendar/CalendarHeader.tsx.html +0 -492
  140. package/coverage/lcov-report/src/views/Calendar/Day.tsx.html +0 -360
  141. package/coverage/lcov-report/src/views/Calendar/DayWrapper.tsx.html +0 -168
  142. package/coverage/lcov-report/src/views/Calendar/SlideTransition.tsx.html +0 -369
  143. package/coverage/lcov-report/src/views/Calendar/index.html +0 -149
  144. package/coverage/lcov-report/src/views/Clock/Clock.tsx.html +0 -585
  145. package/coverage/lcov-report/src/views/Clock/ClockPointer.tsx.html +0 -381
  146. package/coverage/lcov-report/src/views/Clock/index.html +0 -110
  147. package/coverage/lcov-report/src/views/Month/Month.tsx.html +0 -297
  148. package/coverage/lcov-report/src/views/Month/MonthView.tsx.html +0 -351
  149. package/coverage/lcov-report/src/views/Month/index.html +0 -110
  150. package/coverage/lcov.info +0 -1094
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
3
+
4
+ export const ArrowLeftIcon: React.SFC<SvgIconProps> = props => {
5
+ return (
6
+ <SvgIcon {...props}>
7
+ <path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z" />
8
+ <path fill="none" d="M0 0h24v24H0V0z" />
9
+ </SvgIcon>
10
+ );
11
+ };
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
3
+
4
+ export const ArrowRightIcon: React.SFC<SvgIconProps> = props => {
5
+ return (
6
+ <SvgIcon {...props}>
7
+ <path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z" />
8
+ <path fill="none" d="M0 0h24v24H0V0z" />
9
+ </SvgIcon>
10
+ );
11
+ };
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
3
+
4
+ export const DateRangeIcon: React.SFC<SvgIconProps> = props => {
5
+ return (
6
+ <SvgIcon {...props}>
7
+ <path d="M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z" />
8
+ <path fill="none" d="M0 0h24v24H0z" />
9
+ </SvgIcon>
10
+ );
11
+ };
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
3
+
4
+ export const KeyboardIcon: React.SFC<SvgIconProps> = props => {
5
+ return (
6
+ <SvgIcon {...props}>
7
+ <path d="M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z" />
8
+ <path fill="none" d="M0 0h24v24H0z" />
9
+ </SvgIcon>
10
+ );
11
+ };
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';
3
+
4
+ export const TimeIcon: React.SFC<SvgIconProps> = props => {
5
+ return (
6
+ <SvgIcon {...props}>
7
+ <path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z" />
8
+ <path fill="none" d="M0 0h24v24H0z" />
9
+ <path d="M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z" />
10
+ </SvgIcon>
11
+ );
12
+ };
@@ -0,0 +1,11 @@
1
+ enum ClockType {
2
+ HOURS = 'hours',
3
+
4
+ MINUTES = 'minutes',
5
+
6
+ SECONDS = 'seconds',
7
+ }
8
+
9
+ export type ClockViewType = 'hours' | 'minutes' | 'seconds';
10
+
11
+ export default ClockType;
@@ -0,0 +1,5 @@
1
+ export const DIALOG_WIDTH = 310;
2
+
3
+ export const DIALOG_WIDTH_WIDER = 325;
4
+
5
+ export const VIEW_HEIGHT = 305;
@@ -0,0 +1,37 @@
1
+ import * as PropTypes from 'prop-types';
2
+ import { BaseTimePickerProps } from '../TimePicker/TimePicker';
3
+ import { BaseDatePickerProps } from '../DatePicker/DatePicker';
4
+
5
+ const date = PropTypes.oneOfType([
6
+ PropTypes.object,
7
+ PropTypes.string,
8
+ PropTypes.number,
9
+ PropTypes.instanceOf(Date),
10
+ ]);
11
+
12
+ const datePickerView = PropTypes.oneOf(['year', 'month', 'day']);
13
+
14
+ export type ParsableDate = object | string | number | Date | null | undefined;
15
+
16
+ export const DomainPropTypes = { date, datePickerView };
17
+
18
+ /* eslint-disable @typescript-eslint/no-object-literal-type-assertion */
19
+ export const timePickerDefaultProps = {
20
+ ampm: true,
21
+ invalidDateMessage: 'Invalid Time Format',
22
+ } as BaseTimePickerProps;
23
+
24
+ export const datePickerDefaultProps = {
25
+ minDate: new Date('1900-01-01'),
26
+ maxDate: new Date('2200-01-01'),
27
+ invalidDateMessage: 'Invalid Date Format',
28
+ minDateMessage: 'Date should not be before minimal date',
29
+ maxDateMessage: 'Date should not be after maximal date',
30
+ allowKeyboardControl: true,
31
+ } as BaseDatePickerProps;
32
+
33
+ export const dateTimePickerDefaultProps = {
34
+ ...timePickerDefaultProps,
35
+ ...datePickerDefaultProps,
36
+ showTabs: true,
37
+ } as BaseTimePickerProps & BaseDatePickerProps;
package/src/index.ts ADDED
@@ -0,0 +1,48 @@
1
+ import { MaterialUiPickersDate } from './typings/date';
2
+ import { KeyboardTimePickerProps } from './TimePicker';
3
+ import { DatePickerProps, KeyboardDatePickerProps } from './DatePicker';
4
+ import { DateTimePickerProps, KeyboardDateTimePickerProps } from './DateTimePicker';
5
+
6
+ export type TimePickerProps = KeyboardTimePickerProps;
7
+
8
+ export type KeyboardTimePickerProps = KeyboardTimePickerProps;
9
+
10
+ export type DatePickerProps = DatePickerProps;
11
+
12
+ export type KeyboardDatePickerProps = KeyboardDatePickerProps;
13
+
14
+ export type DateTimePickerProps = DateTimePickerProps;
15
+
16
+ export type KeyboardDateTimePickerProps = KeyboardDateTimePickerProps;
17
+
18
+ export type MaterialUiPickersDate = MaterialUiPickersDate;
19
+
20
+ export { DatePicker, KeyboardDatePicker } from './DatePicker';
21
+
22
+ export { TimePicker, KeyboardTimePicker } from './TimePicker';
23
+
24
+ export { DateTimePicker, KeyboardDateTimePicker } from './DateTimePicker';
25
+
26
+ export { default as Calendar } from './views/Calendar/Calendar';
27
+
28
+ export { default as Day } from './views/Calendar/Day';
29
+
30
+ export { default as TimePickerView } from './views/Clock/ClockView';
31
+
32
+ export { default as Clock } from './views/Clock/Clock';
33
+
34
+ export { Picker } from './Picker/Picker';
35
+
36
+ export { makePurePicker } from './Picker/WrappedPurePicker';
37
+
38
+ export { makeKeyboardPicker } from './Picker/WrappedKeyboardPicker';
39
+
40
+ export { validate } from './_helpers/text-field-helper';
41
+
42
+ export { useUtils } from './_shared/hooks/useUtils';
43
+
44
+ export { usePickerState } from './_shared/hooks/usePickerState';
45
+
46
+ export { useKeyboardPickerState } from './_shared/hooks/useKeyboardPickerState';
47
+
48
+ export { default as MuiPickersUtilsProvider, MuiPickersContext } from './MuiPickersUtilsProvider';
@@ -0,0 +1,60 @@
1
+ import { MaterialUiPickersDate } from './date';
2
+ import { WrapperVariant } from '../wrappers/Wrapper';
3
+ import { ParsableDate } from '../constants/prop-types';
4
+ import { ToolbarComponentProps } from '../Picker/Picker';
5
+
6
+ export interface BasePickerProps {
7
+ /** Picker value */
8
+ value: ParsableDate;
9
+ /** onChange callback */
10
+ onChange: (date: MaterialUiPickersDate) => void;
11
+ /**
12
+ * Auto accept date on selection
13
+ * @default false
14
+ */
15
+ autoOk?: boolean;
16
+ /** Format string */
17
+ format?: string;
18
+ /** Disable datepicker and text field */
19
+ disabled?: boolean;
20
+ /** Dynamic formatter of text field value */
21
+ labelFunc?: (date: MaterialUiPickersDate, invalidLabel: string) => string;
22
+ /** Date that will be initially highlighted if null was passed */
23
+ initialFocusedDate?: ParsableDate;
24
+ /**
25
+ * Message displaying in text field if date is invalid (doesn't work in keyboard mode)
26
+ * @default 'unknown'
27
+ */
28
+ invalidLabel?: string;
29
+ /**
30
+ * Message displaying in text field, if null passed (doesn't work in keyboard mode)
31
+ * @default ' '
32
+ */
33
+ emptyLabel?: string;
34
+ /** Callback fired when date is accepted */
35
+ onAccept?: (date: MaterialUiPickersDate) => void;
36
+ /** Callback fired when new error should be displayed */
37
+ onError?: (error: React.ReactNode, value: MaterialUiPickersDate | ParsableDate) => void;
38
+ /** On open callback */
39
+ onOpen?: () => void;
40
+ /** On close callback */
41
+ onClose?: () => void;
42
+ /** Controlled picker open state */
43
+ open?: boolean;
44
+ /**
45
+ * Hide toolbar and show only date/time views
46
+ * @default false
47
+ */
48
+ disableToolbar?: boolean;
49
+ /**
50
+ * Force rendering in particular orientation
51
+ * @default "portrait"
52
+ */
53
+ orientation?: 'portrait' | 'landscape';
54
+ /* Component that will replace default toolbar renderer */
55
+ ToolbarComponent?: React.ComponentType<ToolbarComponentProps>;
56
+ variant?: WrapperVariant;
57
+ showShiftButtons?: boolean;
58
+ setShiftFunction?: (days: number) => Date;
59
+ shiftButtonValues?: Object;
60
+ }
@@ -0,0 +1,3 @@
1
+ import { DateType } from '@date-io/type';
2
+
3
+ export type MaterialUiPickersDate = DateType | null;
@@ -0,0 +1,10 @@
1
+ import { Omit } from '@material-ui/core';
2
+ /**
3
+ * All standard components exposed by `material-ui` are `StyledComponents` with
4
+ * certain `classes`, on which one can also set a top-level `className` and inline
5
+ * `style`.
6
+ */
7
+ export type ExtendMui<C, Removals extends keyof C = never> = Omit<
8
+ C,
9
+ 'classes' | 'theme' | Removals
10
+ >;
@@ -0,0 +1,44 @@
1
+ import { styles as ClockStyles } from '../views/Clock/Clock';
2
+ import { useStyles as DayStyles } from '../views/Calendar/Day';
3
+ import { styles as ModalDialogStyles } from '../_shared/ModalDialog';
4
+ import { styles as CalendarStyles } from '../views/Calendar/Calendar';
5
+ import { useStyles as MuiPickersYearStyles } from '../views/Year/Year';
6
+ import { styles as ToolbarButtonStyles } from '../_shared/ToolbarButton';
7
+ import { useStyles as MuiPickersMonthStyles } from '../views/Month/Month';
8
+ import { styles as ClockPointerStyles } from '../views/Clock/ClockPointer';
9
+ import { useStyles as PickerToolbarStyles } from '../_shared/PickerToolbar';
10
+ import { useStyles as ClockNumberStyles } from '../views/Clock/ClockNumber';
11
+ import { useStyles as DTTabsStyles } from '../DateTimePicker/DateTimePickerTabs';
12
+ import { useStyles as DatePickerRootStyles } from '../DatePicker/DatePickerToolbar';
13
+ import { useStyles as MuiPickersYearSelectionStyles } from '../views/Year/YearView';
14
+ import { StyleRules, StyleRulesCallback } from '@material-ui/core/styles/withStyles';
15
+ import { useStyles as CalendarHeaderStyles } from '../views/Calendar/CalendarHeader';
16
+ import { useStyles as DTHeaderStyles } from '../DateTimePicker/DateTimePickerToolbar';
17
+ import { useStyles as TimePickerToolbarStyles } from '../TimePicker/TimePickerToolbar';
18
+ import { useStyles as SlideTransitionStyles } from '../views/Calendar/SlideTransition';
19
+ import { useStyles as MuiPickersMonthSelectionStyles } from '../views/Month/MonthView';
20
+ import { useStyles as MuiPickerDTToolbarStyles } from '../DateTimePicker/DateTimePickerToolbar';
21
+
22
+ type Classes<T> = Partial<StyleRules<any>>;
23
+
24
+ export interface MuiPickersOverrides {
25
+ MuiPickersDay?: Classes<typeof DayStyles>;
26
+ MuiPickerDTHeader?: Classes<typeof DTHeaderStyles>;
27
+ MuiPickerDTTabs?: Classes<typeof DTTabsStyles>;
28
+ MuiPickersCalendar?: Classes<typeof CalendarStyles>;
29
+ MuiPickersCalendarHeader?: Classes<typeof CalendarHeaderStyles>;
30
+ MuiPickersSlideTransition?: Classes<typeof SlideTransitionStyles>;
31
+ MuiPickersYearSelectionStyles?: Classes<typeof MuiPickersYearSelectionStyles>;
32
+ MuiPickersYear?: Classes<typeof MuiPickersYearStyles>;
33
+ MuiPickersMonthSelection?: Classes<typeof MuiPickersMonthSelectionStyles>;
34
+ MuiPickersMonth?: Classes<typeof MuiPickersMonthStyles>;
35
+ MuiPickersTimePickerToolbar?: Classes<typeof TimePickerToolbarStyles>;
36
+ MuiPickersClock?: Classes<typeof ClockStyles>;
37
+ MuiPickersClockNumber?: Classes<typeof ClockNumberStyles>;
38
+ MuiPickersClockPointer?: Classes<typeof ClockPointerStyles>;
39
+ MuiPickersModal?: Classes<typeof ModalDialogStyles>;
40
+ MuiPickersToolbar?: Classes<typeof PickerToolbarStyles>;
41
+ MuiPickersToolbarButton?: Classes<typeof ToolbarButtonStyles>;
42
+ MuiPickersDatePickerRoot?: Classes<typeof DatePickerRootStyles>;
43
+ MuiPickerDTToolbar?: Classes<typeof MuiPickerDTToolbarStyles>;
44
+ }
@@ -0,0 +1,361 @@
1
+ import * as React from 'react';
2
+ import * as PropTypes from 'prop-types';
3
+ import Day from './Day';
4
+ import DayWrapper from './DayWrapper';
5
+ import CalendarHeader from './CalendarHeader';
6
+ import CircularProgress from '@material-ui/core/CircularProgress';
7
+ import SlideTransition, { SlideDirection } from './SlideTransition';
8
+ import { Theme } from '@material-ui/core';
9
+ import { MaterialUiPickersDate } from '../../typings/date';
10
+ import { runKeyHandler } from '../../_shared/hooks/useKeyDown';
11
+ import { IconButtonProps } from '@material-ui/core/IconButton';
12
+ import { withStyles, WithStyles } from '@material-ui/core/styles';
13
+ import { findClosestEnabledDate } from '../../_helpers/date-utils';
14
+ import { withUtils, WithUtilsProps } from '../../_shared/WithUtils';
15
+
16
+ export interface OutterCalendarProps {
17
+ /** Left arrow icon */
18
+ leftArrowIcon?: React.ReactNode;
19
+ /** Right arrow icon */
20
+ rightArrowIcon?: React.ReactNode;
21
+ /** Custom renderer for day */
22
+ renderDay?: (
23
+ day: MaterialUiPickersDate,
24
+ selectedDate: MaterialUiPickersDate,
25
+ dayInCurrentMonth: boolean,
26
+ dayComponent: JSX.Element
27
+ ) => JSX.Element;
28
+ /**
29
+ * Enables keyboard listener for moving between days in calendar
30
+ * @default true
31
+ */
32
+ allowKeyboardControl?: boolean;
33
+ /**
34
+ * Props to pass to left arrow button
35
+ * @type {Partial<IconButtonProps>}
36
+ */
37
+ leftArrowButtonProps?: Partial<IconButtonProps>;
38
+ /**
39
+ * Props to pass to right arrow button
40
+ * @type {Partial<IconButtonProps>}
41
+ */
42
+ rightArrowButtonProps?: Partial<IconButtonProps>;
43
+ /** Disable specific date */
44
+ shouldDisableDate?: (day: MaterialUiPickersDate) => boolean;
45
+ /** Callback firing on month change. Return promise to render spinner till it will not be resolved */
46
+ onMonthChange?: (date: MaterialUiPickersDate) => void | Promise<void>;
47
+ /** Custom loading indicator */
48
+ loadingIndicator?: JSX.Element;
49
+ }
50
+
51
+ export interface CalendarProps
52
+ extends OutterCalendarProps,
53
+ WithUtilsProps,
54
+ WithStyles<typeof styles, true> {
55
+ /** Calendar Date */
56
+ date: MaterialUiPickersDate;
57
+ /** Calendar onChange */
58
+ onChange: (date: MaterialUiPickersDate, isFinish?: boolean) => void;
59
+ /** Min date */
60
+ minDate?: MaterialUiPickersDate;
61
+ /** Max date */
62
+ maxDate?: MaterialUiPickersDate;
63
+ /** Disable past dates */
64
+ disablePast?: boolean;
65
+ /** Disable future dates */
66
+ disableFuture?: boolean;
67
+ }
68
+
69
+ export interface CalendarState {
70
+ slideDirection: SlideDirection;
71
+ currentMonth: MaterialUiPickersDate;
72
+ lastDate?: MaterialUiPickersDate;
73
+ loadingQueue: number;
74
+ }
75
+
76
+ const KeyDownListener = ({ onKeyDown }: { onKeyDown: (e: KeyboardEvent) => void }) => {
77
+ React.useEffect(() => {
78
+ window.addEventListener('keydown', onKeyDown);
79
+ return () => {
80
+ window.removeEventListener('keydown', onKeyDown);
81
+ };
82
+ }, [onKeyDown]);
83
+
84
+ return null;
85
+ };
86
+
87
+ export class Calendar extends React.Component<CalendarProps, CalendarState> {
88
+ static propTypes: any = {
89
+ renderDay: PropTypes.func,
90
+ shouldDisableDate: PropTypes.func,
91
+ allowKeyboardControl: PropTypes.bool,
92
+ };
93
+
94
+ static defaultProps: Partial<CalendarProps> = {
95
+ minDate: new Date('1900-01-01'),
96
+ maxDate: new Date('2200-01-01'),
97
+ disablePast: false,
98
+ disableFuture: false,
99
+ allowKeyboardControl: true,
100
+ };
101
+
102
+ static getDerivedStateFromProps(nextProps: CalendarProps, state: CalendarState) {
103
+ const { utils, date: nextDate } = nextProps;
104
+
105
+ if (!utils.isEqual(nextDate, state.lastDate)) {
106
+ const nextMonth = utils.getMonth(nextDate);
107
+ const lastDate = state.lastDate || nextDate;
108
+ const lastMonth = utils.getMonth(lastDate);
109
+
110
+ return {
111
+ lastDate: nextDate,
112
+ currentMonth: nextProps.utils.startOfMonth(nextDate),
113
+ // prettier-ignore
114
+ slideDirection: nextMonth === lastMonth
115
+ ? state.slideDirection
116
+ : utils.isAfterDay(nextDate, lastDate)
117
+ ? 'left'
118
+ : 'right'
119
+ };
120
+ }
121
+
122
+ return null;
123
+ }
124
+
125
+ state: CalendarState = {
126
+ slideDirection: 'left',
127
+ currentMonth: this.props.utils.startOfMonth(this.props.date),
128
+ loadingQueue: 0,
129
+ };
130
+
131
+ componentDidMount() {
132
+ const { date, minDate, maxDate, utils, disablePast, disableFuture } = this.props;
133
+
134
+ if (this.shouldDisableDate(date)) {
135
+ const closestEnabledDate = findClosestEnabledDate({
136
+ date,
137
+ utils,
138
+ minDate: utils.date(minDate),
139
+ maxDate: utils.date(maxDate),
140
+ disablePast: Boolean(disablePast),
141
+ disableFuture: Boolean(disableFuture),
142
+ shouldDisableDate: this.shouldDisableDate,
143
+ });
144
+
145
+ this.handleDaySelect(closestEnabledDate, false);
146
+ }
147
+ }
148
+
149
+ private pushToLoadingQueue = () => {
150
+ const loadingQueue = this.state.loadingQueue + 1;
151
+ this.setState({ loadingQueue });
152
+ };
153
+
154
+ private popFromLoadingQueue = () => {
155
+ let loadingQueue = this.state.loadingQueue;
156
+ loadingQueue = loadingQueue <= 0 ? 0 : loadingQueue - 1;
157
+ this.setState({ loadingQueue });
158
+ };
159
+
160
+ handleChangeMonth = (newMonth: MaterialUiPickersDate, slideDirection: SlideDirection) => {
161
+ this.setState({ currentMonth: newMonth, slideDirection });
162
+
163
+ if (this.props.onMonthChange) {
164
+ const returnVal = this.props.onMonthChange(newMonth);
165
+ if (returnVal) {
166
+ this.pushToLoadingQueue();
167
+ returnVal.then(() => {
168
+ this.popFromLoadingQueue();
169
+ });
170
+ }
171
+ }
172
+ };
173
+
174
+ validateMinMaxDate = (day: MaterialUiPickersDate) => {
175
+ const { minDate, maxDate, utils, disableFuture, disablePast } = this.props;
176
+ const now = utils.date();
177
+ const moment = utils.moment;
178
+
179
+ return Boolean(
180
+ (disableFuture && utils.isAfterDay(day, now)) ||
181
+ (disablePast && moment(day).isBefore(now, 'second')) ||
182
+ (minDate && utils.isBeforeDay(day, utils.date(minDate))) ||
183
+ (maxDate && utils.isAfterDay(day, utils.date(maxDate)))
184
+ );
185
+ };
186
+
187
+ shouldDisablePrevMonth = () => {
188
+ const { utils, disablePast, minDate } = this.props;
189
+
190
+ const now = utils.date();
191
+ const firstEnabledMonth = utils.startOfMonth(
192
+ disablePast && utils.isAfter(now, utils.date(minDate)) ? now : utils.date(minDate)
193
+ );
194
+
195
+ return !utils.isBefore(firstEnabledMonth, this.state.currentMonth);
196
+ };
197
+
198
+ shouldDisableNextMonth = () => {
199
+ const { utils, disableFuture, maxDate } = this.props;
200
+
201
+ const now = utils.date();
202
+ const lastEnabledMonth = utils.startOfMonth(
203
+ disableFuture && utils.isBefore(now, utils.date(maxDate)) ? now : utils.date(maxDate)
204
+ );
205
+
206
+ return !utils.isAfter(lastEnabledMonth, this.state.currentMonth);
207
+ };
208
+
209
+ shouldDisableDate = (day: MaterialUiPickersDate) => {
210
+ const { shouldDisableDate } = this.props;
211
+
212
+ return this.validateMinMaxDate(day) || Boolean(shouldDisableDate && shouldDisableDate(day));
213
+ };
214
+
215
+ handleDaySelect = (day: MaterialUiPickersDate, isFinish = true) => {
216
+ const { date, utils } = this.props;
217
+
218
+ this.props.onChange(utils.mergeDateAndTime(day, date), isFinish);
219
+ };
220
+
221
+ moveToDay = (day: MaterialUiPickersDate) => {
222
+ const { utils } = this.props;
223
+
224
+ if (day && !this.shouldDisableDate(day)) {
225
+ if (utils.getMonth(day) !== utils.getMonth(this.state.currentMonth)) {
226
+ this.handleChangeMonth(utils.startOfMonth(day), 'left');
227
+ }
228
+
229
+ this.handleDaySelect(day, false);
230
+ }
231
+ };
232
+
233
+ handleKeyDown = (event: KeyboardEvent) => {
234
+ const { theme, date, utils } = this.props;
235
+
236
+ runKeyHandler(event, {
237
+ ArrowUp: () => this.moveToDay(utils.addDays(date, -7)),
238
+ ArrowDown: () => this.moveToDay(utils.addDays(date, 7)),
239
+ ArrowLeft: () => this.moveToDay(utils.addDays(date, theme.direction === 'ltr' ? -1 : 1)),
240
+ ArrowRight: () => this.moveToDay(utils.addDays(date, theme.direction === 'ltr' ? 1 : -1)),
241
+ });
242
+ };
243
+
244
+ private renderWeeks = () => {
245
+ const { utils, classes } = this.props;
246
+ const weeks = utils.getWeekArray(this.state.currentMonth);
247
+
248
+ return weeks.map(week => (
249
+ <div key={`week-${week[0]!.toString()}`} className={classes.week}>
250
+ {this.renderDays(week)}
251
+ </div>
252
+ ));
253
+ };
254
+
255
+ private renderDays = (week: MaterialUiPickersDate[]) => {
256
+ const { date, renderDay, utils } = this.props;
257
+
258
+ const now = utils.date();
259
+ const selectedDate = utils.startOfDay(date);
260
+ const currentMonthNumber = utils.getMonth(this.state.currentMonth);
261
+
262
+ return week.map(day => {
263
+ const disabled = this.shouldDisableDate(day);
264
+ const isDayInCurrentMonth = utils.getMonth(day) === currentMonthNumber;
265
+
266
+ let dayComponent = (
267
+ <Day
268
+ disabled={disabled}
269
+ current={utils.isSameDay(day, now)}
270
+ hidden={!isDayInCurrentMonth}
271
+ selected={utils.isSameDay(selectedDate, day)}
272
+ >
273
+ {utils.getDayText(day)}
274
+ </Day>
275
+ );
276
+
277
+ if (renderDay) {
278
+ dayComponent = renderDay(day, selectedDate, isDayInCurrentMonth, dayComponent);
279
+ }
280
+
281
+ return (
282
+ <DayWrapper
283
+ value={day}
284
+ key={day!.toString()}
285
+ disabled={disabled}
286
+ dayInCurrentMonth={isDayInCurrentMonth}
287
+ onSelect={this.handleDaySelect}
288
+ >
289
+ {dayComponent}
290
+ </DayWrapper>
291
+ );
292
+ });
293
+ };
294
+
295
+ render() {
296
+ const { currentMonth, slideDirection } = this.state;
297
+ const {
298
+ classes,
299
+ allowKeyboardControl,
300
+ leftArrowButtonProps,
301
+ leftArrowIcon,
302
+ rightArrowButtonProps,
303
+ rightArrowIcon,
304
+ loadingIndicator,
305
+ } = this.props;
306
+ const loadingElement = loadingIndicator ? loadingIndicator : <CircularProgress />;
307
+
308
+ return (
309
+ <React.Fragment>
310
+ {allowKeyboardControl && <KeyDownListener onKeyDown={this.handleKeyDown} />}
311
+
312
+ <CalendarHeader
313
+ currentMonth={currentMonth!}
314
+ slideDirection={slideDirection}
315
+ onMonthChange={this.handleChangeMonth}
316
+ leftArrowIcon={leftArrowIcon}
317
+ leftArrowButtonProps={leftArrowButtonProps}
318
+ rightArrowIcon={rightArrowIcon}
319
+ rightArrowButtonProps={rightArrowButtonProps}
320
+ disablePrevMonth={this.shouldDisablePrevMonth()}
321
+ disableNextMonth={this.shouldDisableNextMonth()}
322
+ />
323
+
324
+ <SlideTransition
325
+ slideDirection={slideDirection}
326
+ transKey={currentMonth!.toString()}
327
+ className={classes.transitionContainer}
328
+ >
329
+ <>
330
+ {(this.state.loadingQueue > 0 && (
331
+ <div className={classes.progressContainer}>{loadingElement}</div>
332
+ )) || <div>{this.renderWeeks()}</div>}
333
+ </>
334
+ </SlideTransition>
335
+ </React.Fragment>
336
+ );
337
+ }
338
+ }
339
+
340
+ export const styles = (theme: Theme) => ({
341
+ transitionContainer: {
342
+ minHeight: 36 * 6,
343
+ marginTop: theme.spacing(1.5),
344
+ },
345
+ progressContainer: {
346
+ width: '100%',
347
+ height: '100%',
348
+ display: 'flex',
349
+ justifyContent: 'center',
350
+ alignItems: 'center',
351
+ },
352
+ week: {
353
+ display: 'flex',
354
+ justifyContent: 'center',
355
+ },
356
+ });
357
+
358
+ export default withStyles(styles, {
359
+ name: 'MuiPickersCalendar',
360
+ withTheme: true,
361
+ })(withUtils()(Calendar));