@nuskin/nextgen-header 1.6.0 → 1.7.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/package-dist/index.js +204 -3
- package/package-dist/index.js.map +1 -1
- package/package-dist/index.mjs +204 -3
- package/package-dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/package-dist/index.js
CHANGED
|
@@ -1611,6 +1611,166 @@ function HeaderNavigationRegion(_ref) {
|
|
|
1611
1611
|
HeaderNavigationRegion.propTypes = {
|
|
1612
1612
|
headerNavigationService: (external_prop_types_default()).object.isRequired
|
|
1613
1613
|
};
|
|
1614
|
+
;// ./src/utils/common.js
|
|
1615
|
+
/**
|
|
1616
|
+
* Validate and sanitize a URL string.
|
|
1617
|
+
* Returns '#' for invalid/empty values to provide safe fallback anchors.
|
|
1618
|
+
*
|
|
1619
|
+
* SSR-safe: no DOM/window access.
|
|
1620
|
+
*
|
|
1621
|
+
* @param {*} url - The URL value to validate
|
|
1622
|
+
* @returns {string} The original URL if valid, otherwise '#'
|
|
1623
|
+
*/
|
|
1624
|
+
var validateUrl = function validateUrl(url) {
|
|
1625
|
+
if (!url || typeof url !== 'string' || url.trim() === '') {
|
|
1626
|
+
return '#';
|
|
1627
|
+
}
|
|
1628
|
+
return url;
|
|
1629
|
+
};
|
|
1630
|
+
;// ./src/components/top-ribbon/types.js
|
|
1631
|
+
|
|
1632
|
+
var NavigationLinkPropTypes = external_prop_types_default().shape({
|
|
1633
|
+
label: (external_prop_types_default()).string.isRequired,
|
|
1634
|
+
url: (external_prop_types_default()).string.isRequired,
|
|
1635
|
+
ariaLabel: (external_prop_types_default()).string,
|
|
1636
|
+
dataTestId: (external_prop_types_default()).string,
|
|
1637
|
+
gtmEvent: (external_prop_types_default()).object
|
|
1638
|
+
});
|
|
1639
|
+
var TopRibbonPropTypes = {
|
|
1640
|
+
links: external_prop_types_default().arrayOf(NavigationLinkPropTypes).isRequired,
|
|
1641
|
+
className: (external_prop_types_default()).string,
|
|
1642
|
+
ariaLabel: (external_prop_types_default()).string,
|
|
1643
|
+
dataTestId: (external_prop_types_default()).string
|
|
1644
|
+
};
|
|
1645
|
+
;// ./src/components/top-ribbon/TopRibbon.styled.jsx
|
|
1646
|
+
|
|
1647
|
+
function TopRibbon_styled_EMOTION_STRINGIFIED_CSS_ERROR_() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
|
|
1648
|
+
// Main container for the top ribbon navigation
|
|
1649
|
+
var StyledTopRibbon = /*#__PURE__*/createStyled("header", true ? {
|
|
1650
|
+
target: "ei9etl03"
|
|
1651
|
+
} : 0)( true ? {
|
|
1652
|
+
name: "1i3elid",
|
|
1653
|
+
styles: "background-color:#000000;width:100%;position:relative;@media (max-width: 1023px){display:none;}&:focus-within{outline:none;}"
|
|
1654
|
+
} : 0);
|
|
1655
|
+
|
|
1656
|
+
// Navigation list container
|
|
1657
|
+
var StyledNavigationList = /*#__PURE__*/createStyled("ul", true ? {
|
|
1658
|
+
target: "ei9etl02"
|
|
1659
|
+
} : 0)( true ? {
|
|
1660
|
+
name: "1qblcar",
|
|
1661
|
+
styles: "margin:0;padding:0;list-style:none;display:flex;align-items:center;justify-content:center;gap:24px;padding:10px 24px;width:100%;box-sizing:border-box"
|
|
1662
|
+
} : 0);
|
|
1663
|
+
|
|
1664
|
+
// Individual navigation item container
|
|
1665
|
+
var StyledNavigationItem = /*#__PURE__*/createStyled("li", true ? {
|
|
1666
|
+
target: "ei9etl01"
|
|
1667
|
+
} : 0)( true ? {
|
|
1668
|
+
name: "qy80on",
|
|
1669
|
+
styles: "margin:0;padding:0;flex-shrink:0;position:relative"
|
|
1670
|
+
} : 0);
|
|
1671
|
+
|
|
1672
|
+
// Navigation link with hover effects
|
|
1673
|
+
var StyledNavigationLink = /*#__PURE__*/createStyled("a", true ? {
|
|
1674
|
+
target: "ei9etl00"
|
|
1675
|
+
} : 0)( true ? {
|
|
1676
|
+
name: "1pvnuug",
|
|
1677
|
+
styles: "display:inline-block;padding:0;cursor:pointer;color:#ffffff;font-family:\"Inter\",-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif;font-size:14px;font-weight:400;line-height:20px;text-align:center;white-space:nowrap;text-decoration:underline;text-decoration-style:solid;text-decoration-color:transparent;transition:text-decoration-color 0.2s ease,background-color 0.2s ease;position:relative;&:hover{color:#ffffff;text-decoration-color:#ffffff;}&:focus-visible{outline:2px solid #ffffff;outline-offset:2px;background-color:rgba(255, 255, 255, 0.1);text-decoration-color:#ffffff;}&:focus:not(:focus-visible){outline:none;background-color:transparent;}&:active{background-color:rgba(255, 255, 255, 0.05);}@media (prefers-contrast: high){&:focus-visible{outline-color:currentColor;}}"
|
|
1678
|
+
} : 0);
|
|
1679
|
+
;// ./src/components/top-ribbon/TopRibbon.jsx
|
|
1680
|
+
function TopRibbon_typeof(o) { "@babel/helpers - typeof"; return TopRibbon_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, TopRibbon_typeof(o); }
|
|
1681
|
+
function TopRibbon_ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
1682
|
+
function TopRibbon_objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? TopRibbon_ownKeys(Object(t), !0).forEach(function (r) { TopRibbon_defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : TopRibbon_ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
1683
|
+
function TopRibbon_defineProperty(e, r, t) { return (r = TopRibbon_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
1684
|
+
function TopRibbon_toPropertyKey(t) { var i = TopRibbon_toPrimitive(t, "string"); return "symbol" == TopRibbon_typeof(i) ? i : i + ""; }
|
|
1685
|
+
function TopRibbon_toPrimitive(t, r) { if ("object" != TopRibbon_typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != TopRibbon_typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
1686
|
+
|
|
1687
|
+
|
|
1688
|
+
|
|
1689
|
+
|
|
1690
|
+
|
|
1691
|
+
/**
|
|
1692
|
+
* TopRibbon Navigation Component
|
|
1693
|
+
*
|
|
1694
|
+
* Renders a desktop-only navigation ribbon with:
|
|
1695
|
+
* - Pure black background (#000000) per Figma specifications
|
|
1696
|
+
* - White text links (#FFFFFF) with Figma-exact hover underlines
|
|
1697
|
+
* - Figma-exact typography (14px/20px, Inter font)
|
|
1698
|
+
* - Full WCAG 2.1 AA accessibility compliance
|
|
1699
|
+
* - Responsive behavior (hidden below 1024px breakpoint)
|
|
1700
|
+
* - CSR & SSR compatible (no direct window/document access at render time)
|
|
1701
|
+
*
|
|
1702
|
+
* @param {Object} props - Component props
|
|
1703
|
+
* @returns {JSX.Element|null} Rendered navigation component
|
|
1704
|
+
*/
|
|
1705
|
+
|
|
1706
|
+
var TopRibbon = function TopRibbon(_ref) {
|
|
1707
|
+
var links = _ref.links,
|
|
1708
|
+
_ref$className = _ref.className,
|
|
1709
|
+
className = _ref$className === void 0 ? '' : _ref$className,
|
|
1710
|
+
_ref$ariaLabel = _ref.ariaLabel,
|
|
1711
|
+
ariaLabel = _ref$ariaLabel === void 0 ? 'Top navigation' : _ref$ariaLabel,
|
|
1712
|
+
_ref$dataTestId = _ref.dataTestId,
|
|
1713
|
+
dataTestId = _ref$dataTestId === void 0 ? 'top-ribbon-nav' : _ref$dataTestId;
|
|
1714
|
+
// Validate required props — safe to call in SSR
|
|
1715
|
+
if (!links || !Array.isArray(links) || links.length === 0) {
|
|
1716
|
+
return null;
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
/**
|
|
1720
|
+
* Fires a GTM dataLayer event when a link is clicked.
|
|
1721
|
+
* Does NOT call preventDefault — native target="_blank" behaviour is preserved.
|
|
1722
|
+
* SSR-safe: guarded behind typeof window check.
|
|
1723
|
+
*
|
|
1724
|
+
* @param {Object} item - The navigation item that was clicked
|
|
1725
|
+
*/
|
|
1726
|
+
var handleClick = function handleClick(item) {
|
|
1727
|
+
if (typeof window === 'undefined' || !Array.isArray(window.dataLayer)) return;
|
|
1728
|
+
window.dataLayer.push(TopRibbon_objectSpread({
|
|
1729
|
+
event: 'top_ribbon_click',
|
|
1730
|
+
link_text: item.label,
|
|
1731
|
+
link_url: item.url
|
|
1732
|
+
}, item.gtmEvent));
|
|
1733
|
+
};
|
|
1734
|
+
return /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(StyledTopRibbon, {
|
|
1735
|
+
className: className,
|
|
1736
|
+
"data-testid": dataTestId,
|
|
1737
|
+
children: /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)("nav", {
|
|
1738
|
+
"aria-label": ariaLabel,
|
|
1739
|
+
role: "navigation",
|
|
1740
|
+
"data-testid": "".concat(dataTestId, "-nav"),
|
|
1741
|
+
children: /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(StyledNavigationList, {
|
|
1742
|
+
"data-testid": "".concat(dataTestId, "-list"),
|
|
1743
|
+
children: links.map(function (item, index) {
|
|
1744
|
+
if (!item || TopRibbon_typeof(item) !== 'object') return null;
|
|
1745
|
+
var label = item.label,
|
|
1746
|
+
url = item.url,
|
|
1747
|
+
itemAriaLabel = item.ariaLabel,
|
|
1748
|
+
itemTestId = item.dataTestId;
|
|
1749
|
+
if (!label || !url) return null;
|
|
1750
|
+
var linkHref = validateUrl(url);
|
|
1751
|
+
var linkAriaLabel = itemAriaLabel || "Navigate to ".concat(label);
|
|
1752
|
+
var linkTestId = itemTestId || "".concat(dataTestId, "-item-").concat(index);
|
|
1753
|
+
return /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(StyledNavigationItem, {
|
|
1754
|
+
"data-testid": "".concat(linkTestId, "-container"),
|
|
1755
|
+
children: /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(StyledNavigationLink, {
|
|
1756
|
+
href: linkHref,
|
|
1757
|
+
target: "_blank",
|
|
1758
|
+
rel: "noopener noreferrer",
|
|
1759
|
+
onClick: function onClick() {
|
|
1760
|
+
return handleClick(item);
|
|
1761
|
+
},
|
|
1762
|
+
"aria-label": linkAriaLabel,
|
|
1763
|
+
"data-testid": linkTestId,
|
|
1764
|
+
children: label
|
|
1765
|
+
})
|
|
1766
|
+
}, "nav-item-".concat(index, "-").concat(label));
|
|
1767
|
+
})
|
|
1768
|
+
})
|
|
1769
|
+
})
|
|
1770
|
+
});
|
|
1771
|
+
};
|
|
1772
|
+
TopRibbon.propTypes = TopRibbonPropTypes;
|
|
1773
|
+
/* harmony default export */ const top_ribbon_TopRibbon = (TopRibbon);
|
|
1614
1774
|
;// ./src/header/components/HeaderView.jsx
|
|
1615
1775
|
|
|
1616
1776
|
|
|
@@ -1623,6 +1783,7 @@ HeaderNavigationRegion.propTypes = {
|
|
|
1623
1783
|
|
|
1624
1784
|
|
|
1625
1785
|
|
|
1786
|
+
|
|
1626
1787
|
/**
|
|
1627
1788
|
* Header shell: each region calls async getters on its service to load copy before rendering.
|
|
1628
1789
|
* Layout follows docs/header-domain-language.png (logo left; utility + pill search stacked right).
|
|
@@ -1638,14 +1799,48 @@ function HeaderView(_ref) {
|
|
|
1638
1799
|
headerAccountService = _ref.headerAccountService,
|
|
1639
1800
|
headerCartService = _ref.headerCartService,
|
|
1640
1801
|
headerSearchService = _ref.headerSearchService,
|
|
1641
|
-
headerNavigationService = _ref.headerNavigationService
|
|
1802
|
+
headerNavigationService = _ref.headerNavigationService,
|
|
1803
|
+
_ref$topRibbonLinks = _ref.topRibbonLinks,
|
|
1804
|
+
topRibbonLinks = _ref$topRibbonLinks === void 0 ? [{
|
|
1805
|
+
label: 'Hair',
|
|
1806
|
+
url: '/hair',
|
|
1807
|
+
ariaLabel: 'Shop Hair'
|
|
1808
|
+
}, {
|
|
1809
|
+
label: 'Skin',
|
|
1810
|
+
url: '/skin',
|
|
1811
|
+
ariaLabel: 'Shop Skin'
|
|
1812
|
+
}, {
|
|
1813
|
+
label: 'Body',
|
|
1814
|
+
url: '/body',
|
|
1815
|
+
ariaLabel: 'Shop Body'
|
|
1816
|
+
}, {
|
|
1817
|
+
label: 'Fragrance',
|
|
1818
|
+
url: '/fragrance',
|
|
1819
|
+
ariaLabel: 'Shop Fragrance'
|
|
1820
|
+
}, {
|
|
1821
|
+
label: 'Beauty Bio',
|
|
1822
|
+
url: '/beauty-bio',
|
|
1823
|
+
ariaLabel: 'Shop Beauty Bio'
|
|
1824
|
+
}, {
|
|
1825
|
+
label: 'Accessories',
|
|
1826
|
+
url: '/accessories',
|
|
1827
|
+
ariaLabel: 'Shop Accessories'
|
|
1828
|
+
}, {
|
|
1829
|
+
label: 'Gifts',
|
|
1830
|
+
url: '/gifts',
|
|
1831
|
+
ariaLabel: 'Shop Gifts'
|
|
1832
|
+
}] : _ref$topRibbonLinks;
|
|
1642
1833
|
return /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsxs)(HeaderRoot, {
|
|
1643
1834
|
role: "banner",
|
|
1644
1835
|
"data-testid": "header-view",
|
|
1645
1836
|
"data-country": country,
|
|
1646
1837
|
"data-language": language,
|
|
1647
1838
|
"data-locale": locale,
|
|
1648
|
-
children: [/*#__PURE__*/(0,jsx_runtime_namespaceObject.
|
|
1839
|
+
children: [/*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(top_ribbon_TopRibbon, {
|
|
1840
|
+
links: topRibbonLinks,
|
|
1841
|
+
ariaLabel: "Top navigation",
|
|
1842
|
+
dataTestId: "header-top-ribbon"
|
|
1843
|
+
}), /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsxs)(TopHeaderRow, {
|
|
1649
1844
|
children: [/*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(LogoSlot, {
|
|
1650
1845
|
children: /*#__PURE__*/(0,jsx_runtime_namespaceObject.jsx)(HeaderLogoRegion, {
|
|
1651
1846
|
headerLogoService: headerLogoService
|
|
@@ -1686,7 +1881,13 @@ HeaderView.propTypes = {
|
|
|
1686
1881
|
headerAccountService: serviceProp,
|
|
1687
1882
|
headerCartService: serviceProp,
|
|
1688
1883
|
headerSearchService: serviceProp,
|
|
1689
|
-
headerNavigationService: serviceProp
|
|
1884
|
+
headerNavigationService: serviceProp,
|
|
1885
|
+
topRibbonLinks: external_prop_types_default().arrayOf(external_prop_types_default().shape({
|
|
1886
|
+
label: (external_prop_types_default()).string.isRequired,
|
|
1887
|
+
url: (external_prop_types_default()).string.isRequired,
|
|
1888
|
+
ariaLabel: (external_prop_types_default()).string,
|
|
1889
|
+
dataTestId: (external_prop_types_default()).string
|
|
1890
|
+
}))
|
|
1690
1891
|
};
|
|
1691
1892
|
;// ./src/styles/Main.styled.js
|
|
1692
1893
|
|