UNPKG

@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
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