@transferwise/components 0.0.0-experimental-26e4e3f → 0.0.0-experimental-36044b4
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 +741 -466
- package/build/index.js.map +1 -1
- package/build/index.mjs +741 -467
- 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 +1 -1
- 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 +29 -8
package/build/index.js
CHANGED
|
@@ -1492,7 +1492,716 @@ const Button = /*#__PURE__*/React.forwardRef(({
|
|
|
1492
1492
|
});
|
|
1493
1493
|
});
|
|
1494
1494
|
|
|
1495
|
-
const Card$
|
|
1495
|
+
const Card$2 = /*#__PURE__*/React.forwardRef(({
|
|
1496
|
+
className,
|
|
1497
|
+
children = null,
|
|
1498
|
+
id,
|
|
1499
|
+
isDisabled = false,
|
|
1500
|
+
isSmall = false,
|
|
1501
|
+
onDismiss,
|
|
1502
|
+
testId,
|
|
1503
|
+
...props
|
|
1504
|
+
}, ref) => {
|
|
1505
|
+
const closeButtonReference = React.useRef(null);
|
|
1506
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
1507
|
+
ref: ref,
|
|
1508
|
+
className: classNames__default.default('np-Card', {
|
|
1509
|
+
'np-Card--small': !!isSmall,
|
|
1510
|
+
'is-disabled': !!isDisabled
|
|
1511
|
+
}, className),
|
|
1512
|
+
id: id,
|
|
1513
|
+
"data-testid": testId,
|
|
1514
|
+
...props,
|
|
1515
|
+
children: [onDismiss && /*#__PURE__*/jsxRuntime.jsx(CloseButton, {
|
|
1516
|
+
ref: closeButtonReference,
|
|
1517
|
+
className: "np-Card-closeButton",
|
|
1518
|
+
size: isSmall ? 'sm' : 'md',
|
|
1519
|
+
isDisabled: isDisabled,
|
|
1520
|
+
testId: "close-button",
|
|
1521
|
+
onClick: e => {
|
|
1522
|
+
stopPropagation$1(e);
|
|
1523
|
+
onDismiss();
|
|
1524
|
+
}
|
|
1525
|
+
}), children]
|
|
1526
|
+
});
|
|
1527
|
+
});
|
|
1528
|
+
Card$2.displayName = 'Card';
|
|
1529
|
+
|
|
1530
|
+
function Display({
|
|
1531
|
+
as: Heading = 'h1',
|
|
1532
|
+
type = exports.Typography.DISPLAY_LARGE,
|
|
1533
|
+
children,
|
|
1534
|
+
className,
|
|
1535
|
+
id
|
|
1536
|
+
}) {
|
|
1537
|
+
return /*#__PURE__*/jsxRuntime.jsx(Heading, {
|
|
1538
|
+
id: id,
|
|
1539
|
+
className: classNames__default.default(`np-text-${type}`, 'text-primary', className),
|
|
1540
|
+
children: children
|
|
1541
|
+
});
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
const useConditionalListener = ({
|
|
1545
|
+
attachListener,
|
|
1546
|
+
callback,
|
|
1547
|
+
eventType,
|
|
1548
|
+
parent
|
|
1549
|
+
}) => {
|
|
1550
|
+
React.useEffect(() => {
|
|
1551
|
+
if (attachListener && !neptuneValidation.isUndefined(parent)) {
|
|
1552
|
+
parent.addEventListener(eventType, callback, true);
|
|
1553
|
+
}
|
|
1554
|
+
return () => {
|
|
1555
|
+
if (!neptuneValidation.isUndefined(parent)) {
|
|
1556
|
+
parent.removeEventListener(eventType, callback, true);
|
|
1557
|
+
}
|
|
1558
|
+
};
|
|
1559
|
+
}, [attachListener, callback, eventType, parent]);
|
|
1560
|
+
};
|
|
1561
|
+
|
|
1562
|
+
const DirectionContext = /*#__PURE__*/React.createContext(exports.Direction.LTR);
|
|
1563
|
+
const DirectionProvider = ({
|
|
1564
|
+
direction,
|
|
1565
|
+
children
|
|
1566
|
+
}) => {
|
|
1567
|
+
return /*#__PURE__*/jsxRuntime.jsx(DirectionContext.Provider, {
|
|
1568
|
+
value: direction,
|
|
1569
|
+
children: children
|
|
1570
|
+
});
|
|
1571
|
+
};
|
|
1572
|
+
|
|
1573
|
+
const useDirection = () => {
|
|
1574
|
+
const direction = React.useContext(DirectionContext);
|
|
1575
|
+
return {
|
|
1576
|
+
direction,
|
|
1577
|
+
isRTL: direction === 'rtl'
|
|
1578
|
+
};
|
|
1579
|
+
};
|
|
1580
|
+
|
|
1581
|
+
const ObserverParams = {
|
|
1582
|
+
threshold: 0.1
|
|
1583
|
+
};
|
|
1584
|
+
|
|
1585
|
+
/**
|
|
1586
|
+
* useHasIntersected.
|
|
1587
|
+
* Use this custom hook to detect when an element has became visible inside the viewport. This hook checks only if the intersection happend.
|
|
1588
|
+
* Once the intersection has happened the hook will not return false even if the element gets out of the viewport.
|
|
1589
|
+
*
|
|
1590
|
+
* @param elRef.elRef
|
|
1591
|
+
* @param {object} [elRef] - node object that contains a react reference to the element that needs to be observed.
|
|
1592
|
+
* @param {strimng} [loading = 'eager'] - string that contains the type of loading.
|
|
1593
|
+
* @param elRef.loading
|
|
1594
|
+
* @usage `const [hasIntersected] = useHasIntersected({imageRef,loading});`
|
|
1595
|
+
*/
|
|
1596
|
+
const useHasIntersected = ({
|
|
1597
|
+
elRef,
|
|
1598
|
+
loading
|
|
1599
|
+
}) => {
|
|
1600
|
+
const [hasIntersected, setHasIntersected] = React.useState(false);
|
|
1601
|
+
const {
|
|
1602
|
+
current
|
|
1603
|
+
} = elRef || {};
|
|
1604
|
+
const isValidReference = () => {
|
|
1605
|
+
return elRef && current;
|
|
1606
|
+
};
|
|
1607
|
+
const handleOnIntersect = (entries, observer) => {
|
|
1608
|
+
entries.forEach(entry => {
|
|
1609
|
+
if (entry.isIntersecting) {
|
|
1610
|
+
setHasIntersected(true);
|
|
1611
|
+
observer.unobserve(current);
|
|
1612
|
+
}
|
|
1613
|
+
});
|
|
1614
|
+
};
|
|
1615
|
+
React.useEffect(() => {
|
|
1616
|
+
let observer;
|
|
1617
|
+
let didCancel = false;
|
|
1618
|
+
|
|
1619
|
+
// Check if window is define for SSR and Old browsers fallback
|
|
1620
|
+
if (typeof window === 'undefined' || !window.IntersectionObserver || !isValidReference()) {
|
|
1621
|
+
setHasIntersected(true);
|
|
1622
|
+
} else if (!didCancel) {
|
|
1623
|
+
observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
|
|
1624
|
+
observer.observe(current);
|
|
1625
|
+
}
|
|
1626
|
+
return () => {
|
|
1627
|
+
didCancel = true;
|
|
1628
|
+
if (observer) {
|
|
1629
|
+
observer.unobserve(current);
|
|
1630
|
+
}
|
|
1631
|
+
};
|
|
1632
|
+
}, [elRef]);
|
|
1633
|
+
if (loading === 'eager') {
|
|
1634
|
+
return [false];
|
|
1635
|
+
}
|
|
1636
|
+
return [hasIntersected];
|
|
1637
|
+
};
|
|
1638
|
+
|
|
1639
|
+
function useMedia(query) {
|
|
1640
|
+
return React.useSyncExternalStore(onStoreChange => {
|
|
1641
|
+
const mediaQueryList = window.matchMedia(query);
|
|
1642
|
+
mediaQueryList.addEventListener('change', onStoreChange);
|
|
1643
|
+
return () => {
|
|
1644
|
+
mediaQueryList.removeEventListener('change', onStoreChange);
|
|
1645
|
+
};
|
|
1646
|
+
}, () => typeof window !== 'undefined' ? window.matchMedia(query).matches : undefined, () => undefined);
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
function useScreenSize(size) {
|
|
1650
|
+
return useMedia(`(min-width: ${size}px)`);
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
/**
|
|
1654
|
+
* @deprecated Prefer `useScreenSize` instead.
|
|
1655
|
+
*/
|
|
1656
|
+
const useLayout = () => {
|
|
1657
|
+
const screenXs = useScreenSize(exports.Breakpoint.EXTRA_SMALL);
|
|
1658
|
+
const screenSm = useScreenSize(exports.Breakpoint.SMALL);
|
|
1659
|
+
const screenMd = useScreenSize(exports.Breakpoint.MEDIUM);
|
|
1660
|
+
const screenLg = useScreenSize(exports.Breakpoint.LARGE);
|
|
1661
|
+
const screenXl = useScreenSize(exports.Breakpoint.EXTRA_LARGE);
|
|
1662
|
+
return {
|
|
1663
|
+
isMobile: screenSm != null ? !screenSm : undefined,
|
|
1664
|
+
isExtraSmall: screenXs,
|
|
1665
|
+
isSmall: screenSm,
|
|
1666
|
+
isMedium: screenMd,
|
|
1667
|
+
isLarge: screenLg,
|
|
1668
|
+
isExtraLarge: screenXl
|
|
1669
|
+
};
|
|
1670
|
+
};
|
|
1671
|
+
|
|
1672
|
+
const EmptyTransparentImage = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
|
|
1673
|
+
const Image = ({
|
|
1674
|
+
id,
|
|
1675
|
+
src,
|
|
1676
|
+
alt,
|
|
1677
|
+
onLoad,
|
|
1678
|
+
onError,
|
|
1679
|
+
className,
|
|
1680
|
+
loading,
|
|
1681
|
+
stretch = true,
|
|
1682
|
+
role,
|
|
1683
|
+
shrink = true
|
|
1684
|
+
}) => {
|
|
1685
|
+
const elementReference = React.useRef(null);
|
|
1686
|
+
const [hasIntersected] = useHasIntersected({
|
|
1687
|
+
elRef: elementReference,
|
|
1688
|
+
loading
|
|
1689
|
+
});
|
|
1690
|
+
let imageSource = src;
|
|
1691
|
+
let imageOnLoad = onLoad;
|
|
1692
|
+
if (loading === 'lazy' && !hasIntersected) {
|
|
1693
|
+
imageSource = EmptyTransparentImage;
|
|
1694
|
+
imageOnLoad = undefined;
|
|
1695
|
+
}
|
|
1696
|
+
return /*#__PURE__*/jsxRuntime.jsx("img", {
|
|
1697
|
+
ref: elementReference,
|
|
1698
|
+
id: id,
|
|
1699
|
+
alt: alt,
|
|
1700
|
+
src: imageSource,
|
|
1701
|
+
className: classNames__default.default(['tw-image', {
|
|
1702
|
+
'tw-image__stretch': stretch,
|
|
1703
|
+
'tw-image__shrink': shrink
|
|
1704
|
+
}, className]),
|
|
1705
|
+
role: role,
|
|
1706
|
+
onLoad: imageOnLoad,
|
|
1707
|
+
onError: onError
|
|
1708
|
+
});
|
|
1709
|
+
};
|
|
1710
|
+
|
|
1711
|
+
const defaultPromoCardContext = {
|
|
1712
|
+
state: '',
|
|
1713
|
+
isDisabled: false,
|
|
1714
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
1715
|
+
onChange: () => {}
|
|
1716
|
+
};
|
|
1717
|
+
/**
|
|
1718
|
+
* The PromoCard context object.
|
|
1719
|
+
*/
|
|
1720
|
+
const PromoCardContext = /*#__PURE__*/React.createContext(defaultPromoCardContext);
|
|
1721
|
+
/**
|
|
1722
|
+
* A custom hook for accessing the PromoCard context object.
|
|
1723
|
+
*
|
|
1724
|
+
* The `usePromoCardContext` hook is used to access the PromoCard context object
|
|
1725
|
+
* from within a child PromoCard component. It throws an error if the context
|
|
1726
|
+
* object is not available, which can help with debugging and development.
|
|
1727
|
+
*
|
|
1728
|
+
* @returns {PromoCardContextType} - The PromoCard context object.
|
|
1729
|
+
*/
|
|
1730
|
+
const usePromoCardContext = () => {
|
|
1731
|
+
return React.useContext(PromoCardContext);
|
|
1732
|
+
};
|
|
1733
|
+
|
|
1734
|
+
const PromoCardIndicator = ({
|
|
1735
|
+
className,
|
|
1736
|
+
children,
|
|
1737
|
+
label,
|
|
1738
|
+
icon,
|
|
1739
|
+
isSmall = false,
|
|
1740
|
+
testid,
|
|
1741
|
+
...rest
|
|
1742
|
+
}) => {
|
|
1743
|
+
const isIconString = icon && typeof icon === 'string';
|
|
1744
|
+
const IconComponent = isIconString && {
|
|
1745
|
+
check: icons.Check,
|
|
1746
|
+
arrow: icons.ArrowRight,
|
|
1747
|
+
download: icons.Download
|
|
1748
|
+
}[icon];
|
|
1749
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
1750
|
+
className: classNames__default.default('np-Card-indicator', className),
|
|
1751
|
+
"data-testid": testid,
|
|
1752
|
+
...rest,
|
|
1753
|
+
children: [label && /*#__PURE__*/jsxRuntime.jsx(Body, {
|
|
1754
|
+
as: "span",
|
|
1755
|
+
type: exports.Typography.BODY_LARGE_BOLD,
|
|
1756
|
+
className: "np-Card-indicatorText",
|
|
1757
|
+
children: label
|
|
1758
|
+
}), icon && /*#__PURE__*/jsxRuntime.jsx(Avatar, {
|
|
1759
|
+
type: exports.AvatarType.ICON,
|
|
1760
|
+
size: isSmall ? 40 : 56,
|
|
1761
|
+
backgroundColor: "var(--Card-indicator-icon-background-color)",
|
|
1762
|
+
className: "np-Card-indicatorIcon",
|
|
1763
|
+
children: IconComponent ? /*#__PURE__*/jsxRuntime.jsx(IconComponent, {
|
|
1764
|
+
size: 24,
|
|
1765
|
+
"aria-hidden": "true"
|
|
1766
|
+
}) : icon
|
|
1767
|
+
}), children]
|
|
1768
|
+
});
|
|
1769
|
+
};
|
|
1770
|
+
|
|
1771
|
+
const PromoCard = /*#__PURE__*/React.forwardRef(({
|
|
1772
|
+
className,
|
|
1773
|
+
description,
|
|
1774
|
+
defaultChecked,
|
|
1775
|
+
download,
|
|
1776
|
+
href,
|
|
1777
|
+
hrefLang,
|
|
1778
|
+
id,
|
|
1779
|
+
headingLevel = 'h3',
|
|
1780
|
+
imageAlt,
|
|
1781
|
+
imageClass,
|
|
1782
|
+
imageSource,
|
|
1783
|
+
indicatorLabel,
|
|
1784
|
+
indicatorIcon,
|
|
1785
|
+
isChecked,
|
|
1786
|
+
isDisabled,
|
|
1787
|
+
onClick,
|
|
1788
|
+
onKeyDown,
|
|
1789
|
+
rel,
|
|
1790
|
+
tabIndex,
|
|
1791
|
+
target,
|
|
1792
|
+
testId,
|
|
1793
|
+
title,
|
|
1794
|
+
type,
|
|
1795
|
+
value,
|
|
1796
|
+
isSmall,
|
|
1797
|
+
useDisplayFont = true,
|
|
1798
|
+
anchorRef,
|
|
1799
|
+
anchorId,
|
|
1800
|
+
...props
|
|
1801
|
+
}, ref) => {
|
|
1802
|
+
// Set the `checked` state to the value of `defaultChecked` if it is truthy,
|
|
1803
|
+
// or the value of `isChecked` if it is truthy, or `false` if neither
|
|
1804
|
+
// is truthy.
|
|
1805
|
+
const {
|
|
1806
|
+
state,
|
|
1807
|
+
onChange,
|
|
1808
|
+
isDisabled: contextIsDisabled
|
|
1809
|
+
} = usePromoCardContext();
|
|
1810
|
+
const [checked, setChecked] = React.useState(type === 'checkbox' ? defaultChecked ?? isChecked ?? false : false);
|
|
1811
|
+
const handleClick = () => {
|
|
1812
|
+
if (type === 'radio') {
|
|
1813
|
+
onChange(value || ''); // Update the context state for radio
|
|
1814
|
+
} else if (type === 'checkbox') {
|
|
1815
|
+
setChecked(!checked); // Update local state for checkbox
|
|
1816
|
+
}
|
|
1817
|
+
};
|
|
1818
|
+
const fallbackId = React.useId();
|
|
1819
|
+
const componentId = id || fallbackId;
|
|
1820
|
+
// Set the icon to `'arrow'` if `href` is truthy and `type` is falsy, or
|
|
1821
|
+
// `'download'` if `download` is truthy. If neither condition is true, set
|
|
1822
|
+
// `icon` to `undefined`.
|
|
1823
|
+
// Create a function to get icon type
|
|
1824
|
+
const getIconType = () => {
|
|
1825
|
+
if (indicatorIcon) {
|
|
1826
|
+
return indicatorIcon;
|
|
1827
|
+
}
|
|
1828
|
+
if (download) {
|
|
1829
|
+
return 'download';
|
|
1830
|
+
}
|
|
1831
|
+
if (href && !type) {
|
|
1832
|
+
return 'arrow';
|
|
1833
|
+
}
|
|
1834
|
+
return undefined;
|
|
1835
|
+
};
|
|
1836
|
+
// Define all class names string based on the values of the `href`, `type`,
|
|
1837
|
+
// `checked`, and `className` props.
|
|
1838
|
+
const commonClasses = classNames__default.default({
|
|
1839
|
+
'np-Card--promoCard': true,
|
|
1840
|
+
'np-Card--checked': !href && type,
|
|
1841
|
+
'np-Card--link': href && !type,
|
|
1842
|
+
'is-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined
|
|
1843
|
+
}, className);
|
|
1844
|
+
// Object with common props that will be passed to the `Card` components
|
|
1845
|
+
const commonProps = {
|
|
1846
|
+
className: commonClasses,
|
|
1847
|
+
id: componentId,
|
|
1848
|
+
isDisabled: isDisabled || contextIsDisabled,
|
|
1849
|
+
onClick,
|
|
1850
|
+
onKeyDown,
|
|
1851
|
+
ref,
|
|
1852
|
+
'data-testid': testId,
|
|
1853
|
+
isSmall
|
|
1854
|
+
};
|
|
1855
|
+
// Object with Anchor props that will be passed to the `a` element. These
|
|
1856
|
+
// won't be refurned if set to `isDisabled`
|
|
1857
|
+
const anchorProps = href && !isDisabled ? {
|
|
1858
|
+
download,
|
|
1859
|
+
href: href || undefined,
|
|
1860
|
+
hrefLang,
|
|
1861
|
+
rel,
|
|
1862
|
+
target,
|
|
1863
|
+
ref: anchorRef,
|
|
1864
|
+
id: anchorId
|
|
1865
|
+
} : {};
|
|
1866
|
+
// Object of all Checked props that will be passed to the root `Card` component
|
|
1867
|
+
const checkedProps = (type === 'checkbox' || type === 'radio') && !href ? {
|
|
1868
|
+
...commonProps,
|
|
1869
|
+
'aria-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined,
|
|
1870
|
+
'aria-describedby': `${componentId}-title`,
|
|
1871
|
+
'aria-disabled': isDisabled,
|
|
1872
|
+
'data-value': value ?? undefined,
|
|
1873
|
+
role: type === 'checkbox' || type === 'radio' ? type : undefined,
|
|
1874
|
+
onClick: handleClick,
|
|
1875
|
+
onKeyDown: event => {
|
|
1876
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
1877
|
+
handleClick();
|
|
1878
|
+
}
|
|
1879
|
+
},
|
|
1880
|
+
ref,
|
|
1881
|
+
tabIndex: 0
|
|
1882
|
+
} : {};
|
|
1883
|
+
const getTitle = () => {
|
|
1884
|
+
const titleContent = href && !type ? /*#__PURE__*/jsxRuntime.jsx("a", {
|
|
1885
|
+
className: "np-Card-titleLink",
|
|
1886
|
+
...anchorProps,
|
|
1887
|
+
children: title
|
|
1888
|
+
}) : title;
|
|
1889
|
+
const titleProps = {
|
|
1890
|
+
id: `${componentId}-title`,
|
|
1891
|
+
as: headingLevel,
|
|
1892
|
+
className: 'np-Card-title'
|
|
1893
|
+
};
|
|
1894
|
+
return useDisplayFont ? /*#__PURE__*/jsxRuntime.jsx(Display, {
|
|
1895
|
+
type: exports.Typography.DISPLAY_SMALL,
|
|
1896
|
+
...titleProps,
|
|
1897
|
+
children: titleContent
|
|
1898
|
+
}) : /*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
1899
|
+
type: exports.Typography.TITLE_SUBSECTION,
|
|
1900
|
+
...titleProps,
|
|
1901
|
+
children: titleContent
|
|
1902
|
+
});
|
|
1903
|
+
};
|
|
1904
|
+
React.useEffect(() => {
|
|
1905
|
+
setChecked(defaultChecked ?? isChecked ?? false);
|
|
1906
|
+
}, [defaultChecked, isChecked]);
|
|
1907
|
+
return /*#__PURE__*/jsxRuntime.jsxs(Card$2, {
|
|
1908
|
+
...commonProps,
|
|
1909
|
+
...checkedProps,
|
|
1910
|
+
...props,
|
|
1911
|
+
children: [(value === state || checked) && /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
1912
|
+
className: "np-Card-check",
|
|
1913
|
+
children: /*#__PURE__*/jsxRuntime.jsx(icons.Check, {
|
|
1914
|
+
size: 24,
|
|
1915
|
+
"aria-hidden": "true"
|
|
1916
|
+
})
|
|
1917
|
+
}), getTitle(), /*#__PURE__*/jsxRuntime.jsx(Body, {
|
|
1918
|
+
className: "np-Card-description",
|
|
1919
|
+
children: description
|
|
1920
|
+
}), imageSource && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
1921
|
+
className: classNames__default.default('np-Card-image', {
|
|
1922
|
+
imageClass
|
|
1923
|
+
}),
|
|
1924
|
+
children: /*#__PURE__*/jsxRuntime.jsx(Image, {
|
|
1925
|
+
src: imageSource,
|
|
1926
|
+
alt: imageAlt || '',
|
|
1927
|
+
loading: "lazy"
|
|
1928
|
+
})
|
|
1929
|
+
}), /*#__PURE__*/jsxRuntime.jsx(PromoCardIndicator, {
|
|
1930
|
+
label: indicatorLabel,
|
|
1931
|
+
icon: getIconType(),
|
|
1932
|
+
isSmall: isSmall
|
|
1933
|
+
})]
|
|
1934
|
+
});
|
|
1935
|
+
});
|
|
1936
|
+
var PromoCard$1 = /*#__PURE__*/React__namespace.default.memo(PromoCard);
|
|
1937
|
+
|
|
1938
|
+
const LEFT_SCROLL_OFFSET = 8;
|
|
1939
|
+
const Carousel = ({
|
|
1940
|
+
header,
|
|
1941
|
+
className,
|
|
1942
|
+
cards,
|
|
1943
|
+
onClick
|
|
1944
|
+
}) => {
|
|
1945
|
+
const [scrollPosition, setScrollPosition] = React.useState(0);
|
|
1946
|
+
const [previousScrollPosition, setPreviousScrollPosition] = React.useState(0);
|
|
1947
|
+
const [scrollIsAtEnd, setScrollIsAtEnd] = React.useState(false);
|
|
1948
|
+
const [visibleCardOnMobileView, setVisibleCardOnMobileView] = React.useState('');
|
|
1949
|
+
const carouselElementRef = React.useRef(null);
|
|
1950
|
+
const carouselCardsRef = React.useRef([]);
|
|
1951
|
+
const isLeftActionButtonEnabled = scrollPosition > LEFT_SCROLL_OFFSET;
|
|
1952
|
+
const areActionButtonsEnabled = isLeftActionButtonEnabled || !scrollIsAtEnd;
|
|
1953
|
+
const [focusedCard, setFocusedCard] = React.useState(cards?.[0]?.id);
|
|
1954
|
+
const updateScrollButtonsState = () => {
|
|
1955
|
+
if (carouselElementRef.current) {
|
|
1956
|
+
const {
|
|
1957
|
+
scrollWidth,
|
|
1958
|
+
offsetWidth
|
|
1959
|
+
} = carouselElementRef.current;
|
|
1960
|
+
const scrollAtEnd = scrollWidth - offsetWidth <= scrollPosition + LEFT_SCROLL_OFFSET;
|
|
1961
|
+
setScrollIsAtEnd(scrollAtEnd);
|
|
1962
|
+
}
|
|
1963
|
+
const scrollDirecton = scrollPosition > previousScrollPosition ? 'right' : 'left';
|
|
1964
|
+
const cardsInFullViewIds = [];
|
|
1965
|
+
carouselCardsRef.current.forEach(card => {
|
|
1966
|
+
if (isVisible(carouselElementRef.current, card.cardElement)) {
|
|
1967
|
+
// eslint-disable-next-line functional/immutable-data
|
|
1968
|
+
cardsInFullViewIds.push(card.cardElement.getAttribute('id') ?? '');
|
|
1969
|
+
}
|
|
1970
|
+
});
|
|
1971
|
+
if (cardsInFullViewIds.length >= 1) {
|
|
1972
|
+
const visibleCardIndex = scrollDirecton === 'right' ? cardsInFullViewIds.length - 1 : 0;
|
|
1973
|
+
const visibleCardId = cardsInFullViewIds[visibleCardIndex];
|
|
1974
|
+
setVisibleCardOnMobileView(visibleCardId);
|
|
1975
|
+
setFocusedCard(visibleCardId);
|
|
1976
|
+
}
|
|
1977
|
+
setPreviousScrollPosition(scrollPosition);
|
|
1978
|
+
};
|
|
1979
|
+
const scrollCarousel = (direction = 'right') => {
|
|
1980
|
+
if (carouselElementRef.current) {
|
|
1981
|
+
const {
|
|
1982
|
+
scrollWidth
|
|
1983
|
+
} = carouselElementRef.current;
|
|
1984
|
+
const cardWidth = scrollWidth / carouselCardsRef.current.length;
|
|
1985
|
+
const res = Math.floor(cardWidth - cardWidth * 0.05);
|
|
1986
|
+
carouselElementRef.current.scrollBy({
|
|
1987
|
+
left: direction === 'right' ? res : -res,
|
|
1988
|
+
behavior: 'smooth'
|
|
1989
|
+
});
|
|
1990
|
+
}
|
|
1991
|
+
};
|
|
1992
|
+
const handleOnKeyDown = (event, index) => {
|
|
1993
|
+
if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
|
|
1994
|
+
const nextIndex = event.key === 'ArrowRight' ? index + 1 : index - 1;
|
|
1995
|
+
const nextCard = cards[nextIndex];
|
|
1996
|
+
if (nextCard) {
|
|
1997
|
+
const ref = carouselCardsRef.current[nextIndex];
|
|
1998
|
+
if (ref.type === 'promo') {
|
|
1999
|
+
ref.anchorElement?.focus();
|
|
2000
|
+
} else {
|
|
2001
|
+
ref.cardElement?.focus();
|
|
2002
|
+
}
|
|
2003
|
+
scrollCardIntoView(carouselCardsRef.current[nextIndex].cardElement, nextCard);
|
|
2004
|
+
event.preventDefault();
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
2008
|
+
event.currentTarget.click();
|
|
2009
|
+
}
|
|
2010
|
+
};
|
|
2011
|
+
const scrollCardIntoView = (element, card) => {
|
|
2012
|
+
element.scrollIntoView({
|
|
2013
|
+
behavior: 'smooth',
|
|
2014
|
+
block: 'nearest',
|
|
2015
|
+
inline: 'center'
|
|
2016
|
+
});
|
|
2017
|
+
setFocusedCard(card.id);
|
|
2018
|
+
};
|
|
2019
|
+
React.useEffect(() => {
|
|
2020
|
+
updateScrollButtonsState();
|
|
2021
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2022
|
+
}, [scrollPosition]);
|
|
2023
|
+
React.useEffect(() => {
|
|
2024
|
+
window.addEventListener('resize', updateScrollButtonsState);
|
|
2025
|
+
return () => {
|
|
2026
|
+
window.removeEventListener('resize', updateScrollButtonsState);
|
|
2027
|
+
};
|
|
2028
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2029
|
+
}, []);
|
|
2030
|
+
const addElementToCardsRefArray = (index, ref) => {
|
|
2031
|
+
if (ref) {
|
|
2032
|
+
// eslint-disable-next-line functional/immutable-data
|
|
2033
|
+
carouselCardsRef.current[index] = {
|
|
2034
|
+
type: ref.type ?? carouselCardsRef.current?.[index]?.type,
|
|
2035
|
+
cardElement: ref.cardElement ?? carouselCardsRef.current?.[index]?.cardElement,
|
|
2036
|
+
anchorElement: ref.anchorElement ?? carouselCardsRef.current?.[index]?.anchorElement
|
|
2037
|
+
};
|
|
2038
|
+
}
|
|
2039
|
+
};
|
|
2040
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
2041
|
+
className: classNames__default.default('carousel-wrapper', className),
|
|
2042
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
2043
|
+
className: "d-flex justify-content-between carousel__header",
|
|
2044
|
+
children: [typeof header === 'string' ? /*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
2045
|
+
as: "span",
|
|
2046
|
+
type: "title-body",
|
|
2047
|
+
children: header
|
|
2048
|
+
}) : header, areActionButtonsEnabled ? /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
2049
|
+
className: "hidden-xs",
|
|
2050
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(ActionButton, {
|
|
2051
|
+
className: "carousel__scroll-button",
|
|
2052
|
+
tabIndex: -1,
|
|
2053
|
+
priority: "secondary",
|
|
2054
|
+
disabled: !isLeftActionButtonEnabled,
|
|
2055
|
+
"aria-hidden": "true",
|
|
2056
|
+
"data-testid": "scroll-carousel-left",
|
|
2057
|
+
onClick: () => scrollCarousel('left'),
|
|
2058
|
+
children: /*#__PURE__*/jsxRuntime.jsx(icons.ChevronLeft, {})
|
|
2059
|
+
}), /*#__PURE__*/jsxRuntime.jsx(ActionButton, {
|
|
2060
|
+
tabIndex: -1,
|
|
2061
|
+
className: "carousel__scroll-button m-l-1",
|
|
2062
|
+
priority: "secondary",
|
|
2063
|
+
"aria-hidden": "true",
|
|
2064
|
+
"data-testid": "scroll-carousel-right",
|
|
2065
|
+
disabled: scrollIsAtEnd,
|
|
2066
|
+
onClick: () => scrollCarousel(),
|
|
2067
|
+
children: /*#__PURE__*/jsxRuntime.jsx(icons.ChevronRight, {})
|
|
2068
|
+
})]
|
|
2069
|
+
}) : null]
|
|
2070
|
+
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2071
|
+
ref: carouselElementRef,
|
|
2072
|
+
tabIndex: -1,
|
|
2073
|
+
role: "list",
|
|
2074
|
+
className: "carousel",
|
|
2075
|
+
onScroll: event => {
|
|
2076
|
+
const target = event.target;
|
|
2077
|
+
setScrollPosition(target.scrollLeft);
|
|
2078
|
+
},
|
|
2079
|
+
children: cards?.map((card, index) => {
|
|
2080
|
+
const sharedProps = {
|
|
2081
|
+
id: card.id,
|
|
2082
|
+
className: classNames__default.default('carousel__card', {
|
|
2083
|
+
'carousel__card--focused': card.id === focusedCard
|
|
2084
|
+
}),
|
|
2085
|
+
onClick: () => {
|
|
2086
|
+
card.onClick?.();
|
|
2087
|
+
onClick?.(card.id);
|
|
2088
|
+
},
|
|
2089
|
+
onFocus: event => {
|
|
2090
|
+
scrollCardIntoView(event.currentTarget, card);
|
|
2091
|
+
}
|
|
2092
|
+
};
|
|
2093
|
+
const cardContent = card.type !== 'promo' ? /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2094
|
+
id: `${card.id}-content`,
|
|
2095
|
+
className: classNames__default.default('carousel__card-content', {
|
|
2096
|
+
[card.className ?? '']: !!card.className
|
|
2097
|
+
})
|
|
2098
|
+
// eslint-disable-next-line react/forbid-dom-props
|
|
2099
|
+
,
|
|
2100
|
+
style: card.styles,
|
|
2101
|
+
children: card.content
|
|
2102
|
+
}) : null;
|
|
2103
|
+
if (card.type === 'button') {
|
|
2104
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2105
|
+
"aria-labelledby": `${card.id}-content`,
|
|
2106
|
+
role: "listitem",
|
|
2107
|
+
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2108
|
+
...sharedProps,
|
|
2109
|
+
ref: el => {
|
|
2110
|
+
if (el) {
|
|
2111
|
+
// eslint-disable-next-line functional/immutable-data
|
|
2112
|
+
carouselCardsRef.current[index] = {
|
|
2113
|
+
type: 'default',
|
|
2114
|
+
cardElement: el
|
|
2115
|
+
};
|
|
2116
|
+
}
|
|
2117
|
+
},
|
|
2118
|
+
role: "button",
|
|
2119
|
+
tabIndex: 0,
|
|
2120
|
+
onKeyDown: event => handleOnKeyDown(event, index),
|
|
2121
|
+
children: cardContent
|
|
2122
|
+
})
|
|
2123
|
+
}, card.id);
|
|
2124
|
+
}
|
|
2125
|
+
if (card.type === 'promo') {
|
|
2126
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2127
|
+
id: card.id,
|
|
2128
|
+
role: "listitem",
|
|
2129
|
+
"aria-labelledby": `${card.id}-anchor`,
|
|
2130
|
+
children: /*#__PURE__*/jsxRuntime.jsx(PromoCard$1, {
|
|
2131
|
+
...card,
|
|
2132
|
+
type: undefined,
|
|
2133
|
+
...sharedProps,
|
|
2134
|
+
ref: el => {
|
|
2135
|
+
if (el) {
|
|
2136
|
+
addElementToCardsRefArray(index, {
|
|
2137
|
+
type: 'promo',
|
|
2138
|
+
cardElement: el
|
|
2139
|
+
});
|
|
2140
|
+
}
|
|
2141
|
+
},
|
|
2142
|
+
anchorRef: el => {
|
|
2143
|
+
if (el) {
|
|
2144
|
+
addElementToCardsRefArray(index, {
|
|
2145
|
+
type: 'promo',
|
|
2146
|
+
anchorElement: el
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
2149
|
+
},
|
|
2150
|
+
anchorId: `${card.id}-anchor`,
|
|
2151
|
+
onKeyDown: event => handleOnKeyDown(event, index)
|
|
2152
|
+
})
|
|
2153
|
+
}, card.id);
|
|
2154
|
+
}
|
|
2155
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2156
|
+
"aria-labelledby": `${card.id}-content`,
|
|
2157
|
+
role: "listitem",
|
|
2158
|
+
children: /*#__PURE__*/jsxRuntime.jsx("a", {
|
|
2159
|
+
...sharedProps,
|
|
2160
|
+
ref: el => {
|
|
2161
|
+
if (el) {
|
|
2162
|
+
// eslint-disable-next-line functional/immutable-data
|
|
2163
|
+
carouselCardsRef.current[index] = {
|
|
2164
|
+
type: 'default',
|
|
2165
|
+
cardElement: el
|
|
2166
|
+
};
|
|
2167
|
+
}
|
|
2168
|
+
},
|
|
2169
|
+
href: card.href,
|
|
2170
|
+
rel: "noreferrer",
|
|
2171
|
+
onKeyDown: event => handleOnKeyDown(event, index),
|
|
2172
|
+
children: cardContent
|
|
2173
|
+
})
|
|
2174
|
+
}, card.id);
|
|
2175
|
+
})
|
|
2176
|
+
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2177
|
+
className: "visible-xs",
|
|
2178
|
+
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
2179
|
+
className: "carousel__indicators",
|
|
2180
|
+
children: cards?.map((card, index) => /*#__PURE__*/jsxRuntime.jsx("button", {
|
|
2181
|
+
"data-testid": `${card.id}-indicator`,
|
|
2182
|
+
tabIndex: -1,
|
|
2183
|
+
"aria-hidden": true,
|
|
2184
|
+
type: "button",
|
|
2185
|
+
className: classNames__default.default('carousel__indicator', {
|
|
2186
|
+
'carousel__indicator--selected': card.id === visibleCardOnMobileView
|
|
2187
|
+
}),
|
|
2188
|
+
onClick: () => {
|
|
2189
|
+
scrollCardIntoView(carouselCardsRef.current[index].cardElement, card);
|
|
2190
|
+
}
|
|
2191
|
+
}, `${card.id}-indicator`))
|
|
2192
|
+
})
|
|
2193
|
+
})]
|
|
2194
|
+
});
|
|
2195
|
+
};
|
|
2196
|
+
const isVisible = (container, el) => {
|
|
2197
|
+
const cWidth = container.offsetWidth;
|
|
2198
|
+
const cScrollOffset = container.scrollLeft;
|
|
2199
|
+
const elemLeft = el.offsetLeft - container.offsetLeft;
|
|
2200
|
+
const elemRight = elemLeft + el.offsetWidth;
|
|
2201
|
+
return elemLeft >= cScrollOffset && elemRight <= cScrollOffset + cWidth;
|
|
2202
|
+
};
|
|
2203
|
+
|
|
2204
|
+
const Card = /*#__PURE__*/React.forwardRef((props, reference) => {
|
|
1496
2205
|
const {
|
|
1497
2206
|
'aria-label': ariaLabel,
|
|
1498
2207
|
as: Element,
|
|
@@ -1543,7 +2252,7 @@ const Card$1 = /*#__PURE__*/React.forwardRef((props, reference) => {
|
|
|
1543
2252
|
const hasChildren = ({
|
|
1544
2253
|
children
|
|
1545
2254
|
}) => children;
|
|
1546
|
-
Card
|
|
2255
|
+
Card.propTypes = {
|
|
1547
2256
|
'aria-label': PropTypes__default.default.string,
|
|
1548
2257
|
as: PropTypes__default.default.string,
|
|
1549
2258
|
isExpanded: requiredIf__default.default(PropTypes__default.default.bool, hasChildren),
|
|
@@ -1556,7 +2265,7 @@ Card$1.propTypes = {
|
|
|
1556
2265
|
className: PropTypes__default.default.string,
|
|
1557
2266
|
'data-testid': PropTypes__default.default.string
|
|
1558
2267
|
};
|
|
1559
|
-
Card
|
|
2268
|
+
Card.defaultProps = {
|
|
1560
2269
|
'aria-label': undefined,
|
|
1561
2270
|
as: 'div',
|
|
1562
2271
|
children: null,
|
|
@@ -1564,7 +2273,7 @@ Card$1.defaultProps = {
|
|
|
1564
2273
|
className: null,
|
|
1565
2274
|
'data-testid': null
|
|
1566
2275
|
};
|
|
1567
|
-
var Card$
|
|
2276
|
+
var Card$1 = Card;
|
|
1568
2277
|
|
|
1569
2278
|
const CheckboxButton = /*#__PURE__*/React.forwardRef(({
|
|
1570
2279
|
checked,
|
|
@@ -2050,134 +2759,6 @@ const DimmerContentWrapper = ({
|
|
|
2050
2759
|
};
|
|
2051
2760
|
var Dimmer$1 = withNextPortalWrapper(Dimmer);
|
|
2052
2761
|
|
|
2053
|
-
const useConditionalListener = ({
|
|
2054
|
-
attachListener,
|
|
2055
|
-
callback,
|
|
2056
|
-
eventType,
|
|
2057
|
-
parent
|
|
2058
|
-
}) => {
|
|
2059
|
-
React.useEffect(() => {
|
|
2060
|
-
if (attachListener && !neptuneValidation.isUndefined(parent)) {
|
|
2061
|
-
parent.addEventListener(eventType, callback, true);
|
|
2062
|
-
}
|
|
2063
|
-
return () => {
|
|
2064
|
-
if (!neptuneValidation.isUndefined(parent)) {
|
|
2065
|
-
parent.removeEventListener(eventType, callback, true);
|
|
2066
|
-
}
|
|
2067
|
-
};
|
|
2068
|
-
}, [attachListener, callback, eventType, parent]);
|
|
2069
|
-
};
|
|
2070
|
-
|
|
2071
|
-
const DirectionContext = /*#__PURE__*/React.createContext(exports.Direction.LTR);
|
|
2072
|
-
const DirectionProvider = ({
|
|
2073
|
-
direction,
|
|
2074
|
-
children
|
|
2075
|
-
}) => {
|
|
2076
|
-
return /*#__PURE__*/jsxRuntime.jsx(DirectionContext.Provider, {
|
|
2077
|
-
value: direction,
|
|
2078
|
-
children: children
|
|
2079
|
-
});
|
|
2080
|
-
};
|
|
2081
|
-
|
|
2082
|
-
const useDirection = () => {
|
|
2083
|
-
const direction = React.useContext(DirectionContext);
|
|
2084
|
-
return {
|
|
2085
|
-
direction,
|
|
2086
|
-
isRTL: direction === 'rtl'
|
|
2087
|
-
};
|
|
2088
|
-
};
|
|
2089
|
-
|
|
2090
|
-
const ObserverParams = {
|
|
2091
|
-
threshold: 0.1
|
|
2092
|
-
};
|
|
2093
|
-
|
|
2094
|
-
/**
|
|
2095
|
-
* useHasIntersected.
|
|
2096
|
-
* Use this custom hook to detect when an element has became visible inside the viewport. This hook checks only if the intersection happend.
|
|
2097
|
-
* Once the intersection has happened the hook will not return false even if the element gets out of the viewport.
|
|
2098
|
-
*
|
|
2099
|
-
* @param elRef.elRef
|
|
2100
|
-
* @param {object} [elRef] - node object that contains a react reference to the element that needs to be observed.
|
|
2101
|
-
* @param {strimng} [loading = 'eager'] - string that contains the type of loading.
|
|
2102
|
-
* @param elRef.loading
|
|
2103
|
-
* @usage `const [hasIntersected] = useHasIntersected({imageRef,loading});`
|
|
2104
|
-
*/
|
|
2105
|
-
const useHasIntersected = ({
|
|
2106
|
-
elRef,
|
|
2107
|
-
loading
|
|
2108
|
-
}) => {
|
|
2109
|
-
const [hasIntersected, setHasIntersected] = React.useState(false);
|
|
2110
|
-
const {
|
|
2111
|
-
current
|
|
2112
|
-
} = elRef || {};
|
|
2113
|
-
const isValidReference = () => {
|
|
2114
|
-
return elRef && current;
|
|
2115
|
-
};
|
|
2116
|
-
const handleOnIntersect = (entries, observer) => {
|
|
2117
|
-
entries.forEach(entry => {
|
|
2118
|
-
if (entry.isIntersecting) {
|
|
2119
|
-
setHasIntersected(true);
|
|
2120
|
-
observer.unobserve(current);
|
|
2121
|
-
}
|
|
2122
|
-
});
|
|
2123
|
-
};
|
|
2124
|
-
React.useEffect(() => {
|
|
2125
|
-
let observer;
|
|
2126
|
-
let didCancel = false;
|
|
2127
|
-
|
|
2128
|
-
// Check if window is define for SSR and Old browsers fallback
|
|
2129
|
-
if (typeof window === 'undefined' || !window.IntersectionObserver || !isValidReference()) {
|
|
2130
|
-
setHasIntersected(true);
|
|
2131
|
-
} else if (!didCancel) {
|
|
2132
|
-
observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
|
|
2133
|
-
observer.observe(current);
|
|
2134
|
-
}
|
|
2135
|
-
return () => {
|
|
2136
|
-
didCancel = true;
|
|
2137
|
-
if (observer) {
|
|
2138
|
-
observer.unobserve(current);
|
|
2139
|
-
}
|
|
2140
|
-
};
|
|
2141
|
-
}, [elRef]);
|
|
2142
|
-
if (loading === 'eager') {
|
|
2143
|
-
return [false];
|
|
2144
|
-
}
|
|
2145
|
-
return [hasIntersected];
|
|
2146
|
-
};
|
|
2147
|
-
|
|
2148
|
-
function useMedia(query) {
|
|
2149
|
-
return React.useSyncExternalStore(onStoreChange => {
|
|
2150
|
-
const mediaQueryList = window.matchMedia(query);
|
|
2151
|
-
mediaQueryList.addEventListener('change', onStoreChange);
|
|
2152
|
-
return () => {
|
|
2153
|
-
mediaQueryList.removeEventListener('change', onStoreChange);
|
|
2154
|
-
};
|
|
2155
|
-
}, () => typeof window !== 'undefined' ? window.matchMedia(query).matches : undefined, () => undefined);
|
|
2156
|
-
}
|
|
2157
|
-
|
|
2158
|
-
function useScreenSize(size) {
|
|
2159
|
-
return useMedia(`(min-width: ${size}px)`);
|
|
2160
|
-
}
|
|
2161
|
-
|
|
2162
|
-
/**
|
|
2163
|
-
* @deprecated Prefer `useScreenSize` instead.
|
|
2164
|
-
*/
|
|
2165
|
-
const useLayout = () => {
|
|
2166
|
-
const screenXs = useScreenSize(exports.Breakpoint.EXTRA_SMALL);
|
|
2167
|
-
const screenSm = useScreenSize(exports.Breakpoint.SMALL);
|
|
2168
|
-
const screenMd = useScreenSize(exports.Breakpoint.MEDIUM);
|
|
2169
|
-
const screenLg = useScreenSize(exports.Breakpoint.LARGE);
|
|
2170
|
-
const screenXl = useScreenSize(exports.Breakpoint.EXTRA_LARGE);
|
|
2171
|
-
return {
|
|
2172
|
-
isMobile: screenSm != null ? !screenSm : undefined,
|
|
2173
|
-
isExtraSmall: screenXs,
|
|
2174
|
-
isSmall: screenSm,
|
|
2175
|
-
isMedium: screenMd,
|
|
2176
|
-
isLarge: screenLg,
|
|
2177
|
-
isExtraLarge: screenXl
|
|
2178
|
-
};
|
|
2179
|
-
};
|
|
2180
|
-
|
|
2181
2762
|
const EXIT_ANIMATION = 350;
|
|
2182
2763
|
const SlidingPanel = /*#__PURE__*/React.forwardRef(({
|
|
2183
2764
|
position = 'left',
|
|
@@ -2457,39 +3038,6 @@ const BottomSheet$1 = props => {
|
|
|
2457
3038
|
});
|
|
2458
3039
|
};
|
|
2459
3040
|
|
|
2460
|
-
const Card = ({
|
|
2461
|
-
className,
|
|
2462
|
-
children = null,
|
|
2463
|
-
id,
|
|
2464
|
-
isDisabled = false,
|
|
2465
|
-
isSmall = false,
|
|
2466
|
-
onDismiss,
|
|
2467
|
-
testId,
|
|
2468
|
-
...props
|
|
2469
|
-
}) => {
|
|
2470
|
-
const closeButtonReference = React.useRef(null);
|
|
2471
|
-
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
2472
|
-
className: classNames__default.default('np-Card', {
|
|
2473
|
-
'np-Card--small': !!isSmall,
|
|
2474
|
-
'is-disabled': !!isDisabled
|
|
2475
|
-
}, className),
|
|
2476
|
-
id: id,
|
|
2477
|
-
"data-testid": testId,
|
|
2478
|
-
...props,
|
|
2479
|
-
children: [onDismiss && /*#__PURE__*/jsxRuntime.jsx(CloseButton, {
|
|
2480
|
-
ref: closeButtonReference,
|
|
2481
|
-
className: "np-Card-closeButton",
|
|
2482
|
-
size: isSmall ? 'sm' : 'md',
|
|
2483
|
-
isDisabled: isDisabled,
|
|
2484
|
-
testId: "close-button",
|
|
2485
|
-
onClick: e => {
|
|
2486
|
-
stopPropagation$1(e);
|
|
2487
|
-
onDismiss();
|
|
2488
|
-
}
|
|
2489
|
-
}), children]
|
|
2490
|
-
});
|
|
2491
|
-
};
|
|
2492
|
-
|
|
2493
3041
|
function CriticalCommsBanner({
|
|
2494
3042
|
title,
|
|
2495
3043
|
subtitle,
|
|
@@ -4347,20 +4895,6 @@ DefinitionList.defaultProps = {
|
|
|
4347
4895
|
};
|
|
4348
4896
|
var DefinitionList$1 = DefinitionList;
|
|
4349
4897
|
|
|
4350
|
-
function Display({
|
|
4351
|
-
as: Heading = 'h1',
|
|
4352
|
-
type = exports.Typography.DISPLAY_LARGE,
|
|
4353
|
-
children,
|
|
4354
|
-
className,
|
|
4355
|
-
id
|
|
4356
|
-
}) {
|
|
4357
|
-
return /*#__PURE__*/jsxRuntime.jsx(Heading, {
|
|
4358
|
-
id: id,
|
|
4359
|
-
className: classNames__default.default(`np-text-${type}`, 'text-primary', className),
|
|
4360
|
-
children: children
|
|
4361
|
-
});
|
|
4362
|
-
}
|
|
4363
|
-
|
|
4364
4898
|
const DropFade = ({
|
|
4365
4899
|
children,
|
|
4366
4900
|
show
|
|
@@ -5042,71 +5576,32 @@ const HeaderAction = ({
|
|
|
5042
5576
|
*/
|
|
5043
5577
|
const Header = ({
|
|
5044
5578
|
action,
|
|
5045
|
-
as = 'h5',
|
|
5046
|
-
title,
|
|
5047
|
-
className
|
|
5048
|
-
}) => {
|
|
5049
|
-
if (!action) {
|
|
5050
|
-
return /*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
5051
|
-
as: as,
|
|
5052
|
-
type: exports.Typography.TITLE_GROUP,
|
|
5053
|
-
className: classNames__default.default('np-header', 'np-header__title', className),
|
|
5054
|
-
children: title
|
|
5055
|
-
});
|
|
5056
|
-
}
|
|
5057
|
-
if (as === 'legend') {
|
|
5058
|
-
// eslint-disable-next-line no-console
|
|
5059
|
-
console.warn('Legends should be the first child in a fieldset, and this is not possible when including an action');
|
|
5060
|
-
}
|
|
5061
|
-
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
5062
|
-
className: classNames__default.default('np-header', className),
|
|
5063
|
-
children: [/*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
5064
|
-
as: as,
|
|
5065
|
-
type: exports.Typography.TITLE_GROUP,
|
|
5066
|
-
className: "np-header__title",
|
|
5067
|
-
children: title
|
|
5068
|
-
}), /*#__PURE__*/jsxRuntime.jsx(HeaderAction, {
|
|
5069
|
-
action: action
|
|
5070
|
-
})]
|
|
5071
|
-
});
|
|
5072
|
-
};
|
|
5073
|
-
|
|
5074
|
-
const EmptyTransparentImage = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
|
|
5075
|
-
const Image = ({
|
|
5076
|
-
id,
|
|
5077
|
-
src,
|
|
5078
|
-
alt,
|
|
5079
|
-
onLoad,
|
|
5080
|
-
onError,
|
|
5081
|
-
className,
|
|
5082
|
-
loading,
|
|
5083
|
-
stretch = true,
|
|
5084
|
-
role,
|
|
5085
|
-
shrink = true
|
|
5086
|
-
}) => {
|
|
5087
|
-
const elementReference = React.useRef(null);
|
|
5088
|
-
const [hasIntersected] = useHasIntersected({
|
|
5089
|
-
elRef: elementReference,
|
|
5090
|
-
loading
|
|
5091
|
-
});
|
|
5092
|
-
let imageSource = src;
|
|
5093
|
-
let imageOnLoad = onLoad;
|
|
5094
|
-
if (loading === 'lazy' && !hasIntersected) {
|
|
5095
|
-
imageSource = EmptyTransparentImage;
|
|
5096
|
-
imageOnLoad = undefined;
|
|
5579
|
+
as = 'h5',
|
|
5580
|
+
title,
|
|
5581
|
+
className
|
|
5582
|
+
}) => {
|
|
5583
|
+
if (!action) {
|
|
5584
|
+
return /*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
5585
|
+
as: as,
|
|
5586
|
+
type: exports.Typography.TITLE_GROUP,
|
|
5587
|
+
className: classNames__default.default('np-header', 'np-header__title', className),
|
|
5588
|
+
children: title
|
|
5589
|
+
});
|
|
5097
5590
|
}
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
className: classNames__default.default(
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5591
|
+
if (as === 'legend') {
|
|
5592
|
+
// eslint-disable-next-line no-console
|
|
5593
|
+
console.warn('Legends should be the first child in a fieldset, and this is not possible when including an action');
|
|
5594
|
+
}
|
|
5595
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
5596
|
+
className: classNames__default.default('np-header', className),
|
|
5597
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
5598
|
+
as: as,
|
|
5599
|
+
type: exports.Typography.TITLE_GROUP,
|
|
5600
|
+
className: "np-header__title",
|
|
5601
|
+
children: title
|
|
5602
|
+
}), /*#__PURE__*/jsxRuntime.jsx(HeaderAction, {
|
|
5603
|
+
action: action
|
|
5604
|
+
})]
|
|
5110
5605
|
});
|
|
5111
5606
|
};
|
|
5112
5607
|
|
|
@@ -8977,227 +9472,6 @@ const ProgressBar = ({
|
|
|
8977
9472
|
});
|
|
8978
9473
|
};
|
|
8979
9474
|
|
|
8980
|
-
const defaultPromoCardContext = {
|
|
8981
|
-
state: '',
|
|
8982
|
-
isDisabled: false,
|
|
8983
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
8984
|
-
onChange: () => {}
|
|
8985
|
-
};
|
|
8986
|
-
/**
|
|
8987
|
-
* The PromoCard context object.
|
|
8988
|
-
*/
|
|
8989
|
-
const PromoCardContext = /*#__PURE__*/React.createContext(defaultPromoCardContext);
|
|
8990
|
-
/**
|
|
8991
|
-
* A custom hook for accessing the PromoCard context object.
|
|
8992
|
-
*
|
|
8993
|
-
* The `usePromoCardContext` hook is used to access the PromoCard context object
|
|
8994
|
-
* from within a child PromoCard component. It throws an error if the context
|
|
8995
|
-
* object is not available, which can help with debugging and development.
|
|
8996
|
-
*
|
|
8997
|
-
* @returns {PromoCardContextType} - The PromoCard context object.
|
|
8998
|
-
*/
|
|
8999
|
-
const usePromoCardContext = () => {
|
|
9000
|
-
return React.useContext(PromoCardContext);
|
|
9001
|
-
};
|
|
9002
|
-
|
|
9003
|
-
const PromoCardIndicator = ({
|
|
9004
|
-
className,
|
|
9005
|
-
children,
|
|
9006
|
-
label,
|
|
9007
|
-
icon,
|
|
9008
|
-
isSmall = false,
|
|
9009
|
-
testid,
|
|
9010
|
-
...rest
|
|
9011
|
-
}) => {
|
|
9012
|
-
const isIconString = icon && typeof icon === 'string';
|
|
9013
|
-
const IconComponent = isIconString && {
|
|
9014
|
-
check: icons.Check,
|
|
9015
|
-
arrow: icons.ArrowRight,
|
|
9016
|
-
download: icons.Download
|
|
9017
|
-
}[icon];
|
|
9018
|
-
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
9019
|
-
className: classNames__default.default('np-Card-indicator', className),
|
|
9020
|
-
"data-testid": testid,
|
|
9021
|
-
...rest,
|
|
9022
|
-
children: [label && /*#__PURE__*/jsxRuntime.jsx(Body, {
|
|
9023
|
-
as: "span",
|
|
9024
|
-
type: exports.Typography.BODY_LARGE_BOLD,
|
|
9025
|
-
className: "np-Card-indicatorText",
|
|
9026
|
-
children: label
|
|
9027
|
-
}), icon && /*#__PURE__*/jsxRuntime.jsx(Avatar, {
|
|
9028
|
-
type: exports.AvatarType.ICON,
|
|
9029
|
-
size: isSmall ? 40 : 56,
|
|
9030
|
-
backgroundColor: "var(--Card-indicator-icon-background-color)",
|
|
9031
|
-
className: "np-Card-indicatorIcon",
|
|
9032
|
-
children: IconComponent ? /*#__PURE__*/jsxRuntime.jsx(IconComponent, {
|
|
9033
|
-
size: 24,
|
|
9034
|
-
"aria-hidden": "true"
|
|
9035
|
-
}) : icon
|
|
9036
|
-
}), children]
|
|
9037
|
-
});
|
|
9038
|
-
};
|
|
9039
|
-
|
|
9040
|
-
const PromoCard = /*#__PURE__*/React.forwardRef(({
|
|
9041
|
-
className,
|
|
9042
|
-
description,
|
|
9043
|
-
defaultChecked,
|
|
9044
|
-
download,
|
|
9045
|
-
href,
|
|
9046
|
-
hrefLang,
|
|
9047
|
-
id,
|
|
9048
|
-
headingLevel = 'h3',
|
|
9049
|
-
imageAlt,
|
|
9050
|
-
imageClass,
|
|
9051
|
-
imageSource,
|
|
9052
|
-
indicatorLabel,
|
|
9053
|
-
indicatorIcon,
|
|
9054
|
-
isChecked,
|
|
9055
|
-
isDisabled,
|
|
9056
|
-
onClick,
|
|
9057
|
-
rel,
|
|
9058
|
-
tabIndex,
|
|
9059
|
-
target,
|
|
9060
|
-
testId,
|
|
9061
|
-
title,
|
|
9062
|
-
type,
|
|
9063
|
-
value,
|
|
9064
|
-
isSmall,
|
|
9065
|
-
useDisplayFont = true,
|
|
9066
|
-
...props
|
|
9067
|
-
}, reference) => {
|
|
9068
|
-
// Set the `checked` state to the value of `defaultChecked` if it is truthy,
|
|
9069
|
-
// or the value of `isChecked` if it is truthy, or `false` if neither
|
|
9070
|
-
// is truthy.
|
|
9071
|
-
const {
|
|
9072
|
-
state,
|
|
9073
|
-
onChange,
|
|
9074
|
-
isDisabled: contextIsDisabled
|
|
9075
|
-
} = usePromoCardContext();
|
|
9076
|
-
const [checked, setChecked] = React.useState(type === 'checkbox' ? defaultChecked ?? isChecked ?? false : false);
|
|
9077
|
-
const handleClick = () => {
|
|
9078
|
-
if (type === 'radio') {
|
|
9079
|
-
onChange(value || ''); // Update the context state for radio
|
|
9080
|
-
} else if (type === 'checkbox') {
|
|
9081
|
-
setChecked(!checked); // Update local state for checkbox
|
|
9082
|
-
}
|
|
9083
|
-
};
|
|
9084
|
-
const fallbackId = React.useId();
|
|
9085
|
-
const componentId = id || fallbackId;
|
|
9086
|
-
// Set the icon to `'arrow'` if `href` is truthy and `type` is falsy, or
|
|
9087
|
-
// `'download'` if `download` is truthy. If neither condition is true, set
|
|
9088
|
-
// `icon` to `undefined`.
|
|
9089
|
-
// Create a function to get icon type
|
|
9090
|
-
const getIconType = () => {
|
|
9091
|
-
if (indicatorIcon) {
|
|
9092
|
-
return indicatorIcon;
|
|
9093
|
-
}
|
|
9094
|
-
if (download) {
|
|
9095
|
-
return 'download';
|
|
9096
|
-
}
|
|
9097
|
-
if (href && !type) {
|
|
9098
|
-
return 'arrow';
|
|
9099
|
-
}
|
|
9100
|
-
return undefined;
|
|
9101
|
-
};
|
|
9102
|
-
// Define all class names string based on the values of the `href`, `type`,
|
|
9103
|
-
// `checked`, and `className` props.
|
|
9104
|
-
const commonClasses = classNames__default.default({
|
|
9105
|
-
'np-Card--promoCard': true,
|
|
9106
|
-
'np-Card--checked': !href && type,
|
|
9107
|
-
'np-Card--link': href && !type,
|
|
9108
|
-
'is-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined
|
|
9109
|
-
}, className);
|
|
9110
|
-
// Object with common props that will be passed to the `Card` components
|
|
9111
|
-
const commonProps = {
|
|
9112
|
-
className: commonClasses,
|
|
9113
|
-
id: componentId,
|
|
9114
|
-
isDisabled: isDisabled || contextIsDisabled,
|
|
9115
|
-
onClick,
|
|
9116
|
-
ref: reference,
|
|
9117
|
-
'data-testid': testId,
|
|
9118
|
-
isSmall
|
|
9119
|
-
};
|
|
9120
|
-
// Object with Anchor props that will be passed to the `a` element. These
|
|
9121
|
-
// won't be refurned if set to `isDisabled`
|
|
9122
|
-
const anchorProps = href && !isDisabled ? {
|
|
9123
|
-
download,
|
|
9124
|
-
href: href || undefined,
|
|
9125
|
-
hrefLang,
|
|
9126
|
-
rel,
|
|
9127
|
-
target
|
|
9128
|
-
} : {};
|
|
9129
|
-
// Object of all Checked props that will be passed to the root `Card` component
|
|
9130
|
-
const checkedProps = (type === 'checkbox' || type === 'radio') && !href ? {
|
|
9131
|
-
...commonProps,
|
|
9132
|
-
'aria-checked': type === 'radio' ? value === state : type === 'checkbox' ? checked : undefined,
|
|
9133
|
-
'aria-describedby': `${componentId}-title`,
|
|
9134
|
-
'aria-disabled': isDisabled,
|
|
9135
|
-
'data-value': value ?? undefined,
|
|
9136
|
-
role: type === 'checkbox' || type === 'radio' ? type : undefined,
|
|
9137
|
-
onClick: handleClick,
|
|
9138
|
-
onKeyDown: event => {
|
|
9139
|
-
if (event.key === 'Enter' || event.key === ' ') {
|
|
9140
|
-
handleClick();
|
|
9141
|
-
}
|
|
9142
|
-
},
|
|
9143
|
-
ref: reference,
|
|
9144
|
-
tabIndex: 0
|
|
9145
|
-
} : {};
|
|
9146
|
-
const getTitle = () => {
|
|
9147
|
-
const titleContent = href && !type ? /*#__PURE__*/jsxRuntime.jsx("a", {
|
|
9148
|
-
className: "np-Card-titleLink",
|
|
9149
|
-
...anchorProps,
|
|
9150
|
-
children: title
|
|
9151
|
-
}) : title;
|
|
9152
|
-
const titleProps = {
|
|
9153
|
-
id: `${componentId}-title`,
|
|
9154
|
-
as: headingLevel,
|
|
9155
|
-
className: 'np-Card-title'
|
|
9156
|
-
};
|
|
9157
|
-
return useDisplayFont ? /*#__PURE__*/jsxRuntime.jsx(Display, {
|
|
9158
|
-
type: exports.Typography.DISPLAY_SMALL,
|
|
9159
|
-
...titleProps,
|
|
9160
|
-
children: titleContent
|
|
9161
|
-
}) : /*#__PURE__*/jsxRuntime.jsx(Title, {
|
|
9162
|
-
type: exports.Typography.TITLE_SUBSECTION,
|
|
9163
|
-
...titleProps,
|
|
9164
|
-
children: titleContent
|
|
9165
|
-
});
|
|
9166
|
-
};
|
|
9167
|
-
React.useEffect(() => {
|
|
9168
|
-
setChecked(defaultChecked ?? isChecked ?? false);
|
|
9169
|
-
}, [defaultChecked, isChecked]);
|
|
9170
|
-
return /*#__PURE__*/jsxRuntime.jsxs(Card, {
|
|
9171
|
-
...commonProps,
|
|
9172
|
-
...checkedProps,
|
|
9173
|
-
...props,
|
|
9174
|
-
children: [(value === state || checked) && /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
9175
|
-
className: "np-Card-check",
|
|
9176
|
-
children: /*#__PURE__*/jsxRuntime.jsx(icons.Check, {
|
|
9177
|
-
size: 24,
|
|
9178
|
-
"aria-hidden": "true"
|
|
9179
|
-
})
|
|
9180
|
-
}), getTitle(), /*#__PURE__*/jsxRuntime.jsx(Body, {
|
|
9181
|
-
className: "np-Card-description",
|
|
9182
|
-
children: description
|
|
9183
|
-
}), imageSource && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
9184
|
-
className: classNames__default.default('np-Card-image', {
|
|
9185
|
-
imageClass
|
|
9186
|
-
}),
|
|
9187
|
-
children: /*#__PURE__*/jsxRuntime.jsx(Image, {
|
|
9188
|
-
src: imageSource,
|
|
9189
|
-
alt: imageAlt || '',
|
|
9190
|
-
loading: "lazy"
|
|
9191
|
-
})
|
|
9192
|
-
}), /*#__PURE__*/jsxRuntime.jsx(PromoCardIndicator, {
|
|
9193
|
-
label: indicatorLabel,
|
|
9194
|
-
icon: getIconType(),
|
|
9195
|
-
isSmall: isSmall
|
|
9196
|
-
})]
|
|
9197
|
-
});
|
|
9198
|
-
});
|
|
9199
|
-
var PromoCard$1 = /*#__PURE__*/React__namespace.default.memo(PromoCard);
|
|
9200
|
-
|
|
9201
9475
|
const PromoCardGroup = ({
|
|
9202
9476
|
children,
|
|
9203
9477
|
className,
|
|
@@ -14498,11 +14772,12 @@ exports.Alert = Alert;
|
|
|
14498
14772
|
exports.Avatar = Avatar;
|
|
14499
14773
|
exports.AvatarWrapper = AvatarWrapper;
|
|
14500
14774
|
exports.Badge = Badge;
|
|
14501
|
-
exports.BaseCard = Card;
|
|
14775
|
+
exports.BaseCard = Card$2;
|
|
14502
14776
|
exports.Body = Body;
|
|
14503
14777
|
exports.BottomSheet = BottomSheet$1;
|
|
14504
14778
|
exports.Button = Button;
|
|
14505
|
-
exports.Card = Card$
|
|
14779
|
+
exports.Card = Card$1;
|
|
14780
|
+
exports.Carousel = Carousel;
|
|
14506
14781
|
exports.Checkbox = Checkbox;
|
|
14507
14782
|
exports.CheckboxButton = CheckboxButton$1;
|
|
14508
14783
|
exports.CheckboxOption = CheckboxOption;
|