@transferwise/components 45.25.2 → 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 (39) 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/chips/Chip.css +1 -1
  7. package/build/styles/dateLookup/DateLookup.css +1 -1
  8. package/build/styles/main.css +1 -1
  9. package/build/types/dateLookup/DateLookup.d.ts.map +1 -1
  10. package/build/types/dateLookup/getFocusableTime/getFocusableTime.d.ts +9 -0
  11. package/build/types/dateLookup/getFocusableTime/getFocusableTime.d.ts.map +1 -0
  12. package/build/types/dateLookup/monthCalendar/table/MonthCalendarTable.d.ts +1 -1
  13. package/build/types/dateLookup/monthCalendar/table/MonthCalendarTable.d.ts.map +1 -1
  14. package/build/types/dateLookup/tableLink/TableLink.d.ts +14 -4
  15. package/build/types/dateLookup/tableLink/TableLink.d.ts.map +1 -1
  16. package/build/types/dateLookup/tableLink/index.d.ts +1 -1
  17. package/build/types/dateLookup/tableLink/index.d.ts.map +1 -1
  18. package/build/types/dateLookup/yearCalendar/table/YearCalendarTable.d.ts.map +1 -1
  19. package/package.json +2 -2
  20. package/src/chips/Chip.css +1 -1
  21. package/src/chips/Chip.less +9 -21
  22. package/src/dateLookup/DateLookup.css +1 -1
  23. package/src/dateLookup/DateLookup.js +19 -4
  24. package/src/dateLookup/DateLookup.keyboardEvents.spec.js +12 -0
  25. package/src/dateLookup/DateLookup.less +39 -49
  26. package/src/dateLookup/DateLookup.story.js +8 -7
  27. package/src/dateLookup/dayCalendar/table/DayCalendarTable.js +28 -3
  28. package/src/dateLookup/dayCalendar/table/DayCalendarTable.spec.js +25 -0
  29. package/src/dateLookup/getFocusableTime/getFocusable.spec.ts +40 -0
  30. package/src/dateLookup/getFocusableTime/getFocusableTime.tsx +14 -0
  31. package/src/dateLookup/monthCalendar/table/MonthCalendarTable.js +33 -20
  32. package/src/dateLookup/monthCalendar/table/MonthCalendarTable.spec.js +33 -0
  33. package/src/dateLookup/tableLink/TableLink.spec.js +6 -15
  34. package/src/dateLookup/tableLink/TableLink.tsx +79 -0
  35. package/src/dateLookup/yearCalendar/table/YearCalendarTable.js +33 -11
  36. package/src/dateLookup/yearCalendar/table/YearCalendarTable.spec.js +26 -0
  37. package/src/main.css +1 -1
  38. package/src/dateLookup/tableLink/TableLink.js +0 -70
  39. /package/src/dateLookup/tableLink/{index.js → index.ts} +0 -0
@@ -3575,6 +3575,10 @@ DateHeader.defaultProps = {
3575
3575
  };
3576
3576
  var DateHeader$1 = DateHeader;
3577
3577
 
3578
+ function getFocusableTime(props) {
3579
+ 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));
3580
+ }
3581
+
3578
3582
  // NB! Using with UTC timestamp (YYYY-MM-DD) might lead to unexpected results, for example
3579
3583
  // getStartOfDay(new Date('1995-01-01')) in Los Angeles returns 31 Dec 1994, but in
3580
3584
  // in Singapore it is 1 Jan 1995.
@@ -3586,61 +3590,56 @@ function getStartOfDay(date) {
3586
3590
  return new Date(date.getFullYear(), date.getMonth(), date.getDate());
3587
3591
  }
3588
3592
 
3589
- class TableLink extends PureComponent {
3590
- onClick = event => {
3593
+ const TableLink = ({
3594
+ item,
3595
+ type,
3596
+ title,
3597
+ longTitle,
3598
+ active,
3599
+ disabled,
3600
+ today,
3601
+ autofocus,
3602
+ onClick
3603
+ }) => {
3604
+ const buttonRef = useRef(null);
3605
+ const intl = useIntl();
3606
+ useEffect(() => {
3607
+ if (autofocus) {
3608
+ setTimeout(() => {
3609
+ buttonRef.current?.focus();
3610
+ }, 0);
3611
+ }
3612
+ }, [autofocus]);
3613
+ const onCalendarClick = event => {
3591
3614
  event.preventDefault();
3592
- if (!this.props.disabled) {
3593
- this.props.onClick(this.props.item);
3615
+ if (!disabled) {
3616
+ onClick(item);
3594
3617
  }
3595
3618
  };
3596
- calculateAriaLabel = (longTitle, title, active, type, formatMessage) => {
3619
+ const calculateAriaLabel = () => {
3597
3620
  if (active) {
3598
- return `${longTitle || title}, ${formatMessage(messages$6.selected)} ${formatMessage(messages$6[type])}`;
3621
+ return `${longTitle || title || ''}, ${intl.formatMessage(messages$6.selected)} ${intl.formatMessage(messages$6[type])}`;
3599
3622
  }
3600
3623
  return longTitle || title;
3601
3624
  };
3602
- render() {
3603
- const {
3604
- item,
3605
- type,
3606
- title,
3607
- longTitle,
3608
- active,
3609
- disabled,
3610
- today,
3611
- intl: {
3612
- formatMessage
3613
- }
3614
- } = this.props;
3615
- return /*#__PURE__*/jsx(Fragment, {
3616
- children: /*#__PURE__*/jsx("button", {
3617
- type: "button",
3618
- className: `tw-date-lookup-${type}-option ${active ? 'active' : ''} ${today ? 'today' : ''} np-text-body-default-bold`,
3619
- disabled: disabled,
3620
- "aria-label": this.calculateAriaLabel(longTitle, title, active, type, formatMessage),
3621
- "aria-pressed": active,
3622
- onClick: this.onClick,
3623
- children: title || item
3624
- })
3625
- });
3626
- }
3627
- }
3628
- TableLink.propTypes = {
3629
- item: PropTypes.number.isRequired,
3630
- // day (1-31), month (0-11) or year (2018 etc)
3631
- type: PropTypes.oneOf(['day', 'month', 'year']).isRequired,
3632
- title: PropTypes.string,
3633
- longTitle: PropTypes.string,
3634
- active: PropTypes.bool.isRequired,
3635
- disabled: PropTypes.bool.isRequired,
3636
- today: PropTypes.bool.isRequired,
3637
- onClick: PropTypes.func.isRequired
3638
- };
3639
- TableLink.defaultProps = {
3640
- title: null,
3641
- longTitle: null
3625
+ return /*#__PURE__*/jsx(Fragment, {
3626
+ children: /*#__PURE__*/jsx("button", {
3627
+ ref: buttonRef,
3628
+ type: "button",
3629
+ className: classNames(`tw-date-lookup-${type}-option np-text-body-default-bold`, {
3630
+ active: !!active
3631
+ }, {
3632
+ today: !!today
3633
+ }),
3634
+ disabled: disabled,
3635
+ tabIndex: autofocus ? 0 : -1,
3636
+ "aria-label": calculateAriaLabel(),
3637
+ "aria-pressed": active,
3638
+ onClick: onCalendarClick,
3639
+ children: title || item
3640
+ })
3641
+ });
3642
3642
  };
3643
- var TableLink$1 = injectIntl(TableLink);
3644
3643
 
3645
3644
  const SHORT_DAY_FORMAT = {
3646
3645
  day: 'numeric'
@@ -3711,6 +3710,22 @@ class DayCalendarTable extends PureComponent {
3711
3710
  } = this.props;
3712
3711
  return !!(selectedDate && +new Date(viewYear, viewMonth, day) === +selectedDate);
3713
3712
  };
3713
+ isToday = day => {
3714
+ const {
3715
+ viewMonth,
3716
+ viewYear
3717
+ } = this.props;
3718
+ return Number(getStartOfDay(new Date())) === Number(new Date(viewYear, viewMonth, day));
3719
+ };
3720
+ getAutofocusDay = weeks => {
3721
+ const days = weeks.flatMap(week => week);
3722
+ return getFocusableTime({
3723
+ isActive: this.isActive,
3724
+ isNow: this.isToday,
3725
+ isDisabled: this.isDisabled,
3726
+ timeSpan: days
3727
+ });
3728
+ };
3714
3729
  render() {
3715
3730
  const {
3716
3731
  viewMonth,
@@ -3720,12 +3735,13 @@ class DayCalendarTable extends PureComponent {
3720
3735
  }
3721
3736
  } = this.props;
3722
3737
  const weeks = this.getTableStructure();
3738
+ let autoFocusDay = this.getAutofocusDay(weeks, viewMonth, viewYear);
3723
3739
  return /*#__PURE__*/jsxs("table", {
3724
3740
  className: "table table-condensed table-bordered tw-date-lookup-calendar m-b-0",
3725
3741
  children: [/*#__PURE__*/jsx("thead", {
3726
3742
  children: /*#__PURE__*/jsx("tr", {
3727
3743
  children: this.days.map((day, index) => /*#__PURE__*/jsxs("th", {
3728
- className: "text-xs-center np-text-body-default-bold",
3744
+ className: index > 4 ? 'text-xs-center np-text-body-default' : 'text-xs-center np-text-body-default-bold',
3729
3745
  children: [/*#__PURE__*/jsx("span", {
3730
3746
  className: "hidden-xs",
3731
3747
  children: /*#__PURE__*/jsx("abbr", {
@@ -3744,15 +3760,16 @@ class DayCalendarTable extends PureComponent {
3744
3760
  }), /*#__PURE__*/jsx("tbody", {
3745
3761
  children: weeks.map((week, weekIndex) => /*#__PURE__*/jsx("tr", {
3746
3762
  children: week.map((day, dayIndex) => /*#__PURE__*/jsx("td", {
3747
- className: dayIndex > 4 ? 'default' : '',
3748
- children: day && /*#__PURE__*/jsx(TableLink$1, {
3763
+ className: dayIndex > 4 ? 'weekend' : '',
3764
+ children: day && /*#__PURE__*/jsx(TableLink, {
3749
3765
  item: day,
3750
3766
  type: "day",
3751
3767
  title: formatDate(new Date(viewYear, viewMonth, day), locale, SHORT_DAY_FORMAT),
3768
+ autofocus: day === autoFocusDay,
3752
3769
  longTitle: formatDate(new Date(viewYear, viewMonth, day), locale),
3753
3770
  active: this.isActive(day),
3754
3771
  disabled: this.isDisabled(day),
3755
- today: +getStartOfDay(new Date()) === +new Date(viewYear, viewMonth, day),
3772
+ today: this.isToday(day),
3756
3773
  onClick: this.selectDay
3757
3774
  })
3758
3775
  }, dayIndex))
@@ -3853,11 +3870,11 @@ var DayCalendar$1 = injectIntl(DayCalendar);
3853
3870
 
3854
3871
  const ROWS$1 = 3;
3855
3872
  const COLS$1 = 4;
3856
- const MONTH_ONLY_FORMAY = {
3873
+ const MONTH_ONLY_FORMAT = {
3857
3874
  month: 'short'
3858
3875
  };
3859
3876
  const MonthCalendarTable = ({
3860
- selectedDate: selected,
3877
+ selectedDate,
3861
3878
  min,
3862
3879
  max,
3863
3880
  viewYear,
@@ -3867,19 +3884,37 @@ const MonthCalendarTable = ({
3867
3884
  const {
3868
3885
  locale
3869
3886
  } = useIntl();
3870
- const getLink = month => /*#__PURE__*/jsx(TableLink$1, {
3871
- item: month,
3872
- type: "month",
3873
- title: formatDate(new Date(viewYear, month), locale, MONTH_ONLY_FORMAY),
3874
- active: !!(selected && month === selected.getMonth() && viewYear === selected.getFullYear()),
3875
- disabled: isDisabled(month),
3876
- today: viewYear === new Date().getFullYear() && month === new Date().getMonth(),
3877
- onClick: onSelect
3878
- });
3887
+ const getLink = month => {
3888
+ return /*#__PURE__*/jsx(TableLink, {
3889
+ item: month,
3890
+ type: "month",
3891
+ title: formatDate(new Date(viewYear, month), locale, MONTH_ONLY_FORMAT),
3892
+ active: isActive(month),
3893
+ disabled: isDisabled(month),
3894
+ today: viewYear === new Date().getFullYear() && month === new Date().getMonth(),
3895
+ autofocus: autofocusMonth === month,
3896
+ onClick: onSelect
3897
+ });
3898
+ };
3899
+ const isActive = month => {
3900
+ return selectedDate && month === selectedDate.getMonth() && viewYear === selectedDate.getFullYear();
3901
+ };
3902
+ const isThisMonth = month => {
3903
+ return viewYear === new Date().getFullYear() && month === new Date().getMonth();
3904
+ };
3879
3905
  const isDisabled = month => {
3880
3906
  const date = new Date(viewYear, month);
3881
3907
  return !!(min && date < new Date(min.getFullYear(), min.getMonth()) || max && date > new Date(max.getFullYear(), max.getMonth()));
3882
3908
  };
3909
+ const autofocusMonth = (() => {
3910
+ const months = [...new Array(ROWS$1 * COLS$1)].map((_, index) => index);
3911
+ return getFocusableTime({
3912
+ isActive,
3913
+ isNow: isThisMonth,
3914
+ isDisabled,
3915
+ timeSpan: months
3916
+ });
3917
+ })();
3883
3918
  return /*#__PURE__*/jsxs("table", {
3884
3919
  className: "table table-condensed table-bordered tw-date-lookup-calendar np-text-body-default-bold m-b-0",
3885
3920
  children: [/*#__PURE__*/jsx("thead", {
@@ -3998,15 +4033,36 @@ const YearCalendarTable = ({
3998
4033
  locale
3999
4034
  } = useIntl();
4000
4035
  const startYear = viewYear - viewYear % 20;
4001
- const getLink = year => /*#__PURE__*/jsx(TableLink$1, {
4002
- item: year,
4003
- type: "year",
4004
- title: formatDate(new Date(year, 0), locale, YEAR_ONLY_FORMAT),
4005
- active: !!(selectedDate && year === selectedDate.getFullYear()),
4006
- disabled: !!(min && year < min.getFullYear() || max && year > max.getFullYear()),
4007
- today: year === new Date().getFullYear(),
4008
- onClick: onSelect
4009
- });
4036
+ const getLink = year => {
4037
+ return /*#__PURE__*/jsx(TableLink, {
4038
+ item: year,
4039
+ type: "year",
4040
+ title: formatDate(new Date(year, 0), locale, YEAR_ONLY_FORMAT),
4041
+ active: isActive(year),
4042
+ disabled: isDisabled(year),
4043
+ today: isThisYear(year),
4044
+ autofocus: autofocusYear === year,
4045
+ onClick: onSelect
4046
+ });
4047
+ };
4048
+ const isActive = year => {
4049
+ return !!(selectedDate && year === selectedDate.getFullYear());
4050
+ };
4051
+ const isThisYear = year => {
4052
+ return year === new Date().getFullYear();
4053
+ };
4054
+ const isDisabled = year => {
4055
+ return !!(min && year < min.getFullYear() || max && year > max.getFullYear());
4056
+ };
4057
+ const autofocusYear = (() => {
4058
+ const years = [...new Array(ROWS * COLS)].map((_, index) => startYear + index);
4059
+ return getFocusableTime({
4060
+ isActive,
4061
+ isNow: isThisYear,
4062
+ isDisabled,
4063
+ timeSpan: years
4064
+ });
4065
+ })();
4010
4066
  return /*#__PURE__*/jsxs("table", {
4011
4067
  className: "table table-condensed table-bordered tw-date-lookup-calendar m-b-0",
4012
4068
  children: [/*#__PURE__*/jsx("thead", {
@@ -4113,6 +4169,7 @@ class DateLookup extends PureComponent {
4113
4169
  super(props);
4114
4170
  this.state = {
4115
4171
  selectedDate: getStartOfDay(props.value),
4172
+ originalDate: null,
4116
4173
  min: getStartOfDay(props.min),
4117
4174
  max: getStartOfDay(props.max),
4118
4175
  viewMonth: (props.value || new Date()).getMonth(),
@@ -4175,12 +4232,22 @@ class DateLookup extends PureComponent {
4175
4232
  onFocus();
4176
4233
  }
4177
4234
  };
4235
+ discard = () => {
4236
+ const {
4237
+ originalDate
4238
+ } = this.state;
4239
+ if (originalDate !== null) {
4240
+ this.props.onChange(originalDate);
4241
+ }
4242
+ this.close();
4243
+ };
4178
4244
  close = () => {
4179
4245
  const {
4180
4246
  onBlur
4181
4247
  } = this.props;
4182
4248
  this.setState({
4183
- open: false
4249
+ open: false,
4250
+ originalDate: null
4184
4251
  });
4185
4252
  if (onBlur) {
4186
4253
  onBlur();
@@ -4188,7 +4255,8 @@ class DateLookup extends PureComponent {
4188
4255
  };
4189
4256
  handleKeyDown = event => {
4190
4257
  const {
4191
- open
4258
+ open,
4259
+ originalDate
4192
4260
  } = this.state;
4193
4261
  switch (event.keyCode) {
4194
4262
  case KeyCodes.LEFT:
@@ -4224,6 +4292,9 @@ class DateLookup extends PureComponent {
4224
4292
  event.preventDefault();
4225
4293
  break;
4226
4294
  case KeyCodes.ESCAPE:
4295
+ if (originalDate !== null) {
4296
+ this.props.onChange(originalDate);
4297
+ }
4227
4298
  this.close();
4228
4299
  event.preventDefault();
4229
4300
  break;
@@ -4234,8 +4305,14 @@ class DateLookup extends PureComponent {
4234
4305
  selectedDate,
4235
4306
  min,
4236
4307
  max,
4237
- mode
4308
+ mode,
4309
+ originalDate
4238
4310
  } = this.state;
4311
+ if (originalDate === null) {
4312
+ this.setState({
4313
+ originalDate: selectedDate
4314
+ });
4315
+ }
4239
4316
  let date;
4240
4317
  if (selectedDate) {
4241
4318
  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());
@@ -4368,7 +4445,7 @@ class DateLookup extends PureComponent {
4368
4445
  open: open,
4369
4446
  className: "tw-date-lookup-menu",
4370
4447
  position: Position.BOTTOM,
4371
- onClose: this.close,
4448
+ onClose: this.discard,
4372
4449
  children: this.getCalendar()
4373
4450
  })]
4374
4451
  });