@transferwise/components 0.0.0-experimental-1a3a746 → 0.0.0-experimental-65c6e3a

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 (83) hide show
  1. package/build/index.js +239 -107
  2. package/build/index.js.map +1 -1
  3. package/build/index.mjs +239 -107
  4. package/build/index.mjs.map +1 -1
  5. package/build/types/common/dateUtils/isWithinRange/isWithinRange.d.ts +1 -1
  6. package/build/types/common/dateUtils/isWithinRange/isWithinRange.d.ts.map +1 -1
  7. package/build/types/common/dateUtils/moveToWithinRange/moveToWithinRange.d.ts +1 -1
  8. package/build/types/common/dateUtils/moveToWithinRange/moveToWithinRange.d.ts.map +1 -1
  9. package/build/types/dateLookup/DateLookup.d.ts +28 -80
  10. package/build/types/dateLookup/DateLookup.d.ts.map +1 -1
  11. package/build/types/dateLookup/DateLookup.messages.d.ts +63 -42
  12. package/build/types/dateLookup/DateLookup.messages.d.ts.map +1 -1
  13. package/build/types/dateLookup/dateHeader/DateHeader.d.ts +22 -9
  14. package/build/types/dateLookup/dateHeader/DateHeader.d.ts.map +1 -1
  15. package/build/types/dateLookup/dateHeader/index.d.ts +1 -1
  16. package/build/types/dateLookup/dateHeader/index.d.ts.map +1 -1
  17. package/build/types/dateLookup/dateTrigger/DateTrigger.d.ts +31 -13
  18. package/build/types/dateLookup/dateTrigger/DateTrigger.d.ts.map +1 -1
  19. package/build/types/dateLookup/dateTrigger/index.d.ts +1 -1
  20. package/build/types/dateLookup/dateTrigger/index.d.ts.map +1 -1
  21. package/build/types/dateLookup/dayCalendar/DayCalendar.d.ts +2 -19
  22. package/build/types/dateLookup/dayCalendar/DayCalendar.d.ts.map +1 -1
  23. package/build/types/dateLookup/dayCalendar/index.d.ts +1 -1
  24. package/build/types/dateLookup/dayCalendar/index.d.ts.map +1 -1
  25. package/build/types/dateLookup/dayCalendar/table/DayCalendarTable.d.ts +2 -12
  26. package/build/types/dateLookup/dayCalendar/table/DayCalendarTable.d.ts.map +1 -1
  27. package/build/types/dateLookup/dayCalendar/table/index.d.ts +1 -1
  28. package/build/types/dateLookup/dayCalendar/table/index.d.ts.map +1 -1
  29. package/build/types/dateLookup/getStartOfDay/getStartOfDay.d.ts +1 -1
  30. package/build/types/dateLookup/getStartOfDay/getStartOfDay.d.ts.map +1 -1
  31. package/build/types/dateLookup/getStartOfDay/index.d.ts +1 -1
  32. package/build/types/dateLookup/getStartOfDay/index.d.ts.map +1 -1
  33. package/build/types/dateLookup/index.d.ts +1 -2
  34. package/build/types/dateLookup/index.d.ts.map +1 -1
  35. package/build/types/dateLookup/monthCalendar/MonthCalendar.d.ts +2 -17
  36. package/build/types/dateLookup/monthCalendar/MonthCalendar.d.ts.map +1 -1
  37. package/build/types/dateLookup/monthCalendar/index.d.ts +1 -1
  38. package/build/types/dateLookup/monthCalendar/index.d.ts.map +1 -1
  39. package/build/types/dateLookup/monthCalendar/table/MonthCalendarTable.d.ts +26 -10
  40. package/build/types/dateLookup/monthCalendar/table/MonthCalendarTable.d.ts.map +1 -1
  41. package/build/types/dateLookup/monthCalendar/table/index.d.ts +1 -1
  42. package/build/types/dateLookup/monthCalendar/table/index.d.ts.map +1 -1
  43. package/build/types/dateLookup/yearCalendar/YearCalendar.d.ts +2 -15
  44. package/build/types/dateLookup/yearCalendar/YearCalendar.d.ts.map +1 -1
  45. package/build/types/dateLookup/yearCalendar/index.d.ts +1 -1
  46. package/build/types/dateLookup/yearCalendar/index.d.ts.map +1 -1
  47. package/build/types/dateLookup/yearCalendar/table/YearCalendarTable.d.ts +26 -10
  48. package/build/types/dateLookup/yearCalendar/table/YearCalendarTable.d.ts.map +1 -1
  49. package/build/types/dateLookup/yearCalendar/table/index.d.ts +1 -1
  50. package/build/types/dateLookup/yearCalendar/table/index.d.ts.map +1 -1
  51. package/build/types/index.d.ts +0 -1
  52. package/build/types/index.d.ts.map +1 -1
  53. package/package.json +3 -3
  54. package/src/common/dateUtils/isWithinRange/isWithinRange.spec.ts +0 -21
  55. package/src/common/dateUtils/isWithinRange/isWithinRange.ts +2 -2
  56. package/src/common/dateUtils/moveToWithinRange/moveToWithinRange.ts +2 -11
  57. package/src/dateLookup/{DateLookup.tsx → DateLookup.js} +69 -114
  58. package/src/dateLookup/DateLookup.state.spec.js +0 -7
  59. package/src/dateLookup/{DateLookup.story.tsx → DateLookup.story.js} +14 -13
  60. package/src/dateLookup/dateHeader/{DateHeader.tsx → DateHeader.js} +15 -15
  61. package/src/dateLookup/dateTrigger/{DateTrigger.tsx → DateTrigger.js} +32 -15
  62. package/src/dateLookup/dateTrigger/DateTrigger.spec.js +22 -0
  63. package/src/dateLookup/dayCalendar/{DayCalendar.tsx → DayCalendar.js} +21 -14
  64. package/src/dateLookup/dayCalendar/table/{DayCalendarTable.tsx → DayCalendarTable.js} +37 -26
  65. package/src/dateLookup/getStartOfDay/{getStartOfDay.tsx → getStartOfDay.js} +1 -1
  66. package/src/dateLookup/index.js +1 -0
  67. package/src/dateLookup/monthCalendar/{MonthCalendar.tsx → MonthCalendar.js} +22 -19
  68. package/src/dateLookup/monthCalendar/table/{MonthCalendarTable.tsx → MonthCalendarTable.js} +30 -31
  69. package/src/dateLookup/yearCalendar/{YearCalendar.tsx → YearCalendar.js} +21 -18
  70. package/src/dateLookup/yearCalendar/table/{YearCalendarTable.tsx → YearCalendarTable.js} +28 -26
  71. package/src/index.ts +0 -1
  72. package/src/dateLookup/DateLookup.tests.story.tsx +0 -71
  73. package/src/dateLookup/index.ts +0 -2
  74. /package/src/dateLookup/{DateLookup.messages.ts → DateLookup.messages.js} +0 -0
  75. /package/src/dateLookup/dateHeader/{index.ts → index.js} +0 -0
  76. /package/src/dateLookup/dateTrigger/{index.ts → index.js} +0 -0
  77. /package/src/dateLookup/dayCalendar/{index.ts → index.js} +0 -0
  78. /package/src/dateLookup/dayCalendar/table/{index.ts → index.js} +0 -0
  79. /package/src/dateLookup/getStartOfDay/{index.ts → index.js} +0 -0
  80. /package/src/dateLookup/monthCalendar/{index.ts → index.js} +0 -0
  81. /package/src/dateLookup/monthCalendar/table/{index.ts → index.js} +0 -0
  82. /package/src/dateLookup/yearCalendar/{index.ts → index.js} +0 -0
  83. /package/src/dateLookup/yearCalendar/table/{index.ts → index.js} +0 -0
@@ -1,26 +1,17 @@
1
1
  import { formatDate } from '@transferwise/formatting';
2
+ import { isKey } from '@transferwise/neptune-validation';
3
+ import PropTypes from 'prop-types';
2
4
  import { useIntl } from 'react-intl';
3
5
 
4
6
  import Chevron from '../../chevron';
5
- import { Size, Position, SizeSmall, SizeMedium, SizeLarge } from '../../common';
7
+ import { Size, Position } from '../../common';
6
8
  import { CloseButton } from '../../common/closeButton/CloseButton';
7
9
 
8
10
  import messages from './DateTrigger.messages';
9
11
 
10
- interface DateTriggerProps {
11
- selectedDate: Date | null;
12
- size: SizeSmall | SizeMedium | SizeLarge;
13
- placeholder: string;
14
- label: string;
15
- monthFormat: 'short' | 'long';
16
- disabled: boolean;
17
- onClick: () => void;
18
- onClear?: () => void;
19
- }
20
-
21
- const DateTrigger: React.FC<DateTriggerProps> = ({
12
+ const DateTrigger = ({
22
13
  selectedDate,
23
- size = Size.MEDIUM,
14
+ size,
24
15
  placeholder,
25
16
  label,
26
17
  monthFormat,
@@ -30,6 +21,14 @@ const DateTrigger: React.FC<DateTriggerProps> = ({
30
21
  }) => {
31
22
  const { locale, formatMessage } = useIntl();
32
23
 
24
+ const handleKeyDown = (event) => {
25
+ if (isKey({ keyType: 'Space', event: event }) || isKey({ keyType: 'Enter', event: event })) {
26
+ event.stopPropagation();
27
+ event.preventDefault();
28
+ onClear();
29
+ }
30
+ };
31
+
33
32
  return (
34
33
  <>
35
34
  <button
@@ -65,11 +64,12 @@ const DateTrigger: React.FC<DateTriggerProps> = ({
65
64
  className={`clear-btn clear-btn--${size}`}
66
65
  aria-label={`${formatMessage(messages.ariaLabel)} ${label}`}
67
66
  size={Size.SMALL}
68
- onClick={(event: React.MouseEvent<HTMLButtonElement>) => {
67
+ onClick={(event) => {
69
68
  event.stopPropagation();
70
69
  event.preventDefault();
71
70
  onClear();
72
71
  }}
72
+ onKeyPress={handleKeyDown}
73
73
  />
74
74
  </span>
75
75
  </>
@@ -78,4 +78,21 @@ const DateTrigger: React.FC<DateTriggerProps> = ({
78
78
  );
79
79
  };
80
80
 
81
+ DateTrigger.propTypes = {
82
+ selectedDate: PropTypes.instanceOf(Date),
83
+ size: PropTypes.oneOf(['sm', 'md', 'lg']),
84
+ placeholder: PropTypes.string.isRequired,
85
+ label: PropTypes.string.isRequired,
86
+ monthFormat: PropTypes.oneOf(['short', 'long']).isRequired,
87
+ disabled: PropTypes.bool.isRequired,
88
+ onClick: PropTypes.func,
89
+ onClear: PropTypes.func,
90
+ };
91
+
92
+ DateTrigger.defaultProps = {
93
+ selectedDate: null,
94
+ size: Size.MEDIUM,
95
+ onClear: undefined,
96
+ };
97
+
81
98
  export default DateTrigger;
@@ -2,6 +2,7 @@ import * as formatting from '@transferwise/formatting';
2
2
  import { shallow } from 'enzyme';
3
3
 
4
4
  import Chevron from '../../chevron';
5
+ import { fakeKeyDownEventForKey } from '../../common/fakeEvents';
5
6
 
6
7
  import DateTrigger from '.';
7
8
 
@@ -115,6 +116,27 @@ describe('DateTrigger', () => {
115
116
  expect(clearButton()).toHaveLength(1);
116
117
  });
117
118
 
119
+ it('calls onClear when user press Space', () => {
120
+ const onClear = jest.fn();
121
+ component.setProps({ onClear });
122
+ clearButton().simulate('keypress', fakeKeyDownEventForKey(' '));
123
+ expect(onClear).toHaveBeenCalledTimes(1);
124
+ });
125
+
126
+ it('calls onClear when user press Enter', () => {
127
+ const onClear = jest.fn();
128
+ component.setProps({ onClear });
129
+ clearButton().simulate('keypress', fakeKeyDownEventForKey('Enter'));
130
+ expect(onClear).toHaveBeenCalledTimes(1);
131
+ });
132
+
133
+ it(`doesn't call onClear when user press a random key`, () => {
134
+ const onClear = jest.fn();
135
+ component.setProps({ onClear });
136
+ clearButton().simulate('keypress', fakeKeyDownEventForKey('r'));
137
+ expect(onClear).not.toHaveBeenCalled();
138
+ });
139
+
118
140
  const button = () => component.find('.np-date-trigger');
119
141
  const clearButton = () => component.find('.clear-btn');
120
142
  const chevron = () => component.find(Chevron);
@@ -1,6 +1,7 @@
1
1
  import { formatDate } from '@transferwise/formatting';
2
+ import PropTypes from 'prop-types';
2
3
  import { PureComponent } from 'react';
3
- import { injectIntl, WrappedComponentProps } from 'react-intl';
4
+ import { injectIntl } from 'react-intl';
4
5
 
5
6
  import { MonthFormat } from '../../common';
6
7
  import messages from '../DateLookup.messages';
@@ -8,19 +9,7 @@ import DateHeader from '../dateHeader';
8
9
 
9
10
  import DayCalendarTable from './table';
10
11
 
11
- interface DayCalendarProps extends WrappedComponentProps {
12
- selectedDate: Date | null;
13
- min: Date | null;
14
- max: Date | null;
15
- viewMonth: number;
16
- viewYear: number;
17
- monthFormat: `${MonthFormat}`;
18
- onSelect: (date: Date) => void;
19
- onLabelClick: () => void;
20
- onViewDateUpdate: (date: { month: number; year: number }) => void;
21
- }
22
-
23
- class DayCalendar extends PureComponent<DayCalendarProps> {
12
+ class DayCalendar extends PureComponent {
24
13
  selectPreviousMonth = () => {
25
14
  const { viewMonth, viewYear } = this.props;
26
15
  this.props.onViewDateUpdate({
@@ -67,4 +56,22 @@ class DayCalendar extends PureComponent<DayCalendarProps> {
67
56
  }
68
57
  }
69
58
 
59
+ DayCalendar.propTypes = {
60
+ selectedDate: PropTypes.instanceOf(Date),
61
+ min: PropTypes.instanceOf(Date),
62
+ max: PropTypes.instanceOf(Date),
63
+ viewMonth: PropTypes.number.isRequired,
64
+ viewYear: PropTypes.number.isRequired,
65
+ monthFormat: PropTypes.oneOf([MonthFormat.LONG, MonthFormat.SHORT]).isRequired,
66
+ onSelect: PropTypes.func.isRequired,
67
+ onLabelClick: PropTypes.func.isRequired,
68
+ onViewDateUpdate: PropTypes.func.isRequired,
69
+ };
70
+
71
+ DayCalendar.defaultProps = {
72
+ selectedDate: null,
73
+ min: null,
74
+ max: null,
75
+ };
76
+
70
77
  export default injectIntl(DayCalendar);
@@ -1,24 +1,16 @@
1
1
  import { formatDate } from '@transferwise/formatting';
2
+ import PropTypes from 'prop-types';
2
3
  import { PureComponent } from 'react';
3
- import { injectIntl, WrappedComponentProps } from 'react-intl';
4
+ import { injectIntl } from 'react-intl';
4
5
 
5
6
  import { getDayNames, isWithinRange } from '../../../common/dateUtils';
6
7
  import { getFocusableTime } from '../../getFocusableTime/getFocusableTime';
7
8
  import { getStartOfDay } from '../../getStartOfDay';
8
9
  import TableLink from '../../tableLink';
9
10
 
10
- const SHORT_DAY_FORMAT: Intl.DateTimeFormatOptions = { day: 'numeric' };
11
+ const SHORT_DAY_FORMAT = { day: 'numeric' };
11
12
 
12
- interface DayCalendarTableProps extends WrappedComponentProps {
13
- selectedDate: Date | null;
14
- min: Date | null;
15
- max: Date | null;
16
- viewMonth: number;
17
- viewYear: number;
18
- onSelect: (date: Date) => void;
19
- }
20
-
21
- class DayCalendarTable extends PureComponent<DayCalendarTableProps> {
13
+ class DayCalendarTable extends PureComponent {
22
14
  getTableStructure = () => {
23
15
  const { viewMonth, viewYear } = this.props;
24
16
  let firstDayOfMonth = new Date(viewYear, viewMonth, 1).getDay();
@@ -28,13 +20,13 @@ class DayCalendarTable extends PureComponent<DayCalendarTableProps> {
28
20
  }
29
21
  const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
30
22
 
31
- let week: number[] = [];
32
- const weeks: number[][] = [];
23
+ let week = [];
24
+ const weeks = [];
33
25
  let i;
34
26
 
35
27
  // Pad first week
36
28
  for (i = 1; i < firstDayOfMonth; i += 1) {
37
- week.push(-1);
29
+ week.push(false);
38
30
  }
39
31
  // Fill in days
40
32
  for (i = 1; i <= daysInMonth; i += 1) {
@@ -47,7 +39,7 @@ class DayCalendarTable extends PureComponent<DayCalendarTableProps> {
47
39
  if (week.length > 0) {
48
40
  // Pad last week
49
41
  for (i = week.length; i < 7; i += 1) {
50
- week.push(-1);
42
+ week.push(false);
51
43
  }
52
44
  weeks.push(week);
53
45
  }
@@ -58,29 +50,29 @@ class DayCalendarTable extends PureComponent<DayCalendarTableProps> {
58
50
  daysShort = getDayNames(this.props.intl.locale, 'narrow');
59
51
  daysLong = getDayNames(this.props.intl.locale, 'long');
60
52
 
61
- selectDay = (day: number) => {
53
+ selectDay = (day) => {
62
54
  const { viewMonth, viewYear, onSelect } = this.props;
63
55
  onSelect(new Date(viewYear, viewMonth, day));
64
56
  };
65
57
 
66
- isDisabled = (day: number) => {
58
+ isDisabled = (day) => {
67
59
  const { min, max, viewMonth, viewYear } = this.props;
68
60
  const date = new Date(viewYear, viewMonth, day);
69
61
 
70
62
  return !isWithinRange(date, min, max);
71
63
  };
72
64
 
73
- isActive = (day: number) => {
65
+ isActive = (day) => {
74
66
  const { selectedDate, viewMonth, viewYear } = this.props;
75
67
  return !!(selectedDate && +new Date(viewYear, viewMonth, day) === +selectedDate);
76
68
  };
77
69
 
78
- isToday = (day: number) => {
70
+ isToday = (day) => {
79
71
  const { viewMonth, viewYear } = this.props;
80
72
  return Number(getStartOfDay(new Date())) === Number(new Date(viewYear, viewMonth, day));
81
73
  };
82
74
 
83
- getAutofocusDay = (weeks: number[][]) => {
75
+ getAutofocusDay = (weeks) => {
84
76
  const days = weeks.flatMap((week) => week);
85
77
  return getFocusableTime({
86
78
  isActive: this.isActive,
@@ -91,9 +83,13 @@ class DayCalendarTable extends PureComponent<DayCalendarTableProps> {
91
83
  };
92
84
 
93
85
  render() {
94
- const { viewMonth, viewYear, intl } = this.props;
86
+ const {
87
+ viewMonth,
88
+ viewYear,
89
+ intl: { locale },
90
+ } = this.props;
95
91
  const weeks = this.getTableStructure();
96
- const autoFocusDay = this.getAutofocusDay(weeks);
92
+ let autoFocusDay = this.getAutofocusDay(weeks, viewMonth, viewYear);
97
93
  return (
98
94
  <table className="table table-condensed table-bordered tw-date-lookup-calendar m-b-0">
99
95
  <thead>
@@ -123,17 +119,17 @@ class DayCalendarTable extends PureComponent<DayCalendarTableProps> {
123
119
  <tr key={weekIndex}>
124
120
  {week.map((day, dayIndex) => (
125
121
  <td key={dayIndex} className={dayIndex > 4 ? 'weekend' : ''}>
126
- {day !== -1 && (
122
+ {day && (
127
123
  <TableLink
128
124
  item={day}
129
125
  type="day"
130
126
  title={formatDate(
131
127
  new Date(viewYear, viewMonth, day),
132
- intl.locale,
128
+ locale,
133
129
  SHORT_DAY_FORMAT,
134
130
  )}
135
131
  autofocus={day === autoFocusDay}
136
- longTitle={formatDate(new Date(viewYear, viewMonth, day), intl.locale)}
132
+ longTitle={formatDate(new Date(viewYear, viewMonth, day), locale)}
137
133
  active={this.isActive(day)}
138
134
  disabled={this.isDisabled(day)}
139
135
  today={this.isToday(day)}
@@ -151,4 +147,19 @@ class DayCalendarTable extends PureComponent<DayCalendarTableProps> {
151
147
  }
152
148
  }
153
149
 
150
+ DayCalendarTable.propTypes = {
151
+ selectedDate: PropTypes.instanceOf(Date),
152
+ min: PropTypes.instanceOf(Date),
153
+ max: PropTypes.instanceOf(Date),
154
+ viewMonth: PropTypes.number.isRequired,
155
+ viewYear: PropTypes.number.isRequired,
156
+ onSelect: PropTypes.func.isRequired,
157
+ };
158
+
159
+ DayCalendarTable.defaultProps = {
160
+ selectedDate: null,
161
+ min: null,
162
+ max: null,
163
+ };
164
+
154
165
  export default injectIntl(DayCalendarTable);
@@ -2,7 +2,7 @@
2
2
  // getStartOfDay(new Date('1995-01-01')) in Los Angeles returns 31 Dec 1994, but in
3
3
  // in Singapore it is 1 Jan 1995.
4
4
  // You might want to use/implement `getUTCStartOfDay` if you want it to be 1995 in any timezone
5
- export function getStartOfDay(date: Date | null) {
5
+ export function getStartOfDay(date) {
6
6
  if (!date) {
7
7
  return null;
8
8
  }
@@ -0,0 +1 @@
1
+ export { default } from './DateLookup';
@@ -1,25 +1,15 @@
1
1
  import { formatDate } from '@transferwise/formatting';
2
+ import PropTypes from 'prop-types';
2
3
  import { PureComponent } from 'react';
3
- import { injectIntl, WrappedComponentProps } from 'react-intl';
4
+ import { injectIntl } from 'react-intl';
4
5
 
5
6
  import messages from '../DateLookup.messages';
6
7
  import DateHeader from '../dateHeader';
7
8
 
8
9
  import MonthCalendarTable from './table';
9
10
 
10
- interface MonthCalendarProps extends WrappedComponentProps {
11
- selectedDate: Date | null;
12
- min: Date | null;
13
- max: Date | null;
14
- viewYear: number;
15
- placeholder: string;
16
- onSelect: () => void;
17
- onLabelClick: () => void;
18
- onViewDateUpdate: (date: { year?: number; month?: number }) => void;
19
- }
20
-
21
- class MonthCalendar extends PureComponent<MonthCalendarProps> {
22
- onMonthSelect = (month: number) => {
11
+ class MonthCalendar extends PureComponent {
12
+ onMonthSelect = (month) => {
23
13
  this.props.onViewDateUpdate({ month });
24
14
  this.props.onSelect();
25
15
  };
@@ -52,11 +42,7 @@ class MonthCalendar extends PureComponent<MonthCalendarProps> {
52
42
  onNextClick={this.selectNextYear}
53
43
  />
54
44
  <MonthCalendarTable
55
- selectedDate={selectedDate}
56
- min={min}
57
- max={max}
58
- viewYear={viewYear}
59
- placeholder={placeholder}
45
+ {...{ selectedDate, min, max, viewYear, placeholder }}
60
46
  onSelect={this.onMonthSelect}
61
47
  />
62
48
  </>
@@ -64,4 +50,21 @@ class MonthCalendar extends PureComponent<MonthCalendarProps> {
64
50
  }
65
51
  }
66
52
 
53
+ MonthCalendar.propTypes = {
54
+ selectedDate: PropTypes.instanceOf(Date),
55
+ min: PropTypes.instanceOf(Date),
56
+ max: PropTypes.instanceOf(Date),
57
+ viewYear: PropTypes.number.isRequired,
58
+ placeholder: PropTypes.string.isRequired,
59
+ onSelect: PropTypes.func.isRequired,
60
+ onLabelClick: PropTypes.func.isRequired,
61
+ onViewDateUpdate: PropTypes.func.isRequired,
62
+ };
63
+
64
+ MonthCalendar.defaultProps = {
65
+ selectedDate: null,
66
+ min: null,
67
+ max: null,
68
+ };
69
+
67
70
  export default injectIntl(MonthCalendar);
@@ -1,33 +1,17 @@
1
1
  import { formatDate } from '@transferwise/formatting';
2
+ import PropTypes from 'prop-types';
2
3
  import { useIntl } from 'react-intl';
3
4
 
4
5
  import { getFocusableTime } from '../../getFocusableTime/getFocusableTime';
5
6
  import TableLink from '../../tableLink';
6
7
 
7
- interface MonthCalendarTableProps {
8
- selectedDate: Date | null;
9
- min: Date | null;
10
- max: Date | null;
11
- viewYear: number;
12
- placeholder: string;
13
- onSelect: (date: number) => void;
14
- }
15
-
16
8
  const ROWS = 3;
17
9
  const COLS = 4;
18
- const MONTH_ONLY_FORMAT: Intl.DateTimeFormatOptions = { month: 'short' };
10
+ const MONTH_ONLY_FORMAT = { month: 'short' };
19
11
 
20
- const MonthCalendarTable = ({
21
- selectedDate,
22
- min,
23
- max,
24
- viewYear,
25
- placeholder,
26
- onSelect,
27
- }: MonthCalendarTableProps) => {
12
+ const MonthCalendarTable = ({ selectedDate, min, max, viewYear, placeholder, onSelect }) => {
28
13
  const { locale } = useIntl();
29
-
30
- const getLink = (month: number) => {
14
+ const getLink = (month) => {
31
15
  return (
32
16
  <TableLink
33
17
  item={month}
@@ -42,19 +26,17 @@ const MonthCalendarTable = ({
42
26
  );
43
27
  };
44
28
 
45
- const isActive = (month: number) => {
46
- return !!(
47
- selectedDate &&
48
- month === selectedDate.getMonth() &&
49
- viewYear === selectedDate.getFullYear()
29
+ const isActive = (month) => {
30
+ return (
31
+ selectedDate && month === selectedDate.getMonth() && viewYear === selectedDate.getFullYear()
50
32
  );
51
33
  };
52
34
 
53
- const isThisMonth = (month: number) => {
35
+ const isThisMonth = (month) => {
54
36
  return viewYear === new Date().getFullYear() && month === new Date().getMonth();
55
37
  };
56
38
 
57
- const isDisabled = (month: number) => {
39
+ const isDisabled = (month) => {
58
40
  const date = new Date(viewYear, month);
59
41
  return !!(
60
42
  (min && date < new Date(min.getFullYear(), min.getMonth())) ||
@@ -63,7 +45,7 @@ const MonthCalendarTable = ({
63
45
  };
64
46
 
65
47
  const autofocusMonth = (() => {
66
- const months: number[] = [...new Array<number>(ROWS * COLS)].map((_, index) => index);
48
+ const months = [...new Array(ROWS * COLS)].map((_, index) => index);
67
49
  return getFocusableTime({ isActive, isNow: isThisMonth, isDisabled, timeSpan: months });
68
50
  })();
69
51
 
@@ -71,20 +53,37 @@ const MonthCalendarTable = ({
71
53
  <table className="table table-condensed table-bordered tw-date-lookup-calendar np-text-body-default-bold m-b-0">
72
54
  <thead className="sr-only">
73
55
  <tr>
74
- <th colSpan={COLS}>{placeholder}</th>
56
+ <th colSpan="3">{placeholder}</th>
75
57
  </tr>
76
58
  </thead>
77
59
  <tbody>
78
- {Array.from({ length: ROWS }, (_, rowIndex) => (
60
+ {/* eslint-disable react/no-array-index-key */}
61
+ {[...new Array(ROWS)].map((row, rowIndex) => (
79
62
  <tr key={rowIndex}>
80
- {Array.from({ length: COLS }, (_, colIndex) => (
63
+ {[...new Array(COLS)].map((col, colIndex) => (
81
64
  <td key={colIndex}>{getLink(rowIndex * COLS + colIndex)}</td>
82
65
  ))}
83
66
  </tr>
84
67
  ))}
68
+ {/* eslint-enable react/no-array-index-key */}
85
69
  </tbody>
86
70
  </table>
87
71
  );
88
72
  };
89
73
 
74
+ MonthCalendarTable.propTypes = {
75
+ selectedDate: PropTypes.instanceOf(Date),
76
+ min: PropTypes.instanceOf(Date),
77
+ max: PropTypes.instanceOf(Date),
78
+ viewYear: PropTypes.number.isRequired,
79
+ placeholder: PropTypes.string.isRequired,
80
+ onSelect: PropTypes.func.isRequired,
81
+ };
82
+
83
+ MonthCalendarTable.defaultProps = {
84
+ selectedDate: null,
85
+ min: null,
86
+ max: null,
87
+ };
88
+
90
89
  export default MonthCalendarTable;
@@ -1,23 +1,14 @@
1
+ import PropTypes from 'prop-types';
1
2
  import { PureComponent } from 'react';
2
- import { injectIntl, WrappedComponentProps } from 'react-intl';
3
+ import { injectIntl } from 'react-intl';
3
4
 
4
5
  import messages from '../DateLookup.messages';
5
6
  import DateHeader from '../dateHeader';
6
7
 
7
8
  import YearCalendarTable from './table';
8
9
 
9
- interface YearCalendarProps extends WrappedComponentProps {
10
- selectedDate: Date | null;
11
- min: Date | null;
12
- max: Date | null;
13
- viewYear: number;
14
- placeholder: string;
15
- onSelect: () => void;
16
- onViewDateUpdate: (date: { year: number }) => void;
17
- }
18
-
19
- class YearCalendar extends PureComponent<YearCalendarProps> {
20
- onYearSelect = (year: number) => {
10
+ class YearCalendar extends PureComponent {
11
+ onYearSelect = (year) => {
21
12
  this.props.onViewDateUpdate({ year });
22
13
  this.props.onSelect();
23
14
  };
@@ -47,11 +38,7 @@ class YearCalendar extends PureComponent<YearCalendarProps> {
47
38
  onNextClick={this.selectNextYears}
48
39
  />
49
40
  <YearCalendarTable
50
- selectedDate={selectedDate}
51
- min={min}
52
- max={max}
53
- viewYear={viewYear}
54
- placeholder={placeholder || ''}
41
+ {...{ selectedDate, min, max, viewYear, placeholder }}
55
42
  onSelect={this.onYearSelect}
56
43
  />
57
44
  </>
@@ -59,4 +46,20 @@ class YearCalendar extends PureComponent<YearCalendarProps> {
59
46
  }
60
47
  }
61
48
 
49
+ YearCalendar.propTypes = {
50
+ selectedDate: PropTypes.instanceOf(Date),
51
+ min: PropTypes.instanceOf(Date),
52
+ max: PropTypes.instanceOf(Date),
53
+ viewYear: PropTypes.number.isRequired,
54
+ placeholder: PropTypes.string.isRequired,
55
+ onSelect: PropTypes.func.isRequired,
56
+ onViewDateUpdate: PropTypes.func.isRequired,
57
+ };
58
+
59
+ YearCalendar.defaultProps = {
60
+ selectedDate: null,
61
+ min: null,
62
+ max: null,
63
+ };
64
+
62
65
  export default injectIntl(YearCalendar);
@@ -1,33 +1,18 @@
1
1
  import { formatDate } from '@transferwise/formatting';
2
+ import PropTypes from 'prop-types';
2
3
  import { useIntl } from 'react-intl';
3
4
 
4
5
  import { getFocusableTime } from '../../getFocusableTime/getFocusableTime';
5
6
  import TableLink from '../../tableLink';
6
7
 
7
- interface YearCalendarTableProps {
8
- selectedDate: Date | null;
9
- min: Date | null;
10
- max: Date | null;
11
- viewYear: number;
12
- placeholder: string;
13
- onSelect: (year: number) => void;
14
- }
15
-
16
8
  const ROWS = 5;
17
9
  const COLS = 4;
18
- const YEAR_ONLY_FORMAT: Intl.DateTimeFormatOptions = { year: 'numeric' };
10
+ const YEAR_ONLY_FORMAT = { year: 'numeric' };
19
11
 
20
- const YearCalendarTable = ({
21
- selectedDate,
22
- min,
23
- max,
24
- viewYear,
25
- placeholder,
26
- onSelect,
27
- }: YearCalendarTableProps) => {
12
+ const YearCalendarTable = ({ selectedDate, min, max, viewYear, placeholder, onSelect }) => {
28
13
  const { locale } = useIntl();
29
14
  const startYear = viewYear - (viewYear % 20);
30
- const getLink = (year: number) => {
15
+ const getLink = (year) => {
31
16
  return (
32
17
  <TableLink
33
18
  item={year}
@@ -42,20 +27,20 @@ const YearCalendarTable = ({
42
27
  );
43
28
  };
44
29
 
45
- const isActive = (year: number) => {
30
+ const isActive = (year) => {
46
31
  return !!(selectedDate && year === selectedDate.getFullYear());
47
32
  };
48
33
 
49
- const isThisYear = (year: number) => {
34
+ const isThisYear = (year) => {
50
35
  return year === new Date().getFullYear();
51
36
  };
52
37
 
53
- const isDisabled = (year: number) => {
38
+ const isDisabled = (year) => {
54
39
  return !!((min && year < min.getFullYear()) || (max && year > max.getFullYear()));
55
40
  };
56
41
 
57
42
  const autofocusYear = (() => {
58
- const years = [...new Array<number>(ROWS * COLS)].map((_, index) => startYear + index);
43
+ const years = [...new Array(ROWS * COLS)].map((_, index) => startYear + index);
59
44
  return getFocusableTime({ isActive, isNow: isThisYear, isDisabled, timeSpan: years });
60
45
  })();
61
46
 
@@ -63,20 +48,37 @@ const YearCalendarTable = ({
63
48
  <table className="table table-condensed table-bordered tw-date-lookup-calendar m-b-0">
64
49
  <thead className="sr-only">
65
50
  <tr>
66
- <th colSpan={COLS}>{placeholder}</th>
51
+ <th colSpan="4">{placeholder}</th>
67
52
  </tr>
68
53
  </thead>
69
54
  <tbody>
70
- {Array.from({ length: ROWS }, (_, rowIndex) => (
55
+ {/* eslint-disable react/no-array-index-key */}
56
+ {[...new Array(ROWS)].map((row, rowIndex) => (
71
57
  <tr key={rowIndex}>
72
- {Array.from({ length: COLS }, (_, colIndex) => (
58
+ {[...new Array(COLS)].map((col, colIndex) => (
73
59
  <td key={colIndex}>{getLink(startYear + rowIndex * COLS + colIndex)}</td>
74
60
  ))}
75
61
  </tr>
76
62
  ))}
63
+ {/* eslint-enable react/no-array-index-key */}
77
64
  </tbody>
78
65
  </table>
79
66
  );
80
67
  };
81
68
 
69
+ YearCalendarTable.propTypes = {
70
+ selectedDate: PropTypes.instanceOf(Date),
71
+ min: PropTypes.instanceOf(Date),
72
+ max: PropTypes.instanceOf(Date),
73
+ viewYear: PropTypes.number.isRequired,
74
+ placeholder: PropTypes.string.isRequired,
75
+ onSelect: PropTypes.func.isRequired,
76
+ };
77
+
78
+ YearCalendarTable.defaultProps = {
79
+ selectedDate: null,
80
+ min: null,
81
+ max: null,
82
+ };
83
+
82
84
  export default YearCalendarTable;
package/src/index.ts CHANGED
@@ -12,7 +12,6 @@ export type { InfoProps } from './info';
12
12
  export type { SummaryProps } from './summary';
13
13
  export type { InputProps } from './inputs/Input';
14
14
  export type { DateInputProps } from './dateInput';
15
- export type { DateLookupProps } from './dateLookup';
16
15
  export type { InputWithDisplayFormatProps } from './inputWithDisplayFormat';
17
16
  export type { InputGroupProps } from './inputs/InputGroup';
18
17
  export type { LoaderProps } from './loader';