@transferwise/components 46.31.0 → 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.
- package/build/index.js +742 -467
- package/build/index.js.map +1 -1
- package/build/index.mjs +742 -468
- package/build/index.mjs.map +1 -1
- package/build/main.css +135 -0
- package/build/styles/carousel/Carousel.css +135 -0
- package/build/styles/main.css +135 -0
- package/build/types/carousel/Carousel.d.ts +26 -0
- package/build/types/carousel/Carousel.d.ts.map +1 -0
- package/build/types/carousel/index.d.ts +3 -0
- package/build/types/carousel/index.d.ts.map +1 -0
- package/build/types/common/card/Card.d.ts +2 -2
- package/build/types/common/card/Card.d.ts.map +1 -1
- package/build/types/index.d.ts +2 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/types/promoCard/PromoCard.d.ts +16 -5
- package/build/types/promoCard/PromoCard.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/carousel/Carousel.css +135 -0
- package/src/carousel/Carousel.less +133 -0
- package/src/carousel/Carousel.spec.tsx +221 -0
- package/src/carousel/Carousel.story.tsx +63 -0
- package/src/carousel/Carousel.tsx +345 -0
- package/src/carousel/index.ts +3 -0
- package/src/common/card/Card.tsx +51 -43
- package/src/index.ts +2 -0
- package/src/main.css +135 -0
- package/src/main.less +1 -0
- package/src/promoCard/PromoCard.story.tsx +2 -2
- package/src/promoCard/PromoCard.tsx +30 -9
package/build/index.js
CHANGED
|
@@ -1510,7 +1510,717 @@ const Button = /*#__PURE__*/React.forwardRef(({
|
|
|
1510
1510
|
});
|
|
1511
1511
|
});
|
|
1512
1512
|
|
|
1513
|
-
const Card$
|
|
1513
|
+
const Card$2 = /*#__PURE__*/React.forwardRef(({
|
|
1514
|
+
className,
|
|
1515
|
+
children = null,
|
|
1516
|
+
id,
|
|
1517
|
+
isDisabled = false,
|
|
1518
|
+
isSmall = false,
|
|
1519
|
+
onDismiss,
|
|
1520
|
+
testId,
|
|
1521
|
+
...props
|
|
1522
|
+
}, ref) => {
|
|
1523
|
+
const closeButtonReference = React.useRef(null);
|
|
1524
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
1525
|
+
ref: ref,
|
|
1526
|
+
className: classNames__default.default('np-Card', {
|
|
1527
|
+
'np-Card--small': !!isSmall,
|
|
1528
|
+
'is-disabled': !!isDisabled
|
|
1529
|
+
}, className),
|
|
1530
|
+
id: id,
|
|
1531
|
+
"data-testid": testId,
|
|
1532
|
+
...props,
|
|
1533
|
+
children: [onDismiss && /*#__PURE__*/jsxRuntime.jsx(CloseButton, {
|
|
1534
|
+
ref: closeButtonReference,
|
|
1535
|
+
className: "np-Card-closeButton",
|
|
1536
|
+
size: isSmall ? 'sm' : 'md',
|
|
1537
|
+
isDisabled: isDisabled,
|
|
1538
|
+
testId: "close-button",
|
|
1539
|
+
onClick: e => {
|
|
1540
|
+
stopPropagation$1(e);
|
|
1541
|
+
onDismiss();
|
|
1542
|
+
}
|
|
1543
|
+
}), children]
|
|
1544
|
+
});
|
|
1545
|
+
});
|
|
1546
|
+
Card$2.displayName = 'Card';
|
|
1547
|
+
|
|
1548
|
+
function Display({
|
|
1549
|
+
as: Heading = 'h1',
|
|
1550
|
+
type = exports.Typography.DISPLAY_LARGE,
|
|
1551
|
+
children,
|
|
1552
|
+
className,
|
|
1553
|
+
id
|
|
1554
|
+
}) {
|
|
1555
|
+
return /*#__PURE__*/jsxRuntime.jsx(Heading, {
|
|
1556
|
+
id: id,
|
|
1557
|
+
className: classNames__default.default(`np-text-${type}`, 'text-primary', className),
|
|
1558
|
+
children: children
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
const useConditionalListener = ({
|
|
1563
|
+
attachListener,
|
|
1564
|
+
callback,
|
|
1565
|
+
eventType,
|
|
1566
|
+
parent
|
|
1567
|
+
}) => {
|
|
1568
|
+
React.useEffect(() => {
|
|
1569
|
+
if (attachListener && !neptuneValidation.isUndefined(parent)) {
|
|
1570
|
+
parent.addEventListener(eventType, callback, true);
|
|
1571
|
+
}
|
|
1572
|
+
return () => {
|
|
1573
|
+
if (!neptuneValidation.isUndefined(parent)) {
|
|
1574
|
+
parent.removeEventListener(eventType, callback, true);
|
|
1575
|
+
}
|
|
1576
|
+
};
|
|
1577
|
+
}, [attachListener, callback, eventType, parent]);
|
|
1578
|
+
};
|
|
1579
|
+
|
|
1580
|
+
const DirectionContext = /*#__PURE__*/React.createContext(exports.Direction.LTR);
|
|
1581
|
+
const DirectionProvider = ({
|
|
1582
|
+
direction,
|
|
1583
|
+
children
|
|
1584
|
+
}) => {
|
|
1585
|
+
return /*#__PURE__*/jsxRuntime.jsx(DirectionContext.Provider, {
|
|
1586
|
+
value: direction,
|
|
1587
|
+
children: children
|
|
1588
|
+
});
|
|
1589
|
+
};
|
|
1590
|
+
|
|
1591
|
+
const useDirection = () => {
|
|
1592
|
+
const direction = React.useContext(DirectionContext);
|
|
1593
|
+
return {
|
|
1594
|
+
direction,
|
|
1595
|
+
isRTL: direction === 'rtl'
|
|
1596
|
+
};
|
|
1597
|
+
};
|
|
1598
|
+
|
|
1599
|
+
const ObserverParams = {
|
|
1600
|
+
threshold: 0.1
|
|
1601
|
+
};
|
|
1602
|
+
|
|
1603
|
+
/**
|
|
1604
|
+
* useHasIntersected.
|
|
1605
|
+
* Use this custom hook to detect when an element has became visible inside the viewport. This hook checks only if the intersection happend.
|
|
1606
|
+
* Once the intersection has happened the hook will not return false even if the element gets out of the viewport.
|
|
1607
|
+
*
|
|
1608
|
+
* @param elRef.elRef
|
|
1609
|
+
* @param {object} [elRef] - node object that contains a react reference to the element that needs to be observed.
|
|
1610
|
+
* @param {strimng} [loading = 'eager'] - string that contains the type of loading.
|
|
1611
|
+
* @param elRef.loading
|
|
1612
|
+
* @usage `const [hasIntersected] = useHasIntersected({imageRef,loading});`
|
|
1613
|
+
*/
|
|
1614
|
+
const useHasIntersected = ({
|
|
1615
|
+
elRef,
|
|
1616
|
+
loading
|
|
1617
|
+
}) => {
|
|
1618
|
+
const [hasIntersected, setHasIntersected] = React.useState(false);
|
|
1619
|
+
const {
|
|
1620
|
+
current
|
|
1621
|
+
} = elRef || {};
|
|
1622
|
+
const isValidReference = () => {
|
|
1623
|
+
return elRef && current;
|
|
1624
|
+
};
|
|
1625
|
+
const handleOnIntersect = (entries, observer) => {
|
|
1626
|
+
entries.forEach(entry => {
|
|
1627
|
+
if (entry.isIntersecting) {
|
|
1628
|
+
setHasIntersected(true);
|
|
1629
|
+
observer.unobserve(current);
|
|
1630
|
+
}
|
|
1631
|
+
});
|
|
1632
|
+
};
|
|
1633
|
+
React.useEffect(() => {
|
|
1634
|
+
let observer;
|
|
1635
|
+
let didCancel = false;
|
|
1636
|
+
|
|
1637
|
+
// Check if window is define for SSR and Old browsers fallback
|
|
1638
|
+
if (typeof window === 'undefined' || !window.IntersectionObserver || !isValidReference()) {
|
|
1639
|
+
setHasIntersected(true);
|
|
1640
|
+
} else if (!didCancel) {
|
|
1641
|
+
observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
|
|
1642
|
+
observer.observe(current);
|
|
1643
|
+
}
|
|
1644
|
+
return () => {
|
|
1645
|
+
didCancel = true;
|
|
1646
|
+
if (observer) {
|
|
1647
|
+
observer.unobserve(current);
|
|
1648
|
+
}
|
|
1649
|
+
};
|
|
1650
|
+
}, [elRef]);
|
|
1651
|
+
if (loading === 'eager') {
|
|
1652
|
+
return [false];
|
|
1653
|
+
}
|
|
1654
|
+
return [hasIntersected];
|
|
1655
|
+
};
|
|
1656
|
+
|
|
1657
|
+
// eslint-disable-next-line import/extensions
|
|
1658
|
+
function useMedia(query) {
|
|
1659
|
+
return index_js.useSyncExternalStore(onStoreChange => {
|
|
1660
|
+
const mediaQueryList = window.matchMedia(query);
|
|
1661
|
+
mediaQueryList.addEventListener('change', onStoreChange);
|
|
1662
|
+
return () => {
|
|
1663
|
+
mediaQueryList.removeEventListener('change', onStoreChange);
|
|
1664
|
+
};
|
|
1665
|
+
}, () => typeof window !== 'undefined' ? window.matchMedia(query).matches : undefined, () => undefined);
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
function useScreenSize(size) {
|
|
1669
|
+
return useMedia(`(min-width: ${size}px)`);
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
/**
|
|
1673
|
+
* @deprecated Prefer `useScreenSize` instead.
|
|
1674
|
+
*/
|
|
1675
|
+
const useLayout = () => {
|
|
1676
|
+
const screenXs = useScreenSize(exports.Breakpoint.EXTRA_SMALL);
|
|
1677
|
+
const screenSm = useScreenSize(exports.Breakpoint.SMALL);
|
|
1678
|
+
const screenMd = useScreenSize(exports.Breakpoint.MEDIUM);
|
|
1679
|
+
const screenLg = useScreenSize(exports.Breakpoint.LARGE);
|
|
1680
|
+
const screenXl = useScreenSize(exports.Breakpoint.EXTRA_LARGE);
|
|
1681
|
+
return {
|
|
1682
|
+
isMobile: screenSm != null ? !screenSm : undefined,
|
|
1683
|
+
isExtraSmall: screenXs,
|
|
1684
|
+
isSmall: screenSm,
|
|
1685
|
+
isMedium: screenMd,
|
|
1686
|
+
isLarge: screenLg,
|
|
1687
|
+
isExtraLarge: screenXl
|
|
1688
|
+
};
|
|
1689
|
+
};
|
|
1690
|
+
|
|
1691
|
+
const EmptyTransparentImage = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
|
|
1692
|
+
const Image = ({
|
|
1693
|
+
id,
|
|
1694
|
+
src,
|
|
1695
|
+
alt,
|
|
1696
|
+
onLoad,
|
|
1697
|
+
onError,
|
|
1698
|
+
className,
|
|
1699
|
+
loading,
|
|
1700
|
+
stretch = true,
|
|
1701
|
+
role,
|
|
1702
|
+
shrink = true
|
|
1703
|
+
}) => {
|
|
1704
|
+
const elementReference = React.useRef(null);
|
|
1705
|
+
const [hasIntersected] = useHasIntersected({
|
|
1706
|
+
elRef: elementReference,
|
|
1707
|
+
loading
|
|
1708
|
+
});
|
|
1709
|
+
let imageSource = src;
|
|
1710
|
+
let imageOnLoad = onLoad;
|
|
1711
|
+
if (loading === 'lazy' && !hasIntersected) {
|
|
1712
|
+
imageSource = EmptyTransparentImage;
|
|
1713
|
+
imageOnLoad = undefined;
|
|
1714
|
+
}
|
|
1715
|
+
return /*#__PURE__*/jsxRuntime.jsx("img", {
|
|
1716
|
+
ref: elementReference,
|
|
1717
|
+
id: id,
|
|
1718
|
+
alt: alt,
|
|
1719
|
+
src: imageSource,
|
|
1720
|
+
className: classNames__default.default(['tw-image', {
|
|
1721
|
+
'tw-image__stretch': stretch,
|
|
1722
|
+
'tw-image__shrink': shrink
|
|
1723
|
+
}, className]),
|
|
1724
|
+
role: role,
|
|
1725
|
+
onLoad: imageOnLoad,
|
|
1726
|
+
onError: onError
|
|
1727
|
+
});
|
|
1728
|
+
};
|
|
1729
|
+
|
|
1730
|
+
const defaultPromoCardContext = {
|
|
1731
|
+
state: '',
|
|
1732
|
+
isDisabled: false,
|
|
1733
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
1734
|
+
onChange: () => {}
|
|
1735
|
+
};
|
|
1736
|
+
/**
|
|
1737
|
+
* The PromoCard context object.
|
|
1738
|
+
*/
|
|
1739
|
+
const PromoCardContext = /*#__PURE__*/React.createContext(defaultPromoCardContext);
|
|
1740
|
+
/**
|
|
1741
|
+
* A custom hook for accessing the PromoCard context object.
|
|
1742
|
+
*
|
|
1743
|
+
* The `usePromoCardContext` hook is used to access the PromoCard context object
|
|
1744
|
+
* from within a child PromoCard component. It throws an error if the context
|
|
1745
|
+
* object is not available, which can help with debugging and development.
|
|
1746
|
+
*
|
|
1747
|
+
* @returns {PromoCardContextType} - The PromoCard context object.
|
|
1748
|
+
*/
|
|
1749
|
+
const usePromoCardContext = () => {
|
|
1750
|
+
return React.useContext(PromoCardContext);
|
|
1751
|
+
};
|
|
1752
|
+
|
|
1753
|
+
const PromoCardIndicator = ({
|
|
1754
|
+
className,
|
|
1755
|
+
children,
|
|
1756
|
+
label,
|
|
1757
|
+
icon,
|
|
1758
|
+
isSmall = false,
|
|
1759
|
+
testid,
|
|
1760
|
+
...rest
|
|
1761
|
+
}) => {
|
|
1762
|
+
const isIconString = icon && typeof icon === 'string';
|
|
1763
|
+
const IconComponent = isIconString && {
|
|
1764
|
+
check: icons.Check,
|
|
1765
|
+
arrow: icons.ArrowRight,
|
|
1766
|
+
download: icons.Download
|
|
1767
|
+
}[icon];
|
|
1768
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
1769
|
+
className: classNames__default.default('np-Card-indicator', className),
|
|
1770
|
+
"data-testid": testid,
|
|
1771
|
+
...rest,
|
|
1772
|
+
children: [label && /*#__PURE__*/jsxRuntime.jsx(Body, {
|
|
1773
|
+
as: "span",
|
|
1774
|
+
type: exports.Typography.BODY_LARGE_BOLD,
|
|
1775
|
+
className: "np-Card-indicatorText",
|
|
1776
|
+
children: label
|
|
1777
|
+
}), icon && /*#__PURE__*/jsxRuntime.jsx(Avatar, {
|
|
1778
|
+
type: exports.AvatarType.ICON,
|
|
1779
|
+
size: isSmall ? 40 : 56,
|
|
1780
|
+
backgroundColor: "var(--Card-indicator-icon-background-color)",
|
|
1781
|
+
className: "np-Card-indicatorIcon",
|
|
1782
|
+
children: IconComponent ? /*#__PURE__*/jsxRuntime.jsx(IconComponent, {
|
|
1783
|
+
size: 24,
|
|
1784
|
+
"aria-hidden": "true"
|
|
1785
|
+
}) : icon
|
|
1786
|
+
}), children]
|
|
1787
|
+
});
|
|
1788
|
+
};
|
|
1789
|
+
|
|
1790
|
+
const PromoCard = /*#__PURE__*/React.forwardRef(({
|
|
1791
|
+
className,
|
|
1792
|
+
description,
|
|
1793
|
+
defaultChecked,
|
|
1794
|
+
download,
|
|
1795
|
+
href,
|
|
1796
|
+
hrefLang,
|
|
1797
|
+
id,
|
|
1798
|
+
headingLevel = 'h3',
|
|
1799
|
+
imageAlt,
|
|
1800
|
+
imageClass,
|
|
1801
|
+
imageSource,
|
|
1802
|
+
indicatorLabel,
|
|
1803
|
+
indicatorIcon,
|
|
1804
|
+
isChecked,
|
|
1805
|
+
isDisabled,
|
|
1806
|
+
onClick,
|
|
1807
|
+
onKeyDown,
|
|
1808
|
+
rel,
|
|
1809
|
+
tabIndex,
|
|
1810
|
+
target,
|
|
1811
|
+
testId,
|
|
1812
|
+
title,
|
|
1813
|
+
type,
|
|
1814
|
+
value,
|
|
1815
|
+
isSmall,
|
|
1816
|
+
useDisplayFont = true,
|
|
1817
|
+
anchorRef,
|
|
1818
|
+
anchorId,
|
|
1819
|
+
...props
|
|
1820
|
+
}, ref) => {
|
|
1821
|
+
// Set the `checked` state to the value of `defaultChecked` if it is truthy,
|
|
1822
|
+
// or the value of `isChecked` if it is truthy, or `false` if neither
|
|
1823
|
+
// is truthy.
|
|
1824
|
+
const {
|
|
1825
|
+
state,
|
|
1826
|
+
onChange,
|
|
1827
|
+
isDisabled: contextIsDisabled
|
|
1828
|
+
} = usePromoCardContext();
|
|
1829
|
+
const [checked, setChecked] = React.useState(type === 'checkbox' ? defaultChecked ?? isChecked ?? false : false);
|
|
1830
|
+
const handleClick = () => {
|
|
1831
|
+
if (type === 'radio') {
|
|
1832
|
+
onChange(value || ''); // Update the context state for radio
|
|
1833
|
+
} else if (type === 'checkbox') {
|
|
1834
|
+
setChecked(!checked); // Update local state for checkbox
|
|
1835
|
+
}
|
|
1836
|
+
};
|
|
1837
|
+
const fallbackId = reactId.useId();
|
|
1838
|
+
const componentId = id || fallbackId;
|
|
1839
|
+
// Set the icon to `'arrow'` if `href` is truthy and `type` is falsy, or
|
|
1840
|
+
// `'download'` if `download` is truthy. If neither condition is true, set
|
|
1841
|
+
// `icon` to `undefined`.
|
|
1842
|
+
// Create a function to get icon type
|
|
1843
|
+
const getIconType = () => {
|
|
1844
|
+
if (indicatorIcon) {
|
|
1845
|
+
return indicatorIcon;
|
|
1846
|
+
}
|
|
1847
|
+
if (download) {
|
|
1848
|
+
return 'download';
|
|
1849
|
+
}
|
|
1850
|
+
if (href && !type) {
|
|
1851
|
+
return 'arrow';
|
|
1852
|
+
}
|
|
1853
|
+
return undefined;
|
|
1854
|
+
};
|
|
1855
|
+
// Define all class names string based on the values of the `href`, `type`,
|
|
1856
|
+
// `checked`, and `className` props.
|
|
1857
|
+
const commonClasses = classNames__default.default({
|
|
1858
|
+
'np-Card--promoCard': true,
|
|
1859
|
+
'np-Card--checked': !href && type,
|
|
1860
|
+
'np-Card--link': href && !type,
|
|
1861
|
+
'is-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined
|
|
1862
|
+
}, className);
|
|
1863
|
+
// Object with common props that will be passed to the `Card` components
|
|
1864
|
+
const commonProps = {
|
|
1865
|
+
className: commonClasses,
|
|
1866
|
+
id: componentId,
|
|
1867
|
+
isDisabled: isDisabled || contextIsDisabled,
|
|
1868
|
+
onClick,
|
|
1869
|
+
onKeyDown,
|
|
1870
|
+
ref,
|
|
1871
|
+
'data-testid': testId,
|
|
1872
|
+
isSmall
|
|
1873
|
+
};
|
|
1874
|
+
// Object with Anchor props that will be passed to the `a` element. These
|
|
1875
|
+
// won't be refurned if set to `isDisabled`
|
|
1876
|
+
const anchorProps = href && !isDisabled ? {
|
|
1877
|
+
download,
|
|
1878
|
+
href: href || undefined,
|
|
1879
|
+
hrefLang,
|
|
1880
|
+
rel,
|
|
1881
|
+
target,
|
|
1882
|
+
ref: anchorRef,
|
|
1883
|
+
id: anchorId
|
|
1884
|
+
} : {};
|
|
1885
|
+
// Object of all Checked props that will be passed to the root `Card` component
|
|
1886
|
+
const checkedProps = (type === 'checkbox' || type === 'radio') && !href ? {
|
|
1887
|
+
...commonProps,
|
|
1888
|
+
'aria-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined,
|
|
1889
|
+
'aria-describedby': `${componentId}-title`,
|
|
1890
|
+
'aria-disabled': isDisabled,
|
|
1891
|
+
'data-value': value ?? undefined,
|
|
1892
|
+
role: type === 'checkbox' || type === 'radio' ? type : undefined,
|
|
1893
|
+
onClick: handleClick,
|
|
1894
|
+
onKeyDown: event => {
|
|
1895
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
1896
|
+
handleClick();
|
|
1897
|
+
}
|
|
1898
|
+
},
|
|
1899
|
+
ref,
|
|
1900
|
+
tabIndex: 0
|
|
1901
|
+
} : {};
|
|
1902
|
+
const getTitle = () => {
|
|
1903
|
+
const titleContent = href && !type ? /*#__PURE__*/jsxRuntime.jsx("a", {
|
|
1904
|
+
className: "np-Card-titleLink",
|
|
1905
|
+
...anchorProps,
|
|
1906
|
+
children: title
|
|
1907
|
+
}) : title;
|
|
1908
|
+
const titleProps = {
|
|
1909
|
+
id: `${componentId}-title`,
|
|
1910
|
+
as: headingLevel,
|
|
1911
|
+
className: 'np-Card-title'
|
|
1912
|
+
};
|
|
1913
|
+
return useDisplayFont ? /*#__PURE__*/jsxRuntime.jsx(Display, {
|
|
1914
|
+
type: exports.Typography.DISPLAY_SMALL,
|
|
1915
|
+
...titleProps,
|
|
1916
|
+
children: titleContent
|
|
1917
|
+
}) : /*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
1918
|
+
type: exports.Typography.TITLE_SUBSECTION,
|
|
1919
|
+
...titleProps,
|
|
1920
|
+
children: titleContent
|
|
1921
|
+
});
|
|
1922
|
+
};
|
|
1923
|
+
React.useEffect(() => {
|
|
1924
|
+
setChecked(defaultChecked ?? isChecked ?? false);
|
|
1925
|
+
}, [defaultChecked, isChecked]);
|
|
1926
|
+
return /*#__PURE__*/jsxRuntime.jsxs(Card$2, {
|
|
1927
|
+
...commonProps,
|
|
1928
|
+
...checkedProps,
|
|
1929
|
+
...props,
|
|
1930
|
+
children: [(value === state || checked) && /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
1931
|
+
className: "np-Card-check",
|
|
1932
|
+
children: /*#__PURE__*/jsxRuntime.jsx(icons.Check, {
|
|
1933
|
+
size: 24,
|
|
1934
|
+
"aria-hidden": "true"
|
|
1935
|
+
})
|
|
1936
|
+
}), getTitle(), /*#__PURE__*/jsxRuntime.jsx(Body, {
|
|
1937
|
+
className: "np-Card-description",
|
|
1938
|
+
children: description
|
|
1939
|
+
}), imageSource && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
1940
|
+
className: classNames__default.default('np-Card-image', {
|
|
1941
|
+
imageClass
|
|
1942
|
+
}),
|
|
1943
|
+
children: /*#__PURE__*/jsxRuntime.jsx(Image, {
|
|
1944
|
+
src: imageSource,
|
|
1945
|
+
alt: imageAlt || '',
|
|
1946
|
+
loading: "lazy"
|
|
1947
|
+
})
|
|
1948
|
+
}), /*#__PURE__*/jsxRuntime.jsx(PromoCardIndicator, {
|
|
1949
|
+
label: indicatorLabel,
|
|
1950
|
+
icon: getIconType(),
|
|
1951
|
+
isSmall: isSmall
|
|
1952
|
+
})]
|
|
1953
|
+
});
|
|
1954
|
+
});
|
|
1955
|
+
var PromoCard$1 = /*#__PURE__*/React__namespace.default.memo(PromoCard);
|
|
1956
|
+
|
|
1957
|
+
const LEFT_SCROLL_OFFSET = 8;
|
|
1958
|
+
const Carousel = ({
|
|
1959
|
+
header,
|
|
1960
|
+
className,
|
|
1961
|
+
cards,
|
|
1962
|
+
onClick
|
|
1963
|
+
}) => {
|
|
1964
|
+
const [scrollPosition, setScrollPosition] = React.useState(0);
|
|
1965
|
+
const [previousScrollPosition, setPreviousScrollPosition] = React.useState(0);
|
|
1966
|
+
const [scrollIsAtEnd, setScrollIsAtEnd] = React.useState(false);
|
|
1967
|
+
const [visibleCardOnMobileView, setVisibleCardOnMobileView] = React.useState('');
|
|
1968
|
+
const carouselElementRef = React.useRef(null);
|
|
1969
|
+
const carouselCardsRef = React.useRef([]);
|
|
1970
|
+
const isLeftActionButtonEnabled = scrollPosition > LEFT_SCROLL_OFFSET;
|
|
1971
|
+
const areActionButtonsEnabled = isLeftActionButtonEnabled || !scrollIsAtEnd;
|
|
1972
|
+
const [focusedCard, setFocusedCard] = React.useState(cards?.[0]?.id);
|
|
1973
|
+
const updateScrollButtonsState = () => {
|
|
1974
|
+
if (carouselElementRef.current) {
|
|
1975
|
+
const {
|
|
1976
|
+
scrollWidth,
|
|
1977
|
+
offsetWidth
|
|
1978
|
+
} = carouselElementRef.current;
|
|
1979
|
+
const scrollAtEnd = scrollWidth - offsetWidth <= scrollPosition + LEFT_SCROLL_OFFSET;
|
|
1980
|
+
setScrollIsAtEnd(scrollAtEnd);
|
|
1981
|
+
}
|
|
1982
|
+
const scrollDirecton = scrollPosition > previousScrollPosition ? 'right' : 'left';
|
|
1983
|
+
const cardsInFullViewIds = [];
|
|
1984
|
+
carouselCardsRef.current.forEach(card => {
|
|
1985
|
+
if (isVisible(carouselElementRef.current, card.cardElement)) {
|
|
1986
|
+
// eslint-disable-next-line functional/immutable-data
|
|
1987
|
+
cardsInFullViewIds.push(card.cardElement.getAttribute('id') ?? '');
|
|
1988
|
+
}
|
|
1989
|
+
});
|
|
1990
|
+
if (cardsInFullViewIds.length >= 1) {
|
|
1991
|
+
const visibleCardIndex = scrollDirecton === 'right' ? cardsInFullViewIds.length - 1 : 0;
|
|
1992
|
+
const visibleCardId = cardsInFullViewIds[visibleCardIndex];
|
|
1993
|
+
setVisibleCardOnMobileView(visibleCardId);
|
|
1994
|
+
setFocusedCard(visibleCardId);
|
|
1995
|
+
}
|
|
1996
|
+
setPreviousScrollPosition(scrollPosition);
|
|
1997
|
+
};
|
|
1998
|
+
const scrollCarousel = (direction = 'right') => {
|
|
1999
|
+
if (carouselElementRef.current) {
|
|
2000
|
+
const {
|
|
2001
|
+
scrollWidth
|
|
2002
|
+
} = carouselElementRef.current;
|
|
2003
|
+
const cardWidth = scrollWidth / carouselCardsRef.current.length;
|
|
2004
|
+
const res = Math.floor(cardWidth - cardWidth * 0.05);
|
|
2005
|
+
carouselElementRef.current.scrollBy({
|
|
2006
|
+
left: direction === 'right' ? res : -res,
|
|
2007
|
+
behavior: 'smooth'
|
|
2008
|
+
});
|
|
2009
|
+
}
|
|
2010
|
+
};
|
|
2011
|
+
const handleOnKeyDown = (event, index) => {
|
|
2012
|
+
if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
|
|
2013
|
+
const nextIndex = event.key === 'ArrowRight' ? index + 1 : index - 1;
|
|
2014
|
+
const nextCard = cards[nextIndex];
|
|
2015
|
+
if (nextCard) {
|
|
2016
|
+
const ref = carouselCardsRef.current[nextIndex];
|
|
2017
|
+
if (ref.type === 'promo') {
|
|
2018
|
+
ref.anchorElement?.focus();
|
|
2019
|
+
} else {
|
|
2020
|
+
ref.cardElement?.focus();
|
|
2021
|
+
}
|
|
2022
|
+
scrollCardIntoView(carouselCardsRef.current[nextIndex].cardElement, nextCard);
|
|
2023
|
+
event.preventDefault();
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
2027
|
+
event.currentTarget.click();
|
|
2028
|
+
}
|
|
2029
|
+
};
|
|
2030
|
+
const scrollCardIntoView = (element, card) => {
|
|
2031
|
+
element.scrollIntoView({
|
|
2032
|
+
behavior: 'smooth',
|
|
2033
|
+
block: 'nearest',
|
|
2034
|
+
inline: 'center'
|
|
2035
|
+
});
|
|
2036
|
+
setFocusedCard(card.id);
|
|
2037
|
+
};
|
|
2038
|
+
React.useEffect(() => {
|
|
2039
|
+
updateScrollButtonsState();
|
|
2040
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2041
|
+
}, [scrollPosition]);
|
|
2042
|
+
React.useEffect(() => {
|
|
2043
|
+
window.addEventListener('resize', updateScrollButtonsState);
|
|
2044
|
+
return () => {
|
|
2045
|
+
window.removeEventListener('resize', updateScrollButtonsState);
|
|
2046
|
+
};
|
|
2047
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2048
|
+
}, []);
|
|
2049
|
+
const addElementToCardsRefArray = (index, ref) => {
|
|
2050
|
+
if (ref) {
|
|
2051
|
+
// eslint-disable-next-line functional/immutable-data
|
|
2052
|
+
carouselCardsRef.current[index] = {
|
|
2053
|
+
type: ref.type ?? carouselCardsRef.current?.[index]?.type,
|
|
2054
|
+
cardElement: ref.cardElement ?? carouselCardsRef.current?.[index]?.cardElement,
|
|
2055
|
+
anchorElement: ref.anchorElement ?? carouselCardsRef.current?.[index]?.anchorElement
|
|
2056
|
+
};
|
|
2057
|
+
}
|
|
2058
|
+
};
|
|
2059
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
2060
|
+
className: classNames__default.default('carousel-wrapper', className),
|
|
2061
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
2062
|
+
className: "d-flex justify-content-between carousel__header",
|
|
2063
|
+
children: [typeof header === 'string' ? /*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
2064
|
+
as: "span",
|
|
2065
|
+
type: "title-body",
|
|
2066
|
+
children: header
|
|
2067
|
+
}) : header, areActionButtonsEnabled ? /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
2068
|
+
className: "hidden-xs",
|
|
2069
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(ActionButton, {
|
|
2070
|
+
className: "carousel__scroll-button",
|
|
2071
|
+
tabIndex: -1,
|
|
2072
|
+
priority: "secondary",
|
|
2073
|
+
disabled: !isLeftActionButtonEnabled,
|
|
2074
|
+
"aria-hidden": "true",
|
|
2075
|
+
"data-testid": "scroll-carousel-left",
|
|
2076
|
+
onClick: () => scrollCarousel('left'),
|
|
2077
|
+
children: /*#__PURE__*/jsxRuntime.jsx(icons.ChevronLeft, {})
|
|
2078
|
+
}), /*#__PURE__*/jsxRuntime.jsx(ActionButton, {
|
|
2079
|
+
tabIndex: -1,
|
|
2080
|
+
className: "carousel__scroll-button m-l-1",
|
|
2081
|
+
priority: "secondary",
|
|
2082
|
+
"aria-hidden": "true",
|
|
2083
|
+
"data-testid": "scroll-carousel-right",
|
|
2084
|
+
disabled: scrollIsAtEnd,
|
|
2085
|
+
onClick: () => scrollCarousel(),
|
|
2086
|
+
children: /*#__PURE__*/jsxRuntime.jsx(icons.ChevronRight, {})
|
|
2087
|
+
})]
|
|
2088
|
+
}) : null]
|
|
2089
|
+
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2090
|
+
ref: carouselElementRef,
|
|
2091
|
+
tabIndex: -1,
|
|
2092
|
+
role: "list",
|
|
2093
|
+
className: "carousel",
|
|
2094
|
+
onScroll: event => {
|
|
2095
|
+
const target = event.target;
|
|
2096
|
+
setScrollPosition(target.scrollLeft);
|
|
2097
|
+
},
|
|
2098
|
+
children: cards?.map((card, index) => {
|
|
2099
|
+
const sharedProps = {
|
|
2100
|
+
id: card.id,
|
|
2101
|
+
className: classNames__default.default('carousel__card', {
|
|
2102
|
+
'carousel__card--focused': card.id === focusedCard
|
|
2103
|
+
}),
|
|
2104
|
+
onClick: () => {
|
|
2105
|
+
card.onClick?.();
|
|
2106
|
+
onClick?.(card.id);
|
|
2107
|
+
},
|
|
2108
|
+
onFocus: event => {
|
|
2109
|
+
scrollCardIntoView(event.currentTarget, card);
|
|
2110
|
+
}
|
|
2111
|
+
};
|
|
2112
|
+
const cardContent = card.type !== 'promo' ? /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2113
|
+
id: `${card.id}-content`,
|
|
2114
|
+
className: classNames__default.default('carousel__card-content', {
|
|
2115
|
+
[card.className ?? '']: !!card.className
|
|
2116
|
+
})
|
|
2117
|
+
// eslint-disable-next-line react/forbid-dom-props
|
|
2118
|
+
,
|
|
2119
|
+
style: card.styles,
|
|
2120
|
+
children: card.content
|
|
2121
|
+
}) : null;
|
|
2122
|
+
if (card.type === 'button') {
|
|
2123
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2124
|
+
"aria-labelledby": `${card.id}-content`,
|
|
2125
|
+
role: "listitem",
|
|
2126
|
+
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2127
|
+
...sharedProps,
|
|
2128
|
+
ref: el => {
|
|
2129
|
+
if (el) {
|
|
2130
|
+
// eslint-disable-next-line functional/immutable-data
|
|
2131
|
+
carouselCardsRef.current[index] = {
|
|
2132
|
+
type: 'default',
|
|
2133
|
+
cardElement: el
|
|
2134
|
+
};
|
|
2135
|
+
}
|
|
2136
|
+
},
|
|
2137
|
+
role: "button",
|
|
2138
|
+
tabIndex: 0,
|
|
2139
|
+
onKeyDown: event => handleOnKeyDown(event, index),
|
|
2140
|
+
children: cardContent
|
|
2141
|
+
})
|
|
2142
|
+
}, card.id);
|
|
2143
|
+
}
|
|
2144
|
+
if (card.type === 'promo') {
|
|
2145
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2146
|
+
id: card.id,
|
|
2147
|
+
role: "listitem",
|
|
2148
|
+
"aria-labelledby": `${card.id}-anchor`,
|
|
2149
|
+
children: /*#__PURE__*/jsxRuntime.jsx(PromoCard$1, {
|
|
2150
|
+
...card,
|
|
2151
|
+
type: undefined,
|
|
2152
|
+
...sharedProps,
|
|
2153
|
+
ref: el => {
|
|
2154
|
+
if (el) {
|
|
2155
|
+
addElementToCardsRefArray(index, {
|
|
2156
|
+
type: 'promo',
|
|
2157
|
+
cardElement: el
|
|
2158
|
+
});
|
|
2159
|
+
}
|
|
2160
|
+
},
|
|
2161
|
+
anchorRef: el => {
|
|
2162
|
+
if (el) {
|
|
2163
|
+
addElementToCardsRefArray(index, {
|
|
2164
|
+
type: 'promo',
|
|
2165
|
+
anchorElement: el
|
|
2166
|
+
});
|
|
2167
|
+
}
|
|
2168
|
+
},
|
|
2169
|
+
anchorId: `${card.id}-anchor`,
|
|
2170
|
+
onKeyDown: event => handleOnKeyDown(event, index)
|
|
2171
|
+
})
|
|
2172
|
+
}, card.id);
|
|
2173
|
+
}
|
|
2174
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2175
|
+
"aria-labelledby": `${card.id}-content`,
|
|
2176
|
+
role: "listitem",
|
|
2177
|
+
children: /*#__PURE__*/jsxRuntime.jsx("a", {
|
|
2178
|
+
...sharedProps,
|
|
2179
|
+
ref: el => {
|
|
2180
|
+
if (el) {
|
|
2181
|
+
// eslint-disable-next-line functional/immutable-data
|
|
2182
|
+
carouselCardsRef.current[index] = {
|
|
2183
|
+
type: 'default',
|
|
2184
|
+
cardElement: el
|
|
2185
|
+
};
|
|
2186
|
+
}
|
|
2187
|
+
},
|
|
2188
|
+
href: card.href,
|
|
2189
|
+
rel: "noreferrer",
|
|
2190
|
+
onKeyDown: event => handleOnKeyDown(event, index),
|
|
2191
|
+
children: cardContent
|
|
2192
|
+
})
|
|
2193
|
+
}, card.id);
|
|
2194
|
+
})
|
|
2195
|
+
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2196
|
+
className: "visible-xs",
|
|
2197
|
+
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2198
|
+
className: "carousel__indicators",
|
|
2199
|
+
children: cards?.map((card, index) => /*#__PURE__*/jsxRuntime.jsx("button", {
|
|
2200
|
+
"data-testid": `${card.id}-indicator`,
|
|
2201
|
+
tabIndex: -1,
|
|
2202
|
+
"aria-hidden": true,
|
|
2203
|
+
type: "button",
|
|
2204
|
+
className: classNames__default.default('carousel__indicator', {
|
|
2205
|
+
'carousel__indicator--selected': card.id === visibleCardOnMobileView
|
|
2206
|
+
}),
|
|
2207
|
+
onClick: () => {
|
|
2208
|
+
scrollCardIntoView(carouselCardsRef.current[index].cardElement, card);
|
|
2209
|
+
}
|
|
2210
|
+
}, `${card.id}-indicator`))
|
|
2211
|
+
})
|
|
2212
|
+
})]
|
|
2213
|
+
});
|
|
2214
|
+
};
|
|
2215
|
+
const isVisible = (container, el) => {
|
|
2216
|
+
const cWidth = container.offsetWidth;
|
|
2217
|
+
const cScrollOffset = container.scrollLeft;
|
|
2218
|
+
const elemLeft = el.offsetLeft - container.offsetLeft;
|
|
2219
|
+
const elemRight = elemLeft + el.offsetWidth;
|
|
2220
|
+
return elemLeft >= cScrollOffset && elemRight <= cScrollOffset + cWidth;
|
|
2221
|
+
};
|
|
2222
|
+
|
|
2223
|
+
const Card = /*#__PURE__*/React.forwardRef((props, reference) => {
|
|
1514
2224
|
const {
|
|
1515
2225
|
'aria-label': ariaLabel,
|
|
1516
2226
|
as: Element,
|
|
@@ -1561,7 +2271,7 @@ const Card$1 = /*#__PURE__*/React.forwardRef((props, reference) => {
|
|
|
1561
2271
|
const hasChildren = ({
|
|
1562
2272
|
children
|
|
1563
2273
|
}) => children;
|
|
1564
|
-
Card
|
|
2274
|
+
Card.propTypes = {
|
|
1565
2275
|
'aria-label': PropTypes__default.default.string,
|
|
1566
2276
|
as: PropTypes__default.default.string,
|
|
1567
2277
|
isExpanded: requiredIf__default.default(PropTypes__default.default.bool, hasChildren),
|
|
@@ -1574,7 +2284,7 @@ Card$1.propTypes = {
|
|
|
1574
2284
|
className: PropTypes__default.default.string,
|
|
1575
2285
|
'data-testid': PropTypes__default.default.string
|
|
1576
2286
|
};
|
|
1577
|
-
Card
|
|
2287
|
+
Card.defaultProps = {
|
|
1578
2288
|
'aria-label': undefined,
|
|
1579
2289
|
as: 'div',
|
|
1580
2290
|
children: null,
|
|
@@ -1582,7 +2292,7 @@ Card$1.defaultProps = {
|
|
|
1582
2292
|
className: null,
|
|
1583
2293
|
'data-testid': null
|
|
1584
2294
|
};
|
|
1585
|
-
var Card$
|
|
2295
|
+
var Card$1 = Card;
|
|
1586
2296
|
|
|
1587
2297
|
const CheckboxButton = /*#__PURE__*/React.forwardRef(({
|
|
1588
2298
|
checked,
|
|
@@ -2068,135 +2778,6 @@ const DimmerContentWrapper = ({
|
|
|
2068
2778
|
};
|
|
2069
2779
|
var Dimmer$1 = withNextPortalWrapper(Dimmer);
|
|
2070
2780
|
|
|
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
2781
|
const EXIT_ANIMATION = 350;
|
|
2201
2782
|
const SlidingPanel = /*#__PURE__*/React.forwardRef(({
|
|
2202
2783
|
position = 'left',
|
|
@@ -2476,39 +3057,6 @@ const BottomSheet$1 = props => {
|
|
|
2476
3057
|
});
|
|
2477
3058
|
};
|
|
2478
3059
|
|
|
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
3060
|
function CriticalCommsBanner({
|
|
2513
3061
|
title,
|
|
2514
3062
|
subtitle,
|
|
@@ -4366,20 +4914,6 @@ DefinitionList.defaultProps = {
|
|
|
4366
4914
|
};
|
|
4367
4915
|
var DefinitionList$1 = DefinitionList;
|
|
4368
4916
|
|
|
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
4917
|
const DropFade = ({
|
|
4384
4918
|
children,
|
|
4385
4919
|
show
|
|
@@ -5063,71 +5597,32 @@ const HeaderAction = ({
|
|
|
5063
5597
|
*/
|
|
5064
5598
|
const Header = ({
|
|
5065
5599
|
action,
|
|
5066
|
-
as = 'h5',
|
|
5067
|
-
title,
|
|
5068
|
-
className
|
|
5069
|
-
}) => {
|
|
5070
|
-
if (!action) {
|
|
5071
|
-
return /*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
5072
|
-
as: as,
|
|
5073
|
-
type: exports.Typography.TITLE_GROUP,
|
|
5074
|
-
className: classNames__default.default('np-header', 'np-header__title', className),
|
|
5075
|
-
children: title
|
|
5076
|
-
});
|
|
5077
|
-
}
|
|
5078
|
-
if (as === 'legend') {
|
|
5079
|
-
// eslint-disable-next-line no-console
|
|
5080
|
-
console.warn('Legends should be the first child in a fieldset, and this is not possible when including an action');
|
|
5081
|
-
}
|
|
5082
|
-
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
5083
|
-
className: classNames__default.default('np-header', className),
|
|
5084
|
-
children: [/*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
5085
|
-
as: as,
|
|
5086
|
-
type: exports.Typography.TITLE_GROUP,
|
|
5087
|
-
className: "np-header__title",
|
|
5088
|
-
children: title
|
|
5089
|
-
}), /*#__PURE__*/jsxRuntime.jsx(HeaderAction, {
|
|
5090
|
-
action: action
|
|
5091
|
-
})]
|
|
5092
|
-
});
|
|
5093
|
-
};
|
|
5094
|
-
|
|
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;
|
|
5600
|
+
as = 'h5',
|
|
5601
|
+
title,
|
|
5602
|
+
className
|
|
5603
|
+
}) => {
|
|
5604
|
+
if (!action) {
|
|
5605
|
+
return /*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
5606
|
+
as: as,
|
|
5607
|
+
type: exports.Typography.TITLE_GROUP,
|
|
5608
|
+
className: classNames__default.default('np-header', 'np-header__title', className),
|
|
5609
|
+
children: title
|
|
5610
|
+
});
|
|
5118
5611
|
}
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
className: classNames__default.default(
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5612
|
+
if (as === 'legend') {
|
|
5613
|
+
// eslint-disable-next-line no-console
|
|
5614
|
+
console.warn('Legends should be the first child in a fieldset, and this is not possible when including an action');
|
|
5615
|
+
}
|
|
5616
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
5617
|
+
className: classNames__default.default('np-header', className),
|
|
5618
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
5619
|
+
as: as,
|
|
5620
|
+
type: exports.Typography.TITLE_GROUP,
|
|
5621
|
+
className: "np-header__title",
|
|
5622
|
+
children: title
|
|
5623
|
+
}), /*#__PURE__*/jsxRuntime.jsx(HeaderAction, {
|
|
5624
|
+
action: action
|
|
5625
|
+
})]
|
|
5131
5626
|
});
|
|
5132
5627
|
};
|
|
5133
5628
|
|
|
@@ -9000,227 +9495,6 @@ const ProgressBar = ({
|
|
|
9000
9495
|
});
|
|
9001
9496
|
};
|
|
9002
9497
|
|
|
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
9498
|
const PromoCardGroup = ({
|
|
9225
9499
|
children,
|
|
9226
9500
|
className,
|
|
@@ -14521,11 +14795,12 @@ exports.Alert = Alert;
|
|
|
14521
14795
|
exports.Avatar = Avatar;
|
|
14522
14796
|
exports.AvatarWrapper = AvatarWrapper;
|
|
14523
14797
|
exports.Badge = Badge;
|
|
14524
|
-
exports.BaseCard = Card;
|
|
14798
|
+
exports.BaseCard = Card$2;
|
|
14525
14799
|
exports.Body = Body;
|
|
14526
14800
|
exports.BottomSheet = BottomSheet$1;
|
|
14527
14801
|
exports.Button = Button;
|
|
14528
|
-
exports.Card = Card$
|
|
14802
|
+
exports.Card = Card$1;
|
|
14803
|
+
exports.Carousel = Carousel;
|
|
14529
14804
|
exports.Checkbox = Checkbox;
|
|
14530
14805
|
exports.CheckboxButton = CheckboxButton$1;
|
|
14531
14806
|
exports.CheckboxOption = CheckboxOption;
|