@medialane/ui 0.267.0 → 0.269.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.
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
6
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
7
  size?: "default" | "icon" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
6
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
7
  size?: "default" | "icon" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -82,16 +82,12 @@ function CollectionCard({ collection, href, settingsHref, className }) {
82
82
  }
83
83
  ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40" }),
84
84
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute inset-x-2 bottom-2 flex flex-col items-start gap-1", children: [
85
- !collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs text-white bg-black/55 backdrop-blur-md", children: [
85
+ !collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs text-white bg-black/30 backdrop-blur-md", children: [
86
86
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-2.5 w-2.5 animate-spin" }),
87
87
  "Indexing\u2026"
88
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "max-w-full truncate rounded-full px-3 py-1 text-sm font-bold leading-tight text-white bg-black/55 backdrop-blur-md", children: collection.name ?? "Unnamed Collection" }),
89
- (collection.totalSupply != null || floor) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-x-2.5 gap-y-0.5 rounded-full px-2.5 py-1 text-2xs font-medium text-white bg-black/55 backdrop-blur-md", children: [
90
- collection.totalSupply != null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
91
- collection.totalSupply.toLocaleString(),
92
- " ",
93
- collection.totalSupply === 1 ? "item" : "items"
94
- ] }),
88
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "max-w-full truncate rounded-full px-3 py-1 text-sm font-bold leading-tight text-white bg-black/30 backdrop-blur-md", children: collection.name ?? "Unnamed Collection" }),
89
+ (collection.totalSupply != null || floor) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-x-2.5 gap-y-0.5 rounded-full px-2.5 py-1 text-2xs font-medium text-white bg-black/30 backdrop-blur-md", children: [
90
+ collection.totalSupply != null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: collection.totalSupply.toLocaleString() }),
95
91
  floor && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1 font-bold text-white", children: [
96
92
  "Floor",
97
93
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: floor.symbol, size: 10 }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const floor = parseFloorPrice(collection.floorPrice);\n\n return (\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n onError={() => setImgError(true)}\n unoptimized\n />\n ) : (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40\" />\n )}\n\n <div className=\"absolute inset-x-2 bottom-2 flex flex-col items-start gap-1\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs text-white bg-black/55 backdrop-blur-md\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p className=\"max-w-full truncate rounded-full px-3 py-1 text-sm font-bold leading-tight text-white bg-black/55 backdrop-blur-md\">\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n {(collection.totalSupply != null || floor) && (\n <div className=\"flex flex-wrap items-center gap-x-2.5 gap-y-0.5 rounded-full px-2.5 py-1 text-2xs font-medium text-white bg-black/55 backdrop-blur-md\">\n {collection.totalSupply != null && (\n <span>\n {collection.totalSupply.toLocaleString()} {collection.totalSupply === 1 ? \"item\" : \"items\"}\n </span>\n )}\n {floor && (\n <span className=\"inline-flex items-center gap-1 font-bold text-white\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function CollectionCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n <div className=\"absolute inset-0 animate-pulse bg-muted\" />\n <div className=\"absolute bottom-3 left-3 right-3 space-y-1.5\">\n <div className=\"h-4 w-2/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n <div className=\"h-3 w-1/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiDY;AA/CZ,mBAAyB;AACzB,kBAAiB;AACjB,mBAAkB;AAClB,0BAAmC;AACnC,gBAAmB;AACnB,oBAAmC;AACnC,+BAA2B;AAC3B,2BAA6B;AAE7B,2BAA4B;AAE5B,SAAS,gBAAgB,OAA6E;AACpG,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,gBAAY,kCAAmB,KAAK;AAC1C,QAAM,QAAQ,UAAU,KAAK,EAAE,MAAM,KAAK;AAC1C,MAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,SAAS,MAAM,MAAM,SAAS,CAAC;AACrC,QAAM,SAAS,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AAC1C,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAWO,SAAS,eAAe,EAAE,YAAY,MAAM,cAAc,UAAU,GAAwB;AACjG,QAAM,mBAAe,kCAAY;AACjC,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,WAAW,aAAa,WAAW,OAAO,EAAE,OAAO,IAAI,CAAC;AAC9D,QAAM,YAAY,YAAY,CAAC;AAC/B,QAAM,QAAQ,gBAAgB,WAAW,UAAU;AAEnD,SACE,6CAAC,uCAAW,eAAW,cAAG,4BAA4B,SAAS,GAC5D;AAAA,oBACC;AAAA,MAAC,YAAAA;AAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAClC,WAAU;AAAA,QACV,cAAW;AAAA,QAEX,sDAAC,UAAK,WAAU,yJACd,sDAAC,iCAAU,WAAU,eAAc,GACrC;AAAA;AAAA,IACF;AAAA,IAGF,4CAAC,YAAAA,SAAA,EAAK,MAAM,QAAQ,gBAAgB,WAAW,eAAe,IAAI,WAAU,yBAC1E,uDAAC,SAAI,WAAU,0DACZ;AAAA,kBACC;AAAA,QAAC,aAAAC;AAAA,QAAA;AAAA,UACC,KAAK;AAAA,UACL,KAAK,WAAW,QAAQ;AAAA,UACxB,MAAI;AAAA,UACJ,WAAU;AAAA,UACV,SAAS,MAAM,YAAY,IAAI;AAAA,UAC/B,aAAW;AAAA;AAAA,MACb,IAEA,4CAAC,SAAI,WAAU,8FAA6F;AAAA,MAG9G,6CAAC,SAAI,WAAU,+DACZ;AAAA,SAAC,WAAW,QAAQ,WAAW,mBAAmB,YACjD,6CAAC,UAAK,WAAU,qGACd;AAAA,sDAAC,+BAAQ,WAAU,4BAA2B;AAAA,UAAE;AAAA,WAElD,IAEA,4CAAC,OAAE,WAAU,sHACV,qBAAW,QAAQ,sBACtB;AAAA,SAGA,WAAW,eAAe,QAAQ,UAClC,6CAAC,SAAI,WAAU,yIACZ;AAAA,qBAAW,eAAe,QACzB,6CAAC,UACE;AAAA,uBAAW,YAAY,eAAe;AAAA,YAAE;AAAA,YAAE,WAAW,gBAAgB,IAAI,SAAS;AAAA,aACrF;AAAA,UAED,SACC,6CAAC,UAAK,WAAU,uDAAsD;AAAA;AAAA,YAEpE,4CAAC,qCAAa,QAAQ,MAAM,QAAQ,MAAM,IAAI;AAAA,YAC7C,MAAM;AAAA,aACT;AAAA,WAEJ;AAAA,SAEJ;AAAA,OACF,GACF;AAAA,KACF;AAEJ;AAEO,SAAS,yBAAyB;AACvC,SACE,4CAAC,SAAI,WAAU,6BACb,uDAAC,SAAI,WAAU,0DACb;AAAA,gDAAC,SAAI,WAAU,2CAA0C;AAAA,IACzD,6CAAC,SAAI,WAAU,gDACb;AAAA,kDAAC,SAAI,WAAU,6DAA4D;AAAA,MAC3E,4CAAC,SAAI,WAAU,6DAA4D;AAAA,OAC7E;AAAA,KACF,GACF;AAEJ;","names":["Link","Image"]}
1
+ {"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const floor = parseFloorPrice(collection.floorPrice);\n\n return (\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n onError={() => setImgError(true)}\n unoptimized\n />\n ) : (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40\" />\n )}\n\n <div className=\"absolute inset-x-2 bottom-2 flex flex-col items-start gap-1\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs text-white bg-black/30 backdrop-blur-md\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p className=\"max-w-full truncate rounded-full px-3 py-1 text-sm font-bold leading-tight text-white bg-black/30 backdrop-blur-md\">\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n {(collection.totalSupply != null || floor) && (\n <div className=\"flex flex-wrap items-center gap-x-2.5 gap-y-0.5 rounded-full px-2.5 py-1 text-2xs font-medium text-white bg-black/30 backdrop-blur-md\">\n {collection.totalSupply != null && (\n <span>{collection.totalSupply.toLocaleString()}</span>\n )}\n {floor && (\n <span className=\"inline-flex items-center gap-1 font-bold text-white\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function CollectionCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n <div className=\"absolute inset-0 animate-pulse bg-muted\" />\n <div className=\"absolute bottom-3 left-3 right-3 space-y-1.5\">\n <div className=\"h-4 w-2/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n <div className=\"h-3 w-1/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiDY;AA/CZ,mBAAyB;AACzB,kBAAiB;AACjB,mBAAkB;AAClB,0BAAmC;AACnC,gBAAmB;AACnB,oBAAmC;AACnC,+BAA2B;AAC3B,2BAA6B;AAE7B,2BAA4B;AAE5B,SAAS,gBAAgB,OAA6E;AACpG,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,gBAAY,kCAAmB,KAAK;AAC1C,QAAM,QAAQ,UAAU,KAAK,EAAE,MAAM,KAAK;AAC1C,MAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,SAAS,MAAM,MAAM,SAAS,CAAC;AACrC,QAAM,SAAS,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AAC1C,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAWO,SAAS,eAAe,EAAE,YAAY,MAAM,cAAc,UAAU,GAAwB;AACjG,QAAM,mBAAe,kCAAY;AACjC,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,WAAW,aAAa,WAAW,OAAO,EAAE,OAAO,IAAI,CAAC;AAC9D,QAAM,YAAY,YAAY,CAAC;AAC/B,QAAM,QAAQ,gBAAgB,WAAW,UAAU;AAEnD,SACE,6CAAC,uCAAW,eAAW,cAAG,4BAA4B,SAAS,GAC5D;AAAA,oBACC;AAAA,MAAC,YAAAA;AAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAClC,WAAU;AAAA,QACV,cAAW;AAAA,QAEX,sDAAC,UAAK,WAAU,yJACd,sDAAC,iCAAU,WAAU,eAAc,GACrC;AAAA;AAAA,IACF;AAAA,IAGF,4CAAC,YAAAA,SAAA,EAAK,MAAM,QAAQ,gBAAgB,WAAW,eAAe,IAAI,WAAU,yBAC1E,uDAAC,SAAI,WAAU,0DACZ;AAAA,kBACC;AAAA,QAAC,aAAAC;AAAA,QAAA;AAAA,UACC,KAAK;AAAA,UACL,KAAK,WAAW,QAAQ;AAAA,UACxB,MAAI;AAAA,UACJ,WAAU;AAAA,UACV,SAAS,MAAM,YAAY,IAAI;AAAA,UAC/B,aAAW;AAAA;AAAA,MACb,IAEA,4CAAC,SAAI,WAAU,8FAA6F;AAAA,MAG9G,6CAAC,SAAI,WAAU,+DACZ;AAAA,SAAC,WAAW,QAAQ,WAAW,mBAAmB,YACjD,6CAAC,UAAK,WAAU,qGACd;AAAA,sDAAC,+BAAQ,WAAU,4BAA2B;AAAA,UAAE;AAAA,WAElD,IAEA,4CAAC,OAAE,WAAU,sHACV,qBAAW,QAAQ,sBACtB;AAAA,SAGA,WAAW,eAAe,QAAQ,UAClC,6CAAC,SAAI,WAAU,yIACZ;AAAA,qBAAW,eAAe,QACzB,4CAAC,UAAM,qBAAW,YAAY,eAAe,GAAE;AAAA,UAEhD,SACC,6CAAC,UAAK,WAAU,uDAAsD;AAAA;AAAA,YAEpE,4CAAC,qCAAa,QAAQ,MAAM,QAAQ,MAAM,IAAI;AAAA,YAC7C,MAAM;AAAA,aACT;AAAA,WAEJ;AAAA,SAEJ;AAAA,OACF,GACF;AAAA,KACF;AAEJ;AAEO,SAAS,yBAAyB;AACvC,SACE,4CAAC,SAAI,WAAU,6BACb,uDAAC,SAAI,WAAU,0DACb;AAAA,gDAAC,SAAI,WAAU,2CAA0C;AAAA,IACzD,6CAAC,SAAI,WAAU,gDACb;AAAA,kDAAC,SAAI,WAAU,6DAA4D;AAAA,MAC3E,4CAAC,SAAI,WAAU,6DAA4D;AAAA,OAC7E;AAAA,KACF,GACF;AAEJ;","names":["Link","Image"]}
@@ -48,16 +48,12 @@ function CollectionCard({ collection, href, settingsHref, className }) {
48
48
  }
49
49
  ) : /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40" }),
50
50
  /* @__PURE__ */ jsxs("div", { className: "absolute inset-x-2 bottom-2 flex flex-col items-start gap-1", children: [
51
- !collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs text-white bg-black/55 backdrop-blur-md", children: [
51
+ !collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs text-white bg-black/30 backdrop-blur-md", children: [
52
52
  /* @__PURE__ */ jsx(Loader2, { className: "h-2.5 w-2.5 animate-spin" }),
53
53
  "Indexing\u2026"
54
- ] }) : /* @__PURE__ */ jsx("p", { className: "max-w-full truncate rounded-full px-3 py-1 text-sm font-bold leading-tight text-white bg-black/55 backdrop-blur-md", children: collection.name ?? "Unnamed Collection" }),
55
- (collection.totalSupply != null || floor) && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-2.5 gap-y-0.5 rounded-full px-2.5 py-1 text-2xs font-medium text-white bg-black/55 backdrop-blur-md", children: [
56
- collection.totalSupply != null && /* @__PURE__ */ jsxs("span", { children: [
57
- collection.totalSupply.toLocaleString(),
58
- " ",
59
- collection.totalSupply === 1 ? "item" : "items"
60
- ] }),
54
+ ] }) : /* @__PURE__ */ jsx("p", { className: "max-w-full truncate rounded-full px-3 py-1 text-sm font-bold leading-tight text-white bg-black/30 backdrop-blur-md", children: collection.name ?? "Unnamed Collection" }),
55
+ (collection.totalSupply != null || floor) && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-2.5 gap-y-0.5 rounded-full px-2.5 py-1 text-2xs font-medium text-white bg-black/30 backdrop-blur-md", children: [
56
+ collection.totalSupply != null && /* @__PURE__ */ jsx("span", { children: collection.totalSupply.toLocaleString() }),
61
57
  floor && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 font-bold text-white", children: [
62
58
  "Floor",
63
59
  /* @__PURE__ */ jsx(CurrencyIcon, { symbol: floor.symbol, size: 10 }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const floor = parseFloorPrice(collection.floorPrice);\n\n return (\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n onError={() => setImgError(true)}\n unoptimized\n />\n ) : (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40\" />\n )}\n\n <div className=\"absolute inset-x-2 bottom-2 flex flex-col items-start gap-1\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs text-white bg-black/55 backdrop-blur-md\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p className=\"max-w-full truncate rounded-full px-3 py-1 text-sm font-bold leading-tight text-white bg-black/55 backdrop-blur-md\">\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n {(collection.totalSupply != null || floor) && (\n <div className=\"flex flex-wrap items-center gap-x-2.5 gap-y-0.5 rounded-full px-2.5 py-1 text-2xs font-medium text-white bg-black/55 backdrop-blur-md\">\n {collection.totalSupply != null && (\n <span>\n {collection.totalSupply.toLocaleString()} {collection.totalSupply === 1 ? \"item\" : \"items\"}\n </span>\n )}\n {floor && (\n <span className=\"inline-flex items-center gap-1 font-bold text-white\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function CollectionCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n <div className=\"absolute inset-0 animate-pulse bg-muted\" />\n <div className=\"absolute bottom-3 left-3 right-3 space-y-1.5\">\n <div className=\"h-4 w-2/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n <div className=\"h-3 w-1/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AAiDY,cAsBE,YAtBF;AA/CZ,SAAS,gBAAgB;AACzB,OAAO,UAAU;AACjB,OAAO,WAAW;AAClB,SAAS,SAAS,iBAAiB;AACnC,SAAS,UAAU;AACnB,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAE7B,SAAS,mBAAmB;AAE5B,SAAS,gBAAgB,OAA6E;AACpG,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,YAAY,mBAAmB,KAAK;AAC1C,QAAM,QAAQ,UAAU,KAAK,EAAE,MAAM,KAAK;AAC1C,MAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,SAAS,MAAM,MAAM,SAAS,CAAC;AACrC,QAAM,SAAS,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AAC1C,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAWO,SAAS,eAAe,EAAE,YAAY,MAAM,cAAc,UAAU,GAAwB;AACjG,QAAM,eAAe,YAAY;AACjC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,WAAW,aAAa,WAAW,OAAO,EAAE,OAAO,IAAI,CAAC;AAC9D,QAAM,YAAY,YAAY,CAAC;AAC/B,QAAM,QAAQ,gBAAgB,WAAW,UAAU;AAEnD,SACE,qBAAC,cAAW,WAAW,GAAG,4BAA4B,SAAS,GAC5D;AAAA,oBACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAClC,WAAU;AAAA,QACV,cAAW;AAAA,QAEX,8BAAC,UAAK,WAAU,yJACd,8BAAC,aAAU,WAAU,eAAc,GACrC;AAAA;AAAA,IACF;AAAA,IAGF,oBAAC,QAAK,MAAM,QAAQ,gBAAgB,WAAW,eAAe,IAAI,WAAU,yBAC1E,+BAAC,SAAI,WAAU,0DACZ;AAAA,kBACC;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,KAAK,WAAW,QAAQ;AAAA,UACxB,MAAI;AAAA,UACJ,WAAU;AAAA,UACV,SAAS,MAAM,YAAY,IAAI;AAAA,UAC/B,aAAW;AAAA;AAAA,MACb,IAEA,oBAAC,SAAI,WAAU,8FAA6F;AAAA,MAG9G,qBAAC,SAAI,WAAU,+DACZ;AAAA,SAAC,WAAW,QAAQ,WAAW,mBAAmB,YACjD,qBAAC,UAAK,WAAU,qGACd;AAAA,8BAAC,WAAQ,WAAU,4BAA2B;AAAA,UAAE;AAAA,WAElD,IAEA,oBAAC,OAAE,WAAU,sHACV,qBAAW,QAAQ,sBACtB;AAAA,SAGA,WAAW,eAAe,QAAQ,UAClC,qBAAC,SAAI,WAAU,yIACZ;AAAA,qBAAW,eAAe,QACzB,qBAAC,UACE;AAAA,uBAAW,YAAY,eAAe;AAAA,YAAE;AAAA,YAAE,WAAW,gBAAgB,IAAI,SAAS;AAAA,aACrF;AAAA,UAED,SACC,qBAAC,UAAK,WAAU,uDAAsD;AAAA;AAAA,YAEpE,oBAAC,gBAAa,QAAQ,MAAM,QAAQ,MAAM,IAAI;AAAA,YAC7C,MAAM;AAAA,aACT;AAAA,WAEJ;AAAA,SAEJ;AAAA,OACF,GACF;AAAA,KACF;AAEJ;AAEO,SAAS,yBAAyB;AACvC,SACE,oBAAC,SAAI,WAAU,6BACb,+BAAC,SAAI,WAAU,0DACb;AAAA,wBAAC,SAAI,WAAU,2CAA0C;AAAA,IACzD,qBAAC,SAAI,WAAU,gDACb;AAAA,0BAAC,SAAI,WAAU,6DAA4D;AAAA,MAC3E,oBAAC,SAAI,WAAU,6DAA4D;AAAA,OAC7E;AAAA,KACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const floor = parseFloorPrice(collection.floorPrice);\n\n return (\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n onError={() => setImgError(true)}\n unoptimized\n />\n ) : (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40\" />\n )}\n\n <div className=\"absolute inset-x-2 bottom-2 flex flex-col items-start gap-1\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs text-white bg-black/30 backdrop-blur-md\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p className=\"max-w-full truncate rounded-full px-3 py-1 text-sm font-bold leading-tight text-white bg-black/30 backdrop-blur-md\">\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n {(collection.totalSupply != null || floor) && (\n <div className=\"flex flex-wrap items-center gap-x-2.5 gap-y-0.5 rounded-full px-2.5 py-1 text-2xs font-medium text-white bg-black/30 backdrop-blur-md\">\n {collection.totalSupply != null && (\n <span>{collection.totalSupply.toLocaleString()}</span>\n )}\n {floor && (\n <span className=\"inline-flex items-center gap-1 font-bold text-white\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function CollectionCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n <div className=\"absolute inset-0 animate-pulse bg-muted\" />\n <div className=\"absolute bottom-3 left-3 right-3 space-y-1.5\">\n <div className=\"h-4 w-2/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n <div className=\"h-3 w-1/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AAiDY,cAsBE,YAtBF;AA/CZ,SAAS,gBAAgB;AACzB,OAAO,UAAU;AACjB,OAAO,WAAW;AAClB,SAAS,SAAS,iBAAiB;AACnC,SAAS,UAAU;AACnB,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAE7B,SAAS,mBAAmB;AAE5B,SAAS,gBAAgB,OAA6E;AACpG,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,YAAY,mBAAmB,KAAK;AAC1C,QAAM,QAAQ,UAAU,KAAK,EAAE,MAAM,KAAK;AAC1C,MAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,SAAS,MAAM,MAAM,SAAS,CAAC;AACrC,QAAM,SAAS,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AAC1C,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAWO,SAAS,eAAe,EAAE,YAAY,MAAM,cAAc,UAAU,GAAwB;AACjG,QAAM,eAAe,YAAY;AACjC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,WAAW,aAAa,WAAW,OAAO,EAAE,OAAO,IAAI,CAAC;AAC9D,QAAM,YAAY,YAAY,CAAC;AAC/B,QAAM,QAAQ,gBAAgB,WAAW,UAAU;AAEnD,SACE,qBAAC,cAAW,WAAW,GAAG,4BAA4B,SAAS,GAC5D;AAAA,oBACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAClC,WAAU;AAAA,QACV,cAAW;AAAA,QAEX,8BAAC,UAAK,WAAU,yJACd,8BAAC,aAAU,WAAU,eAAc,GACrC;AAAA;AAAA,IACF;AAAA,IAGF,oBAAC,QAAK,MAAM,QAAQ,gBAAgB,WAAW,eAAe,IAAI,WAAU,yBAC1E,+BAAC,SAAI,WAAU,0DACZ;AAAA,kBACC;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,KAAK,WAAW,QAAQ;AAAA,UACxB,MAAI;AAAA,UACJ,WAAU;AAAA,UACV,SAAS,MAAM,YAAY,IAAI;AAAA,UAC/B,aAAW;AAAA;AAAA,MACb,IAEA,oBAAC,SAAI,WAAU,8FAA6F;AAAA,MAG9G,qBAAC,SAAI,WAAU,+DACZ;AAAA,SAAC,WAAW,QAAQ,WAAW,mBAAmB,YACjD,qBAAC,UAAK,WAAU,qGACd;AAAA,8BAAC,WAAQ,WAAU,4BAA2B;AAAA,UAAE;AAAA,WAElD,IAEA,oBAAC,OAAE,WAAU,sHACV,qBAAW,QAAQ,sBACtB;AAAA,SAGA,WAAW,eAAe,QAAQ,UAClC,qBAAC,SAAI,WAAU,yIACZ;AAAA,qBAAW,eAAe,QACzB,oBAAC,UAAM,qBAAW,YAAY,eAAe,GAAE;AAAA,UAEhD,SACC,qBAAC,UAAK,WAAU,uDAAsD;AAAA;AAAA,YAEpE,oBAAC,gBAAa,QAAQ,MAAM,QAAQ,MAAM,IAAI;AAAA,YAC7C,MAAM;AAAA,aACT;AAAA,WAEJ;AAAA,SAEJ;AAAA,OACF,GACF;AAAA,KACF;AAEJ;AAEO,SAAS,yBAAyB;AACvC,SACE,oBAAC,SAAI,WAAU,6BACb,+BAAC,SAAI,WAAU,0DACb;AAAA,wBAAC,SAAI,WAAU,2CAA0C;AAAA,IACzD,qBAAC,SAAI,WAAU,gDACb;AAAA,0BAAC,SAAI,WAAU,6DAA4D;AAAA,MAC3E,oBAAC,SAAI,WAAU,6DAA4D;AAAA,OAC7E;AAAA,KACF,GACF;AAEJ;","names":[]}
@@ -1,10 +1,10 @@
1
- import * as React from 'react';
2
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
3
  import { FastMintProps } from './types.cjs';
4
4
  import 'starknet';
5
5
  import '@medialane/sdk';
6
6
  import '@medialane/sdk/starknet';
7
7
 
8
- declare function FastMint(props: FastMintProps): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
8
+ declare function FastMint(props: FastMintProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;
9
9
 
10
10
  export { FastMint };
@@ -1,10 +1,10 @@
1
- import * as React from 'react';
2
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
3
  import { FastMintProps } from './types.js';
4
4
  import 'starknet';
5
5
  import '@medialane/sdk';
6
6
  import '@medialane/sdk/starknet';
7
7
 
8
- declare function FastMint(props: FastMintProps): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
8
+ declare function FastMint(props: FastMintProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;
9
9
 
10
10
  export { FastMint };
@@ -36,8 +36,8 @@ function PageBackdrop({ image }) {
36
36
  src: image,
37
37
  alt: "",
38
38
  "aria-hidden": true,
39
- className: "absolute inset-0 w-full h-full object-cover opacity-20 scale-110",
40
- style: { filter: "blur(60px) saturate(1.5)" }
39
+ className: "absolute inset-0 w-full h-full object-cover opacity-50 dark:opacity-40 scale-110",
40
+ style: { filter: "blur(80px) saturate(1.8)" }
41
41
  }
42
42
  ) });
43
43
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/media-header.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, type ElementType, type ReactNode } from \"react\";\nimport { Skeleton } from \"./skeleton.js\";\n\nexport interface MediaHeaderProps {\n image: string | null;\n imageAlt: string;\n fallbackIcon: ElementType;\n loading?: boolean;\n children: ReactNode;\n}\n\nexport function PageBackdrop({ image }: { image: string | null }) {\n if (!image) return null;\n return (\n <div className=\"fixed inset-0 -z-10 overflow-hidden pointer-events-none\">\n <img\n src={image}\n alt=\"\"\n aria-hidden\n className=\"absolute inset-0 w-full h-full object-cover opacity-20 scale-110\"\n style={{ filter: \"blur(60px) saturate(1.5)\" }}\n />\n </div>\n );\n}\n\nconst FRAME = \"w-full sm:w-44 lg:w-56 shrink-0 rounded-2xl overflow-hidden bg-muted\";\n\nexport function MediaHeader({ image, imageAlt, fallbackIcon: FallbackIcon, loading = false, children }: MediaHeaderProps) {\n const [imgError, setImgError] = useState(false);\n\n if (loading) {\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <Skeleton className={`${FRAME} aspect-square`} />\n <div className=\"flex-1 w-full space-y-3\">\n <Skeleton className=\"h-6 w-40\" />\n <Skeleton className=\"h-10 w-2/3\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <PageBackdrop image={image} />\n\n <div className={FRAME}>\n {image && !imgError ? (\n <img src={image} alt={imageAlt} onError={() => setImgError(true)} className=\"block w-full h-auto max-h-[80vh] object-contain sm:aspect-square sm:h-full sm:object-cover\" />\n ) : (\n <div className=\"aspect-square w-full flex items-center justify-center\">\n <FallbackIcon className=\"h-1/3 w-1/3 text-muted-foreground/40\" />\n </div>\n )}\n </div>\n\n <div className=\"flex-1 space-y-5 min-w-0 w-full\">{children}</div>\n </div>\n );\n}\n\nexport function HeaderStats({ children }: { children: ReactNode }) {\n return <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground\">{children}</div>;\n}\n\nexport function HeaderStat({ label, children }: { label: string; children: ReactNode }) {\n return (\n <span className=\"inline-flex items-center gap-1.5\">\n <span>{label}</span>\n <span className=\"font-semibold text-foreground tabular-nums\">{children}</span>\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBM;AAfN,mBAA2D;AAC3D,sBAAyB;AAUlB,SAAS,aAAa,EAAE,MAAM,GAA6B;AAChE,MAAI,CAAC,MAAO,QAAO;AACnB,SACE,4CAAC,SAAI,WAAU,2DACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,KAAI;AAAA,MACJ,eAAW;AAAA,MACX,WAAU;AAAA,MACV,OAAO,EAAE,QAAQ,2BAA2B;AAAA;AAAA,EAC9C,GACF;AAEJ;AAEA,MAAM,QAAQ;AAEP,SAAS,YAAY,EAAE,OAAO,UAAU,cAAc,cAAc,UAAU,OAAO,SAAS,GAAqB;AACxH,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAE9C,MAAI,SAAS;AACX,WACE,6CAAC,SAAI,WAAU,gFACb;AAAA,kDAAC,4BAAS,WAAW,GAAG,KAAK,kBAAkB;AAAA,MAC/C,6CAAC,SAAI,WAAU,2BACb;AAAA,oDAAC,4BAAS,WAAU,YAAW;AAAA,QAC/B,4CAAC,4BAAS,WAAU,cAAa;AAAA,QACjC,4CAAC,4BAAS,WAAU,eAAc;AAAA,SACpC;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,6CAAC,SAAI,WAAU,gFACb;AAAA,gDAAC,gBAAa,OAAc;AAAA,IAE5B,4CAAC,SAAI,WAAW,OACb,mBAAS,CAAC,WACT,4CAAC,SAAI,KAAK,OAAO,KAAK,UAAU,SAAS,MAAM,YAAY,IAAI,GAAG,WAAU,8FAA6F,IAEzK,4CAAC,SAAI,WAAU,yDACb,sDAAC,gBAAa,WAAU,wCAAuC,GACjE,GAEJ;AAAA,IAEA,4CAAC,SAAI,WAAU,mCAAmC,UAAS;AAAA,KAC7D;AAEJ;AAEO,SAAS,YAAY,EAAE,SAAS,GAA4B;AACjE,SAAO,4CAAC,SAAI,WAAU,6EAA6E,UAAS;AAC9G;AAEO,SAAS,WAAW,EAAE,OAAO,SAAS,GAA2C;AACtF,SACE,6CAAC,UAAK,WAAU,oCACd;AAAA,gDAAC,UAAM,iBAAM;AAAA,IACb,4CAAC,UAAK,WAAU,8CAA8C,UAAS;AAAA,KACzE;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/media-header.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, type ElementType, type ReactNode } from \"react\";\nimport { Skeleton } from \"./skeleton.js\";\n\nexport interface MediaHeaderProps {\n image: string | null;\n imageAlt: string;\n fallbackIcon: ElementType;\n loading?: boolean;\n children: ReactNode;\n}\n\nexport function PageBackdrop({ image }: { image: string | null }) {\n if (!image) return null;\n return (\n <div className=\"fixed inset-0 -z-10 overflow-hidden pointer-events-none\">\n <img\n src={image}\n alt=\"\"\n aria-hidden\n className=\"absolute inset-0 w-full h-full object-cover opacity-50 dark:opacity-40 scale-110\"\n style={{ filter: \"blur(80px) saturate(1.8)\" }}\n />\n </div>\n );\n}\n\nconst FRAME = \"w-full sm:w-44 lg:w-56 shrink-0 rounded-2xl overflow-hidden bg-muted\";\n\nexport function MediaHeader({ image, imageAlt, fallbackIcon: FallbackIcon, loading = false, children }: MediaHeaderProps) {\n const [imgError, setImgError] = useState(false);\n\n if (loading) {\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <Skeleton className={`${FRAME} aspect-square`} />\n <div className=\"flex-1 w-full space-y-3\">\n <Skeleton className=\"h-6 w-40\" />\n <Skeleton className=\"h-10 w-2/3\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <PageBackdrop image={image} />\n\n <div className={FRAME}>\n {image && !imgError ? (\n <img src={image} alt={imageAlt} onError={() => setImgError(true)} className=\"block w-full h-auto max-h-[80vh] object-contain sm:aspect-square sm:h-full sm:object-cover\" />\n ) : (\n <div className=\"aspect-square w-full flex items-center justify-center\">\n <FallbackIcon className=\"h-1/3 w-1/3 text-muted-foreground/40\" />\n </div>\n )}\n </div>\n\n <div className=\"flex-1 space-y-5 min-w-0 w-full\">{children}</div>\n </div>\n );\n}\n\nexport function HeaderStats({ children }: { children: ReactNode }) {\n return <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground\">{children}</div>;\n}\n\nexport function HeaderStat({ label, children }: { label: string; children: ReactNode }) {\n return (\n <span className=\"inline-flex items-center gap-1.5\">\n <span>{label}</span>\n <span className=\"font-semibold text-foreground tabular-nums\">{children}</span>\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBM;AAfN,mBAA2D;AAC3D,sBAAyB;AAUlB,SAAS,aAAa,EAAE,MAAM,GAA6B;AAChE,MAAI,CAAC,MAAO,QAAO;AACnB,SACE,4CAAC,SAAI,WAAU,2DACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,KAAI;AAAA,MACJ,eAAW;AAAA,MACX,WAAU;AAAA,MACV,OAAO,EAAE,QAAQ,2BAA2B;AAAA;AAAA,EAC9C,GACF;AAEJ;AAEA,MAAM,QAAQ;AAEP,SAAS,YAAY,EAAE,OAAO,UAAU,cAAc,cAAc,UAAU,OAAO,SAAS,GAAqB;AACxH,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAE9C,MAAI,SAAS;AACX,WACE,6CAAC,SAAI,WAAU,gFACb;AAAA,kDAAC,4BAAS,WAAW,GAAG,KAAK,kBAAkB;AAAA,MAC/C,6CAAC,SAAI,WAAU,2BACb;AAAA,oDAAC,4BAAS,WAAU,YAAW;AAAA,QAC/B,4CAAC,4BAAS,WAAU,cAAa;AAAA,QACjC,4CAAC,4BAAS,WAAU,eAAc;AAAA,SACpC;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,6CAAC,SAAI,WAAU,gFACb;AAAA,gDAAC,gBAAa,OAAc;AAAA,IAE5B,4CAAC,SAAI,WAAW,OACb,mBAAS,CAAC,WACT,4CAAC,SAAI,KAAK,OAAO,KAAK,UAAU,SAAS,MAAM,YAAY,IAAI,GAAG,WAAU,8FAA6F,IAEzK,4CAAC,SAAI,WAAU,yDACb,sDAAC,gBAAa,WAAU,wCAAuC,GACjE,GAEJ;AAAA,IAEA,4CAAC,SAAI,WAAU,mCAAmC,UAAS;AAAA,KAC7D;AAEJ;AAEO,SAAS,YAAY,EAAE,SAAS,GAA4B;AACjE,SAAO,4CAAC,SAAI,WAAU,6EAA6E,UAAS;AAC9G;AAEO,SAAS,WAAW,EAAE,OAAO,SAAS,GAA2C;AACtF,SACE,6CAAC,UAAK,WAAU,oCACd;AAAA,gDAAC,UAAM,iBAAM;AAAA,IACb,4CAAC,UAAK,WAAU,8CAA8C,UAAS;AAAA,KACzE;AAEJ;","names":[]}
@@ -10,8 +10,8 @@ function PageBackdrop({ image }) {
10
10
  src: image,
11
11
  alt: "",
12
12
  "aria-hidden": true,
13
- className: "absolute inset-0 w-full h-full object-cover opacity-20 scale-110",
14
- style: { filter: "blur(60px) saturate(1.5)" }
13
+ className: "absolute inset-0 w-full h-full object-cover opacity-50 dark:opacity-40 scale-110",
14
+ style: { filter: "blur(80px) saturate(1.8)" }
15
15
  }
16
16
  ) });
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/media-header.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, type ElementType, type ReactNode } from \"react\";\nimport { Skeleton } from \"./skeleton.js\";\n\nexport interface MediaHeaderProps {\n image: string | null;\n imageAlt: string;\n fallbackIcon: ElementType;\n loading?: boolean;\n children: ReactNode;\n}\n\nexport function PageBackdrop({ image }: { image: string | null }) {\n if (!image) return null;\n return (\n <div className=\"fixed inset-0 -z-10 overflow-hidden pointer-events-none\">\n <img\n src={image}\n alt=\"\"\n aria-hidden\n className=\"absolute inset-0 w-full h-full object-cover opacity-20 scale-110\"\n style={{ filter: \"blur(60px) saturate(1.5)\" }}\n />\n </div>\n );\n}\n\nconst FRAME = \"w-full sm:w-44 lg:w-56 shrink-0 rounded-2xl overflow-hidden bg-muted\";\n\nexport function MediaHeader({ image, imageAlt, fallbackIcon: FallbackIcon, loading = false, children }: MediaHeaderProps) {\n const [imgError, setImgError] = useState(false);\n\n if (loading) {\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <Skeleton className={`${FRAME} aspect-square`} />\n <div className=\"flex-1 w-full space-y-3\">\n <Skeleton className=\"h-6 w-40\" />\n <Skeleton className=\"h-10 w-2/3\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <PageBackdrop image={image} />\n\n <div className={FRAME}>\n {image && !imgError ? (\n <img src={image} alt={imageAlt} onError={() => setImgError(true)} className=\"block w-full h-auto max-h-[80vh] object-contain sm:aspect-square sm:h-full sm:object-cover\" />\n ) : (\n <div className=\"aspect-square w-full flex items-center justify-center\">\n <FallbackIcon className=\"h-1/3 w-1/3 text-muted-foreground/40\" />\n </div>\n )}\n </div>\n\n <div className=\"flex-1 space-y-5 min-w-0 w-full\">{children}</div>\n </div>\n );\n}\n\nexport function HeaderStats({ children }: { children: ReactNode }) {\n return <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground\">{children}</div>;\n}\n\nexport function HeaderStat({ label, children }: { label: string; children: ReactNode }) {\n return (\n <span className=\"inline-flex items-center gap-1.5\">\n <span>{label}</span>\n <span className=\"font-semibold text-foreground tabular-nums\">{children}</span>\n </span>\n );\n}\n"],"mappings":";AAiBM,cAoBE,YApBF;AAfN,SAAS,gBAAkD;AAC3D,SAAS,gBAAgB;AAUlB,SAAS,aAAa,EAAE,MAAM,GAA6B;AAChE,MAAI,CAAC,MAAO,QAAO;AACnB,SACE,oBAAC,SAAI,WAAU,2DACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,KAAI;AAAA,MACJ,eAAW;AAAA,MACX,WAAU;AAAA,MACV,OAAO,EAAE,QAAQ,2BAA2B;AAAA;AAAA,EAC9C,GACF;AAEJ;AAEA,MAAM,QAAQ;AAEP,SAAS,YAAY,EAAE,OAAO,UAAU,cAAc,cAAc,UAAU,OAAO,SAAS,GAAqB;AACxH,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,MAAI,SAAS;AACX,WACE,qBAAC,SAAI,WAAU,gFACb;AAAA,0BAAC,YAAS,WAAW,GAAG,KAAK,kBAAkB;AAAA,MAC/C,qBAAC,SAAI,WAAU,2BACb;AAAA,4BAAC,YAAS,WAAU,YAAW;AAAA,QAC/B,oBAAC,YAAS,WAAU,cAAa;AAAA,QACjC,oBAAC,YAAS,WAAU,eAAc;AAAA,SACpC;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,gFACb;AAAA,wBAAC,gBAAa,OAAc;AAAA,IAE5B,oBAAC,SAAI,WAAW,OACb,mBAAS,CAAC,WACT,oBAAC,SAAI,KAAK,OAAO,KAAK,UAAU,SAAS,MAAM,YAAY,IAAI,GAAG,WAAU,8FAA6F,IAEzK,oBAAC,SAAI,WAAU,yDACb,8BAAC,gBAAa,WAAU,wCAAuC,GACjE,GAEJ;AAAA,IAEA,oBAAC,SAAI,WAAU,mCAAmC,UAAS;AAAA,KAC7D;AAEJ;AAEO,SAAS,YAAY,EAAE,SAAS,GAA4B;AACjE,SAAO,oBAAC,SAAI,WAAU,6EAA6E,UAAS;AAC9G;AAEO,SAAS,WAAW,EAAE,OAAO,SAAS,GAA2C;AACtF,SACE,qBAAC,UAAK,WAAU,oCACd;AAAA,wBAAC,UAAM,iBAAM;AAAA,IACb,oBAAC,UAAK,WAAU,8CAA8C,UAAS;AAAA,KACzE;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/media-header.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, type ElementType, type ReactNode } from \"react\";\nimport { Skeleton } from \"./skeleton.js\";\n\nexport interface MediaHeaderProps {\n image: string | null;\n imageAlt: string;\n fallbackIcon: ElementType;\n loading?: boolean;\n children: ReactNode;\n}\n\nexport function PageBackdrop({ image }: { image: string | null }) {\n if (!image) return null;\n return (\n <div className=\"fixed inset-0 -z-10 overflow-hidden pointer-events-none\">\n <img\n src={image}\n alt=\"\"\n aria-hidden\n className=\"absolute inset-0 w-full h-full object-cover opacity-50 dark:opacity-40 scale-110\"\n style={{ filter: \"blur(80px) saturate(1.8)\" }}\n />\n </div>\n );\n}\n\nconst FRAME = \"w-full sm:w-44 lg:w-56 shrink-0 rounded-2xl overflow-hidden bg-muted\";\n\nexport function MediaHeader({ image, imageAlt, fallbackIcon: FallbackIcon, loading = false, children }: MediaHeaderProps) {\n const [imgError, setImgError] = useState(false);\n\n if (loading) {\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <Skeleton className={`${FRAME} aspect-square`} />\n <div className=\"flex-1 w-full space-y-3\">\n <Skeleton className=\"h-6 w-40\" />\n <Skeleton className=\"h-10 w-2/3\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <PageBackdrop image={image} />\n\n <div className={FRAME}>\n {image && !imgError ? (\n <img src={image} alt={imageAlt} onError={() => setImgError(true)} className=\"block w-full h-auto max-h-[80vh] object-contain sm:aspect-square sm:h-full sm:object-cover\" />\n ) : (\n <div className=\"aspect-square w-full flex items-center justify-center\">\n <FallbackIcon className=\"h-1/3 w-1/3 text-muted-foreground/40\" />\n </div>\n )}\n </div>\n\n <div className=\"flex-1 space-y-5 min-w-0 w-full\">{children}</div>\n </div>\n );\n}\n\nexport function HeaderStats({ children }: { children: ReactNode }) {\n return <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground\">{children}</div>;\n}\n\nexport function HeaderStat({ label, children }: { label: string; children: ReactNode }) {\n return (\n <span className=\"inline-flex items-center gap-1.5\">\n <span>{label}</span>\n <span className=\"font-semibold text-foreground tabular-nums\">{children}</span>\n </span>\n );\n}\n"],"mappings":";AAiBM,cAoBE,YApBF;AAfN,SAAS,gBAAkD;AAC3D,SAAS,gBAAgB;AAUlB,SAAS,aAAa,EAAE,MAAM,GAA6B;AAChE,MAAI,CAAC,MAAO,QAAO;AACnB,SACE,oBAAC,SAAI,WAAU,2DACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,KAAI;AAAA,MACJ,eAAW;AAAA,MACX,WAAU;AAAA,MACV,OAAO,EAAE,QAAQ,2BAA2B;AAAA;AAAA,EAC9C,GACF;AAEJ;AAEA,MAAM,QAAQ;AAEP,SAAS,YAAY,EAAE,OAAO,UAAU,cAAc,cAAc,UAAU,OAAO,SAAS,GAAqB;AACxH,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,MAAI,SAAS;AACX,WACE,qBAAC,SAAI,WAAU,gFACb;AAAA,0BAAC,YAAS,WAAW,GAAG,KAAK,kBAAkB;AAAA,MAC/C,qBAAC,SAAI,WAAU,2BACb;AAAA,4BAAC,YAAS,WAAU,YAAW;AAAA,QAC/B,oBAAC,YAAS,WAAU,cAAa;AAAA,QACjC,oBAAC,YAAS,WAAU,eAAc;AAAA,SACpC;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,gFACb;AAAA,wBAAC,gBAAa,OAAc;AAAA,IAE5B,oBAAC,SAAI,WAAW,OACb,mBAAS,CAAC,WACT,oBAAC,SAAI,KAAK,OAAO,KAAK,UAAU,SAAS,MAAM,YAAY,IAAI,GAAG,WAAU,8FAA6F,IAEzK,oBAAC,SAAI,WAAU,yDACb,8BAAC,gBAAa,WAAU,wCAAuC,GACjE,GAEJ;AAAA,IAEA,oBAAC,SAAI,WAAU,mCAAmC,UAAS;AAAA,KAC7D;AAEJ;AAEO,SAAS,YAAY,EAAE,SAAS,GAA4B;AACjE,SAAO,oBAAC,SAAI,WAAU,6EAA6E,UAAS;AAC9G;AAEO,SAAS,WAAW,EAAE,OAAO,SAAS,GAA2C;AACtF,SACE,qBAAC,UAAK,WAAU,oCACd;AAAA,wBAAC,UAAM,iBAAM;AAAA,IACb,oBAAC,UAAK,WAAU,8CAA8C,UAAS;AAAA,KACzE;AAEJ;","names":[]}
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
10
10
  declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
11
11
  declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
12
12
  declare const sheetVariants: (props?: ({
13
- side?: "bottom" | "left" | "right" | "top" | null | undefined;
13
+ side?: "left" | "right" | "bottom" | "top" | null | undefined;
14
14
  } & class_variance_authority_types.ClassProp) | undefined) => string;
15
15
  interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
16
16
  overlayClassName?: string;
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
10
10
  declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
11
11
  declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
12
12
  declare const sheetVariants: (props?: ({
13
- side?: "bottom" | "left" | "right" | "top" | null | undefined;
13
+ side?: "left" | "right" | "bottom" | "top" | null | undefined;
14
14
  } & class_variance_authority_types.ClassProp) | undefined) => string;
15
15
  interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
16
16
  overlayClassName?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.267.0",
3
+ "version": "0.269.0",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "sideEffects": false,