@transferwise/components 46.30.2 → 46.32.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 (80) hide show
  1. package/build/index.js +931 -523
  2. package/build/index.js.map +1 -1
  3. package/build/index.mjs +928 -523
  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/dateInput/DateInput.d.ts +5 -4
  15. package/build/types/dateInput/DateInput.d.ts.map +1 -1
  16. package/build/types/dateLookup/DateLookup.d.ts +11 -4
  17. package/build/types/dateLookup/DateLookup.d.ts.map +1 -1
  18. package/build/types/field/Field.d.ts +12 -0
  19. package/build/types/field/Field.d.ts.map +1 -0
  20. package/build/types/index.d.ts +6 -0
  21. package/build/types/index.d.ts.map +1 -1
  22. package/build/types/inputs/Input.d.ts.map +1 -1
  23. package/build/types/inputs/SelectInput.d.ts +1 -1
  24. package/build/types/inputs/SelectInput.d.ts.map +1 -1
  25. package/build/types/inputs/TextArea.d.ts.map +1 -1
  26. package/build/types/inputs/_common.d.ts +2 -2
  27. package/build/types/inputs/_common.d.ts.map +1 -1
  28. package/build/types/inputs/contexts.d.ts +24 -0
  29. package/build/types/inputs/contexts.d.ts.map +1 -0
  30. package/build/types/label/Label.d.ts +9 -0
  31. package/build/types/label/Label.d.ts.map +1 -0
  32. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts +1 -1
  33. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
  34. package/build/types/promoCard/PromoCard.d.ts +16 -5
  35. package/build/types/promoCard/PromoCard.d.ts.map +1 -1
  36. package/build/types/radioGroup/RadioGroup.d.ts.map +1 -1
  37. package/build/types/switch/Switch.d.ts +6 -3
  38. package/build/types/switch/Switch.d.ts.map +1 -1
  39. package/package.json +3 -3
  40. package/src/carousel/Carousel.css +135 -0
  41. package/src/carousel/Carousel.less +133 -0
  42. package/src/carousel/Carousel.spec.tsx +221 -0
  43. package/src/carousel/Carousel.story.tsx +63 -0
  44. package/src/carousel/Carousel.tsx +345 -0
  45. package/src/carousel/index.ts +3 -0
  46. package/src/common/card/Card.tsx +51 -43
  47. package/src/dateInput/DateInput.rtl.spec.tsx +17 -0
  48. package/src/dateInput/DateInput.tsx +28 -22
  49. package/src/dateLookup/DateLookup.keyboardEvents.spec.js +2 -2
  50. package/src/dateLookup/DateLookup.rtl.spec.tsx +21 -0
  51. package/src/dateLookup/DateLookup.state.spec.js +5 -5
  52. package/src/dateLookup/DateLookup.tests.story.tsx +4 -11
  53. package/src/dateLookup/DateLookup.tsx +24 -9
  54. package/src/dateLookup/DateLookup.view.spec.js +11 -11
  55. package/src/field/Field.spec.tsx +95 -0
  56. package/src/field/Field.story.tsx +59 -0
  57. package/src/field/Field.tsx +70 -0
  58. package/src/index.ts +6 -0
  59. package/src/inputs/Input.tsx +5 -3
  60. package/src/inputs/SelectInput.spec.tsx +10 -0
  61. package/src/inputs/SelectInput.tsx +9 -4
  62. package/src/inputs/TextArea.tsx +6 -3
  63. package/src/inputs/_ButtonInput.tsx +2 -2
  64. package/src/inputs/_common.ts +2 -2
  65. package/src/inputs/contexts.tsx +45 -0
  66. package/src/label/Label.spec.tsx +26 -0
  67. package/src/label/Label.story.tsx +37 -0
  68. package/src/label/Label.tsx +20 -0
  69. package/src/main.css +135 -0
  70. package/src/main.less +1 -0
  71. package/src/phoneNumberInput/PhoneNumberInput.story.tsx +16 -22
  72. package/src/phoneNumberInput/PhoneNumberInput.tsx +14 -2
  73. package/src/promoCard/PromoCard.story.tsx +2 -2
  74. package/src/promoCard/PromoCard.tsx +30 -9
  75. package/src/radioGroup/RadioGroup.rtl.spec.tsx +14 -0
  76. package/src/radioGroup/RadioGroup.story.tsx +26 -0
  77. package/src/radioGroup/RadioGroup.tsx +4 -1
  78. package/src/switch/Switch.spec.tsx +10 -0
  79. package/src/switch/Switch.tsx +22 -13
  80. package/src/utilities/logActionRequired.js +1 -1
package/build/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
- import React__default, { forwardRef, cloneElement, useState, useEffect, useRef, useMemo, Component, useCallback, createContext, useContext, useImperativeHandle, createElement, PureComponent, createRef, isValidElement, Children, Fragment as Fragment$1 } from 'react';
2
+ import React__default, { forwardRef, cloneElement, useState, useEffect, useRef, useMemo, Component, createContext, useContext, useCallback, useImperativeHandle, createElement, PureComponent, createRef, isValidElement, Children, Fragment as Fragment$1 } from 'react';
3
3
  import { useId } from '@radix-ui/react-id';
4
4
  import classNames from 'classnames';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
- import { ChevronUp, CrossCircleFill, Cross, NavigateAway, Check, Info as Info$1, Alert as Alert$1, ClockBorderless, Briefcase, Person, AlertCircleFill, ArrowLeft, QuestionMarkCircle, AlertCircle, Search, CrossCircle, ChevronDown, CheckCircleFill, ArrowRight, Download, ClockFill, Upload as Upload$2, Document, Plus, PlusCircle } from '@transferwise/icons';
6
+ import { ChevronUp, CrossCircleFill, Cross, NavigateAway, Check, Info as Info$1, Alert as Alert$1, ClockBorderless, Briefcase, Person, ArrowRight, Download, ChevronLeft, ChevronRight, AlertCircleFill, ArrowLeft, AlertCircle, QuestionMarkCircle, Search, CrossCircle, ChevronDown, CheckCircleFill, ClockFill, Upload as Upload$2, Document, Plus, PlusCircle } from '@transferwise/icons';
7
7
  import { defineMessages, useIntl, injectIntl, IntlProvider } from 'react-intl';
8
8
  import PropTypes from 'prop-types';
9
9
  import commonmark from 'commonmark';
@@ -796,7 +796,7 @@ function Title({
796
796
  }
797
797
 
798
798
  function logActionRequired(message) {
799
- if (['development', 'test'].includes(process?.env?.NODE_ENV)) {
799
+ if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {
800
800
  // eslint-disable-next-line no-console
801
801
  console.warn(message);
802
802
  }
@@ -1480,7 +1480,717 @@ const Button = /*#__PURE__*/forwardRef(({
1480
1480
  });
1481
1481
  });
1482
1482
 
1483
- const Card$1 = /*#__PURE__*/forwardRef((props, reference) => {
1483
+ const Card$2 = /*#__PURE__*/forwardRef(({
1484
+ className,
1485
+ children = null,
1486
+ id,
1487
+ isDisabled = false,
1488
+ isSmall = false,
1489
+ onDismiss,
1490
+ testId,
1491
+ ...props
1492
+ }, ref) => {
1493
+ const closeButtonReference = useRef(null);
1494
+ return /*#__PURE__*/jsxs("div", {
1495
+ ref: ref,
1496
+ className: classNames('np-Card', {
1497
+ 'np-Card--small': !!isSmall,
1498
+ 'is-disabled': !!isDisabled
1499
+ }, className),
1500
+ id: id,
1501
+ "data-testid": testId,
1502
+ ...props,
1503
+ children: [onDismiss && /*#__PURE__*/jsx(CloseButton, {
1504
+ ref: closeButtonReference,
1505
+ className: "np-Card-closeButton",
1506
+ size: isSmall ? 'sm' : 'md',
1507
+ isDisabled: isDisabled,
1508
+ testId: "close-button",
1509
+ onClick: e => {
1510
+ stopPropagation$1(e);
1511
+ onDismiss();
1512
+ }
1513
+ }), children]
1514
+ });
1515
+ });
1516
+ Card$2.displayName = 'Card';
1517
+
1518
+ function Display({
1519
+ as: Heading = 'h1',
1520
+ type = Typography.DISPLAY_LARGE,
1521
+ children,
1522
+ className,
1523
+ id
1524
+ }) {
1525
+ return /*#__PURE__*/jsx(Heading, {
1526
+ id: id,
1527
+ className: classNames(`np-text-${type}`, 'text-primary', className),
1528
+ children: children
1529
+ });
1530
+ }
1531
+
1532
+ const useConditionalListener = ({
1533
+ attachListener,
1534
+ callback,
1535
+ eventType,
1536
+ parent
1537
+ }) => {
1538
+ useEffect(() => {
1539
+ if (attachListener && !isUndefined(parent)) {
1540
+ parent.addEventListener(eventType, callback, true);
1541
+ }
1542
+ return () => {
1543
+ if (!isUndefined(parent)) {
1544
+ parent.removeEventListener(eventType, callback, true);
1545
+ }
1546
+ };
1547
+ }, [attachListener, callback, eventType, parent]);
1548
+ };
1549
+
1550
+ const DirectionContext = /*#__PURE__*/createContext(Direction.LTR);
1551
+ const DirectionProvider = ({
1552
+ direction,
1553
+ children
1554
+ }) => {
1555
+ return /*#__PURE__*/jsx(DirectionContext.Provider, {
1556
+ value: direction,
1557
+ children: children
1558
+ });
1559
+ };
1560
+
1561
+ const useDirection = () => {
1562
+ const direction = useContext(DirectionContext);
1563
+ return {
1564
+ direction,
1565
+ isRTL: direction === 'rtl'
1566
+ };
1567
+ };
1568
+
1569
+ const ObserverParams = {
1570
+ threshold: 0.1
1571
+ };
1572
+
1573
+ /**
1574
+ * useHasIntersected.
1575
+ * Use this custom hook to detect when an element has became visible inside the viewport. This hook checks only if the intersection happend.
1576
+ * Once the intersection has happened the hook will not return false even if the element gets out of the viewport.
1577
+ *
1578
+ * @param elRef.elRef
1579
+ * @param {object} [elRef] - node object that contains a react reference to the element that needs to be observed.
1580
+ * @param {strimng} [loading = 'eager'] - string that contains the type of loading.
1581
+ * @param elRef.loading
1582
+ * @usage `const [hasIntersected] = useHasIntersected({imageRef,loading});`
1583
+ */
1584
+ const useHasIntersected = ({
1585
+ elRef,
1586
+ loading
1587
+ }) => {
1588
+ const [hasIntersected, setHasIntersected] = useState(false);
1589
+ const {
1590
+ current
1591
+ } = elRef || {};
1592
+ const isValidReference = () => {
1593
+ return elRef && current;
1594
+ };
1595
+ const handleOnIntersect = (entries, observer) => {
1596
+ entries.forEach(entry => {
1597
+ if (entry.isIntersecting) {
1598
+ setHasIntersected(true);
1599
+ observer.unobserve(current);
1600
+ }
1601
+ });
1602
+ };
1603
+ useEffect(() => {
1604
+ let observer;
1605
+ let didCancel = false;
1606
+
1607
+ // Check if window is define for SSR and Old browsers fallback
1608
+ if (typeof window === 'undefined' || !window.IntersectionObserver || !isValidReference()) {
1609
+ setHasIntersected(true);
1610
+ } else if (!didCancel) {
1611
+ observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
1612
+ observer.observe(current);
1613
+ }
1614
+ return () => {
1615
+ didCancel = true;
1616
+ if (observer) {
1617
+ observer.unobserve(current);
1618
+ }
1619
+ };
1620
+ }, [elRef]);
1621
+ if (loading === 'eager') {
1622
+ return [false];
1623
+ }
1624
+ return [hasIntersected];
1625
+ };
1626
+
1627
+ // eslint-disable-next-line import/extensions
1628
+ function useMedia(query) {
1629
+ return useSyncExternalStore(onStoreChange => {
1630
+ const mediaQueryList = window.matchMedia(query);
1631
+ mediaQueryList.addEventListener('change', onStoreChange);
1632
+ return () => {
1633
+ mediaQueryList.removeEventListener('change', onStoreChange);
1634
+ };
1635
+ }, () => typeof window !== 'undefined' ? window.matchMedia(query).matches : undefined, () => undefined);
1636
+ }
1637
+
1638
+ function useScreenSize(size) {
1639
+ return useMedia(`(min-width: ${size}px)`);
1640
+ }
1641
+
1642
+ /**
1643
+ * @deprecated Prefer `useScreenSize` instead.
1644
+ */
1645
+ const useLayout = () => {
1646
+ const screenXs = useScreenSize(Breakpoint.EXTRA_SMALL);
1647
+ const screenSm = useScreenSize(Breakpoint.SMALL);
1648
+ const screenMd = useScreenSize(Breakpoint.MEDIUM);
1649
+ const screenLg = useScreenSize(Breakpoint.LARGE);
1650
+ const screenXl = useScreenSize(Breakpoint.EXTRA_LARGE);
1651
+ return {
1652
+ isMobile: screenSm != null ? !screenSm : undefined,
1653
+ isExtraSmall: screenXs,
1654
+ isSmall: screenSm,
1655
+ isMedium: screenMd,
1656
+ isLarge: screenLg,
1657
+ isExtraLarge: screenXl
1658
+ };
1659
+ };
1660
+
1661
+ const EmptyTransparentImage = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
1662
+ const Image = ({
1663
+ id,
1664
+ src,
1665
+ alt,
1666
+ onLoad,
1667
+ onError,
1668
+ className,
1669
+ loading,
1670
+ stretch = true,
1671
+ role,
1672
+ shrink = true
1673
+ }) => {
1674
+ const elementReference = useRef(null);
1675
+ const [hasIntersected] = useHasIntersected({
1676
+ elRef: elementReference,
1677
+ loading
1678
+ });
1679
+ let imageSource = src;
1680
+ let imageOnLoad = onLoad;
1681
+ if (loading === 'lazy' && !hasIntersected) {
1682
+ imageSource = EmptyTransparentImage;
1683
+ imageOnLoad = undefined;
1684
+ }
1685
+ return /*#__PURE__*/jsx("img", {
1686
+ ref: elementReference,
1687
+ id: id,
1688
+ alt: alt,
1689
+ src: imageSource,
1690
+ className: classNames(['tw-image', {
1691
+ 'tw-image__stretch': stretch,
1692
+ 'tw-image__shrink': shrink
1693
+ }, className]),
1694
+ role: role,
1695
+ onLoad: imageOnLoad,
1696
+ onError: onError
1697
+ });
1698
+ };
1699
+
1700
+ const defaultPromoCardContext = {
1701
+ state: '',
1702
+ isDisabled: false,
1703
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1704
+ onChange: () => {}
1705
+ };
1706
+ /**
1707
+ * The PromoCard context object.
1708
+ */
1709
+ const PromoCardContext = /*#__PURE__*/createContext(defaultPromoCardContext);
1710
+ /**
1711
+ * A custom hook for accessing the PromoCard context object.
1712
+ *
1713
+ * The `usePromoCardContext` hook is used to access the PromoCard context object
1714
+ * from within a child PromoCard component. It throws an error if the context
1715
+ * object is not available, which can help with debugging and development.
1716
+ *
1717
+ * @returns {PromoCardContextType} - The PromoCard context object.
1718
+ */
1719
+ const usePromoCardContext = () => {
1720
+ return useContext(PromoCardContext);
1721
+ };
1722
+
1723
+ const PromoCardIndicator = ({
1724
+ className,
1725
+ children,
1726
+ label,
1727
+ icon,
1728
+ isSmall = false,
1729
+ testid,
1730
+ ...rest
1731
+ }) => {
1732
+ const isIconString = icon && typeof icon === 'string';
1733
+ const IconComponent = isIconString && {
1734
+ check: Check,
1735
+ arrow: ArrowRight,
1736
+ download: Download
1737
+ }[icon];
1738
+ return /*#__PURE__*/jsxs("div", {
1739
+ className: classNames('np-Card-indicator', className),
1740
+ "data-testid": testid,
1741
+ ...rest,
1742
+ children: [label && /*#__PURE__*/jsx(Body, {
1743
+ as: "span",
1744
+ type: Typography.BODY_LARGE_BOLD,
1745
+ className: "np-Card-indicatorText",
1746
+ children: label
1747
+ }), icon && /*#__PURE__*/jsx(Avatar, {
1748
+ type: AvatarType.ICON,
1749
+ size: isSmall ? 40 : 56,
1750
+ backgroundColor: "var(--Card-indicator-icon-background-color)",
1751
+ className: "np-Card-indicatorIcon",
1752
+ children: IconComponent ? /*#__PURE__*/jsx(IconComponent, {
1753
+ size: 24,
1754
+ "aria-hidden": "true"
1755
+ }) : icon
1756
+ }), children]
1757
+ });
1758
+ };
1759
+
1760
+ const PromoCard = /*#__PURE__*/forwardRef(({
1761
+ className,
1762
+ description,
1763
+ defaultChecked,
1764
+ download,
1765
+ href,
1766
+ hrefLang,
1767
+ id,
1768
+ headingLevel = 'h3',
1769
+ imageAlt,
1770
+ imageClass,
1771
+ imageSource,
1772
+ indicatorLabel,
1773
+ indicatorIcon,
1774
+ isChecked,
1775
+ isDisabled,
1776
+ onClick,
1777
+ onKeyDown,
1778
+ rel,
1779
+ tabIndex,
1780
+ target,
1781
+ testId,
1782
+ title,
1783
+ type,
1784
+ value,
1785
+ isSmall,
1786
+ useDisplayFont = true,
1787
+ anchorRef,
1788
+ anchorId,
1789
+ ...props
1790
+ }, ref) => {
1791
+ // Set the `checked` state to the value of `defaultChecked` if it is truthy,
1792
+ // or the value of `isChecked` if it is truthy, or `false` if neither
1793
+ // is truthy.
1794
+ const {
1795
+ state,
1796
+ onChange,
1797
+ isDisabled: contextIsDisabled
1798
+ } = usePromoCardContext();
1799
+ const [checked, setChecked] = useState(type === 'checkbox' ? defaultChecked ?? isChecked ?? false : false);
1800
+ const handleClick = () => {
1801
+ if (type === 'radio') {
1802
+ onChange(value || ''); // Update the context state for radio
1803
+ } else if (type === 'checkbox') {
1804
+ setChecked(!checked); // Update local state for checkbox
1805
+ }
1806
+ };
1807
+ const fallbackId = useId();
1808
+ const componentId = id || fallbackId;
1809
+ // Set the icon to `'arrow'` if `href` is truthy and `type` is falsy, or
1810
+ // `'download'` if `download` is truthy. If neither condition is true, set
1811
+ // `icon` to `undefined`.
1812
+ // Create a function to get icon type
1813
+ const getIconType = () => {
1814
+ if (indicatorIcon) {
1815
+ return indicatorIcon;
1816
+ }
1817
+ if (download) {
1818
+ return 'download';
1819
+ }
1820
+ if (href && !type) {
1821
+ return 'arrow';
1822
+ }
1823
+ return undefined;
1824
+ };
1825
+ // Define all class names string based on the values of the `href`, `type`,
1826
+ // `checked`, and `className` props.
1827
+ const commonClasses = classNames({
1828
+ 'np-Card--promoCard': true,
1829
+ 'np-Card--checked': !href && type,
1830
+ 'np-Card--link': href && !type,
1831
+ 'is-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined
1832
+ }, className);
1833
+ // Object with common props that will be passed to the `Card` components
1834
+ const commonProps = {
1835
+ className: commonClasses,
1836
+ id: componentId,
1837
+ isDisabled: isDisabled || contextIsDisabled,
1838
+ onClick,
1839
+ onKeyDown,
1840
+ ref,
1841
+ 'data-testid': testId,
1842
+ isSmall
1843
+ };
1844
+ // Object with Anchor props that will be passed to the `a` element. These
1845
+ // won't be refurned if set to `isDisabled`
1846
+ const anchorProps = href && !isDisabled ? {
1847
+ download,
1848
+ href: href || undefined,
1849
+ hrefLang,
1850
+ rel,
1851
+ target,
1852
+ ref: anchorRef,
1853
+ id: anchorId
1854
+ } : {};
1855
+ // Object of all Checked props that will be passed to the root `Card` component
1856
+ const checkedProps = (type === 'checkbox' || type === 'radio') && !href ? {
1857
+ ...commonProps,
1858
+ 'aria-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined,
1859
+ 'aria-describedby': `${componentId}-title`,
1860
+ 'aria-disabled': isDisabled,
1861
+ 'data-value': value ?? undefined,
1862
+ role: type === 'checkbox' || type === 'radio' ? type : undefined,
1863
+ onClick: handleClick,
1864
+ onKeyDown: event => {
1865
+ if (event.key === 'Enter' || event.key === ' ') {
1866
+ handleClick();
1867
+ }
1868
+ },
1869
+ ref,
1870
+ tabIndex: 0
1871
+ } : {};
1872
+ const getTitle = () => {
1873
+ const titleContent = href && !type ? /*#__PURE__*/jsx("a", {
1874
+ className: "np-Card-titleLink",
1875
+ ...anchorProps,
1876
+ children: title
1877
+ }) : title;
1878
+ const titleProps = {
1879
+ id: `${componentId}-title`,
1880
+ as: headingLevel,
1881
+ className: 'np-Card-title'
1882
+ };
1883
+ return useDisplayFont ? /*#__PURE__*/jsx(Display, {
1884
+ type: Typography.DISPLAY_SMALL,
1885
+ ...titleProps,
1886
+ children: titleContent
1887
+ }) : /*#__PURE__*/jsx(Title, {
1888
+ type: Typography.TITLE_SUBSECTION,
1889
+ ...titleProps,
1890
+ children: titleContent
1891
+ });
1892
+ };
1893
+ useEffect(() => {
1894
+ setChecked(defaultChecked ?? isChecked ?? false);
1895
+ }, [defaultChecked, isChecked]);
1896
+ return /*#__PURE__*/jsxs(Card$2, {
1897
+ ...commonProps,
1898
+ ...checkedProps,
1899
+ ...props,
1900
+ children: [(value === state || checked) && /*#__PURE__*/jsx("span", {
1901
+ className: "np-Card-check",
1902
+ children: /*#__PURE__*/jsx(Check, {
1903
+ size: 24,
1904
+ "aria-hidden": "true"
1905
+ })
1906
+ }), getTitle(), /*#__PURE__*/jsx(Body, {
1907
+ className: "np-Card-description",
1908
+ children: description
1909
+ }), imageSource && /*#__PURE__*/jsx("div", {
1910
+ className: classNames('np-Card-image', {
1911
+ imageClass
1912
+ }),
1913
+ children: /*#__PURE__*/jsx(Image, {
1914
+ src: imageSource,
1915
+ alt: imageAlt || '',
1916
+ loading: "lazy"
1917
+ })
1918
+ }), /*#__PURE__*/jsx(PromoCardIndicator, {
1919
+ label: indicatorLabel,
1920
+ icon: getIconType(),
1921
+ isSmall: isSmall
1922
+ })]
1923
+ });
1924
+ });
1925
+ var PromoCard$1 = /*#__PURE__*/React__default.memo(PromoCard);
1926
+
1927
+ const LEFT_SCROLL_OFFSET = 8;
1928
+ const Carousel = ({
1929
+ header,
1930
+ className,
1931
+ cards,
1932
+ onClick
1933
+ }) => {
1934
+ const [scrollPosition, setScrollPosition] = useState(0);
1935
+ const [previousScrollPosition, setPreviousScrollPosition] = useState(0);
1936
+ const [scrollIsAtEnd, setScrollIsAtEnd] = useState(false);
1937
+ const [visibleCardOnMobileView, setVisibleCardOnMobileView] = useState('');
1938
+ const carouselElementRef = useRef(null);
1939
+ const carouselCardsRef = useRef([]);
1940
+ const isLeftActionButtonEnabled = scrollPosition > LEFT_SCROLL_OFFSET;
1941
+ const areActionButtonsEnabled = isLeftActionButtonEnabled || !scrollIsAtEnd;
1942
+ const [focusedCard, setFocusedCard] = useState(cards?.[0]?.id);
1943
+ const updateScrollButtonsState = () => {
1944
+ if (carouselElementRef.current) {
1945
+ const {
1946
+ scrollWidth,
1947
+ offsetWidth
1948
+ } = carouselElementRef.current;
1949
+ const scrollAtEnd = scrollWidth - offsetWidth <= scrollPosition + LEFT_SCROLL_OFFSET;
1950
+ setScrollIsAtEnd(scrollAtEnd);
1951
+ }
1952
+ const scrollDirecton = scrollPosition > previousScrollPosition ? 'right' : 'left';
1953
+ const cardsInFullViewIds = [];
1954
+ carouselCardsRef.current.forEach(card => {
1955
+ if (isVisible(carouselElementRef.current, card.cardElement)) {
1956
+ // eslint-disable-next-line functional/immutable-data
1957
+ cardsInFullViewIds.push(card.cardElement.getAttribute('id') ?? '');
1958
+ }
1959
+ });
1960
+ if (cardsInFullViewIds.length >= 1) {
1961
+ const visibleCardIndex = scrollDirecton === 'right' ? cardsInFullViewIds.length - 1 : 0;
1962
+ const visibleCardId = cardsInFullViewIds[visibleCardIndex];
1963
+ setVisibleCardOnMobileView(visibleCardId);
1964
+ setFocusedCard(visibleCardId);
1965
+ }
1966
+ setPreviousScrollPosition(scrollPosition);
1967
+ };
1968
+ const scrollCarousel = (direction = 'right') => {
1969
+ if (carouselElementRef.current) {
1970
+ const {
1971
+ scrollWidth
1972
+ } = carouselElementRef.current;
1973
+ const cardWidth = scrollWidth / carouselCardsRef.current.length;
1974
+ const res = Math.floor(cardWidth - cardWidth * 0.05);
1975
+ carouselElementRef.current.scrollBy({
1976
+ left: direction === 'right' ? res : -res,
1977
+ behavior: 'smooth'
1978
+ });
1979
+ }
1980
+ };
1981
+ const handleOnKeyDown = (event, index) => {
1982
+ if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
1983
+ const nextIndex = event.key === 'ArrowRight' ? index + 1 : index - 1;
1984
+ const nextCard = cards[nextIndex];
1985
+ if (nextCard) {
1986
+ const ref = carouselCardsRef.current[nextIndex];
1987
+ if (ref.type === 'promo') {
1988
+ ref.anchorElement?.focus();
1989
+ } else {
1990
+ ref.cardElement?.focus();
1991
+ }
1992
+ scrollCardIntoView(carouselCardsRef.current[nextIndex].cardElement, nextCard);
1993
+ event.preventDefault();
1994
+ }
1995
+ }
1996
+ if (event.key === 'Enter' || event.key === ' ') {
1997
+ event.currentTarget.click();
1998
+ }
1999
+ };
2000
+ const scrollCardIntoView = (element, card) => {
2001
+ element.scrollIntoView({
2002
+ behavior: 'smooth',
2003
+ block: 'nearest',
2004
+ inline: 'center'
2005
+ });
2006
+ setFocusedCard(card.id);
2007
+ };
2008
+ useEffect(() => {
2009
+ updateScrollButtonsState();
2010
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2011
+ }, [scrollPosition]);
2012
+ useEffect(() => {
2013
+ window.addEventListener('resize', updateScrollButtonsState);
2014
+ return () => {
2015
+ window.removeEventListener('resize', updateScrollButtonsState);
2016
+ };
2017
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2018
+ }, []);
2019
+ const addElementToCardsRefArray = (index, ref) => {
2020
+ if (ref) {
2021
+ // eslint-disable-next-line functional/immutable-data
2022
+ carouselCardsRef.current[index] = {
2023
+ type: ref.type ?? carouselCardsRef.current?.[index]?.type,
2024
+ cardElement: ref.cardElement ?? carouselCardsRef.current?.[index]?.cardElement,
2025
+ anchorElement: ref.anchorElement ?? carouselCardsRef.current?.[index]?.anchorElement
2026
+ };
2027
+ }
2028
+ };
2029
+ return /*#__PURE__*/jsxs("div", {
2030
+ className: classNames('carousel-wrapper', className),
2031
+ children: [/*#__PURE__*/jsxs("div", {
2032
+ className: "d-flex justify-content-between carousel__header",
2033
+ children: [typeof header === 'string' ? /*#__PURE__*/jsx(Title, {
2034
+ as: "span",
2035
+ type: "title-body",
2036
+ children: header
2037
+ }) : header, areActionButtonsEnabled ? /*#__PURE__*/jsxs("div", {
2038
+ className: "hidden-xs",
2039
+ children: [/*#__PURE__*/jsx(ActionButton, {
2040
+ className: "carousel__scroll-button",
2041
+ tabIndex: -1,
2042
+ priority: "secondary",
2043
+ disabled: !isLeftActionButtonEnabled,
2044
+ "aria-hidden": "true",
2045
+ "data-testid": "scroll-carousel-left",
2046
+ onClick: () => scrollCarousel('left'),
2047
+ children: /*#__PURE__*/jsx(ChevronLeft, {})
2048
+ }), /*#__PURE__*/jsx(ActionButton, {
2049
+ tabIndex: -1,
2050
+ className: "carousel__scroll-button m-l-1",
2051
+ priority: "secondary",
2052
+ "aria-hidden": "true",
2053
+ "data-testid": "scroll-carousel-right",
2054
+ disabled: scrollIsAtEnd,
2055
+ onClick: () => scrollCarousel(),
2056
+ children: /*#__PURE__*/jsx(ChevronRight, {})
2057
+ })]
2058
+ }) : null]
2059
+ }), /*#__PURE__*/jsx("div", {
2060
+ ref: carouselElementRef,
2061
+ tabIndex: -1,
2062
+ role: "list",
2063
+ className: "carousel",
2064
+ onScroll: event => {
2065
+ const target = event.target;
2066
+ setScrollPosition(target.scrollLeft);
2067
+ },
2068
+ children: cards?.map((card, index) => {
2069
+ const sharedProps = {
2070
+ id: card.id,
2071
+ className: classNames('carousel__card', {
2072
+ 'carousel__card--focused': card.id === focusedCard
2073
+ }),
2074
+ onClick: () => {
2075
+ card.onClick?.();
2076
+ onClick?.(card.id);
2077
+ },
2078
+ onFocus: event => {
2079
+ scrollCardIntoView(event.currentTarget, card);
2080
+ }
2081
+ };
2082
+ const cardContent = card.type !== 'promo' ? /*#__PURE__*/jsx("div", {
2083
+ id: `${card.id}-content`,
2084
+ className: classNames('carousel__card-content', {
2085
+ [card.className ?? '']: !!card.className
2086
+ })
2087
+ // eslint-disable-next-line react/forbid-dom-props
2088
+ ,
2089
+ style: card.styles,
2090
+ children: card.content
2091
+ }) : null;
2092
+ if (card.type === 'button') {
2093
+ return /*#__PURE__*/jsx("div", {
2094
+ "aria-labelledby": `${card.id}-content`,
2095
+ role: "listitem",
2096
+ children: /*#__PURE__*/jsx("div", {
2097
+ ...sharedProps,
2098
+ ref: el => {
2099
+ if (el) {
2100
+ // eslint-disable-next-line functional/immutable-data
2101
+ carouselCardsRef.current[index] = {
2102
+ type: 'default',
2103
+ cardElement: el
2104
+ };
2105
+ }
2106
+ },
2107
+ role: "button",
2108
+ tabIndex: 0,
2109
+ onKeyDown: event => handleOnKeyDown(event, index),
2110
+ children: cardContent
2111
+ })
2112
+ }, card.id);
2113
+ }
2114
+ if (card.type === 'promo') {
2115
+ return /*#__PURE__*/jsx("div", {
2116
+ id: card.id,
2117
+ role: "listitem",
2118
+ "aria-labelledby": `${card.id}-anchor`,
2119
+ children: /*#__PURE__*/jsx(PromoCard$1, {
2120
+ ...card,
2121
+ type: undefined,
2122
+ ...sharedProps,
2123
+ ref: el => {
2124
+ if (el) {
2125
+ addElementToCardsRefArray(index, {
2126
+ type: 'promo',
2127
+ cardElement: el
2128
+ });
2129
+ }
2130
+ },
2131
+ anchorRef: el => {
2132
+ if (el) {
2133
+ addElementToCardsRefArray(index, {
2134
+ type: 'promo',
2135
+ anchorElement: el
2136
+ });
2137
+ }
2138
+ },
2139
+ anchorId: `${card.id}-anchor`,
2140
+ onKeyDown: event => handleOnKeyDown(event, index)
2141
+ })
2142
+ }, card.id);
2143
+ }
2144
+ return /*#__PURE__*/jsx("div", {
2145
+ "aria-labelledby": `${card.id}-content`,
2146
+ role: "listitem",
2147
+ children: /*#__PURE__*/jsx("a", {
2148
+ ...sharedProps,
2149
+ ref: el => {
2150
+ if (el) {
2151
+ // eslint-disable-next-line functional/immutable-data
2152
+ carouselCardsRef.current[index] = {
2153
+ type: 'default',
2154
+ cardElement: el
2155
+ };
2156
+ }
2157
+ },
2158
+ href: card.href,
2159
+ rel: "noreferrer",
2160
+ onKeyDown: event => handleOnKeyDown(event, index),
2161
+ children: cardContent
2162
+ })
2163
+ }, card.id);
2164
+ })
2165
+ }), /*#__PURE__*/jsx("div", {
2166
+ className: "visible-xs",
2167
+ children: /*#__PURE__*/jsx("div", {
2168
+ className: "carousel__indicators",
2169
+ children: cards?.map((card, index) => /*#__PURE__*/jsx("button", {
2170
+ "data-testid": `${card.id}-indicator`,
2171
+ tabIndex: -1,
2172
+ "aria-hidden": true,
2173
+ type: "button",
2174
+ className: classNames('carousel__indicator', {
2175
+ 'carousel__indicator--selected': card.id === visibleCardOnMobileView
2176
+ }),
2177
+ onClick: () => {
2178
+ scrollCardIntoView(carouselCardsRef.current[index].cardElement, card);
2179
+ }
2180
+ }, `${card.id}-indicator`))
2181
+ })
2182
+ })]
2183
+ });
2184
+ };
2185
+ const isVisible = (container, el) => {
2186
+ const cWidth = container.offsetWidth;
2187
+ const cScrollOffset = container.scrollLeft;
2188
+ const elemLeft = el.offsetLeft - container.offsetLeft;
2189
+ const elemRight = elemLeft + el.offsetWidth;
2190
+ return elemLeft >= cScrollOffset && elemRight <= cScrollOffset + cWidth;
2191
+ };
2192
+
2193
+ const Card = /*#__PURE__*/forwardRef((props, reference) => {
1484
2194
  const {
1485
2195
  'aria-label': ariaLabel,
1486
2196
  as: Element,
@@ -1531,7 +2241,7 @@ const Card$1 = /*#__PURE__*/forwardRef((props, reference) => {
1531
2241
  const hasChildren = ({
1532
2242
  children
1533
2243
  }) => children;
1534
- Card$1.propTypes = {
2244
+ Card.propTypes = {
1535
2245
  'aria-label': PropTypes.string,
1536
2246
  as: PropTypes.string,
1537
2247
  isExpanded: requiredIf(PropTypes.bool, hasChildren),
@@ -1544,7 +2254,7 @@ Card$1.propTypes = {
1544
2254
  className: PropTypes.string,
1545
2255
  'data-testid': PropTypes.string
1546
2256
  };
1547
- Card$1.defaultProps = {
2257
+ Card.defaultProps = {
1548
2258
  'aria-label': undefined,
1549
2259
  as: 'div',
1550
2260
  children: null,
@@ -1552,7 +2262,7 @@ Card$1.defaultProps = {
1552
2262
  className: null,
1553
2263
  'data-testid': null
1554
2264
  };
1555
- var Card$2 = Card$1;
2265
+ var Card$1 = Card;
1556
2266
 
1557
2267
  const CheckboxButton = /*#__PURE__*/forwardRef(({
1558
2268
  checked,
@@ -2005,167 +2715,38 @@ const Dimmer = ({
2005
2715
  const DimmerWrapper = ({
2006
2716
  open,
2007
2717
  hasNotExited,
2008
- children
2009
- }) => {
2010
- const {
2011
- screenMode,
2012
- theme
2013
- } = useTheme();
2014
- return open || hasNotExited ? /*#__PURE__*/jsx(ThemeProvider, {
2015
- theme: "personal",
2016
- screenMode: theme === 'personal' ? screenMode : 'light',
2017
- isNotRootProvider: true,
2018
- children: children
2019
- }) : /*#__PURE__*/jsx(Fragment, {
2020
- children: children
2021
- });
2022
- };
2023
- const DimmerContentWrapper = ({
2024
- children,
2025
- scrollBody
2026
- }) => {
2027
- useEffect(() => {
2028
- if (scrollBody) {
2029
- addNoScrollClass();
2030
- }
2031
- return () => {
2032
- if (scrollBody) {
2033
- removeNoScrollClass();
2034
- }
2035
- };
2036
- }, [scrollBody]);
2037
- return children;
2038
- };
2039
- var Dimmer$1 = withNextPortalWrapper(Dimmer);
2040
-
2041
- const useConditionalListener = ({
2042
- attachListener,
2043
- callback,
2044
- eventType,
2045
- parent
2046
- }) => {
2047
- useEffect(() => {
2048
- if (attachListener && !isUndefined(parent)) {
2049
- parent.addEventListener(eventType, callback, true);
2050
- }
2051
- return () => {
2052
- if (!isUndefined(parent)) {
2053
- parent.removeEventListener(eventType, callback, true);
2054
- }
2055
- };
2056
- }, [attachListener, callback, eventType, parent]);
2057
- };
2058
-
2059
- const DirectionContext = /*#__PURE__*/createContext(Direction.LTR);
2060
- const DirectionProvider = ({
2061
- direction,
2062
- children
2063
- }) => {
2064
- return /*#__PURE__*/jsx(DirectionContext.Provider, {
2065
- value: direction,
2066
- children: children
2067
- });
2068
- };
2069
-
2070
- const useDirection = () => {
2071
- const direction = useContext(DirectionContext);
2072
- return {
2073
- direction,
2074
- isRTL: direction === 'rtl'
2075
- };
2076
- };
2077
-
2078
- const ObserverParams = {
2079
- threshold: 0.1
2080
- };
2081
-
2082
- /**
2083
- * useHasIntersected.
2084
- * Use this custom hook to detect when an element has became visible inside the viewport. This hook checks only if the intersection happend.
2085
- * Once the intersection has happened the hook will not return false even if the element gets out of the viewport.
2086
- *
2087
- * @param elRef.elRef
2088
- * @param {object} [elRef] - node object that contains a react reference to the element that needs to be observed.
2089
- * @param {strimng} [loading = 'eager'] - string that contains the type of loading.
2090
- * @param elRef.loading
2091
- * @usage `const [hasIntersected] = useHasIntersected({imageRef,loading});`
2092
- */
2093
- const useHasIntersected = ({
2094
- elRef,
2095
- loading
2718
+ children
2096
2719
  }) => {
2097
- const [hasIntersected, setHasIntersected] = useState(false);
2098
2720
  const {
2099
- current
2100
- } = elRef || {};
2101
- const isValidReference = () => {
2102
- return elRef && current;
2103
- };
2104
- const handleOnIntersect = (entries, observer) => {
2105
- entries.forEach(entry => {
2106
- if (entry.isIntersecting) {
2107
- setHasIntersected(true);
2108
- observer.unobserve(current);
2109
- }
2110
- });
2111
- };
2721
+ screenMode,
2722
+ theme
2723
+ } = useTheme();
2724
+ return open || hasNotExited ? /*#__PURE__*/jsx(ThemeProvider, {
2725
+ theme: "personal",
2726
+ screenMode: theme === 'personal' ? screenMode : 'light',
2727
+ isNotRootProvider: true,
2728
+ children: children
2729
+ }) : /*#__PURE__*/jsx(Fragment, {
2730
+ children: children
2731
+ });
2732
+ };
2733
+ const DimmerContentWrapper = ({
2734
+ children,
2735
+ scrollBody
2736
+ }) => {
2112
2737
  useEffect(() => {
2113
- let observer;
2114
- let didCancel = false;
2115
-
2116
- // Check if window is define for SSR and Old browsers fallback
2117
- if (typeof window === 'undefined' || !window.IntersectionObserver || !isValidReference()) {
2118
- setHasIntersected(true);
2119
- } else if (!didCancel) {
2120
- observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
2121
- observer.observe(current);
2738
+ if (scrollBody) {
2739
+ addNoScrollClass();
2122
2740
  }
2123
2741
  return () => {
2124
- didCancel = true;
2125
- if (observer) {
2126
- observer.unobserve(current);
2742
+ if (scrollBody) {
2743
+ removeNoScrollClass();
2127
2744
  }
2128
2745
  };
2129
- }, [elRef]);
2130
- if (loading === 'eager') {
2131
- return [false];
2132
- }
2133
- return [hasIntersected];
2134
- };
2135
-
2136
- // eslint-disable-next-line import/extensions
2137
- function useMedia(query) {
2138
- return useSyncExternalStore(onStoreChange => {
2139
- const mediaQueryList = window.matchMedia(query);
2140
- mediaQueryList.addEventListener('change', onStoreChange);
2141
- return () => {
2142
- mediaQueryList.removeEventListener('change', onStoreChange);
2143
- };
2144
- }, () => typeof window !== 'undefined' ? window.matchMedia(query).matches : undefined, () => undefined);
2145
- }
2146
-
2147
- function useScreenSize(size) {
2148
- return useMedia(`(min-width: ${size}px)`);
2149
- }
2150
-
2151
- /**
2152
- * @deprecated Prefer `useScreenSize` instead.
2153
- */
2154
- const useLayout = () => {
2155
- const screenXs = useScreenSize(Breakpoint.EXTRA_SMALL);
2156
- const screenSm = useScreenSize(Breakpoint.SMALL);
2157
- const screenMd = useScreenSize(Breakpoint.MEDIUM);
2158
- const screenLg = useScreenSize(Breakpoint.LARGE);
2159
- const screenXl = useScreenSize(Breakpoint.EXTRA_LARGE);
2160
- return {
2161
- isMobile: screenSm != null ? !screenSm : undefined,
2162
- isExtraSmall: screenXs,
2163
- isSmall: screenSm,
2164
- isMedium: screenMd,
2165
- isLarge: screenLg,
2166
- isExtraLarge: screenXl
2167
- };
2746
+ }, [scrollBody]);
2747
+ return children;
2168
2748
  };
2749
+ var Dimmer$1 = withNextPortalWrapper(Dimmer);
2169
2750
 
2170
2751
  const EXIT_ANIMATION = 350;
2171
2752
  const SlidingPanel = /*#__PURE__*/forwardRef(({
@@ -2446,39 +3027,6 @@ const BottomSheet$1 = props => {
2446
3027
  });
2447
3028
  };
2448
3029
 
2449
- const Card = ({
2450
- className,
2451
- children = null,
2452
- id,
2453
- isDisabled = false,
2454
- isSmall = false,
2455
- onDismiss,
2456
- testId,
2457
- ...props
2458
- }) => {
2459
- const closeButtonReference = useRef(null);
2460
- return /*#__PURE__*/jsxs("div", {
2461
- className: classNames('np-Card', {
2462
- 'np-Card--small': !!isSmall,
2463
- 'is-disabled': !!isDisabled
2464
- }, className),
2465
- id: id,
2466
- "data-testid": testId,
2467
- ...props,
2468
- children: [onDismiss && /*#__PURE__*/jsx(CloseButton, {
2469
- ref: closeButtonReference,
2470
- className: "np-Card-closeButton",
2471
- size: isSmall ? 'sm' : 'md',
2472
- isDisabled: isDisabled,
2473
- testId: "close-button",
2474
- onClick: e => {
2475
- stopPropagation$1(e);
2476
- onDismiss();
2477
- }
2478
- }), children]
2479
- });
2480
- };
2481
-
2482
3030
  function CriticalCommsBanner({
2483
3031
  title,
2484
3032
  subtitle,
@@ -2592,6 +3140,36 @@ const isMonthAndYearFormat = dateString => validDateString(dateString) && dateSt
2592
3140
  const MDY = new Set(['en-US']);
2593
3141
  const YMD = new Set(['hu', 'hu-HU', 'zh-HK', 'zh-CN', 'ja', 'ja-JP']);
2594
3142
 
3143
+ const FieldLabelIdContext = /*#__PURE__*/createContext(undefined);
3144
+ const FieldLabelIdContextProvider = FieldLabelIdContext.Provider;
3145
+ const InputIdContext = /*#__PURE__*/createContext(undefined);
3146
+ const InputIdContextProvider = InputIdContext.Provider;
3147
+ const InputDescribedByContext = /*#__PURE__*/createContext(undefined);
3148
+ const InputDescribedByProvider = InputDescribedByContext.Provider;
3149
+ const InputInvalidContext = /*#__PURE__*/createContext(undefined);
3150
+ const InputInvalidProvider = InputInvalidContext.Provider;
3151
+ function useInputAttributes({
3152
+ nonLabelable
3153
+ } = {}) {
3154
+ const labelId = useContext(FieldLabelIdContext);
3155
+ return {
3156
+ id: useContext(InputIdContext),
3157
+ 'aria-labelledby': nonLabelable ? labelId : undefined,
3158
+ 'aria-describedby': useContext(InputDescribedByContext),
3159
+ 'aria-invalid': useContext(InputInvalidContext)
3160
+ };
3161
+ }
3162
+ function withInputAttributes(Component, args) {
3163
+ function ComponentWithInputAttributes(props) {
3164
+ return /*#__PURE__*/jsx(Component, {
3165
+ inputAttributes: useInputAttributes(args),
3166
+ ...props
3167
+ });
3168
+ }
3169
+ ComponentWithInputAttributes.displayName = `withInputAttributes(${Component.displayName || Component.name || 'Component'})`;
3170
+ return ComponentWithInputAttributes;
3171
+ }
3172
+
2595
3173
  var messages$9 = defineMessages({
2596
3174
  monthLabel: {
2597
3175
  id: "neptune.DateInput.month.label"
@@ -2616,7 +3194,7 @@ const convertToLocalMidnight = date => {
2616
3194
  };
2617
3195
 
2618
3196
  const DateInput = ({
2619
- 'aria-labelledby': ariaLabelledBy,
3197
+ 'aria-labelledby': ariaLabelledByProp,
2620
3198
  'aria-label': ariaLabel,
2621
3199
  disabled = false,
2622
3200
  size = Size.MEDIUM,
@@ -2632,9 +3210,14 @@ const DateInput = ({
2632
3210
  onFocus,
2633
3211
  onBlur,
2634
3212
  placeholders,
2635
- id,
3213
+ id: idProp,
2636
3214
  selectProps = {}
2637
3215
  }) => {
3216
+ const inputAttributes = useInputAttributes({
3217
+ nonLabelable: true
3218
+ });
3219
+ const id = idProp ?? inputAttributes.id;
3220
+ const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes['aria-labelledby'];
2638
3221
  const {
2639
3222
  locale,
2640
3223
  formatMessage
@@ -2671,9 +3254,9 @@ const DateInput = ({
2671
3254
  const [year, setYear] = useState(() => getInitialDate('year'));
2672
3255
  const [lastBroadcastedValue, setLastBroadcastedValue] = useState(getDateObject);
2673
3256
  const monthNames = getMonthNames(locale, monthFormat);
2674
- dayLabel = dayLabel || formatMessage(messages$9.dayLabel);
2675
- monthLabel = monthLabel || formatMessage(messages$9.monthLabel);
2676
- yearLabel = yearLabel || formatMessage(messages$9.yearLabel);
3257
+ dayLabel ||= formatMessage(messages$9.dayLabel);
3258
+ monthLabel ||= formatMessage(messages$9.monthLabel);
3259
+ yearLabel ||= formatMessage(messages$9.yearLabel);
2677
3260
  placeholders = {
2678
3261
  day: placeholders?.day || formatMessage(messages$9.dayPlaceholder),
2679
3262
  month: placeholders?.month || formatMessage(messages$9.monthLabel),
@@ -2864,6 +3447,7 @@ const DateInput = ({
2864
3447
  const yearFirst = YMD.has(locale);
2865
3448
  return /*#__PURE__*/jsx("div", {
2866
3449
  className: "tw-date",
3450
+ ...inputAttributes,
2867
3451
  id: id,
2868
3452
  "aria-labelledby": ariaLabelledBy,
2869
3453
  "aria-label": ariaLabel,
@@ -2883,15 +3467,15 @@ const DateInput = ({
2883
3467
  return /*#__PURE__*/jsxs(Fragment, {
2884
3468
  children: [getMonth(), getDay(), getYear()]
2885
3469
  });
2886
- } else if (yearFirst) {
3470
+ }
3471
+ if (yearFirst) {
2887
3472
  return /*#__PURE__*/jsxs(Fragment, {
2888
3473
  children: [getYear(), getMonth(), getDay()]
2889
3474
  });
2890
- } else {
2891
- return /*#__PURE__*/jsxs(Fragment, {
2892
- children: [getDay(), getMonth(), getYear()]
2893
- });
2894
3475
  }
3476
+ return /*#__PURE__*/jsxs(Fragment, {
3477
+ children: [getDay(), getMonth(), getYear()]
3478
+ });
2895
3479
  })()
2896
3480
  })
2897
3481
  });
@@ -3992,18 +4576,23 @@ class DateLookup extends PureComponent {
3992
4576
  open
3993
4577
  } = this.state;
3994
4578
  const {
4579
+ inputAttributes,
4580
+ id: idProp,
4581
+ 'aria-labelledby': ariaLabelledByProp,
3995
4582
  size,
3996
4583
  placeholder,
3997
4584
  label,
3998
- 'aria-labelledby': ariaLabelledBy,
3999
4585
  monthFormat,
4000
4586
  disabled,
4001
4587
  clearable,
4002
4588
  value
4003
4589
  } = this.props;
4590
+ const id = idProp ?? inputAttributes?.id;
4591
+ const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes?.['aria-labelledby'];
4004
4592
  return /*#__PURE__*/jsxs("div", {
4005
4593
  ref: this.element,
4006
- id: this.props.id,
4594
+ ...inputAttributes,
4595
+ id: id,
4007
4596
  "aria-labelledby": ariaLabelledBy,
4008
4597
  className: "input-group",
4009
4598
  onKeyDown: this.handleKeyDown,
@@ -4027,6 +4616,9 @@ class DateLookup extends PureComponent {
4027
4616
  });
4028
4617
  }
4029
4618
  }
4619
+ var DateLookup$1 = withInputAttributes(DateLookup, {
4620
+ nonLabelable: true
4621
+ });
4030
4622
 
4031
4623
  const NavigationOption = /*#__PURE__*/forwardRef(({
4032
4624
  as: component = 'button',
@@ -4292,20 +4884,6 @@ DefinitionList.defaultProps = {
4292
4884
  };
4293
4885
  var DefinitionList$1 = DefinitionList;
4294
4886
 
4295
- function Display({
4296
- as: Heading = 'h1',
4297
- type = Typography.DISPLAY_LARGE,
4298
- children,
4299
- className,
4300
- id
4301
- }) {
4302
- return /*#__PURE__*/jsx(Heading, {
4303
- id: id,
4304
- className: classNames(`np-text-${type}`, 'text-primary', className),
4305
- children: children
4306
- });
4307
- }
4308
-
4309
4887
  const DropFade = ({
4310
4888
  children,
4311
4889
  show
@@ -4873,6 +5451,84 @@ const FlowNavigation = ({
4873
5451
  });
4874
5452
  };
4875
5453
 
5454
+ function InlineAlert({
5455
+ id,
5456
+ type = 'neutral',
5457
+ className,
5458
+ children
5459
+ }) {
5460
+ const danger = type === 'negative' || type === 'error';
5461
+ return /*#__PURE__*/jsxs("div", {
5462
+ role: "alert",
5463
+ id: id,
5464
+ className: classNames('alert alert-detach', `alert-${danger ? 'danger' : type}`, className),
5465
+ children: [danger && /*#__PURE__*/jsx(AlertCircle, {}), /*#__PURE__*/jsx("div", {
5466
+ children: children
5467
+ })]
5468
+ });
5469
+ }
5470
+
5471
+ const Label = ({
5472
+ id,
5473
+ htmlFor,
5474
+ className,
5475
+ children
5476
+ }) => {
5477
+ return /*#__PURE__*/jsx("label", {
5478
+ id: id,
5479
+ htmlFor: htmlFor,
5480
+ className: classNames('control-label d-flex flex-column gap-y-1 m-b-0', className),
5481
+ children: children
5482
+ });
5483
+ };
5484
+
5485
+ const Field = ({
5486
+ id,
5487
+ label,
5488
+ hint,
5489
+ error,
5490
+ className,
5491
+ children
5492
+ }) => {
5493
+ const hasError = Boolean(error);
5494
+ const hasHint = Boolean(hint) && !hasError;
5495
+ const labelId = useId();
5496
+ const fallbackInputId = useId(); // TODO: Use `React.useId()` when react>=18
5497
+ const inputId = id !== null ? id ?? fallbackInputId : undefined;
5498
+ const descriptionId = useId(); // TODO: Use `React.useId()` when react>=18
5499
+ return /*#__PURE__*/jsx(FieldLabelIdContextProvider, {
5500
+ value: labelId,
5501
+ children: /*#__PURE__*/jsx(InputIdContextProvider, {
5502
+ value: inputId,
5503
+ children: /*#__PURE__*/jsx(InputDescribedByProvider, {
5504
+ value: hasError || hasHint ? descriptionId : undefined,
5505
+ children: /*#__PURE__*/jsx(InputInvalidProvider, {
5506
+ value: hasError,
5507
+ children: /*#__PURE__*/jsxs("div", {
5508
+ className: classNames('form-group d-block', {
5509
+ 'has-error': hasError,
5510
+ 'has-info': hasHint
5511
+ }, className),
5512
+ children: [/*#__PURE__*/jsxs(Label, {
5513
+ id: labelId,
5514
+ htmlFor: inputId,
5515
+ children: [label, children]
5516
+ }), hasHint && /*#__PURE__*/jsx(InlineAlert, {
5517
+ type: Sentiment.NEUTRAL,
5518
+ id: descriptionId,
5519
+ children: hint
5520
+ }), hasError && /*#__PURE__*/jsx(InlineAlert, {
5521
+ type: Sentiment.NEGATIVE,
5522
+ id: descriptionId,
5523
+ children: error
5524
+ })]
5525
+ })
5526
+ })
5527
+ })
5528
+ })
5529
+ });
5530
+ };
5531
+
4876
5532
  const HeaderAction = ({
4877
5533
  action
4878
5534
  }) => {
@@ -4940,45 +5596,6 @@ const Header = ({
4940
5596
  });
4941
5597
  };
4942
5598
 
4943
- const EmptyTransparentImage = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
4944
- const Image = ({
4945
- id,
4946
- src,
4947
- alt,
4948
- onLoad,
4949
- onError,
4950
- className,
4951
- loading,
4952
- stretch = true,
4953
- role,
4954
- shrink = true
4955
- }) => {
4956
- const elementReference = useRef(null);
4957
- const [hasIntersected] = useHasIntersected({
4958
- elRef: elementReference,
4959
- loading
4960
- });
4961
- let imageSource = src;
4962
- let imageOnLoad = onLoad;
4963
- if (loading === 'lazy' && !hasIntersected) {
4964
- imageSource = EmptyTransparentImage;
4965
- imageOnLoad = undefined;
4966
- }
4967
- return /*#__PURE__*/jsx("img", {
4968
- ref: elementReference,
4969
- id: id,
4970
- alt: alt,
4971
- src: imageSource,
4972
- className: classNames(['tw-image', {
4973
- 'tw-image__stretch': stretch,
4974
- 'tw-image__shrink': shrink
4975
- }, className]),
4976
- role: role,
4977
- onLoad: imageOnLoad,
4978
- onError: onError
4979
- });
4980
- };
4981
-
4982
5599
  // TODO: consider to move this enum into component file once we migrate it on TypeScript or replace with some common enum
4983
5600
  var InfoPresentation;
4984
5601
  (function (InfoPresentation) {
@@ -5205,20 +5822,16 @@ const Info = ({
5205
5822
  });
5206
5823
  };
5207
5824
 
5208
- function InlineAlert({
5209
- id,
5210
- type = 'neutral',
5211
- className,
5212
- children
5213
- }) {
5214
- const danger = type === 'negative' || type === 'error';
5215
- return /*#__PURE__*/jsxs("div", {
5216
- role: "alert",
5217
- id: id,
5218
- className: classNames('alert alert-detach', `alert-${danger ? 'danger' : type}`, className),
5219
- children: [danger && /*#__PURE__*/jsx(AlertCircle, {}), /*#__PURE__*/jsx("div", {
5220
- children: children
5221
- })]
5825
+ function inputClassNameBase({
5826
+ size = 'auto'
5827
+ } = {}) {
5828
+ return classNames('form-control',
5829
+ // TODO: Deprecate
5830
+ 'np-form-control', {
5831
+ 'np-form-control--size-auto': size === 'auto',
5832
+ 'np-form-control--size-sm': size === 'sm',
5833
+ 'np-form-control--size-md': size === 'md',
5834
+ 'np-form-control--size-lg': size === 'lg'
5222
5835
  });
5223
5836
  }
5224
5837
 
@@ -5340,29 +5953,17 @@ function InputAddon({
5340
5953
  });
5341
5954
  }
5342
5955
 
5343
- function formControlClassNameBase({
5344
- size = 'auto'
5345
- } = {}) {
5346
- return classNames('form-control',
5347
- // TODO: Deprecate
5348
- 'np-form-control', {
5349
- 'np-form-control--size-auto': size === 'auto',
5350
- 'np-form-control--size-sm': size === 'sm',
5351
- 'np-form-control--size-md': size === 'md',
5352
- 'np-form-control--size-lg': size === 'lg'
5353
- });
5354
- }
5355
-
5356
5956
  const Input = /*#__PURE__*/forwardRef(function Input({
5357
5957
  size = 'auto',
5358
5958
  shape = 'rectangle',
5359
5959
  className,
5360
5960
  ...restProps
5361
5961
  }, reference) {
5962
+ const inputAttributes = useInputAttributes();
5362
5963
  const inputPaddings = useInputPaddings();
5363
5964
  return /*#__PURE__*/jsx("input", {
5364
5965
  ref: reference,
5365
- className: classNames(className, formControlClassNameBase({
5966
+ className: classNames(className, inputClassNameBase({
5366
5967
  size
5367
5968
  }), 'np-input', {
5368
5969
  'np-input--shape-rectangle': shape === 'rectangle',
@@ -5371,6 +5972,7 @@ const Input = /*#__PURE__*/forwardRef(function Input({
5371
5972
  // eslint-disable-next-line react/forbid-dom-props
5372
5973
  ,
5373
5974
  style: inputPaddings,
5975
+ ...inputAttributes,
5374
5976
  ...restProps
5375
5977
  });
5376
5978
  });
@@ -5792,12 +6394,6 @@ const PolymorphicWithOverrides = /*#__PURE__*/forwardRef(function PolymorphicWit
5792
6394
  });
5793
6395
  });
5794
6396
 
5795
- var messages$5 = defineMessages({
5796
- noResultsFound: {
5797
- id: "neptune.SelectInput.noResultsFound"
5798
- }
5799
- });
5800
-
5801
6397
  function PreventScroll() {
5802
6398
  usePreventScroll();
5803
6399
  return null;
@@ -5917,7 +6513,7 @@ const ButtonInput = /*#__PURE__*/forwardRef(function ButtonInput({
5917
6513
  return /*#__PURE__*/jsx("button", {
5918
6514
  ref: ref,
5919
6515
  type: "button",
5920
- className: classNames(className, formControlClassNameBase({
6516
+ className: classNames(className, inputClassNameBase({
5921
6517
  size
5922
6518
  }), 'np-button-input')
5923
6519
  // eslint-disable-next-line react/forbid-dom-props
@@ -6033,6 +6629,12 @@ function Popover({
6033
6629
  });
6034
6630
  }
6035
6631
 
6632
+ var messages$5 = defineMessages({
6633
+ noResultsFound: {
6634
+ id: "neptune.SelectInput.noResultsFound"
6635
+ }
6636
+ });
6637
+
6036
6638
  function searchableString(value) {
6037
6639
  return value.trim().replace(/\s+/gu, ' ').normalize('NFKC').toLowerCase();
6038
6640
  }
@@ -6152,7 +6754,7 @@ function SelectInputClearButton({
6152
6754
  }
6153
6755
  const noop = () => {};
6154
6756
  function SelectInput({
6155
- id,
6757
+ id: idProp,
6156
6758
  name,
6157
6759
  multiple,
6158
6760
  placeholder,
@@ -6173,6 +6775,8 @@ function SelectInput({
6173
6775
  onClose,
6174
6776
  onClear
6175
6777
  }) {
6778
+ const inputAttributes = useInputAttributes();
6779
+ const id = idProp ?? inputAttributes.id;
6176
6780
  const [open, setOpen] = useState(false);
6177
6781
  const initialized = useRef(false);
6178
6782
  const handleClose = useEffectEvent(onClose ?? (() => {}));
@@ -6233,6 +6837,7 @@ function SelectInput({
6233
6837
  ref(node);
6234
6838
  triggerRef.current = node;
6235
6839
  },
6840
+ ...inputAttributes,
6236
6841
  id,
6237
6842
  ...mergeProps({
6238
6843
  onClick: () => {
@@ -6586,9 +7191,11 @@ const TextArea = /*#__PURE__*/forwardRef(function TextArea({
6586
7191
  className,
6587
7192
  ...restProps
6588
7193
  }, reference) {
7194
+ const inputAttributes = useInputAttributes();
6589
7195
  return /*#__PURE__*/jsx("textarea", {
6590
7196
  ref: reference,
6591
- className: classNames(className, formControlClassNameBase(), 'np-text-area'),
7197
+ className: classNames(className, inputClassNameBase(), 'np-text-area'),
7198
+ ...inputAttributes,
6592
7199
  ...restProps
6593
7200
  });
6594
7201
  });
@@ -8705,6 +9312,12 @@ const PhoneNumberInput = ({
8705
9312
  return explodeNumberModel(cleanValue);
8706
9313
  });
8707
9314
  const [broadcastedValue, setBroadcastedValue] = useState(null);
9315
+ const [suffixDirty, setSuffixDirty] = useState(false);
9316
+ useEffect(() => {
9317
+ if (internalValue.suffix) {
9318
+ setSuffixDirty(true);
9319
+ }
9320
+ }, [internalValue.suffix]);
8708
9321
  const countriesByPrefix = useMemo(() => groupCountriesByPrefix(sortArrayByProperty(excludeCountries(countries, disabledCountries), 'iso3')), [disabledCountries]);
8709
9322
  const onSuffixChange = event => {
8710
9323
  const suffix = event.target.value;
@@ -8768,6 +9381,11 @@ const PhoneNumberInput = ({
8768
9381
  format: country?.phoneFormat
8769
9382
  }));
8770
9383
  },
9384
+ onClose: () => {
9385
+ if (suffixDirty) {
9386
+ onBlur?.();
9387
+ }
9388
+ },
8771
9389
  ...selectProps
8772
9390
  })
8773
9391
  }), /*#__PURE__*/jsx("div", {
@@ -8787,7 +9405,7 @@ const PhoneNumberInput = ({
8787
9405
  onChange: onSuffixChange,
8788
9406
  onPaste: onPaste,
8789
9407
  onFocus: onFocus,
8790
- onBlur: onBlur
9408
+ onBlur: () => onBlur?.()
8791
9409
  })
8792
9410
  })
8793
9411
  })]
@@ -8847,227 +9465,6 @@ const ProgressBar = ({
8847
9465
  });
8848
9466
  };
8849
9467
 
8850
- const defaultPromoCardContext = {
8851
- state: '',
8852
- isDisabled: false,
8853
- // eslint-disable-next-line @typescript-eslint/no-empty-function
8854
- onChange: () => {}
8855
- };
8856
- /**
8857
- * The PromoCard context object.
8858
- */
8859
- const PromoCardContext = /*#__PURE__*/createContext(defaultPromoCardContext);
8860
- /**
8861
- * A custom hook for accessing the PromoCard context object.
8862
- *
8863
- * The `usePromoCardContext` hook is used to access the PromoCard context object
8864
- * from within a child PromoCard component. It throws an error if the context
8865
- * object is not available, which can help with debugging and development.
8866
- *
8867
- * @returns {PromoCardContextType} - The PromoCard context object.
8868
- */
8869
- const usePromoCardContext = () => {
8870
- return useContext(PromoCardContext);
8871
- };
8872
-
8873
- const PromoCardIndicator = ({
8874
- className,
8875
- children,
8876
- label,
8877
- icon,
8878
- isSmall = false,
8879
- testid,
8880
- ...rest
8881
- }) => {
8882
- const isIconString = icon && typeof icon === 'string';
8883
- const IconComponent = isIconString && {
8884
- check: Check,
8885
- arrow: ArrowRight,
8886
- download: Download
8887
- }[icon];
8888
- return /*#__PURE__*/jsxs("div", {
8889
- className: classNames('np-Card-indicator', className),
8890
- "data-testid": testid,
8891
- ...rest,
8892
- children: [label && /*#__PURE__*/jsx(Body, {
8893
- as: "span",
8894
- type: Typography.BODY_LARGE_BOLD,
8895
- className: "np-Card-indicatorText",
8896
- children: label
8897
- }), icon && /*#__PURE__*/jsx(Avatar, {
8898
- type: AvatarType.ICON,
8899
- size: isSmall ? 40 : 56,
8900
- backgroundColor: "var(--Card-indicator-icon-background-color)",
8901
- className: "np-Card-indicatorIcon",
8902
- children: IconComponent ? /*#__PURE__*/jsx(IconComponent, {
8903
- size: 24,
8904
- "aria-hidden": "true"
8905
- }) : icon
8906
- }), children]
8907
- });
8908
- };
8909
-
8910
- const PromoCard = /*#__PURE__*/forwardRef(({
8911
- className,
8912
- description,
8913
- defaultChecked,
8914
- download,
8915
- href,
8916
- hrefLang,
8917
- id,
8918
- headingLevel = 'h3',
8919
- imageAlt,
8920
- imageClass,
8921
- imageSource,
8922
- indicatorLabel,
8923
- indicatorIcon,
8924
- isChecked,
8925
- isDisabled,
8926
- onClick,
8927
- rel,
8928
- tabIndex,
8929
- target,
8930
- testId,
8931
- title,
8932
- type,
8933
- value,
8934
- isSmall,
8935
- useDisplayFont = true,
8936
- ...props
8937
- }, reference) => {
8938
- // Set the `checked` state to the value of `defaultChecked` if it is truthy,
8939
- // or the value of `isChecked` if it is truthy, or `false` if neither
8940
- // is truthy.
8941
- const {
8942
- state,
8943
- onChange,
8944
- isDisabled: contextIsDisabled
8945
- } = usePromoCardContext();
8946
- const [checked, setChecked] = useState(type === 'checkbox' ? defaultChecked ?? isChecked ?? false : false);
8947
- const handleClick = () => {
8948
- if (type === 'radio') {
8949
- onChange(value || ''); // Update the context state for radio
8950
- } else if (type === 'checkbox') {
8951
- setChecked(!checked); // Update local state for checkbox
8952
- }
8953
- };
8954
- const fallbackId = useId();
8955
- const componentId = id || fallbackId;
8956
- // Set the icon to `'arrow'` if `href` is truthy and `type` is falsy, or
8957
- // `'download'` if `download` is truthy. If neither condition is true, set
8958
- // `icon` to `undefined`.
8959
- // Create a function to get icon type
8960
- const getIconType = () => {
8961
- if (indicatorIcon) {
8962
- return indicatorIcon;
8963
- }
8964
- if (download) {
8965
- return 'download';
8966
- }
8967
- if (href && !type) {
8968
- return 'arrow';
8969
- }
8970
- return undefined;
8971
- };
8972
- // Define all class names string based on the values of the `href`, `type`,
8973
- // `checked`, and `className` props.
8974
- const commonClasses = classNames({
8975
- 'np-Card--promoCard': true,
8976
- 'np-Card--checked': !href && type,
8977
- 'np-Card--link': href && !type,
8978
- 'is-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined
8979
- }, className);
8980
- // Object with common props that will be passed to the `Card` components
8981
- const commonProps = {
8982
- className: commonClasses,
8983
- id: componentId,
8984
- isDisabled: isDisabled || contextIsDisabled,
8985
- onClick,
8986
- ref: reference,
8987
- 'data-testid': testId,
8988
- isSmall
8989
- };
8990
- // Object with Anchor props that will be passed to the `a` element. These
8991
- // won't be refurned if set to `isDisabled`
8992
- const anchorProps = href && !isDisabled ? {
8993
- download,
8994
- href: href || undefined,
8995
- hrefLang,
8996
- rel,
8997
- target
8998
- } : {};
8999
- // Object of all Checked props that will be passed to the root `Card` component
9000
- const checkedProps = (type === 'checkbox' || type === 'radio') && !href ? {
9001
- ...commonProps,
9002
- 'aria-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined,
9003
- 'aria-describedby': `${componentId}-title`,
9004
- 'aria-disabled': isDisabled,
9005
- 'data-value': value ?? undefined,
9006
- role: type === 'checkbox' || type === 'radio' ? type : undefined,
9007
- onClick: handleClick,
9008
- onKeyDown: event => {
9009
- if (event.key === 'Enter' || event.key === ' ') {
9010
- handleClick();
9011
- }
9012
- },
9013
- ref: reference,
9014
- tabIndex: 0
9015
- } : {};
9016
- const getTitle = () => {
9017
- const titleContent = href && !type ? /*#__PURE__*/jsx("a", {
9018
- className: "np-Card-titleLink",
9019
- ...anchorProps,
9020
- children: title
9021
- }) : title;
9022
- const titleProps = {
9023
- id: `${componentId}-title`,
9024
- as: headingLevel,
9025
- className: 'np-Card-title'
9026
- };
9027
- return useDisplayFont ? /*#__PURE__*/jsx(Display, {
9028
- type: Typography.DISPLAY_SMALL,
9029
- ...titleProps,
9030
- children: titleContent
9031
- }) : /*#__PURE__*/jsx(Title, {
9032
- type: Typography.TITLE_SUBSECTION,
9033
- ...titleProps,
9034
- children: titleContent
9035
- });
9036
- };
9037
- useEffect(() => {
9038
- setChecked(defaultChecked ?? isChecked ?? false);
9039
- }, [defaultChecked, isChecked]);
9040
- return /*#__PURE__*/jsxs(Card, {
9041
- ...commonProps,
9042
- ...checkedProps,
9043
- ...props,
9044
- children: [(value === state || checked) && /*#__PURE__*/jsx("span", {
9045
- className: "np-Card-check",
9046
- children: /*#__PURE__*/jsx(Check, {
9047
- size: 24,
9048
- "aria-hidden": "true"
9049
- })
9050
- }), getTitle(), /*#__PURE__*/jsx(Body, {
9051
- className: "np-Card-description",
9052
- children: description
9053
- }), imageSource && /*#__PURE__*/jsx("div", {
9054
- className: classNames('np-Card-image', {
9055
- imageClass
9056
- }),
9057
- children: /*#__PURE__*/jsx(Image, {
9058
- src: imageSource,
9059
- alt: imageAlt || '',
9060
- loading: "lazy"
9061
- })
9062
- }), /*#__PURE__*/jsx(PromoCardIndicator, {
9063
- label: indicatorLabel,
9064
- icon: getIconType(),
9065
- isSmall: isSmall
9066
- })]
9067
- });
9068
- });
9069
- var PromoCard$1 = /*#__PURE__*/React__default.memo(PromoCard);
9070
-
9071
9468
  const PromoCardGroup = ({
9072
9469
  children,
9073
9470
  className,
@@ -9334,9 +9731,13 @@ function RadioGroup({
9334
9731
  selectedValue: controlledValue,
9335
9732
  onChange
9336
9733
  }) {
9734
+ const inputAttributes = useInputAttributes({
9735
+ nonLabelable: true
9736
+ });
9337
9737
  const [uncontrolledValue, setUncontrolledValue] = useState(controlledValue);
9338
9738
  return radios.length > 0 ? /*#__PURE__*/jsx("div", {
9339
9739
  role: "radiogroup",
9740
+ ...inputAttributes,
9340
9741
  children: radios.map(({
9341
9742
  value = '',
9342
9743
  ...restProps
@@ -10448,13 +10849,18 @@ const Summary = ({
10448
10849
  };
10449
10850
 
10450
10851
  const Switch = props => {
10852
+ const inputAttributes = useInputAttributes({
10853
+ nonLabelable: true
10854
+ });
10451
10855
  const {
10452
10856
  isModern
10453
10857
  } = useTheme();
10454
10858
  const {
10455
10859
  checked,
10456
10860
  className,
10457
- id,
10861
+ id = inputAttributes.id,
10862
+ 'aria-label': ariaLabel,
10863
+ 'aria-labelledby': ariaLabelledbyProp,
10458
10864
  onClick,
10459
10865
  disabled
10460
10866
  } = props;
@@ -10485,19 +10891,18 @@ const Switch = props => {
10485
10891
  })
10486
10892
  });
10487
10893
  };
10488
- const ariaLabel = props['aria-label'];
10489
- const ariaLabelledby = ariaLabel ? undefined : props['aria-labelledby'];
10490
- logActionRequiredIf('Switch now expects either `aria-label` or `aria-labelledby`, and will soon make these props required. Please update your usage to provide one or the other.', !ariaLabel && !ariaLabelledby);
10894
+ const ariaLabelledby = (ariaLabel ? undefined : ariaLabelledbyProp) ?? inputAttributes['aria-labelledby'];
10491
10895
  return /*#__PURE__*/jsxs("span", {
10492
10896
  className: classNames('np-switch', {
10493
10897
  'np-switch--unchecked': !checked,
10494
10898
  'np-switch--checked': checked,
10495
- disabled: disabled
10899
+ disabled
10496
10900
  }, className),
10497
10901
  tabIndex: 0,
10498
10902
  role: "switch",
10499
10903
  "aria-checked": checked,
10500
10904
  "aria-label": ariaLabel,
10905
+ ...inputAttributes,
10501
10906
  "aria-labelledby": ariaLabelledby,
10502
10907
  id: id,
10503
10908
  "aria-disabled": disabled,
@@ -14353,5 +14758,5 @@ const translations = {
14353
14758
  'zh-HK': zhHK
14354
14759
  };
14355
14760
 
14356
- export { Accordion, ActionButton, ActionOption, Alert, AlertArrowPosition, Avatar, AvatarType, AvatarWrapper, Badge, Card as BaseCard, Body, BottomSheet$1 as BottomSheet, Breakpoint, Button, Card$2 as Card, Checkbox, CheckboxButton$1 as CheckboxButton, CheckboxOption, Chevron, Chip, Chips, CircularButton, ControlType, CriticalCommsBanner, DEFAULT_LANG, DEFAULT_LOCALE, DateInput, DateLookup, DateMode, Decision, DecisionPresentation, DecisionType, DefinitionList$1 as DefinitionList, Dimmer$1 as Dimmer, Direction, DirectionProvider, Display, Drawer$1 as Drawer, DropFade, Emphasis, FileType, FlowNavigation, Header, Image, Info, InfoPresentation, InlineAlert, Input, InputGroup, InputWithDisplayFormat, InstructionsList, LanguageProvider, Layout, Link, ListItem$1 as ListItem, Loader, Logo$1 as Logo, LogoType, Markdown, MarkdownNodeType, Modal, Money, MoneyInput$1 as MoneyInput, MonthFormat, NavigationOption, NavigationOptionList as NavigationOptionsList, Nudge, Option$2 as Option, OverlayHeader$1 as OverlayHeader, PhoneNumberInput, Popover$1 as Popover, Position, Priority, ProcessIndicator$1 as ProcessIndicator, ProfileType, Progress, ProgressBar, PromoCard$1 as PromoCard, PromoCardGroup$1 as PromoCardGroup, Provider, RTL_LANGUAGES, Radio, RadioGroup, RadioOption, SUPPORTED_LANGUAGES, Scroll, SearchInput, Section, SegmentedControl, Select, SelectInput, SelectInputOptionContent, SelectInputTriggerButton, Sentiment, Size, SlidingPanel, SnackbarConsumer, SnackbarContext, SnackbarPortal, SnackbarProvider, Status, StatusIcon, Stepper, Sticky, Summary, Switch, SwitchOption, Tabs$1 as Tabs, TextArea, TextareaWithDisplayFormat, Theme, Title, Tooltip, Type, Typeahead, Typography, Upload$1 as Upload, UploadInput, UploadStep, Variant, Width, adjustLocale, getCountryFromLocale, getDirectionFromLocale, getLangFromLocale, isBrowser, isServerSide, translations, useDirection, useLayout, useScreenSize, useSnackbar };
14761
+ export { Accordion, ActionButton, ActionOption, Alert, AlertArrowPosition, Avatar, AvatarType, AvatarWrapper, Badge, Card$2 as BaseCard, Body, BottomSheet$1 as BottomSheet, Breakpoint, Button, Card$1 as Card, Carousel, Checkbox, CheckboxButton$1 as CheckboxButton, CheckboxOption, Chevron, Chip, Chips, CircularButton, ControlType, CriticalCommsBanner, DEFAULT_LANG, DEFAULT_LOCALE, DateInput, DateLookup$1 as DateLookup, DateMode, Decision, DecisionPresentation, DecisionType, DefinitionList$1 as DefinitionList, Dimmer$1 as Dimmer, Direction, DirectionProvider, Display, Drawer$1 as Drawer, DropFade, Emphasis, Field, FileType, FlowNavigation, Header, Image, Info, InfoPresentation, InlineAlert, Input, InputGroup, InputWithDisplayFormat, InstructionsList, Label, LanguageProvider, Layout, Link, ListItem$1 as ListItem, Loader, Logo$1 as Logo, LogoType, Markdown, MarkdownNodeType, Modal, Money, MoneyInput$1 as MoneyInput, MonthFormat, NavigationOption, NavigationOptionList as NavigationOptionsList, Nudge, Option$2 as Option, OverlayHeader$1 as OverlayHeader, PhoneNumberInput, Popover$1 as Popover, Position, Priority, ProcessIndicator$1 as ProcessIndicator, ProfileType, Progress, ProgressBar, PromoCard$1 as PromoCard, PromoCardGroup$1 as PromoCardGroup, Provider, RTL_LANGUAGES, Radio, RadioGroup, RadioOption, SUPPORTED_LANGUAGES, Scroll, SearchInput, Section, SegmentedControl, Select, SelectInput, SelectInputOptionContent, SelectInputTriggerButton, Sentiment, Size, SlidingPanel, SnackbarConsumer, SnackbarContext, SnackbarPortal, SnackbarProvider, Status, StatusIcon, Stepper, Sticky, Summary, Switch, SwitchOption, Tabs$1 as Tabs, TextArea, TextareaWithDisplayFormat, Theme, Title, Tooltip, Type, Typeahead, Typography, Upload$1 as Upload, UploadInput, UploadStep, Variant, Width, adjustLocale, getCountryFromLocale, getDirectionFromLocale, getLangFromLocale, isBrowser, isServerSide, translations, useDirection, useLayout, useScreenSize, useSnackbar };
14357
14762
  //# sourceMappingURL=index.mjs.map