@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,104 @@
1
+ import * as React from 'react';
2
+ import clsx from 'clsx';
3
+ import ClockType, { ClockViewType } from '../../constants/ClockType';
4
+ import { Theme } from '@material-ui/core';
5
+ import { withStyles, createStyles, WithStyles } from '@material-ui/core/styles';
6
+
7
+ export interface ClockPointerProps extends WithStyles<typeof styles> {
8
+ value: number;
9
+ hasSelected: boolean;
10
+ isInner: boolean;
11
+ type: ClockViewType;
12
+ }
13
+
14
+ export class ClockPointer extends React.Component<ClockPointerProps> {
15
+ public static getDerivedStateFromProps = (
16
+ nextProps: ClockPointerProps,
17
+ state: ClockPointer['state']
18
+ ) => {
19
+ if (nextProps.type !== state.previousType) {
20
+ return {
21
+ toAnimateTransform: true,
22
+ previousType: nextProps.type,
23
+ };
24
+ }
25
+
26
+ return {
27
+ toAnimateTransform: false,
28
+ previousType: nextProps.type,
29
+ };
30
+ };
31
+
32
+ public state = {
33
+ toAnimateTransform: false,
34
+ previousType: undefined,
35
+ };
36
+
37
+ public getAngleStyle = () => {
38
+ const { value, isInner, type } = this.props;
39
+
40
+ const max = type === ClockType.HOURS ? 12 : 60;
41
+ let angle = (360 / max) * value;
42
+
43
+ if (type === ClockType.HOURS && value > 12) {
44
+ angle -= 360; // round up angle to max 360 degrees
45
+ }
46
+
47
+ return {
48
+ height: isInner ? '26%' : '40%',
49
+ transform: `rotateZ(${angle}deg)`,
50
+ };
51
+ };
52
+
53
+ public render() {
54
+ const { classes, hasSelected } = this.props;
55
+
56
+ return (
57
+ <div
58
+ style={this.getAngleStyle()}
59
+ className={clsx(classes.pointer, {
60
+ [classes.animateTransform]: this.state.toAnimateTransform,
61
+ })}
62
+ >
63
+ <div
64
+ className={clsx(classes.thumb, {
65
+ [classes.noPoint]: hasSelected,
66
+ })}
67
+ />
68
+ </div>
69
+ );
70
+ }
71
+ }
72
+
73
+ export const styles = (theme: Theme) =>
74
+ createStyles({
75
+ pointer: {
76
+ width: 2,
77
+ backgroundColor: theme.palette.primary.main,
78
+ position: 'absolute',
79
+ left: 'calc(50% - 1px)',
80
+ bottom: '50%',
81
+ transformOrigin: 'center bottom 0px',
82
+ },
83
+ animateTransform: {
84
+ transition: theme.transitions.create(['transform', 'height']),
85
+ },
86
+ thumb: {
87
+ width: 4,
88
+ height: 4,
89
+ backgroundColor: theme.palette.primary.contrastText,
90
+ borderRadius: '100%',
91
+ position: 'absolute',
92
+ top: -21,
93
+ left: -15,
94
+ border: `14px solid ${theme.palette.primary.main}`,
95
+ boxSizing: 'content-box',
96
+ },
97
+ noPoint: {
98
+ backgroundColor: theme.palette.primary.main,
99
+ },
100
+ });
101
+
102
+ export default withStyles(styles, {
103
+ name: 'MuiPickersClockPointer',
104
+ })(ClockPointer as React.ComponentType<ClockPointerProps>);
@@ -0,0 +1,105 @@
1
+ import * as React from 'react';
2
+ import * as PropTypes from 'prop-types';
3
+ import Clock from './Clock';
4
+ import ClockType, { ClockViewType } from '../../constants/ClockType';
5
+ import { useUtils } from '../../_shared/hooks/useUtils';
6
+ import { MaterialUiPickersDate } from '../../typings/date';
7
+ import { getHourNumbers, getMinutesNumbers } from './ClockNumbers';
8
+ import { convertToMeridiem, getMeridiem } from '../../_helpers/time-utils';
9
+
10
+ export interface TimePickerViewProps {
11
+ /** TimePicker value */
12
+ date: MaterialUiPickersDate;
13
+ /** Clock type */
14
+ type: ClockViewType;
15
+ /** 12h/24h clock mode */
16
+ ampm?: boolean;
17
+ /** Minutes step */
18
+ minutesStep?: number;
19
+ /** On hour change */
20
+ onHourChange: (date: MaterialUiPickersDate, isFinish?: boolean) => void;
21
+ /** On minutes change */
22
+ onMinutesChange: (date: MaterialUiPickersDate, isFinish?: boolean) => void;
23
+ /** On seconds change */
24
+ onSecondsChange: (date: MaterialUiPickersDate, isFinish?: boolean) => void;
25
+ }
26
+
27
+ export const TimePickerView: React.FC<TimePickerViewProps> = ({
28
+ type,
29
+ onHourChange,
30
+ onMinutesChange,
31
+ onSecondsChange,
32
+ ampm,
33
+ date,
34
+ minutesStep,
35
+ }) => {
36
+ const utils = useUtils();
37
+ const viewProps = React.useMemo(() => {
38
+ switch (type) {
39
+ case ClockType.HOURS:
40
+ return {
41
+ value: utils.getHours(date),
42
+ children: getHourNumbers({ date, utils, ampm: Boolean(ampm) }),
43
+ onChange: (value: number, isFinish?: boolean) => {
44
+ const currentMeridiem = getMeridiem(date, utils);
45
+ const updatedTimeWithMeridiem = convertToMeridiem(
46
+ utils.setHours(date, value),
47
+ currentMeridiem,
48
+ Boolean(ampm),
49
+ utils
50
+ );
51
+
52
+ onHourChange(updatedTimeWithMeridiem, isFinish);
53
+ },
54
+ };
55
+
56
+ case ClockType.MINUTES:
57
+ const minutesValue = utils.getMinutes(date);
58
+ return {
59
+ value: minutesValue,
60
+ children: getMinutesNumbers({ value: minutesValue, utils }),
61
+ onChange: (value: number, isFinish?: boolean) => {
62
+ const updatedTime = utils.setMinutes(date, value);
63
+
64
+ onMinutesChange(updatedTime, isFinish);
65
+ },
66
+ };
67
+
68
+ case ClockType.SECONDS:
69
+ const secondsValue = utils.getSeconds(date);
70
+ return {
71
+ value: secondsValue,
72
+ children: getMinutesNumbers({ value: secondsValue, utils }),
73
+ onChange: (value: number, isFinish?: boolean) => {
74
+ const updatedTime = utils.setSeconds(date, value);
75
+
76
+ onSecondsChange(updatedTime, isFinish);
77
+ },
78
+ };
79
+
80
+ default:
81
+ throw new Error('You must provide the type for TimePickerView');
82
+ }
83
+ }, [ampm, date, onHourChange, onMinutesChange, onSecondsChange, type, utils]);
84
+
85
+ return <Clock type={type} ampm={ampm} minutesStep={minutesStep} {...viewProps} />;
86
+ };
87
+
88
+ TimePickerView.displayName = 'TimePickerView';
89
+
90
+ TimePickerView.propTypes = {
91
+ date: PropTypes.object.isRequired,
92
+ onHourChange: PropTypes.func.isRequired,
93
+ onMinutesChange: PropTypes.func.isRequired,
94
+ onSecondsChange: PropTypes.func.isRequired,
95
+ ampm: PropTypes.bool,
96
+ minutesStep: PropTypes.number,
97
+ type: PropTypes.oneOf(Object.keys(ClockType).map(key => ClockType[key as any])).isRequired,
98
+ } as any;
99
+
100
+ TimePickerView.defaultProps = {
101
+ ampm: true,
102
+ minutesStep: 1,
103
+ };
104
+
105
+ export default React.memo(TimePickerView);
@@ -0,0 +1,76 @@
1
+ import * as React from 'react';
2
+ import clsx from 'clsx';
3
+ import Typography from '@material-ui/core/Typography';
4
+ import { makeStyles } from '@material-ui/core/styles';
5
+
6
+ export interface MonthProps {
7
+ children: React.ReactNode;
8
+ disabled?: boolean;
9
+ onSelect: (value: any) => void;
10
+ selected?: boolean;
11
+ value: any;
12
+ }
13
+
14
+ export const useStyles = makeStyles(
15
+ theme => ({
16
+ root: {
17
+ flex: '1 0 33.33%',
18
+ display: 'flex',
19
+ alignItems: 'center',
20
+ justifyContent: 'center',
21
+ cursor: 'pointer',
22
+ outline: 'none',
23
+ height: 75,
24
+ transition: theme.transitions.create('font-size', { duration: '100ms' }),
25
+ '&:focus': {
26
+ color: theme.palette.primary.main,
27
+ fontWeight: theme.typography.fontWeightMedium,
28
+ },
29
+ },
30
+ monthSelected: {
31
+ color: theme.palette.primary.main,
32
+ fontWeight: theme.typography.fontWeightMedium,
33
+ },
34
+ monthDisabled: {
35
+ pointerEvents: 'none',
36
+ color: theme.palette.text.hint,
37
+ },
38
+ }),
39
+ { name: 'MuiPickersMonth' }
40
+ );
41
+
42
+ export const Month: React.FC<MonthProps> = ({
43
+ selected,
44
+ onSelect,
45
+ disabled,
46
+ value,
47
+ children,
48
+ ...other
49
+ }) => {
50
+ const classes = useStyles();
51
+ const handleSelection = React.useCallback(() => {
52
+ onSelect(value);
53
+ }, [onSelect, value]);
54
+
55
+ return (
56
+ <Typography
57
+ role="button"
58
+ component="div"
59
+ className={clsx(classes.root, {
60
+ [classes.monthSelected]: selected,
61
+ [classes.monthDisabled]: disabled,
62
+ })}
63
+ tabIndex={disabled ? -1 : 0}
64
+ onClick={handleSelection}
65
+ onKeyPress={handleSelection}
66
+ color={selected ? 'primary' : undefined}
67
+ variant={selected ? 'h5' : 'subtitle1'}
68
+ children={children}
69
+ {...other}
70
+ />
71
+ );
72
+ };
73
+
74
+ Month.displayName = 'Month';
75
+
76
+ export default Month;
@@ -0,0 +1,94 @@
1
+ import * as React from 'react';
2
+ import Month from './Month';
3
+ import { makeStyles } from '@material-ui/core/styles';
4
+ import { useUtils } from '../../_shared/hooks/useUtils';
5
+ import { ParsableDate } from '../../constants/prop-types';
6
+ import { MaterialUiPickersDate } from '../../typings/date';
7
+
8
+ export interface MonthSelectionProps {
9
+ date: MaterialUiPickersDate;
10
+ minDate?: ParsableDate;
11
+ maxDate?: ParsableDate;
12
+ onChange: (date: MaterialUiPickersDate, isFinish: boolean) => void;
13
+ disablePast?: boolean | null | undefined;
14
+ disableFuture?: boolean | null | undefined;
15
+ onMonthChange?: (date: MaterialUiPickersDate) => void | Promise<void>;
16
+ }
17
+
18
+ export const useStyles = makeStyles(
19
+ {
20
+ container: {
21
+ width: 310,
22
+ display: 'flex',
23
+ flexWrap: 'wrap',
24
+ alignContent: 'stretch',
25
+ },
26
+ },
27
+ { name: 'MuiPickersMonthSelection' }
28
+ );
29
+
30
+ export const MonthSelection: React.FC<MonthSelectionProps> = ({
31
+ disablePast,
32
+ disableFuture,
33
+ minDate,
34
+ maxDate,
35
+ date,
36
+ onMonthChange,
37
+ onChange,
38
+ }) => {
39
+ const utils = useUtils();
40
+ const classes = useStyles();
41
+ const currentMonth = utils.getMonth(date);
42
+
43
+ const shouldDisableMonth = (month: MaterialUiPickersDate) => {
44
+ const now = utils.date();
45
+ const utilMinDate = utils.date(minDate);
46
+ const utilMaxDate = utils.date(maxDate);
47
+
48
+ const firstEnabledMonth = utils.startOfMonth(
49
+ disablePast && utils.isAfter(now, utilMinDate) ? now : utilMinDate
50
+ );
51
+
52
+ const lastEnabledMonth = utils.startOfMonth(
53
+ disableFuture && utils.isBefore(now, utilMaxDate) ? now : utilMaxDate
54
+ );
55
+
56
+ const isBeforeFirstEnabled = utils.isBefore(month, firstEnabledMonth);
57
+ const isAfterLastEnabled = utils.isAfter(month, lastEnabledMonth);
58
+
59
+ return isBeforeFirstEnabled || isAfterLastEnabled;
60
+ };
61
+
62
+ const onMonthSelect = React.useCallback(
63
+ (month: number) => {
64
+ const newDate = utils.setMonth(date, month);
65
+
66
+ onChange(newDate, true);
67
+ if (onMonthChange) {
68
+ onMonthChange(newDate);
69
+ }
70
+ },
71
+ [date, onChange, onMonthChange, utils]
72
+ );
73
+
74
+ return (
75
+ <div className={classes.container}>
76
+ {utils.getMonthArray(date).map(month => {
77
+ const monthNumber = utils.getMonth(month);
78
+ const monthText = utils.format(month, 'MMM');
79
+
80
+ return (
81
+ <Month
82
+ key={monthText}
83
+ value={monthNumber}
84
+ selected={monthNumber === currentMonth}
85
+ onSelect={onMonthSelect}
86
+ disabled={shouldDisableMonth(month)}
87
+ >
88
+ {monthText}
89
+ </Month>
90
+ );
91
+ })}
92
+ </div>
93
+ );
94
+ };
@@ -0,0 +1,77 @@
1
+ import * as React from 'react';
2
+ import clsx from 'clsx';
3
+ import Typography from '@material-ui/core/Typography';
4
+ import { makeStyles } from '@material-ui/core/styles';
5
+
6
+ export interface YearProps {
7
+ children: React.ReactNode;
8
+ disabled?: boolean;
9
+ onSelect: (value: any) => void;
10
+ selected?: boolean;
11
+ value: any;
12
+ forwardedRef?: React.Ref<HTMLElement | null>;
13
+ }
14
+
15
+ export const useStyles = makeStyles(
16
+ theme => ({
17
+ root: {
18
+ height: 40,
19
+ display: 'flex',
20
+ alignItems: 'center',
21
+ justifyContent: 'center',
22
+ cursor: 'pointer',
23
+ outline: 'none',
24
+ '&:focus': {
25
+ color: theme.palette.primary.main,
26
+ fontWeight: theme.typography.fontWeightMedium,
27
+ },
28
+ },
29
+ yearSelected: {
30
+ margin: '10px 0',
31
+ fontWeight: theme.typography.fontWeightMedium,
32
+ },
33
+ yearDisabled: {
34
+ pointerEvents: 'none',
35
+ color: theme.palette.text.hint,
36
+ },
37
+ }),
38
+ { name: 'MuiPickersYear' }
39
+ );
40
+
41
+ export const Year: React.FC<YearProps> = ({
42
+ onSelect,
43
+ forwardedRef,
44
+ value,
45
+ selected,
46
+ disabled,
47
+ children,
48
+ ...other
49
+ }) => {
50
+ const classes = useStyles();
51
+ const handleClick = React.useCallback(() => onSelect(value), [onSelect, value]);
52
+
53
+ return (
54
+ <Typography
55
+ role="button"
56
+ component="div"
57
+ tabIndex={disabled ? -1 : 0}
58
+ onClick={handleClick}
59
+ onKeyPress={handleClick}
60
+ color={selected ? 'primary' : undefined}
61
+ variant={selected ? 'h5' : 'subtitle1'}
62
+ children={children}
63
+ ref={forwardedRef}
64
+ className={clsx(classes.root, {
65
+ [classes.yearSelected]: selected,
66
+ [classes.yearDisabled]: disabled,
67
+ })}
68
+ {...other}
69
+ />
70
+ );
71
+ };
72
+
73
+ Year.displayName = 'Year';
74
+
75
+ export default React.forwardRef<HTMLElement, YearProps>((props, ref) => (
76
+ <Year {...props} forwardedRef={ref} />
77
+ ));
@@ -0,0 +1,91 @@
1
+ import * as React from 'react';
2
+ import Year from './Year';
3
+ import { DateType } from '@date-io/type';
4
+ import { makeStyles } from '@material-ui/core/styles';
5
+ import { useUtils } from '../../_shared/hooks/useUtils';
6
+ import { VariantContext } from '../../wrappers/Wrapper';
7
+ import { MaterialUiPickersDate } from '../../typings/date';
8
+
9
+ export interface YearSelectionProps {
10
+ date: MaterialUiPickersDate;
11
+ minDate: DateType;
12
+ maxDate: DateType;
13
+ onChange: (date: MaterialUiPickersDate, isFinish: boolean) => void;
14
+ disablePast?: boolean | null | undefined;
15
+ disableFuture?: boolean | null | undefined;
16
+ animateYearScrolling?: boolean | null | undefined;
17
+ onYearChange?: (date: MaterialUiPickersDate) => void;
18
+ }
19
+
20
+ export const useStyles = makeStyles(
21
+ {
22
+ container: {
23
+ height: 300,
24
+ overflowY: 'auto',
25
+ },
26
+ },
27
+ { name: 'MuiPickersYearSelection' }
28
+ );
29
+
30
+ export const YearSelection: React.FC<YearSelectionProps> = ({
31
+ date,
32
+ onChange,
33
+ onYearChange,
34
+ minDate,
35
+ maxDate,
36
+ disablePast,
37
+ disableFuture,
38
+ animateYearScrolling,
39
+ }) => {
40
+ const utils = useUtils();
41
+ const classes = useStyles();
42
+ const currentVariant = React.useContext(VariantContext);
43
+ const selectedYearRef = React.useRef<HTMLElement>(null);
44
+
45
+ React.useEffect(() => {
46
+ if (selectedYearRef.current && selectedYearRef.current.scrollIntoView) {
47
+ selectedYearRef.current.scrollIntoView({
48
+ block: currentVariant === 'static' ? 'nearest' : 'center',
49
+ behavior: animateYearScrolling ? 'smooth' : 'auto',
50
+ });
51
+ }
52
+ }, []); // eslint-disable-line
53
+
54
+ const currentYear = utils.getYear(date);
55
+ const onYearSelect = React.useCallback(
56
+ (year: number) => {
57
+ const newDate = utils.setYear(date, year);
58
+ if (onYearChange) {
59
+ onYearChange(newDate);
60
+ }
61
+
62
+ onChange(newDate, true);
63
+ },
64
+ [date, onChange, onYearChange, utils]
65
+ );
66
+
67
+ return (
68
+ <div className={classes.container}>
69
+ {utils.getYearRange(minDate, maxDate).map(year => {
70
+ const yearNumber = utils.getYear(year);
71
+ const selected = yearNumber === currentYear;
72
+
73
+ return (
74
+ <Year
75
+ key={utils.getYearText(year)}
76
+ selected={selected}
77
+ value={yearNumber}
78
+ onSelect={onYearSelect}
79
+ ref={selected ? selectedYearRef : undefined}
80
+ disabled={Boolean(
81
+ (disablePast && utils.isBeforeYear(year, utils.date())) ||
82
+ (disableFuture && utils.isAfterYear(year, utils.date()))
83
+ )}
84
+ >
85
+ {utils.getYearText(year)}
86
+ </Year>
87
+ );
88
+ })}
89
+ </div>
90
+ );
91
+ };
@@ -0,0 +1,80 @@
1
+ import * as React from 'react';
2
+ import * as PropTypes from 'prop-types';
3
+ import clsx from 'clsx';
4
+ import Popover, { PopoverProps as PopoverPropsType } from '@material-ui/core/Popover';
5
+ import { WrapperProps } from './Wrapper';
6
+ import { makeStyles } from '@material-ui/core/styles';
7
+ import { useKeyDown } from '../_shared/hooks/useKeyDown';
8
+ import { TextFieldProps } from '@material-ui/core/TextField';
9
+ import { DIALOG_WIDTH, DIALOG_WIDTH_WIDER } from '../constants/dimensions';
10
+
11
+ export const useStyles = makeStyles(
12
+ {
13
+ popoverPaper: {
14
+ width: DIALOG_WIDTH,
15
+ paddingBottom: 8,
16
+ },
17
+ popoverPaperWider: {
18
+ width: DIALOG_WIDTH_WIDER,
19
+ },
20
+ },
21
+ { name: 'MuiPickersInlineWrapper' }
22
+ );
23
+
24
+ export interface InlineWrapperProps<T = TextFieldProps> extends WrapperProps<T> {
25
+ /** Popover props passed to material-ui Popover (with variant="inline") */
26
+ PopoverProps?: Partial<PopoverPropsType>;
27
+ }
28
+
29
+ export const InlineWrapper: React.FC<InlineWrapperProps> = ({
30
+ open,
31
+ wider,
32
+ children,
33
+ PopoverProps,
34
+ onClear,
35
+ onDismiss,
36
+ onSetToday,
37
+ onAccept,
38
+ showTabs,
39
+ DateInputProps,
40
+ InputComponent,
41
+ ...other
42
+ }) => {
43
+ const ref = React.useRef();
44
+ const classes = useStyles();
45
+
46
+ useKeyDown(open, {
47
+ Enter: onAccept,
48
+ });
49
+
50
+ return (
51
+ <React.Fragment>
52
+ <InputComponent {...other} {...DateInputProps} inputRef={ref} />
53
+
54
+ <Popover
55
+ open={open}
56
+ onClose={onDismiss}
57
+ anchorEl={ref.current}
58
+ classes={{
59
+ paper: clsx(classes.popoverPaper, { [classes.popoverPaperWider]: wider }),
60
+ }}
61
+ anchorOrigin={{
62
+ vertical: 'bottom',
63
+ horizontal: 'center',
64
+ }}
65
+ transformOrigin={{
66
+ vertical: 'top',
67
+ horizontal: 'center',
68
+ }}
69
+ children={children}
70
+ {...PopoverProps}
71
+ />
72
+ </React.Fragment>
73
+ );
74
+ };
75
+
76
+ InlineWrapper.propTypes = {
77
+ onOpen: PropTypes.func,
78
+ onClose: PropTypes.func,
79
+ PopoverProps: PropTypes.object,
80
+ } as any;