require("./chunk-9hOWP6kD.cjs");
const require_WidgetInteractionContext = require("./WidgetInteractionContext-DUJhDVnC.cjs");
const require_SearchSort = require("./SearchSort-BW1co5BK.cjs");
const require_registries = require("./registries-DgzzKX8_.cjs");
const require_preview_context = require("./preview-context-J_Viyhgm.cjs");
const require_src = require("./src-CMer7k-Y.cjs");
let react = require("react");
let _tanstack_react_query = require("@tanstack/react-query");
let react_jsx_runtime = require("react/jsx-runtime");
let lucide_react = require("lucide-react");
//#region ../../shop/ui/src/utils/media-helpers.ts
const VIDEO_EXTENSIONS = [
	".mp4",
	".webm",
	".mov",
	".avi",
	".m4v",
	".mkv",
	".ogv",
	".ogg",
	".wmv",
	".flv",
	".3gp"
];
function isVideoUrl(url) {
	if (!url) return false;
	const lowerUrl = url.toLowerCase();
	return VIDEO_EXTENSIONS.some((ext) => lowerUrl.includes(ext));
}
function getVideoThumbnailUrl(videoUrl) {
	if (videoUrl.includes("ik.imagekit.io")) return `${videoUrl}/ik-thumbnail.jpg`;
	return videoUrl;
}
//#endregion
//#region ../widgets/src/widgets/ShopWidget.tsx
const GRID_BY_COLUMNS = {
	2: "grid grid-cols-2 gap-3 @lg:gap-4",
	3: "grid grid-cols-2 gap-3 @sm:grid-cols-3 @lg:gap-4",
	4: "grid grid-cols-2 gap-3 @sm:grid-cols-3 @lg:grid-cols-4 @lg:gap-4",
	5: "grid grid-cols-2 gap-3 @sm:grid-cols-3 @md:grid-cols-4 @xl:grid-cols-5 @lg:gap-4",
	6: "grid grid-cols-2 gap-3 @sm:grid-cols-3 @md:grid-cols-4 @xl:grid-cols-5 @2xl:grid-cols-6 @lg:gap-4"
};
const SORT_OPTIONS = [
	{
		id: "title_asc",
		label: "Title (A–Z)"
	},
	{
		id: "title_desc",
		label: "Title (Z–A)"
	},
	{
		id: "price_asc",
		label: "Price (Low to High)"
	},
	{
		id: "price_desc",
		label: "Price (High to Low)"
	},
	{
		id: "created_at_desc",
		label: "Recently added"
	},
	{
		id: "created_at_asc",
		label: "Oldest"
	}
];
const PREVIEW_PRODUCTS = [
	{
		id: "preview-1",
		name: "Premium Wireless Headphones",
		price: "$249"
	},
	{
		id: "preview-2",
		name: "Smart Watch Series X",
		price: "$199"
	},
	{
		id: "preview-3",
		name: "Sunglasses",
		price: "$79"
	},
	{
		id: "preview-4",
		name: "Trail Running Shoes",
		price: "$129"
	},
	{
		id: "preview-5",
		name: "Daypack Backpack",
		price: "$89"
	},
	{
		id: "preview-6",
		name: "Stainless Bottle",
		price: "$32"
	},
	{
		id: "preview-7",
		name: "Linen Throw",
		price: "$59"
	},
	{
		id: "preview-8",
		name: "Ceramic Mug",
		price: "$24"
	},
	{
		id: "preview-9",
		name: "Wool Blanket",
		price: "$148"
	},
	{
		id: "preview-10",
		name: "Leather Wallet",
		price: "$45"
	},
	{
		id: "preview-11",
		name: "Pour-Over Kettle",
		price: "$78"
	},
	{
		id: "preview-12",
		name: "Linen Shirt",
		price: "$95"
	}
];
function clampColumns(value) {
	const n = Math.round(value ?? 4);
	if (n <= 2) return 2;
	if (n >= 6) return 6;
	return n;
}
const INFINITE_SCROLL_THRESHOLD = 10;
function clampPageSize(value) {
	const n = Math.round(value ?? 25);
	return Math.max(1, n);
}
function normalizeDataSourceProduct(input) {
	const r = input;
	const name = r.name ?? r.title ?? "";
	let images;
	if (Array.isArray(r.images) && r.images.length > 0) images = r.images.flatMap((img) => {
		const i = img;
		const url = i.url ?? i.image_url;
		if (!url) return [];
		return [{
			url,
			alt: i.alt ?? null
		}];
	});
	else {
		const url = r.image_url ?? r.imageUrl ?? r.thumbnail_url;
		images = url ? [{
			url,
			alt: null
		}] : [];
	}
	const cleaned = {};
	for (const [k, v] of Object.entries(r)) if (v !== void 0) cleaned[k] = v;
	return {
		...cleaned,
		name,
		images
	};
}
function getShopWidgetProductImage(product) {
	if (product.images && product.images.length > 0) return product.images[0]?.url ?? null;
	return null;
}
function getShopWidgetProductPrice(product) {
	if (product.is_bundle) return require_SearchSort.formatPortalPriceRange(product.price_range, product.currency) ?? require_SearchSort.formatPortalPrice(product.price, product.currency);
	return require_SearchSort.formatPortalPrice(product.wholesale_price ?? product.price, product.currency);
}
function getShopWidgetProductRetailPrice(product) {
	if (!product.wholesale_price || product.is_bundle) return null;
	const wholesalePrice = require_SearchSort.formatPortalPrice(product.wholesale_price, product.currency);
	const retailPrice = require_SearchSort.formatPortalPrice(product.price, product.currency);
	return retailPrice !== wholesalePrice ? retailPrice : null;
}
function cardScopedStyle(cardBackground, cardTextColor) {
	const style = {};
	if (cardBackground) style["--card"] = `var(--${cardBackground})`;
	if (cardTextColor) style["--foreground"] = `var(--${cardTextColor})`;
	return style;
}
function ShopWidget({ titleEnabled = true, title = "", titleColor = "foreground", showSearch = true, showSort = true, columns = 4, pageSize = 25, useDataSource = false, products, background = {
	type: "solid",
	color: "background"
}, padding = 6, borderRadius = "lg", cardBackground, cardTextColor, className, ...props }) {
	const { isPreview } = require_preview_context.useWidgetPreviewContext();
	const safeColumns = clampColumns(columns);
	const safePageSize = clampPageSize(pageSize);
	const backgroundColor = background.color ?? "background";
	const backgroundImage = background.type === "image" && (background.resource?.image_url || background.resource?.imageUrl) ? `url(${background.resource.image_url || background.resource.imageUrl})` : "none";
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: `bg-${backgroundColor} p-${padding} rounded-${borderRadius} @container ${className ?? ""}`,
		style: { backgroundImage },
		...props,
		children: isPreview ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PreviewBody, {
			columns: safeColumns,
			titleEnabled,
			title,
			titleColor,
			showSearch,
			showSort,
			cardBackground,
			cardTextColor
		}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveBody, {
			columns: safeColumns,
			pageSize: safePageSize,
			titleEnabled,
			title,
			titleColor,
			showSearch,
			showSort,
			useDataSource,
			products,
			cardBackground,
			cardTextColor
		})
	});
}
function PreviewBody({ columns, titleEnabled, title, titleColor, showSearch, showSort, cardBackground, cardTextColor }) {
	const hasTitle = titleEnabled && !!title;
	return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [(hasTitle || showSearch || showSort) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
		className: "mb-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-2",
		children: [hasTitle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
			className: `text-${titleColor} text-2xl font-semibold tracking-tight`,
			children: title
		}), (showSearch || showSort) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "flex items-center gap-2 sm:ml-auto",
			children: [showSearch && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
				"aria-hidden": true,
				className: "bg-muted h-9 w-full max-w-sm rounded-md sm:w-64"
			}), showSort && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
				"aria-hidden": true,
				className: "bg-muted size-9 rounded-md"
			})]
		})]
	}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: GRID_BY_COLUMNS[columns],
		style: cardScopedStyle(cardBackground, cardTextColor),
		children: PREVIEW_PRODUCTS.slice(0, columns * 2).map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductCardCompact, {
			name: p.name,
			imageUrl: null,
			price: p.price,
			retailPrice: null,
			cv: null,
			qv: null,
			isBundle: false
		}, p.id))
	})] });
}
function LiveBody({ useDataSource, products, ...rest }) {
	if (useDataSource) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataSourceBody, {
		columns: rest.columns,
		titleEnabled: rest.titleEnabled,
		title: rest.title,
		titleColor: rest.titleColor,
		products: products ?? [],
		cardBackground: rest.cardBackground,
		cardTextColor: rest.cardTextColor
	});
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CatalogBody, { ...rest });
}
function DataSourceBody({ columns, titleEnabled, title, titleColor, products, cardBackground, cardTextColor }) {
	const { onNavigate } = require_WidgetInteractionContext.useWidgetInteraction();
	const handleSelect = (0, react.useCallback)((id) => {
		onNavigate?.(`shop/${id}`);
	}, [onNavigate]);
	return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [titleEnabled && !!title && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
		className: `text-${titleColor} mb-6 text-2xl font-semibold tracking-tight`,
		children: title
	}), products.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "flex flex-col items-center justify-center py-12 text-center",
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
			className: "text-muted-foreground text-sm",
			children: "No products yet."
		})
	}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: GRID_BY_COLUMNS[columns],
		style: cardScopedStyle(cardBackground, cardTextColor),
		children: products.map((product) => {
			if (product.id == null) return null;
			const shareableType = product.shareable_type;
			if (shareableType != null && shareableType !== "Product") return null;
			const productId = product.id;
			const normalizedProduct = normalizeDataSourceProduct(product);
			return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductCardCompact, {
				name: normalizedProduct.name ?? "Product",
				imageUrl: getShopWidgetProductImage(normalizedProduct),
				price: getShopWidgetProductPrice(normalizedProduct),
				retailPrice: getShopWidgetProductRetailPrice(normalizedProduct),
				cv: normalizedProduct.cv ?? null,
				qv: normalizedProduct.qv ?? null,
				isBundle: normalizedProduct.is_bundle === true,
				onClick: () => handleSelect(productId)
			}, productId);
		})
	})] });
}
function CatalogBody({ columns, pageSize, titleEnabled, title, titleColor, showSearch, showSort, cardBackground, cardTextColor }) {
	const observerTarget = (0, react.useRef)(null);
	const { onNavigate } = require_WidgetInteractionContext.useWidgetInteraction();
	const isInfinite = pageSize > INFINITE_SCROLL_THRESHOLD;
	const catalog = require_SearchSort.usePortalProductCatalog({ perPage: isInfinite ? INFINITE_SCROLL_THRESHOLD : pageSize });
	const { data, isLoading, isFetchingNextPage, hasNextPage, fetchNextPage, error, isFetched } = (0, _tanstack_react_query.useInfiniteQuery)({
		queryKey: catalog.queryKey,
		queryFn: ({ pageParam, signal }) => catalog.fetchProducts(pageParam, signal),
		getNextPageParam: catalog.getNextPageParam,
		initialPageParam: void 0
	});
	const allProducts = (0, react.useMemo)(() => data?.pages.flatMap((page) => page.products) ?? [], [data?.pages]);
	const visibleProducts = (0, react.useMemo)(() => isInfinite ? allProducts : allProducts.slice(0, pageSize), [
		allProducts,
		pageSize,
		isInfinite
	]);
	const reachedLimit = !isInfinite && visibleProducts.length >= pageSize;
	const handleIntersect = (0, react.useCallback)((entries) => {
		if (entries[0]?.isIntersecting && hasNextPage && !isFetchingNextPage && !reachedLimit) fetchNextPage();
	}, [
		hasNextPage,
		isFetchingNextPage,
		fetchNextPage,
		reachedLimit
	]);
	(0, react.useEffect)(() => {
		const target = observerTarget.current;
		if (!target) return;
		const observer = new IntersectionObserver(handleIntersect, {
			threshold: .1,
			rootMargin: "200px"
		});
		observer.observe(target);
		return () => observer.disconnect();
	}, [handleIntersect]);
	const handleSelect = (0, react.useCallback)((id) => {
		onNavigate?.(`shop/${id}`);
	}, [onNavigate]);
	const hasTitle = titleEnabled && !!title;
	return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [(hasTitle || showSearch || showSort) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
		className: "mb-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-2",
		children: [hasTitle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
			className: `text-${titleColor} text-2xl font-semibold tracking-tight`,
			children: title
		}), (showSearch || showSort) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "flex items-center gap-2 sm:ml-auto",
			children: [showSearch && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
				className: "w-full max-w-sm sm:w-64",
				children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_SearchSort.SearchSort, {
					searchValue: catalog.searchTerm,
					onSearchChange: catalog.setSearchTerm,
					placeholder: "Search products"
				})
			}), showSort && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuTrigger, {
				asChild: true,
				children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
					variant: "outline",
					size: "icon",
					className: "border-foreground/10 size-9 shrink-0",
					children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ArrowUpDown, { className: "size-3" })
				})
			}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuContent, {
				align: "end",
				className: "w-60",
				children: [
					/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuLabel, { children: "Sort by" }),
					/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuSeparator, {}),
					/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuRadioGroup, {
						value: catalog.currentSort,
						onValueChange: catalog.setCurrentSort,
						children: SORT_OPTIONS.map((opt) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuRadioItem, {
							value: opt.id,
							children: opt.label
						}, opt.id))
					})
				]
			})] })]
		})]
	}), isLoading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkeletonGrid, {
		columns,
		count: Math.max(columns * 2, 8)
	}) : error && visibleProducts.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "bg-destructive/10 text-destructive my-6 rounded-lg px-4 py-3 text-sm",
		children: "Couldn’t load products. Try again later."
	}) : isFetched && visibleProducts.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "flex flex-col items-center justify-center py-12 text-center",
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
			className: "text-muted-foreground text-sm",
			children: catalog.searchTerm ? `No products match “${catalog.searchTerm}”.` : "No products yet."
		})
	}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
		/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
			className: GRID_BY_COLUMNS[columns],
			style: cardScopedStyle(cardBackground, cardTextColor),
			children: visibleProducts.map((product) => {
				if (product.id == null) return null;
				const productId = product.id;
				return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductCardCompact, {
					name: product.name ?? "Product",
					imageUrl: getShopWidgetProductImage(product),
					price: getShopWidgetProductPrice(product),
					retailPrice: getShopWidgetProductRetailPrice(product),
					cv: product.cv ?? null,
					qv: product.qv ?? null,
					isBundle: product.is_bundle === true,
					onClick: () => handleSelect(productId)
				}, productId);
			})
		}),
		!reachedLimit && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ref: observerTarget }),
		isFetchingNextPage && !reachedLimit && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
			className: "mt-6",
			children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkeletonGrid, {
				columns,
				count: columns
			})
		}),
		error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
			className: "bg-destructive/10 text-destructive mt-6 rounded-lg px-4 py-3 text-sm",
			children: "Couldn’t load more products. Try again later."
		})
	] })] });
}
function ProductCardCompact({ name, imageUrl, price, retailPrice, cv, qv, isBundle, onClick }) {
	const [imageFailed, setImageFailed] = (0, react.useState)(false);
	const [isHovered, setIsHovered] = (0, react.useState)(false);
	const interactive = !!onClick;
	const isVideo = isVideoUrl(imageUrl);
	const coverImageUrl = imageUrl && !imageFailed ? isVideo ? getVideoThumbnailUrl(imageUrl) : imageUrl : null;
	return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
		type: "button",
		onClick,
		disabled: !interactive,
		className: `bg-card text-card-foreground group flex min-w-0 flex-col overflow-hidden rounded-lg text-left ${interactive ? "cursor-pointer" : "cursor-default"} focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none`,
		children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "bg-muted/40 relative aspect-square w-full overflow-hidden rounded-md @md:rounded-lg",
			children: [
				isVideo && imageUrl && isHovered ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("video", {
					src: imageUrl,
					className: "absolute inset-0 h-full w-full object-cover",
					autoPlay: true,
					muted: true,
					loop: true,
					playsInline: true,
					onMouseLeave: () => setIsHovered(false)
				}) : coverImageUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
					src: coverImageUrl,
					alt: name,
					className: "h-full w-full object-cover transition-transform duration-300 group-hover:scale-[1.02]",
					loading: "lazy",
					decoding: "async",
					onError: () => setImageFailed(true),
					onMouseEnter: () => isVideo && setIsHovered(true)
				}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
					className: "flex h-full w-full items-center justify-center",
					children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "text-muted-foreground/40 size-10" })
				}),
				isVideo && !isHovered && coverImageUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
					className: "absolute inset-0 flex items-center justify-center",
					children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
						className: "flex size-12 items-center justify-center rounded-full bg-black/50 backdrop-blur-sm",
						children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CirclePlay, { className: "size-8 text-white" })
					})
				}),
				isBundle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Badge, {
					variant: "secondary",
					className: "absolute top-2 left-2",
					children: "Bundle"
				})
			]
		}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "min-w-0 px-0.5 pt-2 pb-0.5 @md:px-1 @md:pt-2.5",
			children: [
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
					className: "text-foreground line-clamp-1 text-xs leading-snug font-semibold @md:text-sm",
					children: name
				}),
				/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
					className: "mt-1 flex min-w-0 items-center gap-1.5",
					children: [price && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
						className: "text-foreground text-sm leading-none font-semibold @md:text-base",
						children: price
					}), retailPrice && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
						className: "text-muted-foreground text-xs leading-none line-through @md:text-sm",
						children: retailPrice
					})]
				}),
				(cv != null || qv != null) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
					className: "text-muted-foreground mt-1 truncate text-xs leading-tight",
					children: [
						"CV ",
						cv ?? "-",
						" | QV ",
						qv ?? "-"
					]
				})
			]
		})]
	});
}
function SkeletonGrid({ columns, count }) {
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: GRID_BY_COLUMNS[columns],
		children: Array.from({ length: count }, (_, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "space-y-3",
			children: [
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "aspect-square w-full rounded-lg" }),
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "h-4 w-3/4" }),
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "h-4 w-1/3" })
			]
		}, i))
	});
}
const shopWidgetPropertySchema = {
	widgetType: "ShopWidget",
	displayName: "Shop",
	tabsConfig: [{
		id: "styling",
		label: "Styling"
	}, {
		id: "data",
		label: "Data"
	}],
	dataSourceTargetProps: ["products"],
	fields: [
		{
			key: "titleEnabled",
			label: "Widget Title",
			type: "boolean",
			description: "Enable the heading shown above the grid",
			defaultValue: true,
			tab: "styling",
			group: "Title"
		},
		{
			key: "title",
			label: "Title",
			type: "text",
			description: "Heading text shown above the grid",
			defaultValue: "",
			tab: "styling",
			group: "Title",
			requiresKeyToBeTrue: "titleEnabled"
		},
		require_registries.getColorField({
			key: "titleColor",
			label: "Title Color",
			description: "Color of the heading text",
			defaultValue: "foreground",
			tab: "styling",
			group: "Title",
			requiresKeyToBeTrue: "titleEnabled"
		}),
		{
			key: "showSearch",
			label: "Show Search",
			type: "boolean",
			description: "Display the search input above the grid",
			defaultValue: true,
			tab: "styling",
			group: "Display",
			requiresKeyValue: {
				key: "useDataSource",
				value: false
			}
		},
		{
			key: "showSort",
			label: "Show Sort",
			type: "boolean",
			description: "Display the sort menu above the grid",
			defaultValue: true,
			tab: "styling",
			group: "Display",
			requiresKeyValue: {
				key: "useDataSource",
				value: false
			}
		},
		{
			key: "columns",
			label: "Columns (desktop)",
			type: "select",
			description: "Max columns at the largest breakpoint. Narrow widgets show 2 columns; wider containers scale up smoothly to the chosen maximum.",
			options: [
				{
					label: "2",
					value: 2
				},
				{
					label: "3",
					value: 3
				},
				{
					label: "4",
					value: 4
				},
				{
					label: "5",
					value: 5
				},
				{
					label: "6",
					value: 6
				}
			],
			defaultValue: 4,
			tab: "styling",
			group: "Display"
		},
		{
			type: "background",
			key: "background",
			label: "Background",
			description: "Container background",
			defaultValue: "background",
			tab: "styling",
			group: "Design"
		},
		require_registries.getPaddingField({
			key: "padding",
			label: "Padding",
			description: "Inner spacing around the grid",
			defaultValue: 6,
			tab: "styling",
			group: "Design"
		}),
		require_registries.getBorderRadiusField({
			key: "borderRadius",
			label: "Border Radius",
			description: "Container corner radius",
			defaultValue: "lg",
			tab: "styling",
			group: "Design"
		}),
		require_registries.getColorField({
			key: "cardBackground",
			label: "Card Background",
			description: "Override the card background color. Leave unset to use the theme's card color.",
			tab: "styling",
			group: "Card"
		}),
		require_registries.getColorField({
			key: "cardTextColor",
			label: "Card Text",
			description: "Override title + price color inside each card. Leave unset to use the theme's foreground color.",
			tab: "styling",
			group: "Card"
		}),
		{
			key: "useDataSource",
			label: "Use Data Source",
			type: "boolean",
			description: "Off shows all products from the catalog. On replaces the catalog with a data source — disables search and sort.",
			defaultValue: false,
			tab: "data",
			group: "Data Configuration"
		},
		{
			key: "pageSize",
			label: "Products to show",
			type: "number",
			description: "Up to 10 acts as a hard cap. Above 10 the grid switches to infinite scroll (products load in batches of 10 as you scroll).",
			defaultValue: 25,
			tab: "data",
			group: "Data Configuration",
			requiresKeyValue: {
				key: "useDataSource",
				value: false
			}
		},
		{
			key: "dataSource",
			label: "Data Source",
			type: "dataSource",
			description: "",
			tab: "data",
			group: "Data Configuration",
			requiresKeyToBeTrue: "useDataSource"
		}
	]
};
//#endregion
Object.defineProperty(exports, "ShopWidget", {
	enumerable: true,
	get: function() {
		return ShopWidget;
	}
});
Object.defineProperty(exports, "getVideoThumbnailUrl", {
	enumerable: true,
	get: function() {
		return getVideoThumbnailUrl;
	}
});
Object.defineProperty(exports, "isVideoUrl", {
	enumerable: true,
	get: function() {
		return isVideoUrl;
	}
});
Object.defineProperty(exports, "shopWidgetPropertySchema", {
	enumerable: true,
	get: function() {
		return shopWidgetPropertySchema;
	}
});

//# sourceMappingURL=ShopWidget-Cy3Ix3Dx.cjs.map