@transferwise/components 46.31.0 → 46.33.0

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 (58) hide show
  1. package/build/index.js +764 -474
  2. package/build/index.js.map +1 -1
  3. package/build/index.mjs +763 -474
  4. package/build/index.mjs.map +1 -1
  5. package/build/main.css +135 -0
  6. package/build/styles/carousel/Carousel.css +135 -0
  7. package/build/styles/main.css +135 -0
  8. package/build/types/carousel/Carousel.d.ts +26 -0
  9. package/build/types/carousel/Carousel.d.ts.map +1 -0
  10. package/build/types/carousel/index.d.ts +3 -0
  11. package/build/types/carousel/index.d.ts.map +1 -0
  12. package/build/types/common/card/Card.d.ts +2 -2
  13. package/build/types/common/card/Card.d.ts.map +1 -1
  14. package/build/types/common/domHelpers/documentIosClick.d.ts +0 -1
  15. package/build/types/common/domHelpers/documentIosClick.d.ts.map +1 -1
  16. package/build/types/common/domHelpers/index.d.ts +1 -1
  17. package/build/types/common/domHelpers/index.d.ts.map +1 -1
  18. package/build/types/dateLookup/DateLookup.d.ts.map +1 -1
  19. package/build/types/index.d.ts +2 -0
  20. package/build/types/index.d.ts.map +1 -1
  21. package/build/types/moneyInput/MoneyInput.d.ts +4 -2
  22. package/build/types/moneyInput/MoneyInput.d.ts.map +1 -1
  23. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts +1 -1
  24. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
  25. package/build/types/promoCard/PromoCard.d.ts +16 -5
  26. package/build/types/promoCard/PromoCard.d.ts.map +1 -1
  27. package/build/types/select/Select.d.ts +7 -7
  28. package/build/types/select/Select.d.ts.map +1 -1
  29. package/build/types/typeahead/Typeahead.d.ts +4 -55
  30. package/build/types/typeahead/Typeahead.d.ts.map +1 -1
  31. package/package.json +1 -1
  32. package/src/carousel/Carousel.css +135 -0
  33. package/src/carousel/Carousel.less +133 -0
  34. package/src/carousel/Carousel.spec.tsx +221 -0
  35. package/src/carousel/Carousel.story.tsx +63 -0
  36. package/src/carousel/Carousel.tsx +345 -0
  37. package/src/carousel/index.ts +3 -0
  38. package/src/common/card/Card.tsx +51 -43
  39. package/src/common/domHelpers/documentIosClick.ts +0 -5
  40. package/src/common/domHelpers/index.ts +0 -1
  41. package/src/dateLookup/DateLookup.rtl.spec.tsx +2 -3
  42. package/src/dateLookup/DateLookup.tsx +1 -3
  43. package/src/index.ts +2 -0
  44. package/src/inputs/SelectInput.spec.tsx +1 -1
  45. package/src/main.css +135 -0
  46. package/src/main.less +1 -0
  47. package/src/moneyInput/MoneyInput.rtl.spec.tsx +10 -0
  48. package/src/moneyInput/MoneyInput.spec.js +10 -5
  49. package/src/moneyInput/MoneyInput.tsx +21 -14
  50. package/src/phoneNumberInput/PhoneNumberInput.rtl.spec.tsx +10 -0
  51. package/src/phoneNumberInput/PhoneNumberInput.tsx +11 -2
  52. package/src/promoCard/PromoCard.story.tsx +2 -2
  53. package/src/promoCard/PromoCard.tsx +30 -9
  54. package/src/select/Select.js +18 -15
  55. package/src/select/Select.rtl.spec.tsx +17 -0
  56. package/src/select/Select.spec.js +2 -7
  57. package/src/typeahead/Typeahead.rtl.spec.tsx +16 -0
  58. package/src/typeahead/Typeahead.tsx +21 -7
package/build/index.js CHANGED
@@ -166,10 +166,6 @@ function stopPropagation$1(event) {
166
166
  event.nativeEvent.stopImmediatePropagation();
167
167
  }
168
168
  }
169
- function getSimpleRandomId(prefix) {
170
- const random = Math.ceil(Math.random() * 999999);
171
- return `${prefix}${random}`;
172
- }
173
169
 
174
170
  /**
175
171
  * Defined in `Dimmer.less`
@@ -1508,9 +1504,719 @@ const Button = /*#__PURE__*/React.forwardRef(({
1508
1504
  className: "btn-loader"
1509
1505
  })]
1510
1506
  });
1511
- });
1507
+ });
1508
+
1509
+ const Card$2 = /*#__PURE__*/React.forwardRef(({
1510
+ className,
1511
+ children = null,
1512
+ id,
1513
+ isDisabled = false,
1514
+ isSmall = false,
1515
+ onDismiss,
1516
+ testId,
1517
+ ...props
1518
+ }, ref) => {
1519
+ const closeButtonReference = React.useRef(null);
1520
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
1521
+ ref: ref,
1522
+ className: classNames__default.default('np-Card', {
1523
+ 'np-Card--small': !!isSmall,
1524
+ 'is-disabled': !!isDisabled
1525
+ }, className),
1526
+ id: id,
1527
+ "data-testid": testId,
1528
+ ...props,
1529
+ children: [onDismiss && /*#__PURE__*/jsxRuntime.jsx(CloseButton, {
1530
+ ref: closeButtonReference,
1531
+ className: "np-Card-closeButton",
1532
+ size: isSmall ? 'sm' : 'md',
1533
+ isDisabled: isDisabled,
1534
+ testId: "close-button",
1535
+ onClick: e => {
1536
+ stopPropagation$1(e);
1537
+ onDismiss();
1538
+ }
1539
+ }), children]
1540
+ });
1541
+ });
1542
+ Card$2.displayName = 'Card';
1543
+
1544
+ function Display({
1545
+ as: Heading = 'h1',
1546
+ type = exports.Typography.DISPLAY_LARGE,
1547
+ children,
1548
+ className,
1549
+ id
1550
+ }) {
1551
+ return /*#__PURE__*/jsxRuntime.jsx(Heading, {
1552
+ id: id,
1553
+ className: classNames__default.default(`np-text-${type}`, 'text-primary', className),
1554
+ children: children
1555
+ });
1556
+ }
1557
+
1558
+ const useConditionalListener = ({
1559
+ attachListener,
1560
+ callback,
1561
+ eventType,
1562
+ parent
1563
+ }) => {
1564
+ React.useEffect(() => {
1565
+ if (attachListener && !neptuneValidation.isUndefined(parent)) {
1566
+ parent.addEventListener(eventType, callback, true);
1567
+ }
1568
+ return () => {
1569
+ if (!neptuneValidation.isUndefined(parent)) {
1570
+ parent.removeEventListener(eventType, callback, true);
1571
+ }
1572
+ };
1573
+ }, [attachListener, callback, eventType, parent]);
1574
+ };
1575
+
1576
+ const DirectionContext = /*#__PURE__*/React.createContext(exports.Direction.LTR);
1577
+ const DirectionProvider = ({
1578
+ direction,
1579
+ children
1580
+ }) => {
1581
+ return /*#__PURE__*/jsxRuntime.jsx(DirectionContext.Provider, {
1582
+ value: direction,
1583
+ children: children
1584
+ });
1585
+ };
1586
+
1587
+ const useDirection = () => {
1588
+ const direction = React.useContext(DirectionContext);
1589
+ return {
1590
+ direction,
1591
+ isRTL: direction === 'rtl'
1592
+ };
1593
+ };
1594
+
1595
+ const ObserverParams = {
1596
+ threshold: 0.1
1597
+ };
1598
+
1599
+ /**
1600
+ * useHasIntersected.
1601
+ * Use this custom hook to detect when an element has became visible inside the viewport. This hook checks only if the intersection happend.
1602
+ * Once the intersection has happened the hook will not return false even if the element gets out of the viewport.
1603
+ *
1604
+ * @param elRef.elRef
1605
+ * @param {object} [elRef] - node object that contains a react reference to the element that needs to be observed.
1606
+ * @param {strimng} [loading = 'eager'] - string that contains the type of loading.
1607
+ * @param elRef.loading
1608
+ * @usage `const [hasIntersected] = useHasIntersected({imageRef,loading});`
1609
+ */
1610
+ const useHasIntersected = ({
1611
+ elRef,
1612
+ loading
1613
+ }) => {
1614
+ const [hasIntersected, setHasIntersected] = React.useState(false);
1615
+ const {
1616
+ current
1617
+ } = elRef || {};
1618
+ const isValidReference = () => {
1619
+ return elRef && current;
1620
+ };
1621
+ const handleOnIntersect = (entries, observer) => {
1622
+ entries.forEach(entry => {
1623
+ if (entry.isIntersecting) {
1624
+ setHasIntersected(true);
1625
+ observer.unobserve(current);
1626
+ }
1627
+ });
1628
+ };
1629
+ React.useEffect(() => {
1630
+ let observer;
1631
+ let didCancel = false;
1632
+
1633
+ // Check if window is define for SSR and Old browsers fallback
1634
+ if (typeof window === 'undefined' || !window.IntersectionObserver || !isValidReference()) {
1635
+ setHasIntersected(true);
1636
+ } else if (!didCancel) {
1637
+ observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
1638
+ observer.observe(current);
1639
+ }
1640
+ return () => {
1641
+ didCancel = true;
1642
+ if (observer) {
1643
+ observer.unobserve(current);
1644
+ }
1645
+ };
1646
+ }, [elRef]);
1647
+ if (loading === 'eager') {
1648
+ return [false];
1649
+ }
1650
+ return [hasIntersected];
1651
+ };
1652
+
1653
+ // eslint-disable-next-line import/extensions
1654
+ function useMedia(query) {
1655
+ return index_js.useSyncExternalStore(onStoreChange => {
1656
+ const mediaQueryList = window.matchMedia(query);
1657
+ mediaQueryList.addEventListener('change', onStoreChange);
1658
+ return () => {
1659
+ mediaQueryList.removeEventListener('change', onStoreChange);
1660
+ };
1661
+ }, () => typeof window !== 'undefined' ? window.matchMedia(query).matches : undefined, () => undefined);
1662
+ }
1663
+
1664
+ function useScreenSize(size) {
1665
+ return useMedia(`(min-width: ${size}px)`);
1666
+ }
1667
+
1668
+ /**
1669
+ * @deprecated Prefer `useScreenSize` instead.
1670
+ */
1671
+ const useLayout = () => {
1672
+ const screenXs = useScreenSize(exports.Breakpoint.EXTRA_SMALL);
1673
+ const screenSm = useScreenSize(exports.Breakpoint.SMALL);
1674
+ const screenMd = useScreenSize(exports.Breakpoint.MEDIUM);
1675
+ const screenLg = useScreenSize(exports.Breakpoint.LARGE);
1676
+ const screenXl = useScreenSize(exports.Breakpoint.EXTRA_LARGE);
1677
+ return {
1678
+ isMobile: screenSm != null ? !screenSm : undefined,
1679
+ isExtraSmall: screenXs,
1680
+ isSmall: screenSm,
1681
+ isMedium: screenMd,
1682
+ isLarge: screenLg,
1683
+ isExtraLarge: screenXl
1684
+ };
1685
+ };
1686
+
1687
+ const EmptyTransparentImage = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
1688
+ const Image = ({
1689
+ id,
1690
+ src,
1691
+ alt,
1692
+ onLoad,
1693
+ onError,
1694
+ className,
1695
+ loading,
1696
+ stretch = true,
1697
+ role,
1698
+ shrink = true
1699
+ }) => {
1700
+ const elementReference = React.useRef(null);
1701
+ const [hasIntersected] = useHasIntersected({
1702
+ elRef: elementReference,
1703
+ loading
1704
+ });
1705
+ let imageSource = src;
1706
+ let imageOnLoad = onLoad;
1707
+ if (loading === 'lazy' && !hasIntersected) {
1708
+ imageSource = EmptyTransparentImage;
1709
+ imageOnLoad = undefined;
1710
+ }
1711
+ return /*#__PURE__*/jsxRuntime.jsx("img", {
1712
+ ref: elementReference,
1713
+ id: id,
1714
+ alt: alt,
1715
+ src: imageSource,
1716
+ className: classNames__default.default(['tw-image', {
1717
+ 'tw-image__stretch': stretch,
1718
+ 'tw-image__shrink': shrink
1719
+ }, className]),
1720
+ role: role,
1721
+ onLoad: imageOnLoad,
1722
+ onError: onError
1723
+ });
1724
+ };
1725
+
1726
+ const defaultPromoCardContext = {
1727
+ state: '',
1728
+ isDisabled: false,
1729
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1730
+ onChange: () => {}
1731
+ };
1732
+ /**
1733
+ * The PromoCard context object.
1734
+ */
1735
+ const PromoCardContext = /*#__PURE__*/React.createContext(defaultPromoCardContext);
1736
+ /**
1737
+ * A custom hook for accessing the PromoCard context object.
1738
+ *
1739
+ * The `usePromoCardContext` hook is used to access the PromoCard context object
1740
+ * from within a child PromoCard component. It throws an error if the context
1741
+ * object is not available, which can help with debugging and development.
1742
+ *
1743
+ * @returns {PromoCardContextType} - The PromoCard context object.
1744
+ */
1745
+ const usePromoCardContext = () => {
1746
+ return React.useContext(PromoCardContext);
1747
+ };
1748
+
1749
+ const PromoCardIndicator = ({
1750
+ className,
1751
+ children,
1752
+ label,
1753
+ icon,
1754
+ isSmall = false,
1755
+ testid,
1756
+ ...rest
1757
+ }) => {
1758
+ const isIconString = icon && typeof icon === 'string';
1759
+ const IconComponent = isIconString && {
1760
+ check: icons.Check,
1761
+ arrow: icons.ArrowRight,
1762
+ download: icons.Download
1763
+ }[icon];
1764
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
1765
+ className: classNames__default.default('np-Card-indicator', className),
1766
+ "data-testid": testid,
1767
+ ...rest,
1768
+ children: [label && /*#__PURE__*/jsxRuntime.jsx(Body, {
1769
+ as: "span",
1770
+ type: exports.Typography.BODY_LARGE_BOLD,
1771
+ className: "np-Card-indicatorText",
1772
+ children: label
1773
+ }), icon && /*#__PURE__*/jsxRuntime.jsx(Avatar, {
1774
+ type: exports.AvatarType.ICON,
1775
+ size: isSmall ? 40 : 56,
1776
+ backgroundColor: "var(--Card-indicator-icon-background-color)",
1777
+ className: "np-Card-indicatorIcon",
1778
+ children: IconComponent ? /*#__PURE__*/jsxRuntime.jsx(IconComponent, {
1779
+ size: 24,
1780
+ "aria-hidden": "true"
1781
+ }) : icon
1782
+ }), children]
1783
+ });
1784
+ };
1785
+
1786
+ const PromoCard = /*#__PURE__*/React.forwardRef(({
1787
+ className,
1788
+ description,
1789
+ defaultChecked,
1790
+ download,
1791
+ href,
1792
+ hrefLang,
1793
+ id,
1794
+ headingLevel = 'h3',
1795
+ imageAlt,
1796
+ imageClass,
1797
+ imageSource,
1798
+ indicatorLabel,
1799
+ indicatorIcon,
1800
+ isChecked,
1801
+ isDisabled,
1802
+ onClick,
1803
+ onKeyDown,
1804
+ rel,
1805
+ tabIndex,
1806
+ target,
1807
+ testId,
1808
+ title,
1809
+ type,
1810
+ value,
1811
+ isSmall,
1812
+ useDisplayFont = true,
1813
+ anchorRef,
1814
+ anchorId,
1815
+ ...props
1816
+ }, ref) => {
1817
+ // Set the `checked` state to the value of `defaultChecked` if it is truthy,
1818
+ // or the value of `isChecked` if it is truthy, or `false` if neither
1819
+ // is truthy.
1820
+ const {
1821
+ state,
1822
+ onChange,
1823
+ isDisabled: contextIsDisabled
1824
+ } = usePromoCardContext();
1825
+ const [checked, setChecked] = React.useState(type === 'checkbox' ? defaultChecked ?? isChecked ?? false : false);
1826
+ const handleClick = () => {
1827
+ if (type === 'radio') {
1828
+ onChange(value || ''); // Update the context state for radio
1829
+ } else if (type === 'checkbox') {
1830
+ setChecked(!checked); // Update local state for checkbox
1831
+ }
1832
+ };
1833
+ const fallbackId = reactId.useId();
1834
+ const componentId = id || fallbackId;
1835
+ // Set the icon to `'arrow'` if `href` is truthy and `type` is falsy, or
1836
+ // `'download'` if `download` is truthy. If neither condition is true, set
1837
+ // `icon` to `undefined`.
1838
+ // Create a function to get icon type
1839
+ const getIconType = () => {
1840
+ if (indicatorIcon) {
1841
+ return indicatorIcon;
1842
+ }
1843
+ if (download) {
1844
+ return 'download';
1845
+ }
1846
+ if (href && !type) {
1847
+ return 'arrow';
1848
+ }
1849
+ return undefined;
1850
+ };
1851
+ // Define all class names string based on the values of the `href`, `type`,
1852
+ // `checked`, and `className` props.
1853
+ const commonClasses = classNames__default.default({
1854
+ 'np-Card--promoCard': true,
1855
+ 'np-Card--checked': !href && type,
1856
+ 'np-Card--link': href && !type,
1857
+ 'is-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined
1858
+ }, className);
1859
+ // Object with common props that will be passed to the `Card` components
1860
+ const commonProps = {
1861
+ className: commonClasses,
1862
+ id: componentId,
1863
+ isDisabled: isDisabled || contextIsDisabled,
1864
+ onClick,
1865
+ onKeyDown,
1866
+ ref,
1867
+ 'data-testid': testId,
1868
+ isSmall
1869
+ };
1870
+ // Object with Anchor props that will be passed to the `a` element. These
1871
+ // won't be refurned if set to `isDisabled`
1872
+ const anchorProps = href && !isDisabled ? {
1873
+ download,
1874
+ href: href || undefined,
1875
+ hrefLang,
1876
+ rel,
1877
+ target,
1878
+ ref: anchorRef,
1879
+ id: anchorId
1880
+ } : {};
1881
+ // Object of all Checked props that will be passed to the root `Card` component
1882
+ const checkedProps = (type === 'checkbox' || type === 'radio') && !href ? {
1883
+ ...commonProps,
1884
+ 'aria-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined,
1885
+ 'aria-describedby': `${componentId}-title`,
1886
+ 'aria-disabled': isDisabled,
1887
+ 'data-value': value ?? undefined,
1888
+ role: type === 'checkbox' || type === 'radio' ? type : undefined,
1889
+ onClick: handleClick,
1890
+ onKeyDown: event => {
1891
+ if (event.key === 'Enter' || event.key === ' ') {
1892
+ handleClick();
1893
+ }
1894
+ },
1895
+ ref,
1896
+ tabIndex: 0
1897
+ } : {};
1898
+ const getTitle = () => {
1899
+ const titleContent = href && !type ? /*#__PURE__*/jsxRuntime.jsx("a", {
1900
+ className: "np-Card-titleLink",
1901
+ ...anchorProps,
1902
+ children: title
1903
+ }) : title;
1904
+ const titleProps = {
1905
+ id: `${componentId}-title`,
1906
+ as: headingLevel,
1907
+ className: 'np-Card-title'
1908
+ };
1909
+ return useDisplayFont ? /*#__PURE__*/jsxRuntime.jsx(Display, {
1910
+ type: exports.Typography.DISPLAY_SMALL,
1911
+ ...titleProps,
1912
+ children: titleContent
1913
+ }) : /*#__PURE__*/jsxRuntime.jsx(Title, {
1914
+ type: exports.Typography.TITLE_SUBSECTION,
1915
+ ...titleProps,
1916
+ children: titleContent
1917
+ });
1918
+ };
1919
+ React.useEffect(() => {
1920
+ setChecked(defaultChecked ?? isChecked ?? false);
1921
+ }, [defaultChecked, isChecked]);
1922
+ return /*#__PURE__*/jsxRuntime.jsxs(Card$2, {
1923
+ ...commonProps,
1924
+ ...checkedProps,
1925
+ ...props,
1926
+ children: [(value === state || checked) && /*#__PURE__*/jsxRuntime.jsx("span", {
1927
+ className: "np-Card-check",
1928
+ children: /*#__PURE__*/jsxRuntime.jsx(icons.Check, {
1929
+ size: 24,
1930
+ "aria-hidden": "true"
1931
+ })
1932
+ }), getTitle(), /*#__PURE__*/jsxRuntime.jsx(Body, {
1933
+ className: "np-Card-description",
1934
+ children: description
1935
+ }), imageSource && /*#__PURE__*/jsxRuntime.jsx("div", {
1936
+ className: classNames__default.default('np-Card-image', {
1937
+ imageClass
1938
+ }),
1939
+ children: /*#__PURE__*/jsxRuntime.jsx(Image, {
1940
+ src: imageSource,
1941
+ alt: imageAlt || '',
1942
+ loading: "lazy"
1943
+ })
1944
+ }), /*#__PURE__*/jsxRuntime.jsx(PromoCardIndicator, {
1945
+ label: indicatorLabel,
1946
+ icon: getIconType(),
1947
+ isSmall: isSmall
1948
+ })]
1949
+ });
1950
+ });
1951
+ var PromoCard$1 = /*#__PURE__*/React__namespace.default.memo(PromoCard);
1952
+
1953
+ const LEFT_SCROLL_OFFSET = 8;
1954
+ const Carousel = ({
1955
+ header,
1956
+ className,
1957
+ cards,
1958
+ onClick
1959
+ }) => {
1960
+ const [scrollPosition, setScrollPosition] = React.useState(0);
1961
+ const [previousScrollPosition, setPreviousScrollPosition] = React.useState(0);
1962
+ const [scrollIsAtEnd, setScrollIsAtEnd] = React.useState(false);
1963
+ const [visibleCardOnMobileView, setVisibleCardOnMobileView] = React.useState('');
1964
+ const carouselElementRef = React.useRef(null);
1965
+ const carouselCardsRef = React.useRef([]);
1966
+ const isLeftActionButtonEnabled = scrollPosition > LEFT_SCROLL_OFFSET;
1967
+ const areActionButtonsEnabled = isLeftActionButtonEnabled || !scrollIsAtEnd;
1968
+ const [focusedCard, setFocusedCard] = React.useState(cards?.[0]?.id);
1969
+ const updateScrollButtonsState = () => {
1970
+ if (carouselElementRef.current) {
1971
+ const {
1972
+ scrollWidth,
1973
+ offsetWidth
1974
+ } = carouselElementRef.current;
1975
+ const scrollAtEnd = scrollWidth - offsetWidth <= scrollPosition + LEFT_SCROLL_OFFSET;
1976
+ setScrollIsAtEnd(scrollAtEnd);
1977
+ }
1978
+ const scrollDirecton = scrollPosition > previousScrollPosition ? 'right' : 'left';
1979
+ const cardsInFullViewIds = [];
1980
+ carouselCardsRef.current.forEach(card => {
1981
+ if (isVisible(carouselElementRef.current, card.cardElement)) {
1982
+ // eslint-disable-next-line functional/immutable-data
1983
+ cardsInFullViewIds.push(card.cardElement.getAttribute('id') ?? '');
1984
+ }
1985
+ });
1986
+ if (cardsInFullViewIds.length >= 1) {
1987
+ const visibleCardIndex = scrollDirecton === 'right' ? cardsInFullViewIds.length - 1 : 0;
1988
+ const visibleCardId = cardsInFullViewIds[visibleCardIndex];
1989
+ setVisibleCardOnMobileView(visibleCardId);
1990
+ setFocusedCard(visibleCardId);
1991
+ }
1992
+ setPreviousScrollPosition(scrollPosition);
1993
+ };
1994
+ const scrollCarousel = (direction = 'right') => {
1995
+ if (carouselElementRef.current) {
1996
+ const {
1997
+ scrollWidth
1998
+ } = carouselElementRef.current;
1999
+ const cardWidth = scrollWidth / carouselCardsRef.current.length;
2000
+ const res = Math.floor(cardWidth - cardWidth * 0.05);
2001
+ carouselElementRef.current.scrollBy({
2002
+ left: direction === 'right' ? res : -res,
2003
+ behavior: 'smooth'
2004
+ });
2005
+ }
2006
+ };
2007
+ const handleOnKeyDown = (event, index) => {
2008
+ if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
2009
+ const nextIndex = event.key === 'ArrowRight' ? index + 1 : index - 1;
2010
+ const nextCard = cards[nextIndex];
2011
+ if (nextCard) {
2012
+ const ref = carouselCardsRef.current[nextIndex];
2013
+ if (ref.type === 'promo') {
2014
+ ref.anchorElement?.focus();
2015
+ } else {
2016
+ ref.cardElement?.focus();
2017
+ }
2018
+ scrollCardIntoView(carouselCardsRef.current[nextIndex].cardElement, nextCard);
2019
+ event.preventDefault();
2020
+ }
2021
+ }
2022
+ if (event.key === 'Enter' || event.key === ' ') {
2023
+ event.currentTarget.click();
2024
+ }
2025
+ };
2026
+ const scrollCardIntoView = (element, card) => {
2027
+ element.scrollIntoView({
2028
+ behavior: 'smooth',
2029
+ block: 'nearest',
2030
+ inline: 'center'
2031
+ });
2032
+ setFocusedCard(card.id);
2033
+ };
2034
+ React.useEffect(() => {
2035
+ updateScrollButtonsState();
2036
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2037
+ }, [scrollPosition]);
2038
+ React.useEffect(() => {
2039
+ window.addEventListener('resize', updateScrollButtonsState);
2040
+ return () => {
2041
+ window.removeEventListener('resize', updateScrollButtonsState);
2042
+ };
2043
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2044
+ }, []);
2045
+ const addElementToCardsRefArray = (index, ref) => {
2046
+ if (ref) {
2047
+ // eslint-disable-next-line functional/immutable-data
2048
+ carouselCardsRef.current[index] = {
2049
+ type: ref.type ?? carouselCardsRef.current?.[index]?.type,
2050
+ cardElement: ref.cardElement ?? carouselCardsRef.current?.[index]?.cardElement,
2051
+ anchorElement: ref.anchorElement ?? carouselCardsRef.current?.[index]?.anchorElement
2052
+ };
2053
+ }
2054
+ };
2055
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
2056
+ className: classNames__default.default('carousel-wrapper', className),
2057
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
2058
+ className: "d-flex justify-content-between carousel__header",
2059
+ children: [typeof header === 'string' ? /*#__PURE__*/jsxRuntime.jsx(Title, {
2060
+ as: "span",
2061
+ type: "title-body",
2062
+ children: header
2063
+ }) : header, areActionButtonsEnabled ? /*#__PURE__*/jsxRuntime.jsxs("div", {
2064
+ className: "hidden-xs",
2065
+ children: [/*#__PURE__*/jsxRuntime.jsx(ActionButton, {
2066
+ className: "carousel__scroll-button",
2067
+ tabIndex: -1,
2068
+ priority: "secondary",
2069
+ disabled: !isLeftActionButtonEnabled,
2070
+ "aria-hidden": "true",
2071
+ "data-testid": "scroll-carousel-left",
2072
+ onClick: () => scrollCarousel('left'),
2073
+ children: /*#__PURE__*/jsxRuntime.jsx(icons.ChevronLeft, {})
2074
+ }), /*#__PURE__*/jsxRuntime.jsx(ActionButton, {
2075
+ tabIndex: -1,
2076
+ className: "carousel__scroll-button m-l-1",
2077
+ priority: "secondary",
2078
+ "aria-hidden": "true",
2079
+ "data-testid": "scroll-carousel-right",
2080
+ disabled: scrollIsAtEnd,
2081
+ onClick: () => scrollCarousel(),
2082
+ children: /*#__PURE__*/jsxRuntime.jsx(icons.ChevronRight, {})
2083
+ })]
2084
+ }) : null]
2085
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
2086
+ ref: carouselElementRef,
2087
+ tabIndex: -1,
2088
+ role: "list",
2089
+ className: "carousel",
2090
+ onScroll: event => {
2091
+ const target = event.target;
2092
+ setScrollPosition(target.scrollLeft);
2093
+ },
2094
+ children: cards?.map((card, index) => {
2095
+ const sharedProps = {
2096
+ id: card.id,
2097
+ className: classNames__default.default('carousel__card', {
2098
+ 'carousel__card--focused': card.id === focusedCard
2099
+ }),
2100
+ onClick: () => {
2101
+ card.onClick?.();
2102
+ onClick?.(card.id);
2103
+ },
2104
+ onFocus: event => {
2105
+ scrollCardIntoView(event.currentTarget, card);
2106
+ }
2107
+ };
2108
+ const cardContent = card.type !== 'promo' ? /*#__PURE__*/jsxRuntime.jsx("div", {
2109
+ id: `${card.id}-content`,
2110
+ className: classNames__default.default('carousel__card-content', {
2111
+ [card.className ?? '']: !!card.className
2112
+ })
2113
+ // eslint-disable-next-line react/forbid-dom-props
2114
+ ,
2115
+ style: card.styles,
2116
+ children: card.content
2117
+ }) : null;
2118
+ if (card.type === 'button') {
2119
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
2120
+ "aria-labelledby": `${card.id}-content`,
2121
+ role: "listitem",
2122
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
2123
+ ...sharedProps,
2124
+ ref: el => {
2125
+ if (el) {
2126
+ // eslint-disable-next-line functional/immutable-data
2127
+ carouselCardsRef.current[index] = {
2128
+ type: 'default',
2129
+ cardElement: el
2130
+ };
2131
+ }
2132
+ },
2133
+ role: "button",
2134
+ tabIndex: 0,
2135
+ onKeyDown: event => handleOnKeyDown(event, index),
2136
+ children: cardContent
2137
+ })
2138
+ }, card.id);
2139
+ }
2140
+ if (card.type === 'promo') {
2141
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
2142
+ id: card.id,
2143
+ role: "listitem",
2144
+ "aria-labelledby": `${card.id}-anchor`,
2145
+ children: /*#__PURE__*/jsxRuntime.jsx(PromoCard$1, {
2146
+ ...card,
2147
+ type: undefined,
2148
+ ...sharedProps,
2149
+ ref: el => {
2150
+ if (el) {
2151
+ addElementToCardsRefArray(index, {
2152
+ type: 'promo',
2153
+ cardElement: el
2154
+ });
2155
+ }
2156
+ },
2157
+ anchorRef: el => {
2158
+ if (el) {
2159
+ addElementToCardsRefArray(index, {
2160
+ type: 'promo',
2161
+ anchorElement: el
2162
+ });
2163
+ }
2164
+ },
2165
+ anchorId: `${card.id}-anchor`,
2166
+ onKeyDown: event => handleOnKeyDown(event, index)
2167
+ })
2168
+ }, card.id);
2169
+ }
2170
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
2171
+ "aria-labelledby": `${card.id}-content`,
2172
+ role: "listitem",
2173
+ children: /*#__PURE__*/jsxRuntime.jsx("a", {
2174
+ ...sharedProps,
2175
+ ref: el => {
2176
+ if (el) {
2177
+ // eslint-disable-next-line functional/immutable-data
2178
+ carouselCardsRef.current[index] = {
2179
+ type: 'default',
2180
+ cardElement: el
2181
+ };
2182
+ }
2183
+ },
2184
+ href: card.href,
2185
+ rel: "noreferrer",
2186
+ onKeyDown: event => handleOnKeyDown(event, index),
2187
+ children: cardContent
2188
+ })
2189
+ }, card.id);
2190
+ })
2191
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
2192
+ className: "visible-xs",
2193
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
2194
+ className: "carousel__indicators",
2195
+ children: cards?.map((card, index) => /*#__PURE__*/jsxRuntime.jsx("button", {
2196
+ "data-testid": `${card.id}-indicator`,
2197
+ tabIndex: -1,
2198
+ "aria-hidden": true,
2199
+ type: "button",
2200
+ className: classNames__default.default('carousel__indicator', {
2201
+ 'carousel__indicator--selected': card.id === visibleCardOnMobileView
2202
+ }),
2203
+ onClick: () => {
2204
+ scrollCardIntoView(carouselCardsRef.current[index].cardElement, card);
2205
+ }
2206
+ }, `${card.id}-indicator`))
2207
+ })
2208
+ })]
2209
+ });
2210
+ };
2211
+ const isVisible = (container, el) => {
2212
+ const cWidth = container.offsetWidth;
2213
+ const cScrollOffset = container.scrollLeft;
2214
+ const elemLeft = el.offsetLeft - container.offsetLeft;
2215
+ const elemRight = elemLeft + el.offsetWidth;
2216
+ return elemLeft >= cScrollOffset && elemRight <= cScrollOffset + cWidth;
2217
+ };
1512
2218
 
1513
- const Card$1 = /*#__PURE__*/React.forwardRef((props, reference) => {
2219
+ const Card = /*#__PURE__*/React.forwardRef((props, reference) => {
1514
2220
  const {
1515
2221
  'aria-label': ariaLabel,
1516
2222
  as: Element,
@@ -1561,7 +2267,7 @@ const Card$1 = /*#__PURE__*/React.forwardRef((props, reference) => {
1561
2267
  const hasChildren = ({
1562
2268
  children
1563
2269
  }) => children;
1564
- Card$1.propTypes = {
2270
+ Card.propTypes = {
1565
2271
  'aria-label': PropTypes__default.default.string,
1566
2272
  as: PropTypes__default.default.string,
1567
2273
  isExpanded: requiredIf__default.default(PropTypes__default.default.bool, hasChildren),
@@ -1574,7 +2280,7 @@ Card$1.propTypes = {
1574
2280
  className: PropTypes__default.default.string,
1575
2281
  'data-testid': PropTypes__default.default.string
1576
2282
  };
1577
- Card$1.defaultProps = {
2283
+ Card.defaultProps = {
1578
2284
  'aria-label': undefined,
1579
2285
  as: 'div',
1580
2286
  children: null,
@@ -1582,7 +2288,7 @@ Card$1.defaultProps = {
1582
2288
  className: null,
1583
2289
  'data-testid': null
1584
2290
  };
1585
- var Card$2 = Card$1;
2291
+ var Card$1 = Card;
1586
2292
 
1587
2293
  const CheckboxButton = /*#__PURE__*/React.forwardRef(({
1588
2294
  checked,
@@ -2068,135 +2774,6 @@ const DimmerContentWrapper = ({
2068
2774
  };
2069
2775
  var Dimmer$1 = withNextPortalWrapper(Dimmer);
2070
2776
 
2071
- const useConditionalListener = ({
2072
- attachListener,
2073
- callback,
2074
- eventType,
2075
- parent
2076
- }) => {
2077
- React.useEffect(() => {
2078
- if (attachListener && !neptuneValidation.isUndefined(parent)) {
2079
- parent.addEventListener(eventType, callback, true);
2080
- }
2081
- return () => {
2082
- if (!neptuneValidation.isUndefined(parent)) {
2083
- parent.removeEventListener(eventType, callback, true);
2084
- }
2085
- };
2086
- }, [attachListener, callback, eventType, parent]);
2087
- };
2088
-
2089
- const DirectionContext = /*#__PURE__*/React.createContext(exports.Direction.LTR);
2090
- const DirectionProvider = ({
2091
- direction,
2092
- children
2093
- }) => {
2094
- return /*#__PURE__*/jsxRuntime.jsx(DirectionContext.Provider, {
2095
- value: direction,
2096
- children: children
2097
- });
2098
- };
2099
-
2100
- const useDirection = () => {
2101
- const direction = React.useContext(DirectionContext);
2102
- return {
2103
- direction,
2104
- isRTL: direction === 'rtl'
2105
- };
2106
- };
2107
-
2108
- const ObserverParams = {
2109
- threshold: 0.1
2110
- };
2111
-
2112
- /**
2113
- * useHasIntersected.
2114
- * Use this custom hook to detect when an element has became visible inside the viewport. This hook checks only if the intersection happend.
2115
- * Once the intersection has happened the hook will not return false even if the element gets out of the viewport.
2116
- *
2117
- * @param elRef.elRef
2118
- * @param {object} [elRef] - node object that contains a react reference to the element that needs to be observed.
2119
- * @param {strimng} [loading = 'eager'] - string that contains the type of loading.
2120
- * @param elRef.loading
2121
- * @usage `const [hasIntersected] = useHasIntersected({imageRef,loading});`
2122
- */
2123
- const useHasIntersected = ({
2124
- elRef,
2125
- loading
2126
- }) => {
2127
- const [hasIntersected, setHasIntersected] = React.useState(false);
2128
- const {
2129
- current
2130
- } = elRef || {};
2131
- const isValidReference = () => {
2132
- return elRef && current;
2133
- };
2134
- const handleOnIntersect = (entries, observer) => {
2135
- entries.forEach(entry => {
2136
- if (entry.isIntersecting) {
2137
- setHasIntersected(true);
2138
- observer.unobserve(current);
2139
- }
2140
- });
2141
- };
2142
- React.useEffect(() => {
2143
- let observer;
2144
- let didCancel = false;
2145
-
2146
- // Check if window is define for SSR and Old browsers fallback
2147
- if (typeof window === 'undefined' || !window.IntersectionObserver || !isValidReference()) {
2148
- setHasIntersected(true);
2149
- } else if (!didCancel) {
2150
- observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
2151
- observer.observe(current);
2152
- }
2153
- return () => {
2154
- didCancel = true;
2155
- if (observer) {
2156
- observer.unobserve(current);
2157
- }
2158
- };
2159
- }, [elRef]);
2160
- if (loading === 'eager') {
2161
- return [false];
2162
- }
2163
- return [hasIntersected];
2164
- };
2165
-
2166
- // eslint-disable-next-line import/extensions
2167
- function useMedia(query) {
2168
- return index_js.useSyncExternalStore(onStoreChange => {
2169
- const mediaQueryList = window.matchMedia(query);
2170
- mediaQueryList.addEventListener('change', onStoreChange);
2171
- return () => {
2172
- mediaQueryList.removeEventListener('change', onStoreChange);
2173
- };
2174
- }, () => typeof window !== 'undefined' ? window.matchMedia(query).matches : undefined, () => undefined);
2175
- }
2176
-
2177
- function useScreenSize(size) {
2178
- return useMedia(`(min-width: ${size}px)`);
2179
- }
2180
-
2181
- /**
2182
- * @deprecated Prefer `useScreenSize` instead.
2183
- */
2184
- const useLayout = () => {
2185
- const screenXs = useScreenSize(exports.Breakpoint.EXTRA_SMALL);
2186
- const screenSm = useScreenSize(exports.Breakpoint.SMALL);
2187
- const screenMd = useScreenSize(exports.Breakpoint.MEDIUM);
2188
- const screenLg = useScreenSize(exports.Breakpoint.LARGE);
2189
- const screenXl = useScreenSize(exports.Breakpoint.EXTRA_LARGE);
2190
- return {
2191
- isMobile: screenSm != null ? !screenSm : undefined,
2192
- isExtraSmall: screenXs,
2193
- isSmall: screenSm,
2194
- isMedium: screenMd,
2195
- isLarge: screenLg,
2196
- isExtraLarge: screenXl
2197
- };
2198
- };
2199
-
2200
2777
  const EXIT_ANIMATION = 350;
2201
2778
  const SlidingPanel = /*#__PURE__*/React.forwardRef(({
2202
2779
  position = 'left',
@@ -2476,39 +3053,6 @@ const BottomSheet$1 = props => {
2476
3053
  });
2477
3054
  };
2478
3055
 
2479
- const Card = ({
2480
- className,
2481
- children = null,
2482
- id,
2483
- isDisabled = false,
2484
- isSmall = false,
2485
- onDismiss,
2486
- testId,
2487
- ...props
2488
- }) => {
2489
- const closeButtonReference = React.useRef(null);
2490
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
2491
- className: classNames__default.default('np-Card', {
2492
- 'np-Card--small': !!isSmall,
2493
- 'is-disabled': !!isDisabled
2494
- }, className),
2495
- id: id,
2496
- "data-testid": testId,
2497
- ...props,
2498
- children: [onDismiss && /*#__PURE__*/jsxRuntime.jsx(CloseButton, {
2499
- ref: closeButtonReference,
2500
- className: "np-Card-closeButton",
2501
- size: isSmall ? 'sm' : 'md',
2502
- isDisabled: isDisabled,
2503
- testId: "close-button",
2504
- onClick: e => {
2505
- stopPropagation$1(e);
2506
- onDismiss();
2507
- }
2508
- }), children]
2509
- });
2510
- };
2511
-
2512
3056
  function CriticalCommsBanner({
2513
3057
  title,
2514
3058
  subtitle,
@@ -4366,20 +4910,6 @@ DefinitionList.defaultProps = {
4366
4910
  };
4367
4911
  var DefinitionList$1 = DefinitionList;
4368
4912
 
4369
- function Display({
4370
- as: Heading = 'h1',
4371
- type = exports.Typography.DISPLAY_LARGE,
4372
- children,
4373
- className,
4374
- id
4375
- }) {
4376
- return /*#__PURE__*/jsxRuntime.jsx(Heading, {
4377
- id: id,
4378
- className: classNames__default.default(`np-text-${type}`, 'text-primary', className),
4379
- children: children
4380
- });
4381
- }
4382
-
4383
4913
  const DropFade = ({
4384
4914
  children,
4385
4915
  show
@@ -5092,45 +5622,6 @@ const Header = ({
5092
5622
  });
5093
5623
  };
5094
5624
 
5095
- const EmptyTransparentImage = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
5096
- const Image = ({
5097
- id,
5098
- src,
5099
- alt,
5100
- onLoad,
5101
- onError,
5102
- className,
5103
- loading,
5104
- stretch = true,
5105
- role,
5106
- shrink = true
5107
- }) => {
5108
- const elementReference = React.useRef(null);
5109
- const [hasIntersected] = useHasIntersected({
5110
- elRef: elementReference,
5111
- loading
5112
- });
5113
- let imageSource = src;
5114
- let imageOnLoad = onLoad;
5115
- if (loading === 'lazy' && !hasIntersected) {
5116
- imageSource = EmptyTransparentImage;
5117
- imageOnLoad = undefined;
5118
- }
5119
- return /*#__PURE__*/jsxRuntime.jsx("img", {
5120
- ref: elementReference,
5121
- id: id,
5122
- alt: alt,
5123
- src: imageSource,
5124
- className: classNames__default.default(['tw-image', {
5125
- 'tw-image__stretch': stretch,
5126
- 'tw-image__shrink': shrink
5127
- }, className]),
5128
- role: role,
5129
- onLoad: imageOnLoad,
5130
- onError: onError
5131
- });
5132
- };
5133
-
5134
5625
  // TODO: consider to move this enum into component file once we migrate it on TypeScript or replace with some common enum
5135
5626
  exports.InfoPresentation = void 0;
5136
5627
  (function (InfoPresentation) {
@@ -6965,9 +7456,8 @@ const formatAmountIfSet = ({
6965
7456
  }) => {
6966
7457
  if (maxLengthOverride) {
6967
7458
  return amount != null ? String(amount) : '';
6968
- } else {
6969
- return typeof amount === 'number' ? formatting.formatAmount(amount, currency, locale) : '';
6970
7459
  }
7460
+ return typeof amount === 'number' ? formatting.formatAmount(amount, currency, locale) : '';
6971
7461
  };
6972
7462
  const parseNumber = ({
6973
7463
  amount,
@@ -7025,7 +7515,7 @@ class MoneyInput extends React.Component {
7025
7515
  key,
7026
7516
  ctrlKey
7027
7517
  } = event;
7028
- const isNumberKey = neptuneValidation.isNumber(parseInt(key, 10));
7518
+ const isNumberKey = neptuneValidation.isNumber(Number.parseInt(key, 10));
7029
7519
  return isNumberKey || metaKey || ctrlKey || allowedInputKeys.has(key);
7030
7520
  };
7031
7521
  handleKeyDown = event => {
@@ -7041,7 +7531,7 @@ class MoneyInput extends React.Component {
7041
7531
  const parsed = neptuneValidation.isEmpty(paste) ? null : parseNumber({
7042
7532
  amount: paste,
7043
7533
  currency: this.props.selectedCurrency.currency,
7044
- locale: locale,
7534
+ locale,
7045
7535
  maxLengthOverride: this.props.maxLengthOverride
7046
7536
  });
7047
7537
  if (isNumberOrNull(parsed)) {
@@ -7049,7 +7539,7 @@ class MoneyInput extends React.Component {
7049
7539
  formattedAmount: formatAmountIfSet({
7050
7540
  amount: parsed,
7051
7541
  currency: this.props.selectedCurrency.currency,
7052
- locale: locale,
7542
+ locale,
7053
7543
  maxLengthOverride: this.props.maxLengthOverride
7054
7544
  })
7055
7545
  });
@@ -7146,15 +7636,17 @@ class MoneyInput extends React.Component {
7146
7636
  style = className => this.props.classNames[className] || className;
7147
7637
  render() {
7148
7638
  const {
7639
+ inputAttributes,
7640
+ id: amountInputId,
7641
+ 'aria-labelledby': ariaLabelledByProp,
7149
7642
  selectedCurrency,
7150
7643
  onCurrencyChange,
7151
7644
  size,
7152
7645
  addon,
7153
- id,
7154
- 'aria-labelledby': ariaLabelledBy,
7155
7646
  selectProps,
7156
7647
  maxLengthOverride
7157
7648
  } = this.props;
7649
+ const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes?.['aria-labelledby'];
7158
7650
  const selectOptions = this.getSelectOptions();
7159
7651
  const hasSingleCurrency = () => {
7160
7652
  if (selectOptions.length !== 0) {
@@ -7175,10 +7667,12 @@ class MoneyInput extends React.Component {
7175
7667
  const isFixedCurrency = !this.state.searchQuery && hasSingleCurrency() || !onCurrencyChange;
7176
7668
  const disabled = !this.props.onAmountChange;
7177
7669
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
7670
+ role: "group",
7671
+ ...inputAttributes,
7178
7672
  "aria-labelledby": ariaLabelledBy,
7179
7673
  className: classNames__default.default(this.style('tw-money-input'), this.style('input-group'), this.style(`input-group-${size}`)),
7180
7674
  children: [/*#__PURE__*/jsxRuntime.jsx(Input, {
7181
- id: id,
7675
+ id: amountInputId,
7182
7676
  value: this.state.formattedAmount,
7183
7677
  inputMode: "decimal",
7184
7678
  disabled: disabled,
@@ -7279,7 +7773,7 @@ function currencyOptionFitsQuery(option, query) {
7279
7773
  return contains(option.label, query) || contains(option.searchable, query) || contains(option.note, query);
7280
7774
  }
7281
7775
  function contains(property, query) {
7282
- return property && property.toLowerCase().includes(query.toLowerCase());
7776
+ return property?.toLowerCase().includes(query.toLowerCase());
7283
7777
  }
7284
7778
  function sortOptionsLabelsToFirst(options, query) {
7285
7779
  return [...options].sort((first, second) => {
@@ -7297,7 +7791,9 @@ function sortOptionsLabelsToFirst(options, query) {
7297
7791
  return 0;
7298
7792
  });
7299
7793
  }
7300
- var MoneyInput$1 = reactIntl.injectIntl(MoneyInput);
7794
+ var MoneyInput$1 = reactIntl.injectIntl(withInputAttributes(MoneyInput, {
7795
+ nonLabelable: true
7796
+ }));
7301
7797
 
7302
7798
  const NavigationOptionList = ({
7303
7799
  children
@@ -8818,7 +9314,7 @@ const defaultSelectProps = {};
8818
9314
  const defaultDisabledCountries = [];
8819
9315
  const PhoneNumberInput = ({
8820
9316
  id,
8821
- 'aria-labelledby': ariaLabelledBy,
9317
+ 'aria-labelledby': ariaLabelledByProp,
8822
9318
  required,
8823
9319
  disabled,
8824
9320
  initialValue,
@@ -8832,6 +9328,10 @@ const PhoneNumberInput = ({
8832
9328
  selectProps = defaultSelectProps,
8833
9329
  disabledCountries = defaultDisabledCountries
8834
9330
  }) => {
9331
+ const inputAttributes = useInputAttributes({
9332
+ nonLabelable: true
9333
+ });
9334
+ const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes['aria-labelledby'];
8835
9335
  const {
8836
9336
  locale,
8837
9337
  formatMessage
@@ -8888,6 +9388,8 @@ const PhoneNumberInput = ({
8888
9388
  setBroadcastedValue(internalValue);
8889
9389
  }, [onChange, broadcastedValue, internalValue]);
8890
9390
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
9391
+ role: "group",
9392
+ ...inputAttributes,
8891
9393
  "aria-labelledby": ariaLabelledBy,
8892
9394
  className: "tw-telephone",
8893
9395
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
@@ -9000,227 +9502,6 @@ const ProgressBar = ({
9000
9502
  });
9001
9503
  };
9002
9504
 
9003
- const defaultPromoCardContext = {
9004
- state: '',
9005
- isDisabled: false,
9006
- // eslint-disable-next-line @typescript-eslint/no-empty-function
9007
- onChange: () => {}
9008
- };
9009
- /**
9010
- * The PromoCard context object.
9011
- */
9012
- const PromoCardContext = /*#__PURE__*/React.createContext(defaultPromoCardContext);
9013
- /**
9014
- * A custom hook for accessing the PromoCard context object.
9015
- *
9016
- * The `usePromoCardContext` hook is used to access the PromoCard context object
9017
- * from within a child PromoCard component. It throws an error if the context
9018
- * object is not available, which can help with debugging and development.
9019
- *
9020
- * @returns {PromoCardContextType} - The PromoCard context object.
9021
- */
9022
- const usePromoCardContext = () => {
9023
- return React.useContext(PromoCardContext);
9024
- };
9025
-
9026
- const PromoCardIndicator = ({
9027
- className,
9028
- children,
9029
- label,
9030
- icon,
9031
- isSmall = false,
9032
- testid,
9033
- ...rest
9034
- }) => {
9035
- const isIconString = icon && typeof icon === 'string';
9036
- const IconComponent = isIconString && {
9037
- check: icons.Check,
9038
- arrow: icons.ArrowRight,
9039
- download: icons.Download
9040
- }[icon];
9041
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
9042
- className: classNames__default.default('np-Card-indicator', className),
9043
- "data-testid": testid,
9044
- ...rest,
9045
- children: [label && /*#__PURE__*/jsxRuntime.jsx(Body, {
9046
- as: "span",
9047
- type: exports.Typography.BODY_LARGE_BOLD,
9048
- className: "np-Card-indicatorText",
9049
- children: label
9050
- }), icon && /*#__PURE__*/jsxRuntime.jsx(Avatar, {
9051
- type: exports.AvatarType.ICON,
9052
- size: isSmall ? 40 : 56,
9053
- backgroundColor: "var(--Card-indicator-icon-background-color)",
9054
- className: "np-Card-indicatorIcon",
9055
- children: IconComponent ? /*#__PURE__*/jsxRuntime.jsx(IconComponent, {
9056
- size: 24,
9057
- "aria-hidden": "true"
9058
- }) : icon
9059
- }), children]
9060
- });
9061
- };
9062
-
9063
- const PromoCard = /*#__PURE__*/React.forwardRef(({
9064
- className,
9065
- description,
9066
- defaultChecked,
9067
- download,
9068
- href,
9069
- hrefLang,
9070
- id,
9071
- headingLevel = 'h3',
9072
- imageAlt,
9073
- imageClass,
9074
- imageSource,
9075
- indicatorLabel,
9076
- indicatorIcon,
9077
- isChecked,
9078
- isDisabled,
9079
- onClick,
9080
- rel,
9081
- tabIndex,
9082
- target,
9083
- testId,
9084
- title,
9085
- type,
9086
- value,
9087
- isSmall,
9088
- useDisplayFont = true,
9089
- ...props
9090
- }, reference) => {
9091
- // Set the `checked` state to the value of `defaultChecked` if it is truthy,
9092
- // or the value of `isChecked` if it is truthy, or `false` if neither
9093
- // is truthy.
9094
- const {
9095
- state,
9096
- onChange,
9097
- isDisabled: contextIsDisabled
9098
- } = usePromoCardContext();
9099
- const [checked, setChecked] = React.useState(type === 'checkbox' ? defaultChecked ?? isChecked ?? false : false);
9100
- const handleClick = () => {
9101
- if (type === 'radio') {
9102
- onChange(value || ''); // Update the context state for radio
9103
- } else if (type === 'checkbox') {
9104
- setChecked(!checked); // Update local state for checkbox
9105
- }
9106
- };
9107
- const fallbackId = reactId.useId();
9108
- const componentId = id || fallbackId;
9109
- // Set the icon to `'arrow'` if `href` is truthy and `type` is falsy, or
9110
- // `'download'` if `download` is truthy. If neither condition is true, set
9111
- // `icon` to `undefined`.
9112
- // Create a function to get icon type
9113
- const getIconType = () => {
9114
- if (indicatorIcon) {
9115
- return indicatorIcon;
9116
- }
9117
- if (download) {
9118
- return 'download';
9119
- }
9120
- if (href && !type) {
9121
- return 'arrow';
9122
- }
9123
- return undefined;
9124
- };
9125
- // Define all class names string based on the values of the `href`, `type`,
9126
- // `checked`, and `className` props.
9127
- const commonClasses = classNames__default.default({
9128
- 'np-Card--promoCard': true,
9129
- 'np-Card--checked': !href && type,
9130
- 'np-Card--link': href && !type,
9131
- 'is-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined
9132
- }, className);
9133
- // Object with common props that will be passed to the `Card` components
9134
- const commonProps = {
9135
- className: commonClasses,
9136
- id: componentId,
9137
- isDisabled: isDisabled || contextIsDisabled,
9138
- onClick,
9139
- ref: reference,
9140
- 'data-testid': testId,
9141
- isSmall
9142
- };
9143
- // Object with Anchor props that will be passed to the `a` element. These
9144
- // won't be refurned if set to `isDisabled`
9145
- const anchorProps = href && !isDisabled ? {
9146
- download,
9147
- href: href || undefined,
9148
- hrefLang,
9149
- rel,
9150
- target
9151
- } : {};
9152
- // Object of all Checked props that will be passed to the root `Card` component
9153
- const checkedProps = (type === 'checkbox' || type === 'radio') && !href ? {
9154
- ...commonProps,
9155
- 'aria-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined,
9156
- 'aria-describedby': `${componentId}-title`,
9157
- 'aria-disabled': isDisabled,
9158
- 'data-value': value ?? undefined,
9159
- role: type === 'checkbox' || type === 'radio' ? type : undefined,
9160
- onClick: handleClick,
9161
- onKeyDown: event => {
9162
- if (event.key === 'Enter' || event.key === ' ') {
9163
- handleClick();
9164
- }
9165
- },
9166
- ref: reference,
9167
- tabIndex: 0
9168
- } : {};
9169
- const getTitle = () => {
9170
- const titleContent = href && !type ? /*#__PURE__*/jsxRuntime.jsx("a", {
9171
- className: "np-Card-titleLink",
9172
- ...anchorProps,
9173
- children: title
9174
- }) : title;
9175
- const titleProps = {
9176
- id: `${componentId}-title`,
9177
- as: headingLevel,
9178
- className: 'np-Card-title'
9179
- };
9180
- return useDisplayFont ? /*#__PURE__*/jsxRuntime.jsx(Display, {
9181
- type: exports.Typography.DISPLAY_SMALL,
9182
- ...titleProps,
9183
- children: titleContent
9184
- }) : /*#__PURE__*/jsxRuntime.jsx(Title, {
9185
- type: exports.Typography.TITLE_SUBSECTION,
9186
- ...titleProps,
9187
- children: titleContent
9188
- });
9189
- };
9190
- React.useEffect(() => {
9191
- setChecked(defaultChecked ?? isChecked ?? false);
9192
- }, [defaultChecked, isChecked]);
9193
- return /*#__PURE__*/jsxRuntime.jsxs(Card, {
9194
- ...commonProps,
9195
- ...checkedProps,
9196
- ...props,
9197
- children: [(value === state || checked) && /*#__PURE__*/jsxRuntime.jsx("span", {
9198
- className: "np-Card-check",
9199
- children: /*#__PURE__*/jsxRuntime.jsx(icons.Check, {
9200
- size: 24,
9201
- "aria-hidden": "true"
9202
- })
9203
- }), getTitle(), /*#__PURE__*/jsxRuntime.jsx(Body, {
9204
- className: "np-Card-description",
9205
- children: description
9206
- }), imageSource && /*#__PURE__*/jsxRuntime.jsx("div", {
9207
- className: classNames__default.default('np-Card-image', {
9208
- imageClass
9209
- }),
9210
- children: /*#__PURE__*/jsxRuntime.jsx(Image, {
9211
- src: imageSource,
9212
- alt: imageAlt || '',
9213
- loading: "lazy"
9214
- })
9215
- }), /*#__PURE__*/jsxRuntime.jsx(PromoCardIndicator, {
9216
- label: indicatorLabel,
9217
- icon: getIconType(),
9218
- isSmall: isSmall
9219
- })]
9220
- });
9221
- });
9222
- var PromoCard$1 = /*#__PURE__*/React__namespace.default.memo(PromoCard);
9223
-
9224
9505
  const PromoCardGroup = ({
9225
9506
  children,
9226
9507
  className,
@@ -9841,6 +10122,7 @@ function Select({
9841
10122
  dropdownProps,
9842
10123
  buttonProps
9843
10124
  }) {
10125
+ const inputAttributes = useInputAttributes();
9844
10126
  const {
9845
10127
  formatMessage
9846
10128
  } = reactIntl.useIntl();
@@ -9860,7 +10142,6 @@ function Select({
9860
10142
  const optionsListReference = React.useRef(null);
9861
10143
  const isSearchEnabled = !!onSearchChange || !!search;
9862
10144
  const isDropdownAutoWidth = dropdownWidth == null;
9863
- const fallbackButtonId = React.useMemo(() => getSimpleRandomId('np-select-'), []);
9864
10145
  const options = React.useMemo(() => {
9865
10146
  if (!search || !searchValue) {
9866
10147
  return defaultOptions;
@@ -9868,14 +10149,14 @@ function Select({
9868
10149
  return defaultOptions.filter(isSearchableOption).filter(option => {
9869
10150
  if (typeof search === 'function') {
9870
10151
  return search(option, searchValue);
9871
- } else {
9872
- return defaultFilterFunction(option, searchValue);
9873
10152
  }
10153
+ return defaultFilterFunction(option, searchValue);
9874
10154
  });
9875
10155
  }, [defaultOptions, search, searchValue]);
9876
10156
  const selectableOptions = React.useMemo(() => options.filter(isActionableOption), [options]);
9877
10157
  const focusedOption = selectableOptions[keyboardFocusedOptionIndex];
9878
- const computedId = id || fallbackButtonId;
10158
+ const fallbackButtonId = reactId.useId();
10159
+ const computedId = id || inputAttributes.id || fallbackButtonId;
9879
10160
  const listboxId = `${computedId}-listbox`;
9880
10161
  const searchBoxId = `${computedId}-searchbox`;
9881
10162
  const {
@@ -10006,7 +10287,7 @@ function Select({
10006
10287
  React.useEffect(() => {
10007
10288
  if (open) {
10008
10289
  if (!isMobile || searchValue) {
10009
- if (isSearchEnabled && !!searchBoxReference.current) {
10290
+ if (isSearchEnabled && searchBoxReference.current) {
10010
10291
  searchBoxReference.current.focus();
10011
10292
  }
10012
10293
  if (!isSearchEnabled && optionsListReference.current && (previousKeyboardFocusedOptionIndex.current == null || Number.isNaN(previousKeyboardFocusedOptionIndex.current))) {
@@ -10192,6 +10473,7 @@ function Select({
10192
10473
  onBlur: handleOnBlur,
10193
10474
  children: [/*#__PURE__*/jsxRuntime.jsxs(Button, {
10194
10475
  ref: dropdownButtonReference,
10476
+ ...inputAttributes,
10195
10477
  id: computedId,
10196
10478
  block: block,
10197
10479
  size: size,
@@ -10267,9 +10549,6 @@ Select.propTypes = {
10267
10549
  * if `function` you can define your own search function to implement custom search experience. This search function used while filtering the options array. The custom search function takes two parameters. First is the option the second is the keyword.
10268
10550
  */
10269
10551
  search: PropTypes__default.default.oneOfType([PropTypes__default.default.bool, PropTypes__default.default.func]),
10270
- onChange: PropTypes__default.default.func.isRequired,
10271
- onFocus: PropTypes__default.default.func,
10272
- onBlur: PropTypes__default.default.func,
10273
10552
  options: PropTypes__default.default.arrayOf(PropTypes__default.default.shape({
10274
10553
  value: PropTypes__default.default.any,
10275
10554
  label: PropTypes__default.default.node,
@@ -10282,17 +10561,20 @@ Select.propTypes = {
10282
10561
  disabled: PropTypes__default.default.bool,
10283
10562
  searchStrings: PropTypes__default.default.arrayOf(PropTypes__default.default.string)
10284
10563
  })).isRequired,
10285
- /**
10286
- * To have full control of your search value and response use `onSearchChange` function combined with `searchValue` and custom filtering on the options array.
10287
- * DO NOT USE TOGETHER WITH `search` PROPERTY
10288
- */
10289
- onSearchChange: PropTypes__default.default.func,
10290
10564
  searchValue: PropTypes__default.default.string,
10291
10565
  searchPlaceholder: PropTypes__default.default.string,
10292
10566
  classNames: PropTypes__default.default.objectOf(PropTypes__default.default.string),
10293
10567
  dropdownUp: PropTypes__default.default.bool,
10294
10568
  buttonProps: PropTypes__default.default.object,
10295
- dropdownProps: PropTypes__default.default.object
10569
+ dropdownProps: PropTypes__default.default.object,
10570
+ onChange: PropTypes__default.default.func.isRequired,
10571
+ onFocus: PropTypes__default.default.func,
10572
+ onBlur: PropTypes__default.default.func,
10573
+ /**
10574
+ * To have full control of your search value and response use `onSearchChange` function combined with `searchValue` and custom filtering on the options array.
10575
+ * DO NOT USE TOGETHER WITH `search` PROPERTY
10576
+ */
10577
+ onSearchChange: PropTypes__default.default.func
10296
10578
  };
10297
10579
  Select.defaultProps = {
10298
10580
  id: undefined,
@@ -11888,7 +12170,8 @@ class Typeahead extends React.Component {
11888
12170
  };
11889
12171
  render() {
11890
12172
  const {
11891
- id,
12173
+ inputAttributes,
12174
+ id: idProp,
11892
12175
  placeholder,
11893
12176
  multiple,
11894
12177
  size,
@@ -11906,6 +12189,7 @@ class Typeahead extends React.Component {
11906
12189
  alert,
11907
12190
  inputAutoComplete
11908
12191
  } = this.props;
12192
+ const id = idProp ?? inputAttributes?.id;
11909
12193
  const {
11910
12194
  errorState,
11911
12195
  query,
@@ -11931,6 +12215,8 @@ class Typeahead extends React.Component {
11931
12215
  const hasWarning = displayAlert && alertType === exports.Sentiment.WARNING;
11932
12216
  const hasInfo = displayAlert && alertType === exports.Sentiment.NEUTRAL;
11933
12217
  return /*#__PURE__*/jsxRuntime.jsx("div", {
12218
+ role: "group",
12219
+ ...inputAttributes,
11934
12220
  id: id,
11935
12221
  className: classNames__default.default('typeahead', `typeahead-${size}`, {
11936
12222
  'typeahead--has-value': selected.length > 0,
@@ -11986,6 +12272,9 @@ class Typeahead extends React.Component {
11986
12272
  });
11987
12273
  }
11988
12274
  }
12275
+ var Typeahead$1 = withInputAttributes(Typeahead, {
12276
+ nonLabelable: true
12277
+ });
11989
12278
 
11990
12279
  // TODO: consider to move this enum into component file once we migrate it on TypeScript or replace with some common enum
11991
12280
  exports.UploadStep = void 0;
@@ -14521,11 +14810,12 @@ exports.Alert = Alert;
14521
14810
  exports.Avatar = Avatar;
14522
14811
  exports.AvatarWrapper = AvatarWrapper;
14523
14812
  exports.Badge = Badge;
14524
- exports.BaseCard = Card;
14813
+ exports.BaseCard = Card$2;
14525
14814
  exports.Body = Body;
14526
14815
  exports.BottomSheet = BottomSheet$1;
14527
14816
  exports.Button = Button;
14528
- exports.Card = Card$2;
14817
+ exports.Card = Card$1;
14818
+ exports.Carousel = Carousel;
14529
14819
  exports.Checkbox = Checkbox;
14530
14820
  exports.CheckboxButton = CheckboxButton$1;
14531
14821
  exports.CheckboxOption = CheckboxOption;
@@ -14607,7 +14897,7 @@ exports.TextArea = TextArea;
14607
14897
  exports.TextareaWithDisplayFormat = TextareaWithDisplayFormat;
14608
14898
  exports.Title = Title;
14609
14899
  exports.Tooltip = Tooltip;
14610
- exports.Typeahead = Typeahead;
14900
+ exports.Typeahead = Typeahead$1;
14611
14901
  exports.Upload = Upload$1;
14612
14902
  exports.UploadInput = UploadInput;
14613
14903
  exports.adjustLocale = adjustLocale;