@medialane/ui 0.44.0 → 0.46.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.
@@ -36,7 +36,6 @@ var import_jsx_runtime = require("react/jsx-runtime");
36
36
  var import_image = __toESM(require("next/image"), 1);
37
37
  var import_link = __toESM(require("next/link"), 1);
38
38
  var import_lucide_react = require("lucide-react");
39
- var import_cn = require("../utils/cn.js");
40
39
  function AssetCollectionBar({
41
40
  collectionName,
42
41
  collectionImage,
@@ -45,64 +44,41 @@ function AssetCollectionBar({
45
44
  siblingTokens,
46
45
  onNavigate
47
46
  }) {
48
- const currentIndex = siblingTokens.findIndex((t) => String(t.tokenId) === String(currentTokenId));
49
- const prevToken = currentIndex > 0 ? siblingTokens[currentIndex - 1] : null;
50
- const nextToken = currentIndex >= 0 && currentIndex < siblingTokens.length - 1 ? siblingTokens[currentIndex + 1] : null;
51
- const showFilmstrip = siblingTokens.length > 1;
52
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-3", children: [
53
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
54
- import_link.default,
55
- {
56
- href: collectionHref,
57
- className: "flex items-center gap-2.5 group min-w-0",
58
- children: [
59
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative h-8 w-8 rounded-lg overflow-hidden shrink-0 bg-muted ring-1 ring-border/50 group-hover:ring-border transition-all", children: collectionImage ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_image.default, { src: collectionImage, alt: "", fill: true, className: "object-cover", unoptimized: true }) : null }),
60
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0 flex-1", children: [
61
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-muted-foreground leading-none mb-0.5", children: "Collection" }),
62
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-semibold truncate leading-tight group-hover:text-primary transition-colors", children: collectionName })
63
- ] }),
64
- siblingTokens.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground tabular-nums", children: siblingTokens.length })
65
- ]
47
+ const others = siblingTokens.filter(
48
+ (t) => String(t.tokenId) !== String(currentTokenId)
49
+ );
50
+ const preview = others.slice(0, 4);
51
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rounded-2xl bg-gradient-to-br from-muted/40 to-transparent overflow-hidden p-4 space-y-3", children: [
52
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_link.default, { href: collectionHref, className: "flex items-center gap-3 group min-w-0", children: [
53
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative h-11 w-11 rounded-xl overflow-hidden shrink-0 bg-gradient-to-br from-brand-blue/20 to-brand-purple/20 ring-1 ring-border/30 group-hover:ring-border/60 transition-all", children: collectionImage ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_image.default, { src: collectionImage, alt: "", fill: true, className: "object-cover", unoptimized: true }) : null }),
54
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-bold leading-tight truncate min-w-0 flex-1 group-hover:text-primary transition-colors", children: collectionName }),
55
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "shrink-0 h-8 w-8 rounded-xl bg-background/40 flex items-center justify-center text-muted-foreground group-hover:bg-background/70 group-hover:text-foreground transition-all", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRight, { className: "h-3.5 w-3.5" }) })
56
+ ] }),
57
+ preview.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-4 gap-1.5", children: Array.from({ length: 4 }).map((_, i) => {
58
+ const sibling = preview[i];
59
+ if (!sibling) {
60
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "aspect-square rounded-xl bg-muted/20" }, i);
66
61
  }
67
- ),
68
- showFilmstrip ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1", children: [
69
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
62
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
70
63
  "button",
71
64
  {
72
65
  type: "button",
73
- disabled: !prevToken,
74
- onClick: () => prevToken && onNavigate(prevToken.tokenId),
75
- className: "shrink-0 inline-flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground transition hover:text-foreground active:scale-95 disabled:opacity-25 disabled:pointer-events-none",
76
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronLeft, { className: "h-3.5 w-3.5" })
77
- }
78
- ),
79
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-center gap-1.5 overflow-x-auto scroll-smooth [scrollbar-width:none] [&::-webkit-scrollbar]:hidden py-0.5", children: siblingTokens.map((sibling) => {
80
- const isCurrent = String(sibling.tokenId) === String(currentTokenId);
81
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
82
- "button",
83
- {
84
- type: "button",
85
- onClick: () => onNavigate(sibling.tokenId),
86
- className: (0, import_cn.cn)(
87
- "relative h-16 w-16 shrink-0 rounded-xl overflow-hidden transition-all duration-200",
88
- isCurrent ? "opacity-100 scale-100 shadow-sm" : "opacity-50 hover:opacity-80 scale-95 hover:scale-100"
89
- ),
90
- children: sibling.image ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_image.default, { src: sibling.image, alt: "", fill: true, className: "object-cover", unoptimized: true }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-full w-full bg-muted" })
91
- },
92
- sibling.tokenId
93
- );
94
- }) }),
95
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
96
- "button",
97
- {
98
- type: "button",
99
- disabled: !nextToken,
100
- onClick: () => nextToken && onNavigate(nextToken.tokenId),
101
- className: "shrink-0 inline-flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground transition hover:text-foreground active:scale-95 disabled:opacity-25 disabled:pointer-events-none",
102
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronRight, { className: "h-3.5 w-3.5" })
103
- }
104
- )
105
- ] }) : null
66
+ onClick: () => onNavigate(sibling.tokenId),
67
+ className: "group relative aspect-square rounded-xl overflow-hidden transition-all duration-200 hover:scale-[1.02] active:scale-95",
68
+ children: sibling.image ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
69
+ import_image.default,
70
+ {
71
+ src: sibling.image,
72
+ alt: "",
73
+ fill: true,
74
+ className: "object-cover transition-transform duration-300 group-hover:scale-105",
75
+ unoptimized: true
76
+ }
77
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-full w-full bg-muted" })
78
+ },
79
+ sibling.tokenId
80
+ );
81
+ }) })
106
82
  ] });
107
83
  }
108
84
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-collection-bar.tsx"],"sourcesContent":["\"use client\";\n\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface AssetCollectionBarSibling {\n tokenId: string;\n /** Already-resolved, ready-to-render src (e.g. via the caller's ipfsToHttp). `null` renders a placeholder. */\n image: string | null;\n}\n\nexport interface AssetCollectionBarProps {\n collectionName: string;\n /** Already-resolved, ready-to-render src (e.g. via the caller's ipfsToHttp). */\n collectionImage?: string | null;\n collectionHref: string;\n currentTokenId: string;\n siblingTokens: AssetCollectionBarSibling[];\n onNavigate: (tokenId: string) => void;\n}\n\nexport function AssetCollectionBar({\n collectionName,\n collectionImage,\n collectionHref,\n currentTokenId,\n siblingTokens,\n onNavigate,\n}: AssetCollectionBarProps) {\n const currentIndex = siblingTokens.findIndex((t) => String(t.tokenId) === String(currentTokenId));\n const prevToken = currentIndex > 0 ? siblingTokens[currentIndex - 1] : null;\n const nextToken =\n currentIndex >= 0 && currentIndex < siblingTokens.length - 1 ? siblingTokens[currentIndex + 1] : null;\n const showFilmstrip = siblingTokens.length > 1;\n\n return (\n <div className=\"space-y-3\">\n {/* Collection identity — left-aligned, compact */}\n <Link\n href={collectionHref}\n className=\"flex items-center gap-2.5 group min-w-0\"\n >\n <div className=\"relative h-8 w-8 rounded-lg overflow-hidden shrink-0 bg-muted ring-1 ring-border/50 group-hover:ring-border transition-all\">\n {collectionImage ? (\n <Image src={collectionImage} alt=\"\" fill className=\"object-cover\" unoptimized />\n ) : null}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-xs text-muted-foreground leading-none mb-0.5\">Collection</p>\n <p className=\"text-sm font-semibold truncate leading-tight group-hover:text-primary transition-colors\">\n {collectionName}\n </p>\n </div>\n {siblingTokens.length > 0 && (\n <span className=\"shrink-0 text-xs text-muted-foreground tabular-nums\">\n {siblingTokens.length}\n </span>\n )}\n </Link>\n\n {/* Filmstrip */}\n {showFilmstrip ? (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n disabled={!prevToken}\n onClick={() => prevToken && onNavigate(prevToken.tokenId)}\n className=\"shrink-0 inline-flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground transition hover:text-foreground active:scale-95 disabled:opacity-25 disabled:pointer-events-none\"\n >\n <ChevronLeft className=\"h-3.5 w-3.5\" />\n </button>\n\n <div className=\"flex items-center gap-1.5 overflow-x-auto scroll-smooth [scrollbar-width:none] [&::-webkit-scrollbar]:hidden py-0.5\">\n {siblingTokens.map((sibling) => {\n const isCurrent = String(sibling.tokenId) === String(currentTokenId);\n return (\n <button\n key={sibling.tokenId}\n type=\"button\"\n onClick={() => onNavigate(sibling.tokenId)}\n className={cn(\n \"relative h-16 w-16 shrink-0 rounded-xl overflow-hidden transition-all duration-200\",\n isCurrent\n ? \"opacity-100 scale-100 shadow-sm\"\n : \"opacity-50 hover:opacity-80 scale-95 hover:scale-100\"\n )}\n >\n {sibling.image ? (\n <Image src={sibling.image} alt=\"\" fill className=\"object-cover\" unoptimized />\n ) : (\n <div className=\"h-full w-full bg-muted\" />\n )}\n </button>\n );\n })}\n </div>\n\n <button\n type=\"button\"\n disabled={!nextToken}\n onClick={() => nextToken && onNavigate(nextToken.tokenId)}\n className=\"shrink-0 inline-flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground transition hover:text-foreground active:scale-95 disabled:opacity-25 disabled:pointer-events-none\"\n >\n <ChevronRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA8CY;AA5CZ,mBAAkB;AAClB,kBAAiB;AACjB,0BAA0C;AAC1C,gBAAmB;AAkBZ,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,eAAe,cAAc,UAAU,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,OAAO,cAAc,CAAC;AAChG,QAAM,YAAY,eAAe,IAAI,cAAc,eAAe,CAAC,IAAI;AACvE,QAAM,YACJ,gBAAgB,KAAK,eAAe,cAAc,SAAS,IAAI,cAAc,eAAe,CAAC,IAAI;AACnG,QAAM,gBAAgB,cAAc,SAAS;AAE7C,SACE,6CAAC,SAAI,WAAU,aAEb;AAAA;AAAA,MAAC,YAAAA;AAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN,WAAU;AAAA,QAEV;AAAA,sDAAC,SAAI,WAAU,8HACZ,4BACC,4CAAC,aAAAC,SAAA,EAAM,KAAK,iBAAiB,KAAI,IAAG,MAAI,MAAC,WAAU,gBAAe,aAAW,MAAC,IAC5E,MACN;AAAA,UACA,6CAAC,SAAI,WAAU,kBACb;AAAA,wDAAC,OAAE,WAAU,qDAAoD,wBAAU;AAAA,YAC3E,4CAAC,OAAE,WAAU,2FACV,0BACH;AAAA,aACF;AAAA,UACC,cAAc,SAAS,KACtB,4CAAC,UAAK,WAAU,uDACb,wBAAc,QACjB;AAAA;AAAA;AAAA,IAEJ;AAAA,IAGC,gBACC,6CAAC,SAAI,WAAU,2BACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU,CAAC;AAAA,UACX,SAAS,MAAM,aAAa,WAAW,UAAU,OAAO;AAAA,UACxD,WAAU;AAAA,UAEV,sDAAC,mCAAY,WAAU,eAAc;AAAA;AAAA,MACvC;AAAA,MAEA,4CAAC,SAAI,WAAU,uHACZ,wBAAc,IAAI,CAAC,YAAY;AAC9B,cAAM,YAAY,OAAO,QAAQ,OAAO,MAAM,OAAO,cAAc;AACnE,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,SAAS,MAAM,WAAW,QAAQ,OAAO;AAAA,YACzC,eAAW;AAAA,cACT;AAAA,cACA,YACI,oCACA;AAAA,YACN;AAAA,YAEC,kBAAQ,QACP,4CAAC,aAAAA,SAAA,EAAM,KAAK,QAAQ,OAAO,KAAI,IAAG,MAAI,MAAC,WAAU,gBAAe,aAAW,MAAC,IAE5E,4CAAC,SAAI,WAAU,0BAAyB;AAAA;AAAA,UAbrC,QAAQ;AAAA,QAef;AAAA,MAEJ,CAAC,GACH;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU,CAAC;AAAA,UACX,SAAS,MAAM,aAAa,WAAW,UAAU,OAAO;AAAA,UACxD,WAAU;AAAA,UAEV,sDAAC,oCAAa,WAAU,eAAc;AAAA;AAAA,MACxC;AAAA,OACF,IACE;AAAA,KACN;AAEJ;","names":["Link","Image"]}
1
+ {"version":3,"sources":["../../src/components/asset-collection-bar.tsx"],"sourcesContent":["\"use client\";\n\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { ArrowRight } from \"lucide-react\";\nexport interface AssetCollectionBarSibling {\n tokenId: string;\n /** Already-resolved, ready-to-render src. `null` renders a placeholder. */\n image: string | null;\n}\n\nexport interface AssetCollectionBarProps {\n collectionName: string;\n collectionImage?: string | null;\n collectionHref: string;\n currentTokenId: string;\n siblingTokens: AssetCollectionBarSibling[];\n onNavigate: (tokenId: string) => void;\n}\n\nexport function AssetCollectionBar({\n collectionName,\n collectionImage,\n collectionHref,\n currentTokenId,\n siblingTokens,\n onNavigate,\n}: AssetCollectionBarProps) {\n // Show up to 4 OTHER tokens — never the current one\n const others = siblingTokens.filter(\n (t) => String(t.tokenId) !== String(currentTokenId)\n );\n const preview = others.slice(0, 4);\n\n return (\n <div className=\"rounded-2xl bg-gradient-to-br from-muted/40 to-transparent overflow-hidden p-4 space-y-3\">\n\n {/* Collection identity — links to collection page */}\n <Link href={collectionHref} className=\"flex items-center gap-3 group min-w-0\">\n <div className=\"relative h-11 w-11 rounded-xl overflow-hidden shrink-0 bg-gradient-to-br from-brand-blue/20 to-brand-purple/20 ring-1 ring-border/30 group-hover:ring-border/60 transition-all\">\n {collectionImage ? (\n <Image src={collectionImage} alt=\"\" fill className=\"object-cover\" unoptimized />\n ) : null}\n </div>\n <p className=\"text-sm font-bold leading-tight truncate min-w-0 flex-1 group-hover:text-primary transition-colors\">\n {collectionName}\n </p>\n <div className=\"shrink-0 h-8 w-8 rounded-xl bg-background/40 flex items-center justify-center text-muted-foreground group-hover:bg-background/70 group-hover:text-foreground transition-all\">\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </div>\n </Link>\n\n {/* Grid — always 4 columns so thumbnails stay the same size regardless of count */}\n {preview.length > 0 && (\n <div className=\"grid grid-cols-4 gap-1.5\">\n {Array.from({ length: 4 }).map((_, i) => {\n const sibling = preview[i];\n if (!sibling) {\n return <div key={i} className=\"aspect-square rounded-xl bg-muted/20\" />;\n }\n return (\n <button\n key={sibling.tokenId}\n type=\"button\"\n onClick={() => onNavigate(sibling.tokenId)}\n className=\"group relative aspect-square rounded-xl overflow-hidden transition-all duration-200 hover:scale-[1.02] active:scale-95\"\n >\n {sibling.image ? (\n <Image\n src={sibling.image}\n alt=\"\"\n fill\n className=\"object-cover transition-transform duration-300 group-hover:scale-105\"\n unoptimized\n />\n ) : (\n <div className=\"h-full w-full bg-muted\" />\n )}\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsCM;AApCN,mBAAkB;AAClB,kBAAiB;AACjB,0BAA2B;AAgBpB,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAE1B,QAAM,SAAS,cAAc;AAAA,IAC3B,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,OAAO,cAAc;AAAA,EACpD;AACA,QAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AAEjC,SACE,6CAAC,SAAI,WAAU,4FAGb;AAAA,iDAAC,YAAAA,SAAA,EAAK,MAAM,gBAAgB,WAAU,yCACpC;AAAA,kDAAC,SAAI,WAAU,kLACZ,4BACC,4CAAC,aAAAC,SAAA,EAAM,KAAK,iBAAiB,KAAI,IAAG,MAAI,MAAC,WAAU,gBAAe,aAAW,MAAC,IAC5E,MACN;AAAA,MACA,4CAAC,OAAE,WAAU,sGACV,0BACH;AAAA,MACA,4CAAC,SAAI,WAAU,+KACb,sDAAC,kCAAW,WAAU,eAAc,GACtC;AAAA,OACF;AAAA,IAGC,QAAQ,SAAS,KAChB,4CAAC,SAAI,WAAU,4BACZ,gBAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM;AACvC,YAAM,UAAU,QAAQ,CAAC;AACzB,UAAI,CAAC,SAAS;AACZ,eAAO,4CAAC,SAAY,WAAU,0CAAb,CAAoD;AAAA,MACvE;AACA,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,MAAK;AAAA,UACL,SAAS,MAAM,WAAW,QAAQ,OAAO;AAAA,UACzC,WAAU;AAAA,UAET,kBAAQ,QACP;AAAA,YAAC,aAAAA;AAAA,YAAA;AAAA,cACC,KAAK,QAAQ;AAAA,cACb,KAAI;AAAA,cACJ,MAAI;AAAA,cACJ,WAAU;AAAA,cACV,aAAW;AAAA;AAAA,UACb,IAEA,4CAAC,SAAI,WAAU,0BAAyB;AAAA;AAAA,QAdrC,QAAQ;AAAA,MAgBf;AAAA,IAEJ,CAAC,GACH;AAAA,KAEJ;AAEJ;","names":["Link","Image"]}
@@ -2,12 +2,11 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
 
3
3
  interface AssetCollectionBarSibling {
4
4
  tokenId: string;
5
- /** Already-resolved, ready-to-render src (e.g. via the caller's ipfsToHttp). `null` renders a placeholder. */
5
+ /** Already-resolved, ready-to-render src. `null` renders a placeholder. */
6
6
  image: string | null;
7
7
  }
8
8
  interface AssetCollectionBarProps {
9
9
  collectionName: string;
10
- /** Already-resolved, ready-to-render src (e.g. via the caller's ipfsToHttp). */
11
10
  collectionImage?: string | null;
12
11
  collectionHref: string;
13
12
  currentTokenId: string;
@@ -2,12 +2,11 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
 
3
3
  interface AssetCollectionBarSibling {
4
4
  tokenId: string;
5
- /** Already-resolved, ready-to-render src (e.g. via the caller's ipfsToHttp). `null` renders a placeholder. */
5
+ /** Already-resolved, ready-to-render src. `null` renders a placeholder. */
6
6
  image: string | null;
7
7
  }
8
8
  interface AssetCollectionBarProps {
9
9
  collectionName: string;
10
- /** Already-resolved, ready-to-render src (e.g. via the caller's ipfsToHttp). */
11
10
  collectionImage?: string | null;
12
11
  collectionHref: string;
13
12
  currentTokenId: string;
@@ -2,8 +2,7 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import Image from "next/image";
4
4
  import Link from "next/link";
5
- import { ChevronLeft, ChevronRight } from "lucide-react";
6
- import { cn } from "../utils/cn.js";
5
+ import { ArrowRight } from "lucide-react";
7
6
  function AssetCollectionBar({
8
7
  collectionName,
9
8
  collectionImage,
@@ -12,64 +11,41 @@ function AssetCollectionBar({
12
11
  siblingTokens,
13
12
  onNavigate
14
13
  }) {
15
- const currentIndex = siblingTokens.findIndex((t) => String(t.tokenId) === String(currentTokenId));
16
- const prevToken = currentIndex > 0 ? siblingTokens[currentIndex - 1] : null;
17
- const nextToken = currentIndex >= 0 && currentIndex < siblingTokens.length - 1 ? siblingTokens[currentIndex + 1] : null;
18
- const showFilmstrip = siblingTokens.length > 1;
19
- return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
20
- /* @__PURE__ */ jsxs(
21
- Link,
22
- {
23
- href: collectionHref,
24
- className: "flex items-center gap-2.5 group min-w-0",
25
- children: [
26
- /* @__PURE__ */ jsx("div", { className: "relative h-8 w-8 rounded-lg overflow-hidden shrink-0 bg-muted ring-1 ring-border/50 group-hover:ring-border transition-all", children: collectionImage ? /* @__PURE__ */ jsx(Image, { src: collectionImage, alt: "", fill: true, className: "object-cover", unoptimized: true }) : null }),
27
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
28
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground leading-none mb-0.5", children: "Collection" }),
29
- /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold truncate leading-tight group-hover:text-primary transition-colors", children: collectionName })
30
- ] }),
31
- siblingTokens.length > 0 && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs text-muted-foreground tabular-nums", children: siblingTokens.length })
32
- ]
14
+ const others = siblingTokens.filter(
15
+ (t) => String(t.tokenId) !== String(currentTokenId)
16
+ );
17
+ const preview = others.slice(0, 4);
18
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl bg-gradient-to-br from-muted/40 to-transparent overflow-hidden p-4 space-y-3", children: [
19
+ /* @__PURE__ */ jsxs(Link, { href: collectionHref, className: "flex items-center gap-3 group min-w-0", children: [
20
+ /* @__PURE__ */ jsx("div", { className: "relative h-11 w-11 rounded-xl overflow-hidden shrink-0 bg-gradient-to-br from-brand-blue/20 to-brand-purple/20 ring-1 ring-border/30 group-hover:ring-border/60 transition-all", children: collectionImage ? /* @__PURE__ */ jsx(Image, { src: collectionImage, alt: "", fill: true, className: "object-cover", unoptimized: true }) : null }),
21
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-bold leading-tight truncate min-w-0 flex-1 group-hover:text-primary transition-colors", children: collectionName }),
22
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 h-8 w-8 rounded-xl bg-background/40 flex items-center justify-center text-muted-foreground group-hover:bg-background/70 group-hover:text-foreground transition-all", children: /* @__PURE__ */ jsx(ArrowRight, { className: "h-3.5 w-3.5" }) })
23
+ ] }),
24
+ preview.length > 0 && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-4 gap-1.5", children: Array.from({ length: 4 }).map((_, i) => {
25
+ const sibling = preview[i];
26
+ if (!sibling) {
27
+ return /* @__PURE__ */ jsx("div", { className: "aspect-square rounded-xl bg-muted/20" }, i);
33
28
  }
34
- ),
35
- showFilmstrip ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
36
- /* @__PURE__ */ jsx(
29
+ return /* @__PURE__ */ jsx(
37
30
  "button",
38
31
  {
39
32
  type: "button",
40
- disabled: !prevToken,
41
- onClick: () => prevToken && onNavigate(prevToken.tokenId),
42
- className: "shrink-0 inline-flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground transition hover:text-foreground active:scale-95 disabled:opacity-25 disabled:pointer-events-none",
43
- children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5" })
44
- }
45
- ),
46
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 overflow-x-auto scroll-smooth [scrollbar-width:none] [&::-webkit-scrollbar]:hidden py-0.5", children: siblingTokens.map((sibling) => {
47
- const isCurrent = String(sibling.tokenId) === String(currentTokenId);
48
- return /* @__PURE__ */ jsx(
49
- "button",
50
- {
51
- type: "button",
52
- onClick: () => onNavigate(sibling.tokenId),
53
- className: cn(
54
- "relative h-16 w-16 shrink-0 rounded-xl overflow-hidden transition-all duration-200",
55
- isCurrent ? "opacity-100 scale-100 shadow-sm" : "opacity-50 hover:opacity-80 scale-95 hover:scale-100"
56
- ),
57
- children: sibling.image ? /* @__PURE__ */ jsx(Image, { src: sibling.image, alt: "", fill: true, className: "object-cover", unoptimized: true }) : /* @__PURE__ */ jsx("div", { className: "h-full w-full bg-muted" })
58
- },
59
- sibling.tokenId
60
- );
61
- }) }),
62
- /* @__PURE__ */ jsx(
63
- "button",
64
- {
65
- type: "button",
66
- disabled: !nextToken,
67
- onClick: () => nextToken && onNavigate(nextToken.tokenId),
68
- className: "shrink-0 inline-flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground transition hover:text-foreground active:scale-95 disabled:opacity-25 disabled:pointer-events-none",
69
- children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5" })
70
- }
71
- )
72
- ] }) : null
33
+ onClick: () => onNavigate(sibling.tokenId),
34
+ className: "group relative aspect-square rounded-xl overflow-hidden transition-all duration-200 hover:scale-[1.02] active:scale-95",
35
+ children: sibling.image ? /* @__PURE__ */ jsx(
36
+ Image,
37
+ {
38
+ src: sibling.image,
39
+ alt: "",
40
+ fill: true,
41
+ className: "object-cover transition-transform duration-300 group-hover:scale-105",
42
+ unoptimized: true
43
+ }
44
+ ) : /* @__PURE__ */ jsx("div", { className: "h-full w-full bg-muted" })
45
+ },
46
+ sibling.tokenId
47
+ );
48
+ }) })
73
49
  ] });
74
50
  }
75
51
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-collection-bar.tsx"],"sourcesContent":["\"use client\";\n\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface AssetCollectionBarSibling {\n tokenId: string;\n /** Already-resolved, ready-to-render src (e.g. via the caller's ipfsToHttp). `null` renders a placeholder. */\n image: string | null;\n}\n\nexport interface AssetCollectionBarProps {\n collectionName: string;\n /** Already-resolved, ready-to-render src (e.g. via the caller's ipfsToHttp). */\n collectionImage?: string | null;\n collectionHref: string;\n currentTokenId: string;\n siblingTokens: AssetCollectionBarSibling[];\n onNavigate: (tokenId: string) => void;\n}\n\nexport function AssetCollectionBar({\n collectionName,\n collectionImage,\n collectionHref,\n currentTokenId,\n siblingTokens,\n onNavigate,\n}: AssetCollectionBarProps) {\n const currentIndex = siblingTokens.findIndex((t) => String(t.tokenId) === String(currentTokenId));\n const prevToken = currentIndex > 0 ? siblingTokens[currentIndex - 1] : null;\n const nextToken =\n currentIndex >= 0 && currentIndex < siblingTokens.length - 1 ? siblingTokens[currentIndex + 1] : null;\n const showFilmstrip = siblingTokens.length > 1;\n\n return (\n <div className=\"space-y-3\">\n {/* Collection identity — left-aligned, compact */}\n <Link\n href={collectionHref}\n className=\"flex items-center gap-2.5 group min-w-0\"\n >\n <div className=\"relative h-8 w-8 rounded-lg overflow-hidden shrink-0 bg-muted ring-1 ring-border/50 group-hover:ring-border transition-all\">\n {collectionImage ? (\n <Image src={collectionImage} alt=\"\" fill className=\"object-cover\" unoptimized />\n ) : null}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-xs text-muted-foreground leading-none mb-0.5\">Collection</p>\n <p className=\"text-sm font-semibold truncate leading-tight group-hover:text-primary transition-colors\">\n {collectionName}\n </p>\n </div>\n {siblingTokens.length > 0 && (\n <span className=\"shrink-0 text-xs text-muted-foreground tabular-nums\">\n {siblingTokens.length}\n </span>\n )}\n </Link>\n\n {/* Filmstrip */}\n {showFilmstrip ? (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n disabled={!prevToken}\n onClick={() => prevToken && onNavigate(prevToken.tokenId)}\n className=\"shrink-0 inline-flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground transition hover:text-foreground active:scale-95 disabled:opacity-25 disabled:pointer-events-none\"\n >\n <ChevronLeft className=\"h-3.5 w-3.5\" />\n </button>\n\n <div className=\"flex items-center gap-1.5 overflow-x-auto scroll-smooth [scrollbar-width:none] [&::-webkit-scrollbar]:hidden py-0.5\">\n {siblingTokens.map((sibling) => {\n const isCurrent = String(sibling.tokenId) === String(currentTokenId);\n return (\n <button\n key={sibling.tokenId}\n type=\"button\"\n onClick={() => onNavigate(sibling.tokenId)}\n className={cn(\n \"relative h-16 w-16 shrink-0 rounded-xl overflow-hidden transition-all duration-200\",\n isCurrent\n ? \"opacity-100 scale-100 shadow-sm\"\n : \"opacity-50 hover:opacity-80 scale-95 hover:scale-100\"\n )}\n >\n {sibling.image ? (\n <Image src={sibling.image} alt=\"\" fill className=\"object-cover\" unoptimized />\n ) : (\n <div className=\"h-full w-full bg-muted\" />\n )}\n </button>\n );\n })}\n </div>\n\n <button\n type=\"button\"\n disabled={!nextToken}\n onClick={() => nextToken && onNavigate(nextToken.tokenId)}\n className=\"shrink-0 inline-flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground transition hover:text-foreground active:scale-95 disabled:opacity-25 disabled:pointer-events-none\"\n >\n <ChevronRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";AA8CY,cAGJ,YAHI;AA5CZ,OAAO,WAAW;AAClB,OAAO,UAAU;AACjB,SAAS,aAAa,oBAAoB;AAC1C,SAAS,UAAU;AAkBZ,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,eAAe,cAAc,UAAU,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,OAAO,cAAc,CAAC;AAChG,QAAM,YAAY,eAAe,IAAI,cAAc,eAAe,CAAC,IAAI;AACvE,QAAM,YACJ,gBAAgB,KAAK,eAAe,cAAc,SAAS,IAAI,cAAc,eAAe,CAAC,IAAI;AACnG,QAAM,gBAAgB,cAAc,SAAS;AAE7C,SACE,qBAAC,SAAI,WAAU,aAEb;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,WAAU;AAAA,QAEV;AAAA,8BAAC,SAAI,WAAU,8HACZ,4BACC,oBAAC,SAAM,KAAK,iBAAiB,KAAI,IAAG,MAAI,MAAC,WAAU,gBAAe,aAAW,MAAC,IAC5E,MACN;AAAA,UACA,qBAAC,SAAI,WAAU,kBACb;AAAA,gCAAC,OAAE,WAAU,qDAAoD,wBAAU;AAAA,YAC3E,oBAAC,OAAE,WAAU,2FACV,0BACH;AAAA,aACF;AAAA,UACC,cAAc,SAAS,KACtB,oBAAC,UAAK,WAAU,uDACb,wBAAc,QACjB;AAAA;AAAA;AAAA,IAEJ;AAAA,IAGC,gBACC,qBAAC,SAAI,WAAU,2BACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU,CAAC;AAAA,UACX,SAAS,MAAM,aAAa,WAAW,UAAU,OAAO;AAAA,UACxD,WAAU;AAAA,UAEV,8BAAC,eAAY,WAAU,eAAc;AAAA;AAAA,MACvC;AAAA,MAEA,oBAAC,SAAI,WAAU,uHACZ,wBAAc,IAAI,CAAC,YAAY;AAC9B,cAAM,YAAY,OAAO,QAAQ,OAAO,MAAM,OAAO,cAAc;AACnE,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,SAAS,MAAM,WAAW,QAAQ,OAAO;AAAA,YACzC,WAAW;AAAA,cACT;AAAA,cACA,YACI,oCACA;AAAA,YACN;AAAA,YAEC,kBAAQ,QACP,oBAAC,SAAM,KAAK,QAAQ,OAAO,KAAI,IAAG,MAAI,MAAC,WAAU,gBAAe,aAAW,MAAC,IAE5E,oBAAC,SAAI,WAAU,0BAAyB;AAAA;AAAA,UAbrC,QAAQ;AAAA,QAef;AAAA,MAEJ,CAAC,GACH;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU,CAAC;AAAA,UACX,SAAS,MAAM,aAAa,WAAW,UAAU,OAAO;AAAA,UACxD,WAAU;AAAA,UAEV,8BAAC,gBAAa,WAAU,eAAc;AAAA;AAAA,MACxC;AAAA,OACF,IACE;AAAA,KACN;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/asset-collection-bar.tsx"],"sourcesContent":["\"use client\";\n\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { ArrowRight } from \"lucide-react\";\nexport interface AssetCollectionBarSibling {\n tokenId: string;\n /** Already-resolved, ready-to-render src. `null` renders a placeholder. */\n image: string | null;\n}\n\nexport interface AssetCollectionBarProps {\n collectionName: string;\n collectionImage?: string | null;\n collectionHref: string;\n currentTokenId: string;\n siblingTokens: AssetCollectionBarSibling[];\n onNavigate: (tokenId: string) => void;\n}\n\nexport function AssetCollectionBar({\n collectionName,\n collectionImage,\n collectionHref,\n currentTokenId,\n siblingTokens,\n onNavigate,\n}: AssetCollectionBarProps) {\n // Show up to 4 OTHER tokens — never the current one\n const others = siblingTokens.filter(\n (t) => String(t.tokenId) !== String(currentTokenId)\n );\n const preview = others.slice(0, 4);\n\n return (\n <div className=\"rounded-2xl bg-gradient-to-br from-muted/40 to-transparent overflow-hidden p-4 space-y-3\">\n\n {/* Collection identity — links to collection page */}\n <Link href={collectionHref} className=\"flex items-center gap-3 group min-w-0\">\n <div className=\"relative h-11 w-11 rounded-xl overflow-hidden shrink-0 bg-gradient-to-br from-brand-blue/20 to-brand-purple/20 ring-1 ring-border/30 group-hover:ring-border/60 transition-all\">\n {collectionImage ? (\n <Image src={collectionImage} alt=\"\" fill className=\"object-cover\" unoptimized />\n ) : null}\n </div>\n <p className=\"text-sm font-bold leading-tight truncate min-w-0 flex-1 group-hover:text-primary transition-colors\">\n {collectionName}\n </p>\n <div className=\"shrink-0 h-8 w-8 rounded-xl bg-background/40 flex items-center justify-center text-muted-foreground group-hover:bg-background/70 group-hover:text-foreground transition-all\">\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </div>\n </Link>\n\n {/* Grid — always 4 columns so thumbnails stay the same size regardless of count */}\n {preview.length > 0 && (\n <div className=\"grid grid-cols-4 gap-1.5\">\n {Array.from({ length: 4 }).map((_, i) => {\n const sibling = preview[i];\n if (!sibling) {\n return <div key={i} className=\"aspect-square rounded-xl bg-muted/20\" />;\n }\n return (\n <button\n key={sibling.tokenId}\n type=\"button\"\n onClick={() => onNavigate(sibling.tokenId)}\n className=\"group relative aspect-square rounded-xl overflow-hidden transition-all duration-200 hover:scale-[1.02] active:scale-95\"\n >\n {sibling.image ? (\n <Image\n src={sibling.image}\n alt=\"\"\n fill\n className=\"object-cover transition-transform duration-300 group-hover:scale-105\"\n unoptimized\n />\n ) : (\n <div className=\"h-full w-full bg-muted\" />\n )}\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";AAsCM,SAGM,KAHN;AApCN,OAAO,WAAW;AAClB,OAAO,UAAU;AACjB,SAAS,kBAAkB;AAgBpB,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAE1B,QAAM,SAAS,cAAc;AAAA,IAC3B,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,OAAO,cAAc;AAAA,EACpD;AACA,QAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AAEjC,SACE,qBAAC,SAAI,WAAU,4FAGb;AAAA,yBAAC,QAAK,MAAM,gBAAgB,WAAU,yCACpC;AAAA,0BAAC,SAAI,WAAU,kLACZ,4BACC,oBAAC,SAAM,KAAK,iBAAiB,KAAI,IAAG,MAAI,MAAC,WAAU,gBAAe,aAAW,MAAC,IAC5E,MACN;AAAA,MACA,oBAAC,OAAE,WAAU,sGACV,0BACH;AAAA,MACA,oBAAC,SAAI,WAAU,+KACb,8BAAC,cAAW,WAAU,eAAc,GACtC;AAAA,OACF;AAAA,IAGC,QAAQ,SAAS,KAChB,oBAAC,SAAI,WAAU,4BACZ,gBAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM;AACvC,YAAM,UAAU,QAAQ,CAAC;AACzB,UAAI,CAAC,SAAS;AACZ,eAAO,oBAAC,SAAY,WAAU,0CAAb,CAAoD;AAAA,MACvE;AACA,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,MAAK;AAAA,UACL,SAAS,MAAM,WAAW,QAAQ,OAAO;AAAA,UACzC,WAAU;AAAA,UAET,kBAAQ,QACP;AAAA,YAAC;AAAA;AAAA,cACC,KAAK,QAAQ;AAAA,cACb,KAAI;AAAA,cACJ,MAAI;AAAA,cACJ,WAAU;AAAA,cACV,aAAW;AAAA;AAAA,UACb,IAEA,oBAAC,SAAI,WAAU,0BAAyB;AAAA;AAAA,QAdrC,QAAQ;AAAA,MAgBf;AAAA,IAEJ,CAAC,GACH;AAAA,KAEJ;AAEJ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.44.0",
3
+ "version": "0.46.0",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",