@shopify/shop-minis-react
Version:
React component library for Shopify Shop Minis with Tailwind CSS v4 support (source-only, requires TypeScript)
317 lines (316 loc) • 7.65 kB
JavaScript
import { jsxs as p, jsx as r, Fragment as H } from "react/jsx-runtime";
import * as b from "react";
import { cva as M } from "../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
import { useShopNavigation as U } from "../../hooks/navigation/useShopNavigation.js";
import { useSavedProductsActions as E } from "../../hooks/user/useSavedProductsActions.js";
import { formatMoney as f } from "../../lib/formatMoney.js";
import { cn as a } from "../../lib/utils.js";
import { Badge as G } from "../atoms/badge.js";
import { Button as J } from "../atoms/button.js";
import { Touchable as K } from "../atoms/touchable.js";
import Q from "../../node_modules/.pnpm/lucide-react@0.513.0_react@19.1.0/node_modules/lucide-react/dist/esm/icons/heart.js";
import { Root as V } from "../../node_modules/.pnpm/@radix-ui_react-slot@1.2.3_@types_react@19.1.6_react@19.1.0/node_modules/@radix-ui/react-slot/dist/index.js";
const W = M(
"relative w-full overflow-hidden rounded-xl border border-gray-200",
{
variants: {
variant: {
default: "",
priceOverlay: "",
compact: ""
},
touchable: {
true: "cursor-pointer",
false: ""
}
},
defaultVariants: {
variant: "default",
touchable: !0
}
}
);
function X({
className: e,
variant: t,
touchable: o = !0,
asChild: c = !1,
onPress: i,
...h
}) {
const n = /* @__PURE__ */ r(
c ? V : "div",
{
className: a(
W({ variant: t, touchable: o }),
"border-0",
e
),
...h
}
);
return o && i ? /* @__PURE__ */ r(
K,
{
onClick: i,
whileTap: { opacity: 0.7 },
transition: {
opacity: { type: "tween", duration: 0.08, ease: "easeInOut" }
},
children: n
}
) : n;
}
function Y({
className: e,
variant: t = "default",
...o
}) {
return /* @__PURE__ */ r(
"div",
{
"data-slot": "product-card-image-container",
className: a(
// Ensure the product image is stretched to the full size of the container (can't use width/height: 100% because of flex)
"flex justify-stretch items-stretch",
"relative overflow-hidden rounded-xl border border-gray-200",
"w-full aspect-square",
t === "compact" ? "min-h-[104px]" : "min-h-[134px]",
e
),
...o
}
);
}
function Z({
className: e,
src: t,
alt: o,
...c
}) {
return /* @__PURE__ */ r("div", { className: "bg-gray-100 flex items-center justify-center", children: t ? /* @__PURE__ */ r(
"img",
{
"data-slot": "product-card-image",
src: t,
alt: o,
className: a("w-full h-full object-cover", e),
...c
}
) : /* @__PURE__ */ r("div", { className: "text-gray-400 text-sm", children: "No Image" }) });
}
function j({
className: e,
position: t = "bottom-left",
children: o,
...c
}) {
return /* @__PURE__ */ r(
"div",
{
className: a(
"absolute z-10",
t === "top-left" ? "top-3 left-3" : "bottom-2 left-2"
),
children: /* @__PURE__ */ r(
G,
{
className: a("bg-black/50 text-white rounded", e),
...c,
children: o
}
)
}
);
}
function _({
className: e,
onPress: t,
filled: o = !1,
...c
}) {
return /* @__PURE__ */ r("div", { className: a("absolute bottom-3 right-3 z-10", e), ...c, children: /* @__PURE__ */ r(
J,
{
onClick: t,
variant: "secondary",
size: "icon",
className: a(
"h-8 w-8 rounded-full border-0 shadow-sm",
o ? "bg-primary" : "bg-grayscale-l6/60 backdrop-blur-sm"
),
stopPropagation: !0,
children: /* @__PURE__ */ r(
Q,
{
fill: o ? "currentColor" : "none",
className: "h-4 w-4 text-white"
}
)
}
) });
}
function $({
className: e,
variant: t = "default",
...o
}) {
return t !== "default" ? null : /* @__PURE__ */ r(
"div",
{
"data-slot": "product-card-info",
className: a("px-1 pt-2 pb-0 space-y-1", e),
...o
}
);
}
function tt({
className: e,
children: t,
...o
}) {
return /* @__PURE__ */ r(
"h3",
{
"data-slot": "product-card-title",
className: a(
"text-sm font-medium leading-tight text-gray-900",
"truncate overflow-hidden whitespace-nowrap text-ellipsis",
e
),
...o,
children: t
}
);
}
function rt({ className: e, ...t }) {
return /* @__PURE__ */ r(
"div",
{
"data-slot": "product-card-price",
className: a("flex items-center gap-2", e),
...t
}
);
}
function S({
className: e,
...t
}) {
return /* @__PURE__ */ r(
"span",
{
"data-slot": "product-card-current-price",
className: a("text-sm font-semibold text-gray-900", e),
...t
}
);
}
function et({
className: e,
...t
}) {
return /* @__PURE__ */ r(
"span",
{
"data-slot": "product-card-original-price",
className: a("text-sm text-gray-500 line-through", e),
...t
}
);
}
function ht({
product: e,
selectedProductVariant: t,
variant: o = "default",
touchable: c = !0,
badgeText: i,
badgeVariant: h = "secondary",
onFavoriteToggled: m
}) {
const { navigateToProduct: n } = U(), { saveProduct: x, unsaveProduct: P } = E(), {
id: d,
title: w,
featuredImage: B,
price: F,
compareAtPrice: O,
isFavorited: z,
defaultVariantId: g,
shop: v
} = e, N = t?.image || B, I = t?.price || F, A = t?.compareAtPrice || O, [y, k] = b.useState(z), s = I?.currencyCode, l = I?.amount, R = N?.url, T = N?.altText || w, C = A?.amount, L = C && C !== l, q = b.useCallback(() => {
c && n({
productId: d
});
}, [n, d, c]), D = b.useCallback(async () => {
const u = y;
k(!u), m?.(!u);
try {
u ? await P({
productId: d,
shopId: v.id,
productVariantId: t?.id || g
}) : await x({
productId: d,
shopId: v.id,
productVariantId: t?.id || g
});
} catch {
k(u), m?.(u);
}
}, [
y,
d,
v.id,
t?.id,
g,
x,
P,
m
]);
return /* @__PURE__ */ p(
X,
{
variant: o,
touchable: c,
onPress: q,
children: [
/* @__PURE__ */ p(Y, { variant: o, children: [
/* @__PURE__ */ r(Z, { src: R, alt: T }),
o === "priceOverlay" && s && l && /* @__PURE__ */ r(j, { position: "top-left", children: f(l, s) }),
i && /* @__PURE__ */ r(j, { position: "bottom-left", variant: h, children: i }),
/* @__PURE__ */ r(
_,
{
filled: y,
onPress: D
}
)
] }),
/* @__PURE__ */ p($, { variant: o, children: [
/* @__PURE__ */ r(tt, { children: w }),
/* @__PURE__ */ r(rt, { children: L ? /* @__PURE__ */ p(H, { children: [
/* @__PURE__ */ r(S, { children: f(l, s) }),
/* @__PURE__ */ r(et, { children: f(
C,
A?.currencyCode || s
) })
] }) : /* @__PURE__ */ r(S, { children: f(l, s) }) })
] })
]
}
);
}
export {
ht as ProductCard,
j as ProductCardBadge,
S as ProductCardCurrentPrice,
_ as ProductCardFavoriteButton,
Z as ProductCardImage,
Y as ProductCardImageContainer,
$ as ProductCardInfo,
et as ProductCardOriginalPrice,
rt as ProductCardPrice,
X as ProductCardRoot,
tt as ProductCardTitle
};
//# sourceMappingURL=product-card.js.map