@snowcone-app/ui 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4554,6 +4554,7 @@ function AddToCart({
4554
4554
  text = "Add to Bag",
4555
4555
  loadingText = "Adding...",
4556
4556
  successText = "Added!",
4557
+ errorText = "Couldn't add \u2014 try again",
4557
4558
  disabled = false,
4558
4559
  className = "",
4559
4560
  quantity = 1,
@@ -4563,8 +4564,10 @@ function AddToCart({
4563
4564
  }) {
4564
4565
  const context = useProduct();
4565
4566
  const shopContext = useShopOptional();
4566
- const [loading, setLoading] = useState12(false);
4567
- const [success, setSuccess] = useState12(false);
4567
+ const [status, setStatus] = useState12("idle");
4568
+ const [errorMessage, setErrorMessage] = useState12(null);
4569
+ const loading = status === "adding";
4570
+ const success = status === "added";
4568
4571
  useEffect12(() => {
4569
4572
  checkProviders(
4570
4573
  "AddToCart",
@@ -4587,7 +4590,8 @@ function AddToCart({
4587
4590
  const handleClick = async () => {
4588
4591
  if (isDisabled || !product) return;
4589
4592
  try {
4590
- setLoading(true);
4593
+ setStatus("adding");
4594
+ setErrorMessage(null);
4591
4595
  const cartDetail = createCartDetail({
4592
4596
  productId: product.id,
4593
4597
  quantity,
@@ -4598,20 +4602,23 @@ function AddToCart({
4598
4602
  if (!cartDetail) {
4599
4603
  throw new Error("Invalid selection - unable to create cart detail");
4600
4604
  }
4601
- await simulateCartOperation(simulateDelay);
4602
- onClick?.(cartDetail);
4603
- setSuccess(true);
4605
+ if (onClick) {
4606
+ await onClick(cartDetail);
4607
+ } else {
4608
+ await simulateCartOperation(simulateDelay);
4609
+ }
4610
+ setStatus("added");
4604
4611
  setTimeout(() => {
4605
- setSuccess(false);
4612
+ setStatus((s) => s === "added" ? "idle" : s);
4606
4613
  }, 2e3);
4607
4614
  } catch (error) {
4608
- onError?.(error);
4609
- console.error("Add to cart failed:", error);
4610
- } finally {
4611
- setLoading(false);
4615
+ const err = error instanceof Error ? error : new Error(String(error));
4616
+ setStatus("error");
4617
+ setErrorMessage(err.message);
4618
+ onError?.(err);
4612
4619
  }
4613
4620
  };
4614
- const buttonText = loading ? loadingText : success ? successText : text;
4621
+ const buttonText = loading ? loadingText : success ? successText : status === "error" ? errorText : text;
4615
4622
  const defaultStyles = "w-full bg-primary text-primary-foreground hover:bg-primary/90 px-6 py-3 rounded-button font-medium transition-colors";
4616
4623
  const buttonClasses = `
4617
4624
  ${defaultStyles}
@@ -4622,6 +4629,7 @@ function AddToCart({
4622
4629
  const getAriaLabel = () => {
4623
4630
  if (loading) return loadingText;
4624
4631
  if (success) return successText;
4632
+ if (status === "error") return `${errorText} - ${product?.name || "product"}`;
4625
4633
  if (!product) return text;
4626
4634
  return `${text} - ${product.name || "product"}`;
4627
4635
  };
@@ -4635,9 +4643,11 @@ function AddToCart({
4635
4643
  onClick: handleClick,
4636
4644
  "aria-label": getAriaLabel(),
4637
4645
  "aria-busy": loading,
4646
+ "data-add-to-cart": status,
4638
4647
  children: buttonText
4639
4648
  }
4640
- )
4649
+ ),
4650
+ status === "error" && errorMessage && /* @__PURE__ */ jsx42("p", { role: "alert", className: "mt-2 text-sm text-destructive", children: errorMessage })
4641
4651
  ] });
4642
4652
  }
4643
4653
 
@@ -5383,7 +5393,12 @@ function PlacementClipShapeSelector() {
5383
5393
 
5384
5394
  // src/composed/PlacementTabs.tsx
5385
5395
  import { useRef as useRef10, useState as useState16, useLayoutEffect as useLayoutEffect2 } from "react";
5386
- import { jsx as jsx50, jsxs as jsxs32 } from "react/jsx-runtime";
5396
+ import { Fragment as Fragment9, jsx as jsx50, jsxs as jsxs32 } from "react/jsx-runtime";
5397
+ function linkedPlacementsLabel(count) {
5398
+ return count === 2 ? "Both sides" : `All ${count} areas`;
5399
+ }
5400
+ var ACTION_CLASS = "transition-colors duration-200 cursor-pointer text-muted-foreground hover:text-foreground underline underline-offset-4 decoration-muted-foreground/40 hover:decoration-foreground";
5401
+ var PILL_CLASS = "inline-flex items-center rounded-full bg-foreground/[0.08] px-3 py-1 font-medium text-foreground";
5387
5402
  function PlacementTabs({
5388
5403
  placements,
5389
5404
  selectedPlacement,
@@ -5391,7 +5406,13 @@ function PlacementTabs({
5391
5406
  isDesktop = false,
5392
5407
  toolbarPlaceholderId = "toolbar-placeholder",
5393
5408
  toolbarSize = 120,
5394
- className = ""
5409
+ className = "",
5410
+ linked,
5411
+ onSplitAll,
5412
+ onLinkAll,
5413
+ linkedLabel,
5414
+ splitAllLabel = "Customize separately",
5415
+ linkAllLabel = "Use one design for all"
5395
5416
  }) {
5396
5417
  const containerRef = useRef10(null);
5397
5418
  const [lineHeight, setLineHeight] = useState16(24);
@@ -5408,7 +5429,7 @@ function PlacementTabs({
5408
5429
  if (isDesktop) {
5409
5430
  return null;
5410
5431
  }
5411
- return /* @__PURE__ */ jsx50("div", { className: `flex justify-end w-full ${className}`, children: /* @__PURE__ */ jsx50(
5432
+ return /* @__PURE__ */ jsx50("div", { className: `flex justify-end w-full ${className}`, "data-placement-tabs": true, children: /* @__PURE__ */ jsx50(
5412
5433
  "span",
5413
5434
  {
5414
5435
  id: toolbarPlaceholderId,
@@ -5417,16 +5438,68 @@ function PlacementTabs({
5417
5438
  }
5418
5439
  ) });
5419
5440
  }
5441
+ const dataLinked = linked === void 0 ? void 0 : linked ? "true" : "false";
5442
+ const labels = placements.map((p) => p.label);
5443
+ const renderItems = (tabClass) => {
5444
+ if (linked === true) {
5445
+ return /* @__PURE__ */ jsxs32(Fragment9, { children: [
5446
+ /* @__PURE__ */ jsx50(
5447
+ "span",
5448
+ {
5449
+ className: `${tabClass} ${PILL_CLASS}`,
5450
+ "data-placement-pill": true,
5451
+ title: labels.join(" \xB7 "),
5452
+ "aria-label": `One design on ${labels.join(", ")}`,
5453
+ children: linkedLabel ?? linkedPlacementsLabel(placements.length)
5454
+ }
5455
+ ),
5456
+ onSplitAll && /* @__PURE__ */ jsx50(
5457
+ "button",
5458
+ {
5459
+ type: "button",
5460
+ onClick: onSplitAll,
5461
+ className: `${tabClass} ${ACTION_CLASS}`,
5462
+ "data-action": "split-all",
5463
+ children: splitAllLabel
5464
+ }
5465
+ )
5466
+ ] });
5467
+ }
5468
+ return /* @__PURE__ */ jsxs32(Fragment9, { children: [
5469
+ placements.map((p) => /* @__PURE__ */ jsx50(
5470
+ "button",
5471
+ {
5472
+ type: "button",
5473
+ onClick: () => onPlacementChange(p.label),
5474
+ "data-placement-tab": p.label,
5475
+ "aria-pressed": selectedPlacement === p.label,
5476
+ className: `${tabClass} transition-all duration-200 cursor-pointer border-b-2 ${selectedPlacement === p.label ? "text-foreground border-primary" : "text-foreground/70 hover:text-foreground border-muted-foreground/20 hover:border-muted-foreground/40"}`,
5477
+ children: p.label
5478
+ },
5479
+ p.label
5480
+ )),
5481
+ linked === false && onLinkAll && /* @__PURE__ */ jsx50(
5482
+ "button",
5483
+ {
5484
+ type: "button",
5485
+ onClick: onLinkAll,
5486
+ className: `${tabClass} ${ACTION_CLASS}`,
5487
+ "data-action": "link-all",
5488
+ children: linkAllLabel
5489
+ }
5490
+ )
5491
+ ] });
5492
+ };
5420
5493
  if (isDesktop) {
5421
- return /* @__PURE__ */ jsx50("div", { className: `flex flex-wrap gap-x-3 text-sm leading-relaxed w-full ${className}`, children: placements.map((p) => /* @__PURE__ */ jsx50(
5422
- "button",
5494
+ return /* @__PURE__ */ jsx50(
5495
+ "div",
5423
5496
  {
5424
- onClick: () => onPlacementChange(p.label),
5425
- className: `transition-all duration-200 cursor-pointer border-b-2 ${selectedPlacement === p.label ? "text-foreground border-primary" : "text-foreground/70 hover:text-foreground border-muted-foreground/20 hover:border-muted-foreground/40"}`,
5426
- children: p.label
5427
- },
5428
- p.label
5429
- )) });
5497
+ className: `flex flex-wrap items-center gap-x-3 gap-y-1 text-sm leading-relaxed w-full ${className}`,
5498
+ "data-placement-tabs": true,
5499
+ "data-linked": dataLinked,
5500
+ children: renderItems("")
5501
+ }
5502
+ );
5430
5503
  }
5431
5504
  const linesForToolbar = Math.ceil(toolbarSize / lineHeight);
5432
5505
  const shapeInsetPx = linesForToolbar * lineHeight;
@@ -5435,6 +5508,8 @@ function PlacementTabs({
5435
5508
  {
5436
5509
  ref: containerRef,
5437
5510
  className: `flex overflow-hidden text-sm leading-relaxed w-full ${className}`,
5511
+ "data-placement-tabs": true,
5512
+ "data-linked": dataLinked,
5438
5513
  children: /* @__PURE__ */ jsxs32("p", { className: "m-0 w-full", children: [
5439
5514
  /* @__PURE__ */ jsx50(
5440
5515
  "span",
@@ -5453,15 +5528,7 @@ function PlacementTabs({
5453
5528
  )
5454
5529
  }
5455
5530
  ),
5456
- placements.map((p) => /* @__PURE__ */ jsx50(
5457
- "button",
5458
- {
5459
- onClick: () => onPlacementChange(p.label),
5460
- className: `inline transition-all duration-200 cursor-pointer mr-3 border-b-2 ${selectedPlacement === p.label ? "text-foreground border-primary" : "text-foreground/70 hover:text-foreground border-muted-foreground/20 hover:border-muted-foreground/40"}`,
5461
- children: p.label
5462
- },
5463
- p.label
5464
- ))
5531
+ renderItems("inline mr-3")
5465
5532
  ] })
5466
5533
  }
5467
5534
  );
@@ -8735,7 +8802,7 @@ var canvasExportService = new CanvasExportService();
8735
8802
 
8736
8803
  // src/components/CanvasIsolationBoundary.tsx
8737
8804
  import React41, { useEffect as useEffect26 } from "react";
8738
- import { Fragment as Fragment9, jsx as jsx54, jsxs as jsxs33 } from "react/jsx-runtime";
8805
+ import { Fragment as Fragment10, jsx as jsx54, jsxs as jsxs33 } from "react/jsx-runtime";
8739
8806
  function CanvasIsolationConfigurator({
8740
8807
  placementName: placementNameProp,
8741
8808
  onArtworkChange,
@@ -8788,7 +8855,7 @@ function CanvasIsolationConfigurator({
8788
8855
  }
8789
8856
  var IsolatedChildren = React41.memo(
8790
8857
  function IsolatedChildren2({ children }) {
8791
- return /* @__PURE__ */ jsx54(Fragment9, { children });
8858
+ return /* @__PURE__ */ jsx54(Fragment10, { children });
8792
8859
  },
8793
8860
  // Custom comparison: ALWAYS return true (never re-render due to parent changes)
8794
8861
  // This is intentional - children should use refs/services for updates that need to bypass this
@@ -8801,7 +8868,7 @@ function CanvasIsolationBoundary({
8801
8868
  clearImageBitmapCache,
8802
8869
  serializeStateForServer
8803
8870
  }) {
8804
- return /* @__PURE__ */ jsxs33(Fragment9, { children: [
8871
+ return /* @__PURE__ */ jsxs33(Fragment10, { children: [
8805
8872
  /* @__PURE__ */ jsx54(
8806
8873
  CanvasIsolationConfigurator,
8807
8874
  {
@@ -9049,7 +9116,7 @@ import {
9049
9116
  useCallback as useCallback17
9050
9117
  } from "react";
9051
9118
  import { createPortal as createPortal2 } from "react-dom";
9052
- import { Fragment as Fragment10, jsx as jsx56, jsxs as jsxs35 } from "react/jsx-runtime";
9119
+ import { Fragment as Fragment11, jsx as jsx56, jsxs as jsxs35 } from "react/jsx-runtime";
9053
9120
  var BANDS = [
9054
9121
  { rgb: "230, 45, 55", delay: "-0.0s" },
9055
9122
  // red
@@ -9296,7 +9363,7 @@ var LoadingOverlayPrismCandy = memo2(function LoadingOverlayPrismCandy2({
9296
9363
  let fadeClass = "";
9297
9364
  if (!visible) fadeClass = "candy-fade-out";
9298
9365
  else if (mounted) fadeClass = "candy-fade-in";
9299
- return /* @__PURE__ */ jsxs35(Fragment10, { children: [
9366
+ return /* @__PURE__ */ jsxs35(Fragment11, { children: [
9300
9367
  /* @__PURE__ */ jsx56(
9301
9368
  "div",
9302
9369
  {
@@ -9445,7 +9512,7 @@ import {
9445
9512
  describeProductArtAlignment,
9446
9513
  getSnapPoints
9447
9514
  } from "@snowcone-app/sdk";
9448
- import { Fragment as Fragment11, jsx as jsx58, jsxs as jsxs36 } from "react/jsx-runtime";
9515
+ import { Fragment as Fragment12, jsx as jsx58, jsxs as jsxs36 } from "react/jsx-runtime";
9449
9516
  function ArtAlignment({
9450
9517
  src: propSrc,
9451
9518
  artworkAspectRatio: propAspectRatio,
@@ -9818,7 +9885,7 @@ function ArtAlignment({
9818
9885
  loading: "eager"
9819
9886
  }
9820
9887
  ),
9821
- isReady && maskDimensions.width > 0 && /* @__PURE__ */ jsxs36(Fragment11, { children: [
9888
+ isReady && maskDimensions.width > 0 && /* @__PURE__ */ jsxs36(Fragment12, { children: [
9822
9889
  /* @__PURE__ */ jsx58("div", { style: overlayStyle }),
9823
9890
  /* @__PURE__ */ jsx58(
9824
9891
  "img",
@@ -10654,14 +10721,14 @@ var HeroProductImage = memo3(function HeroProductImage2({
10654
10721
 
10655
10722
  // src/composed/SafeImg.tsx
10656
10723
  import React45, { useEffect as useEffect33, useState as useState32 } from "react";
10657
- import { Fragment as Fragment12, jsx as jsx62 } from "react/jsx-runtime";
10724
+ import { Fragment as Fragment13, jsx as jsx62 } from "react/jsx-runtime";
10658
10725
  var SafeImg = React45.forwardRef(
10659
10726
  function SafeImg2({ fallback = null, onError, src, ...rest }, ref) {
10660
10727
  const [failed, setFailed] = useState32(false);
10661
10728
  useEffect33(() => {
10662
10729
  setFailed(false);
10663
10730
  }, [src]);
10664
- if (failed) return /* @__PURE__ */ jsx62(Fragment12, { children: fallback });
10731
+ if (failed) return /* @__PURE__ */ jsx62(Fragment13, { children: fallback });
10665
10732
  return /* @__PURE__ */ jsx62(
10666
10733
  "img",
10667
10734
  {
@@ -10990,7 +11057,7 @@ import { useRefinementList, useRange, useStats as useStats2 } from "react-instan
10990
11057
  import { X as LucideX2, SlidersHorizontal as LucideSlidersHorizontal2 } from "lucide-react";
10991
11058
  import { useState as useState35, useEffect as useEffect37 } from "react";
10992
11059
  import * as Slider2 from "@radix-ui/react-slider";
10993
- import { Fragment as Fragment13, jsx as jsx68, jsxs as jsxs44 } from "react/jsx-runtime";
11060
+ import { Fragment as Fragment14, jsx as jsx68, jsxs as jsxs44 } from "react/jsx-runtime";
10994
11061
  var XIcon2 = LucideX2;
10995
11062
  function FiltersDrawer({ isOpen, onClose }) {
10996
11063
  const [showCounts, setShowCounts] = useState35(false);
@@ -11015,7 +11082,7 @@ function FiltersDrawer({ isOpen, onClose }) {
11015
11082
  document.addEventListener("keydown", handleEscape);
11016
11083
  return () => document.removeEventListener("keydown", handleEscape);
11017
11084
  }, [isOpen, onClose]);
11018
- return /* @__PURE__ */ jsxs44(Fragment13, { children: [
11085
+ return /* @__PURE__ */ jsxs44(Fragment14, { children: [
11019
11086
  /* @__PURE__ */ jsx68(
11020
11087
  "div",
11021
11088
  {
@@ -11308,10 +11375,10 @@ function PriceSection() {
11308
11375
  }
11309
11376
 
11310
11377
  // src/composed/search/Filters.tsx
11311
- import { Fragment as Fragment14, jsx as jsx69, jsxs as jsxs45 } from "react/jsx-runtime";
11378
+ import { Fragment as Fragment15, jsx as jsx69, jsxs as jsxs45 } from "react/jsx-runtime";
11312
11379
  function Filters({ buttonClassName, buttonText }) {
11313
11380
  const [isOpen, setIsOpen] = useState36(false);
11314
- return /* @__PURE__ */ jsxs45(Fragment14, { children: [
11381
+ return /* @__PURE__ */ jsxs45(Fragment15, { children: [
11315
11382
  /* @__PURE__ */ jsx69(
11316
11383
  FiltersButton,
11317
11384
  {
@@ -11410,7 +11477,7 @@ import { useState as useState39, useEffect as useEffect39 } from "react";
11410
11477
  // src/composed/zoom/ZoomOverlay.tsx
11411
11478
  import { useState as useState37, useCallback as useCallback20 } from "react";
11412
11479
  import { Plus as LucidePlus2, Minus as LucideMinus2 } from "lucide-react";
11413
- import { Fragment as Fragment15, jsx as jsx71, jsxs as jsxs47 } from "react/jsx-runtime";
11480
+ import { Fragment as Fragment16, jsx as jsx71, jsxs as jsxs47 } from "react/jsx-runtime";
11414
11481
  var PlusIcon2 = LucidePlus2;
11415
11482
  var MinusIcon2 = LucideMinus2;
11416
11483
  function ZoomOverlay({
@@ -11469,7 +11536,7 @@ function ZoomOverlay({
11469
11536
  const isZoomed = zoomedImageIndex === imageIndex;
11470
11537
  const isHovered = hoveredImageIndex === imageIndex;
11471
11538
  const cursorStyle = isLargeTouchDevice ? "pointer" : isTouchDevice ? "default" : "none";
11472
- return /* @__PURE__ */ jsxs47(Fragment15, { children: [
11539
+ return /* @__PURE__ */ jsxs47(Fragment16, { children: [
11473
11540
  /* @__PURE__ */ jsx71("div", { className: "sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement }),
11474
11541
  /* @__PURE__ */ jsx71(
11475
11542
  "div",
@@ -11564,7 +11631,7 @@ import {
11564
11631
  TransformComponent as OriginalTransformComponent
11565
11632
  } from "react-zoom-pan-pinch";
11566
11633
  import { X as X2 } from "lucide-react";
11567
- import { Fragment as Fragment16, jsx as jsx72, jsxs as jsxs48 } from "react/jsx-runtime";
11634
+ import { Fragment as Fragment17, jsx as jsx72, jsxs as jsxs48 } from "react/jsx-runtime";
11568
11635
  var TransformWrapper = OriginalTransformWrapper;
11569
11636
  var TransformComponent = OriginalTransformComponent;
11570
11637
  var EnhancedImageViewer = ({
@@ -11883,7 +11950,7 @@ var EnhancedImageViewer = ({
11883
11950
  };
11884
11951
  const nextIndex = findNextAvailableIndex(currentIndex, 1);
11885
11952
  const prevIndex = findNextAvailableIndex(currentIndex, -1);
11886
- return /* @__PURE__ */ jsxs48(Fragment16, { children: [
11953
+ return /* @__PURE__ */ jsxs48(Fragment17, { children: [
11887
11954
  /* @__PURE__ */ jsx72(
11888
11955
  "button",
11889
11956
  {
@@ -11985,7 +12052,7 @@ var EnhancedImageViewer = ({
11985
12052
  };
11986
12053
 
11987
12054
  // src/composed/zoom/ResponsiveZoom.tsx
11988
- import { Fragment as Fragment17, jsx as jsx73, jsxs as jsxs49 } from "react/jsx-runtime";
12055
+ import { Fragment as Fragment18, jsx as jsx73, jsxs as jsxs49 } from "react/jsx-runtime";
11989
12056
  function ResponsiveZoom({
11990
12057
  imageIndex,
11991
12058
  children,
@@ -12026,7 +12093,7 @@ function ResponsiveZoom({
12026
12093
  }
12027
12094
  }
12028
12095
  };
12029
- return /* @__PURE__ */ jsxs49(Fragment17, { children: [
12096
+ return /* @__PURE__ */ jsxs49(Fragment18, { children: [
12030
12097
  isTouchDevice ? /* @__PURE__ */ jsx73(
12031
12098
  "div",
12032
12099
  {
@@ -12967,7 +13034,7 @@ function HeroCarousel({
12967
13034
 
12968
13035
  // src/composed/grids/MasonryGrid.tsx
12969
13036
  import { useState as useState42, useEffect as useEffect42, useMemo as useMemo16 } from "react";
12970
- import { Fragment as Fragment18, jsx as jsx76 } from "react/jsx-runtime";
13037
+ import { Fragment as Fragment19, jsx as jsx76 } from "react/jsx-runtime";
12971
13038
  var BREAKPOINTS = {
12972
13039
  sm: 640,
12973
13040
  md: 768,
@@ -13039,7 +13106,7 @@ function MasonryGrid({
13039
13106
  );
13040
13107
  if (items.length === 0) {
13041
13108
  if (emptyContent) {
13042
- return /* @__PURE__ */ jsx76(Fragment18, { children: emptyContent });
13109
+ return /* @__PURE__ */ jsx76(Fragment19, { children: emptyContent });
13043
13110
  }
13044
13111
  return null;
13045
13112
  }
@@ -14208,7 +14275,7 @@ function RadiusScale({ className = "" }) {
14208
14275
 
14209
14276
  // src/design-system/ThemeSwitcher.tsx
14210
14277
  import { useState as useState45, useEffect as useEffect46 } from "react";
14211
- import { Fragment as Fragment19, jsx as jsx87, jsxs as jsxs60 } from "react/jsx-runtime";
14278
+ import { Fragment as Fragment20, jsx as jsx87, jsxs as jsxs60 } from "react/jsx-runtime";
14212
14279
  function readThemeFromDOM() {
14213
14280
  if (typeof document === "undefined") {
14214
14281
  return { themeName: "Linear", isDark: false };
@@ -14282,7 +14349,7 @@ function ThemeSwitcher({ className = "", showBaseThemesOnly = true }) {
14282
14349
  ]
14283
14350
  }
14284
14351
  ),
14285
- isOpen && /* @__PURE__ */ jsxs60(Fragment19, { children: [
14352
+ isOpen && /* @__PURE__ */ jsxs60(Fragment20, { children: [
14286
14353
  /* @__PURE__ */ jsx87(
14287
14354
  "div",
14288
14355
  {
@@ -14406,7 +14473,7 @@ function usePersonalizationContext() {
14406
14473
  }
14407
14474
 
14408
14475
  // src/personalization/PersonalizationProvider.tsx
14409
- import { Fragment as Fragment20, jsx as jsx89, jsxs as jsxs62 } from "react/jsx-runtime";
14476
+ import { Fragment as Fragment21, jsx as jsx89, jsxs as jsxs62 } from "react/jsx-runtime";
14410
14477
  function createBridgeFromCanvas(canvasModule) {
14411
14478
  const { useEditor, useCommands, useImageBinding } = canvasModule;
14412
14479
  function TextBinder({ name, value }) {
@@ -14494,7 +14561,7 @@ function createBridgeFromCanvas(canvasModule) {
14494
14561
  return null;
14495
14562
  }
14496
14563
  return function PersonalizationBridge({ fields = [], values = {} } = {}) {
14497
- return /* @__PURE__ */ jsx89(Fragment20, { children: fields.map((field) => {
14564
+ return /* @__PURE__ */ jsx89(Fragment21, { children: fields.map((field) => {
14498
14565
  if (field.type === "text") {
14499
14566
  return /* @__PURE__ */ jsx89(TextBinder, { name: field.name, value: values[field.name] ?? "" }, `text-${field.name}`);
14500
14567
  }
@@ -15046,6 +15113,7 @@ export {
15046
15113
  isWideMonitor,
15047
15114
  kbdVariants,
15048
15115
  linkVariants,
15116
+ linkedPlacementsLabel,
15049
15117
  listProducts4 as listProducts,
15050
15118
  normalizeHex,
15051
15119
  observe,