@transferwise/components 0.0.0-experimental-e9526a8 → 0.0.0-experimental-9a61b0a

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 (61) hide show
  1. package/build/i18n/en.json +8 -0
  2. package/build/index.esm.js +388 -241
  3. package/build/index.esm.js.map +1 -1
  4. package/build/index.js +387 -240
  5. package/build/index.js.map +1 -1
  6. package/build/main.css +1 -1
  7. package/build/styles/dateLookup/DateLookup.css +1 -1
  8. package/build/styles/main.css +1 -1
  9. package/build/types/common/focusBoundary/FocusBoundary.d.ts +2 -2
  10. package/build/types/common/focusBoundary/FocusBoundary.d.ts.map +1 -1
  11. package/build/types/common/focusBoundary/utils/getFocusableElements.d.ts +2 -0
  12. package/build/types/common/focusBoundary/utils/getFocusableElements.d.ts.map +1 -0
  13. package/build/types/common/focusBoundary/utils/index.d.ts +3 -0
  14. package/build/types/common/focusBoundary/utils/index.d.ts.map +1 -0
  15. package/build/types/common/focusBoundary/utils/resetFocus.d.ts +2 -0
  16. package/build/types/common/focusBoundary/utils/resetFocus.d.ts.map +1 -0
  17. package/build/types/dateLookup/DateLookup.messages.d.ts +65 -0
  18. package/build/types/dateLookup/DateLookup.messages.d.ts.map +1 -0
  19. package/build/types/dateLookup/dateHeader/DateHeader.d.ts +3 -1
  20. package/build/types/dateLookup/dateHeader/DateHeader.d.ts.map +1 -1
  21. package/build/types/dateLookup/tableLink/TableLink.d.ts +4 -26
  22. package/build/types/dateLookup/tableLink/TableLink.d.ts.map +1 -1
  23. package/build/types/dateLookup/yearCalendar/YearCalendar.d.ts +4 -29
  24. package/build/types/dateLookup/yearCalendar/YearCalendar.d.ts.map +1 -1
  25. package/build/types/upload/steps/completeStep/completeStep.d.ts.map +1 -1
  26. package/build/types/upload/steps/processingStep/processingStep.d.ts.map +1 -1
  27. package/package.json +1 -2
  28. package/src/common/bottomSheet/__snapshots__/BottomSheet.spec.tsx.snap +1 -8
  29. package/src/common/focusBoundary/FocusBoundary.spec.tsx +66 -0
  30. package/src/common/focusBoundary/FocusBoundary.tsx +36 -6
  31. package/src/common/focusBoundary/__snapshots__/FocusBoundary.spec.tsx.snap +16 -0
  32. package/src/common/focusBoundary/utils/getFocusableElements.js +25 -0
  33. package/src/common/focusBoundary/utils/getFocusableElements.spec.js +51 -0
  34. package/src/common/focusBoundary/utils/index.js +2 -0
  35. package/src/common/focusBoundary/utils/resetFocus.js +23 -0
  36. package/src/common/focusBoundary/utils/resetFocus.spec.js +103 -0
  37. package/src/dateLookup/DateLookup.css +1 -1
  38. package/src/dateLookup/DateLookup.keyboardEvents.spec.js +3 -3
  39. package/src/dateLookup/DateLookup.less +4 -0
  40. package/src/dateLookup/DateLookup.messages.js +44 -0
  41. package/src/dateLookup/DateLookup.testingLibrary.spec.js +39 -0
  42. package/src/dateLookup/dateHeader/DateHeader.js +48 -26
  43. package/src/dateLookup/dateHeader/DateHeader.spec.js +37 -0
  44. package/src/dateLookup/dayCalendar/DayCalendar.js +3 -1
  45. package/src/dateLookup/dayCalendar/DayCalendar.spec.js +7 -1
  46. package/src/dateLookup/dayCalendar/table/DayCalendarTable.js +7 -3
  47. package/src/dateLookup/dayCalendar/table/DayCalendarTable.spec.js +1 -0
  48. package/src/dateLookup/monthCalendar/MonthCalendar.js +3 -1
  49. package/src/dateLookup/monthCalendar/MonthCalendar.spec.js +7 -1
  50. package/src/dateLookup/monthCalendar/table/MonthCalendarTable.spec.js +4 -5
  51. package/src/dateLookup/tableLink/TableLink.js +24 -3
  52. package/src/dateLookup/tableLink/TableLink.spec.js +60 -4
  53. package/src/dateLookup/yearCalendar/YearCalendar.js +16 -3
  54. package/src/dateLookup/yearCalendar/YearCalendar.spec.js +14 -1
  55. package/src/dateLookup/yearCalendar/table/YearCalendarTable.spec.js +4 -5
  56. package/src/i18n/en.json +8 -0
  57. package/src/main.css +1 -1
  58. package/src/upload/Upload.js +1 -1
  59. package/src/upload/steps/completeStep/completeStep.js +4 -1
  60. package/src/upload/steps/processingStep/processingStep.js +1 -0
  61. package/src/uploadInput/uploadItem/UploadItem.tsx +1 -1
@@ -1,7 +1,7 @@
1
1
  import classNames from 'classnames';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import * as React from 'react';
4
- import React__default, { forwardRef, cloneElement, useState, useRef, useMemo, useEffect, useCallback, useLayoutEffect, createContext, useContext, PureComponent, createRef, Component, Children, Fragment as Fragment$1 } from 'react';
4
+ import React__default, { forwardRef, cloneElement, useState, useRef, useMemo, useEffect, useLayoutEffect, createContext, useContext, useCallback, PureComponent, createRef, Component, Children, Fragment as Fragment$1 } from 'react';
5
5
  import { ChevronUp, CrossCircleFill, Cross, NavigateAway, Check, Info as Info$1, Alert as Alert$2, ClockBorderless, CheckCircle, InfoCircle, Warning, CrossCircle, Clock, Briefcase, Person, ArrowLeft, QuestionMarkCircle, AlertCircle, Search, ChevronDown, CheckCircleFill, ArrowRight, Download, ClockFill, Upload as Upload$2, Document, Plus, PlusCircle, AlertCircleFill } from '@transferwise/icons';
6
6
  import PropTypes from 'prop-types';
7
7
  import { defineMessages, useIntl, injectIntl, IntlProvider } from 'react-intl';
@@ -10,9 +10,8 @@ import { formatDate, formatNumber, formatMoney, formatAmount } from '@transferwi
10
10
  import throttle from 'lodash.throttle';
11
11
  import { CSSTransition } from 'react-transition-group';
12
12
  import { createPortal } from 'react-dom';
13
- import { FocusScope } from '@react-aria/focus';
14
- import mergeRefs from 'react-merge-refs';
15
13
  import { isUndefined, isKey, isNumber, isEmpty, isNull, isArray } from '@transferwise/neptune-validation';
14
+ import mergeRefs from 'react-merge-refs';
16
15
  import { usePopper } from 'react-popper';
17
16
  import { Transition, Listbox } from '@headlessui/react';
18
17
  import { useId } from '@radix-ui/react-id';
@@ -763,7 +762,7 @@ const ActionOption = ({
763
762
  });
764
763
  };
765
764
 
766
- var messages$8 = defineMessages({
765
+ var messages$9 = defineMessages({
767
766
  ariaLabel: {
768
767
  id: "neptune.CloseButton.ariaLabel"
769
768
  }
@@ -779,7 +778,7 @@ const CloseButton = /*#__PURE__*/forwardRef(function CloseButton({
779
778
  testId
780
779
  }, reference) {
781
780
  const intl = useIntl();
782
- ariaLabel ??= intl.formatMessage(messages$8.ariaLabel);
781
+ ariaLabel ??= intl.formatMessage(messages$9.ariaLabel);
783
782
  const Icon = filled ? CrossCircleFill : Cross;
784
783
  return /*#__PURE__*/jsx("button", {
785
784
  ref: reference,
@@ -799,7 +798,7 @@ const CloseButton = /*#__PURE__*/forwardRef(function CloseButton({
799
798
  });
800
799
  });
801
800
 
802
- var messages$7 = defineMessages({
801
+ var messages$8 = defineMessages({
803
802
  opensInNewTab: {
804
803
  id: "neptune.Link.opensInNewTab"
805
804
  }
@@ -828,7 +827,7 @@ const Link = ({
828
827
  onClick: onClick,
829
828
  ...props,
830
829
  children: [children, " ", isBlank && /*#__PURE__*/jsx(NavigateAway, {
831
- title: formatMessage(messages$7.opensInNewTab)
830
+ title: formatMessage(messages$8.opensInNewTab)
832
831
  })]
833
832
  });
834
833
  };
@@ -1458,22 +1457,269 @@ function getInitials(name) {
1458
1457
  return allInitials[0] + allInitials.slice(-1);
1459
1458
  }
1460
1459
 
1460
+ const THROTTLE_MS = 100;
1461
+ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
1462
+ const useClientWidth = ({
1463
+ ref,
1464
+ throttleMs = THROTTLE_MS
1465
+ }) => {
1466
+ const [clientWidth, setClientWidth] = useState(null);
1467
+ useIsomorphicLayoutEffect(() => {
1468
+ // eslint-disable-next-line unicorn/consistent-function-scoping
1469
+ const updateClientWidth = () => {
1470
+ if (ref) {
1471
+ // when `ref` is a window
1472
+ if ('innerWidth' in ref) {
1473
+ setClientWidth(ref.innerWidth);
1474
+ }
1475
+ // when `ref` is an element
1476
+ else if (ref.current) {
1477
+ setClientWidth(ref.current.clientWidth);
1478
+ }
1479
+ }
1480
+ };
1481
+ // This assignment saves a reference to the function so it will be the same passed to both addEventListener removeEventListener.
1482
+ // If throttle gets passed directly to both add and removeEventListenet the results will be that the event
1483
+ // won't get removed even if the component is unmounted.
1484
+ const attachedFunction = throttle(updateClientWidth, throttleMs);
1485
+ window.addEventListener('resize', attachedFunction, true);
1486
+ // using requestAnimationFrame to perform the calculation before the next repaint
1487
+ // getting width earlier causes issues in animations when used with react-transition-group
1488
+ window.requestAnimationFrame(updateClientWidth);
1489
+ return () => window.removeEventListener('resize', attachedFunction, true);
1490
+ }, []);
1491
+ return [clientWidth];
1492
+ };
1493
+ useClientWidth.THROTTLE_MS = THROTTLE_MS;
1494
+
1495
+ const useConditionalListener = ({
1496
+ attachListener,
1497
+ callback,
1498
+ eventType,
1499
+ parent
1500
+ }) => {
1501
+ useEffect(() => {
1502
+ if (attachListener && !isUndefined(parent)) {
1503
+ parent.addEventListener(eventType, callback, true);
1504
+ }
1505
+ return () => {
1506
+ if (!isUndefined(parent)) {
1507
+ parent.removeEventListener(eventType, callback, true);
1508
+ }
1509
+ };
1510
+ }, [attachListener, callback, eventType, parent]);
1511
+ };
1512
+
1513
+ const DirectionContext = /*#__PURE__*/createContext(Direction.LTR);
1514
+ const DirectionProvider = ({
1515
+ direction,
1516
+ children
1517
+ }) => {
1518
+ return /*#__PURE__*/jsx(DirectionContext.Provider, {
1519
+ value: direction,
1520
+ children: children
1521
+ });
1522
+ };
1523
+
1524
+ const useDirection = () => {
1525
+ const direction = useContext(DirectionContext);
1526
+ return {
1527
+ direction,
1528
+ isRTL: direction === 'rtl'
1529
+ };
1530
+ };
1531
+
1532
+ const ObserverParams = {
1533
+ threshold: 0.1
1534
+ };
1535
+
1536
+ /**
1537
+ * useHasIntersected.
1538
+ * Use this custom hook to detect when an element has became visible inside the viewport. This hook checks only if the intersection happend.
1539
+ * Once the intersection has happened the hook will not return false even if the element gets out of the viewport.
1540
+ *
1541
+ * @param elRef.elRef
1542
+ * @param {object} [elRef] - node object that contains a react reference to the element that needs to be observed.
1543
+ * @param {strimng} [loading = 'eager'] - string that contains the type of loading.
1544
+ * @param elRef.loading
1545
+ * @usage `const [hasIntersected] = useHasIntersected({imageRef,loading});`
1546
+ */
1547
+ const useHasIntersected = ({
1548
+ elRef,
1549
+ loading
1550
+ }) => {
1551
+ const [hasIntersected, setHasIntersected] = useState(false);
1552
+ const {
1553
+ current
1554
+ } = elRef || {};
1555
+ const isValidReference = () => {
1556
+ return elRef && current;
1557
+ };
1558
+ const handleOnIntersect = (entries, observer) => {
1559
+ entries.forEach(entry => {
1560
+ if (entry.isIntersecting) {
1561
+ setHasIntersected(true);
1562
+ observer.unobserve(current);
1563
+ }
1564
+ });
1565
+ };
1566
+ useEffect(() => {
1567
+ let observer;
1568
+ let didCancel = false;
1569
+
1570
+ // Check if window is define for SSR and Old browsers fallback
1571
+ if (typeof window === 'undefined' || !window.IntersectionObserver || !isValidReference()) {
1572
+ setHasIntersected(true);
1573
+ } else if (!didCancel) {
1574
+ observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
1575
+ observer.observe(current);
1576
+ }
1577
+ return () => {
1578
+ didCancel = true;
1579
+ if (observer) {
1580
+ observer.unobserve(current);
1581
+ }
1582
+ };
1583
+ }, [elRef]);
1584
+ if (loading === 'eager') {
1585
+ return [false];
1586
+ }
1587
+ return [hasIntersected];
1588
+ };
1589
+
1590
+ const useLayout = () => {
1591
+ const windowReference = typeof window === 'undefined' ? undefined : window;
1592
+ const [breakpoint, setBreakpoint] = useState();
1593
+ const [clientWidth] = useClientWidth({
1594
+ ref: windowReference
1595
+ });
1596
+ useEffect(() => {
1597
+ if (!clientWidth) {
1598
+ return;
1599
+ }
1600
+ if (clientWidth <= Breakpoint.EXTRA_SMALL) {
1601
+ setBreakpoint(Breakpoint.EXTRA_SMALL);
1602
+ return;
1603
+ }
1604
+ if (Breakpoint.EXTRA_SMALL < clientWidth && clientWidth <= Breakpoint.SMALL) {
1605
+ setBreakpoint(Breakpoint.SMALL);
1606
+ return;
1607
+ }
1608
+ if (Breakpoint.SMALL < clientWidth && clientWidth <= Breakpoint.MEDIUM) {
1609
+ setBreakpoint(Breakpoint.MEDIUM);
1610
+ return;
1611
+ }
1612
+ if (Breakpoint.MEDIUM < clientWidth && clientWidth <= Breakpoint.LARGE) {
1613
+ setBreakpoint(Breakpoint.LARGE);
1614
+ return;
1615
+ }
1616
+ if (Breakpoint.LARGE < clientWidth) {
1617
+ setBreakpoint(Breakpoint.EXTRA_LARGE);
1618
+ }
1619
+ }, [clientWidth]);
1620
+ return {
1621
+ isMobile: !!breakpoint && [Breakpoint.EXTRA_SMALL, Breakpoint.SMALL].includes(breakpoint),
1622
+ isExtraSmall: breakpoint === Breakpoint.EXTRA_SMALL,
1623
+ isSmall: breakpoint === Breakpoint.SMALL,
1624
+ isMedium: breakpoint === Breakpoint.MEDIUM,
1625
+ isLarge: breakpoint === Breakpoint.LARGE,
1626
+ isExtraLarge: breakpoint === Breakpoint.EXTRA_LARGE
1627
+ };
1628
+ };
1629
+
1630
+ /**
1631
+ * This function returns the first and the last focusable elements within a node.
1632
+ *
1633
+ * @param {Node} focusBoundaryContainer - the area that contains focused elements.
1634
+ * @returns {object} focusableEls - which contains the first focusable element and the last focusable element. First and last can be the same element if area contains one or none focusable element.
1635
+ */
1636
+
1637
+ const getFocusableElements = focusBoundaryContainer => {
1638
+ const focusableEls = {
1639
+ first: focusBoundaryContainer,
1640
+ last: focusBoundaryContainer
1641
+ };
1642
+ if (focusBoundaryContainer?.querySelectorAll) {
1643
+ const allEls = [...focusBoundaryContainer.querySelectorAll('a, button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])')].filter(element => !element.hasAttribute('disabled'));
1644
+ if (allEls.length > 0) {
1645
+ [focusableEls.first] = allEls;
1646
+ focusableEls.last = allEls[allEls.length - 1];
1647
+ }
1648
+ }
1649
+ return focusableEls;
1650
+ };
1651
+
1652
+ /**
1653
+ * This function resets the focus to either last of first focusable elements within a node.
1654
+ *
1655
+ * @param {object} focusableEls - contains the first last of first focusable elements within a node.
1656
+ * @param {object} event - the triggered event
1657
+ */
1658
+
1659
+ const resetFocus = ({
1660
+ focusableEls: {
1661
+ first,
1662
+ last
1663
+ },
1664
+ event
1665
+ }) => {
1666
+ const {
1667
+ activeElement
1668
+ } = document;
1669
+ if (event.shiftKey && activeElement === first) {
1670
+ if (last) {
1671
+ last.focus();
1672
+ }
1673
+ event.preventDefault();
1674
+ }
1675
+ if (!event.shiftKey && activeElement === last) {
1676
+ if (first) {
1677
+ first.focus();
1678
+ }
1679
+ event.preventDefault();
1680
+ }
1681
+ };
1682
+
1683
+ const {
1684
+ TAB
1685
+ } = Key;
1461
1686
  const FocusBoundary = ({
1462
1687
  children
1463
1688
  }) => {
1464
- return (
1465
- /*#__PURE__*/
1466
- // eslint-disable-next-line jsx-a11y/no-autofocus
1467
- jsx(FocusScope, {
1468
- contain: true,
1469
- restoreFocus: true,
1470
- autoFocus: true,
1471
- children: /*#__PURE__*/jsx("div", {
1472
- tabIndex: -1,
1473
- children: children
1474
- })
1475
- })
1476
- );
1689
+ const boundaryReference = useRef(null);
1690
+ const parent = isUndefined(document) ? undefined : document;
1691
+ const [focusableEls, setFocusableEls] = useState({});
1692
+ useEffect(() => {
1693
+ if (boundaryReference?.current) {
1694
+ boundaryReference.current.focus({
1695
+ preventScroll: true
1696
+ });
1697
+ setFocusableEls(getFocusableElements(boundaryReference.current));
1698
+ }
1699
+ }, []);
1700
+ // If event type is Tab the resetFocus will force the focus to either the first focusable or last in boundaryRef .
1701
+ useConditionalListener({
1702
+ eventType: 'keydown',
1703
+ callback: event => {
1704
+ if (isKey({
1705
+ keyType: TAB,
1706
+ event
1707
+ })) {
1708
+ resetFocus({
1709
+ event,
1710
+ focusableEls
1711
+ });
1712
+ }
1713
+ },
1714
+ attachListener: true,
1715
+ parent
1716
+ });
1717
+ return /*#__PURE__*/jsx("div", {
1718
+ ref: boundaryReference,
1719
+ tabIndex: -1,
1720
+ className: "np-focus-boundary outline-none",
1721
+ children: children
1722
+ });
1477
1723
  };
1478
1724
  var FocusBoundary$1 = FocusBoundary;
1479
1725
 
@@ -1728,176 +1974,6 @@ SlidingPanel.defaultProps = {
1728
1974
  };
1729
1975
  var SlidingPanel$1 = SlidingPanel;
1730
1976
 
1731
- const THROTTLE_MS = 100;
1732
- const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
1733
- const useClientWidth = ({
1734
- ref,
1735
- throttleMs = THROTTLE_MS
1736
- }) => {
1737
- const [clientWidth, setClientWidth] = useState(null);
1738
- useIsomorphicLayoutEffect(() => {
1739
- // eslint-disable-next-line unicorn/consistent-function-scoping
1740
- const updateClientWidth = () => {
1741
- if (ref) {
1742
- // when `ref` is a window
1743
- if ('innerWidth' in ref) {
1744
- setClientWidth(ref.innerWidth);
1745
- }
1746
- // when `ref` is an element
1747
- else if (ref.current) {
1748
- setClientWidth(ref.current.clientWidth);
1749
- }
1750
- }
1751
- };
1752
- // This assignment saves a reference to the function so it will be the same passed to both addEventListener removeEventListener.
1753
- // If throttle gets passed directly to both add and removeEventListenet the results will be that the event
1754
- // won't get removed even if the component is unmounted.
1755
- const attachedFunction = throttle(updateClientWidth, throttleMs);
1756
- window.addEventListener('resize', attachedFunction, true);
1757
- // using requestAnimationFrame to perform the calculation before the next repaint
1758
- // getting width earlier causes issues in animations when used with react-transition-group
1759
- window.requestAnimationFrame(updateClientWidth);
1760
- return () => window.removeEventListener('resize', attachedFunction, true);
1761
- }, []);
1762
- return [clientWidth];
1763
- };
1764
- useClientWidth.THROTTLE_MS = THROTTLE_MS;
1765
-
1766
- const useConditionalListener = ({
1767
- attachListener,
1768
- callback,
1769
- eventType,
1770
- parent
1771
- }) => {
1772
- useEffect(() => {
1773
- if (attachListener && !isUndefined(parent)) {
1774
- parent.addEventListener(eventType, callback, true);
1775
- }
1776
- return () => {
1777
- if (!isUndefined(parent)) {
1778
- parent.removeEventListener(eventType, callback, true);
1779
- }
1780
- };
1781
- }, [attachListener, callback, eventType, parent]);
1782
- };
1783
-
1784
- const DirectionContext = /*#__PURE__*/createContext(Direction.LTR);
1785
- const DirectionProvider = ({
1786
- direction,
1787
- children
1788
- }) => {
1789
- return /*#__PURE__*/jsx(DirectionContext.Provider, {
1790
- value: direction,
1791
- children: children
1792
- });
1793
- };
1794
-
1795
- const useDirection = () => {
1796
- const direction = useContext(DirectionContext);
1797
- return {
1798
- direction,
1799
- isRTL: direction === 'rtl'
1800
- };
1801
- };
1802
-
1803
- const ObserverParams = {
1804
- threshold: 0.1
1805
- };
1806
-
1807
- /**
1808
- * useHasIntersected.
1809
- * Use this custom hook to detect when an element has became visible inside the viewport. This hook checks only if the intersection happend.
1810
- * Once the intersection has happened the hook will not return false even if the element gets out of the viewport.
1811
- *
1812
- * @param elRef.elRef
1813
- * @param {object} [elRef] - node object that contains a react reference to the element that needs to be observed.
1814
- * @param {strimng} [loading = 'eager'] - string that contains the type of loading.
1815
- * @param elRef.loading
1816
- * @usage `const [hasIntersected] = useHasIntersected({imageRef,loading});`
1817
- */
1818
- const useHasIntersected = ({
1819
- elRef,
1820
- loading
1821
- }) => {
1822
- const [hasIntersected, setHasIntersected] = useState(false);
1823
- const {
1824
- current
1825
- } = elRef || {};
1826
- const isValidReference = () => {
1827
- return elRef && current;
1828
- };
1829
- const handleOnIntersect = (entries, observer) => {
1830
- entries.forEach(entry => {
1831
- if (entry.isIntersecting) {
1832
- setHasIntersected(true);
1833
- observer.unobserve(current);
1834
- }
1835
- });
1836
- };
1837
- useEffect(() => {
1838
- let observer;
1839
- let didCancel = false;
1840
-
1841
- // Check if window is define for SSR and Old browsers fallback
1842
- if (typeof window === 'undefined' || !window.IntersectionObserver || !isValidReference()) {
1843
- setHasIntersected(true);
1844
- } else if (!didCancel) {
1845
- observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
1846
- observer.observe(current);
1847
- }
1848
- return () => {
1849
- didCancel = true;
1850
- if (observer) {
1851
- observer.unobserve(current);
1852
- }
1853
- };
1854
- }, [elRef]);
1855
- if (loading === 'eager') {
1856
- return [false];
1857
- }
1858
- return [hasIntersected];
1859
- };
1860
-
1861
- const useLayout = () => {
1862
- const windowReference = typeof window === 'undefined' ? undefined : window;
1863
- const [breakpoint, setBreakpoint] = useState();
1864
- const [clientWidth] = useClientWidth({
1865
- ref: windowReference
1866
- });
1867
- useEffect(() => {
1868
- if (!clientWidth) {
1869
- return;
1870
- }
1871
- if (clientWidth <= Breakpoint.EXTRA_SMALL) {
1872
- setBreakpoint(Breakpoint.EXTRA_SMALL);
1873
- return;
1874
- }
1875
- if (Breakpoint.EXTRA_SMALL < clientWidth && clientWidth <= Breakpoint.SMALL) {
1876
- setBreakpoint(Breakpoint.SMALL);
1877
- return;
1878
- }
1879
- if (Breakpoint.SMALL < clientWidth && clientWidth <= Breakpoint.MEDIUM) {
1880
- setBreakpoint(Breakpoint.MEDIUM);
1881
- return;
1882
- }
1883
- if (Breakpoint.MEDIUM < clientWidth && clientWidth <= Breakpoint.LARGE) {
1884
- setBreakpoint(Breakpoint.LARGE);
1885
- return;
1886
- }
1887
- if (Breakpoint.LARGE < clientWidth) {
1888
- setBreakpoint(Breakpoint.EXTRA_LARGE);
1889
- }
1890
- }, [clientWidth]);
1891
- return {
1892
- isMobile: !!breakpoint && [Breakpoint.EXTRA_SMALL, Breakpoint.SMALL].includes(breakpoint),
1893
- isExtraSmall: breakpoint === Breakpoint.EXTRA_SMALL,
1894
- isSmall: breakpoint === Breakpoint.SMALL,
1895
- isMedium: breakpoint === Breakpoint.MEDIUM,
1896
- isLarge: breakpoint === Breakpoint.LARGE,
1897
- isExtraLarge: breakpoint === Breakpoint.EXTRA_LARGE
1898
- };
1899
- };
1900
-
1901
1977
  const INITIAL_Y_POSITION = 0;
1902
1978
  const CONTENT_SCROLL_THRESHOLD = 1;
1903
1979
  const MOVE_OFFSET_THRESHOLD = 50;
@@ -2461,7 +2537,7 @@ const Chip = ({
2461
2537
  }, value);
2462
2538
  };
2463
2539
 
2464
- var messages$6 = defineMessages({
2540
+ var messages$7 = defineMessages({
2465
2541
  ariaLabel: {
2466
2542
  id: "neptune.Chips.ariaLabel"
2467
2543
  }
@@ -2493,7 +2569,7 @@ const Chips = ({
2493
2569
  value: chip.value,
2494
2570
  label: chip.label,
2495
2571
  closeButton: {
2496
- 'aria-label': intl.formatMessage(messages$6.ariaLabel, {
2572
+ 'aria-label': intl.formatMessage(messages$7.ariaLabel, {
2497
2573
  choice: chip.label
2498
2574
  })
2499
2575
  },
@@ -2601,7 +2677,7 @@ const validDateObject = dateObject => dateObject instanceof Date && !isNaN(dateO
2601
2677
 
2602
2678
  const isMonthAndYearFormat = dateString => validDateString(dateString) && dateString.split('-').length < 3;
2603
2679
 
2604
- var messages$5 = defineMessages({
2680
+ var messages$6 = defineMessages({
2605
2681
  monthLabel: {
2606
2682
  id: "neptune.DateInput.month.label"
2607
2683
  },
@@ -2679,12 +2755,12 @@ const DateInput = ({
2679
2755
  const [month, setMonth] = useState(() => getExplodedDate('month'));
2680
2756
  const [year, setYear] = useState(() => getExplodedDate('year'));
2681
2757
  const [lastBroadcastedValue, setLastBroadcastedValue] = useState(getDateObject);
2682
- dayLabel = dayLabel || formatMessage(messages$5.dayLabel);
2683
- monthLabel = monthLabel || formatMessage(messages$5.monthLabel);
2684
- yearLabel = yearLabel || formatMessage(messages$5.yearLabel);
2758
+ dayLabel = dayLabel || formatMessage(messages$6.dayLabel);
2759
+ monthLabel = monthLabel || formatMessage(messages$6.monthLabel);
2760
+ yearLabel = yearLabel || formatMessage(messages$6.yearLabel);
2685
2761
  placeholders = {
2686
2762
  day: placeholders?.day || 'DD',
2687
- month: placeholders?.month || formatMessage(messages$5.monthLabel),
2763
+ month: placeholders?.month || formatMessage(messages$6.monthLabel),
2688
2764
  year: placeholders?.year || 'YYYY'
2689
2765
  };
2690
2766
  const getDateAsString = date => {
@@ -3115,7 +3191,7 @@ const ResponsivePanel = /*#__PURE__*/forwardRef(({
3115
3191
  });
3116
3192
  var ResponsivePanel$1 = ResponsivePanel;
3117
3193
 
3118
- var messages$4 = defineMessages({
3194
+ var messages$5 = defineMessages({
3119
3195
  ariaLabel: {
3120
3196
  id: "neptune.ClearButton.ariaLabel"
3121
3197
  }
@@ -3178,7 +3254,7 @@ const DateTrigger = ({
3178
3254
  className: "input-group-addon",
3179
3255
  children: /*#__PURE__*/jsx(CloseButton, {
3180
3256
  className: `clear-btn clear-btn--${size}`,
3181
- "aria-label": formatMessage(messages$4.ariaLabel),
3257
+ "aria-label": formatMessage(messages$5.ariaLabel),
3182
3258
  size: Size.SMALL,
3183
3259
  onClick: event => {
3184
3260
  event.stopPropagation();
@@ -3208,50 +3284,85 @@ DateTrigger.defaultProps = {
3208
3284
  };
3209
3285
  var DateTrigger$1 = DateTrigger;
3210
3286
 
3287
+ var messages$4 = defineMessages({
3288
+ next: {
3289
+ id: "neptune.DateLookup.next"
3290
+ },
3291
+ previous: {
3292
+ id: "neptune.DateLookup.previous"
3293
+ },
3294
+ day: {
3295
+ id: "neptune.DateLookup.day"
3296
+ },
3297
+ month: {
3298
+ id: "neptune.DateLookup.month"
3299
+ },
3300
+ year: {
3301
+ id: "neptune.DateLookup.year"
3302
+ },
3303
+ twentyYears: {
3304
+ id: "neptune.DateLookup.twentyYears"
3305
+ },
3306
+ selected: {
3307
+ id: "neptune.DateLookup.selected"
3308
+ },
3309
+ goTo20YearView: {
3310
+ id: "neptune.DateLookup.goTo20YearView"
3311
+ }
3312
+ });
3313
+
3211
3314
  const buttonClasses = 'btn-link p-a-0 text-no-decoration np-text-body-large-bold rounded-sm';
3212
3315
  const DateHeader = ({
3213
3316
  label,
3214
3317
  onLabelClick,
3215
3318
  onPreviousClick,
3216
- onNextClick
3217
- }) => /*#__PURE__*/jsxs("div", {
3218
- className: "text-xs-center p-t-1 p-b-2 clearfix",
3219
- children: [/*#__PURE__*/jsx("div", {
3220
- className: "pull-left-single-direction",
3221
- children: /*#__PURE__*/jsx("button", {
3222
- type: "button",
3223
- className: `d-inline-flex ${buttonClasses}`,
3224
- onClick: onPreviousClick,
3225
- children: /*#__PURE__*/jsx(Chevron$1, {
3226
- orientation: Position.LEFT,
3227
- className: "left-single-direction",
3228
- size: Size.MEDIUM
3319
+ onNextClick,
3320
+ dateMode
3321
+ }) => {
3322
+ const intl = useIntl();
3323
+ return /*#__PURE__*/jsxs("div", {
3324
+ className: "text-xs-center p-t-1 p-b-2 clearfix",
3325
+ children: [/*#__PURE__*/jsx("div", {
3326
+ className: "pull-left-single-direction",
3327
+ children: /*#__PURE__*/jsx("button", {
3328
+ type: "button",
3329
+ className: `d-inline-flex ${buttonClasses}`,
3330
+ "aria-label": `${intl.formatMessage(messages$4.previous)} ${dateMode}`,
3331
+ onClick: onPreviousClick,
3332
+ children: /*#__PURE__*/jsx(Chevron$1, {
3333
+ orientation: Position.LEFT,
3334
+ className: "left-single-direction",
3335
+ size: Size.MEDIUM
3336
+ })
3229
3337
  })
3230
- })
3231
- }), label && /*#__PURE__*/jsx("button", {
3232
- type: "button",
3233
- className: `tw-date-lookup-header-current ${buttonClasses}`,
3234
- onClick: onLabelClick,
3235
- children: label
3236
- }), /*#__PURE__*/jsx("div", {
3237
- className: "pull-right-single-direction",
3238
- children: /*#__PURE__*/jsx("button", {
3338
+ }), label && /*#__PURE__*/jsx("button", {
3239
3339
  type: "button",
3240
- className: `d-inline-flex ${buttonClasses}`,
3241
- onClick: onNextClick,
3242
- children: /*#__PURE__*/jsx(Chevron$1, {
3243
- orientation: Position.RIGHT,
3244
- className: "right-single-direction",
3245
- size: Size.MEDIUM
3340
+ className: `tw-date-lookup-header-current ${buttonClasses}`,
3341
+ "aria-label": intl.formatMessage(messages$4.goTo20YearView),
3342
+ onClick: onLabelClick,
3343
+ children: label
3344
+ }), /*#__PURE__*/jsx("div", {
3345
+ className: "pull-right-single-direction",
3346
+ children: /*#__PURE__*/jsx("button", {
3347
+ type: "button",
3348
+ className: `d-inline-flex ${buttonClasses}`,
3349
+ "aria-label": `${useIntl().formatMessage(messages$4.next)} ${dateMode}`,
3350
+ onClick: onNextClick,
3351
+ children: /*#__PURE__*/jsx(Chevron$1, {
3352
+ orientation: Position.RIGHT,
3353
+ className: "right-single-direction",
3354
+ size: Size.MEDIUM
3355
+ })
3246
3356
  })
3247
- })
3248
- })]
3249
- });
3357
+ })]
3358
+ });
3359
+ };
3250
3360
  DateHeader.propTypes = {
3251
3361
  label: PropTypes.string,
3252
3362
  onLabelClick: PropTypes.func,
3253
3363
  onPreviousClick: PropTypes.func.isRequired,
3254
- onNextClick: PropTypes.func.isRequired
3364
+ onNextClick: PropTypes.func.isRequired,
3365
+ dateMode: PropTypes.string
3255
3366
  };
3256
3367
  DateHeader.defaultProps = {
3257
3368
  label: null,
@@ -3277,6 +3388,12 @@ class TableLink extends PureComponent {
3277
3388
  this.props.onClick(this.props.item);
3278
3389
  }
3279
3390
  };
3391
+ calculateAriaLabel = (longTitle, title, active, type, formatMessage) => {
3392
+ if (active) {
3393
+ return `${longTitle || title}, ${formatMessage(messages$4.selected)} ${formatMessage(messages$4[type])}`;
3394
+ }
3395
+ return longTitle || title;
3396
+ };
3280
3397
  render() {
3281
3398
  const {
3282
3399
  item,
@@ -3285,14 +3402,17 @@ class TableLink extends PureComponent {
3285
3402
  longTitle,
3286
3403
  active,
3287
3404
  disabled,
3288
- today
3405
+ today,
3406
+ intl: {
3407
+ formatMessage
3408
+ }
3289
3409
  } = this.props;
3290
3410
  return /*#__PURE__*/jsx(Fragment, {
3291
3411
  children: /*#__PURE__*/jsx("button", {
3292
3412
  type: "button",
3293
3413
  className: `tw-date-lookup-${type}-option ${active ? 'active' : ''} ${today ? 'today' : ''} np-text-body-default-bold`,
3294
3414
  disabled: disabled,
3295
- "aria-label": longTitle,
3415
+ "aria-label": this.calculateAriaLabel(longTitle, title, active, type, formatMessage),
3296
3416
  onClick: this.onClick,
3297
3417
  children: title || item
3298
3418
  })
@@ -3314,7 +3434,7 @@ TableLink.defaultProps = {
3314
3434
  title: null,
3315
3435
  longTitle: null
3316
3436
  };
3317
- var TableLink$1 = TableLink;
3437
+ var TableLink$1 = injectIntl(TableLink);
3318
3438
 
3319
3439
  const SHORT_DAY_FORMAT = {
3320
3440
  day: 'numeric'
@@ -3358,6 +3478,7 @@ class DayCalendarTable extends PureComponent {
3358
3478
  };
3359
3479
  days = getDayNames(this.props.intl.locale, 'short');
3360
3480
  daysShort = getDayNames(this.props.intl.locale, 'narrow');
3481
+ daysLong = getDayNames(this.props.intl.locale, 'long');
3361
3482
  selectDay = day => {
3362
3483
  const {
3363
3484
  viewMonth,
@@ -3401,10 +3522,16 @@ class DayCalendarTable extends PureComponent {
3401
3522
  className: "text-xs-center np-text-body-default-bold",
3402
3523
  children: [/*#__PURE__*/jsx("span", {
3403
3524
  className: "hidden-xs",
3404
- children: day.slice(0, 3)
3525
+ children: /*#__PURE__*/jsx("abbr", {
3526
+ title: this.daysLong[index],
3527
+ children: day.slice(0, 3)
3528
+ })
3405
3529
  }), /*#__PURE__*/jsx("span", {
3406
3530
  className: "visible-xs-inline-block",
3407
- children: this.daysShort[index].slice(0, 2)
3531
+ children: /*#__PURE__*/jsx("abbr", {
3532
+ title: this.daysLong[index],
3533
+ children: this.daysShort[index].slice(0, 2)
3534
+ })
3408
3535
  })]
3409
3536
  }, day))
3410
3537
  })
@@ -3472,7 +3599,8 @@ class DayCalendar extends PureComponent {
3472
3599
  viewMonth,
3473
3600
  viewYear,
3474
3601
  intl: {
3475
- locale
3602
+ locale,
3603
+ formatMessage
3476
3604
  },
3477
3605
  monthFormat,
3478
3606
  onLabelClick,
@@ -3484,6 +3612,7 @@ class DayCalendar extends PureComponent {
3484
3612
  month: monthFormat,
3485
3613
  year: 'numeric'
3486
3614
  }),
3615
+ dateMode: formatMessage(messages$4.month),
3487
3616
  onLabelClick: onLabelClick,
3488
3617
  onPreviousClick: this.selectPreviousMonth,
3489
3618
  onNextClick: this.selectNextMonth
@@ -3603,13 +3732,15 @@ class MonthCalendar extends PureComponent {
3603
3732
  max,
3604
3733
  viewYear,
3605
3734
  intl: {
3606
- locale
3735
+ locale,
3736
+ formatMessage
3607
3737
  },
3608
3738
  placeholder,
3609
3739
  onLabelClick
3610
3740
  } = this.props;
3611
3741
  return /*#__PURE__*/jsxs(Fragment, {
3612
3742
  children: [/*#__PURE__*/jsx(DateHeader$1, {
3743
+ dateMode: formatMessage(messages$4.year),
3613
3744
  label: formatDate(new Date(viewYear, 0), locale, {
3614
3745
  year: 'numeric'
3615
3746
  }),
@@ -3727,10 +3858,14 @@ class YearCalendar extends PureComponent {
3727
3858
  min,
3728
3859
  max,
3729
3860
  viewYear,
3730
- placeholder
3861
+ placeholder,
3862
+ intl: {
3863
+ formatMessage
3864
+ }
3731
3865
  } = this.props;
3732
3866
  return /*#__PURE__*/jsxs(Fragment, {
3733
3867
  children: [/*#__PURE__*/jsx(DateHeader$1, {
3868
+ dateMode: formatMessage(messages$4.twentyYears),
3734
3869
  onPreviousClick: this.selectPreviousYears,
3735
3870
  onNextClick: this.selectNextYears
3736
3871
  }), /*#__PURE__*/jsx(YearCalendarTable$1, {
@@ -3758,7 +3893,7 @@ YearCalendar.defaultProps = {
3758
3893
  min: null,
3759
3894
  max: null
3760
3895
  };
3761
- var YearCalendar$1 = YearCalendar;
3896
+ var YearCalendar$1 = injectIntl(YearCalendar);
3762
3897
 
3763
3898
  const MODE = {
3764
3899
  DAY: 'day',
@@ -6423,7 +6558,7 @@ function SelectInput({
6423
6558
  children: [onClear != null && value != null ? /*#__PURE__*/jsxs(Fragment, {
6424
6559
  children: [/*#__PURE__*/jsx("button", {
6425
6560
  type: "button",
6426
- "aria-label": intl.formatMessage(messages$4.ariaLabel),
6561
+ "aria-label": intl.formatMessage(messages$5.ariaLabel),
6427
6562
  disabled: uiDisabled,
6428
6563
  className: "np-select-input-addon np-select-input-addon--interactive",
6429
6564
  onClick: event => {
@@ -10497,6 +10632,14 @@ var en = {
10497
10632
  "neptune.DateInput.day.label": "Day",
10498
10633
  "neptune.DateInput.month.label": "Month",
10499
10634
  "neptune.DateInput.year.label": "Year",
10635
+ "neptune.DateLookup.day": "day",
10636
+ "neptune.DateLookup.goTo20YearView": "Go to 20 year view",
10637
+ "neptune.DateLookup.month": "month",
10638
+ "neptune.DateLookup.next": "next",
10639
+ "neptune.DateLookup.previous": "previous",
10640
+ "neptune.DateLookup.selected": "selected",
10641
+ "neptune.DateLookup.twentyYears": "20 years",
10642
+ "neptune.DateLookup.year": "year",
10500
10643
  "neptune.Link.opensInNewTab": "(opens in new tab)",
10501
10644
  "neptune.MoneyInput.Select.placeholder": "Select an option...",
10502
10645
  "neptune.Select.searchPlaceholder": "Search...",
@@ -13004,6 +13147,7 @@ const ProcessingStep = props => {
13004
13147
  'm-b-2': isModern
13005
13148
  }),
13006
13149
  type: Typography.TITLE_BODY,
13150
+ "aria-live": "polite",
13007
13151
  children: psProcessingText
13008
13152
  }), psButtonText && /*#__PURE__*/jsx(Button, {
13009
13153
  disabled: psButtonDisabled,
@@ -13047,6 +13191,7 @@ const CompleteStep = props => {
13047
13191
  className: "droppable-card-content",
13048
13192
  children: [/*#__PURE__*/jsx("div", {
13049
13193
  className: "droppable-card-content d-flex flex-column align-items-center",
13194
+ "aria-live": "polite",
13050
13195
  children: isError ? /*#__PURE__*/jsxs(Fragment, {
13051
13196
  children: [isModern ? /*#__PURE__*/jsx(StatusIcon, {
13052
13197
  size: Size.LARGE,
@@ -13415,6 +13560,7 @@ class Upload extends Component {
13415
13560
  onClear: event => this.handleOnClear(event)
13416
13561
  }), !isProcessing && /*#__PURE__*/jsx("div", {
13417
13562
  className: "droppable-dropping-card droppable-card",
13563
+ "aria-live": "polite",
13418
13564
  children: /*#__PURE__*/jsxs("div", {
13419
13565
  className: "droppable-card-content",
13420
13566
  children: [/*#__PURE__*/jsx("div", {
@@ -13889,6 +14035,7 @@ const UploadItem = ({
13889
14035
  onDownload: onDownloadFile,
13890
14036
  children: /*#__PURE__*/jsx("div", {
13891
14037
  className: "np-upload-button",
14038
+ "aria-live": "polite",
13892
14039
  children: /*#__PURE__*/jsxs("div", {
13893
14040
  className: "media",
13894
14041
  children: [/*#__PURE__*/jsx("div", {