@medialane/ui 0.328.0 → 0.329.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.
Files changed (51) hide show
  1. package/dist/components/account/input-otp.d.cts +2 -2
  2. package/dist/components/account/input-otp.d.ts +2 -2
  3. package/dist/components/asset-card.cjs +4 -4
  4. package/dist/components/asset-card.cjs.map +1 -1
  5. package/dist/components/asset-card.js +4 -4
  6. package/dist/components/asset-card.js.map +1 -1
  7. package/dist/components/asset-marketplace-panel.cjs +23 -26
  8. package/dist/components/asset-marketplace-panel.cjs.map +1 -1
  9. package/dist/components/asset-marketplace-panel.js +23 -26
  10. package/dist/components/asset-marketplace-panel.js.map +1 -1
  11. package/dist/components/badge.d.cts +1 -1
  12. package/dist/components/badge.d.ts +1 -1
  13. package/dist/components/button.d.cts +2 -2
  14. package/dist/components/button.d.ts +2 -2
  15. package/dist/components/coin-row.cjs +3 -3
  16. package/dist/components/coin-row.cjs.map +1 -1
  17. package/dist/components/coin-row.js +3 -3
  18. package/dist/components/coin-row.js.map +1 -1
  19. package/dist/components/fast-mint/fast-mint.d.cts +2 -2
  20. package/dist/components/fast-mint/fast-mint.d.ts +2 -2
  21. package/dist/components/listing-card.cjs +2 -14
  22. package/dist/components/listing-card.cjs.map +1 -1
  23. package/dist/components/listing-card.js +2 -14
  24. package/dist/components/listing-card.js.map +1 -1
  25. package/dist/components/price-display.cjs +115 -0
  26. package/dist/components/price-display.cjs.map +1 -0
  27. package/dist/components/price-display.d.cts +44 -0
  28. package/dist/components/price-display.d.ts +44 -0
  29. package/dist/components/price-display.js +91 -0
  30. package/dist/components/price-display.js.map +1 -0
  31. package/dist/components/sheet.d.cts +1 -1
  32. package/dist/components/sheet.d.ts +1 -1
  33. package/dist/components/token-card.cjs +4 -4
  34. package/dist/components/token-card.cjs.map +1 -1
  35. package/dist/components/token-card.js +4 -4
  36. package/dist/components/token-card.js.map +1 -1
  37. package/dist/utils/format.cjs +9 -0
  38. package/dist/utils/format.cjs.map +1 -1
  39. package/dist/utils/format.d.cts +2 -1
  40. package/dist/utils/format.d.ts +2 -1
  41. package/dist/utils/format.js +8 -0
  42. package/dist/utils/format.js.map +1 -1
  43. package/dist/utils/media-wallet/use-erc20-balance.d.cts +1 -1
  44. package/dist/utils/media-wallet/use-erc20-balance.d.ts +1 -1
  45. package/package.json +1 -1
  46. package/dist/components/dual-price.cjs +0 -164
  47. package/dist/components/dual-price.cjs.map +0 -1
  48. package/dist/components/dual-price.d.cts +0 -53
  49. package/dist/components/dual-price.d.ts +0 -53
  50. package/dist/components/dual-price.js +0 -138
  51. package/dist/components/dual-price.js.map +0 -1
@@ -39,7 +39,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
39
39
  var import_link = __toESM(require("./link.js"), 1);
40
40
  var import_image = __toESM(require("./image.js"), 1);
41
41
  var import_cn = require("../utils/cn.js");
42
- var import_dual_price = require("./dual-price.js");
42
+ var import_price_display = require("./price-display.js");
43
43
  var import_coins = require("../data/coins.js");
44
44
  var import_format = require("../utils/format.js");
45
45
  var import_use_image_url = require("../utils/use-image-url.js");
@@ -80,13 +80,13 @@ function PriceCell({ price, status, isLoading }) {
80
80
  }
81
81
  const usd = price.quoteUsdRate != null ? (0, import_format.formatUsdPrice)(price.quotePerCoin * price.quoteUsdRate) : null;
82
82
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
83
- import_dual_price.DualPrice,
83
+ import_price_display.PriceDisplay,
84
84
  {
85
85
  amountFormatted: String(price.quotePerCoin),
86
86
  currency: price.quoteSymbol,
87
87
  usdValue: usd,
88
88
  scale: "card",
89
- secondaryClassName: "hidden sm:flex"
89
+ pillClassName: "hidden sm:inline-flex"
90
90
  }
91
91
  ) });
92
92
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { DualPrice } from \"./dual-price.js\";\nimport {\n coinKind, coinKindLabel, coinAccentToken,\n type CoinCollectionLike, type CoinPriceLike,\n} from \"../data/coins.js\";\nimport { formatUsdPrice } from \"../utils/format.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type CoinMarketStatus = \"live\" | \"pre-launch\" | \"unavailable\";\n\nexport type UseCoinPrice = (collection: CoinCollectionLike) => {\n price: CoinPriceLike | null;\n status?: CoinMarketStatus;\n isLoading: boolean;\n};\n\nexport const COIN_GRID = \"grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 sm:gap-4\";\n\nexport interface CoinRowProps {\n collection: CoinCollectionLike;\n usePrice: UseCoinPrice;\n href: string;\n showKind?: boolean;\n}\n\nexport function CoinAvatar({ collection, size = 36 }: { collection: CoinCollectionLike; size?: number }) {\n const resolveImage = useImageUrl();\n const logoUri = collection.profile?.image ?? collection.image;\n const logo = resolveImage(logoUri);\n const initials = (collection.symbol ?? collection.name ?? \"?\").trim().slice(0, 2).toUpperCase();\n const accent = coinAccentToken(collection.symbol ?? collection.name ?? collection.contractAddress);\n\n return (\n <div\n className={cn(\"relative shrink-0 overflow-hidden rounded-full\", accent)}\n style={{ width: size, height: size }}\n >\n {logo ? (\n <Image src={logo} alt=\"\" fill sizes={`${size}px`} className=\"object-cover\" unoptimized />\n ) : (\n <span\n className=\"flex h-full w-full items-center justify-center font-bold leading-none text-white\"\n style={{ fontSize: size * 0.36 }}\n >\n {initials}\n </span>\n )}\n </div>\n );\n}\n\nfunction PriceCell({ price, status, isLoading }: { price: CoinPriceLike | null; status?: CoinMarketStatus; isLoading: boolean }) {\n if (isLoading) return <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />;\n if (!price) {\n return status === \"pre-launch\" ? (\n <span className=\"block text-right text-xs text-muted-foreground\">Not trading yet</span>\n ) : (\n <span\n className=\"block text-right text-muted-foreground\"\n title=\"No liquidity route was found for this coin on any Starknet DEX yet.\"\n >\n —\n </span>\n );\n }\n\n const usd = price.quoteUsdRate != null ? formatUsdPrice(price.quotePerCoin * price.quoteUsdRate) : null;\n\n return (\n <span className=\"flex justify-end\">\n <DualPrice\n amountFormatted={String(price.quotePerCoin)}\n currency={price.quoteSymbol}\n usdValue={usd}\n scale=\"card\"\n secondaryClassName=\"hidden sm:flex\"\n />\n </span>\n );\n}\n\nexport function CoinRow({ collection, usePrice, href, showKind = false }: CoinRowProps) {\n const { price, status, isLoading } = usePrice(collection);\n\n return (\n <Link\n href={href}\n className={cn(\n COIN_GRID,\n \"border-b border-border/40 px-2 py-2.5 text-sm transition-colors\",\n \"hover:bg-muted/40 active:bg-muted/60\"\n )}\n >\n <span className=\"flex min-w-0 items-center gap-3\">\n <CoinAvatar collection={collection} />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-semibold leading-tight\">{collection.name ?? \"Untitled coin\"}</span>\n <span className=\"block truncate text-xs text-muted-foreground\">\n {collection.symbol ?? \"—\"}\n {showKind && <span className=\"text-muted-foreground/60\"> · {coinKindLabel(coinKind(collection.service))}</span>}\n </span>\n </span>\n </span>\n\n <PriceCell price={price} status={status} isLoading={isLoading} />\n </Link>\n );\n}\n\nexport function CoinRowSkeleton() {\n return (\n <div className={cn(COIN_GRID, \"border-b border-border/40 px-2 py-2.5\")}>\n <span className=\"flex items-center gap-3\">\n <span className=\"h-9 w-9 shrink-0 animate-pulse rounded-full bg-muted-foreground/20\" />\n <span className=\"space-y-1.5\">\n <span className=\"block h-4 w-28 animate-pulse rounded bg-muted-foreground/20\" />\n <span className=\"block h-3 w-14 animate-pulse rounded bg-muted-foreground/10\" />\n </span>\n </span>\n <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />\n </div>\n );\n}\n"],"mappings":"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","names":["Image","Link"]}
1
+ {"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceDisplay } from \"./price-display.js\";\nimport {\n coinKind, coinKindLabel, coinAccentToken,\n type CoinCollectionLike, type CoinPriceLike,\n} from \"../data/coins.js\";\nimport { formatUsdPrice } from \"../utils/format.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type CoinMarketStatus = \"live\" | \"pre-launch\" | \"unavailable\";\n\nexport type UseCoinPrice = (collection: CoinCollectionLike) => {\n price: CoinPriceLike | null;\n status?: CoinMarketStatus;\n isLoading: boolean;\n};\n\nexport const COIN_GRID = \"grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 sm:gap-4\";\n\nexport interface CoinRowProps {\n collection: CoinCollectionLike;\n usePrice: UseCoinPrice;\n href: string;\n showKind?: boolean;\n}\n\nexport function CoinAvatar({ collection, size = 36 }: { collection: CoinCollectionLike; size?: number }) {\n const resolveImage = useImageUrl();\n const logoUri = collection.profile?.image ?? collection.image;\n const logo = resolveImage(logoUri);\n const initials = (collection.symbol ?? collection.name ?? \"?\").trim().slice(0, 2).toUpperCase();\n const accent = coinAccentToken(collection.symbol ?? collection.name ?? collection.contractAddress);\n\n return (\n <div\n className={cn(\"relative shrink-0 overflow-hidden rounded-full\", accent)}\n style={{ width: size, height: size }}\n >\n {logo ? (\n <Image src={logo} alt=\"\" fill sizes={`${size}px`} className=\"object-cover\" unoptimized />\n ) : (\n <span\n className=\"flex h-full w-full items-center justify-center font-bold leading-none text-white\"\n style={{ fontSize: size * 0.36 }}\n >\n {initials}\n </span>\n )}\n </div>\n );\n}\n\nfunction PriceCell({ price, status, isLoading }: { price: CoinPriceLike | null; status?: CoinMarketStatus; isLoading: boolean }) {\n if (isLoading) return <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />;\n if (!price) {\n return status === \"pre-launch\" ? (\n <span className=\"block text-right text-xs text-muted-foreground\">Not trading yet</span>\n ) : (\n <span\n className=\"block text-right text-muted-foreground\"\n title=\"No liquidity route was found for this coin on any Starknet DEX yet.\"\n >\n —\n </span>\n );\n }\n\n const usd = price.quoteUsdRate != null ? formatUsdPrice(price.quotePerCoin * price.quoteUsdRate) : null;\n\n return (\n <span className=\"flex justify-end\">\n <PriceDisplay\n amountFormatted={String(price.quotePerCoin)}\n currency={price.quoteSymbol}\n usdValue={usd}\n scale=\"card\"\n pillClassName=\"hidden sm:inline-flex\"\n />\n </span>\n );\n}\n\nexport function CoinRow({ collection, usePrice, href, showKind = false }: CoinRowProps) {\n const { price, status, isLoading } = usePrice(collection);\n\n return (\n <Link\n href={href}\n className={cn(\n COIN_GRID,\n \"border-b border-border/40 px-2 py-2.5 text-sm transition-colors\",\n \"hover:bg-muted/40 active:bg-muted/60\"\n )}\n >\n <span className=\"flex min-w-0 items-center gap-3\">\n <CoinAvatar collection={collection} />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-semibold leading-tight\">{collection.name ?? \"Untitled coin\"}</span>\n <span className=\"block truncate text-xs text-muted-foreground\">\n {collection.symbol ?? \"—\"}\n {showKind && <span className=\"text-muted-foreground/60\"> · {coinKindLabel(coinKind(collection.service))}</span>}\n </span>\n </span>\n </span>\n\n <PriceCell price={price} status={status} isLoading={isLoading} />\n </Link>\n );\n}\n\nexport function CoinRowSkeleton() {\n return (\n <div className={cn(COIN_GRID, \"border-b border-border/40 px-2 py-2.5\")}>\n <span className=\"flex items-center gap-3\">\n <span className=\"h-9 w-9 shrink-0 animate-pulse rounded-full bg-muted-foreground/20\" />\n <span className=\"space-y-1.5\">\n <span className=\"block h-4 w-28 animate-pulse rounded bg-muted-foreground/20\" />\n <span className=\"block h-3 w-14 animate-pulse rounded bg-muted-foreground/10\" />\n </span>\n </span>\n <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />\n </div>\n );\n}\n"],"mappings":"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","names":["Image","Link"]}
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import Link from "./link.js";
4
4
  import Image from "./image.js";
5
5
  import { cn } from "../utils/cn.js";
6
- import { DualPrice } from "./dual-price.js";
6
+ import { PriceDisplay } from "./price-display.js";
7
7
  import {
8
8
  coinKind,
9
9
  coinKindLabel,
@@ -48,13 +48,13 @@ function PriceCell({ price, status, isLoading }) {
48
48
  }
49
49
  const usd = price.quoteUsdRate != null ? formatUsdPrice(price.quotePerCoin * price.quoteUsdRate) : null;
50
50
  return /* @__PURE__ */ jsx("span", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
51
- DualPrice,
51
+ PriceDisplay,
52
52
  {
53
53
  amountFormatted: String(price.quotePerCoin),
54
54
  currency: price.quoteSymbol,
55
55
  usdValue: usd,
56
56
  scale: "card",
57
- secondaryClassName: "hidden sm:flex"
57
+ pillClassName: "hidden sm:inline-flex"
58
58
  }
59
59
  ) });
60
60
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { DualPrice } from \"./dual-price.js\";\nimport {\n coinKind, coinKindLabel, coinAccentToken,\n type CoinCollectionLike, type CoinPriceLike,\n} from \"../data/coins.js\";\nimport { formatUsdPrice } from \"../utils/format.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type CoinMarketStatus = \"live\" | \"pre-launch\" | \"unavailable\";\n\nexport type UseCoinPrice = (collection: CoinCollectionLike) => {\n price: CoinPriceLike | null;\n status?: CoinMarketStatus;\n isLoading: boolean;\n};\n\nexport const COIN_GRID = \"grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 sm:gap-4\";\n\nexport interface CoinRowProps {\n collection: CoinCollectionLike;\n usePrice: UseCoinPrice;\n href: string;\n showKind?: boolean;\n}\n\nexport function CoinAvatar({ collection, size = 36 }: { collection: CoinCollectionLike; size?: number }) {\n const resolveImage = useImageUrl();\n const logoUri = collection.profile?.image ?? collection.image;\n const logo = resolveImage(logoUri);\n const initials = (collection.symbol ?? collection.name ?? \"?\").trim().slice(0, 2).toUpperCase();\n const accent = coinAccentToken(collection.symbol ?? collection.name ?? collection.contractAddress);\n\n return (\n <div\n className={cn(\"relative shrink-0 overflow-hidden rounded-full\", accent)}\n style={{ width: size, height: size }}\n >\n {logo ? (\n <Image src={logo} alt=\"\" fill sizes={`${size}px`} className=\"object-cover\" unoptimized />\n ) : (\n <span\n className=\"flex h-full w-full items-center justify-center font-bold leading-none text-white\"\n style={{ fontSize: size * 0.36 }}\n >\n {initials}\n </span>\n )}\n </div>\n );\n}\n\nfunction PriceCell({ price, status, isLoading }: { price: CoinPriceLike | null; status?: CoinMarketStatus; isLoading: boolean }) {\n if (isLoading) return <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />;\n if (!price) {\n return status === \"pre-launch\" ? (\n <span className=\"block text-right text-xs text-muted-foreground\">Not trading yet</span>\n ) : (\n <span\n className=\"block text-right text-muted-foreground\"\n title=\"No liquidity route was found for this coin on any Starknet DEX yet.\"\n >\n —\n </span>\n );\n }\n\n const usd = price.quoteUsdRate != null ? formatUsdPrice(price.quotePerCoin * price.quoteUsdRate) : null;\n\n return (\n <span className=\"flex justify-end\">\n <DualPrice\n amountFormatted={String(price.quotePerCoin)}\n currency={price.quoteSymbol}\n usdValue={usd}\n scale=\"card\"\n secondaryClassName=\"hidden sm:flex\"\n />\n </span>\n );\n}\n\nexport function CoinRow({ collection, usePrice, href, showKind = false }: CoinRowProps) {\n const { price, status, isLoading } = usePrice(collection);\n\n return (\n <Link\n href={href}\n className={cn(\n COIN_GRID,\n \"border-b border-border/40 px-2 py-2.5 text-sm transition-colors\",\n \"hover:bg-muted/40 active:bg-muted/60\"\n )}\n >\n <span className=\"flex min-w-0 items-center gap-3\">\n <CoinAvatar collection={collection} />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-semibold leading-tight\">{collection.name ?? \"Untitled coin\"}</span>\n <span className=\"block truncate text-xs text-muted-foreground\">\n {collection.symbol ?? \"—\"}\n {showKind && <span className=\"text-muted-foreground/60\"> · {coinKindLabel(coinKind(collection.service))}</span>}\n </span>\n </span>\n </span>\n\n <PriceCell price={price} status={status} isLoading={isLoading} />\n </Link>\n );\n}\n\nexport function CoinRowSkeleton() {\n return (\n <div className={cn(COIN_GRID, \"border-b border-border/40 px-2 py-2.5\")}>\n <span className=\"flex items-center gap-3\">\n <span className=\"h-9 w-9 shrink-0 animate-pulse rounded-full bg-muted-foreground/20\" />\n <span className=\"space-y-1.5\">\n <span className=\"block h-4 w-28 animate-pulse rounded bg-muted-foreground/20\" />\n <span className=\"block h-3 w-14 animate-pulse rounded bg-muted-foreground/10\" />\n </span>\n </span>\n <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceDisplay } from \"./price-display.js\";\nimport {\n coinKind, coinKindLabel, coinAccentToken,\n type CoinCollectionLike, type CoinPriceLike,\n} from \"../data/coins.js\";\nimport { formatUsdPrice } from \"../utils/format.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type CoinMarketStatus = \"live\" | \"pre-launch\" | \"unavailable\";\n\nexport type UseCoinPrice = (collection: CoinCollectionLike) => {\n price: CoinPriceLike | null;\n status?: CoinMarketStatus;\n isLoading: boolean;\n};\n\nexport const COIN_GRID = \"grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 sm:gap-4\";\n\nexport interface CoinRowProps {\n collection: CoinCollectionLike;\n usePrice: UseCoinPrice;\n href: string;\n showKind?: boolean;\n}\n\nexport function CoinAvatar({ collection, size = 36 }: { collection: CoinCollectionLike; size?: number }) {\n const resolveImage = useImageUrl();\n const logoUri = collection.profile?.image ?? collection.image;\n const logo = resolveImage(logoUri);\n const initials = (collection.symbol ?? collection.name ?? \"?\").trim().slice(0, 2).toUpperCase();\n const accent = coinAccentToken(collection.symbol ?? collection.name ?? collection.contractAddress);\n\n return (\n <div\n className={cn(\"relative shrink-0 overflow-hidden rounded-full\", accent)}\n style={{ width: size, height: size }}\n >\n {logo ? (\n <Image src={logo} alt=\"\" fill sizes={`${size}px`} className=\"object-cover\" unoptimized />\n ) : (\n <span\n className=\"flex h-full w-full items-center justify-center font-bold leading-none text-white\"\n style={{ fontSize: size * 0.36 }}\n >\n {initials}\n </span>\n )}\n </div>\n );\n}\n\nfunction PriceCell({ price, status, isLoading }: { price: CoinPriceLike | null; status?: CoinMarketStatus; isLoading: boolean }) {\n if (isLoading) return <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />;\n if (!price) {\n return status === \"pre-launch\" ? (\n <span className=\"block text-right text-xs text-muted-foreground\">Not trading yet</span>\n ) : (\n <span\n className=\"block text-right text-muted-foreground\"\n title=\"No liquidity route was found for this coin on any Starknet DEX yet.\"\n >\n —\n </span>\n );\n }\n\n const usd = price.quoteUsdRate != null ? formatUsdPrice(price.quotePerCoin * price.quoteUsdRate) : null;\n\n return (\n <span className=\"flex justify-end\">\n <PriceDisplay\n amountFormatted={String(price.quotePerCoin)}\n currency={price.quoteSymbol}\n usdValue={usd}\n scale=\"card\"\n pillClassName=\"hidden sm:inline-flex\"\n />\n </span>\n );\n}\n\nexport function CoinRow({ collection, usePrice, href, showKind = false }: CoinRowProps) {\n const { price, status, isLoading } = usePrice(collection);\n\n return (\n <Link\n href={href}\n className={cn(\n COIN_GRID,\n \"border-b border-border/40 px-2 py-2.5 text-sm transition-colors\",\n \"hover:bg-muted/40 active:bg-muted/60\"\n )}\n >\n <span className=\"flex min-w-0 items-center gap-3\">\n <CoinAvatar collection={collection} />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-semibold leading-tight\">{collection.name ?? \"Untitled coin\"}</span>\n <span className=\"block truncate text-xs text-muted-foreground\">\n {collection.symbol ?? \"—\"}\n {showKind && <span className=\"text-muted-foreground/60\"> · {coinKindLabel(coinKind(collection.service))}</span>}\n </span>\n </span>\n </span>\n\n <PriceCell price={price} status={status} isLoading={isLoading} />\n </Link>\n );\n}\n\nexport function CoinRowSkeleton() {\n return (\n <div className={cn(COIN_GRID, \"border-b border-border/40 px-2 py-2.5\")}>\n <span className=\"flex items-center gap-3\">\n <span className=\"h-9 w-9 shrink-0 animate-pulse rounded-full bg-muted-foreground/20\" />\n <span className=\"space-y-1.5\">\n <span className=\"block h-4 w-28 animate-pulse rounded bg-muted-foreground/20\" />\n <span className=\"block h-3 w-14 animate-pulse rounded bg-muted-foreground/10\" />\n </span>\n </span>\n <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />\n </div>\n );\n}\n"],"mappings":"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","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 };
@@ -39,9 +39,8 @@ var import_link = __toESM(require("./link.js"), 1);
39
39
  var import_lucide_react = require("lucide-react");
40
40
  var import_motion_primitives = require("./motion-primitives.js");
41
41
  var import_animated_token_media = require("./animated-token-media.js");
42
- var import_currency_icon = require("./currency-icon.js");
42
+ var import_price_display = require("./price-display.js");
43
43
  var import_cn = require("../utils/cn.js");
44
- var import_format = require("../utils/format.js");
45
44
  var import_time = require("../utils/time.js");
46
45
  var import_living_render_collections = require("../data/living-render-collections.js");
47
46
  var import_sdk = require("@medialane/sdk");
@@ -51,18 +50,7 @@ function CardPrice({
51
50
  currency,
52
51
  usdValue
53
52
  }) {
54
- if (!amountFormatted) return null;
55
- const amount = (0, import_format.formatDisplayPrice)(amountFormatted);
56
- const primary = usdValue ?? amount;
57
- const showAmount = !!usdValue && !(0, import_format.isStableCurrency)(currency);
58
- const marker = (0, import_currency_icon.hasCurrencyIcon)(currency) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: currency, size: 14 }) : currency;
59
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "flex items-center gap-1.5 tabular-nums", children: [
60
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-base font-bold tracking-tight", children: primary }),
61
- marker || showAmount ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
62
- marker,
63
- showAmount ? amount : null
64
- ] }) : null
65
- ] });
53
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_price_display.PriceDisplay, { amountFormatted, currency, usdValue, scale: "card" });
66
54
  }
67
55
  function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }) {
68
56
  const resolveImage = (0, import_use_image_url.useImageUrl)();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/listing-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport { ShoppingCart, Check, Zap, ArrowUpRight } from \"lucide-react\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { CurrencyIcon, hasCurrencyIcon } from \"./currency-icon.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice, isStableCurrency } from \"../utils/format.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { assetHref as buildAssetHref, type ApiOrder, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype OrderWithAnimation = ApiOrder & { token: (ApiOrder[\"token\"] & { animationUrl?: string | null }) | null };\n\nfunction CardPrice({\n amountFormatted, currency, usdValue,\n}: {\n amountFormatted: string | null | undefined;\n currency: string | null | undefined;\n usdValue?: string | null;\n}) {\n if (!amountFormatted) return null;\n const amount = formatDisplayPrice(amountFormatted);\n const primary = usdValue ?? amount;\n const showAmount = !!usdValue && !isStableCurrency(currency);\n const marker = hasCurrencyIcon(currency) ? <CurrencyIcon symbol={currency} size={14} /> : currency;\n return (\n <p className=\"flex items-center gap-1.5 tabular-nums\">\n <span className=\"text-base font-bold tracking-tight\">{primary}</span>\n {marker || showAmount ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-muted-foreground\">\n {marker}\n {showAmount ? amount : null}\n </span>\n ) : null}\n </p>\n );\n}\n\nexport interface ListingCardProps {\n order: ApiOrder;\n inCart?: boolean;\n onBuy?: (order: ApiOrder) => void;\n onCart?: (order: ApiOrder) => void;\n\n overflowMenu?: React.ReactNode;\n\n primaryAction?: React.ReactNode;\n compact?: boolean;\n\n imageUrl?: string | null;\n\n usdValue?: string | null;\n}\n\nexport function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }: ListingCardProps) {\n const resolveImage = useImageUrl();\n const order = rawOrder as OrderWithAnimation;\n const [imgError, setImgError] = useState(false);\n const isListing = order.offer.itemType === \"ERC721\" || order.offer.itemType === \"ERC1155\";\n const name = order.token?.name ?? `Token #${order.nftTokenId}`;\n const image = imageUrl !== undefined ? imageUrl : (order.token?.image ? resolveImage(order.token.image, { width: 480 }) : null);\n\n const animationUrl = order.token?.animationUrl ?? null;\n const live = !!(order.chain && order.nftContract) && isLivingRenderCollection(order.chain.toUpperCase() as Chain, order.nftContract!);\n const assetHref = buildAssetHref(\"STARKNET\", order.nftContract ?? \"\", order.nftTokenId ?? \"\");\n\n const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);\n\n if (compact) {\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 33vw, 20vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n <div className=\"p-2.5 space-y-0.5\">\n <p className=\"text-xs font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n <p className=\"text-2xs text-muted-foreground\">{timeAgo(order.createdAt)}</p>\n </div>\n </Link>\n </MotionCard>\n );\n }\n\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"min-w-0 space-y-1\">\n <p className=\"text-sm font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n </div>\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\n primaryAction ? (\n primaryAction\n ) : onBuy ? (\n <div className=\"btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9\">\n <button\n className=\"w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n onClick={(e) => { e.preventDefault(); onBuy(order); }}\n >\n <Zap className=\"h-3.5 w-3.5 shrink-0\" /> Buy\n </button>\n </div>\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\n )}\n {onCart && (\n <button\n className={cn(\n \"min-h-11 min-w-11 shrink-0 rounded-[9px] border flex items-center justify-center transition-colors\",\n inCart\n ? \"border-brand-orange/50 bg-brand-orange/10 text-brand-orange\"\n : \"border-border bg-background hover:bg-muted text-foreground\"\n )}\n onClick={(e) => { e.preventDefault(); if (!inCart) onCart(order); }}\n disabled={inCart}\n aria-label={inCart ? \"Added to cart\" : \"Add to cart\"}\n >\n {inCart ? <Check className=\"h-3.5 w-3.5\" /> : <ShoppingCart className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n {overflowMenu}\n </div>\n )}\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function ListingCardSkeleton() {\n return (\n <div className=\"overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"space-y-1\">\n <div className=\"h-4 w-3/4 bg-muted animate-pulse rounded\" />\n <div className=\"h-5 w-1/2 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-9 w-full bg-muted animate-pulse rounded-[9px]\" />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["buildAssetHref","Link"]}
1
+ {"version":3,"sources":["../../src/components/listing-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport { ShoppingCart, Check, Zap, ArrowUpRight } from \"lucide-react\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { PriceDisplay } from \"./price-display.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { assetHref as buildAssetHref, type ApiOrder, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype OrderWithAnimation = ApiOrder & { token: (ApiOrder[\"token\"] & { animationUrl?: string | null }) | null };\n\nfunction CardPrice({\n amountFormatted, currency, usdValue,\n}: {\n amountFormatted: string | null | undefined;\n currency: string | null | undefined;\n usdValue?: string | null;\n}) {\n return <PriceDisplay amountFormatted={amountFormatted} currency={currency} usdValue={usdValue} scale=\"card\" />;\n}\n\nexport interface ListingCardProps {\n order: ApiOrder;\n inCart?: boolean;\n onBuy?: (order: ApiOrder) => void;\n onCart?: (order: ApiOrder) => void;\n\n overflowMenu?: React.ReactNode;\n\n primaryAction?: React.ReactNode;\n compact?: boolean;\n\n imageUrl?: string | null;\n\n usdValue?: string | null;\n}\n\nexport function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }: ListingCardProps) {\n const resolveImage = useImageUrl();\n const order = rawOrder as OrderWithAnimation;\n const [imgError, setImgError] = useState(false);\n const isListing = order.offer.itemType === \"ERC721\" || order.offer.itemType === \"ERC1155\";\n const name = order.token?.name ?? `Token #${order.nftTokenId}`;\n const image = imageUrl !== undefined ? imageUrl : (order.token?.image ? resolveImage(order.token.image, { width: 480 }) : null);\n\n const animationUrl = order.token?.animationUrl ?? null;\n const live = !!(order.chain && order.nftContract) && isLivingRenderCollection(order.chain.toUpperCase() as Chain, order.nftContract!);\n const assetHref = buildAssetHref(\"STARKNET\", order.nftContract ?? \"\", order.nftTokenId ?? \"\");\n\n const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);\n\n if (compact) {\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 33vw, 20vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n <div className=\"p-2.5 space-y-0.5\">\n <p className=\"text-xs font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n <p className=\"text-2xs text-muted-foreground\">{timeAgo(order.createdAt)}</p>\n </div>\n </Link>\n </MotionCard>\n );\n }\n\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"min-w-0 space-y-1\">\n <p className=\"text-sm font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n </div>\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\n primaryAction ? (\n primaryAction\n ) : onBuy ? (\n <div className=\"btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9\">\n <button\n className=\"w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n onClick={(e) => { e.preventDefault(); onBuy(order); }}\n >\n <Zap className=\"h-3.5 w-3.5 shrink-0\" /> Buy\n </button>\n </div>\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\n )}\n {onCart && (\n <button\n className={cn(\n \"min-h-11 min-w-11 shrink-0 rounded-[9px] border flex items-center justify-center transition-colors\",\n inCart\n ? \"border-brand-orange/50 bg-brand-orange/10 text-brand-orange\"\n : \"border-border bg-background hover:bg-muted text-foreground\"\n )}\n onClick={(e) => { e.preventDefault(); if (!inCart) onCart(order); }}\n disabled={inCart}\n aria-label={inCart ? \"Added to cart\" : \"Add to cart\"}\n >\n {inCart ? <Check className=\"h-3.5 w-3.5\" /> : <ShoppingCart className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n {overflowMenu}\n </div>\n )}\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function ListingCardSkeleton() {\n return (\n <div className=\"overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"space-y-1\">\n <div className=\"h-4 w-3/4 bg-muted animate-pulse rounded\" />\n <div className=\"h-5 w-1/2 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-9 w-full bg-muted animate-pulse rounded-[9px]\" />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["buildAssetHref","Link"]}
@@ -5,9 +5,8 @@ import Link from "./link.js";
5
5
  import { ShoppingCart, Check, Zap, ArrowUpRight } from "lucide-react";
6
6
  import { MotionCard } from "./motion-primitives.js";
7
7
  import { AnimatedTokenMedia } from "./animated-token-media.js";
8
- import { CurrencyIcon, hasCurrencyIcon } from "./currency-icon.js";
8
+ import { PriceDisplay } from "./price-display.js";
9
9
  import { cn } from "../utils/cn.js";
10
- import { formatDisplayPrice, isStableCurrency } from "../utils/format.js";
11
10
  import { timeAgo } from "../utils/time.js";
12
11
  import { isLivingRenderCollection } from "../data/living-render-collections.js";
13
12
  import { assetHref as buildAssetHref } from "@medialane/sdk";
@@ -17,18 +16,7 @@ function CardPrice({
17
16
  currency,
18
17
  usdValue
19
18
  }) {
20
- if (!amountFormatted) return null;
21
- const amount = formatDisplayPrice(amountFormatted);
22
- const primary = usdValue ?? amount;
23
- const showAmount = !!usdValue && !isStableCurrency(currency);
24
- const marker = hasCurrencyIcon(currency) ? /* @__PURE__ */ jsx(CurrencyIcon, { symbol: currency, size: 14 }) : currency;
25
- return /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-1.5 tabular-nums", children: [
26
- /* @__PURE__ */ jsx("span", { className: "text-base font-bold tracking-tight", children: primary }),
27
- marker || showAmount ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
28
- marker,
29
- showAmount ? amount : null
30
- ] }) : null
31
- ] });
19
+ return /* @__PURE__ */ jsx(PriceDisplay, { amountFormatted, currency, usdValue, scale: "card" });
32
20
  }
33
21
  function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }) {
34
22
  const resolveImage = useImageUrl();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/listing-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport { ShoppingCart, Check, Zap, ArrowUpRight } from \"lucide-react\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { CurrencyIcon, hasCurrencyIcon } from \"./currency-icon.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice, isStableCurrency } from \"../utils/format.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { assetHref as buildAssetHref, type ApiOrder, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype OrderWithAnimation = ApiOrder & { token: (ApiOrder[\"token\"] & { animationUrl?: string | null }) | null };\n\nfunction CardPrice({\n amountFormatted, currency, usdValue,\n}: {\n amountFormatted: string | null | undefined;\n currency: string | null | undefined;\n usdValue?: string | null;\n}) {\n if (!amountFormatted) return null;\n const amount = formatDisplayPrice(amountFormatted);\n const primary = usdValue ?? amount;\n const showAmount = !!usdValue && !isStableCurrency(currency);\n const marker = hasCurrencyIcon(currency) ? <CurrencyIcon symbol={currency} size={14} /> : currency;\n return (\n <p className=\"flex items-center gap-1.5 tabular-nums\">\n <span className=\"text-base font-bold tracking-tight\">{primary}</span>\n {marker || showAmount ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-muted-foreground\">\n {marker}\n {showAmount ? amount : null}\n </span>\n ) : null}\n </p>\n );\n}\n\nexport interface ListingCardProps {\n order: ApiOrder;\n inCart?: boolean;\n onBuy?: (order: ApiOrder) => void;\n onCart?: (order: ApiOrder) => void;\n\n overflowMenu?: React.ReactNode;\n\n primaryAction?: React.ReactNode;\n compact?: boolean;\n\n imageUrl?: string | null;\n\n usdValue?: string | null;\n}\n\nexport function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }: ListingCardProps) {\n const resolveImage = useImageUrl();\n const order = rawOrder as OrderWithAnimation;\n const [imgError, setImgError] = useState(false);\n const isListing = order.offer.itemType === \"ERC721\" || order.offer.itemType === \"ERC1155\";\n const name = order.token?.name ?? `Token #${order.nftTokenId}`;\n const image = imageUrl !== undefined ? imageUrl : (order.token?.image ? resolveImage(order.token.image, { width: 480 }) : null);\n\n const animationUrl = order.token?.animationUrl ?? null;\n const live = !!(order.chain && order.nftContract) && isLivingRenderCollection(order.chain.toUpperCase() as Chain, order.nftContract!);\n const assetHref = buildAssetHref(\"STARKNET\", order.nftContract ?? \"\", order.nftTokenId ?? \"\");\n\n const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);\n\n if (compact) {\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 33vw, 20vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n <div className=\"p-2.5 space-y-0.5\">\n <p className=\"text-xs font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n <p className=\"text-2xs text-muted-foreground\">{timeAgo(order.createdAt)}</p>\n </div>\n </Link>\n </MotionCard>\n );\n }\n\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"min-w-0 space-y-1\">\n <p className=\"text-sm font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n </div>\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\n primaryAction ? (\n primaryAction\n ) : onBuy ? (\n <div className=\"btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9\">\n <button\n className=\"w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n onClick={(e) => { e.preventDefault(); onBuy(order); }}\n >\n <Zap className=\"h-3.5 w-3.5 shrink-0\" /> Buy\n </button>\n </div>\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\n )}\n {onCart && (\n <button\n className={cn(\n \"min-h-11 min-w-11 shrink-0 rounded-[9px] border flex items-center justify-center transition-colors\",\n inCart\n ? \"border-brand-orange/50 bg-brand-orange/10 text-brand-orange\"\n : \"border-border bg-background hover:bg-muted text-foreground\"\n )}\n onClick={(e) => { e.preventDefault(); if (!inCart) onCart(order); }}\n disabled={inCart}\n aria-label={inCart ? \"Added to cart\" : \"Add to cart\"}\n >\n {inCart ? <Check className=\"h-3.5 w-3.5\" /> : <ShoppingCart className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n {overflowMenu}\n </div>\n )}\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function ListingCardSkeleton() {\n return (\n <div className=\"overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"space-y-1\">\n <div className=\"h-4 w-3/4 bg-muted animate-pulse rounded\" />\n <div className=\"h-5 w-1/2 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-9 w-full bg-muted animate-pulse rounded-[9px]\" />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/listing-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport { ShoppingCart, Check, Zap, ArrowUpRight } from \"lucide-react\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { PriceDisplay } from \"./price-display.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { assetHref as buildAssetHref, type ApiOrder, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype OrderWithAnimation = ApiOrder & { token: (ApiOrder[\"token\"] & { animationUrl?: string | null }) | null };\n\nfunction CardPrice({\n amountFormatted, currency, usdValue,\n}: {\n amountFormatted: string | null | undefined;\n currency: string | null | undefined;\n usdValue?: string | null;\n}) {\n return <PriceDisplay amountFormatted={amountFormatted} currency={currency} usdValue={usdValue} scale=\"card\" />;\n}\n\nexport interface ListingCardProps {\n order: ApiOrder;\n inCart?: boolean;\n onBuy?: (order: ApiOrder) => void;\n onCart?: (order: ApiOrder) => void;\n\n overflowMenu?: React.ReactNode;\n\n primaryAction?: React.ReactNode;\n compact?: boolean;\n\n imageUrl?: string | null;\n\n usdValue?: string | null;\n}\n\nexport function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }: ListingCardProps) {\n const resolveImage = useImageUrl();\n const order = rawOrder as OrderWithAnimation;\n const [imgError, setImgError] = useState(false);\n const isListing = order.offer.itemType === \"ERC721\" || order.offer.itemType === \"ERC1155\";\n const name = order.token?.name ?? `Token #${order.nftTokenId}`;\n const image = imageUrl !== undefined ? imageUrl : (order.token?.image ? resolveImage(order.token.image, { width: 480 }) : null);\n\n const animationUrl = order.token?.animationUrl ?? null;\n const live = !!(order.chain && order.nftContract) && isLivingRenderCollection(order.chain.toUpperCase() as Chain, order.nftContract!);\n const assetHref = buildAssetHref(\"STARKNET\", order.nftContract ?? \"\", order.nftTokenId ?? \"\");\n\n const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);\n\n if (compact) {\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 33vw, 20vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n <div className=\"p-2.5 space-y-0.5\">\n <p className=\"text-xs font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n <p className=\"text-2xs text-muted-foreground\">{timeAgo(order.createdAt)}</p>\n </div>\n </Link>\n </MotionCard>\n );\n }\n\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"min-w-0 space-y-1\">\n <p className=\"text-sm font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n </div>\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\n primaryAction ? (\n primaryAction\n ) : onBuy ? (\n <div className=\"btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9\">\n <button\n className=\"w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n onClick={(e) => { e.preventDefault(); onBuy(order); }}\n >\n <Zap className=\"h-3.5 w-3.5 shrink-0\" /> Buy\n </button>\n </div>\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\n )}\n {onCart && (\n <button\n className={cn(\n \"min-h-11 min-w-11 shrink-0 rounded-[9px] border flex items-center justify-center transition-colors\",\n inCart\n ? \"border-brand-orange/50 bg-brand-orange/10 text-brand-orange\"\n : \"border-border bg-background hover:bg-muted text-foreground\"\n )}\n onClick={(e) => { e.preventDefault(); if (!inCart) onCart(order); }}\n disabled={inCart}\n aria-label={inCart ? \"Added to cart\" : \"Add to cart\"}\n >\n {inCart ? <Check className=\"h-3.5 w-3.5\" /> : <ShoppingCart className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n {overflowMenu}\n </div>\n )}\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function ListingCardSkeleton() {\n return (\n <div className=\"overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"space-y-1\">\n <div className=\"h-4 w-3/4 bg-muted animate-pulse rounded\" />\n <div className=\"h-5 w-1/2 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-9 w-full bg-muted animate-pulse rounded-[9px]\" />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var price_display_exports = {};
21
+ __export(price_display_exports, {
22
+ PriceDisplay: () => PriceDisplay
23
+ });
24
+ module.exports = __toCommonJS(price_display_exports);
25
+ var import_jsx_runtime = require("react/jsx-runtime");
26
+ var import_currency_icon = require("./currency-icon.js");
27
+ var import_cn = require("../utils/cn.js");
28
+ var import_format = require("../utils/format.js");
29
+ const SCALES = {
30
+ hero: {
31
+ gap: "gap-x-4 gap-y-2",
32
+ icon: 26,
33
+ amount: "text-3xl",
34
+ name: "text-lg",
35
+ pill: "px-3 py-1 text-sm",
36
+ showName: true,
37
+ compact: false
38
+ },
39
+ row: {
40
+ gap: "gap-x-3 gap-y-1",
41
+ icon: 14,
42
+ amount: "text-sm",
43
+ name: "text-xs",
44
+ pill: "px-2 py-0.5 text-xs",
45
+ showName: true,
46
+ compact: false
47
+ },
48
+ card: {
49
+ gap: "gap-x-2.5",
50
+ icon: 14,
51
+ amount: "text-base",
52
+ name: "text-xs",
53
+ pill: "px-2 py-0.5 text-xs",
54
+ showName: false,
55
+ compact: true
56
+ }
57
+ };
58
+ function usdLabel(usdValue, compact) {
59
+ let amount = usdValue.replace("$", "");
60
+ if (compact) {
61
+ const n = Number(amount.replace(/,/g, ""));
62
+ if (isFinite(n) && n >= 1e3) amount = (0, import_format.formatCompactPrice)(n);
63
+ }
64
+ return amount.startsWith("<") ? `${amount} USD` : `\u2248 ${amount} USD`;
65
+ }
66
+ function PriceDisplay({
67
+ amountFormatted,
68
+ currency,
69
+ usdValue,
70
+ scale,
71
+ trailing,
72
+ className,
73
+ pillClassName
74
+ }) {
75
+ if (!amountFormatted) return null;
76
+ const s = SCALES[scale];
77
+ const amount = s.compact ? (0, import_format.formatCompactPrice)(amountFormatted) : (0, import_format.formatDisplayPrice)(amountFormatted);
78
+ const showName = !!currency && (s.showName || !(0, import_currency_icon.hasCurrencyIcon)(currency));
79
+ const showPill = !!usdValue && !(0, import_format.isStableCurrency)(currency);
80
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
81
+ "span",
82
+ {
83
+ className: (0, import_cn.cn)(
84
+ "inline-flex items-center tabular-nums",
85
+ s.gap,
86
+ scale === "hero" ? "flex-wrap" : "flex-nowrap whitespace-nowrap",
87
+ className
88
+ ),
89
+ children: [
90
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
91
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: currency, size: s.icon }),
92
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_cn.cn)("font-semibold tracking-tight text-foreground", s.amount), children: amount }),
93
+ showName ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_cn.cn)("font-semibold text-muted-foreground", s.name), children: currency }) : null
94
+ ] }),
95
+ showPill ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
96
+ "span",
97
+ {
98
+ className: (0, import_cn.cn)(
99
+ "inline-flex items-center rounded-full bg-foreground/[0.06] font-medium text-muted-foreground",
100
+ s.pill,
101
+ pillClassName
102
+ ),
103
+ children: usdLabel(usdValue, s.compact)
104
+ }
105
+ ) : null,
106
+ trailing
107
+ ]
108
+ }
109
+ );
110
+ }
111
+ // Annotate the CommonJS export names for ESM import in node:
112
+ 0 && (module.exports = {
113
+ PriceDisplay
114
+ });
115
+ //# sourceMappingURL=price-display.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/price-display.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { CurrencyIcon, hasCurrencyIcon } from \"./currency-icon.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatCompactPrice, formatDisplayPrice, isStableCurrency } from \"../utils/format.js\";\n\nconst SCALES = {\n hero: {\n gap: \"gap-x-4 gap-y-2\",\n icon: 26,\n amount: \"text-3xl\",\n name: \"text-lg\",\n pill: \"px-3 py-1 text-sm\",\n showName: true,\n compact: false,\n },\n row: {\n gap: \"gap-x-3 gap-y-1\",\n icon: 14,\n amount: \"text-sm\",\n name: \"text-xs\",\n pill: \"px-2 py-0.5 text-xs\",\n showName: true,\n compact: false,\n },\n card: {\n gap: \"gap-x-2.5\",\n icon: 14,\n amount: \"text-base\",\n name: \"text-xs\",\n pill: \"px-2 py-0.5 text-xs\",\n showName: false,\n compact: true,\n },\n} as const;\n\nexport type PriceScale = keyof typeof SCALES;\n\nfunction usdLabel(usdValue: string, compact: boolean): string {\n let amount = usdValue.replace(\"$\", \"\");\n if (compact) {\n const n = Number(amount.replace(/,/g, \"\"));\n if (isFinite(n) && n >= 1000) amount = formatCompactPrice(n);\n }\n return amount.startsWith(\"<\") ? `${amount} USD` : `≈ ${amount} USD`;\n}\n\nexport function PriceDisplay({\n amountFormatted,\n currency,\n usdValue,\n scale,\n trailing,\n className,\n pillClassName,\n}: {\n amountFormatted: string | null | undefined;\n currency: string | null | undefined;\n usdValue?: string | null;\n scale: PriceScale;\n trailing?: ReactNode;\n className?: string;\n pillClassName?: string;\n}) {\n if (!amountFormatted) return null;\n const s = SCALES[scale];\n const amount = s.compact ? formatCompactPrice(amountFormatted) : formatDisplayPrice(amountFormatted);\n const showName = !!currency && (s.showName || !hasCurrencyIcon(currency));\n const showPill = !!usdValue && !isStableCurrency(currency);\n\n return (\n <span\n className={cn(\n \"inline-flex items-center tabular-nums\",\n s.gap,\n scale === \"hero\" ? \"flex-wrap\" : \"flex-nowrap whitespace-nowrap\",\n className\n )}\n >\n <span className=\"inline-flex items-center gap-1.5\">\n <CurrencyIcon symbol={currency} size={s.icon} />\n <span className={cn(\"font-semibold tracking-tight text-foreground\", s.amount)}>{amount}</span>\n {showName ? <span className={cn(\"font-semibold text-muted-foreground\", s.name)}>{currency}</span> : null}\n </span>\n {showPill ? (\n <span\n className={cn(\n \"inline-flex items-center rounded-full bg-foreground/[0.06] font-medium text-muted-foreground\",\n s.pill,\n pillClassName\n )}\n >\n {usdLabel(usdValue!, s.compact)}\n </span>\n ) : null}\n {trailing}\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgFM;AA7EN,2BAA8C;AAC9C,gBAAmB;AACnB,oBAAyE;AAEzE,MAAM,SAAS;AAAA,EACb,MAAM;AAAA,IACJ,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AAAA,EACA,KAAK;AAAA,IACH,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AAAA,EACA,MAAM;AAAA,IACJ,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AACF;AAIA,SAAS,SAAS,UAAkB,SAA0B;AAC5D,MAAI,SAAS,SAAS,QAAQ,KAAK,EAAE;AACrC,MAAI,SAAS;AACX,UAAM,IAAI,OAAO,OAAO,QAAQ,MAAM,EAAE,CAAC;AACzC,QAAI,SAAS,CAAC,KAAK,KAAK,IAAM,cAAS,kCAAmB,CAAC;AAAA,EAC7D;AACA,SAAO,OAAO,WAAW,GAAG,IAAI,GAAG,MAAM,SAAS,UAAK,MAAM;AAC/D;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAQG;AACD,MAAI,CAAC,gBAAiB,QAAO;AAC7B,QAAM,IAAI,OAAO,KAAK;AACtB,QAAM,SAAS,EAAE,cAAU,kCAAmB,eAAe,QAAI,kCAAmB,eAAe;AACnG,QAAM,WAAW,CAAC,CAAC,aAAa,EAAE,YAAY,KAAC,sCAAgB,QAAQ;AACvE,QAAM,WAAW,CAAC,CAAC,YAAY,KAAC,gCAAiB,QAAQ;AAEzD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,QACT;AAAA,QACA,EAAE;AAAA,QACF,UAAU,SAAS,cAAc;AAAA,QACjC;AAAA,MACF;AAAA,MAEA;AAAA,qDAAC,UAAK,WAAU,oCACd;AAAA,sDAAC,qCAAa,QAAQ,UAAU,MAAM,EAAE,MAAM;AAAA,UAC9C,4CAAC,UAAK,eAAW,cAAG,gDAAgD,EAAE,MAAM,GAAI,kBAAO;AAAA,UACtF,WAAW,4CAAC,UAAK,eAAW,cAAG,uCAAuC,EAAE,IAAI,GAAI,oBAAS,IAAU;AAAA,WACtG;AAAA,QACC,WACC;AAAA,UAAC;AAAA;AAAA,YACC,eAAW;AAAA,cACT;AAAA,cACA,EAAE;AAAA,cACF;AAAA,YACF;AAAA,YAEC,mBAAS,UAAW,EAAE,OAAO;AAAA;AAAA,QAChC,IACE;AAAA,QACH;AAAA;AAAA;AAAA,EACH;AAEJ;","names":[]}
@@ -0,0 +1,44 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ declare const SCALES: {
5
+ readonly hero: {
6
+ readonly gap: "gap-x-4 gap-y-2";
7
+ readonly icon: 26;
8
+ readonly amount: "text-3xl";
9
+ readonly name: "text-lg";
10
+ readonly pill: "px-3 py-1 text-sm";
11
+ readonly showName: true;
12
+ readonly compact: false;
13
+ };
14
+ readonly row: {
15
+ readonly gap: "gap-x-3 gap-y-1";
16
+ readonly icon: 14;
17
+ readonly amount: "text-sm";
18
+ readonly name: "text-xs";
19
+ readonly pill: "px-2 py-0.5 text-xs";
20
+ readonly showName: true;
21
+ readonly compact: false;
22
+ };
23
+ readonly card: {
24
+ readonly gap: "gap-x-2.5";
25
+ readonly icon: 14;
26
+ readonly amount: "text-base";
27
+ readonly name: "text-xs";
28
+ readonly pill: "px-2 py-0.5 text-xs";
29
+ readonly showName: false;
30
+ readonly compact: true;
31
+ };
32
+ };
33
+ type PriceScale = keyof typeof SCALES;
34
+ declare function PriceDisplay({ amountFormatted, currency, usdValue, scale, trailing, className, pillClassName, }: {
35
+ amountFormatted: string | null | undefined;
36
+ currency: string | null | undefined;
37
+ usdValue?: string | null;
38
+ scale: PriceScale;
39
+ trailing?: ReactNode;
40
+ className?: string;
41
+ pillClassName?: string;
42
+ }): react_jsx_runtime.JSX.Element | null;
43
+
44
+ export { PriceDisplay, type PriceScale };
@@ -0,0 +1,44 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ declare const SCALES: {
5
+ readonly hero: {
6
+ readonly gap: "gap-x-4 gap-y-2";
7
+ readonly icon: 26;
8
+ readonly amount: "text-3xl";
9
+ readonly name: "text-lg";
10
+ readonly pill: "px-3 py-1 text-sm";
11
+ readonly showName: true;
12
+ readonly compact: false;
13
+ };
14
+ readonly row: {
15
+ readonly gap: "gap-x-3 gap-y-1";
16
+ readonly icon: 14;
17
+ readonly amount: "text-sm";
18
+ readonly name: "text-xs";
19
+ readonly pill: "px-2 py-0.5 text-xs";
20
+ readonly showName: true;
21
+ readonly compact: false;
22
+ };
23
+ readonly card: {
24
+ readonly gap: "gap-x-2.5";
25
+ readonly icon: 14;
26
+ readonly amount: "text-base";
27
+ readonly name: "text-xs";
28
+ readonly pill: "px-2 py-0.5 text-xs";
29
+ readonly showName: false;
30
+ readonly compact: true;
31
+ };
32
+ };
33
+ type PriceScale = keyof typeof SCALES;
34
+ declare function PriceDisplay({ amountFormatted, currency, usdValue, scale, trailing, className, pillClassName, }: {
35
+ amountFormatted: string | null | undefined;
36
+ currency: string | null | undefined;
37
+ usdValue?: string | null;
38
+ scale: PriceScale;
39
+ trailing?: ReactNode;
40
+ className?: string;
41
+ pillClassName?: string;
42
+ }): react_jsx_runtime.JSX.Element | null;
43
+
44
+ export { PriceDisplay, type PriceScale };