@shopify/shop-minis-react
Version:
React component library for Shopify Shop Minis with Tailwind CSS v4 support (source-only, requires TypeScript)
281 lines (280 loc) • 8.03 kB
JavaScript
import { jsx as e, jsxs as u, Fragment as p } from "react/jsx-runtime";
import { useCallback as w, useMemo as f, createContext as N, useContext as y } from "react";
import { useShopNavigation as T } from "../../hooks/navigation/useShopNavigation.js";
import { cn as c } from "../../lib/utils.js";
import { isDarkColor as b } from "../../utils/colors.js";
import { Image as k } from "../atoms/image.js";
import { Touchable as I } from "../atoms/touchable.js";
import { extractBrandTheme as M, normalizeRating as z, formatReviewCount as j, getFeaturedImages as D } from "../../utils/merchant-card.js";
import S from "../../shop-minis-react/node_modules/.pnpm/lucide-react@0.513.0_react@19.1.0/node_modules/lucide-react/dist/esm/icons/star.js";
const C = N(
void 0
);
function i() {
const a = y(C);
if (!a)
throw new Error(
"useMerchantCardContext must be used within a MerchantCardProvider"
);
return a;
}
function B({
className: a,
...r
}) {
const { touchable: t, cardTheme: n, onClick: o } = i(), l = /* @__PURE__ */ e(
"div",
{
style: {
backgroundColor: n.backgroundColor
},
className: c(
"relative w-full overflow-hidden rounded-xl bg-white flex flex-col border border-gray-200 aspect-square isolate",
a
),
...r
}
);
return t && o ? /* @__PURE__ */ e(
I,
{
onClick: o,
whileTap: { opacity: 0.7 },
transition: {
opacity: { type: "tween", duration: 0.08, ease: "easeInOut" }
},
children: l
}
) : l;
}
function v({
className: a,
src: r,
alt: t,
thumbhash: n,
...o
}) {
return r ? n ? /* @__PURE__ */ e(
k,
{
"data-slot": "merchant-card-image",
src: r,
alt: t,
thumbhash: n,
className: c(a),
...o
}
) : /* @__PURE__ */ e(
"img",
{
"data-slot": "merchant-card-image",
src: r,
alt: t,
className: c("size-full object-cover", a),
...o
}
) : /* @__PURE__ */ e("div", { className: "w-full h-full bg-gray-100" });
}
function x({ className: a, ...r }) {
const { shop: t } = i(), { name: n, visualTheme: o } = t, l = o?.brandSettings?.colors?.logoAverage, d = o?.brandSettings?.colors?.logoDominant, m = l || d, h = f(
() => m && b(m) ? "bg-white" : "bg-gray-800",
[m]
), s = o?.logoImage?.url, g = `${n} logo`;
return /* @__PURE__ */ e(
"div",
{
"data-slot": "merchant-card-logo",
className: c(
"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10",
"w-16 h-16 rounded-xl bg-white border-2 border-white shadow-sm",
"flex items-center justify-center overflow-hidden",
h,
a
),
...r,
children: s ? /* @__PURE__ */ e(
"img",
{
src: s,
alt: g,
className: "w-full h-full object-cover"
}
) : /* @__PURE__ */ e("div", { className: "w-full h-full bg-gray-200 flex items-center justify-center", children: /* @__PURE__ */ e("span", { className: "text-gray-600 font-semibold text-lg", children: n?.slice(0, 1) }) })
}
);
}
function R({ className: a, ...r }) {
const { cardTheme: t } = i(), o = f(() => t.backgroundColor !== "white" && b(t.backgroundColor), [t.backgroundColor]) ? "text-primary-foreground" : "text-foreground";
return /* @__PURE__ */ e(
"div",
{
"data-slot": "merchant-card-info",
className: c(
"p-3 flex-shrink-0 flex flex-col min-w-0",
o,
a
),
...r
}
);
}
function $({
className: a,
children: r,
...t
}) {
const { shop: n } = i(), { name: o } = n, l = r ?? o;
return /* @__PURE__ */ e(
"h3",
{
"data-slot": "merchant-card-name",
className: c("text-sm font-medium truncate", a),
...t,
children: l
}
);
}
function A({
className: a,
...r
}) {
const { shop: t } = i(), {
reviewAnalytics: { averageRating: n, reviewCount: o }
} = t;
return !n || !o ? null : /* @__PURE__ */ u(
"div",
{
"data-slot": "merchant-card-rating",
className: c("flex items-center gap-1 text-xs", a),
...r,
children: [
/* @__PURE__ */ e(S, { className: "h-3 w-3 fill-current" }),
/* @__PURE__ */ u("span", { className: "text-xs", children: [
z(n),
" (",
j(o),
")"
] })
]
}
);
}
function F({ withLogo: a = !1 }) {
const { shop: r, cardTheme: t, featuredImagesLimit: n } = i(), { visualTheme: o } = r, l = f(
() => D(o, n),
[o, n]
), d = l?.length ?? 0;
return /* @__PURE__ */ u("div", { className: "w-full h-full bg-muted relative flex flex-wrap overflow-hidden", children: [
a && /* @__PURE__ */ e("div", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10", children: /* @__PURE__ */ e(x, {}) }),
(() => {
if (d > 0) {
const h = d === 2 ? "h-full" : "h-1/2";
return l?.map((s, g) => /* @__PURE__ */ e("div", { className: `z-0 w-1/2 ${h}`, children: /* @__PURE__ */ e(
v,
{
src: s.url,
alt: s.altText ?? void 0,
thumbhash: s.thumbhash ?? void 0,
className: "aspect-square"
}
) }, s.url || g));
} else if (t.type === "coverImage")
return /* @__PURE__ */ e(
v,
{
src: t.coverImageUrl,
thumbhash: t.coverImageThumbhash
}
);
return null;
})()
] });
}
function H({ withLogo: a = !1 }) {
const { shop: r, cardTheme: t } = i(), n = r.visualTheme?.brandSettings?.headerTheme?.wordmark;
return /* @__PURE__ */ u("div", { className: "size-full relative", children: [
t.type === "coverImage" && /* @__PURE__ */ u(p, { children: [
/* @__PURE__ */ e(
v,
{
src: t.coverImageUrl,
alt: r.name,
thumbhash: t.coverImageThumbhash ?? void 0
}
),
/* @__PURE__ */ e("div", { className: "absolute inset-0 z-[1] bg-black/20" }),
/* @__PURE__ */ e(
"div",
{
className: "absolute bottom-0 z-[1] size-full",
style: {
background: `linear-gradient(to top, ${t.backgroundColor} 0%, ${t.backgroundColor}00 40%)`
}
}
)
] }),
a && /* @__PURE__ */ e("div", { className: "absolute inset-0 z-[1] flex items-center justify-center", children: n ? /* @__PURE__ */ e(
"img",
{
src: n.url,
alt: n.altText || r.name,
className: "max-h-16 min-h-10 max-w-28 object-contain",
"data-testid": "store-data-wordmark"
}
) : /* @__PURE__ */ e(x, {}) })
] });
}
function U({
isDefault: a,
withLogo: r,
className: t,
...n
}) {
const { cardTheme: o } = i(), l = o.type === "coverImage" || o.type === "brandColor";
return /* @__PURE__ */ e(
"div",
{
className: c("relative overflow-hidden flex-1 flex-wrap", t),
...n,
children: l && !a ? /* @__PURE__ */ e(H, { withLogo: r }) : /* @__PURE__ */ e(F, { withLogo: r })
}
);
}
function Q({
shop: a,
touchable: r = !0,
featuredImagesLimit: t = 4,
children: n
}) {
const { navigateToShop: o } = T(), { id: l, visualTheme: d } = a, m = w(() => {
r && o({ shopId: l });
}, [o, l, r]), h = f(
() => M(d?.brandSettings),
[d?.brandSettings]
), s = f(
() => ({
shop: a,
cardTheme: h,
touchable: r,
featuredImagesLimit: t,
onClick: m
}),
[a, h, r, t, m]
);
return /* @__PURE__ */ e(C.Provider, { value: s, children: n ?? /* @__PURE__ */ u(B, { children: [
/* @__PURE__ */ e(U, { withLogo: !0 }),
/* @__PURE__ */ u(R, { children: [
/* @__PURE__ */ e($, {}),
/* @__PURE__ */ e(A, {})
] })
] }) });
}
export {
Q as MerchantCard,
B as MerchantCardContainer,
U as MerchantCardHeader,
R as MerchantCardInfo,
$ as MerchantCardName,
A as MerchantCardRating
};
//# sourceMappingURL=merchant-card.js.map