@transferwise/components 45.26.0 → 45.26.1

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 (36) hide show
  1. package/build/index.esm.js +152 -75
  2. package/build/index.esm.js.map +1 -1
  3. package/build/index.js +152 -75
  4. package/build/index.js.map +1 -1
  5. package/build/main.css +1 -1
  6. package/build/styles/dateLookup/DateLookup.css +1 -1
  7. package/build/styles/main.css +1 -1
  8. package/build/types/dateLookup/DateLookup.d.ts.map +1 -1
  9. package/build/types/dateLookup/getFocusableTime/getFocusableTime.d.ts +9 -0
  10. package/build/types/dateLookup/getFocusableTime/getFocusableTime.d.ts.map +1 -0
  11. package/build/types/dateLookup/monthCalendar/table/MonthCalendarTable.d.ts +1 -1
  12. package/build/types/dateLookup/monthCalendar/table/MonthCalendarTable.d.ts.map +1 -1
  13. package/build/types/dateLookup/tableLink/TableLink.d.ts +14 -4
  14. package/build/types/dateLookup/tableLink/TableLink.d.ts.map +1 -1
  15. package/build/types/dateLookup/tableLink/index.d.ts +1 -1
  16. package/build/types/dateLookup/tableLink/index.d.ts.map +1 -1
  17. package/build/types/dateLookup/yearCalendar/table/YearCalendarTable.d.ts.map +1 -1
  18. package/package.json +1 -1
  19. package/src/dateLookup/DateLookup.css +1 -1
  20. package/src/dateLookup/DateLookup.js +19 -4
  21. package/src/dateLookup/DateLookup.keyboardEvents.spec.js +12 -0
  22. package/src/dateLookup/DateLookup.less +39 -49
  23. package/src/dateLookup/DateLookup.story.js +8 -7
  24. package/src/dateLookup/dayCalendar/table/DayCalendarTable.js +28 -3
  25. package/src/dateLookup/dayCalendar/table/DayCalendarTable.spec.js +25 -0
  26. package/src/dateLookup/getFocusableTime/getFocusable.spec.ts +40 -0
  27. package/src/dateLookup/getFocusableTime/getFocusableTime.tsx +14 -0
  28. package/src/dateLookup/monthCalendar/table/MonthCalendarTable.js +33 -20
  29. package/src/dateLookup/monthCalendar/table/MonthCalendarTable.spec.js +33 -0
  30. package/src/dateLookup/tableLink/TableLink.spec.js +6 -15
  31. package/src/dateLookup/tableLink/TableLink.tsx +79 -0
  32. package/src/dateLookup/yearCalendar/table/YearCalendarTable.js +33 -11
  33. package/src/dateLookup/yearCalendar/table/YearCalendarTable.spec.js +26 -0
  34. package/src/main.css +1 -1
  35. package/src/dateLookup/tableLink/TableLink.js +0 -70
  36. /package/src/dateLookup/tableLink/{index.js → index.ts} +0 -0
package/build/index.js CHANGED
@@ -3609,6 +3609,10 @@ DateHeader.defaultProps = {
3609
3609
  };
3610
3610
  var DateHeader$1 = DateHeader;
3611
3611
 
3612
+ function getFocusableTime(props) {
3613
+ return props.timeSpan.find(time => props.isActive(time)) || props.timeSpan.find(time => props.isNow(time) && !props.isDisabled(time)) || props.timeSpan.find(time => !props.isDisabled(time));
3614
+ }
3615
+
3612
3616
  // NB! Using with UTC timestamp (YYYY-MM-DD) might lead to unexpected results, for example
3613
3617
  // getStartOfDay(new Date('1995-01-01')) in Los Angeles returns 31 Dec 1994, but in
3614
3618
  // in Singapore it is 1 Jan 1995.
@@ -3620,61 +3624,56 @@ function getStartOfDay(date) {
3620
3624
  return new Date(date.getFullYear(), date.getMonth(), date.getDate());
3621
3625
  }
3622
3626
 
3623
- class TableLink extends React.PureComponent {
3624
- onClick = event => {
3627
+ const TableLink = ({
3628
+ item,
3629
+ type,
3630
+ title,
3631
+ longTitle,
3632
+ active,
3633
+ disabled,
3634
+ today,
3635
+ autofocus,
3636
+ onClick
3637
+ }) => {
3638
+ const buttonRef = React.useRef(null);
3639
+ const intl = reactIntl.useIntl();
3640
+ React.useEffect(() => {
3641
+ if (autofocus) {
3642
+ setTimeout(() => {
3643
+ buttonRef.current?.focus();
3644
+ }, 0);
3645
+ }
3646
+ }, [autofocus]);
3647
+ const onCalendarClick = event => {
3625
3648
  event.preventDefault();
3626
- if (!this.props.disabled) {
3627
- this.props.onClick(this.props.item);
3649
+ if (!disabled) {
3650
+ onClick(item);
3628
3651
  }
3629
3652
  };
3630
- calculateAriaLabel = (longTitle, title, active, type, formatMessage) => {
3653
+ const calculateAriaLabel = () => {
3631
3654
  if (active) {
3632
- return `${longTitle || title}, ${formatMessage(messages$6.selected)} ${formatMessage(messages$6[type])}`;
3655
+ return `${longTitle || title || ''}, ${intl.formatMessage(messages$6.selected)} ${intl.formatMessage(messages$6[type])}`;
3633
3656
  }
3634
3657
  return longTitle || title;
3635
3658
  };
3636
- render() {
3637
- const {
3638
- item,
3639
- type,
3640
- title,
3641
- longTitle,
3642
- active,
3643
- disabled,
3644
- today,
3645
- intl: {
3646
- formatMessage
3647
- }
3648
- } = this.props;
3649
- return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
3650
- children: /*#__PURE__*/jsxRuntime.jsx("button", {
3651
- type: "button",
3652
- className: `tw-date-lookup-${type}-option ${active ? 'active' : ''} ${today ? 'today' : ''} np-text-body-default-bold`,
3653
- disabled: disabled,
3654
- "aria-label": this.calculateAriaLabel(longTitle, title, active, type, formatMessage),
3655
- "aria-pressed": active,
3656
- onClick: this.onClick,
3657
- children: title || item
3658
- })
3659
- });
3660
- }
3661
- }
3662
- TableLink.propTypes = {
3663
- item: PropTypes__default.default.number.isRequired,
3664
- // day (1-31), month (0-11) or year (2018 etc)
3665
- type: PropTypes__default.default.oneOf(['day', 'month', 'year']).isRequired,
3666
- title: PropTypes__default.default.string,
3667
- longTitle: PropTypes__default.default.string,
3668
- active: PropTypes__default.default.bool.isRequired,
3669
- disabled: PropTypes__default.default.bool.isRequired,
3670
- today: PropTypes__default.default.bool.isRequired,
3671
- onClick: PropTypes__default.default.func.isRequired
3672
- };
3673
- TableLink.defaultProps = {
3674
- title: null,
3675
- longTitle: null
3659
+ return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
3660
+ children: /*#__PURE__*/jsxRuntime.jsx("button", {
3661
+ ref: buttonRef,
3662
+ type: "button",
3663
+ className: classNames__default.default(`tw-date-lookup-${type}-option np-text-body-default-bold`, {
3664
+ active: !!active
3665
+ }, {
3666
+ today: !!today
3667
+ }),
3668
+ disabled: disabled,
3669
+ tabIndex: autofocus ? 0 : -1,
3670
+ "aria-label": calculateAriaLabel(),
3671
+ "aria-pressed": active,
3672
+ onClick: onCalendarClick,
3673
+ children: title || item
3674
+ })
3675
+ });
3676
3676
  };
3677
- var TableLink$1 = reactIntl.injectIntl(TableLink);
3678
3677
 
3679
3678
  const SHORT_DAY_FORMAT = {
3680
3679
  day: 'numeric'
@@ -3745,6 +3744,22 @@ class DayCalendarTable extends React.PureComponent {
3745
3744
  } = this.props;
3746
3745
  return !!(selectedDate && +new Date(viewYear, viewMonth, day) === +selectedDate);
3747
3746
  };
3747
+ isToday = day => {
3748
+ const {
3749
+ viewMonth,
3750
+ viewYear
3751
+ } = this.props;
3752
+ return Number(getStartOfDay(new Date())) === Number(new Date(viewYear, viewMonth, day));
3753
+ };
3754
+ getAutofocusDay = weeks => {
3755
+ const days = weeks.flatMap(week => week);
3756
+ return getFocusableTime({
3757
+ isActive: this.isActive,
3758
+ isNow: this.isToday,
3759
+ isDisabled: this.isDisabled,
3760
+ timeSpan: days
3761
+ });
3762
+ };
3748
3763
  render() {
3749
3764
  const {
3750
3765
  viewMonth,
@@ -3754,12 +3769,13 @@ class DayCalendarTable extends React.PureComponent {
3754
3769
  }
3755
3770
  } = this.props;
3756
3771
  const weeks = this.getTableStructure();
3772
+ let autoFocusDay = this.getAutofocusDay(weeks, viewMonth, viewYear);
3757
3773
  return /*#__PURE__*/jsxRuntime.jsxs("table", {
3758
3774
  className: "table table-condensed table-bordered tw-date-lookup-calendar m-b-0",
3759
3775
  children: [/*#__PURE__*/jsxRuntime.jsx("thead", {
3760
3776
  children: /*#__PURE__*/jsxRuntime.jsx("tr", {
3761
3777
  children: this.days.map((day, index) => /*#__PURE__*/jsxRuntime.jsxs("th", {
3762
- className: "text-xs-center np-text-body-default-bold",
3778
+ className: index > 4 ? 'text-xs-center np-text-body-default' : 'text-xs-center np-text-body-default-bold',
3763
3779
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
3764
3780
  className: "hidden-xs",
3765
3781
  children: /*#__PURE__*/jsxRuntime.jsx("abbr", {
@@ -3778,15 +3794,16 @@ class DayCalendarTable extends React.PureComponent {
3778
3794
  }), /*#__PURE__*/jsxRuntime.jsx("tbody", {
3779
3795
  children: weeks.map((week, weekIndex) => /*#__PURE__*/jsxRuntime.jsx("tr", {
3780
3796
  children: week.map((day, dayIndex) => /*#__PURE__*/jsxRuntime.jsx("td", {
3781
- className: dayIndex > 4 ? 'default' : '',
3782
- children: day && /*#__PURE__*/jsxRuntime.jsx(TableLink$1, {
3797
+ className: dayIndex > 4 ? 'weekend' : '',
3798
+ children: day && /*#__PURE__*/jsxRuntime.jsx(TableLink, {
3783
3799
  item: day,
3784
3800
  type: "day",
3785
3801
  title: formatting.formatDate(new Date(viewYear, viewMonth, day), locale, SHORT_DAY_FORMAT),
3802
+ autofocus: day === autoFocusDay,
3786
3803
  longTitle: formatting.formatDate(new Date(viewYear, viewMonth, day), locale),
3787
3804
  active: this.isActive(day),
3788
3805
  disabled: this.isDisabled(day),
3789
- today: +getStartOfDay(new Date()) === +new Date(viewYear, viewMonth, day),
3806
+ today: this.isToday(day),
3790
3807
  onClick: this.selectDay
3791
3808
  })
3792
3809
  }, dayIndex))
@@ -3887,11 +3904,11 @@ var DayCalendar$1 = reactIntl.injectIntl(DayCalendar);
3887
3904
 
3888
3905
  const ROWS$1 = 3;
3889
3906
  const COLS$1 = 4;
3890
- const MONTH_ONLY_FORMAY = {
3907
+ const MONTH_ONLY_FORMAT = {
3891
3908
  month: 'short'
3892
3909
  };
3893
3910
  const MonthCalendarTable = ({
3894
- selectedDate: selected,
3911
+ selectedDate,
3895
3912
  min,
3896
3913
  max,
3897
3914
  viewYear,
@@ -3901,19 +3918,37 @@ const MonthCalendarTable = ({
3901
3918
  const {
3902
3919
  locale
3903
3920
  } = reactIntl.useIntl();
3904
- const getLink = month => /*#__PURE__*/jsxRuntime.jsx(TableLink$1, {
3905
- item: month,
3906
- type: "month",
3907
- title: formatting.formatDate(new Date(viewYear, month), locale, MONTH_ONLY_FORMAY),
3908
- active: !!(selected && month === selected.getMonth() && viewYear === selected.getFullYear()),
3909
- disabled: isDisabled(month),
3910
- today: viewYear === new Date().getFullYear() && month === new Date().getMonth(),
3911
- onClick: onSelect
3912
- });
3921
+ const getLink = month => {
3922
+ return /*#__PURE__*/jsxRuntime.jsx(TableLink, {
3923
+ item: month,
3924
+ type: "month",
3925
+ title: formatting.formatDate(new Date(viewYear, month), locale, MONTH_ONLY_FORMAT),
3926
+ active: isActive(month),
3927
+ disabled: isDisabled(month),
3928
+ today: viewYear === new Date().getFullYear() && month === new Date().getMonth(),
3929
+ autofocus: autofocusMonth === month,
3930
+ onClick: onSelect
3931
+ });
3932
+ };
3933
+ const isActive = month => {
3934
+ return selectedDate && month === selectedDate.getMonth() && viewYear === selectedDate.getFullYear();
3935
+ };
3936
+ const isThisMonth = month => {
3937
+ return viewYear === new Date().getFullYear() && month === new Date().getMonth();
3938
+ };
3913
3939
  const isDisabled = month => {
3914
3940
  const date = new Date(viewYear, month);
3915
3941
  return !!(min && date < new Date(min.getFullYear(), min.getMonth()) || max && date > new Date(max.getFullYear(), max.getMonth()));
3916
3942
  };
3943
+ const autofocusMonth = (() => {
3944
+ const months = [...new Array(ROWS$1 * COLS$1)].map((_, index) => index);
3945
+ return getFocusableTime({
3946
+ isActive,
3947
+ isNow: isThisMonth,
3948
+ isDisabled,
3949
+ timeSpan: months
3950
+ });
3951
+ })();
3917
3952
  return /*#__PURE__*/jsxRuntime.jsxs("table", {
3918
3953
  className: "table table-condensed table-bordered tw-date-lookup-calendar np-text-body-default-bold m-b-0",
3919
3954
  children: [/*#__PURE__*/jsxRuntime.jsx("thead", {
@@ -4032,15 +4067,36 @@ const YearCalendarTable = ({
4032
4067
  locale
4033
4068
  } = reactIntl.useIntl();
4034
4069
  const startYear = viewYear - viewYear % 20;
4035
- const getLink = year => /*#__PURE__*/jsxRuntime.jsx(TableLink$1, {
4036
- item: year,
4037
- type: "year",
4038
- title: formatting.formatDate(new Date(year, 0), locale, YEAR_ONLY_FORMAT),
4039
- active: !!(selectedDate && year === selectedDate.getFullYear()),
4040
- disabled: !!(min && year < min.getFullYear() || max && year > max.getFullYear()),
4041
- today: year === new Date().getFullYear(),
4042
- onClick: onSelect
4043
- });
4070
+ const getLink = year => {
4071
+ return /*#__PURE__*/jsxRuntime.jsx(TableLink, {
4072
+ item: year,
4073
+ type: "year",
4074
+ title: formatting.formatDate(new Date(year, 0), locale, YEAR_ONLY_FORMAT),
4075
+ active: isActive(year),
4076
+ disabled: isDisabled(year),
4077
+ today: isThisYear(year),
4078
+ autofocus: autofocusYear === year,
4079
+ onClick: onSelect
4080
+ });
4081
+ };
4082
+ const isActive = year => {
4083
+ return !!(selectedDate && year === selectedDate.getFullYear());
4084
+ };
4085
+ const isThisYear = year => {
4086
+ return year === new Date().getFullYear();
4087
+ };
4088
+ const isDisabled = year => {
4089
+ return !!(min && year < min.getFullYear() || max && year > max.getFullYear());
4090
+ };
4091
+ const autofocusYear = (() => {
4092
+ const years = [...new Array(ROWS * COLS)].map((_, index) => startYear + index);
4093
+ return getFocusableTime({
4094
+ isActive,
4095
+ isNow: isThisYear,
4096
+ isDisabled,
4097
+ timeSpan: years
4098
+ });
4099
+ })();
4044
4100
  return /*#__PURE__*/jsxRuntime.jsxs("table", {
4045
4101
  className: "table table-condensed table-bordered tw-date-lookup-calendar m-b-0",
4046
4102
  children: [/*#__PURE__*/jsxRuntime.jsx("thead", {
@@ -4147,6 +4203,7 @@ class DateLookup extends React.PureComponent {
4147
4203
  super(props);
4148
4204
  this.state = {
4149
4205
  selectedDate: getStartOfDay(props.value),
4206
+ originalDate: null,
4150
4207
  min: getStartOfDay(props.min),
4151
4208
  max: getStartOfDay(props.max),
4152
4209
  viewMonth: (props.value || new Date()).getMonth(),
@@ -4209,12 +4266,22 @@ class DateLookup extends React.PureComponent {
4209
4266
  onFocus();
4210
4267
  }
4211
4268
  };
4269
+ discard = () => {
4270
+ const {
4271
+ originalDate
4272
+ } = this.state;
4273
+ if (originalDate !== null) {
4274
+ this.props.onChange(originalDate);
4275
+ }
4276
+ this.close();
4277
+ };
4212
4278
  close = () => {
4213
4279
  const {
4214
4280
  onBlur
4215
4281
  } = this.props;
4216
4282
  this.setState({
4217
- open: false
4283
+ open: false,
4284
+ originalDate: null
4218
4285
  });
4219
4286
  if (onBlur) {
4220
4287
  onBlur();
@@ -4222,7 +4289,8 @@ class DateLookup extends React.PureComponent {
4222
4289
  };
4223
4290
  handleKeyDown = event => {
4224
4291
  const {
4225
- open
4292
+ open,
4293
+ originalDate
4226
4294
  } = this.state;
4227
4295
  switch (event.keyCode) {
4228
4296
  case KeyCodes.LEFT:
@@ -4258,6 +4326,9 @@ class DateLookup extends React.PureComponent {
4258
4326
  event.preventDefault();
4259
4327
  break;
4260
4328
  case KeyCodes.ESCAPE:
4329
+ if (originalDate !== null) {
4330
+ this.props.onChange(originalDate);
4331
+ }
4261
4332
  this.close();
4262
4333
  event.preventDefault();
4263
4334
  break;
@@ -4268,8 +4339,14 @@ class DateLookup extends React.PureComponent {
4268
4339
  selectedDate,
4269
4340
  min,
4270
4341
  max,
4271
- mode
4342
+ mode,
4343
+ originalDate
4272
4344
  } = this.state;
4345
+ if (originalDate === null) {
4346
+ this.setState({
4347
+ originalDate: selectedDate
4348
+ });
4349
+ }
4273
4350
  let date;
4274
4351
  if (selectedDate) {
4275
4352
  date = new Date(mode === MODE.YEAR ? selectedDate.getFullYear() + yearsToAdd : selectedDate.getFullYear(), mode === MODE.MONTH ? selectedDate.getMonth() + monthsToAdd : selectedDate.getMonth(), mode === MODE.DAY ? selectedDate.getDate() + daysToAdd : selectedDate.getDate());
@@ -4402,7 +4479,7 @@ class DateLookup extends React.PureComponent {
4402
4479
  open: open,
4403
4480
  className: "tw-date-lookup-menu",
4404
4481
  position: exports.Position.BOTTOM,
4405
- onClose: this.close,
4482
+ onClose: this.discard,
4406
4483
  children: this.getCalendar()
4407
4484
  })]
4408
4485
  });