@the-portland-company/shell 0.8.0 → 0.9.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/CHANGELOG.md +10 -0
- package/dist/index.cjs +177 -150
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -8
- package/dist/index.d.ts +6 -8
- package/dist/index.js +177 -150
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.0 — 2026-07-12
|
|
4
|
+
|
|
5
|
+
### Fixed (Chakra chrome — reconciled with main app)
|
|
6
|
+
|
|
7
|
+
- **`NavItem` re-synced to main-app `AuthenticatedLayout`**: removed the orange→red gradient hover sweep that had diverged from production chrome; restored gray hover, parent active when any child route matches (including Tabs Only), and the effectiveHref vs href-less accordion header split. `brandIcon` + `safeHref` shell additions retained.
|
|
8
|
+
|
|
9
|
+
### Note for hosts
|
|
10
|
+
|
|
11
|
+
- Main VRM app now renders chrome exclusively via `ShellChrome` + `AppLayout` (no dual `AuthenticatedLayoutFrame` chrome path). Contacts already used this path — both apps should pin `^0.9.0`.
|
|
12
|
+
|
|
3
13
|
## 0.8.0 — 2026-07-02
|
|
4
14
|
|
|
5
15
|
### Added (backward-compatible)
|
package/dist/index.cjs
CHANGED
|
@@ -1573,8 +1573,7 @@ function BrandIcon({
|
|
|
1573
1573
|
);
|
|
1574
1574
|
}
|
|
1575
1575
|
var BrandIcon_default = BrandIcon;
|
|
1576
|
-
var
|
|
1577
|
-
var MODE_PETITION = "petition";
|
|
1576
|
+
var safeHref = (h) => h && /^(https?:|mailto:|tel:|\/|#|\.)/i.test(h.trim()) ? h : "#";
|
|
1578
1577
|
function NavItem({
|
|
1579
1578
|
icon,
|
|
1580
1579
|
brandIcon,
|
|
@@ -1595,23 +1594,9 @@ function NavItem({
|
|
|
1595
1594
|
const location = reactRouterDom.useLocation();
|
|
1596
1595
|
const navigate = reactRouterDom.useNavigate();
|
|
1597
1596
|
const mode = useShellMode();
|
|
1598
|
-
const currentMode = mode?.currentMode ?? null;
|
|
1599
1597
|
const modeConfig = resolveModeConfig(mode);
|
|
1600
1598
|
const navPref = useShellNavigationPreference();
|
|
1601
1599
|
const showSubMenu = navPref?.showSubMenu ?? true;
|
|
1602
|
-
const navHoverGradient = currentMode === MODE_CAMPAIGN ? "linear-gradient(90deg, #F2C94C 0%, #E63946 100%)" : currentMode === MODE_PETITION ? "linear-gradient(90deg, #F2C94C 0%, #007BFF 100%)" : "linear-gradient(90deg, #ea6a3a 0%, #E63946 100%)";
|
|
1603
|
-
const gradientSweepBefore = {
|
|
1604
|
-
content: '""',
|
|
1605
|
-
position: "absolute",
|
|
1606
|
-
top: 0,
|
|
1607
|
-
left: 0,
|
|
1608
|
-
bottom: 0,
|
|
1609
|
-
width: "0%",
|
|
1610
|
-
background: navHoverGradient,
|
|
1611
|
-
transition: "width 300ms ease",
|
|
1612
|
-
pointerEvents: "none",
|
|
1613
|
-
zIndex: 0
|
|
1614
|
-
};
|
|
1615
1600
|
const isDisabled = Boolean(navIsDisabled || disabled);
|
|
1616
1601
|
const effectiveHref = href || (Array.isArray(subItems) && subItems.length > 0 ? subItems[0].href : void 0);
|
|
1617
1602
|
const effectivePathname = effectiveHref?.split("?")[0];
|
|
@@ -1621,6 +1606,7 @@ function NavItem({
|
|
|
1621
1606
|
[location.search]
|
|
1622
1607
|
);
|
|
1623
1608
|
const matchesSubItem = (itemHref) => {
|
|
1609
|
+
if (!itemHref) return false;
|
|
1624
1610
|
if (itemHref === currentFullPath) return true;
|
|
1625
1611
|
const itemPath = itemHref.split("?")[0];
|
|
1626
1612
|
const itemSearch = itemHref.includes("?") ? itemHref.split("?")[1] : "";
|
|
@@ -1664,83 +1650,130 @@ function NavItem({
|
|
|
1664
1650
|
return effectivePathname !== `/${location.pathname.split("/")[1]}/dashboard` && location.pathname.startsWith(effectivePathname + "/");
|
|
1665
1651
|
})();
|
|
1666
1652
|
const hasSubItems = showSubMenu && Array.isArray(subItems) && subItems.length > 0;
|
|
1667
|
-
const hasActiveChild =
|
|
1653
|
+
const hasActiveChild = Array.isArray(subItems) && subItems.some((item) => matchesSubItem(item.href || ""));
|
|
1668
1654
|
const isParentActive = isActive || hasActiveChild;
|
|
1669
1655
|
const isSubMenuOpen = isExpanded !== void 0 ? isExpanded : hasSubItems && subItems.some((item) => matchesSubItem(item.href || ""));
|
|
1670
1656
|
const expandedRowBg = isParentActive ? modeConfig?.primaryColor || "brand.500" : isSubMenuOpen ? "gray.100" : "transparent";
|
|
1671
1657
|
const expandedRowTextColor = isParentActive ? "white" : isSubMenuOpen ? "gray.900" : "gray.600";
|
|
1672
1658
|
const disabledRowBg = isSubItem ? "gray.50" : "transparent";
|
|
1673
1659
|
const disabledRowTextColor = "gray.400";
|
|
1660
|
+
const renderIcon = (activeForHover) => {
|
|
1661
|
+
if (brandIcon) {
|
|
1662
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1663
|
+
react.Box,
|
|
1664
|
+
{
|
|
1665
|
+
mr: "4",
|
|
1666
|
+
display: "inline-flex",
|
|
1667
|
+
alignItems: "center",
|
|
1668
|
+
filter: isParentActive || isActive ? "brightness(0) invert(1)" : void 0,
|
|
1669
|
+
_groupHover: isDisabled ? void 0 : {
|
|
1670
|
+
filter: activeForHover ? "brightness(0) invert(1)" : void 0
|
|
1671
|
+
},
|
|
1672
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(BrandIcon_default, { name: brandIcon, size: 18 })
|
|
1673
|
+
}
|
|
1674
|
+
);
|
|
1675
|
+
}
|
|
1676
|
+
if (icon) {
|
|
1677
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1678
|
+
react.Box,
|
|
1679
|
+
{
|
|
1680
|
+
mr: "4",
|
|
1681
|
+
fontSize: "16",
|
|
1682
|
+
_groupHover: {
|
|
1683
|
+
color: isDisabled ? disabledRowTextColor : activeForHover ? "white" : "gray.900"
|
|
1684
|
+
},
|
|
1685
|
+
as: icon
|
|
1686
|
+
}
|
|
1687
|
+
);
|
|
1688
|
+
}
|
|
1689
|
+
return null;
|
|
1690
|
+
};
|
|
1674
1691
|
if (hasSubItems) {
|
|
1675
|
-
const headerProps = {
|
|
1676
|
-
align: "center",
|
|
1677
|
-
px: "4",
|
|
1678
|
-
py: "2.5",
|
|
1679
|
-
mx: "4",
|
|
1680
|
-
w: "auto",
|
|
1681
|
-
borderTopRadius: "lg",
|
|
1682
|
-
borderBottomRadius: isSubMenuOpen ? 0 : "lg",
|
|
1683
|
-
role: "group",
|
|
1684
|
-
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
1685
|
-
opacity: 1,
|
|
1686
|
-
pointerEvents: isDisabled ? "none" : "auto",
|
|
1687
|
-
"data-nav-item-active": String(isParentActive),
|
|
1688
|
-
position: "relative",
|
|
1689
|
-
overflow: "hidden",
|
|
1690
|
-
bg: isDisabled ? disabledRowBg : expandedRowBg,
|
|
1691
|
-
color: isDisabled ? disabledRowTextColor : expandedRowTextColor,
|
|
1692
|
-
_before: isDisabled ? void 0 : gradientSweepBefore,
|
|
1693
|
-
_hover: {
|
|
1694
|
-
color: isDisabled ? disabledRowTextColor : "white",
|
|
1695
|
-
_before: isDisabled ? void 0 : { width: "100%" }
|
|
1696
|
-
},
|
|
1697
|
-
"aria-disabled": isDisabled ? "true" : "false",
|
|
1698
|
-
onClick: (e) => {
|
|
1699
|
-
if (isDisabled) return;
|
|
1700
|
-
if (effectiveHref) e.preventDefault();
|
|
1701
|
-
e.stopPropagation();
|
|
1702
|
-
onToggle?.(menuKey || null);
|
|
1703
|
-
}
|
|
1704
|
-
};
|
|
1705
1692
|
return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { children: [
|
|
1706
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1693
|
+
effectiveHref ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1694
|
+
react.Flex,
|
|
1695
|
+
{
|
|
1696
|
+
align: "center",
|
|
1697
|
+
px: "4",
|
|
1698
|
+
py: "2.5",
|
|
1699
|
+
mx: "4",
|
|
1700
|
+
w: "auto",
|
|
1701
|
+
borderTopRadius: "lg",
|
|
1702
|
+
borderBottomRadius: isSubMenuOpen ? 0 : "lg",
|
|
1703
|
+
role: "group",
|
|
1704
|
+
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
1705
|
+
opacity: 1,
|
|
1706
|
+
pointerEvents: isDisabled ? "none" : "auto",
|
|
1707
|
+
"data-nav-item-active": String(isParentActive),
|
|
1708
|
+
bg: isDisabled ? disabledRowBg : expandedRowBg,
|
|
1709
|
+
color: isDisabled ? disabledRowTextColor : expandedRowTextColor,
|
|
1710
|
+
_hover: {
|
|
1711
|
+
bg: isDisabled ? disabledRowBg : isParentActive ? modeConfig?.accentColor || "brand.600" : "gray.200",
|
|
1712
|
+
color: isDisabled ? disabledRowTextColor : isParentActive ? "white" : "gray.900"
|
|
1713
|
+
},
|
|
1714
|
+
"aria-disabled": isDisabled ? "true" : "false",
|
|
1715
|
+
onClick: (e) => {
|
|
1716
|
+
if (isDisabled) return;
|
|
1717
|
+
e.preventDefault();
|
|
1718
|
+
e.stopPropagation();
|
|
1719
|
+
onToggle?.(menuKey || null);
|
|
1720
|
+
},
|
|
1721
|
+
...rest,
|
|
1722
|
+
children: [
|
|
1723
|
+
renderIcon(isParentActive),
|
|
1724
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { flex: "1", children }),
|
|
1725
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1726
|
+
react.Box,
|
|
1727
|
+
{
|
|
1728
|
+
as: fi.FiChevronDown,
|
|
1729
|
+
transform: isSubMenuOpen ? "rotate(180deg)" : void 0,
|
|
1730
|
+
transition: "transform 0.2s"
|
|
1731
|
+
}
|
|
1732
|
+
)
|
|
1733
|
+
]
|
|
1734
|
+
}
|
|
1735
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1736
|
+
react.Flex,
|
|
1737
|
+
{
|
|
1738
|
+
align: "center",
|
|
1739
|
+
px: "4",
|
|
1740
|
+
py: "2.5",
|
|
1741
|
+
mx: "4",
|
|
1742
|
+
w: "auto",
|
|
1743
|
+
borderTopRadius: "lg",
|
|
1744
|
+
borderBottomRadius: isSubMenuOpen ? 0 : "lg",
|
|
1745
|
+
role: "group",
|
|
1746
|
+
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
1747
|
+
opacity: 1,
|
|
1748
|
+
pointerEvents: isDisabled ? "none" : "auto",
|
|
1749
|
+
"data-nav-item-active": String(isParentActive),
|
|
1750
|
+
bg: isDisabled ? disabledRowBg : expandedRowBg,
|
|
1751
|
+
color: isDisabled ? disabledRowTextColor : expandedRowTextColor,
|
|
1752
|
+
_hover: {
|
|
1753
|
+
bg: isDisabled ? disabledRowBg : hasActiveChild ? modeConfig?.accentColor || "brand.600" : "gray.200",
|
|
1754
|
+
color: isDisabled ? disabledRowTextColor : hasActiveChild ? "white" : "gray.900"
|
|
1755
|
+
},
|
|
1756
|
+
"aria-disabled": isDisabled ? "true" : "false",
|
|
1757
|
+
onClick: (e) => {
|
|
1758
|
+
if (isDisabled) return;
|
|
1759
|
+
e.stopPropagation();
|
|
1760
|
+
onToggle?.(menuKey || null);
|
|
1761
|
+
},
|
|
1762
|
+
...rest,
|
|
1763
|
+
children: [
|
|
1764
|
+
renderIcon(hasActiveChild),
|
|
1765
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { flex: "1", children }),
|
|
1766
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1767
|
+
react.Box,
|
|
1768
|
+
{
|
|
1769
|
+
as: fi.FiChevronDown,
|
|
1770
|
+
transform: isSubMenuOpen ? "rotate(180deg)" : void 0,
|
|
1771
|
+
transition: "transform 0.2s"
|
|
1772
|
+
}
|
|
1773
|
+
)
|
|
1774
|
+
]
|
|
1775
|
+
}
|
|
1776
|
+
),
|
|
1744
1777
|
/* @__PURE__ */ jsxRuntime.jsx(react.Collapse, { in: isSubMenuOpen, animateOpacity: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1745
1778
|
react.Box,
|
|
1746
1779
|
{
|
|
@@ -1784,74 +1817,68 @@ function NavItem({
|
|
|
1784
1817
|
navigate(effectiveHref);
|
|
1785
1818
|
}
|
|
1786
1819
|
};
|
|
1787
|
-
|
|
1788
|
-
|
|
1820
|
+
const rowActive = isSubItem ? isActive : isParentActive;
|
|
1821
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1822
|
+
react.Box,
|
|
1789
1823
|
{
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
py: "2.5",
|
|
1793
|
-
mx: isSubItem ? "0" : "4",
|
|
1794
|
-
w: isSubItem ? "full" : "auto",
|
|
1795
|
-
borderRadius: isSubItem ? "0" : "lg",
|
|
1796
|
-
role: "group",
|
|
1797
|
-
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
1798
|
-
opacity: 1,
|
|
1799
|
-
pointerEvents: isDisabled ? "none" : "auto",
|
|
1800
|
-
"data-nav-item-active": String(isActive),
|
|
1801
|
-
position: "relative",
|
|
1802
|
-
overflow: "hidden",
|
|
1803
|
-
bg: isDisabled ? disabledRowBg : isActive ? isSubItem ? "gray.100" : modeConfig?.primaryColor || "brand.500" : "transparent",
|
|
1804
|
-
color: isDisabled ? disabledRowTextColor : isActive ? isSubItem ? modeConfig?.primaryColor || "brand.500" : "white" : "gray.600",
|
|
1805
|
-
_before: isDisabled ? void 0 : gradientSweepBefore,
|
|
1806
|
-
_hover: {
|
|
1807
|
-
color: isDisabled ? disabledRowTextColor : "white",
|
|
1808
|
-
_before: isDisabled ? void 0 : { width: "100%" }
|
|
1809
|
-
},
|
|
1810
|
-
"aria-disabled": isDisabled ? "true" : "false",
|
|
1824
|
+
as: "a",
|
|
1825
|
+
href: safeHref(effectiveHref),
|
|
1811
1826
|
onClick: handleClick,
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1827
|
+
style: { textDecoration: "none" },
|
|
1828
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1829
|
+
react.Flex,
|
|
1830
|
+
{
|
|
1831
|
+
align: "center",
|
|
1832
|
+
px: "4",
|
|
1833
|
+
py: "2.5",
|
|
1834
|
+
mx: isSubItem ? "0" : "4",
|
|
1835
|
+
w: isSubItem ? "full" : "auto",
|
|
1836
|
+
borderRadius: isSubItem ? "0" : "lg",
|
|
1837
|
+
role: "group",
|
|
1838
|
+
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
1839
|
+
opacity: 1,
|
|
1840
|
+
pointerEvents: isDisabled ? "none" : "auto",
|
|
1841
|
+
"data-nav-item-active": String(rowActive),
|
|
1842
|
+
bg: isDisabled ? disabledRowBg : rowActive ? isSubItem ? "gray.100" : modeConfig?.primaryColor || "brand.500" : "transparent",
|
|
1843
|
+
color: isDisabled ? disabledRowTextColor : rowActive ? isSubItem ? modeConfig?.primaryColor || "brand.500" : "white" : "gray.600",
|
|
1844
|
+
_hover: {
|
|
1845
|
+
bg: isDisabled ? disabledRowBg : rowActive ? isSubItem ? "gray.200" : modeConfig?.accentColor || "brand.600" : "gray.100",
|
|
1846
|
+
color: isDisabled ? disabledRowTextColor : rowActive ? isSubItem ? modeConfig?.primaryColor || "brand.500" : "white" : "gray.900"
|
|
1847
|
+
},
|
|
1848
|
+
"aria-disabled": isDisabled ? "true" : "false",
|
|
1849
|
+
onClick: handleClick,
|
|
1850
|
+
...rest,
|
|
1851
|
+
children: [
|
|
1852
|
+
brandIcon ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1853
|
+
react.Box,
|
|
1854
|
+
{
|
|
1855
|
+
mr: "4",
|
|
1856
|
+
display: "inline-flex",
|
|
1857
|
+
alignItems: "center",
|
|
1858
|
+
filter: rowActive && !isSubItem ? "brightness(0) invert(1)" : void 0,
|
|
1859
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(BrandIcon_default, { name: brandIcon, size: 18 })
|
|
1860
|
+
}
|
|
1861
|
+
) : icon ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1862
|
+
react.Box,
|
|
1863
|
+
{
|
|
1864
|
+
mr: "4",
|
|
1865
|
+
fontSize: "16",
|
|
1866
|
+
_groupHover: {
|
|
1867
|
+
color: isDisabled ? disabledRowTextColor : rowActive ? isSubItem ? modeConfig?.primaryColor || "brand.500" : "white" : "gray.900"
|
|
1868
|
+
},
|
|
1869
|
+
as: icon
|
|
1870
|
+
}
|
|
1871
|
+
) : null,
|
|
1872
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { flex: "1", children: [
|
|
1873
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { children }),
|
|
1874
|
+
subLabel ? /* @__PURE__ */ jsxRuntime.jsx(react.Text, { mt: 0.5, fontSize: "10px", lineHeight: "1.3", color: "gray.400", children: subLabel }) : null,
|
|
1875
|
+
badge && /* @__PURE__ */ jsxRuntime.jsx(react.Badge, { colorScheme: "orange", size: "xs", mt: 1, fontSize: "xs", display: "block", children: badge })
|
|
1876
|
+
] })
|
|
1877
|
+
]
|
|
1878
|
+
}
|
|
1879
|
+
)
|
|
1853
1880
|
}
|
|
1854
|
-
)
|
|
1881
|
+
);
|
|
1855
1882
|
}
|
|
1856
1883
|
var NavItem_default = NavItem;
|
|
1857
1884
|
|