@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.
- package/build/index.js +239 -107
- package/build/index.js.map +1 -1
- package/build/index.mjs +239 -107
- package/build/index.mjs.map +1 -1
- package/build/types/common/dateUtils/isWithinRange/isWithinRange.d.ts +1 -1
- package/build/types/common/dateUtils/isWithinRange/isWithinRange.d.ts.map +1 -1
- package/build/types/common/dateUtils/moveToWithinRange/moveToWithinRange.d.ts +1 -1
- package/build/types/common/dateUtils/moveToWithinRange/moveToWithinRange.d.ts.map +1 -1
- package/build/types/dateLookup/DateLookup.d.ts +28 -80
- package/build/types/dateLookup/DateLookup.d.ts.map +1 -1
- package/build/types/dateLookup/DateLookup.messages.d.ts +63 -42
- package/build/types/dateLookup/DateLookup.messages.d.ts.map +1 -1
- package/build/types/dateLookup/dateHeader/DateHeader.d.ts +22 -9
- package/build/types/dateLookup/dateHeader/DateHeader.d.ts.map +1 -1
- package/build/types/dateLookup/dateHeader/index.d.ts +1 -1
- package/build/types/dateLookup/dateHeader/index.d.ts.map +1 -1
- package/build/types/dateLookup/dateTrigger/DateTrigger.d.ts +31 -13
- package/build/types/dateLookup/dateTrigger/DateTrigger.d.ts.map +1 -1
- package/build/types/dateLookup/dateTrigger/index.d.ts +1 -1
- package/build/types/dateLookup/dateTrigger/index.d.ts.map +1 -1
- package/build/types/dateLookup/dayCalendar/DayCalendar.d.ts +2 -19
- package/build/types/dateLookup/dayCalendar/DayCalendar.d.ts.map +1 -1
- package/build/types/dateLookup/dayCalendar/index.d.ts +1 -1
- package/build/types/dateLookup/dayCalendar/index.d.ts.map +1 -1
- package/build/types/dateLookup/dayCalendar/table/DayCalendarTable.d.ts +2 -12
- package/build/types/dateLookup/dayCalendar/table/DayCalendarTable.d.ts.map +1 -1
- package/build/types/dateLookup/dayCalendar/table/index.d.ts +1 -1
- package/build/types/dateLookup/dayCalendar/table/index.d.ts.map +1 -1
- package/build/types/dateLookup/getStartOfDay/getStartOfDay.d.ts +1 -1
- package/build/types/dateLookup/getStartOfDay/getStartOfDay.d.ts.map +1 -1
- package/build/types/dateLookup/getStartOfDay/index.d.ts +1 -1
- package/build/types/dateLookup/getStartOfDay/index.d.ts.map +1 -1
- package/build/types/dateLookup/index.d.ts +1 -2
- package/build/types/dateLookup/index.d.ts.map +1 -1
- package/build/types/dateLookup/monthCalendar/MonthCalendar.d.ts +2 -17
- package/build/types/dateLookup/monthCalendar/MonthCalendar.d.ts.map +1 -1
- package/build/types/dateLookup/monthCalendar/index.d.ts +1 -1
- package/build/types/dateLookup/monthCalendar/index.d.ts.map +1 -1
- package/build/types/dateLookup/monthCalendar/table/MonthCalendarTable.d.ts +26 -10
- package/build/types/dateLookup/monthCalendar/table/MonthCalendarTable.d.ts.map +1 -1
- package/build/types/dateLookup/monthCalendar/table/index.d.ts +1 -1
- package/build/types/dateLookup/monthCalendar/table/index.d.ts.map +1 -1
- package/build/types/dateLookup/yearCalendar/YearCalendar.d.ts +2 -15
- package/build/types/dateLookup/yearCalendar/YearCalendar.d.ts.map +1 -1
- package/build/types/dateLookup/yearCalendar/index.d.ts +1 -1
- package/build/types/dateLookup/yearCalendar/index.d.ts.map +1 -1
- package/build/types/dateLookup/yearCalendar/table/YearCalendarTable.d.ts +26 -10
- package/build/types/dateLookup/yearCalendar/table/YearCalendarTable.d.ts.map +1 -1
- package/build/types/dateLookup/yearCalendar/table/index.d.ts +1 -1
- package/build/types/dateLookup/yearCalendar/table/index.d.ts.map +1 -1
- package/build/types/index.d.ts +0 -1
- package/build/types/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/common/dateUtils/isWithinRange/isWithinRange.spec.ts +0 -21
- package/src/common/dateUtils/isWithinRange/isWithinRange.ts +2 -2
- package/src/common/dateUtils/moveToWithinRange/moveToWithinRange.ts +2 -11
- package/src/dateLookup/{DateLookup.tsx → DateLookup.js} +69 -114
- package/src/dateLookup/DateLookup.state.spec.js +0 -7
- package/src/dateLookup/{DateLookup.story.tsx → DateLookup.story.js} +14 -13
- package/src/dateLookup/dateHeader/{DateHeader.tsx → DateHeader.js} +15 -15
- package/src/dateLookup/dateTrigger/{DateTrigger.tsx → DateTrigger.js} +32 -15
- package/src/dateLookup/dateTrigger/DateTrigger.spec.js +22 -0
- package/src/dateLookup/dayCalendar/{DayCalendar.tsx → DayCalendar.js} +21 -14
- package/src/dateLookup/dayCalendar/table/{DayCalendarTable.tsx → DayCalendarTable.js} +37 -26
- package/src/dateLookup/getStartOfDay/{getStartOfDay.tsx → getStartOfDay.js} +1 -1
- package/src/dateLookup/index.js +1 -0
- package/src/dateLookup/monthCalendar/{MonthCalendar.tsx → MonthCalendar.js} +22 -19
- package/src/dateLookup/monthCalendar/table/{MonthCalendarTable.tsx → MonthCalendarTable.js} +30 -31
- package/src/dateLookup/yearCalendar/{YearCalendar.tsx → YearCalendar.js} +21 -18
- package/src/dateLookup/yearCalendar/table/{YearCalendarTable.tsx → YearCalendarTable.js} +28 -26
- package/src/index.ts +0 -1
- package/src/dateLookup/DateLookup.tests.story.tsx +0 -71
- package/src/dateLookup/index.ts +0 -2
- /package/src/dateLookup/{DateLookup.messages.ts → DateLookup.messages.js} +0 -0
- /package/src/dateLookup/dateHeader/{index.ts → index.js} +0 -0
- /package/src/dateLookup/dateTrigger/{index.ts → index.js} +0 -0
- /package/src/dateLookup/dayCalendar/{index.ts → index.js} +0 -0
- /package/src/dateLookup/dayCalendar/table/{index.ts → index.js} +0 -0
- /package/src/dateLookup/getStartOfDay/{index.ts → index.js} +0 -0
- /package/src/dateLookup/monthCalendar/{index.ts → index.js} +0 -0
- /package/src/dateLookup/monthCalendar/table/{index.ts → index.js} +0 -0
- /package/src/dateLookup/yearCalendar/{index.ts → index.js} +0 -0
- /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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
11
|
+
const SHORT_DAY_FORMAT = { day: 'numeric' };
|
|
11
12
|
|
|
12
|
-
|
|
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
|
|
32
|
-
const weeks
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 {
|
|
86
|
+
const {
|
|
87
|
+
viewMonth,
|
|
88
|
+
viewYear,
|
|
89
|
+
intl: { locale },
|
|
90
|
+
} = this.props;
|
|
95
91
|
const weeks = this.getTableStructure();
|
|
96
|
-
|
|
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
|
|
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
|
-
|
|
128
|
+
locale,
|
|
133
129
|
SHORT_DAY_FORMAT,
|
|
134
130
|
)}
|
|
135
131
|
autofocus={day === autoFocusDay}
|
|
136
|
-
longTitle={formatDate(new Date(viewYear, viewMonth, day),
|
|
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
|
|
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
|
|
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
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
35
|
+
const isThisMonth = (month) => {
|
|
54
36
|
return viewYear === new Date().getFullYear() && month === new Date().getMonth();
|
|
55
37
|
};
|
|
56
38
|
|
|
57
|
-
const isDisabled = (month
|
|
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
|
|
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=
|
|
56
|
+
<th colSpan="3">{placeholder}</th>
|
|
75
57
|
</tr>
|
|
76
58
|
</thead>
|
|
77
59
|
<tbody>
|
|
78
|
-
{
|
|
60
|
+
{/* eslint-disable react/no-array-index-key */}
|
|
61
|
+
{[...new Array(ROWS)].map((row, rowIndex) => (
|
|
79
62
|
<tr key={rowIndex}>
|
|
80
|
-
{Array
|
|
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
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
30
|
+
const isActive = (year) => {
|
|
46
31
|
return !!(selectedDate && year === selectedDate.getFullYear());
|
|
47
32
|
};
|
|
48
33
|
|
|
49
|
-
const isThisYear = (year
|
|
34
|
+
const isThisYear = (year) => {
|
|
50
35
|
return year === new Date().getFullYear();
|
|
51
36
|
};
|
|
52
37
|
|
|
53
|
-
const isDisabled = (year
|
|
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
|
|
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=
|
|
51
|
+
<th colSpan="4">{placeholder}</th>
|
|
67
52
|
</tr>
|
|
68
53
|
</thead>
|
|
69
54
|
<tbody>
|
|
70
|
-
{
|
|
55
|
+
{/* eslint-disable react/no-array-index-key */}
|
|
56
|
+
{[...new Array(ROWS)].map((row, rowIndex) => (
|
|
71
57
|
<tr key={rowIndex}>
|
|
72
|
-
{Array
|
|
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';
|