@medialane/ui 0.251.0 → 0.253.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.
- package/dist/components/account/input-otp.d.cts +2 -2
- package/dist/components/account/input-otp.d.ts +2 -2
- package/dist/components/asset-page.cjs +11 -4
- package/dist/components/asset-page.cjs.map +1 -1
- package/dist/components/asset-page.js +11 -4
- package/dist/components/asset-page.js.map +1 -1
- package/dist/components/asset-publication.cjs +5 -13
- package/dist/components/asset-publication.cjs.map +1 -1
- package/dist/components/asset-publication.d.cts +2 -2
- package/dist/components/asset-publication.d.ts +2 -2
- package/dist/components/asset-publication.js +5 -13
- package/dist/components/asset-publication.js.map +1 -1
- package/dist/components/asset-top-sections.cjs +9 -1
- package/dist/components/asset-top-sections.cjs.map +1 -1
- package/dist/components/asset-top-sections.d.cts +2 -1
- package/dist/components/asset-top-sections.d.ts +2 -1
- package/dist/components/asset-top-sections.js +9 -1
- package/dist/components/asset-top-sections.js.map +1 -1
- package/dist/components/button.d.cts +2 -2
- package/dist/components/button.d.ts +2 -2
- package/dist/components/collection-card.cjs +11 -19
- package/dist/components/collection-card.cjs.map +1 -1
- package/dist/components/collection-card.js +11 -19
- package/dist/components/collection-card.js.map +1 -1
- package/dist/components/collections-page.cjs +190 -139
- package/dist/components/collections-page.cjs.map +1 -1
- package/dist/components/collections-page.js +181 -140
- package/dist/components/collections-page.js.map +1 -1
- package/dist/components/creator-page.cjs +1 -1
- package/dist/components/creator-page.cjs.map +1 -1
- package/dist/components/creator-page.js +1 -1
- package/dist/components/creator-page.js.map +1 -1
- package/dist/components/drop/create/drop-create.cjs +1 -1
- package/dist/components/drop/create/drop-create.cjs.map +1 -1
- package/dist/components/drop/create/drop-create.js +1 -1
- package/dist/components/drop/create/drop-create.js.map +1 -1
- package/dist/components/drop/create/launch-dialog.cjs +1 -1
- package/dist/components/drop/create/launch-dialog.cjs.map +1 -1
- package/dist/components/drop/create/launch-dialog.js +1 -1
- package/dist/components/drop/create/launch-dialog.js.map +1 -1
- package/dist/components/fast-mint/fast-mint.d.cts +2 -2
- package/dist/components/fast-mint/fast-mint.d.ts +2 -2
- package/dist/components/hero-slider.cjs +2 -1
- package/dist/components/hero-slider.cjs.map +1 -1
- package/dist/components/hero-slider.js +2 -1
- package/dist/components/hero-slider.js.map +1 -1
- package/dist/components/launchpad/edition-mint-schema.d.cts +2 -2
- package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
- package/dist/components/scroll-section.cjs +1 -1
- package/dist/components/scroll-section.cjs.map +1 -1
- package/dist/components/scroll-section.d.cts +1 -1
- package/dist/components/scroll-section.d.ts +1 -1
- package/dist/components/scroll-section.js +1 -1
- package/dist/components/scroll-section.js.map +1 -1
- package/dist/components/sheet.d.cts +1 -1
- package/dist/components/sheet.d.ts +1 -1
- package/dist/utils/external-link.cjs +44 -0
- package/dist/utils/external-link.cjs.map +1 -0
- package/dist/utils/external-link.d.cts +4 -0
- package/dist/utils/external-link.d.ts +4 -0
- package/dist/utils/external-link.js +19 -0
- package/dist/utils/external-link.js.map +1 -0
- package/dist/utils/use-collections.cjs +1 -2
- package/dist/utils/use-collections.cjs.map +1 -1
- package/dist/utils/use-collections.d.cts +3 -0
- package/dist/utils/use-collections.d.ts +3 -0
- package/dist/utils/use-collections.js +1 -2
- package/dist/utils/use-collections.js.map +1 -1
- package/dist/utils/use-tokens-by-ip-type.d.cts +2 -0
- package/dist/utils/use-tokens-by-ip-type.d.ts +2 -0
- package/dist/utils/use-tokens.d.cts +4 -0
- package/dist/utils/use-tokens.d.ts +4 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-publication.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"./button.js\";\n\nexport interface AssetPublicationProps {\n name: string;\n text: string;\n image: string | null;\n imgError: boolean;\n onImageError: () => void;\n onZoom: () => void;\n author?: string | null;\n
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-publication.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"./button.js\";\nimport { externalLink } from \"../utils/external-link.js\";\n\nexport interface AssetPublicationProps {\n name: string;\n text: string;\n image: string | null;\n imgError: boolean;\n onImageError: () => void;\n onZoom: () => void;\n author?: string | null;\n externalUrl?: string | null;\n}\n\nexport function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }: AssetPublicationProps) {\n const link = externalLink(externalUrl);\n const paragraphs = text.split(/\\n{2,}/).map((p) => p.trim()).filter(Boolean);\n const [lead, ...body] = paragraphs.length > 1 ? paragraphs : [null, ...paragraphs];\n\n return (\n <article className=\"min-w-0 space-y-6\">\n <header className=\"space-y-3\">\n <h1 className=\"text-2xl lg:text-4xl font-bold leading-tight break-words\">{name}</h1>\n </header>\n\n {lead ? <p className=\"max-w-3xl text-base leading-relaxed text-foreground whitespace-pre-line\">{lead}</p> : null}\n\n {image && !imgError ? (\n <button type=\"button\" onClick={onZoom} aria-label=\"View full image\" className=\"block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\">\n <img src={image} alt={name} onError={onImageError} className=\"w-full h-auto max-h-[80vh] object-contain\" />\n </button>\n ) : null}\n\n <div className=\"max-w-3xl space-y-4 text-sm leading-relaxed text-foreground/85 break-words\">\n {body.map((paragraph, i) => (\n <p key={i} className=\"whitespace-pre-line\">{paragraph}</p>\n ))}\n </div>\n\n {author || link ? (\n <div className=\"flex flex-wrap items-center gap-4\">\n {author ? <p className=\"min-w-0 break-words text-sm text-muted-foreground\">{author}</p> : null}\n {link ? (\n <Button asChild variant=\"outline\">\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\">\n Read more\n <ExternalLink />\n </a>\n </Button>\n ) : null}\n </div>\n ) : null}\n </article>\n );\n}\n"],"mappings":";AAyBQ,cAsBM,YAtBN;AAvBR,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAatB,SAAS,iBAAiB,EAAE,MAAM,MAAM,OAAO,UAAU,cAAc,QAAQ,QAAQ,YAAY,GAA0B;AAClI,QAAM,OAAO,aAAa,WAAW;AACrC,QAAM,aAAa,KAAK,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAC3E,QAAM,CAAC,MAAM,GAAG,IAAI,IAAI,WAAW,SAAS,IAAI,aAAa,CAAC,MAAM,GAAG,UAAU;AAEjF,SACE,qBAAC,aAAQ,WAAU,qBACjB;AAAA,wBAAC,YAAO,WAAU,aAChB,8BAAC,QAAG,WAAU,4DAA4D,gBAAK,GACjF;AAAA,IAEC,OAAO,oBAAC,OAAE,WAAU,2EAA2E,gBAAK,IAAO;AAAA,IAE3G,SAAS,CAAC,WACT,oBAAC,YAAO,MAAK,UAAS,SAAS,QAAQ,cAAW,mBAAkB,WAAU,8EAC5E,8BAAC,SAAI,KAAK,OAAO,KAAK,MAAM,SAAS,cAAc,WAAU,6CAA4C,GAC3G,IACE;AAAA,IAEJ,oBAAC,SAAI,WAAU,8EACZ,eAAK,IAAI,CAAC,WAAW,MACpB,oBAAC,OAAU,WAAU,uBAAuB,uBAApC,CAA8C,CACvD,GACH;AAAA,IAEC,UAAU,OACT,qBAAC,SAAI,WAAU,qCACZ;AAAA,eAAS,oBAAC,OAAE,WAAU,qDAAqD,kBAAO,IAAO;AAAA,MACzF,OACC,oBAAC,UAAO,SAAO,MAAC,SAAQ,WACtB,+BAAC,OAAE,MAAM,MAAM,QAAO,UAAS,KAAI,uBAAsB;AAAA;AAAA,QAEvD,oBAAC,gBAAa;AAAA,SAChB,GACF,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;","names":[]}
|
|
@@ -44,6 +44,8 @@ var import_address_display = require("./address-display.js");
|
|
|
44
44
|
var import_parent_attribution_banner = require("./parent-attribution-banner.js");
|
|
45
45
|
var import_ip_type_badge = require("./ip-type-badge.js");
|
|
46
46
|
var import_expandable_text = require("./expandable-text.js");
|
|
47
|
+
var import_lucide_react = require("lucide-react");
|
|
48
|
+
var import_external_link = require("../utils/external-link.js");
|
|
47
49
|
function AssetMediaColumn({
|
|
48
50
|
shouldReduce,
|
|
49
51
|
image,
|
|
@@ -137,10 +139,12 @@ function AssetHeaderBlock({
|
|
|
137
139
|
badges,
|
|
138
140
|
utilities,
|
|
139
141
|
description,
|
|
142
|
+
externalUrl,
|
|
140
143
|
ipType,
|
|
141
144
|
parentContract,
|
|
142
145
|
parentTokenId
|
|
143
146
|
}) {
|
|
147
|
+
const link = (0, import_external_link.externalLink)(externalUrl);
|
|
144
148
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
145
149
|
ipType || badges || utilities ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between gap-2 mb-2", children: [
|
|
146
150
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
@@ -158,7 +162,11 @@ function AssetHeaderBlock({
|
|
|
158
162
|
}
|
|
159
163
|
) }) : null,
|
|
160
164
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { className: "text-2xl lg:text-4xl font-bold break-words", children: name }),
|
|
161
|
-
description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_expandable_text.ExpandableText, { text: description, className: "mt-1" }) : null
|
|
165
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_expandable_text.ExpandableText, { text: description, className: "mt-1" }) : null,
|
|
166
|
+
link ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("a", { href: link, target: "_blank", rel: "noopener noreferrer", className: "mt-3 inline-flex items-center gap-1.5 text-sm text-primary hover:underline", children: [
|
|
167
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ExternalLink, { className: "h-3.5 w-3.5" }),
|
|
168
|
+
"Open link"
|
|
169
|
+
] }) : null
|
|
162
170
|
] });
|
|
163
171
|
}
|
|
164
172
|
function AssetOwnerRow({ ownerAddress, ownerHref }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-top-sections.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { useEffect, useState } from \"react\";\nimport { motion } from \"framer-motion\";\nimport { useIntersectionActive } from \"../utils/use-intersection-active.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { ParentAttributionBanner } from \"./parent-attribution-banner.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { ExpandableText } from \"./expandable-text.js\";\n\ninterface AssetMediaColumnProps {\n shouldReduce: boolean;\n image: string | null;\n imageAlt: string;\n imgError: boolean;\n onImageError: () => void;\n fallback: React.ReactNode;\n\n onZoom?: () => void;\n\n animationUrl?: string | null;\n\n live?: boolean;\n}\n\nexport function AssetMediaColumn({\n shouldReduce,\n image,\n imageAlt,\n imgError,\n onImageError,\n fallback,\n onZoom,\n animationUrl,\n live = false,\n}: AssetMediaColumnProps) {\n const [ref, isVisible] = useIntersectionActive<HTMLDivElement>();\n const [loaded, setLoaded] = useState(false);\n useEffect(() => setLoaded(false), [image]);\n const showLive = live && !!animationUrl && isVisible;\n\n const shimmer = !loaded && (\n <div\n className=\"absolute inset-0 min-h-80 animate-[shimmer_1.6s_ease-in-out_infinite] bg-foreground/[0.06]\"\n style={{\n backgroundImage:\n \"linear-gradient(90deg, transparent, color-mix(in srgb, var(--foreground) 8%, transparent), transparent)\",\n backgroundSize: \"200% 100%\",\n }}\n />\n );\n\n return (\n <div ref={ref} className=\"w-full lg:sticky lg:top-16\">\n {showLive ? (\n <div className=\"w-full overflow-hidden rounded-3xl aspect-square\">\n <iframe\n src={animationUrl!}\n title={imageAlt}\n sandbox=\"allow-scripts\"\n loading=\"lazy\"\n className=\"w-full h-full border-0\"\n />\n </div>\n ) : !image || imgError ? (\n <div className=\"w-full overflow-hidden rounded-3xl\">{fallback}</div>\n ) : onZoom ? (\n <motion.button\n type=\"button\"\n onClick={onZoom}\n aria-label=\"View full image\"\n initial={shouldReduce ? false : { opacity: 0, scale: 0.98 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.5 }}\n className=\"group relative block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\"\n >\n {shimmer}\n <img\n src={image}\n alt={imageAlt}\n onLoad={() => setLoaded(true)}\n onError={onImageError}\n className={cn(\n \"w-full h-auto max-h-[80vh] object-contain\",\n \"transition-opacity duration-300 group-hover:opacity-95 group-active:scale-[0.99]\",\n loaded ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </motion.button>\n ) : (\n <motion.div\n initial={shouldReduce ? false : { opacity: 0, scale: 0.98 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.5 }}\n className=\"relative block w-full overflow-hidden rounded-3xl\"\n >\n {shimmer}\n <img\n src={image}\n alt={imageAlt}\n onLoad={() => setLoaded(true)}\n onError={onImageError}\n className={cn(\n \"w-full h-auto max-h-[80vh] object-contain transition-opacity duration-300\",\n loaded ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </motion.div>\n )}\n\n </div>\n );\n}\n\ninterface AssetHeaderBlockProps {\n name: string;\n badges?: React.ReactNode;\n utilities?: React.ReactNode;\n description?: string | null;\n ipType?: string | null;\n parentContract?: string | null;\n parentTokenId?: string | null;\n}\n\nexport function AssetHeaderBlock({\n name,\n badges,\n utilities,\n description,\n ipType,\n parentContract,\n parentTokenId,\n}: AssetHeaderBlockProps) {\n return (\n <div className=\"min-w-0 flex-1\">\n {ipType || badges || utilities ? (\n <div className=\"flex items-center justify-between gap-2 mb-2\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n {ipType ? <IpTypeBadge ipType={ipType} size=\"md\" showLabel /> : null}\n {badges}\n </div>\n {utilities}\n </div>\n ) : null}\n {parentContract && parentTokenId ? (\n <div className=\"mb-3\">\n <ParentAttributionBanner\n parentContract={parentContract}\n parentTokenId={parentTokenId}\n parentName={`Token #${parentTokenId}`}\n />\n </div>\n ) : null}\n <h1 className=\"text-2xl lg:text-4xl font-bold break-words\">{name}</h1>\n {description ? <ExpandableText text={description} className=\"mt-1\" /> : null}\n </div>\n );\n}\n\nexport interface AssetOwnerRowProps {\n ownerAddress: string;\n ownerHref: string;\n}\n\nexport function AssetOwnerRow({ ownerAddress, ownerHref }: AssetOwnerRowProps) {\n return (\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n <span>Owner</span>\n <Link href={ownerHref} className=\"hover:text-primary transition-colors font-medium\">\n <AddressDisplay address={ownerAddress} />\n </Link>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-top-sections.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { useEffect, useState } from \"react\";\nimport { motion } from \"framer-motion\";\nimport { useIntersectionActive } from \"../utils/use-intersection-active.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { ParentAttributionBanner } from \"./parent-attribution-banner.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { ExpandableText } from \"./expandable-text.js\";\nimport { ExternalLink } from \"lucide-react\";\nimport { externalLink } from \"../utils/external-link.js\";\n\ninterface AssetMediaColumnProps {\n shouldReduce: boolean;\n image: string | null;\n imageAlt: string;\n imgError: boolean;\n onImageError: () => void;\n fallback: React.ReactNode;\n\n onZoom?: () => void;\n\n animationUrl?: string | null;\n\n live?: boolean;\n}\n\nexport function AssetMediaColumn({\n shouldReduce,\n image,\n imageAlt,\n imgError,\n onImageError,\n fallback,\n onZoom,\n animationUrl,\n live = false,\n}: AssetMediaColumnProps) {\n const [ref, isVisible] = useIntersectionActive<HTMLDivElement>();\n const [loaded, setLoaded] = useState(false);\n useEffect(() => setLoaded(false), [image]);\n const showLive = live && !!animationUrl && isVisible;\n\n const shimmer = !loaded && (\n <div\n className=\"absolute inset-0 min-h-80 animate-[shimmer_1.6s_ease-in-out_infinite] bg-foreground/[0.06]\"\n style={{\n backgroundImage:\n \"linear-gradient(90deg, transparent, color-mix(in srgb, var(--foreground) 8%, transparent), transparent)\",\n backgroundSize: \"200% 100%\",\n }}\n />\n );\n\n return (\n <div ref={ref} className=\"w-full lg:sticky lg:top-16\">\n {showLive ? (\n <div className=\"w-full overflow-hidden rounded-3xl aspect-square\">\n <iframe\n src={animationUrl!}\n title={imageAlt}\n sandbox=\"allow-scripts\"\n loading=\"lazy\"\n className=\"w-full h-full border-0\"\n />\n </div>\n ) : !image || imgError ? (\n <div className=\"w-full overflow-hidden rounded-3xl\">{fallback}</div>\n ) : onZoom ? (\n <motion.button\n type=\"button\"\n onClick={onZoom}\n aria-label=\"View full image\"\n initial={shouldReduce ? false : { opacity: 0, scale: 0.98 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.5 }}\n className=\"group relative block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\"\n >\n {shimmer}\n <img\n src={image}\n alt={imageAlt}\n onLoad={() => setLoaded(true)}\n onError={onImageError}\n className={cn(\n \"w-full h-auto max-h-[80vh] object-contain\",\n \"transition-opacity duration-300 group-hover:opacity-95 group-active:scale-[0.99]\",\n loaded ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </motion.button>\n ) : (\n <motion.div\n initial={shouldReduce ? false : { opacity: 0, scale: 0.98 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.5 }}\n className=\"relative block w-full overflow-hidden rounded-3xl\"\n >\n {shimmer}\n <img\n src={image}\n alt={imageAlt}\n onLoad={() => setLoaded(true)}\n onError={onImageError}\n className={cn(\n \"w-full h-auto max-h-[80vh] object-contain transition-opacity duration-300\",\n loaded ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </motion.div>\n )}\n\n </div>\n );\n}\n\ninterface AssetHeaderBlockProps {\n name: string;\n badges?: React.ReactNode;\n utilities?: React.ReactNode;\n description?: string | null;\n externalUrl?: string | null;\n ipType?: string | null;\n parentContract?: string | null;\n parentTokenId?: string | null;\n}\n\nexport function AssetHeaderBlock({\n name,\n badges,\n utilities,\n description,\n externalUrl,\n ipType,\n parentContract,\n parentTokenId,\n}: AssetHeaderBlockProps) {\n const link = externalLink(externalUrl);\n return (\n <div className=\"min-w-0 flex-1\">\n {ipType || badges || utilities ? (\n <div className=\"flex items-center justify-between gap-2 mb-2\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n {ipType ? <IpTypeBadge ipType={ipType} size=\"md\" showLabel /> : null}\n {badges}\n </div>\n {utilities}\n </div>\n ) : null}\n {parentContract && parentTokenId ? (\n <div className=\"mb-3\">\n <ParentAttributionBanner\n parentContract={parentContract}\n parentTokenId={parentTokenId}\n parentName={`Token #${parentTokenId}`}\n />\n </div>\n ) : null}\n <h1 className=\"text-2xl lg:text-4xl font-bold break-words\">{name}</h1>\n {description ? <ExpandableText text={description} className=\"mt-1\" /> : null}\n {link ? (\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\" className=\"mt-3 inline-flex items-center gap-1.5 text-sm text-primary hover:underline\">\n <ExternalLink className=\"h-3.5 w-3.5\" />\n Open link\n </a>\n ) : null}\n </div>\n );\n}\n\nexport interface AssetOwnerRowProps {\n ownerAddress: string;\n ownerHref: string;\n}\n\nexport function AssetOwnerRow({ ownerAddress, ownerHref }: AssetOwnerRowProps) {\n return (\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n <span>Owner</span>\n <Link href={ownerHref} className=\"hover:text-primary transition-colors font-medium\">\n <AddressDisplay address={ownerAddress} />\n </Link>\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
|
|
@@ -17,11 +17,12 @@ interface AssetHeaderBlockProps {
|
|
|
17
17
|
badges?: React.ReactNode;
|
|
18
18
|
utilities?: React.ReactNode;
|
|
19
19
|
description?: string | null;
|
|
20
|
+
externalUrl?: string | null;
|
|
20
21
|
ipType?: string | null;
|
|
21
22
|
parentContract?: string | null;
|
|
22
23
|
parentTokenId?: string | null;
|
|
23
24
|
}
|
|
24
|
-
declare function AssetHeaderBlock({ name, badges, utilities, description, ipType, parentContract, parentTokenId, }: AssetHeaderBlockProps): react_jsx_runtime.JSX.Element;
|
|
25
|
+
declare function AssetHeaderBlock({ name, badges, utilities, description, externalUrl, ipType, parentContract, parentTokenId, }: AssetHeaderBlockProps): react_jsx_runtime.JSX.Element;
|
|
25
26
|
interface AssetOwnerRowProps {
|
|
26
27
|
ownerAddress: string;
|
|
27
28
|
ownerHref: string;
|
|
@@ -17,11 +17,12 @@ interface AssetHeaderBlockProps {
|
|
|
17
17
|
badges?: React.ReactNode;
|
|
18
18
|
utilities?: React.ReactNode;
|
|
19
19
|
description?: string | null;
|
|
20
|
+
externalUrl?: string | null;
|
|
20
21
|
ipType?: string | null;
|
|
21
22
|
parentContract?: string | null;
|
|
22
23
|
parentTokenId?: string | null;
|
|
23
24
|
}
|
|
24
|
-
declare function AssetHeaderBlock({ name, badges, utilities, description, ipType, parentContract, parentTokenId, }: AssetHeaderBlockProps): react_jsx_runtime.JSX.Element;
|
|
25
|
+
declare function AssetHeaderBlock({ name, badges, utilities, description, externalUrl, ipType, parentContract, parentTokenId, }: AssetHeaderBlockProps): react_jsx_runtime.JSX.Element;
|
|
25
26
|
interface AssetOwnerRowProps {
|
|
26
27
|
ownerAddress: string;
|
|
27
28
|
ownerHref: string;
|
|
@@ -9,6 +9,8 @@ import { AddressDisplay } from "./address-display.js";
|
|
|
9
9
|
import { ParentAttributionBanner } from "./parent-attribution-banner.js";
|
|
10
10
|
import { IpTypeBadge } from "./ip-type-badge.js";
|
|
11
11
|
import { ExpandableText } from "./expandable-text.js";
|
|
12
|
+
import { ExternalLink } from "lucide-react";
|
|
13
|
+
import { externalLink } from "../utils/external-link.js";
|
|
12
14
|
function AssetMediaColumn({
|
|
13
15
|
shouldReduce,
|
|
14
16
|
image,
|
|
@@ -102,10 +104,12 @@ function AssetHeaderBlock({
|
|
|
102
104
|
badges,
|
|
103
105
|
utilities,
|
|
104
106
|
description,
|
|
107
|
+
externalUrl,
|
|
105
108
|
ipType,
|
|
106
109
|
parentContract,
|
|
107
110
|
parentTokenId
|
|
108
111
|
}) {
|
|
112
|
+
const link = externalLink(externalUrl);
|
|
109
113
|
return /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
110
114
|
ipType || badges || utilities ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 mb-2", children: [
|
|
111
115
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
@@ -123,7 +127,11 @@ function AssetHeaderBlock({
|
|
|
123
127
|
}
|
|
124
128
|
) }) : null,
|
|
125
129
|
/* @__PURE__ */ jsx("h1", { className: "text-2xl lg:text-4xl font-bold break-words", children: name }),
|
|
126
|
-
description ? /* @__PURE__ */ jsx(ExpandableText, { text: description, className: "mt-1" }) : null
|
|
130
|
+
description ? /* @__PURE__ */ jsx(ExpandableText, { text: description, className: "mt-1" }) : null,
|
|
131
|
+
link ? /* @__PURE__ */ jsxs("a", { href: link, target: "_blank", rel: "noopener noreferrer", className: "mt-3 inline-flex items-center gap-1.5 text-sm text-primary hover:underline", children: [
|
|
132
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "h-3.5 w-3.5" }),
|
|
133
|
+
"Open link"
|
|
134
|
+
] }) : null
|
|
127
135
|
] });
|
|
128
136
|
}
|
|
129
137
|
function AssetOwnerRow({ ownerAddress, ownerHref }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-top-sections.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { useEffect, useState } from \"react\";\nimport { motion } from \"framer-motion\";\nimport { useIntersectionActive } from \"../utils/use-intersection-active.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { ParentAttributionBanner } from \"./parent-attribution-banner.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { ExpandableText } from \"./expandable-text.js\";\n\ninterface AssetMediaColumnProps {\n shouldReduce: boolean;\n image: string | null;\n imageAlt: string;\n imgError: boolean;\n onImageError: () => void;\n fallback: React.ReactNode;\n\n onZoom?: () => void;\n\n animationUrl?: string | null;\n\n live?: boolean;\n}\n\nexport function AssetMediaColumn({\n shouldReduce,\n image,\n imageAlt,\n imgError,\n onImageError,\n fallback,\n onZoom,\n animationUrl,\n live = false,\n}: AssetMediaColumnProps) {\n const [ref, isVisible] = useIntersectionActive<HTMLDivElement>();\n const [loaded, setLoaded] = useState(false);\n useEffect(() => setLoaded(false), [image]);\n const showLive = live && !!animationUrl && isVisible;\n\n const shimmer = !loaded && (\n <div\n className=\"absolute inset-0 min-h-80 animate-[shimmer_1.6s_ease-in-out_infinite] bg-foreground/[0.06]\"\n style={{\n backgroundImage:\n \"linear-gradient(90deg, transparent, color-mix(in srgb, var(--foreground) 8%, transparent), transparent)\",\n backgroundSize: \"200% 100%\",\n }}\n />\n );\n\n return (\n <div ref={ref} className=\"w-full lg:sticky lg:top-16\">\n {showLive ? (\n <div className=\"w-full overflow-hidden rounded-3xl aspect-square\">\n <iframe\n src={animationUrl!}\n title={imageAlt}\n sandbox=\"allow-scripts\"\n loading=\"lazy\"\n className=\"w-full h-full border-0\"\n />\n </div>\n ) : !image || imgError ? (\n <div className=\"w-full overflow-hidden rounded-3xl\">{fallback}</div>\n ) : onZoom ? (\n <motion.button\n type=\"button\"\n onClick={onZoom}\n aria-label=\"View full image\"\n initial={shouldReduce ? false : { opacity: 0, scale: 0.98 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.5 }}\n className=\"group relative block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\"\n >\n {shimmer}\n <img\n src={image}\n alt={imageAlt}\n onLoad={() => setLoaded(true)}\n onError={onImageError}\n className={cn(\n \"w-full h-auto max-h-[80vh] object-contain\",\n \"transition-opacity duration-300 group-hover:opacity-95 group-active:scale-[0.99]\",\n loaded ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </motion.button>\n ) : (\n <motion.div\n initial={shouldReduce ? false : { opacity: 0, scale: 0.98 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.5 }}\n className=\"relative block w-full overflow-hidden rounded-3xl\"\n >\n {shimmer}\n <img\n src={image}\n alt={imageAlt}\n onLoad={() => setLoaded(true)}\n onError={onImageError}\n className={cn(\n \"w-full h-auto max-h-[80vh] object-contain transition-opacity duration-300\",\n loaded ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </motion.div>\n )}\n\n </div>\n );\n}\n\ninterface AssetHeaderBlockProps {\n name: string;\n badges?: React.ReactNode;\n utilities?: React.ReactNode;\n description?: string | null;\n ipType?: string | null;\n parentContract?: string | null;\n parentTokenId?: string | null;\n}\n\nexport function AssetHeaderBlock({\n name,\n badges,\n utilities,\n description,\n ipType,\n parentContract,\n parentTokenId,\n}: AssetHeaderBlockProps) {\n return (\n <div className=\"min-w-0 flex-1\">\n {ipType || badges || utilities ? (\n <div className=\"flex items-center justify-between gap-2 mb-2\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n {ipType ? <IpTypeBadge ipType={ipType} size=\"md\" showLabel /> : null}\n {badges}\n </div>\n {utilities}\n </div>\n ) : null}\n {parentContract && parentTokenId ? (\n <div className=\"mb-3\">\n <ParentAttributionBanner\n parentContract={parentContract}\n parentTokenId={parentTokenId}\n parentName={`Token #${parentTokenId}`}\n />\n </div>\n ) : null}\n <h1 className=\"text-2xl lg:text-4xl font-bold break-words\">{name}</h1>\n {description ? <ExpandableText text={description} className=\"mt-1\" /> : null}\n </div>\n );\n}\n\nexport interface AssetOwnerRowProps {\n ownerAddress: string;\n ownerHref: string;\n}\n\nexport function AssetOwnerRow({ ownerAddress, ownerHref }: AssetOwnerRowProps) {\n return (\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n <span>Owner</span>\n <Link href={ownerHref} className=\"hover:text-primary transition-colors font-medium\">\n <AddressDisplay address={ownerAddress} />\n </Link>\n </div>\n );\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-top-sections.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { useEffect, useState } from \"react\";\nimport { motion } from \"framer-motion\";\nimport { useIntersectionActive } from \"../utils/use-intersection-active.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { ParentAttributionBanner } from \"./parent-attribution-banner.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { ExpandableText } from \"./expandable-text.js\";\nimport { ExternalLink } from \"lucide-react\";\nimport { externalLink } from \"../utils/external-link.js\";\n\ninterface AssetMediaColumnProps {\n shouldReduce: boolean;\n image: string | null;\n imageAlt: string;\n imgError: boolean;\n onImageError: () => void;\n fallback: React.ReactNode;\n\n onZoom?: () => void;\n\n animationUrl?: string | null;\n\n live?: boolean;\n}\n\nexport function AssetMediaColumn({\n shouldReduce,\n image,\n imageAlt,\n imgError,\n onImageError,\n fallback,\n onZoom,\n animationUrl,\n live = false,\n}: AssetMediaColumnProps) {\n const [ref, isVisible] = useIntersectionActive<HTMLDivElement>();\n const [loaded, setLoaded] = useState(false);\n useEffect(() => setLoaded(false), [image]);\n const showLive = live && !!animationUrl && isVisible;\n\n const shimmer = !loaded && (\n <div\n className=\"absolute inset-0 min-h-80 animate-[shimmer_1.6s_ease-in-out_infinite] bg-foreground/[0.06]\"\n style={{\n backgroundImage:\n \"linear-gradient(90deg, transparent, color-mix(in srgb, var(--foreground) 8%, transparent), transparent)\",\n backgroundSize: \"200% 100%\",\n }}\n />\n );\n\n return (\n <div ref={ref} className=\"w-full lg:sticky lg:top-16\">\n {showLive ? (\n <div className=\"w-full overflow-hidden rounded-3xl aspect-square\">\n <iframe\n src={animationUrl!}\n title={imageAlt}\n sandbox=\"allow-scripts\"\n loading=\"lazy\"\n className=\"w-full h-full border-0\"\n />\n </div>\n ) : !image || imgError ? (\n <div className=\"w-full overflow-hidden rounded-3xl\">{fallback}</div>\n ) : onZoom ? (\n <motion.button\n type=\"button\"\n onClick={onZoom}\n aria-label=\"View full image\"\n initial={shouldReduce ? false : { opacity: 0, scale: 0.98 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.5 }}\n className=\"group relative block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\"\n >\n {shimmer}\n <img\n src={image}\n alt={imageAlt}\n onLoad={() => setLoaded(true)}\n onError={onImageError}\n className={cn(\n \"w-full h-auto max-h-[80vh] object-contain\",\n \"transition-opacity duration-300 group-hover:opacity-95 group-active:scale-[0.99]\",\n loaded ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </motion.button>\n ) : (\n <motion.div\n initial={shouldReduce ? false : { opacity: 0, scale: 0.98 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.5 }}\n className=\"relative block w-full overflow-hidden rounded-3xl\"\n >\n {shimmer}\n <img\n src={image}\n alt={imageAlt}\n onLoad={() => setLoaded(true)}\n onError={onImageError}\n className={cn(\n \"w-full h-auto max-h-[80vh] object-contain transition-opacity duration-300\",\n loaded ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n </motion.div>\n )}\n\n </div>\n );\n}\n\ninterface AssetHeaderBlockProps {\n name: string;\n badges?: React.ReactNode;\n utilities?: React.ReactNode;\n description?: string | null;\n externalUrl?: string | null;\n ipType?: string | null;\n parentContract?: string | null;\n parentTokenId?: string | null;\n}\n\nexport function AssetHeaderBlock({\n name,\n badges,\n utilities,\n description,\n externalUrl,\n ipType,\n parentContract,\n parentTokenId,\n}: AssetHeaderBlockProps) {\n const link = externalLink(externalUrl);\n return (\n <div className=\"min-w-0 flex-1\">\n {ipType || badges || utilities ? (\n <div className=\"flex items-center justify-between gap-2 mb-2\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n {ipType ? <IpTypeBadge ipType={ipType} size=\"md\" showLabel /> : null}\n {badges}\n </div>\n {utilities}\n </div>\n ) : null}\n {parentContract && parentTokenId ? (\n <div className=\"mb-3\">\n <ParentAttributionBanner\n parentContract={parentContract}\n parentTokenId={parentTokenId}\n parentName={`Token #${parentTokenId}`}\n />\n </div>\n ) : null}\n <h1 className=\"text-2xl lg:text-4xl font-bold break-words\">{name}</h1>\n {description ? <ExpandableText text={description} className=\"mt-1\" /> : null}\n {link ? (\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\" className=\"mt-3 inline-flex items-center gap-1.5 text-sm text-primary hover:underline\">\n <ExternalLink className=\"h-3.5 w-3.5\" />\n Open link\n </a>\n ) : null}\n </div>\n );\n}\n\nexport interface AssetOwnerRowProps {\n ownerAddress: string;\n ownerHref: string;\n}\n\nexport function AssetOwnerRow({ ownerAddress, ownerHref }: AssetOwnerRowProps) {\n return (\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n <span>Owner</span>\n <Link href={ownerHref} className=\"hover:text-primary transition-colors font-medium\">\n <AddressDisplay address={ownerAddress} />\n </Link>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,8 +3,8 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const buttonVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
7
|
-
size?: "
|
|
6
|
+
variant?: "ghost" | "link" | "default" | "destructive" | "outline" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
|
|
7
|
+
size?: "icon" | "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
10
10
|
asChild?: boolean;
|
|
@@ -3,8 +3,8 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const buttonVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
7
|
-
size?: "
|
|
6
|
+
variant?: "ghost" | "link" | "default" | "destructive" | "outline" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
|
|
7
|
+
size?: "icon" | "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
10
10
|
asChild?: boolean;
|
|
@@ -59,8 +59,7 @@ function CollectionCard({ collection, href, settingsHref, className }) {
|
|
|
59
59
|
const showImage = imageUrl && !imgError;
|
|
60
60
|
const initial = (collection.name ?? collection.contractAddress).charAt(0).toUpperCase();
|
|
61
61
|
const floor = parseFloorPrice(collection.floorPrice);
|
|
62
|
-
|
|
63
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)(hasExclusiveContent && "card-exclusive-wrapper btn-border-animated"), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_motion_primitives.MotionCard, { className: (0, import_cn.cn)("card-base group relative", className), children: [
|
|
62
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_motion_primitives.MotionCard, { className: (0, import_cn.cn)("card-base group relative", className), children: [
|
|
64
63
|
settingsHref && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
65
64
|
import_link.default,
|
|
66
65
|
{
|
|
@@ -83,33 +82,26 @@ function CollectionCard({ collection, href, settingsHref, className }) {
|
|
|
83
82
|
unoptimized: true
|
|
84
83
|
}
|
|
85
84
|
) : /* @__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 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-8xl font-black text-white/10 select-none tracking-tighter", children: initial }) }),
|
|
86
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute
|
|
87
|
-
!collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1 text-2xs text-white/
|
|
85
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute inset-x-0 bottom-0 flex flex-col items-start gap-1 bg-gradient-to-t from-black/85 via-black/45 to-transparent px-3 pb-3 pt-14", children: [
|
|
86
|
+
!collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-1 text-2xs text-white/70", children: [
|
|
88
87
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-2.5 w-2.5 animate-spin" }),
|
|
89
88
|
"Indexing\u2026"
|
|
90
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
91
|
-
|
|
92
|
-
{
|
|
93
|
-
className: "font-bold text-sm text-white leading-tight backdrop-blur-md bg-black/30 rounded-lg px-2.5 py-1 max-w-full truncate",
|
|
94
|
-
style: { textShadow: "0 1px 6px rgba(0,0,0,0.5)" },
|
|
95
|
-
children: collection.name ?? "Unnamed Collection"
|
|
96
|
-
}
|
|
97
|
-
),
|
|
98
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
|
|
99
|
-
collection.totalSupply != null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-2xs font-medium text-white/80 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5", children: [
|
|
89
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "max-w-full truncate text-sm font-bold leading-tight text-white", children: collection.name ?? "Unnamed Collection" }),
|
|
90
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-x-2.5 gap-y-0.5 text-2xs font-medium text-white/80", children: [
|
|
91
|
+
collection.totalSupply != null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
100
92
|
collection.totalSupply.toLocaleString(),
|
|
101
|
-
"
|
|
93
|
+
" ",
|
|
94
|
+
collection.totalSupply === 1 ? "item" : "items"
|
|
102
95
|
] }),
|
|
103
|
-
floor && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1
|
|
96
|
+
floor && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1 font-bold text-white/90", children: [
|
|
104
97
|
"Floor",
|
|
105
98
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: floor.symbol, size: 10 }),
|
|
106
99
|
floor.amount
|
|
107
|
-
] })
|
|
108
|
-
hasExclusiveContent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "inline-flex items-center gap-1 text-2xs font-bold text-white backdrop-blur-md bg-black/50 rounded-full px-2 py-0.5", children: "\u2726 Exclusive" })
|
|
100
|
+
] })
|
|
109
101
|
] })
|
|
110
102
|
] })
|
|
111
103
|
] }) })
|
|
112
|
-
] })
|
|
104
|
+
] });
|
|
113
105
|
}
|
|
114
106
|
function CollectionCardSkeleton() {
|
|
115
107
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "card-base overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative aspect-square w-full overflow-hidden bg-muted", children: [
|
|
@@ -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\
|
|
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 initial = (collection.name ?? collection.contractAddress).charAt(0).toUpperCase();\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 flex items-center justify-center\">\n <span className=\"text-8xl font-black text-white/10 select-none tracking-tighter\">\n {initial}\n </span>\n </div>\n )}\n\n <div className=\"absolute inset-x-0 bottom-0 flex flex-col items-start gap-1 bg-gradient-to-t from-black/85 via-black/45 to-transparent px-3 pb-3 pt-14\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 text-2xs text-white/70\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p className=\"max-w-full truncate text-sm font-bold leading-tight text-white\">\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n <div className=\"flex flex-wrap items-center gap-x-2.5 gap-y-0.5 text-2xs font-medium text-white/80\">\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/90\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n </div>\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":"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","names":["Link","Image"]}
|
|
@@ -25,8 +25,7 @@ function CollectionCard({ collection, href, settingsHref, className }) {
|
|
|
25
25
|
const showImage = imageUrl && !imgError;
|
|
26
26
|
const initial = (collection.name ?? collection.contractAddress).charAt(0).toUpperCase();
|
|
27
27
|
const floor = parseFloorPrice(collection.floorPrice);
|
|
28
|
-
|
|
29
|
-
return /* @__PURE__ */ jsx("div", { className: cn(hasExclusiveContent && "card-exclusive-wrapper btn-border-animated"), children: /* @__PURE__ */ jsxs(MotionCard, { className: cn("card-base group relative", className), children: [
|
|
28
|
+
return /* @__PURE__ */ jsxs(MotionCard, { className: cn("card-base group relative", className), children: [
|
|
30
29
|
settingsHref && /* @__PURE__ */ jsx(
|
|
31
30
|
Link,
|
|
32
31
|
{
|
|
@@ -49,33 +48,26 @@ function CollectionCard({ collection, href, settingsHref, className }) {
|
|
|
49
48
|
unoptimized: true
|
|
50
49
|
}
|
|
51
50
|
) : /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40 flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "text-8xl font-black text-white/10 select-none tracking-tighter", children: initial }) }),
|
|
52
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute
|
|
53
|
-
!collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-2xs text-white/
|
|
51
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute inset-x-0 bottom-0 flex flex-col items-start gap-1 bg-gradient-to-t from-black/85 via-black/45 to-transparent px-3 pb-3 pt-14", children: [
|
|
52
|
+
!collection.name && collection.metadataStatus === "PENDING" ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-2xs text-white/70", children: [
|
|
54
53
|
/* @__PURE__ */ jsx(Loader2, { className: "h-2.5 w-2.5 animate-spin" }),
|
|
55
54
|
"Indexing\u2026"
|
|
56
|
-
] }) : /* @__PURE__ */ jsx(
|
|
57
|
-
|
|
58
|
-
{
|
|
59
|
-
className: "font-bold text-sm text-white leading-tight backdrop-blur-md bg-black/30 rounded-lg px-2.5 py-1 max-w-full truncate",
|
|
60
|
-
style: { textShadow: "0 1px 6px rgba(0,0,0,0.5)" },
|
|
61
|
-
children: collection.name ?? "Unnamed Collection"
|
|
62
|
-
}
|
|
63
|
-
),
|
|
64
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
|
|
65
|
-
collection.totalSupply != null && /* @__PURE__ */ jsxs("span", { className: "text-2xs font-medium text-white/80 backdrop-blur-md bg-black/30 rounded-full px-2 py-0.5", children: [
|
|
55
|
+
] }) : /* @__PURE__ */ jsx("p", { className: "max-w-full truncate text-sm font-bold leading-tight text-white", children: collection.name ?? "Unnamed Collection" }),
|
|
56
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-2.5 gap-y-0.5 text-2xs font-medium text-white/80", children: [
|
|
57
|
+
collection.totalSupply != null && /* @__PURE__ */ jsxs("span", { children: [
|
|
66
58
|
collection.totalSupply.toLocaleString(),
|
|
67
|
-
"
|
|
59
|
+
" ",
|
|
60
|
+
collection.totalSupply === 1 ? "item" : "items"
|
|
68
61
|
] }),
|
|
69
|
-
floor && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1
|
|
62
|
+
floor && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 font-bold text-white/90", children: [
|
|
70
63
|
"Floor",
|
|
71
64
|
/* @__PURE__ */ jsx(CurrencyIcon, { symbol: floor.symbol, size: 10 }),
|
|
72
65
|
floor.amount
|
|
73
|
-
] })
|
|
74
|
-
hasExclusiveContent && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1 text-2xs font-bold text-white backdrop-blur-md bg-black/50 rounded-full px-2 py-0.5", children: "\u2726 Exclusive" })
|
|
66
|
+
] })
|
|
75
67
|
] })
|
|
76
68
|
] })
|
|
77
69
|
] }) })
|
|
78
|
-
] })
|
|
70
|
+
] });
|
|
79
71
|
}
|
|
80
72
|
function CollectionCardSkeleton() {
|
|
81
73
|
return /* @__PURE__ */ jsx("div", { className: "card-base overflow-hidden", children: /* @__PURE__ */ jsxs("div", { className: "relative aspect-square w-full overflow-hidden bg-muted", children: [
|
|
@@ -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\
|
|
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 initial = (collection.name ?? collection.contractAddress).charAt(0).toUpperCase();\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 flex items-center justify-center\">\n <span className=\"text-8xl font-black text-white/10 select-none tracking-tighter\">\n {initial}\n </span>\n </div>\n )}\n\n <div className=\"absolute inset-x-0 bottom-0 flex flex-col items-start gap-1 bg-gradient-to-t from-black/85 via-black/45 to-transparent px-3 pb-3 pt-14\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 text-2xs text-white/70\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p className=\"max-w-full truncate text-sm font-bold leading-tight text-white\">\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n <div className=\"flex flex-wrap items-center gap-x-2.5 gap-y-0.5 text-2xs font-medium text-white/80\">\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/90\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n </div>\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":";AAkDY,cA0BE,YA1BF;AAhDZ,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,WAAW,WAAW,QAAQ,WAAW,iBAAiB,OAAO,CAAC,EAAE,YAAY;AACtF,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,+HACb,8BAAC,UAAK,WAAU,kEACb,mBACH,GACF;AAAA,MAGF,qBAAC,SAAI,WAAU,0IACZ;AAAA,SAAC,WAAW,QAAQ,WAAW,mBAAmB,YACjD,qBAAC,UAAK,WAAU,kDACd;AAAA,8BAAC,WAAQ,WAAU,4BAA2B;AAAA,UAAE;AAAA,WAElD,IAEA,oBAAC,OAAE,WAAU,kEACV,qBAAW,QAAQ,sBACtB;AAAA,QAGF,qBAAC,SAAI,WAAU,sFACZ;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,0DAAyD;AAAA;AAAA,YAEvE,oBAAC,gBAAa,QAAQ,MAAM,QAAQ,MAAM,IAAI;AAAA,YAC7C,MAAM;AAAA,aACT;AAAA,WAEJ;AAAA,SACF;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":[]}
|