@fayz-ai/storefront 0.81.0 → 0.83.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.
Files changed (44) hide show
  1. package/dist/analytics/bus.d.ts +3 -1
  2. package/dist/analytics/bus.d.ts.map +1 -1
  3. package/dist/analytics/posthog.d.ts.map +1 -1
  4. package/dist/app/router.d.ts +1 -1
  5. package/dist/blocks/registry.d.ts.map +1 -1
  6. package/dist/chunk-4REZOGGW.js +153 -0
  7. package/dist/chunk-4REZOGGW.js.map +1 -0
  8. package/dist/{chunk-CWHGBPRP.js → chunk-7GX7JLF7.js} +309 -178
  9. package/dist/chunk-7GX7JLF7.js.map +1 -0
  10. package/dist/{chunk-2KCORAVB.js → chunk-7N5HKQBM.js} +3 -2
  11. package/dist/chunk-7N5HKQBM.js.map +1 -0
  12. package/dist/{chunk-OIPNINZQ.js → chunk-XDK5H5Y3.js} +4 -4
  13. package/dist/{chunk-OIPNINZQ.js.map → chunk-XDK5H5Y3.js.map} +1 -1
  14. package/dist/components/delivery/StoreCover.d.ts.map +1 -1
  15. package/dist/document/config.d.ts +24 -0
  16. package/dist/document/config.d.ts.map +1 -1
  17. package/dist/edge.d.ts +2 -1
  18. package/dist/edge.d.ts.map +1 -1
  19. package/dist/edge.js +57 -10
  20. package/dist/edge.js.map +1 -1
  21. package/dist/experiments/assign.d.ts +101 -0
  22. package/dist/experiments/assign.d.ts.map +1 -0
  23. package/dist/experiments/react.d.ts +99 -0
  24. package/dist/experiments/react.d.ts.map +1 -0
  25. package/dist/host/edge-handler.d.ts +32 -2
  26. package/dist/host/edge-handler.d.ts.map +1 -1
  27. package/dist/host/store-host.d.ts +11 -1
  28. package/dist/host/store-host.d.ts.map +1 -1
  29. package/dist/host.d.ts +2 -0
  30. package/dist/host.d.ts.map +1 -1
  31. package/dist/host.js +10 -4
  32. package/dist/host.js.map +1 -1
  33. package/dist/index.d.ts +4 -0
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +7 -6
  36. package/dist/index.js.map +1 -1
  37. package/dist/render.js +4 -3
  38. package/dist/render.js.map +1 -1
  39. package/dist/tanstack.d.ts.map +1 -1
  40. package/dist/tanstack.js +4 -3
  41. package/dist/tanstack.js.map +1 -1
  42. package/package.json +2 -2
  43. package/dist/chunk-2KCORAVB.js.map +0 -1
  44. package/dist/chunk-CWHGBPRP.js.map +0 -1
@@ -1,14 +1,15 @@
1
- import { Link, useStorefrontConfigOptional, useStorefrontConfig, useBlockData, BlockDataError, navigateTo, useRoutePath, toBlockNodes, defaultPageBlocks, PageDataScope, getStorefrontComponents, useLoader, currentStaticRenderPass, matchPath, translate, productSeo, StorefrontConfigProvider, mergePageTheme, pageThemeSelector, MENU_DATA_NEEDS, resolveConfig, useRouterAdapter, shellRouterAdapter, StorefrontRouterProvider, useScrollToTopOnNavigate, checkPageBlocks, normalizeLanguage, useHashPath, resolveStorefrontRoute, matchContentPage } from './chunk-2KCORAVB.js';
1
+ import { Link, useStorefrontConfig, useStorefrontConfigOptional, useBlockData, BlockDataError, navigateTo, useRoutePath, toBlockNodes, defaultPageBlocks, PageDataScope, getStorefrontComponents, useLoader, currentStaticRenderPass, matchPath, translate, productSeo, StorefrontConfigProvider, mergePageTheme, pageThemeSelector, MENU_DATA_NEEDS, resolveConfig, useRouterAdapter, shellRouterAdapter, StorefrontRouterProvider, useScrollToTopOnNavigate, checkPageBlocks, normalizeLanguage, useHashPath, resolveStorefrontRoute, matchContentPage } from './chunk-7N5HKQBM.js';
2
+ import { runningExperiments, CONTROL, readVisitorId } from './chunk-4REZOGGW.js';
2
3
  import { create } from 'zustand';
3
4
  import { persist } from 'zustand/middleware';
4
- import { normalizePostalCode, getCountrySchema, lookupPostalCode, defineLoader, repairBlockTree, renderBlocks, clearExtensionPoints, defineExtensionPoint, runExtensionPoint, runEscapeValve, errorMessage, hasEntityDeclaration, resolveEntityDeclaration, defineBlock, formatPostalCode, countryName, defineEntity, defaultRouterAdapter, describeError, validateAddress } from '@fayz-ai/core';
5
+ import { normalizePostalCode, getCountrySchema, lookupPostalCode, useBlockPath, BlockRenderer, BlockChildren, defineLoader, repairBlockTree, renderBlocks, clearExtensionPoints, defineExtensionPoint, runExtensionPoint, runEscapeValve, errorMessage, hasEntityDeclaration, resolveEntityDeclaration, defineBlock, formatPostalCode, countryName, defineEntity, defaultRouterAdapter, describeError, validateAddress } from '@fayz-ai/core';
5
6
  import { getShopProvider, setShopProvider } from '@fayz-ai/shop/runtime';
6
- import * as React36 from 'react';
7
- import React36__default, { createContext, useRef, useState, useEffect, useMemo, useContext, useCallback } from 'react';
7
+ import * as React37 from 'react';
8
+ import React37__default, { createContext, useRef, useState, useEffect, useMemo, useContext, useCallback } from 'react';
9
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
10
  import { createMockAuthAdapter } from '@fayz-ai/auth';
9
11
  import { createAuthRuntime } from '@fayz-ai/auth/lib/runtime';
10
12
  import { setShopCarrierQuotesResolver, setShopAccessTokenResolver, setShopShippingItemsResolver } from '@fayz-ai/sdk/shop';
11
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
12
13
  import { isStorageImageUrl, imageVariantUrl, imageSrcSet, IMAGE_SRCSET_WIDTHS, validateDiscount, documentDigits, isChargeableProvider, supportsCard, formatDocument, isValidDocument, gatewayLabel, isValidCpf } from '@fayz-ai/shop';
13
14
  import { ChevronLeft, ChevronRight, ShoppingBag, X, Minus, Plus, Send, MessageCircle, Mail, Truck, RefreshCcw, ShieldCheck, ChevronDown, Check, Search, Menu, Trash2, MapPin, Lock, CreditCard, UserRound, Store, Bike, Clock, Pencil, Star, Phone, User, UserCircle, Package, LogOut, QrCode, Copy, XCircle, RotateCcw, PackageCheck, ChefHat, Info, AlertCircle } from 'lucide-react';
14
15
  import { getLucideIcon } from '@fayz-ai/ui/icons';
@@ -531,6 +532,95 @@ async function storeBuyerId(storeId, email) {
531
532
  const hex = Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, "0")).join("");
532
533
  return `store:${storeId}:${hex}`;
533
534
  }
535
+ function isExperimentBinding(value) {
536
+ return typeof value === "object" && value !== null && typeof value.experiment === "string" && typeof value.variants === "object";
537
+ }
538
+ function resolveExperimental(value, variant) {
539
+ if (!isExperimentBinding(value)) return value;
540
+ return value.variants[variant] ?? value.variants.control;
541
+ }
542
+ var bootstrap = null;
543
+ function getExperimentBootstrap() {
544
+ return bootstrap;
545
+ }
546
+ var ExperimentContext = React37__default.createContext(null);
547
+ function ExperimentProvider({ assignments, path, children }) {
548
+ const config = useStorefrontConfig();
549
+ const kept = React37__default.useRef(null);
550
+ if (!kept.current && assignments) kept.current = assignments;
551
+ const current = kept.current ?? { flags: {} };
552
+ if (typeof window !== "undefined" && kept.current && !bootstrap) bootstrap = kept.current;
553
+ const declaredKeys = Object.keys(runningExperiments(config.experiments)).sort().join("\n");
554
+ const declared = React37__default.useMemo(() => new Set(declaredKeys ? declaredKeys.split("\n") : []), [declaredKeys]);
555
+ const exposed = React37__default.useMemo(() => /* @__PURE__ */ new Set(), [path]);
556
+ const value = React37__default.useMemo(() => ({ assignments: current, declared, exposed }), [current, declared, exposed]);
557
+ return /* @__PURE__ */ jsx(ExperimentContext.Provider, { value, children });
558
+ }
559
+ function useExperiment(key) {
560
+ const state = React37__default.useContext(ExperimentContext);
561
+ const assigned = state?.declared.has(key) ? state.assignments.flags[key] : void 0;
562
+ const result = assigned ?? { variant: CONTROL };
563
+ const variant = result.variant;
564
+ const inExperiment = Boolean(assigned);
565
+ React37__default.useEffect(() => {
566
+ if (!state || !inExperiment || state.exposed.has(key)) return;
567
+ state.exposed.add(key);
568
+ trackStorefront("experiment_exposed", { experiment: key, variant });
569
+ }, [state, key, variant, inExperiment]);
570
+ return result;
571
+ }
572
+ function useExperimentValue(value) {
573
+ const bound = isExperimentBinding(value);
574
+ if (!bound) return value;
575
+ const { variant } = useExperiment(value.experiment);
576
+ return resolveExperimental(value, variant);
577
+ }
578
+ function ExperimentBlock({ experiment, node }) {
579
+ const { variant } = useExperiment(experiment ?? "");
580
+ const path = useBlockPath();
581
+ const variants = node?.children ?? [];
582
+ let index = variants.findIndex((child) => child.props?.variant === variant);
583
+ if (index < 0) index = variants.findIndex((child) => child.props?.variant === CONTROL);
584
+ if (index < 0) return null;
585
+ return /* @__PURE__ */ jsx(BlockRenderer, { node: variants[index], path: path ? `${path}.children[${index}]` : void 0 });
586
+ }
587
+ function ExperimentVariantBlock({ node }) {
588
+ return /* @__PURE__ */ jsx(BlockChildren, { node });
589
+ }
590
+ var experimentBlockMeta = {
591
+ label: "Experiment",
592
+ description: 'A/B test: shows one of its variants to each visitor, as bucketed at the edge for the declared experiment of the same key. The variant named "control" is the fallback.',
593
+ settings: [
594
+ {
595
+ id: "experiment",
596
+ type: "text",
597
+ label: "Experiment key",
598
+ required: true,
599
+ help: "The PostHog flag key, declared in the store config under `experiments`."
600
+ }
601
+ ],
602
+ presets: [{ name: "A/B test", props: { experiment: "my-experiment" } }],
603
+ enabledOn: ["home", "catalog", "product", "collection", "content"]
604
+ };
605
+ var experimentVariantBlockMeta = {
606
+ label: "Experiment variant",
607
+ description: "The blocks one variant of an experiment shows.",
608
+ parent: ["experiment"],
609
+ settings: [
610
+ {
611
+ id: "variant",
612
+ type: "text",
613
+ label: "Variant key",
614
+ required: true,
615
+ help: 'Exactly as on the PostHog flag, e.g. "control" or "test".'
616
+ }
617
+ ],
618
+ presets: [
619
+ { name: "Control", props: { variant: "control" } },
620
+ { name: "Test", props: { variant: "test" } }
621
+ ],
622
+ enabledOn: ["home", "catalog", "product", "collection", "content"]
623
+ };
534
624
 
535
625
  // src/analytics/posthog.ts
536
626
  var started = null;
@@ -540,7 +630,24 @@ function startStorefrontPostHog(config, context) {
540
630
  started = (async () => {
541
631
  const { default: posthog } = await import('posthog-js');
542
632
  const store = { store_id: config.storeId, store_name: context.storeName, commerce_mode: context.commerceMode };
633
+ const experiments = getExperimentBootstrap();
634
+ const hasPostHogCookie = document.cookie.includes(`ph_${config.key}_posthog=`);
635
+ const visitorId = hasPostHogCookie ? void 0 : readVisitorId(document.cookie, config.key);
636
+ const flags = experiments?.flags ?? {};
637
+ const bootstrap2 = Object.keys(flags).length || visitorId ? {
638
+ ...visitorId ? { distinctID: visitorId } : {},
639
+ featureFlags: Object.fromEntries(Object.entries(flags).map(([k, a]) => [k, a.variant])),
640
+ featureFlagPayloads: Object.fromEntries(
641
+ Object.entries(flags).filter(([, a]) => a.payload !== void 0).map(([k, a]) => [k, a.payload])
642
+ )
643
+ } : void 0;
543
644
  posthog.init(config.key, {
645
+ ...bootstrap2 ? { bootstrap: bootstrap2 } : {},
646
+ // With variants bootstrapped, the browser does not re-ask /flags on
647
+ // load: an answer that differed from the rendered page (a server-side
648
+ // timeout, a rollout change between the two calls) would tag this
649
+ // visitor's events with a variant they never saw.
650
+ ...Object.keys(flags).length ? { advanced_disable_feature_flags_on_first_load: true } : {},
544
651
  api_host: config.apiHost ?? "/ingest",
545
652
  ui_host: config.uiHost ?? "https://us.posthog.com",
546
653
  defaults: "2026-08-30",
@@ -559,6 +666,16 @@ function startStorefrontPostHog(config, context) {
559
666
  });
560
667
  posthog.register(store);
561
668
  onStorefrontEvent((event) => {
669
+ if (event.name === "experiment_exposed") {
670
+ const { experiment, variant } = event.properties;
671
+ if (typeof experiment !== "string" || typeof variant !== "string") return;
672
+ posthog.capture("$feature_flag_called", {
673
+ $feature_flag: experiment,
674
+ $feature_flag_response: variant,
675
+ [`$feature/${experiment}`]: variant
676
+ });
677
+ return;
678
+ }
562
679
  posthog.capture(event.name, event.properties, { timestamp: new Date(event.at) });
563
680
  });
564
681
  setStorefrontIdentifier((email) => {
@@ -698,19 +815,19 @@ function StorefrontAnalytics({ config, path }) {
698
815
  const metaPixel = pixelId && META_PIXEL_ID.test(pixelId) ? pixelId : null;
699
816
  const reporting = Boolean(posthog || metaPixel);
700
817
  const menuPath = config.delivery?.menuPath;
701
- const previous = React36.useRef(null);
702
- React36.useEffect(() => {
818
+ const previous = React37.useRef(null);
819
+ React37.useEffect(() => {
703
820
  if (!posthog) return;
704
821
  startStorefrontPostHog(posthog, { storeName: config.name, commerceMode: config.commerceMode });
705
822
  }, [posthog, config.name, config.commerceMode]);
706
- React36.useEffect(() => {
823
+ React37.useEffect(() => {
707
824
  if (!metaPixel) return;
708
825
  startStorefrontMetaPixel({ pixelId: metaPixel }, { currency: config.currency ?? "BRL" });
709
826
  }, [metaPixel, config.currency]);
710
- React36.useEffect(() => {
827
+ React37.useEffect(() => {
711
828
  if (metaPixel) trackMetaPageView();
712
829
  }, [metaPixel, path]);
713
- React36.useEffect(() => {
830
+ React37.useEffect(() => {
714
831
  if (!reporting) return;
715
832
  let ready = useCartStore.persist?.hasHydrated?.() ?? true;
716
833
  const unhydrated = useCartStore.persist?.onFinishHydration?.(() => {
@@ -741,7 +858,7 @@ function StorefrontAnalytics({ config, path }) {
741
858
  unhydrated?.();
742
859
  };
743
860
  }, [reporting]);
744
- React36.useEffect(() => {
861
+ React37.useEffect(() => {
745
862
  if (!reporting) return;
746
863
  const from = previous.current;
747
864
  previous.current = path;
@@ -1555,9 +1672,9 @@ function SmoothImage({
1555
1672
  const easing = resolved.easing ?? "cubic-bezier(0.22, 1, 0.36, 1)";
1556
1673
  const blur = resolved.blur ?? true;
1557
1674
  const transform = resolved.transform ?? "none";
1558
- const ref = React36__default.useRef(null);
1559
- const [loaded, setLoaded] = React36__default.useState(() => mode === "none" || !clientMounted);
1560
- const delivered = React36__default.useMemo(() => {
1675
+ const ref = React37__default.useRef(null);
1676
+ const [loaded, setLoaded] = React37__default.useState(() => mode === "none" || !clientMounted);
1677
+ const delivered = React37__default.useMemo(() => {
1561
1678
  if (transform !== "supabase" || !src || srcSet || !isStorageImageUrl(src)) return { src, srcSet, sizes };
1562
1679
  if (variant?.width) {
1563
1680
  const w = variant.width;
@@ -1575,10 +1692,10 @@ function SmoothImage({
1575
1692
  sizes: variant?.sizes ?? sizes ?? "100vw"
1576
1693
  };
1577
1694
  }, [transform, src, srcSet, sizes, variant?.width, variant?.sizes, variant?.widths, variant?.quality]);
1578
- React36__default.useEffect(() => {
1695
+ React37__default.useEffect(() => {
1579
1696
  clientMounted = true;
1580
1697
  }, []);
1581
- React36__default.useEffect(() => {
1698
+ React37__default.useEffect(() => {
1582
1699
  if (mode === "none") {
1583
1700
  setLoaded(true);
1584
1701
  return;
@@ -2520,8 +2637,8 @@ var BADGE_TONE_CLASSES = {
2520
2637
  warning: "bg-amber-500 text-white"
2521
2638
  };
2522
2639
  function useExtensionBadges(product) {
2523
- const [badges, setBadges] = React36__default.useState([]);
2524
- React36__default.useEffect(() => {
2640
+ const [badges, setBadges] = React37__default.useState([]);
2641
+ React37__default.useEffect(() => {
2525
2642
  let cancelled = false;
2526
2643
  getProductCardBadges(product).then((next) => {
2527
2644
  if (!cancelled && next.length > 0) setBadges(next);
@@ -3661,7 +3778,7 @@ function scalarToString(value) {
3661
3778
  }
3662
3779
  function ProductSpecs({ product }) {
3663
3780
  const config = useStorefrontConfig();
3664
- const extraExcluded = React36__default.useMemo(
3781
+ const extraExcluded = React37__default.useMemo(
3665
3782
  () => new Set(config.productSpecs?.exclude ?? []),
3666
3783
  [config.productSpecs?.exclude]
3667
3784
  );
@@ -5386,7 +5503,7 @@ function CollectionHero({
5386
5503
  {
5387
5504
  className: `absolute inset-0 flex flex-col justify-center p-6 text-white sm:p-12 ${OVERLAY_CLASS[overlay]} ${centered ? "items-center text-center" : "items-start text-left"}`,
5388
5505
  children: /* @__PURE__ */ jsxs(Reveal, { className: centered ? "max-w-3xl" : "max-w-2xl", children: [
5389
- logos && logos.length > 0 && /* @__PURE__ */ jsx("div", { className: `mb-6 flex items-center gap-5 ${centered ? "justify-center" : ""}`, children: logos.map((logo, i) => /* @__PURE__ */ jsxs(React36__default.Fragment, { children: [
5506
+ logos && logos.length > 0 && /* @__PURE__ */ jsx("div", { className: `mb-6 flex items-center gap-5 ${centered ? "justify-center" : ""}`, children: logos.map((logo, i) => /* @__PURE__ */ jsxs(React37__default.Fragment, { children: [
5390
5507
  i > 0 && /* @__PURE__ */ jsx("span", { className: "text-2xl font-light opacity-60", "aria-hidden": true, children: "\xD7" }),
5391
5508
  /* @__PURE__ */ jsx("img", { src: logo.src, alt: logo.alt, className: "h-10 w-auto object-contain sm:h-14" })
5392
5509
  ] }, logo.src)) }),
@@ -6116,6 +6233,8 @@ function registerStorefrontBlocks() {
6116
6233
  defineBlock("collectionCta", CollectionCta, { source: "sdk", ...collectionCtaBlockMeta });
6117
6234
  defineBlock("catalogBody", CatalogBodyBlock, { source: "sdk", ...catalogBodyBlockMeta });
6118
6235
  defineBlock("productBody", ProductBodyBlock, { source: "sdk", ...productBodyBlockMeta });
6236
+ defineBlock("experiment", ExperimentBlock, { source: "sdk", ...experimentBlockMeta });
6237
+ defineBlock("experimentVariant", ExperimentVariantBlock, { source: "sdk", ...experimentVariantBlockMeta });
6119
6238
  }
6120
6239
  function sectionsToBlocks(sections) {
6121
6240
  return sections.map((section, i) => {
@@ -6168,10 +6287,10 @@ function StorefrontConfigHost({
6168
6287
  buyer,
6169
6288
  children
6170
6289
  }) {
6171
- const [policy, setPolicy] = React36__default.useState(null);
6172
- const [shipping, setShipping] = React36__default.useState(null);
6173
- const [delivery, setDelivery] = React36__default.useState(null);
6174
- React36__default.useEffect(() => {
6290
+ const [policy, setPolicy] = React37__default.useState(null);
6291
+ const [shipping, setShipping] = React37__default.useState(null);
6292
+ const [delivery, setDelivery] = React37__default.useState(null);
6293
+ React37__default.useEffect(() => {
6175
6294
  let cancelled = false;
6176
6295
  let provider;
6177
6296
  try {
@@ -6208,7 +6327,7 @@ function StorefrontConfigHost({
6208
6327
  cancelled = true;
6209
6328
  };
6210
6329
  }, [config]);
6211
- const resolved = React36__default.useMemo(
6330
+ const resolved = React37__default.useMemo(
6212
6331
  () => applyBuyer(applyDeliveryPolicy(applyShippingSettings(applyStoreSettings(config, policy), shipping), delivery), buyer),
6213
6332
  [config, policy, shipping, delivery, buyer?.language, buyer?.country]
6214
6333
  );
@@ -6220,7 +6339,7 @@ function MarketScope({ children }) {
6220
6339
  const markets = useMarketStore((s2) => s2.markets);
6221
6340
  const market = markets.length ? marketForCountry(markets, country) : null;
6222
6341
  const prices = useMarketStore((s2) => market ? s2.prices[market.code] : void 0);
6223
- React36__default.useEffect(() => {
6342
+ React37__default.useEffect(() => {
6224
6343
  useMarketStore.getState().setActive(market);
6225
6344
  if (!market || market.isDefault || prices) return;
6226
6345
  let provider;
@@ -6232,11 +6351,11 @@ function MarketScope({ children }) {
6232
6351
  void provider.getMarketPrices?.(market.code).then((list) => useMarketStore.getState().setPrices(market.code, list)).catch(() => {
6233
6352
  });
6234
6353
  }, [market?.code, prices]);
6235
- React36__default.useEffect(() => {
6354
+ React37__default.useEffect(() => {
6236
6355
  if (!market || !market.isDefault && !prices) return;
6237
6356
  useCartStore.getState().repriceForMarket();
6238
6357
  }, [market?.code, prices]);
6239
- const value = React36__default.useMemo(() => {
6358
+ const value = React37__default.useMemo(() => {
6240
6359
  if (!market) return base;
6241
6360
  return {
6242
6361
  ...base,
@@ -6366,7 +6485,7 @@ function StorefrontThemeStyle({
6366
6485
  document.getElementById(linkId)?.remove();
6367
6486
  };
6368
6487
  }, [fontsHref, linkId, selector]);
6369
- return React36__default.createElement(
6488
+ return React37__default.createElement(
6370
6489
  "style",
6371
6490
  { "data-sf-theme": theme.name },
6372
6491
  themeToCss(theme, { selector })
@@ -6465,7 +6584,7 @@ function SearchOverlay({ onClose }) {
6465
6584
  "\u201D."
6466
6585
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
6467
6586
  /* @__PURE__ */ jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-4", children: suggestions.map(
6468
- (product) => searchConfig.renderSuggestion ? /* @__PURE__ */ jsx(React36__default.Fragment, { children: searchConfig.renderSuggestion(product) }, product.id) : /* @__PURE__ */ jsx(SuggestionCard, { product, onNavigate: onClose }, product.id)
6587
+ (product) => searchConfig.renderSuggestion ? /* @__PURE__ */ jsx(React37__default.Fragment, { children: searchConfig.renderSuggestion(product) }, product.id) : /* @__PURE__ */ jsx(SuggestionCard, { product, onNavigate: onClose }, product.id)
6469
6588
  ) }),
6470
6589
  /* @__PURE__ */ jsx(
6471
6590
  "button",
@@ -6672,11 +6791,11 @@ function HeaderActions({ onMenuClick }) {
6672
6791
  const openDrawer = useCartStore((s2) => s2.openDrawer);
6673
6792
  const session = useSessionStore();
6674
6793
  const [accountOpen, setAccountOpen] = useState(false);
6675
- const accountRef = React36__default.useRef(null);
6794
+ const accountRef = React37__default.useRef(null);
6676
6795
  const pop = usePopOnChange(count);
6677
6796
  const firstName = session.name?.split(/\s+/)[0];
6678
6797
  const initial2 = (firstName ?? session.email ?? "C").slice(0, 1).toUpperCase();
6679
- React36__default.useEffect(() => {
6798
+ React37__default.useEffect(() => {
6680
6799
  if (!accountOpen) return;
6681
6800
  const onPointerDown = (event) => {
6682
6801
  if (!accountRef.current?.contains(event.target)) setAccountOpen(false);
@@ -6843,7 +6962,7 @@ function MobileMenuDrawer({ open, onClose }) {
6843
6962
  navigateTo(config.catalogPath);
6844
6963
  onClose();
6845
6964
  };
6846
- React36__default.useEffect(() => {
6965
+ React37__default.useEffect(() => {
6847
6966
  if (!open) return;
6848
6967
  const onKey = (e) => {
6849
6968
  if (e.key === "Escape") onClose();
@@ -7817,8 +7936,8 @@ function AddressForm({ country, language, value, onChange, onPostalCode, lookup,
7817
7936
  postalHint()
7818
7937
  ] }, "postalCode");
7819
7938
  }
7820
- if (row.length === 1) return /* @__PURE__ */ jsx(React36__default.Fragment, { children: input(specs.get(cells[0])) }, cells[0]);
7821
- return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: cells.map((key) => /* @__PURE__ */ jsx(React36__default.Fragment, { children: input(specs.get(key)) }, key)) }, cells.join("-"));
7939
+ if (row.length === 1) return /* @__PURE__ */ jsx(React37__default.Fragment, { children: input(specs.get(cells[0])) }, cells[0]);
7940
+ return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: cells.map((key) => /* @__PURE__ */ jsx(React37__default.Fragment, { children: input(specs.get(key)) }, key)) }, cells.join("-"));
7822
7941
  }) });
7823
7942
  }
7824
7943
  function flag(iso2) {
@@ -8174,13 +8293,13 @@ function CardBrick({ publicKey, amount, email, onSubmit, onError }) {
8174
8293
  var POLL_MS = 3e3;
8175
8294
  var RESUME_KEY = "fz.checkout.resume";
8176
8295
  function useExpiry(expiresAt) {
8177
- const target = React36__default.useMemo(() => {
8296
+ const target = React37__default.useMemo(() => {
8178
8297
  if (!expiresAt) return null;
8179
8298
  const t = new Date(expiresAt).getTime();
8180
8299
  return Number.isFinite(t) ? t : null;
8181
8300
  }, [expiresAt]);
8182
- const [now, setNow] = React36__default.useState(() => Date.now());
8183
- React36__default.useEffect(() => {
8301
+ const [now, setNow] = React37__default.useState(() => Date.now());
8302
+ React37__default.useEffect(() => {
8184
8303
  if (target === null) return;
8185
8304
  const id = setInterval(() => setNow(Date.now()), 1e3);
8186
8305
  return () => clearInterval(id);
@@ -8876,7 +8995,7 @@ function CheckoutPage() {
8876
8995
  district: "",
8877
8996
  state: ""
8878
8997
  });
8879
- React36__default.useEffect(() => {
8998
+ React37__default.useEffect(() => {
8880
8999
  if (!known.ready) return;
8881
9000
  setForm((current) => ({
8882
9001
  ...current,
@@ -8892,7 +9011,7 @@ function CheckoutPage() {
8892
9011
  }));
8893
9012
  }, [known.ready, known.phone, known.document, known.address]);
8894
9013
  const [step, setStep] = useState(resume ? 3 : 1);
8895
- const reportedStart = React36__default.useRef(false);
9014
+ const reportedStart = React37__default.useRef(false);
8896
9015
  useEffect(() => {
8897
9016
  if (reportedStart.current) return;
8898
9017
  reportedStart.current = true;
@@ -8905,7 +9024,7 @@ function CheckoutPage() {
8905
9024
  });
8906
9025
  }
8907
9026
  }, []);
8908
- const reportedStep = React36__default.useRef(null);
9027
+ const reportedStep = React37__default.useRef(null);
8909
9028
  useEffect(() => {
8910
9029
  if (reportedStep.current === step) return;
8911
9030
  reportedStep.current = step;
@@ -8914,7 +9033,7 @@ function CheckoutPage() {
8914
9033
  }, [step]);
8915
9034
  const [contactKnown, setContactKnown] = useState(false);
8916
9035
  const [editingContact, setEditingContact] = useState(false);
8917
- const skippedContact = React36__default.useRef(false);
9036
+ const skippedContact = React37__default.useRef(false);
8918
9037
  const fulfillmentType = useDeliveryStore((s2) => s2.fulfillmentType);
8919
9038
  const scheduledFor = useDeliveryStore((s2) => s2.scheduledFor);
8920
9039
  const deliveryReference = useDeliveryStore((s2) => {
@@ -8943,7 +9062,7 @@ function CheckoutPage() {
8943
9062
  const [applyingDiscount, setApplyingDiscount] = useState(false);
8944
9063
  const [showSignin, setShowSignin] = useState(false);
8945
9064
  const [placing, setPlacing] = useState(false);
8946
- const leaving = React36__default.useRef(false);
9065
+ const leaving = React37__default.useRef(false);
8947
9066
  const [zipLookup, setZipLookup] = useState("idle");
8948
9067
  const subtotal = selectSubtotal(cart);
8949
9068
  const discountTotal = selectDiscountTotal(cart);
@@ -8951,7 +9070,7 @@ function CheckoutPage() {
8951
9070
  const shipping = isPickup ? 0 : shippingRaw;
8952
9071
  const total = selectTotal(cart, config) - (isPickup ? shippingRaw : 0);
8953
9072
  const checkoutSlotContext = { subtotal, total };
8954
- const checkoutSessionInput = React36__default.useMemo(() => ({
9073
+ const checkoutSessionInput = React37__default.useMemo(() => ({
8955
9074
  items: cart.lines.map((line) => ({
8956
9075
  productId: line.productId,
8957
9076
  variantId: line.variantId ?? null,
@@ -9128,7 +9247,7 @@ function CheckoutPage() {
9128
9247
  cancelled = true;
9129
9248
  };
9130
9249
  }, [session.customerId]);
9131
- const shownCountry = React36__default.useRef(country);
9250
+ const shownCountry = React37__default.useRef(country);
9132
9251
  useEffect(() => {
9133
9252
  if (shownCountry.current === country) return;
9134
9253
  shownCountry.current = country;
@@ -9917,8 +10036,12 @@ function StoreCover({ onShowHours, onOpenAccount }) {
9917
10036
  const cover = config.delivery?.coverImage;
9918
10037
  const logo = config.delivery?.logoImage;
9919
10038
  const locality = config.delivery?.locality;
10039
+ const size = useExperimentValue(config.delivery?.coverSize) ?? "full";
10040
+ const compact = size === "compact";
9920
10041
  const modes = config.delivery?.fulfillmentModes ?? ["delivery"];
9921
10042
  const type = useDeliveryStore((s2) => s2.fulfillmentType);
10043
+ const etaInfo = type !== "pickup" && config.delivery?.etaMinutes ? etaParts(config.delivery.etaMinutes) : null;
10044
+ const etaText = etaInfo ? t(etaInfo.approx ? "delivery.eta" : "delivery.etaUpTo", { duration: etaInfo.text }) : "";
9922
10045
  const setFulfillmentType = useDeliveryStore((s2) => s2.setFulfillmentType);
9923
10046
  const refreshService = useServiceStore((s2) => s2.refresh);
9924
10047
  const service = useServiceStore();
@@ -9928,89 +10051,97 @@ function StoreCover({ onShowHours, onOpenAccount }) {
9928
10051
  setFulfillmentType(next);
9929
10052
  void refreshService(next);
9930
10053
  }
9931
- return /* @__PURE__ */ jsxs("header", { "data-testid": TID.storeCover, className: "relative isolate bg-neutral-900 text-white", children: [
9932
- cover && /* @__PURE__ */ jsx(
9933
- "img",
9934
- {
9935
- src: cover,
9936
- alt: "",
9937
- "aria-hidden": true,
9938
- className: "absolute inset-0 -z-10 h-full w-full object-cover"
9939
- }
9940
- ),
9941
- /* @__PURE__ */ jsx(
9942
- "div",
9943
- {
9944
- "aria-hidden": true,
9945
- className: "absolute inset-0 -z-10 bg-gradient-to-b from-black/30 via-black/45 to-black/75"
9946
- }
9947
- ),
9948
- /* @__PURE__ */ jsxs("div", { className: "relative mx-auto w-full max-w-3xl px-4 pb-4 pt-8", children: [
9949
- onOpenAccount && /* @__PURE__ */ jsx(
9950
- "button",
9951
- {
9952
- type: "button",
9953
- onClick: onOpenAccount,
9954
- "data-testid": "store-account",
9955
- "aria-label": sessionName ? "Sua conta" : "Entrar ou cadastrar",
9956
- className: "absolute right-4 top-3 grid h-10 w-10 place-items-center rounded-full bg-black/40 text-sm font-bold ring-1 ring-white/25 backdrop-blur",
9957
- children: sessionName ? sessionName.slice(0, 1).toUpperCase() : /* @__PURE__ */ jsx(UserRound, { className: "h-5 w-5" })
9958
- }
9959
- ),
9960
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 [text-shadow:0_1px_3px_rgb(0_0_0_/_0.7)]", children: [
9961
- /* @__PURE__ */ jsx("div", { className: "grid h-14 w-14 shrink-0 place-items-center overflow-hidden rounded-xl bg-white/10 ring-1 ring-white/20", children: logo ? /* @__PURE__ */ jsx("img", { src: logo, alt: "", "aria-hidden": true, className: "h-full w-full object-cover" }) : /* @__PURE__ */ jsx("span", { className: "text-xl font-bold", children: config.name.slice(0, 1) }) }),
9962
- /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
9963
- /* @__PURE__ */ jsx("h1", { className: "truncate text-xl font-bold leading-tight", children: config.name }),
9964
- locality && /* @__PURE__ */ jsx("p", { className: "truncate text-sm text-white/70", children: locality }),
9965
- config.delivery?.paused ? /* @__PURE__ */ jsxs("p", { "data-testid": "store-delivery-paused", className: "mt-0.5 inline-flex items-center gap-1.5 truncate text-sm font-semibold text-amber-300", children: [
9966
- /* @__PURE__ */ jsx("span", { className: "h-2 w-2 shrink-0 rounded-full bg-amber-400", "aria-hidden": true }),
9967
- t("delivery.paused")
9968
- ] }) : (() => {
9969
- const eta = type !== "pickup" && config.delivery?.etaMinutes ? etaParts(config.delivery.etaMinutes) : null;
9970
- return eta ? /* @__PURE__ */ jsx("p", { "data-testid": "store-eta", className: "truncate text-sm text-white/80", children: t(eta.approx ? "delivery.eta" : "delivery.etaUpTo", { duration: eta.text }) }) : null;
9971
- })(),
9972
- showsHours && service.service && // O estado é o botão que abre a placa da porta. Um selo que diz
9973
- // "Fechado" e não leva a lugar nenhum deixa a pessoa sem a única
9974
- // pergunta seguinte que ela tem: então quando abre?
9975
- /* @__PURE__ */ jsxs(
10054
+ return /* @__PURE__ */ jsxs(
10055
+ "header",
10056
+ {
10057
+ "data-testid": TID.storeCover,
10058
+ "data-cover-size": size,
10059
+ className: "relative isolate bg-neutral-900 text-white",
10060
+ children: [
10061
+ cover && /* @__PURE__ */ jsx(
10062
+ "img",
10063
+ {
10064
+ src: cover,
10065
+ alt: "",
10066
+ "aria-hidden": true,
10067
+ className: "absolute inset-0 -z-10 h-full w-full object-cover"
10068
+ }
10069
+ ),
10070
+ /* @__PURE__ */ jsx(
10071
+ "div",
10072
+ {
10073
+ "aria-hidden": true,
10074
+ className: "absolute inset-0 -z-10 bg-gradient-to-b from-black/30 via-black/45 to-black/75"
10075
+ }
10076
+ ),
10077
+ /* @__PURE__ */ jsxs("div", { className: `relative mx-auto w-full max-w-3xl px-4 ${compact ? "pb-3 pt-3" : "pb-4 pt-8"}`, children: [
10078
+ onOpenAccount && /* @__PURE__ */ jsx(
9976
10079
  "button",
9977
10080
  {
9978
10081
  type: "button",
9979
- "data-testid": TID.serviceStatus,
9980
- "data-open": open ? "true" : "false",
9981
- onClick: onShowHours,
9982
- className: "mt-0.5 flex items-center gap-1.5 text-sm font-semibold underline-offset-2 hover:underline",
9983
- children: [
9984
- /* @__PURE__ */ jsx(
9985
- "span",
9986
- {
9987
- "aria-hidden": true,
9988
- className: `h-2 w-2 rounded-full ${open ? "bg-emerald-400" : "bg-red-400"}`
9989
- }
9990
- ),
9991
- open ? /* @__PURE__ */ jsx(OpenUntil, {}) : /* @__PURE__ */ jsx(ClosedUntil, {})
9992
- ]
10082
+ onClick: onOpenAccount,
10083
+ "data-testid": "store-account",
10084
+ "aria-label": sessionName ? "Sua conta" : "Entrar ou cadastrar",
10085
+ className: "absolute right-4 top-3 grid h-10 w-10 place-items-center rounded-full bg-black/40 text-sm font-bold ring-1 ring-white/25 backdrop-blur",
10086
+ children: sessionName ? sessionName.slice(0, 1).toUpperCase() : /* @__PURE__ */ jsx(UserRound, { className: "h-5 w-5" })
9993
10087
  }
9994
- )
10088
+ ),
10089
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 [text-shadow:0_1px_3px_rgb(0_0_0_/_0.7)]", children: [
10090
+ /* @__PURE__ */ jsx("div", { className: `grid ${compact ? "h-11 w-11" : "h-14 w-14"} shrink-0 place-items-center overflow-hidden rounded-xl bg-white/10 ring-1 ring-white/20`, children: logo ? /* @__PURE__ */ jsx("img", { src: logo, alt: "", "aria-hidden": true, className: "h-full w-full object-cover" }) : /* @__PURE__ */ jsx("span", { className: "text-xl font-bold", children: config.name.slice(0, 1) }) }),
10091
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
10092
+ /* @__PURE__ */ jsx("h1", { className: `truncate ${compact ? "text-lg" : "text-xl"} font-bold leading-tight`, children: config.name }),
10093
+ compact && !config.delivery?.paused ? locality || etaText ? /* @__PURE__ */ jsx("p", { "data-testid": etaText ? "store-eta" : void 0, className: "truncate text-sm text-white/80", children: [locality, etaText].filter(Boolean).join(" \xB7 ") }) : null : locality ? /* @__PURE__ */ jsx("p", { className: "truncate text-sm text-white/70", children: locality }) : null,
10094
+ compact && !config.delivery?.paused ? null : config.delivery?.paused ? /* @__PURE__ */ jsxs("p", { "data-testid": "store-delivery-paused", className: "mt-0.5 inline-flex items-center gap-1.5 truncate text-sm font-semibold text-amber-300", children: [
10095
+ /* @__PURE__ */ jsx("span", { className: "h-2 w-2 shrink-0 rounded-full bg-amber-400", "aria-hidden": true }),
10096
+ t("delivery.paused")
10097
+ ] }) : (() => {
10098
+ const eta = type !== "pickup" && config.delivery?.etaMinutes ? etaParts(config.delivery.etaMinutes) : null;
10099
+ return eta ? /* @__PURE__ */ jsx("p", { "data-testid": "store-eta", className: "truncate text-sm text-white/80", children: t(eta.approx ? "delivery.eta" : "delivery.etaUpTo", { duration: eta.text }) }) : null;
10100
+ })(),
10101
+ showsHours && service.service && // O estado é o botão que abre a placa da porta. Um selo que diz
10102
+ // "Fechado" e não leva a lugar nenhum deixa a pessoa sem a única
10103
+ // pergunta seguinte que ela tem: então quando abre?
10104
+ /* @__PURE__ */ jsxs(
10105
+ "button",
10106
+ {
10107
+ type: "button",
10108
+ "data-testid": TID.serviceStatus,
10109
+ "data-open": open ? "true" : "false",
10110
+ onClick: onShowHours,
10111
+ className: "mt-0.5 flex items-center gap-1.5 text-sm font-semibold underline-offset-2 hover:underline",
10112
+ children: [
10113
+ /* @__PURE__ */ jsx(
10114
+ "span",
10115
+ {
10116
+ "aria-hidden": true,
10117
+ className: `h-2 w-2 rounded-full ${open ? "bg-emerald-400" : "bg-red-400"}`
10118
+ }
10119
+ ),
10120
+ open ? /* @__PURE__ */ jsx(OpenUntil, {}) : /* @__PURE__ */ jsx(ClosedUntil, {})
10121
+ ]
10122
+ }
10123
+ )
10124
+ ] })
10125
+ ] }),
10126
+ modes.length > 1 && /* @__PURE__ */ jsx("div", { className: "mt-4 flex gap-1", children: modes.map((mode) => {
10127
+ const active = type === mode;
10128
+ return /* @__PURE__ */ jsx(
10129
+ "button",
10130
+ {
10131
+ type: "button",
10132
+ "data-testid": TID.fulfillmentMode(mode),
10133
+ "aria-pressed": active,
10134
+ onClick: () => choose(mode),
10135
+ className: `rounded-full px-5 py-2 text-sm font-semibold transition ${active ? "bg-white text-neutral-900" : "text-white/80"}`,
10136
+ children: mode === "pickup" ? "Retirada" : "Entrega"
10137
+ },
10138
+ mode
10139
+ );
10140
+ }) })
9995
10141
  ] })
9996
- ] }),
9997
- modes.length > 1 && /* @__PURE__ */ jsx("div", { className: "mt-4 flex gap-1", children: modes.map((mode) => {
9998
- const active = type === mode;
9999
- return /* @__PURE__ */ jsx(
10000
- "button",
10001
- {
10002
- type: "button",
10003
- "data-testid": TID.fulfillmentMode(mode),
10004
- "aria-pressed": active,
10005
- onClick: () => choose(mode),
10006
- className: `rounded-full px-5 py-2 text-sm font-semibold transition ${active ? "bg-white text-neutral-900" : "text-white/80"}`,
10007
- children: mode === "pickup" ? "Retirada" : "Entrega"
10008
- },
10009
- mode
10010
- );
10011
- }) })
10012
- ] })
10013
- ] });
10142
+ ]
10143
+ }
10144
+ );
10014
10145
  }
10015
10146
  function OpenUntil() {
10016
10147
  const service = useServiceStore((s2) => s2.service);
@@ -10041,8 +10172,8 @@ function AddressStrip({
10041
10172
  const money = (v) => formatMoney(v, config.currency, config.locale);
10042
10173
  const subtotal = selectSubtotal(useCartStore());
10043
10174
  const resolve = useDeliveryStore((s2) => s2.resolve);
10044
- const quotedOnce = React36__default.useRef(false);
10045
- React36__default.useEffect(() => {
10175
+ const quotedOnce = React37__default.useRef(false);
10176
+ React37__default.useEffect(() => {
10046
10177
  if (quotedOnce.current || isPickup) return;
10047
10178
  if (delivery.status !== "idle" || delivery.options.length > 0 || !delivery.postalCode) return;
10048
10179
  quotedOnce.current = true;
@@ -10104,17 +10235,17 @@ function MenuToolbar({
10104
10235
  onQuery,
10105
10236
  autoFocusSearch
10106
10237
  }) {
10107
- const inputRef = React36__default.useRef(null);
10108
- const [active, setActive] = React36__default.useState(null);
10109
- React36__default.useEffect(() => {
10238
+ const inputRef = React37__default.useRef(null);
10239
+ const [active, setActive] = React37__default.useState(null);
10240
+ React37__default.useEffect(() => {
10110
10241
  setActive(
10111
10242
  (current) => current && sections.some((s2) => s2.slug === current) ? current : sections[0]?.slug ?? null
10112
10243
  );
10113
10244
  }, [sections]);
10114
- React36__default.useEffect(() => {
10245
+ React37__default.useEffect(() => {
10115
10246
  if (autoFocusSearch) inputRef.current?.focus();
10116
10247
  }, [autoFocusSearch]);
10117
- React36__default.useEffect(() => {
10248
+ React37__default.useEffect(() => {
10118
10249
  if (typeof IntersectionObserver === "undefined") return;
10119
10250
  const seen = /* @__PURE__ */ new Map();
10120
10251
  const observer = new IntersectionObserver(
@@ -10301,10 +10432,10 @@ function ItemSheet({
10301
10432
  }) {
10302
10433
  const config = useStorefrontConfig();
10303
10434
  const money = (v) => formatMoney(v, config.currency, config.locale);
10304
- const groups = React36__default.useMemo(() => getProductOptionGroups(product), [product]);
10305
- const [options, setOptions] = React36__default.useState({});
10306
- const [notes, setNotes] = React36__default.useState("");
10307
- const [quantity, setQuantity] = React36__default.useState(1);
10435
+ const groups = React37__default.useMemo(() => getProductOptionGroups(product), [product]);
10436
+ const [options, setOptions] = React37__default.useState({});
10437
+ const [notes, setNotes] = React37__default.useState("");
10438
+ const [quantity, setQuantity] = React37__default.useState(1);
10308
10439
  const image = product.images?.find((i) => i.isPrimary) ?? product.images?.[0];
10309
10440
  const stock = product.inventoryCount;
10310
10441
  const missing = groups.filter((g) => !options[g.label]);
@@ -10498,8 +10629,8 @@ function ScheduleSheet({ onClose }) {
10498
10629
  const scheduledFor = useDeliveryStore((s2) => s2.scheduledFor);
10499
10630
  const setScheduledFor = useDeliveryStore((s2) => s2.setScheduledFor);
10500
10631
  const timezone = useServiceStore((s2) => s2.service?.timezone) ?? "America/Sao_Paulo";
10501
- const [slots, setSlots] = React36__default.useState(null);
10502
- React36__default.useEffect(() => {
10632
+ const [slots, setSlots] = React37__default.useState(null);
10633
+ React37__default.useEffect(() => {
10503
10634
  let alive = true;
10504
10635
  void (async () => {
10505
10636
  const rows = await getShopProvider()?.listScheduleSlots?.(fulfillmentType) ?? [];
@@ -10509,7 +10640,7 @@ function ScheduleSheet({ onClose }) {
10509
10640
  alive = false;
10510
10641
  };
10511
10642
  }, [fulfillmentType]);
10512
- const days = React36__default.useMemo(() => {
10643
+ const days = React37__default.useMemo(() => {
10513
10644
  const fmtDay = new Intl.DateTimeFormat("pt-BR", {
10514
10645
  weekday: "long",
10515
10646
  day: "2-digit",
@@ -10595,8 +10726,8 @@ function hhmm(time) {
10595
10726
  }
10596
10727
  function ServiceHoursModal({ onClose }) {
10597
10728
  const fulfillmentType = useServiceStore((s2) => s2.fulfillmentType);
10598
- const [hours, setHours] = React36__default.useState(null);
10599
- React36__default.useEffect(() => {
10729
+ const [hours, setHours] = React37__default.useState(null);
10730
+ React37__default.useEffect(() => {
10600
10731
  let alive = true;
10601
10732
  void (async () => {
10602
10733
  const rows = await getShopProvider()?.listServiceHours?.(fulfillmentType) ?? [];
@@ -10606,7 +10737,7 @@ function ServiceHoursModal({ onClose }) {
10606
10737
  alive = false;
10607
10738
  };
10608
10739
  }, [fulfillmentType]);
10609
- const byDay = React36__default.useMemo(() => {
10740
+ const byDay = React37__default.useMemo(() => {
10610
10741
  const map = /* @__PURE__ */ new Map();
10611
10742
  for (const h of hours ?? []) {
10612
10743
  const list = map.get(h.weekday) ?? [];
@@ -10691,7 +10822,7 @@ function AddressSheet({ onClose, onSignIn }) {
10691
10822
  const unsavedCurrent = current && !saved.some((a) => a.id === selectedId) ? current : null;
10692
10823
  const fromAccount = accountBook.filter((a) => !saved.some((b) => normalizePostalCode(b.postalCode) === normalizePostalCode(a.postalCode) && b.number.trim().toLowerCase() === (a.number ?? "").trim().toLowerCase()));
10693
10824
  const nothingToList = saved.length === 0 && !unsavedCurrent && fromAccount.length === 0 && !customerId;
10694
- const [editing, setEditing] = React36__default.useState(
10825
+ const [editing, setEditing] = React37__default.useState(
10695
10826
  nothingToList && !onSignIn ? {} : null
10696
10827
  );
10697
10828
  function pickAccountAddress(a) {
@@ -10710,13 +10841,13 @@ function AddressSheet({ onClose, onSignIn }) {
10710
10841
  void selectAddress(id, subtotal);
10711
10842
  onClose();
10712
10843
  }
10713
- const closeRef = React36__default.useRef(() => {
10844
+ const closeRef = React37__default.useRef(() => {
10714
10845
  });
10715
10846
  closeRef.current = () => {
10716
10847
  if (editing && !nothingToList) setEditing(null);
10717
10848
  else onClose();
10718
10849
  };
10719
- React36__default.useEffect(() => {
10850
+ React37__default.useEffect(() => {
10720
10851
  const onKey = (e) => {
10721
10852
  if (e.key === "Escape") closeRef.current();
10722
10853
  };
@@ -10897,8 +11028,8 @@ function AddressLines({ address }) {
10897
11028
  ] });
10898
11029
  }
10899
11030
  function useAccountAddresses(customerId) {
10900
- const [rows, setRows] = React36__default.useState([]);
10901
- React36__default.useEffect(() => {
11031
+ const [rows, setRows] = React37__default.useState([]);
11032
+ React37__default.useEffect(() => {
10902
11033
  if (!customerId) {
10903
11034
  setRows([]);
10904
11035
  return;
@@ -10926,24 +11057,24 @@ function AddressForm2({ onDone, initial: initial2, replaces }) {
10926
11057
  const storeError = useDeliveryStore((s2) => s2.error);
10927
11058
  const refusedZone = useDeliveryStore((s2) => s2.refusedZone);
10928
11059
  const subtotal = selectSubtotal(useCartStore());
10929
- const [cep, setCep] = React36__default.useState(initial2?.postalCode ? formatPostalCode(initial2.postalCode) : "");
10930
- const [number, setNumber] = React36__default.useState(initial2?.number ?? "");
10931
- const [complement, setComplement] = React36__default.useState(initial2?.complement ?? "");
10932
- const [reference, setReference] = React36__default.useState(initial2?.reference ?? "");
10933
- const [label, setLabel] = React36__default.useState(initial2?.label ?? "");
10934
- const [touched, setTouched] = React36__default.useState(false);
10935
- const numberRef = React36__default.useRef(null);
11060
+ const [cep, setCep] = React37__default.useState(initial2?.postalCode ? formatPostalCode(initial2.postalCode) : "");
11061
+ const [number, setNumber] = React37__default.useState(initial2?.number ?? "");
11062
+ const [complement, setComplement] = React37__default.useState(initial2?.complement ?? "");
11063
+ const [reference, setReference] = React37__default.useState(initial2?.reference ?? "");
11064
+ const [label, setLabel] = React37__default.useState(initial2?.label ?? "");
11065
+ const [touched, setTouched] = React37__default.useState(false);
11066
+ const numberRef = React37__default.useRef(null);
10936
11067
  const digits = normalizePostalCode(cep);
10937
11068
  const found = Boolean(looked) && normalizePostalCode(looked.postalCode) === digits;
10938
- React36__default.useEffect(() => {
11069
+ React37__default.useEffect(() => {
10939
11070
  if (found) numberRef.current?.focus();
10940
11071
  }, [found]);
10941
11072
  async function lookUp() {
10942
11073
  if (digits.length !== 8) return;
10943
11074
  await resolve(digits, subtotal);
10944
11075
  }
10945
- const prefilled = React36__default.useRef(false);
10946
- React36__default.useEffect(() => {
11076
+ const prefilled = React37__default.useRef(false);
11077
+ React37__default.useEffect(() => {
10947
11078
  if (prefilled.current || !initial2?.postalCode) return;
10948
11079
  prefilled.current = true;
10949
11080
  if (!found) void lookUp();
@@ -11159,7 +11290,7 @@ function AccountDrawer({ onClose, onSignIn, onAddresses, onShowHours }) {
11159
11290
  const session = useSessionStore();
11160
11291
  const signedIn = Boolean(session.email);
11161
11292
  const name = session.name || session.email?.split("@")[0] || "";
11162
- React36__default.useEffect(() => {
11293
+ React37__default.useEffect(() => {
11163
11294
  const onKey = (event) => {
11164
11295
  if (event.key === "Escape") onClose();
11165
11296
  };
@@ -11243,8 +11374,8 @@ function AccountDrawer({ onClose, onSignIn, onAddresses, onShowHours }) {
11243
11374
  function MenuPage() {
11244
11375
  const config = useStorefrontConfig();
11245
11376
  const addItem = useCartStore((s2) => s2.addItem);
11246
- const [openProduct, setOpenProduct] = React36__default.useState(null);
11247
- React36__default.useEffect(() => {
11377
+ const [openProduct, setOpenProduct] = React37__default.useState(null);
11378
+ React37__default.useEffect(() => {
11248
11379
  if (!openProduct) return;
11249
11380
  trackStorefront("product_viewed", {
11250
11381
  product_id: openProduct.id,
@@ -11255,18 +11386,18 @@ function MenuPage() {
11255
11386
  surface: "menu_sheet"
11256
11387
  });
11257
11388
  }, [openProduct?.id]);
11258
- const [showHours, setShowHours] = React36__default.useState(false);
11259
- const [showClosed, setShowClosed] = React36__default.useState(false);
11260
- const [showAddress, setShowAddress] = React36__default.useState(false);
11261
- const [showAccount, setShowAccount] = React36__default.useState(false);
11262
- const [showSignIn, setShowSignIn] = React36__default.useState(false);
11263
- const [showSchedule, setShowSchedule] = React36__default.useState(false);
11264
- const [query, setQuery] = React36__default.useState("");
11389
+ const [showHours, setShowHours] = React37__default.useState(false);
11390
+ const [showClosed, setShowClosed] = React37__default.useState(false);
11391
+ const [showAddress, setShowAddress] = React37__default.useState(false);
11392
+ const [showAccount, setShowAccount] = React37__default.useState(false);
11393
+ const [showSignIn, setShowSignIn] = React37__default.useState(false);
11394
+ const [showSchedule, setShowSchedule] = React37__default.useState(false);
11395
+ const [query, setQuery] = React37__default.useState("");
11265
11396
  const serviceState = useServiceStore();
11266
11397
  const refreshService = useServiceStore((s2) => s2.refresh);
11267
11398
  const paused = Boolean(config.delivery?.paused);
11268
11399
  const isOpen = selectIsOpen(serviceState) && !paused;
11269
- React36__default.useEffect(() => {
11400
+ React37__default.useEffect(() => {
11270
11401
  void refreshService();
11271
11402
  }, [refreshService]);
11272
11403
  const cart = useCartStore();
@@ -11288,7 +11419,7 @@ function MenuPage() {
11288
11419
  const loading = products.status === "loading" || products.status === "idle";
11289
11420
  const items = products.data ?? [];
11290
11421
  const cats = categories.data ?? [];
11291
- const allSections = React36__default.useMemo(() => {
11422
+ const allSections = React37__default.useMemo(() => {
11292
11423
  const byCategory = /* @__PURE__ */ new Map();
11293
11424
  const loose = [];
11294
11425
  for (const p of items) {
@@ -11316,7 +11447,7 @@ function MenuPage() {
11316
11447
  }
11317
11448
  return ordered;
11318
11449
  }, [items, cats]);
11319
- const highlights = React36__default.useMemo(
11450
+ const highlights = React37__default.useMemo(
11320
11451
  () => pickHighlights(items, {
11321
11452
  listingFeaturedIds: featured.data?.listing,
11322
11453
  menuFeaturedIds: featured.data?.menu,
@@ -11325,7 +11456,7 @@ function MenuPage() {
11325
11456
  [items, featured.data, config.delivery?.highlightSlugs]
11326
11457
  );
11327
11458
  const normalized = query.trim().toLowerCase();
11328
- const sections = React36__default.useMemo(() => {
11459
+ const sections = React37__default.useMemo(() => {
11329
11460
  if (!normalized) return allSections;
11330
11461
  return allSections.map((section) => ({
11331
11462
  ...section,
@@ -11498,7 +11629,7 @@ function MenuPage() {
11498
11629
  );
11499
11630
  }
11500
11631
  function BottomBarSpace() {
11501
- React36__default.useEffect(() => {
11632
+ React37__default.useEffect(() => {
11502
11633
  const root = document.documentElement;
11503
11634
  root.style.setProperty("--fayz-bottom-bar", "4.5rem");
11504
11635
  return () => {
@@ -11789,7 +11920,7 @@ function OrderConfirmationPage({ orderId }) {
11789
11920
  const [loading, setLoading] = useState(true);
11790
11921
  const money = (v) => formatMoney(v, config.currency, config.locale);
11791
11922
  useStorefrontHead({ title: order ? `Pedido #${order.orderNumber} \u2014 ${config.name}` : config.name });
11792
- const reload = React36__default.useCallback(() => {
11923
+ const reload = React37__default.useCallback(() => {
11793
11924
  let cancelled = false;
11794
11925
  getShopProvider().getOrder(orderId).then((o) => {
11795
11926
  if (!cancelled) setOrder(o);
@@ -11818,7 +11949,7 @@ function OrderConfirmationPage({ orderId }) {
11818
11949
  ] }, column)) }),
11819
11950
  /* @__PURE__ */ jsxs("div", { className: "mt-6", children: [
11820
11951
  /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-32" }),
11821
- /* @__PURE__ */ jsx("div", { className: "mt-3 flex items-center gap-2", children: [0, 1, 2, 3].map((node) => /* @__PURE__ */ jsxs(React36__default.Fragment, { children: [
11952
+ /* @__PURE__ */ jsx("div", { className: "mt-3 flex items-center gap-2", children: [0, 1, 2, 3].map((node) => /* @__PURE__ */ jsxs(React37__default.Fragment, { children: [
11822
11953
  /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-7 shrink-0 rounded-full" }),
11823
11954
  node < 3 && /* @__PURE__ */ jsx(Skeleton, { className: "h-px flex-1" })
11824
11955
  ] }, node)) })
@@ -12105,7 +12236,7 @@ function OrdersPanel() {
12105
12236
  /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-24 rounded-full" })
12106
12237
  ] }),
12107
12238
  /* @__PURE__ */ jsx(Skeleton, { className: "mt-2 h-3 w-20" }),
12108
- /* @__PURE__ */ jsx("div", { className: "mt-4 flex items-center gap-2", children: [0, 1, 2, 3].map((node) => /* @__PURE__ */ jsxs(React36__default.Fragment, { children: [
12239
+ /* @__PURE__ */ jsx("div", { className: "mt-4 flex items-center gap-2", children: [0, 1, 2, 3].map((node) => /* @__PURE__ */ jsxs(React37__default.Fragment, { children: [
12109
12240
  /* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-6 shrink-0 rounded-full" }),
12110
12241
  node < 3 && /* @__PURE__ */ jsx(Skeleton, { className: "h-px flex-1" })
12111
12242
  ] }, node)) }),
@@ -12184,7 +12315,7 @@ function ProfilePanel() {
12184
12315
  const [saving, setSaving] = useState(false);
12185
12316
  const [saved, setSaved] = useState(false);
12186
12317
  const [error, setError] = useState(null);
12187
- React36__default.useEffect(() => {
12318
+ React37__default.useEffect(() => {
12188
12319
  if (!supported) return;
12189
12320
  let cancelled = false;
12190
12321
  provider.getMyProfile().then((p) => {
@@ -12477,7 +12608,7 @@ function PolicyPage({ kind }) {
12477
12608
  ] }) })
12478
12609
  ] });
12479
12610
  }
12480
- var StorefrontErrorBoundary = class extends React36__default.Component {
12611
+ var StorefrontErrorBoundary = class extends React37__default.Component {
12481
12612
  constructor() {
12482
12613
  super(...arguments);
12483
12614
  this.state = { error: null };
@@ -12766,6 +12897,6 @@ function createStorefront(options) {
12766
12897
  return createStorefrontApp(config);
12767
12898
  }
12768
12899
 
12769
- export { AddressForm, AddressSheet, AddressStrip, BEFORE_PLACE_ORDER_VALVE, BUYER_COUNTRY_COOKIE, BenefitsRow, CART_LINE_ANNOTATION_POINT, CHECKOUT_FIELD_POINT, CartDrawer, CatalogPage, CategoryShowcase, CheckoutPage, ClosedStoreDialog, CollectionCta, CollectionHero, ContentPage, CountdownBand, CountrySelect, DeliverToPicker, EmailConfirmationRequiredError, EntityListBlock, FaqSection, FiltersPanel, FormBlock, HeroSection, ImageTiles, ItemSheet, ManifestoBlock, MediaCarousel, MenuItemRow, MenuPage, MenuToolbar, MotifStrip, MyPurchasesPage, NewsletterBand, ORDER_METADATA_POINT, OrderConfirmationPage, OrderTrackingTimeline, PAGE_DATA_SCRIPT_ID, PLACEHOLDER_ASPECTS, PRODUCT_CARD_BADGE_POINT, PaymentTerms, Price, ProductCard, ProductDetailPage, ProductEnquiryForm, ProductGallery, ProductGrid, ProductOptionSelector, ProductRail, ProductReviews, ProductSlider, ProductSpecs, ProductSpotlight, PromoBanner, QuantityInput, Reveal, STOREFRONT_SLOTS, ScheduleSheet, SealsBand, SearchOverlay, ServiceHoursModal, Slot, SmoothImage, StepsSection, StoreCover, StorefrontAnalytics, StorefrontConfigHost, StorefrontFooter, StorefrontHeader, StorefrontPage, StorefrontShell, StorefrontThemeStyle, StoryQuote, THEME_SCALE_FIELDS, THEME_SCALE_VAR_PREFIX, TID, Testimonials, TierCards, applyDeliveryPolicy, applyStoreSettings, bannerPlaceholder, buildEnquiryFromForm, collectOrderMetadata, createStorefront, createStorefrontApp, entityListBlockMeta, establishCustomerSession, formatMoney, formatProductOptionSelection, getCartLineAnnotations, getCheckoutFieldContributions, getCustomerAuthAdapter, getProductCardBadges, getProductOptionGroups, hydratedEntriesFor, identifyStorefrontBuyer, initStorefrontRuntime, listSlots, marketForCountry, marketUnitPrice, matchesFacets, mergeCollectionFacet, nextMilestone, normalizeProductOptionSelection, onStorefrontEvent, orderGalleryImages, overrideComponent, overrideProps, pickProductCardImage, placeStorefrontOrder, prefersReducedMotion, productCardComponentContract, productOptionSelectionKey, productPlaceholder, readHydratedPageData, registerStorefrontBlocks, registerStorefrontEntities, registerStorefrontExtensionPoints, registerStorefrontLoaders, resetPageDiagnostics, resetProductOptionsDeprecationWarnings, resetStorefrontExtensionPoints, resolveAuthAdapter, resolveOverride, resolvePaymentTerms, resolveStorefrontProvider, resolveVariantForSelection, roundCents, runBeforePlaceOrderValve, sectionsToBlocks, selectCount, selectDiscountTotal, selectIsOpen, selectRequiresShipping, selectShipping, selectShowsHours, selectSubtotal, selectTotal, selectionPrice, serializePageData, signInByEmail, signOutCustomer, signUpCustomer, startStorefrontPostHog, storeBuyerId, storefrontComponentContracts, themeToCss, toFacetMap, trackStorefront, useBuyerCountry, useBuyerStore, useCartStore, useCatalogStore, useCategories, useDeliveryStore, useDiscountValidator, useEnquiry, useInView, useMarketProduct, useMarketStore, useMyOrders, usePopOnChange, useProduct, useProducts, useScrolled, useServiceStore, useSessionStore, useSlotContext, useStorefrontActions, useStorefrontHead, useStorefrontPage, useStorefrontPageOptional, useT, usedSlots, withFacet, withMarketPrice };
12770
- //# sourceMappingURL=chunk-CWHGBPRP.js.map
12771
- //# sourceMappingURL=chunk-CWHGBPRP.js.map
12900
+ export { AddressForm, AddressSheet, AddressStrip, BEFORE_PLACE_ORDER_VALVE, BUYER_COUNTRY_COOKIE, BenefitsRow, CART_LINE_ANNOTATION_POINT, CHECKOUT_FIELD_POINT, CartDrawer, CatalogPage, CategoryShowcase, CheckoutPage, ClosedStoreDialog, CollectionCta, CollectionHero, ContentPage, CountdownBand, CountrySelect, DeliverToPicker, EmailConfirmationRequiredError, EntityListBlock, ExperimentBlock, ExperimentProvider, ExperimentVariantBlock, FaqSection, FiltersPanel, FormBlock, HeroSection, ImageTiles, ItemSheet, ManifestoBlock, MediaCarousel, MenuItemRow, MenuPage, MenuToolbar, MotifStrip, MyPurchasesPage, NewsletterBand, ORDER_METADATA_POINT, OrderConfirmationPage, OrderTrackingTimeline, PAGE_DATA_SCRIPT_ID, PLACEHOLDER_ASPECTS, PRODUCT_CARD_BADGE_POINT, PaymentTerms, Price, ProductCard, ProductDetailPage, ProductEnquiryForm, ProductGallery, ProductGrid, ProductOptionSelector, ProductRail, ProductReviews, ProductSlider, ProductSpecs, ProductSpotlight, PromoBanner, QuantityInput, Reveal, STOREFRONT_SLOTS, ScheduleSheet, SealsBand, SearchOverlay, ServiceHoursModal, Slot, SmoothImage, StepsSection, StoreCover, StorefrontAnalytics, StorefrontConfigHost, StorefrontFooter, StorefrontHeader, StorefrontPage, StorefrontShell, StorefrontThemeStyle, StoryQuote, THEME_SCALE_FIELDS, THEME_SCALE_VAR_PREFIX, TID, Testimonials, TierCards, applyDeliveryPolicy, applyStoreSettings, bannerPlaceholder, buildEnquiryFromForm, collectOrderMetadata, createStorefront, createStorefrontApp, entityListBlockMeta, establishCustomerSession, formatMoney, formatProductOptionSelection, getCartLineAnnotations, getCheckoutFieldContributions, getCustomerAuthAdapter, getProductCardBadges, getProductOptionGroups, hydratedEntriesFor, identifyStorefrontBuyer, initStorefrontRuntime, isExperimentBinding, listSlots, marketForCountry, marketUnitPrice, matchesFacets, mergeCollectionFacet, nextMilestone, normalizeProductOptionSelection, onStorefrontEvent, orderGalleryImages, overrideComponent, overrideProps, pickProductCardImage, placeStorefrontOrder, prefersReducedMotion, productCardComponentContract, productOptionSelectionKey, productPlaceholder, readHydratedPageData, registerStorefrontBlocks, registerStorefrontEntities, registerStorefrontExtensionPoints, registerStorefrontLoaders, resetPageDiagnostics, resetProductOptionsDeprecationWarnings, resetStorefrontExtensionPoints, resolveAuthAdapter, resolveExperimental, resolveOverride, resolvePaymentTerms, resolveStorefrontProvider, resolveVariantForSelection, roundCents, runBeforePlaceOrderValve, sectionsToBlocks, selectCount, selectDiscountTotal, selectIsOpen, selectRequiresShipping, selectShipping, selectShowsHours, selectSubtotal, selectTotal, selectionPrice, serializePageData, signInByEmail, signOutCustomer, signUpCustomer, startStorefrontPostHog, storeBuyerId, storefrontComponentContracts, themeToCss, toFacetMap, trackStorefront, useBuyerCountry, useBuyerStore, useCartStore, useCatalogStore, useCategories, useDeliveryStore, useDiscountValidator, useEnquiry, useExperiment, useExperimentValue, useInView, useMarketProduct, useMarketStore, useMyOrders, usePopOnChange, useProduct, useProducts, useScrolled, useServiceStore, useSessionStore, useSlotContext, useStorefrontActions, useStorefrontHead, useStorefrontPage, useStorefrontPageOptional, useT, usedSlots, withFacet, withMarketPrice };
12901
+ //# sourceMappingURL=chunk-7GX7JLF7.js.map
12902
+ //# sourceMappingURL=chunk-7GX7JLF7.js.map