@loafmarkets/ui 0.1.386 → 0.1.388

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/dist/index.d.mts CHANGED
@@ -643,7 +643,26 @@ type HeaderPortfolioData = {
643
643
  pnl: number;
644
644
  pnlPercent: number;
645
645
  };
646
- type HeaderActiveTab = "home" | "trade" | "offerings" | "propertyMap" | "about" | "portfolio" | "learn" | "api";
646
+ /**
647
+ * A single nav entry. The consuming app owns the entire nav set (which tabs,
648
+ * their labels, order and grouping) — the Header is a render-only view of this
649
+ * list, so different products/branches ship the same Header and only differ in
650
+ * the array they pass.
651
+ */
652
+ type HeaderNavItem = {
653
+ /** Stable id; also the value matched against `activeKey`. */
654
+ key: string;
655
+ label: string;
656
+ path: string;
657
+ /** Opens in a new tab (e.g. external Docs); never inferred active. */
658
+ external?: boolean;
659
+ /** "primary" = on the bar (default); "more" = inside the More dropdown. */
660
+ group?: "primary" | "more";
661
+ /** Active-tab inference: "exact" (default) or "prefix" (e.g. /offerings/*). */
662
+ match?: "exact" | "prefix";
663
+ /** Overrides navigation when clicked (e.g. trade chunk warm-up). */
664
+ onSelect?: () => void;
665
+ };
647
666
  type HeaderLoginPopupComponentProps = {
648
667
  onClose: () => void;
649
668
  initialView?: LoginPopupView;
@@ -652,19 +671,16 @@ type HeaderProps = {
652
671
  currentUser?: HeaderUser | null;
653
672
  isAuthenticated?: boolean;
654
673
  locationPath?: string;
655
- activeTab?: HeaderActiveTab;
674
+ /** The full nav set, owned by the consuming app. Rendered in order. */
675
+ navItems: HeaderNavItem[];
676
+ /** Force a nav item active by its `key`; otherwise inferred from locationPath. */
677
+ activeKey?: string;
656
678
  onNavigate?: (path: string) => void;
657
679
  onLogout?: () => Promise<void> | void;
658
680
  onSignInClick?: () => void;
659
681
  loginPopupComponent?: React__default.ComponentType<HeaderLoginPopupComponentProps>;
660
- tradePath?: string;
682
+ /** Logo link target (the logo is not a nav item). */
661
683
  homePath?: string;
662
- aboutPath?: string;
663
- learnPath?: string;
664
- apiPath?: string;
665
- offeringsPath?: string;
666
- propertyMapPath?: string;
667
- portfolioPath?: string;
668
684
  loafLiquidityPath?: string;
669
685
  /** Absolute URL for the auth/login surface (e.g. https://auth.loafmarkets.com/login). */
670
686
  authLoginUrl?: string | null;
@@ -678,12 +694,10 @@ type HeaderProps = {
678
694
  logoHref?: string;
679
695
  onLogoClick?: () => void;
680
696
  onLoafLiquidityClick?: () => void;
681
- onTradeClick?: () => void;
682
697
  onProfileNavigate?: () => void;
683
698
  onOrdersNavigate?: () => void;
684
699
  onWalletNavigate?: () => void;
685
700
  onSettingsClick?: () => void;
686
- showTradeTab?: boolean;
687
701
  portfolioSummary?: HeaderPortfolioData | null;
688
702
  /**
689
703
  * True while a brand-new user's test funds (100k mock USD) are being deposited
@@ -1310,4 +1324,4 @@ declare function extractSparkline(candles: ReadonlyArray<{
1310
1324
  }>, maxPoints?: number): number[];
1311
1325
  declare const SparklineChart: React__default.NamedExoticComponent<SparklineChartProps>;
1312
1326
 
1313
- export { type ActivityTabId, AssetSelectorBar, type AssetSelectorBarProps, type AssetSelectorMetric, Badge, type BadgeProps, Button, type ButtonProps, Card, CardContent, type CardContentProps, CardDescription, type CardDescriptionProps, CardFooter, type CardFooterProps, CardHeader, type CardHeaderProps, type CardProps, CardTitle, type CardTitleProps, ContactPopup, type ContactPopupProps, type FinancialItem, type FundWalletParams, type FundWalletResult, Header, type HeaderPortfolioData, type HeaderProps, type HousePositionOrderbook, type HousePositionPendingOrder, HousePositionSlider, HousePositionSliderMobile, type HousePositionSliderMobileOrderPayload, type HousePositionSliderMobileOrderbook, type HousePositionSliderMobileProps, type HousePositionSliderOrderPayload, type HousePositionSliderProps, type InspectionSlot, LoafLiquidityBadge, LoafLiquidityLogo, type LoafLiquidityLogoProps, LoginPopup, type LoginPopupProps, MobileTradeNav, type MobileTradeNavItem, type MobileTradeNavProps, type OfferStatus, OfferingProgressCard, type OfferingProgressCardProps, OnboardingGuide, type OnboardingGuideProps, Orderbook, type OrderbookLevel, type OrderbookProps, type OrderbookSide, type OrderbookTrade, type OverviewImage, type OverviewResponse, OwnerBooking, type OwnerBookingProps, PaymentPopup, type PaymentPopupProps, PortfolioActivityPanel, type PortfolioActivityPanelProps, type PortfolioPosition, PortfolioSummary, type PortfolioSummaryProps, PriceChart, type PriceChartCandle, type PriceChartProps, type PriceChartRange, type PropertyAddressOption, PropertyBuy, PropertyCompareBar, type PropertyCompareBarProps, PropertyDocuments, type PropertyGalleryHotspot, type PropertyGalleryImage, PropertyHeroHeader, type PropertyHeroHeaderProps, PropertyHistory, type PropertyInfoItem, PropertyInspectionTimes, PropertyMediaRow, type PropertyMediaRowProps, type PropertyNewsItem, type PropertyNewsType, PropertyNewsUpdates, type PropertyNewsUpdatesProps, type PropertyOffer, PropertyOffers, type PropertyOffersProps, PropertyOverview, type PropertyOverviewProps, PropertyPhotoGallery, type PropertyPriceSummary, PropertySubheader, type PropertySubheaderAction, type PropertySubheaderProps, type PropertySubheaderTab, PropertyTour, type PropertyTourProps, PropertyValuation, type PropertyValuationProps, type PropertyValueSummary, type PurchaseFeedItem, type SelectorItem, SiteFooter, Skeleton, type SkeletonProps, SlideDigit, SparklineChart, type SparklineChartProps, type ToastData, ToastProvider, type ToastVariant, TradeConfirmationModal, type TradeConfirmationModalDetails, type TradeConfirmationModalProps, TradingSlider, type TradingSliderProps, type YourOrder, type YourOrderSide, YourOrders, type YourOrdersProps, badgeVariants, buttonVariants, extractSparkline, hasPendingActivity, useAdaptivePolling, useToast };
1327
+ export { type ActivityTabId, AssetSelectorBar, type AssetSelectorBarProps, type AssetSelectorMetric, Badge, type BadgeProps, Button, type ButtonProps, Card, CardContent, type CardContentProps, CardDescription, type CardDescriptionProps, CardFooter, type CardFooterProps, CardHeader, type CardHeaderProps, type CardProps, CardTitle, type CardTitleProps, ContactPopup, type ContactPopupProps, type FinancialItem, type FundWalletParams, type FundWalletResult, Header, type HeaderNavItem, type HeaderPortfolioData, type HeaderProps, type HousePositionOrderbook, type HousePositionPendingOrder, HousePositionSlider, HousePositionSliderMobile, type HousePositionSliderMobileOrderPayload, type HousePositionSliderMobileOrderbook, type HousePositionSliderMobileProps, type HousePositionSliderOrderPayload, type HousePositionSliderProps, type InspectionSlot, LoafLiquidityBadge, LoafLiquidityLogo, type LoafLiquidityLogoProps, LoginPopup, type LoginPopupProps, MobileTradeNav, type MobileTradeNavItem, type MobileTradeNavProps, type OfferStatus, OfferingProgressCard, type OfferingProgressCardProps, OnboardingGuide, type OnboardingGuideProps, Orderbook, type OrderbookLevel, type OrderbookProps, type OrderbookSide, type OrderbookTrade, type OverviewImage, type OverviewResponse, OwnerBooking, type OwnerBookingProps, PaymentPopup, type PaymentPopupProps, PortfolioActivityPanel, type PortfolioActivityPanelProps, type PortfolioPosition, PortfolioSummary, type PortfolioSummaryProps, PriceChart, type PriceChartCandle, type PriceChartProps, type PriceChartRange, type PropertyAddressOption, PropertyBuy, PropertyCompareBar, type PropertyCompareBarProps, PropertyDocuments, type PropertyGalleryHotspot, type PropertyGalleryImage, PropertyHeroHeader, type PropertyHeroHeaderProps, PropertyHistory, type PropertyInfoItem, PropertyInspectionTimes, PropertyMediaRow, type PropertyMediaRowProps, type PropertyNewsItem, type PropertyNewsType, PropertyNewsUpdates, type PropertyNewsUpdatesProps, type PropertyOffer, PropertyOffers, type PropertyOffersProps, PropertyOverview, type PropertyOverviewProps, PropertyPhotoGallery, type PropertyPriceSummary, PropertySubheader, type PropertySubheaderAction, type PropertySubheaderProps, type PropertySubheaderTab, PropertyTour, type PropertyTourProps, PropertyValuation, type PropertyValuationProps, type PropertyValueSummary, type PurchaseFeedItem, type SelectorItem, SiteFooter, Skeleton, type SkeletonProps, SlideDigit, SparklineChart, type SparklineChartProps, type ToastData, ToastProvider, type ToastVariant, TradeConfirmationModal, type TradeConfirmationModalDetails, type TradeConfirmationModalProps, TradingSlider, type TradingSliderProps, type YourOrder, type YourOrderSide, YourOrders, type YourOrdersProps, badgeVariants, buttonVariants, extractSparkline, hasPendingActivity, useAdaptivePolling, useToast };
package/dist/index.d.ts CHANGED
@@ -643,7 +643,26 @@ type HeaderPortfolioData = {
643
643
  pnl: number;
644
644
  pnlPercent: number;
645
645
  };
646
- type HeaderActiveTab = "home" | "trade" | "offerings" | "propertyMap" | "about" | "portfolio" | "learn" | "api";
646
+ /**
647
+ * A single nav entry. The consuming app owns the entire nav set (which tabs,
648
+ * their labels, order and grouping) — the Header is a render-only view of this
649
+ * list, so different products/branches ship the same Header and only differ in
650
+ * the array they pass.
651
+ */
652
+ type HeaderNavItem = {
653
+ /** Stable id; also the value matched against `activeKey`. */
654
+ key: string;
655
+ label: string;
656
+ path: string;
657
+ /** Opens in a new tab (e.g. external Docs); never inferred active. */
658
+ external?: boolean;
659
+ /** "primary" = on the bar (default); "more" = inside the More dropdown. */
660
+ group?: "primary" | "more";
661
+ /** Active-tab inference: "exact" (default) or "prefix" (e.g. /offerings/*). */
662
+ match?: "exact" | "prefix";
663
+ /** Overrides navigation when clicked (e.g. trade chunk warm-up). */
664
+ onSelect?: () => void;
665
+ };
647
666
  type HeaderLoginPopupComponentProps = {
648
667
  onClose: () => void;
649
668
  initialView?: LoginPopupView;
@@ -652,19 +671,16 @@ type HeaderProps = {
652
671
  currentUser?: HeaderUser | null;
653
672
  isAuthenticated?: boolean;
654
673
  locationPath?: string;
655
- activeTab?: HeaderActiveTab;
674
+ /** The full nav set, owned by the consuming app. Rendered in order. */
675
+ navItems: HeaderNavItem[];
676
+ /** Force a nav item active by its `key`; otherwise inferred from locationPath. */
677
+ activeKey?: string;
656
678
  onNavigate?: (path: string) => void;
657
679
  onLogout?: () => Promise<void> | void;
658
680
  onSignInClick?: () => void;
659
681
  loginPopupComponent?: React__default.ComponentType<HeaderLoginPopupComponentProps>;
660
- tradePath?: string;
682
+ /** Logo link target (the logo is not a nav item). */
661
683
  homePath?: string;
662
- aboutPath?: string;
663
- learnPath?: string;
664
- apiPath?: string;
665
- offeringsPath?: string;
666
- propertyMapPath?: string;
667
- portfolioPath?: string;
668
684
  loafLiquidityPath?: string;
669
685
  /** Absolute URL for the auth/login surface (e.g. https://auth.loafmarkets.com/login). */
670
686
  authLoginUrl?: string | null;
@@ -678,12 +694,10 @@ type HeaderProps = {
678
694
  logoHref?: string;
679
695
  onLogoClick?: () => void;
680
696
  onLoafLiquidityClick?: () => void;
681
- onTradeClick?: () => void;
682
697
  onProfileNavigate?: () => void;
683
698
  onOrdersNavigate?: () => void;
684
699
  onWalletNavigate?: () => void;
685
700
  onSettingsClick?: () => void;
686
- showTradeTab?: boolean;
687
701
  portfolioSummary?: HeaderPortfolioData | null;
688
702
  /**
689
703
  * True while a brand-new user's test funds (100k mock USD) are being deposited
@@ -1310,4 +1324,4 @@ declare function extractSparkline(candles: ReadonlyArray<{
1310
1324
  }>, maxPoints?: number): number[];
1311
1325
  declare const SparklineChart: React__default.NamedExoticComponent<SparklineChartProps>;
1312
1326
 
1313
- export { type ActivityTabId, AssetSelectorBar, type AssetSelectorBarProps, type AssetSelectorMetric, Badge, type BadgeProps, Button, type ButtonProps, Card, CardContent, type CardContentProps, CardDescription, type CardDescriptionProps, CardFooter, type CardFooterProps, CardHeader, type CardHeaderProps, type CardProps, CardTitle, type CardTitleProps, ContactPopup, type ContactPopupProps, type FinancialItem, type FundWalletParams, type FundWalletResult, Header, type HeaderPortfolioData, type HeaderProps, type HousePositionOrderbook, type HousePositionPendingOrder, HousePositionSlider, HousePositionSliderMobile, type HousePositionSliderMobileOrderPayload, type HousePositionSliderMobileOrderbook, type HousePositionSliderMobileProps, type HousePositionSliderOrderPayload, type HousePositionSliderProps, type InspectionSlot, LoafLiquidityBadge, LoafLiquidityLogo, type LoafLiquidityLogoProps, LoginPopup, type LoginPopupProps, MobileTradeNav, type MobileTradeNavItem, type MobileTradeNavProps, type OfferStatus, OfferingProgressCard, type OfferingProgressCardProps, OnboardingGuide, type OnboardingGuideProps, Orderbook, type OrderbookLevel, type OrderbookProps, type OrderbookSide, type OrderbookTrade, type OverviewImage, type OverviewResponse, OwnerBooking, type OwnerBookingProps, PaymentPopup, type PaymentPopupProps, PortfolioActivityPanel, type PortfolioActivityPanelProps, type PortfolioPosition, PortfolioSummary, type PortfolioSummaryProps, PriceChart, type PriceChartCandle, type PriceChartProps, type PriceChartRange, type PropertyAddressOption, PropertyBuy, PropertyCompareBar, type PropertyCompareBarProps, PropertyDocuments, type PropertyGalleryHotspot, type PropertyGalleryImage, PropertyHeroHeader, type PropertyHeroHeaderProps, PropertyHistory, type PropertyInfoItem, PropertyInspectionTimes, PropertyMediaRow, type PropertyMediaRowProps, type PropertyNewsItem, type PropertyNewsType, PropertyNewsUpdates, type PropertyNewsUpdatesProps, type PropertyOffer, PropertyOffers, type PropertyOffersProps, PropertyOverview, type PropertyOverviewProps, PropertyPhotoGallery, type PropertyPriceSummary, PropertySubheader, type PropertySubheaderAction, type PropertySubheaderProps, type PropertySubheaderTab, PropertyTour, type PropertyTourProps, PropertyValuation, type PropertyValuationProps, type PropertyValueSummary, type PurchaseFeedItem, type SelectorItem, SiteFooter, Skeleton, type SkeletonProps, SlideDigit, SparklineChart, type SparklineChartProps, type ToastData, ToastProvider, type ToastVariant, TradeConfirmationModal, type TradeConfirmationModalDetails, type TradeConfirmationModalProps, TradingSlider, type TradingSliderProps, type YourOrder, type YourOrderSide, YourOrders, type YourOrdersProps, badgeVariants, buttonVariants, extractSparkline, hasPendingActivity, useAdaptivePolling, useToast };
1327
+ export { type ActivityTabId, AssetSelectorBar, type AssetSelectorBarProps, type AssetSelectorMetric, Badge, type BadgeProps, Button, type ButtonProps, Card, CardContent, type CardContentProps, CardDescription, type CardDescriptionProps, CardFooter, type CardFooterProps, CardHeader, type CardHeaderProps, type CardProps, CardTitle, type CardTitleProps, ContactPopup, type ContactPopupProps, type FinancialItem, type FundWalletParams, type FundWalletResult, Header, type HeaderNavItem, type HeaderPortfolioData, type HeaderProps, type HousePositionOrderbook, type HousePositionPendingOrder, HousePositionSlider, HousePositionSliderMobile, type HousePositionSliderMobileOrderPayload, type HousePositionSliderMobileOrderbook, type HousePositionSliderMobileProps, type HousePositionSliderOrderPayload, type HousePositionSliderProps, type InspectionSlot, LoafLiquidityBadge, LoafLiquidityLogo, type LoafLiquidityLogoProps, LoginPopup, type LoginPopupProps, MobileTradeNav, type MobileTradeNavItem, type MobileTradeNavProps, type OfferStatus, OfferingProgressCard, type OfferingProgressCardProps, OnboardingGuide, type OnboardingGuideProps, Orderbook, type OrderbookLevel, type OrderbookProps, type OrderbookSide, type OrderbookTrade, type OverviewImage, type OverviewResponse, OwnerBooking, type OwnerBookingProps, PaymentPopup, type PaymentPopupProps, PortfolioActivityPanel, type PortfolioActivityPanelProps, type PortfolioPosition, PortfolioSummary, type PortfolioSummaryProps, PriceChart, type PriceChartCandle, type PriceChartProps, type PriceChartRange, type PropertyAddressOption, PropertyBuy, PropertyCompareBar, type PropertyCompareBarProps, PropertyDocuments, type PropertyGalleryHotspot, type PropertyGalleryImage, PropertyHeroHeader, type PropertyHeroHeaderProps, PropertyHistory, type PropertyInfoItem, PropertyInspectionTimes, PropertyMediaRow, type PropertyMediaRowProps, type PropertyNewsItem, type PropertyNewsType, PropertyNewsUpdates, type PropertyNewsUpdatesProps, type PropertyOffer, PropertyOffers, type PropertyOffersProps, PropertyOverview, type PropertyOverviewProps, PropertyPhotoGallery, type PropertyPriceSummary, PropertySubheader, type PropertySubheaderAction, type PropertySubheaderProps, type PropertySubheaderTab, PropertyTour, type PropertyTourProps, PropertyValuation, type PropertyValuationProps, type PropertyValueSummary, type PurchaseFeedItem, type SelectorItem, SiteFooter, Skeleton, type SkeletonProps, SlideDigit, SparklineChart, type SparklineChartProps, type ToastData, ToastProvider, type ToastVariant, TradeConfirmationModal, type TradeConfirmationModalDetails, type TradeConfirmationModalProps, TradingSlider, type TradingSliderProps, type YourOrder, type YourOrderSide, YourOrders, type YourOrdersProps, badgeVariants, buttonVariants, extractSparkline, hasPendingActivity, useAdaptivePolling, useToast };
package/dist/index.js CHANGED
@@ -5061,13 +5061,7 @@ function useIsNarrow(maxWidthPx = 768) {
5061
5061
  }, [query]);
5062
5062
  return narrow;
5063
5063
  }
5064
- var DEFAULT_TRADE_PATH = "/trade";
5065
5064
  var DEFAULT_HOME_PATH = "/";
5066
- var DEFAULT_ABOUT_PATH = "/about";
5067
- var DEFAULT_LEARN_PATH = "/learn";
5068
- var DEFAULT_API_PATH = "/api";
5069
- var DEFAULT_PROPERTY_MAP_PATH = "/map";
5070
- var DEFAULT_PORTFOLIO_PATH = "/portfolio";
5071
5065
  var DEFAULT_LOAF_LIQUIDITY_PATH = "/loaf-liquidity";
5072
5066
  var DEFAULT_AUTH_RETURN_PARAM = "returnTo";
5073
5067
  var LOGIN_POPUP_EVENT = "loaf:open-login-popup";
@@ -5075,19 +5069,13 @@ var Header = ({
5075
5069
  currentUser,
5076
5070
  isAuthenticated = false,
5077
5071
  locationPath = DEFAULT_HOME_PATH,
5078
- activeTab,
5072
+ navItems,
5073
+ activeKey,
5079
5074
  onNavigate,
5080
5075
  onLogout,
5081
5076
  onSignInClick,
5082
5077
  loginPopupComponent: LoginPopupComponent,
5083
- tradePath = DEFAULT_TRADE_PATH,
5084
5078
  homePath = DEFAULT_HOME_PATH,
5085
- aboutPath = DEFAULT_ABOUT_PATH,
5086
- learnPath = DEFAULT_LEARN_PATH,
5087
- apiPath = DEFAULT_API_PATH,
5088
- offeringsPath,
5089
- propertyMapPath = DEFAULT_PROPERTY_MAP_PATH,
5090
- portfolioPath = DEFAULT_PORTFOLIO_PATH,
5091
5079
  loafLiquidityPath = DEFAULT_LOAF_LIQUIDITY_PATH,
5092
5080
  authLoginUrl,
5093
5081
  authReturnParam = DEFAULT_AUTH_RETURN_PARAM,
@@ -5095,12 +5083,10 @@ var Header = ({
5095
5083
  logoHref,
5096
5084
  onLogoClick,
5097
5085
  onLoafLiquidityClick,
5098
- onTradeClick,
5099
5086
  onProfileNavigate: _onProfileNavigate,
5100
5087
  onOrdersNavigate: _onOrdersNavigate,
5101
5088
  onWalletNavigate: _onWalletNavigate,
5102
5089
  onSettingsClick,
5103
- showTradeTab = true,
5104
5090
  portfolioSummary,
5105
5091
  fundsPending = false,
5106
5092
  transparentOnTop = false
@@ -5244,10 +5230,6 @@ var Header = ({
5244
5230
  window.location.href = path;
5245
5231
  }
5246
5232
  };
5247
- const handleNavigation = (path) => {
5248
- closeMenus();
5249
- performNavigation(path);
5250
- };
5251
5233
  const handleLogoNavigation = (event) => {
5252
5234
  event.preventDefault();
5253
5235
  closeMenus();
@@ -5265,16 +5247,19 @@ var Header = ({
5265
5247
  }
5266
5248
  performNavigation(resolvedLoafLiquidityPath);
5267
5249
  };
5268
- const handleTradeNavigation = () => {
5269
- if (!showTradeTab) {
5250
+ const handleNavItem = (item) => {
5251
+ closeMenus();
5252
+ if (item.onSelect) {
5253
+ item.onSelect();
5270
5254
  return;
5271
5255
  }
5272
- closeMenus();
5273
- if (onTradeClick) {
5274
- onTradeClick();
5256
+ if (item.external) {
5257
+ if (typeof window !== "undefined") {
5258
+ window.open(item.path, "_blank", "noopener,noreferrer");
5259
+ }
5275
5260
  return;
5276
5261
  }
5277
- performNavigation(resolvedTradePath);
5262
+ performNavigation(item.path);
5278
5263
  };
5279
5264
  const handleLogoutClick = async (event) => {
5280
5265
  event?.preventDefault();
@@ -5352,36 +5337,23 @@ var Header = ({
5352
5337
  setShowLoginPopup(false);
5353
5338
  setLoginPopupInitialView(void 0);
5354
5339
  }, []);
5355
- const resolvedTradePath = tradePath ?? DEFAULT_TRADE_PATH;
5356
5340
  const resolvedHomePath = homePath ?? DEFAULT_HOME_PATH;
5357
- const resolvedAboutPath = aboutPath ?? DEFAULT_ABOUT_PATH;
5358
- const resolvedLearnPath = learnPath ?? DEFAULT_LEARN_PATH;
5359
- const resolvedApiPath = apiPath ?? DEFAULT_API_PATH;
5360
- const resolvedOfferingsPath = offeringsPath ?? void 0;
5361
- const offeringsHref = resolvedOfferingsPath ?? resolvedHomePath;
5362
- const resolvedPropertyMapPath = propertyMapPath ?? DEFAULT_PROPERTY_MAP_PATH;
5363
- const resolvedPortfolioPath = portfolioPath ?? DEFAULT_PORTFOLIO_PATH;
5364
5341
  const resolvedLoafLiquidityPath = loafLiquidityPath ?? DEFAULT_LOAF_LIQUIDITY_PATH;
5365
- const inferredActiveTab = (() => {
5366
- if (showTradeTab && locationPath === resolvedTradePath) return "trade";
5367
- if (locationPath === resolvedHomePath) return "home";
5368
- if (locationPath === resolvedAboutPath) return "about";
5369
- if (locationPath === resolvedLearnPath) return "learn";
5370
- if (locationPath === resolvedApiPath) return "api";
5371
- if (resolvedOfferingsPath && locationPath.startsWith(resolvedOfferingsPath)) return "offerings";
5372
- if (locationPath === resolvedPropertyMapPath) return "propertyMap";
5373
- if (locationPath === resolvedPortfolioPath) return "portfolio";
5374
- return null;
5375
- })();
5376
- const resolvedActiveTab = activeTab ?? inferredActiveTab;
5377
- const tradeActive = showTradeTab && resolvedActiveTab === "trade";
5378
- const homeActive = resolvedActiveTab === "home";
5379
- const offeringsActive = resolvedActiveTab === "offerings";
5380
- const propertyMapActive = resolvedActiveTab === "propertyMap";
5381
- const aboutActive = resolvedActiveTab === "about";
5382
- const portfolioActive = resolvedActiveTab === "portfolio";
5383
- const learnActive = resolvedActiveTab === "learn";
5384
- const apiActive = resolvedActiveTab === "api";
5342
+ const inferredActiveKey = navItems.find(
5343
+ (item) => item.external ? false : item.match === "prefix" ? locationPath.startsWith(item.path) : locationPath === item.path
5344
+ )?.key ?? null;
5345
+ const resolvedActiveKey = activeKey ?? inferredActiveKey;
5346
+ const primaryItems = navItems.filter((item) => (item.group ?? "primary") === "primary");
5347
+ const moreItems = navItems.filter((item) => item.group === "more");
5348
+ const moreActive = moreItems.some((item) => item.key === resolvedActiveKey);
5349
+ const navLinkClick = (item) => (event) => {
5350
+ if (item.external) {
5351
+ closeMenus();
5352
+ return;
5353
+ }
5354
+ event.preventDefault();
5355
+ handleNavItem(item);
5356
+ };
5385
5357
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5386
5358
  /* @__PURE__ */ jsxRuntime.jsx(SafeAreaCover, {}),
5387
5359
  /* @__PURE__ */ jsxRuntime.jsx(Overlay, { $isOpen: isMobileMenuOpen, onClick: () => setIsMobileMenuOpen(false) }),
@@ -5398,111 +5370,44 @@ var Header = ({
5398
5370
  style: { display: "flex", flexDirection: "row", alignItems: "center", height: "56px" },
5399
5371
  className: "desktop-nav",
5400
5372
  children: [
5401
- /* @__PURE__ */ jsxRuntime.jsx(
5402
- NavLink,
5403
- {
5404
- href: resolvedHomePath,
5405
- className: homeActive ? "active" : "",
5406
- onClick: (event) => {
5407
- event.preventDefault();
5408
- handleNavigation(resolvedHomePath);
5409
- },
5410
- children: "Home"
5411
- }
5412
- ),
5413
- /* @__PURE__ */ jsxRuntime.jsx(
5373
+ primaryItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
5414
5374
  NavLink,
5415
5375
  {
5416
- href: resolvedPortfolioPath,
5417
- className: portfolioActive ? "active" : "",
5418
- onClick: (event) => {
5419
- event.preventDefault();
5420
- handleNavigation(resolvedPortfolioPath);
5421
- },
5422
- children: "Portfolio"
5423
- }
5424
- ),
5425
- showTradeTab && /* @__PURE__ */ jsxRuntime.jsx(
5426
- NavLink,
5427
- {
5428
- href: resolvedTradePath,
5429
- className: tradeActive ? "active" : "",
5430
- onClick: (event) => {
5431
- event.preventDefault();
5432
- handleTradeNavigation();
5433
- },
5434
- children: "Trade"
5435
- }
5436
- ),
5437
- /* @__PURE__ */ jsxRuntime.jsx(
5438
- NavLink,
5439
- {
5440
- href: offeringsHref,
5441
- className: offeringsActive ? "active" : "",
5442
- onClick: (event) => {
5443
- event.preventDefault();
5444
- handleNavigation(offeringsHref);
5445
- },
5446
- children: "Initial Offerings"
5447
- }
5448
- ),
5449
- /* @__PURE__ */ jsxRuntime.jsx(
5450
- NavLink,
5451
- {
5452
- href: resolvedPropertyMapPath,
5453
- className: propertyMapActive ? "active" : "",
5454
- onClick: (event) => {
5455
- event.preventDefault();
5456
- handleNavigation(resolvedPropertyMapPath);
5457
- },
5458
- children: "Property Map"
5459
- }
5460
- ),
5461
- /* @__PURE__ */ jsxRuntime.jsx(
5462
- NavLink,
5463
- {
5464
- href: resolvedLearnPath,
5465
- className: learnActive ? "active" : "",
5466
- onClick: (event) => {
5467
- event.preventDefault();
5468
- handleNavigation(resolvedLearnPath);
5469
- },
5470
- children: "Learn"
5471
- }
5472
- ),
5473
- /* @__PURE__ */ jsxRuntime.jsx(
5474
- NavLink,
5475
- {
5476
- href: resolvedAboutPath,
5477
- className: aboutActive ? "active" : "",
5478
- onClick: (event) => {
5479
- event.preventDefault();
5480
- handleNavigation(resolvedAboutPath);
5481
- },
5482
- children: "About"
5483
- }
5484
- ),
5485
- /* @__PURE__ */ jsxRuntime.jsx(
5486
- NavLink,
5487
- {
5488
- href: resolvedApiPath,
5489
- className: apiActive ? "active" : "",
5490
- onClick: (event) => {
5491
- event.preventDefault();
5492
- handleNavigation(resolvedApiPath);
5376
+ href: item.path,
5377
+ ...item.external ? { target: "_blank", rel: "noopener noreferrer" } : {},
5378
+ className: item.key === resolvedActiveKey ? "active" : "",
5379
+ onClick: navLinkClick(item),
5380
+ children: item.label
5381
+ },
5382
+ item.key
5383
+ )),
5384
+ moreItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(MoreMenu, { className: "more-menu", children: [
5385
+ /* @__PURE__ */ jsxRuntime.jsxs(
5386
+ MoreTrigger,
5387
+ {
5388
+ type: "button",
5389
+ className: `${isMoreMenuOpen ? "open" : ""} ${moreActive ? "active" : ""}`,
5390
+ "aria-haspopup": "true",
5391
+ "aria-expanded": isMoreMenuOpen,
5392
+ onClick: () => setIsMoreMenuOpen((open) => !open),
5393
+ children: [
5394
+ "More",
5395
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 9l6 6 6-6", strokeLinecap: "round", strokeLinejoin: "round" }) })
5396
+ ]
5397
+ }
5398
+ ),
5399
+ isMoreMenuOpen && /* @__PURE__ */ jsxRuntime.jsx(MoreDropdown, { children: moreItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
5400
+ MoreItem,
5401
+ {
5402
+ href: item.path,
5403
+ ...item.external ? { target: "_blank", rel: "noopener noreferrer" } : {},
5404
+ className: item.key === resolvedActiveKey ? "active" : "",
5405
+ onClick: navLinkClick(item),
5406
+ children: item.label
5493
5407
  },
5494
- children: "API"
5495
- }
5496
- ),
5497
- /* @__PURE__ */ jsxRuntime.jsx(
5498
- NavLink,
5499
- {
5500
- href: "https://docs.loafmarkets.com/en/",
5501
- target: "_blank",
5502
- rel: "noopener noreferrer",
5503
- children: "Docs"
5504
- }
5505
- ),
5408
+ item.key
5409
+ )) })
5410
+ ] }),
5506
5411
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginLeft: "auto", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
5507
5412
  "div",
5508
5413
  {
@@ -5524,29 +5429,7 @@ var Header = ({
5524
5429
  ),
5525
5430
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mobile-menu-content", children: [
5526
5431
  /* @__PURE__ */ jsxRuntime.jsx(MobileMenuHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(MobileMenuClose, { onClick: () => setIsMobileMenuOpen(false), "aria-label": "Close menu", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }) }),
5527
- /* @__PURE__ */ jsxRuntime.jsx(MobileNavItem, { onClick: () => handleNavigation(resolvedHomePath), children: "Home" }),
5528
- /* @__PURE__ */ jsxRuntime.jsx(
5529
- MobileNavItem,
5530
- {
5531
- onClick: () => handleNavigation(resolvedPortfolioPath),
5532
- children: "Portfolio"
5533
- }
5534
- ),
5535
- showTradeTab && /* @__PURE__ */ jsxRuntime.jsx(
5536
- MobileNavItem,
5537
- {
5538
- onClick: () => {
5539
- handleTradeNavigation();
5540
- },
5541
- children: "Trade"
5542
- }
5543
- ),
5544
- /* @__PURE__ */ jsxRuntime.jsx(MobileNavItem, { onClick: () => handleNavigation(offeringsHref), children: "Initial Offerings" }),
5545
- /* @__PURE__ */ jsxRuntime.jsx(MobileNavItem, { onClick: () => handleNavigation(resolvedPropertyMapPath), children: "Property Map" }),
5546
- /* @__PURE__ */ jsxRuntime.jsx(MobileNavItem, { onClick: () => handleNavigation(resolvedLearnPath), children: "Learn" }),
5547
- /* @__PURE__ */ jsxRuntime.jsx(MobileNavItem, { onClick: () => handleNavigation(resolvedAboutPath), children: "About" }),
5548
- /* @__PURE__ */ jsxRuntime.jsx(MobileNavItem, { onClick: () => handleNavigation(resolvedApiPath), children: "API" }),
5549
- /* @__PURE__ */ jsxRuntime.jsx(MobileNavItem, { onClick: () => window.open("https://docs.loafmarkets.com/en/", "_blank", "noopener,noreferrer"), children: "Docs" }),
5432
+ navItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(MobileNavItem, { onClick: () => handleNavItem(item), children: item.label }, item.key)),
5550
5433
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { borderTop: "1px solid #2b3139", margin: "8px 0" } }),
5551
5434
  /* @__PURE__ */ jsxRuntime.jsx(
5552
5435
  MobileNavItem,
@@ -6060,6 +5943,77 @@ var NavLink = styled10__default.default.a`
6060
5943
  }
6061
5944
  }
6062
5945
  `;
5946
+ var MoreMenu = styled10__default.default.div`
5947
+ position: relative;
5948
+ display: flex;
5949
+ align-items: center;
5950
+ height: 56px;
5951
+ `;
5952
+ var MoreTrigger = styled10__default.default.button`
5953
+ margin: 0 12px;
5954
+ padding: 0 4px;
5955
+ height: 56px;
5956
+ display: inline-flex;
5957
+ align-items: center;
5958
+ gap: 4px;
5959
+ background: none;
5960
+ border: none;
5961
+ cursor: pointer;
5962
+ color: #eaecef;
5963
+ font-weight: 500;
5964
+ font-size: 14px;
5965
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif;
5966
+ letter-spacing: 0.2px;
5967
+ transition: color 0.2s ease;
5968
+
5969
+ &:hover,
5970
+ &.active {
5971
+ color: #E6C87E;
5972
+ }
5973
+
5974
+ svg {
5975
+ width: 14px;
5976
+ height: 14px;
5977
+ transition: transform 0.2s ease;
5978
+ }
5979
+ &.open svg {
5980
+ transform: rotate(180deg);
5981
+ }
5982
+ `;
5983
+ var MoreDropdown = styled10__default.default.div`
5984
+ position: absolute;
5985
+ top: 100%;
5986
+ right: 0;
5987
+ min-width: 160px;
5988
+ padding: 6px;
5989
+ background: #1e2026;
5990
+ border: 1px solid #2b3139;
5991
+ border-radius: 10px;
5992
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
5993
+ display: flex;
5994
+ flex-direction: column;
5995
+ z-index: 1100;
5996
+ `;
5997
+ var MoreItem = styled10__default.default.a`
5998
+ padding: 10px 12px;
5999
+ border-radius: 6px;
6000
+ color: #eaecef;
6001
+ font-weight: 500;
6002
+ font-size: 14px;
6003
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif;
6004
+ letter-spacing: 0.2px;
6005
+ text-decoration: none;
6006
+ cursor: pointer;
6007
+ transition: background 0.15s ease, color 0.15s ease;
6008
+
6009
+ &:hover {
6010
+ background: #2b3139;
6011
+ color: #E6C87E;
6012
+ }
6013
+ &.active {
6014
+ color: #E6C87E;
6015
+ }
6016
+ `;
6063
6017
  var Button2 = styled10__default.default.button.attrs({ type: "button" })`
6064
6018
  padding: 0.5rem 1rem;
6065
6019
  border-radius: 6px;
@@ -6855,11 +6809,8 @@ var LoginPopup = ({
6855
6809
  }
6856
6810
  return;
6857
6811
  }
6858
- if (onSubmitReferralCode) {
6859
- setView("referral");
6860
- } else {
6861
- onClose();
6862
- }
6812
+ window.dispatchEvent(new CustomEvent("loaf:onboarding-start"));
6813
+ onClose();
6863
6814
  } catch (err) {
6864
6815
  setError(err instanceof Error ? err.message : "Couldn't complete sign up. Please try again.");
6865
6816
  } finally {
@@ -7002,11 +6953,8 @@ var LoginPopup = ({
7002
6953
  try {
7003
6954
  await onVerifyEmailCode({ code, email });
7004
6955
  if (isSignUp) {
7005
- if (onSubmitReferralCode) {
7006
- setView("referral");
7007
- } else {
7008
- onClose();
7009
- }
6956
+ window.dispatchEvent(new CustomEvent("loaf:onboarding-start"));
6957
+ onClose();
7010
6958
  setLoading(false);
7011
6959
  return;
7012
6960
  }