@medialane/ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,202 @@
1
+ 'use strict';
2
+
3
+ var clsx = require('clsx');
4
+ var tailwindMerge = require('tailwind-merge');
5
+ var Image3 = require('next/image');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+ var lucideReact = require('lucide-react');
8
+ var Link = require('next/link');
9
+ var nextThemes = require('next-themes');
10
+ var react = require('react');
11
+
12
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
+
14
+ var Image3__default = /*#__PURE__*/_interopDefault(Image3);
15
+ var Link__default = /*#__PURE__*/_interopDefault(Link);
16
+
17
+ // src/utils/cn.ts
18
+ function cn(...inputs) {
19
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
20
+ }
21
+
22
+ // src/utils/format.ts
23
+ function adaptiveDecimals(num) {
24
+ if (num === 0 || num >= 1) return 2;
25
+ if (num >= 0.01) return 4;
26
+ const leadingZeros = Math.floor(-Math.log10(Math.abs(num)));
27
+ return leadingZeros + 2;
28
+ }
29
+ function formatDisplayPrice(price) {
30
+ if (price === null || price === void 0) return "";
31
+ const priceStr = String(price);
32
+ const parts = priceStr.split(" ");
33
+ const numericPart = parts[0];
34
+ const currencyPart = parts.length > 1 ? parts.slice(1).join(" ") : "";
35
+ const num = Number(numericPart);
36
+ if (isNaN(num)) return priceStr;
37
+ const maxDecimals = adaptiveDecimals(num);
38
+ const formatted = num.toLocaleString(void 0, {
39
+ minimumFractionDigits: Math.min(2, maxDecimals),
40
+ maximumFractionDigits: maxDecimals
41
+ });
42
+ return currencyPart ? `${formatted} ${currencyPart}` : formatted;
43
+ }
44
+ var CURRENCY_ICONS = {
45
+ USDC: "/usdc.svg",
46
+ USDT: "/usdt.svg",
47
+ ETH: "/eth.svg",
48
+ STRK: "/strk.svg",
49
+ WBTC: "/btc.svg"
50
+ };
51
+ function CurrencyIcon({ symbol, size = 16, className }) {
52
+ const src = symbol ? CURRENCY_ICONS[symbol] : void 0;
53
+ if (!src) return null;
54
+ return /* @__PURE__ */ jsxRuntime.jsx(
55
+ Image3__default.default,
56
+ {
57
+ src,
58
+ alt: symbol ?? "",
59
+ width: size,
60
+ height: size,
61
+ className: cn("inline-block shrink-0", className),
62
+ unoptimized: true
63
+ }
64
+ );
65
+ }
66
+ function CurrencyAmount({
67
+ amount,
68
+ symbol,
69
+ amountClassName,
70
+ iconSize = 14,
71
+ className
72
+ }) {
73
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("inline-flex items-center gap-1", className), children: [
74
+ /* @__PURE__ */ jsxRuntime.jsx(CurrencyIcon, { symbol, size: iconSize }),
75
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: amountClassName, children: amount })
76
+ ] });
77
+ }
78
+ var IP_TYPE_CONFIG = [
79
+ { slug: "audio", label: "Audio", icon: lucideReact.Music, colorClass: "text-violet-400", bgClass: "bg-violet-500/10", apiValue: "Audio" },
80
+ { slug: "video", label: "Video", icon: lucideReact.Film, colorClass: "text-red-400", bgClass: "bg-red-500/10", apiValue: "Video" },
81
+ { slug: "art", label: "Art", icon: lucideReact.Palette, colorClass: "text-pink-400", bgClass: "bg-pink-500/10", apiValue: "Art" },
82
+ { slug: "photography", label: "Photography", icon: lucideReact.Camera, colorClass: "text-amber-400", bgClass: "bg-amber-500/10", apiValue: "Photography" },
83
+ { slug: "nft", label: "NFT", icon: lucideReact.Gem, colorClass: "text-blue-400", bgClass: "bg-blue-500/10", apiValue: null },
84
+ { slug: "software", label: "Software", icon: lucideReact.Code, colorClass: "text-cyan-400", bgClass: "bg-cyan-500/10", apiValue: "Software" },
85
+ { slug: "rwa", label: "RWA", icon: lucideReact.Building, colorClass: "text-lime-400", bgClass: "bg-lime-500/10", apiValue: "RWA" },
86
+ { slug: "patents", label: "Patents", icon: lucideReact.Award, colorClass: "text-emerald-400", bgClass: "bg-emerald-500/10", apiValue: "Patents" },
87
+ { slug: "posts", label: "Posts", icon: lucideReact.FileText, colorClass: "text-orange-400", bgClass: "bg-orange-500/10", apiValue: "Posts" },
88
+ { slug: "publications", label: "Publications", icon: lucideReact.BookOpen, colorClass: "text-teal-400", bgClass: "bg-teal-500/10", apiValue: "Publications" },
89
+ { slug: "documents", label: "Documents", icon: lucideReact.File, colorClass: "text-slate-400", bgClass: "bg-slate-500/10", apiValue: "Documents" },
90
+ { slug: "custom", label: "Custom", icon: lucideReact.Layers, colorClass: "text-indigo-400", bgClass: "bg-indigo-500/10", apiValue: "Custom" }
91
+ ];
92
+ var IP_TYPE_MAP = Object.fromEntries(
93
+ IP_TYPE_CONFIG.map((c) => [c.slug, c])
94
+ );
95
+ var SIZE = {
96
+ sm: { container: "h-6 w-6", icon: "h-3 w-3" },
97
+ md: { container: "h-8 w-8", icon: "h-4 w-4" }
98
+ };
99
+ function IpTypeBadge({ ipType, size = "sm", className, baseUrl = "" }) {
100
+ const config = IP_TYPE_CONFIG.find(
101
+ (c) => c.label === ipType || c.apiValue === ipType
102
+ );
103
+ if (!config) return null;
104
+ const { icon: Icon, colorClass, bgClass, slug, label } = config;
105
+ const { container, icon } = SIZE[size];
106
+ return /* @__PURE__ */ jsxRuntime.jsx(
107
+ "a",
108
+ {
109
+ href: `${baseUrl}/${slug}`,
110
+ title: label,
111
+ className: cn(
112
+ "inline-flex items-center justify-center rounded-full",
113
+ "transition-opacity hover:opacity-80",
114
+ bgClass,
115
+ container,
116
+ className
117
+ ),
118
+ onClick: (e) => e.stopPropagation(),
119
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: cn(colorClass, icon) })
120
+ }
121
+ );
122
+ }
123
+ function MedialaneIcon({ size = 256, href = "/", className }) {
124
+ const { resolvedTheme } = nextThemes.useTheme();
125
+ const [mounted, setMounted] = react.useState(false);
126
+ react.useEffect(() => {
127
+ setMounted(true);
128
+ }, []);
129
+ if (!mounted) {
130
+ return /* @__PURE__ */ jsxRuntime.jsx(Link__default.default, { href, className, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: size, height: size } }) });
131
+ }
132
+ return /* @__PURE__ */ jsxRuntime.jsx(
133
+ Link__default.default,
134
+ {
135
+ href,
136
+ className: `transition-opacity hover:opacity-80 drop-shadow-md ${className ?? ""}`,
137
+ children: /* @__PURE__ */ jsxRuntime.jsx(
138
+ Image3__default.default,
139
+ {
140
+ src: resolvedTheme === "dark" ? "/icon.png" : "/icon.png",
141
+ alt: "Medialane",
142
+ width: size,
143
+ height: size,
144
+ priority: true
145
+ }
146
+ )
147
+ }
148
+ );
149
+ }
150
+ function MedialaneLogoFull({
151
+ width = 196,
152
+ height = 34,
153
+ href = "/",
154
+ className
155
+ }) {
156
+ const { resolvedTheme } = nextThemes.useTheme();
157
+ const [mounted, setMounted] = react.useState(false);
158
+ react.useEffect(() => {
159
+ setMounted(true);
160
+ }, []);
161
+ if (!mounted) {
162
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center space-x-2", children: /* @__PURE__ */ jsxRuntime.jsx(Link__default.default, { href, className, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width, height } }) }) });
163
+ }
164
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center space-x-2", children: /* @__PURE__ */ jsxRuntime.jsx(
165
+ Link__default.default,
166
+ {
167
+ href,
168
+ className: `transition-opacity hover:opacity-80 drop-shadow-md ${className ?? ""}`,
169
+ children: resolvedTheme === "dark" ? /* @__PURE__ */ jsxRuntime.jsx(
170
+ Image3__default.default,
171
+ {
172
+ src: "/medialane-light-logo.png",
173
+ alt: "Medialane",
174
+ width,
175
+ height,
176
+ priority: true
177
+ }
178
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
179
+ Image3__default.default,
180
+ {
181
+ src: "/medialane-dark-logo.png",
182
+ alt: "Medialane",
183
+ width,
184
+ height,
185
+ priority: true
186
+ }
187
+ )
188
+ }
189
+ ) });
190
+ }
191
+
192
+ exports.CurrencyAmount = CurrencyAmount;
193
+ exports.CurrencyIcon = CurrencyIcon;
194
+ exports.IP_TYPE_CONFIG = IP_TYPE_CONFIG;
195
+ exports.IP_TYPE_MAP = IP_TYPE_MAP;
196
+ exports.IpTypeBadge = IpTypeBadge;
197
+ exports.MedialaneIcon = MedialaneIcon;
198
+ exports.MedialaneLogoFull = MedialaneLogoFull;
199
+ exports.cn = cn;
200
+ exports.formatDisplayPrice = formatDisplayPrice;
201
+ //# sourceMappingURL=index.cjs.map
202
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/cn.ts","../src/utils/format.ts","../src/components/currency-icon.tsx","../src/components/ip-type-badge.tsx","../src/components/brand-icon.tsx","../src/components/brand-logo.tsx"],"names":["twMerge","clsx","jsx","Image","Music","Film","Palette","Camera","Gem","Code","Building","Award","FileText","BookOpen","File","Layers","useTheme","useState","useEffect","Link"],"mappings":"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","file":"index.cjs","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","function adaptiveDecimals(num: number): number {\n if (num === 0 || num >= 1) return 2;\n if (num >= 0.01) return 4;\n const leadingZeros = Math.floor(-Math.log10(Math.abs(num)));\n return leadingZeros + 2;\n}\n\n/**\n * Format a display price string with adaptive decimal places.\n * Handles \"1.234 USDC\" format — reformats the numeric part, preserves the symbol.\n */\nexport function formatDisplayPrice(price: string | number | null | undefined): string {\n if (price === null || price === undefined) return \"\";\n const priceStr = String(price);\n const parts = priceStr.split(\" \");\n const numericPart = parts[0];\n const currencyPart = parts.length > 1 ? parts.slice(1).join(\" \") : \"\";\n const num = Number(numericPart);\n if (isNaN(num)) return priceStr;\n const maxDecimals = adaptiveDecimals(num);\n const formatted = num.toLocaleString(undefined, {\n minimumFractionDigits: Math.min(2, maxDecimals),\n maximumFractionDigits: maxDecimals,\n });\n return currencyPart ? `${formatted} ${currencyPart}` : formatted;\n}\n","\"use client\";\n\nimport Image from \"next/image\";\nimport { cn } from \"../utils/cn.js\";\n\nconst CURRENCY_ICONS: Record<string, string> = {\n USDC: \"/usdc.svg\",\n USDT: \"/usdt.svg\",\n ETH: \"/eth.svg\",\n STRK: \"/strk.svg\",\n WBTC: \"/btc.svg\",\n};\n\nexport interface CurrencyIconProps {\n symbol: string | null | undefined;\n size?: number;\n className?: string;\n}\n\nexport function CurrencyIcon({ symbol, size = 16, className }: CurrencyIconProps) {\n const src = symbol ? CURRENCY_ICONS[symbol] : undefined;\n if (!src) return null;\n return (\n <Image\n src={src}\n alt={symbol ?? \"\"}\n width={size}\n height={size}\n className={cn(\"inline-block shrink-0\", className)}\n unoptimized\n />\n );\n}\n\nexport interface CurrencyAmountProps {\n amount: string;\n symbol: string | null | undefined;\n amountClassName?: string;\n iconSize?: number;\n className?: string;\n}\n\nexport function CurrencyAmount({\n amount,\n symbol,\n amountClassName,\n iconSize = 14,\n className,\n}: CurrencyAmountProps) {\n return (\n <span className={cn(\"inline-flex items-center gap-1\", className)}>\n <CurrencyIcon symbol={symbol} size={iconSize} />\n <span className={amountClassName}>{amount}</span>\n </span>\n );\n}\n","\"use client\";\n\nimport {\n Music, Palette, Film, Camera, Gem, Award,\n FileText, BookOpen, File, Building, Code, Layers,\n} from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface IpTypeConfig {\n slug: string;\n label: string;\n icon: React.ElementType;\n colorClass: string;\n bgClass: string;\n /** API ipType value — null means \"nft\" special case */\n apiValue: string | null;\n}\n\nexport const IP_TYPE_CONFIG: IpTypeConfig[] = [\n { slug: \"audio\", label: \"Audio\", icon: Music, colorClass: \"text-violet-400\", bgClass: \"bg-violet-500/10\", apiValue: \"Audio\" },\n { slug: \"video\", label: \"Video\", icon: Film, colorClass: \"text-red-400\", bgClass: \"bg-red-500/10\", apiValue: \"Video\" },\n { slug: \"art\", label: \"Art\", icon: Palette, colorClass: \"text-pink-400\", bgClass: \"bg-pink-500/10\", apiValue: \"Art\" },\n { slug: \"photography\", label: \"Photography\", icon: Camera, colorClass: \"text-amber-400\", bgClass: \"bg-amber-500/10\", apiValue: \"Photography\" },\n { slug: \"nft\", label: \"NFT\", icon: Gem, colorClass: \"text-blue-400\", bgClass: \"bg-blue-500/10\", apiValue: null },\n { slug: \"software\", label: \"Software\", icon: Code, colorClass: \"text-cyan-400\", bgClass: \"bg-cyan-500/10\", apiValue: \"Software\" },\n { slug: \"rwa\", label: \"RWA\", icon: Building, colorClass: \"text-lime-400\", bgClass: \"bg-lime-500/10\", apiValue: \"RWA\" },\n { slug: \"patents\", label: \"Patents\", icon: Award, colorClass: \"text-emerald-400\", bgClass: \"bg-emerald-500/10\", apiValue: \"Patents\" },\n { slug: \"posts\", label: \"Posts\", icon: FileText, colorClass: \"text-orange-400\", bgClass: \"bg-orange-500/10\", apiValue: \"Posts\" },\n { slug: \"publications\", label: \"Publications\", icon: BookOpen, colorClass: \"text-teal-400\", bgClass: \"bg-teal-500/10\", apiValue: \"Publications\" },\n { slug: \"documents\", label: \"Documents\", icon: File, colorClass: \"text-slate-400\", bgClass: \"bg-slate-500/10\", apiValue: \"Documents\" },\n { slug: \"custom\", label: \"Custom\", icon: Layers, colorClass: \"text-indigo-400\", bgClass: \"bg-indigo-500/10\", apiValue: \"Custom\" },\n];\n\nexport const IP_TYPE_MAP = Object.fromEntries(\n IP_TYPE_CONFIG.map((c) => [c.slug, c])\n) as Record<string, IpTypeConfig>;\n\nconst SIZE = {\n sm: { container: \"h-6 w-6\", icon: \"h-3 w-3\" },\n md: { container: \"h-8 w-8\", icon: \"h-4 w-4\" },\n};\n\nexport interface IpTypeBadgeProps {\n ipType: string;\n size?: \"sm\" | \"md\";\n className?: string;\n /** Base URL for IP type pages. Default: \"\" (relative). Example: \"https://medialane.io\" */\n baseUrl?: string;\n}\n\nexport function IpTypeBadge({ ipType, size = \"sm\", className, baseUrl = \"\" }: IpTypeBadgeProps) {\n const config = IP_TYPE_CONFIG.find(\n (c) => c.label === ipType || c.apiValue === ipType\n );\n if (!config) return null;\n const { icon: Icon, colorClass, bgClass, slug, label } = config;\n const { container, icon } = SIZE[size];\n return (\n <a\n href={`${baseUrl}/${slug}`}\n title={label}\n className={cn(\n \"inline-flex items-center justify-center rounded-full\",\n \"transition-opacity hover:opacity-80\",\n bgClass,\n container,\n className\n )}\n onClick={(e) => e.stopPropagation()}\n >\n <Icon className={cn(colorClass, icon)} />\n </a>\n );\n}\n","\"use client\";\n\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { useTheme } from \"next-themes\";\nimport { useEffect, useState } from \"react\";\n\nexport interface MedialaneIconProps {\n size?: number;\n href?: string;\n className?: string;\n}\n\nexport function MedialaneIcon({ size = 256, href = \"/\", className }: MedialaneIconProps) {\n const { resolvedTheme } = useTheme();\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n if (!mounted) {\n return (\n <Link href={href} className={className}>\n <div style={{ width: size, height: size }} />\n </Link>\n );\n }\n\n return (\n <Link\n href={href}\n className={`transition-opacity hover:opacity-80 drop-shadow-md ${className ?? \"\"}`}\n >\n <Image\n src={resolvedTheme === \"dark\" ? \"/icon.png\" : \"/icon.png\"}\n alt=\"Medialane\"\n width={size}\n height={size}\n priority\n />\n </Link>\n );\n}\n","\"use client\";\n\nimport Link from \"next/link\";\nimport Image from \"next/image\";\nimport { useTheme } from \"next-themes\";\nimport { useEffect, useState } from \"react\";\n\nexport interface MedialaneLogoFullProps {\n width?: number;\n height?: number;\n href?: string;\n className?: string;\n}\n\nexport function MedialaneLogoFull({\n width = 196,\n height = 34,\n href = \"/\",\n className,\n}: MedialaneLogoFullProps) {\n const { resolvedTheme } = useTheme();\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n if (!mounted) {\n return (\n <div className=\"flex items-center space-x-2\">\n <Link href={href} className={className}>\n <div style={{ width, height }} />\n </Link>\n </div>\n );\n }\n\n return (\n <div className=\"flex items-center space-x-2\">\n <Link\n href={href}\n className={`transition-opacity hover:opacity-80 drop-shadow-md ${className ?? \"\"}`}\n >\n {resolvedTheme === \"dark\" ? (\n <Image\n src=\"/medialane-light-logo.png\"\n alt=\"Medialane\"\n width={width}\n height={height}\n priority\n />\n ) : (\n <Image\n src=\"/medialane-dark-logo.png\"\n alt=\"Medialane\"\n width={width}\n height={height}\n priority\n />\n )}\n </Link>\n </div>\n );\n}\n"]}
@@ -0,0 +1,62 @@
1
+ import { ClassValue } from 'clsx';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+
4
+ declare function cn(...inputs: ClassValue[]): string;
5
+
6
+ /**
7
+ * Format a display price string with adaptive decimal places.
8
+ * Handles "1.234 USDC" format — reformats the numeric part, preserves the symbol.
9
+ */
10
+ declare function formatDisplayPrice(price: string | number | null | undefined): string;
11
+
12
+ interface CurrencyIconProps {
13
+ symbol: string | null | undefined;
14
+ size?: number;
15
+ className?: string;
16
+ }
17
+ declare function CurrencyIcon({ symbol, size, className }: CurrencyIconProps): react_jsx_runtime.JSX.Element | null;
18
+ interface CurrencyAmountProps {
19
+ amount: string;
20
+ symbol: string | null | undefined;
21
+ amountClassName?: string;
22
+ iconSize?: number;
23
+ className?: string;
24
+ }
25
+ declare function CurrencyAmount({ amount, symbol, amountClassName, iconSize, className, }: CurrencyAmountProps): react_jsx_runtime.JSX.Element;
26
+
27
+ interface IpTypeConfig {
28
+ slug: string;
29
+ label: string;
30
+ icon: React.ElementType;
31
+ colorClass: string;
32
+ bgClass: string;
33
+ /** API ipType value — null means "nft" special case */
34
+ apiValue: string | null;
35
+ }
36
+ declare const IP_TYPE_CONFIG: IpTypeConfig[];
37
+ declare const IP_TYPE_MAP: Record<string, IpTypeConfig>;
38
+ interface IpTypeBadgeProps {
39
+ ipType: string;
40
+ size?: "sm" | "md";
41
+ className?: string;
42
+ /** Base URL for IP type pages. Default: "" (relative). Example: "https://medialane.io" */
43
+ baseUrl?: string;
44
+ }
45
+ declare function IpTypeBadge({ ipType, size, className, baseUrl }: IpTypeBadgeProps): react_jsx_runtime.JSX.Element | null;
46
+
47
+ interface MedialaneIconProps {
48
+ size?: number;
49
+ href?: string;
50
+ className?: string;
51
+ }
52
+ declare function MedialaneIcon({ size, href, className }: MedialaneIconProps): react_jsx_runtime.JSX.Element;
53
+
54
+ interface MedialaneLogoFullProps {
55
+ width?: number;
56
+ height?: number;
57
+ href?: string;
58
+ className?: string;
59
+ }
60
+ declare function MedialaneLogoFull({ width, height, href, className, }: MedialaneLogoFullProps): react_jsx_runtime.JSX.Element;
61
+
62
+ export { CurrencyAmount, type CurrencyAmountProps, CurrencyIcon, type CurrencyIconProps, IP_TYPE_CONFIG, IP_TYPE_MAP, IpTypeBadge, type IpTypeBadgeProps, type IpTypeConfig, MedialaneIcon, type MedialaneIconProps, MedialaneLogoFull, type MedialaneLogoFullProps, cn, formatDisplayPrice };
@@ -0,0 +1,62 @@
1
+ import { ClassValue } from 'clsx';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+
4
+ declare function cn(...inputs: ClassValue[]): string;
5
+
6
+ /**
7
+ * Format a display price string with adaptive decimal places.
8
+ * Handles "1.234 USDC" format — reformats the numeric part, preserves the symbol.
9
+ */
10
+ declare function formatDisplayPrice(price: string | number | null | undefined): string;
11
+
12
+ interface CurrencyIconProps {
13
+ symbol: string | null | undefined;
14
+ size?: number;
15
+ className?: string;
16
+ }
17
+ declare function CurrencyIcon({ symbol, size, className }: CurrencyIconProps): react_jsx_runtime.JSX.Element | null;
18
+ interface CurrencyAmountProps {
19
+ amount: string;
20
+ symbol: string | null | undefined;
21
+ amountClassName?: string;
22
+ iconSize?: number;
23
+ className?: string;
24
+ }
25
+ declare function CurrencyAmount({ amount, symbol, amountClassName, iconSize, className, }: CurrencyAmountProps): react_jsx_runtime.JSX.Element;
26
+
27
+ interface IpTypeConfig {
28
+ slug: string;
29
+ label: string;
30
+ icon: React.ElementType;
31
+ colorClass: string;
32
+ bgClass: string;
33
+ /** API ipType value — null means "nft" special case */
34
+ apiValue: string | null;
35
+ }
36
+ declare const IP_TYPE_CONFIG: IpTypeConfig[];
37
+ declare const IP_TYPE_MAP: Record<string, IpTypeConfig>;
38
+ interface IpTypeBadgeProps {
39
+ ipType: string;
40
+ size?: "sm" | "md";
41
+ className?: string;
42
+ /** Base URL for IP type pages. Default: "" (relative). Example: "https://medialane.io" */
43
+ baseUrl?: string;
44
+ }
45
+ declare function IpTypeBadge({ ipType, size, className, baseUrl }: IpTypeBadgeProps): react_jsx_runtime.JSX.Element | null;
46
+
47
+ interface MedialaneIconProps {
48
+ size?: number;
49
+ href?: string;
50
+ className?: string;
51
+ }
52
+ declare function MedialaneIcon({ size, href, className }: MedialaneIconProps): react_jsx_runtime.JSX.Element;
53
+
54
+ interface MedialaneLogoFullProps {
55
+ width?: number;
56
+ height?: number;
57
+ href?: string;
58
+ className?: string;
59
+ }
60
+ declare function MedialaneLogoFull({ width, height, href, className, }: MedialaneLogoFullProps): react_jsx_runtime.JSX.Element;
61
+
62
+ export { CurrencyAmount, type CurrencyAmountProps, CurrencyIcon, type CurrencyIconProps, IP_TYPE_CONFIG, IP_TYPE_MAP, IpTypeBadge, type IpTypeBadgeProps, type IpTypeConfig, MedialaneIcon, type MedialaneIconProps, MedialaneLogoFull, type MedialaneLogoFullProps, cn, formatDisplayPrice };
package/dist/index.js ADDED
@@ -0,0 +1,187 @@
1
+ import { clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+ import Image3 from 'next/image';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+ import { Music, Film, Palette, Camera, Gem, Code, Building, Award, FileText, BookOpen, File, Layers } from 'lucide-react';
6
+ import Link from 'next/link';
7
+ import { useTheme } from 'next-themes';
8
+ import { useState, useEffect } from 'react';
9
+
10
+ // src/utils/cn.ts
11
+ function cn(...inputs) {
12
+ return twMerge(clsx(inputs));
13
+ }
14
+
15
+ // src/utils/format.ts
16
+ function adaptiveDecimals(num) {
17
+ if (num === 0 || num >= 1) return 2;
18
+ if (num >= 0.01) return 4;
19
+ const leadingZeros = Math.floor(-Math.log10(Math.abs(num)));
20
+ return leadingZeros + 2;
21
+ }
22
+ function formatDisplayPrice(price) {
23
+ if (price === null || price === void 0) return "";
24
+ const priceStr = String(price);
25
+ const parts = priceStr.split(" ");
26
+ const numericPart = parts[0];
27
+ const currencyPart = parts.length > 1 ? parts.slice(1).join(" ") : "";
28
+ const num = Number(numericPart);
29
+ if (isNaN(num)) return priceStr;
30
+ const maxDecimals = adaptiveDecimals(num);
31
+ const formatted = num.toLocaleString(void 0, {
32
+ minimumFractionDigits: Math.min(2, maxDecimals),
33
+ maximumFractionDigits: maxDecimals
34
+ });
35
+ return currencyPart ? `${formatted} ${currencyPart}` : formatted;
36
+ }
37
+ var CURRENCY_ICONS = {
38
+ USDC: "/usdc.svg",
39
+ USDT: "/usdt.svg",
40
+ ETH: "/eth.svg",
41
+ STRK: "/strk.svg",
42
+ WBTC: "/btc.svg"
43
+ };
44
+ function CurrencyIcon({ symbol, size = 16, className }) {
45
+ const src = symbol ? CURRENCY_ICONS[symbol] : void 0;
46
+ if (!src) return null;
47
+ return /* @__PURE__ */ jsx(
48
+ Image3,
49
+ {
50
+ src,
51
+ alt: symbol ?? "",
52
+ width: size,
53
+ height: size,
54
+ className: cn("inline-block shrink-0", className),
55
+ unoptimized: true
56
+ }
57
+ );
58
+ }
59
+ function CurrencyAmount({
60
+ amount,
61
+ symbol,
62
+ amountClassName,
63
+ iconSize = 14,
64
+ className
65
+ }) {
66
+ return /* @__PURE__ */ jsxs("span", { className: cn("inline-flex items-center gap-1", className), children: [
67
+ /* @__PURE__ */ jsx(CurrencyIcon, { symbol, size: iconSize }),
68
+ /* @__PURE__ */ jsx("span", { className: amountClassName, children: amount })
69
+ ] });
70
+ }
71
+ var IP_TYPE_CONFIG = [
72
+ { slug: "audio", label: "Audio", icon: Music, colorClass: "text-violet-400", bgClass: "bg-violet-500/10", apiValue: "Audio" },
73
+ { slug: "video", label: "Video", icon: Film, colorClass: "text-red-400", bgClass: "bg-red-500/10", apiValue: "Video" },
74
+ { slug: "art", label: "Art", icon: Palette, colorClass: "text-pink-400", bgClass: "bg-pink-500/10", apiValue: "Art" },
75
+ { slug: "photography", label: "Photography", icon: Camera, colorClass: "text-amber-400", bgClass: "bg-amber-500/10", apiValue: "Photography" },
76
+ { slug: "nft", label: "NFT", icon: Gem, colorClass: "text-blue-400", bgClass: "bg-blue-500/10", apiValue: null },
77
+ { slug: "software", label: "Software", icon: Code, colorClass: "text-cyan-400", bgClass: "bg-cyan-500/10", apiValue: "Software" },
78
+ { slug: "rwa", label: "RWA", icon: Building, colorClass: "text-lime-400", bgClass: "bg-lime-500/10", apiValue: "RWA" },
79
+ { slug: "patents", label: "Patents", icon: Award, colorClass: "text-emerald-400", bgClass: "bg-emerald-500/10", apiValue: "Patents" },
80
+ { slug: "posts", label: "Posts", icon: FileText, colorClass: "text-orange-400", bgClass: "bg-orange-500/10", apiValue: "Posts" },
81
+ { slug: "publications", label: "Publications", icon: BookOpen, colorClass: "text-teal-400", bgClass: "bg-teal-500/10", apiValue: "Publications" },
82
+ { slug: "documents", label: "Documents", icon: File, colorClass: "text-slate-400", bgClass: "bg-slate-500/10", apiValue: "Documents" },
83
+ { slug: "custom", label: "Custom", icon: Layers, colorClass: "text-indigo-400", bgClass: "bg-indigo-500/10", apiValue: "Custom" }
84
+ ];
85
+ var IP_TYPE_MAP = Object.fromEntries(
86
+ IP_TYPE_CONFIG.map((c) => [c.slug, c])
87
+ );
88
+ var SIZE = {
89
+ sm: { container: "h-6 w-6", icon: "h-3 w-3" },
90
+ md: { container: "h-8 w-8", icon: "h-4 w-4" }
91
+ };
92
+ function IpTypeBadge({ ipType, size = "sm", className, baseUrl = "" }) {
93
+ const config = IP_TYPE_CONFIG.find(
94
+ (c) => c.label === ipType || c.apiValue === ipType
95
+ );
96
+ if (!config) return null;
97
+ const { icon: Icon, colorClass, bgClass, slug, label } = config;
98
+ const { container, icon } = SIZE[size];
99
+ return /* @__PURE__ */ jsx(
100
+ "a",
101
+ {
102
+ href: `${baseUrl}/${slug}`,
103
+ title: label,
104
+ className: cn(
105
+ "inline-flex items-center justify-center rounded-full",
106
+ "transition-opacity hover:opacity-80",
107
+ bgClass,
108
+ container,
109
+ className
110
+ ),
111
+ onClick: (e) => e.stopPropagation(),
112
+ children: /* @__PURE__ */ jsx(Icon, { className: cn(colorClass, icon) })
113
+ }
114
+ );
115
+ }
116
+ function MedialaneIcon({ size = 256, href = "/", className }) {
117
+ const { resolvedTheme } = useTheme();
118
+ const [mounted, setMounted] = useState(false);
119
+ useEffect(() => {
120
+ setMounted(true);
121
+ }, []);
122
+ if (!mounted) {
123
+ return /* @__PURE__ */ jsx(Link, { href, className, children: /* @__PURE__ */ jsx("div", { style: { width: size, height: size } }) });
124
+ }
125
+ return /* @__PURE__ */ jsx(
126
+ Link,
127
+ {
128
+ href,
129
+ className: `transition-opacity hover:opacity-80 drop-shadow-md ${className ?? ""}`,
130
+ children: /* @__PURE__ */ jsx(
131
+ Image3,
132
+ {
133
+ src: resolvedTheme === "dark" ? "/icon.png" : "/icon.png",
134
+ alt: "Medialane",
135
+ width: size,
136
+ height: size,
137
+ priority: true
138
+ }
139
+ )
140
+ }
141
+ );
142
+ }
143
+ function MedialaneLogoFull({
144
+ width = 196,
145
+ height = 34,
146
+ href = "/",
147
+ className
148
+ }) {
149
+ const { resolvedTheme } = useTheme();
150
+ const [mounted, setMounted] = useState(false);
151
+ useEffect(() => {
152
+ setMounted(true);
153
+ }, []);
154
+ if (!mounted) {
155
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center space-x-2", children: /* @__PURE__ */ jsx(Link, { href, className, children: /* @__PURE__ */ jsx("div", { style: { width, height } }) }) });
156
+ }
157
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center space-x-2", children: /* @__PURE__ */ jsx(
158
+ Link,
159
+ {
160
+ href,
161
+ className: `transition-opacity hover:opacity-80 drop-shadow-md ${className ?? ""}`,
162
+ children: resolvedTheme === "dark" ? /* @__PURE__ */ jsx(
163
+ Image3,
164
+ {
165
+ src: "/medialane-light-logo.png",
166
+ alt: "Medialane",
167
+ width,
168
+ height,
169
+ priority: true
170
+ }
171
+ ) : /* @__PURE__ */ jsx(
172
+ Image3,
173
+ {
174
+ src: "/medialane-dark-logo.png",
175
+ alt: "Medialane",
176
+ width,
177
+ height,
178
+ priority: true
179
+ }
180
+ )
181
+ }
182
+ ) });
183
+ }
184
+
185
+ export { CurrencyAmount, CurrencyIcon, IP_TYPE_CONFIG, IP_TYPE_MAP, IpTypeBadge, MedialaneIcon, MedialaneLogoFull, cn, formatDisplayPrice };
186
+ //# sourceMappingURL=index.js.map
187
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/cn.ts","../src/utils/format.ts","../src/components/currency-icon.tsx","../src/components/ip-type-badge.tsx","../src/components/brand-icon.tsx","../src/components/brand-logo.tsx"],"names":["Image","jsx","useTheme","useState","useEffect","Link"],"mappings":"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","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","function adaptiveDecimals(num: number): number {\n if (num === 0 || num >= 1) return 2;\n if (num >= 0.01) return 4;\n const leadingZeros = Math.floor(-Math.log10(Math.abs(num)));\n return leadingZeros + 2;\n}\n\n/**\n * Format a display price string with adaptive decimal places.\n * Handles \"1.234 USDC\" format — reformats the numeric part, preserves the symbol.\n */\nexport function formatDisplayPrice(price: string | number | null | undefined): string {\n if (price === null || price === undefined) return \"\";\n const priceStr = String(price);\n const parts = priceStr.split(\" \");\n const numericPart = parts[0];\n const currencyPart = parts.length > 1 ? parts.slice(1).join(\" \") : \"\";\n const num = Number(numericPart);\n if (isNaN(num)) return priceStr;\n const maxDecimals = adaptiveDecimals(num);\n const formatted = num.toLocaleString(undefined, {\n minimumFractionDigits: Math.min(2, maxDecimals),\n maximumFractionDigits: maxDecimals,\n });\n return currencyPart ? `${formatted} ${currencyPart}` : formatted;\n}\n","\"use client\";\n\nimport Image from \"next/image\";\nimport { cn } from \"../utils/cn.js\";\n\nconst CURRENCY_ICONS: Record<string, string> = {\n USDC: \"/usdc.svg\",\n USDT: \"/usdt.svg\",\n ETH: \"/eth.svg\",\n STRK: \"/strk.svg\",\n WBTC: \"/btc.svg\",\n};\n\nexport interface CurrencyIconProps {\n symbol: string | null | undefined;\n size?: number;\n className?: string;\n}\n\nexport function CurrencyIcon({ symbol, size = 16, className }: CurrencyIconProps) {\n const src = symbol ? CURRENCY_ICONS[symbol] : undefined;\n if (!src) return null;\n return (\n <Image\n src={src}\n alt={symbol ?? \"\"}\n width={size}\n height={size}\n className={cn(\"inline-block shrink-0\", className)}\n unoptimized\n />\n );\n}\n\nexport interface CurrencyAmountProps {\n amount: string;\n symbol: string | null | undefined;\n amountClassName?: string;\n iconSize?: number;\n className?: string;\n}\n\nexport function CurrencyAmount({\n amount,\n symbol,\n amountClassName,\n iconSize = 14,\n className,\n}: CurrencyAmountProps) {\n return (\n <span className={cn(\"inline-flex items-center gap-1\", className)}>\n <CurrencyIcon symbol={symbol} size={iconSize} />\n <span className={amountClassName}>{amount}</span>\n </span>\n );\n}\n","\"use client\";\n\nimport {\n Music, Palette, Film, Camera, Gem, Award,\n FileText, BookOpen, File, Building, Code, Layers,\n} from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface IpTypeConfig {\n slug: string;\n label: string;\n icon: React.ElementType;\n colorClass: string;\n bgClass: string;\n /** API ipType value — null means \"nft\" special case */\n apiValue: string | null;\n}\n\nexport const IP_TYPE_CONFIG: IpTypeConfig[] = [\n { slug: \"audio\", label: \"Audio\", icon: Music, colorClass: \"text-violet-400\", bgClass: \"bg-violet-500/10\", apiValue: \"Audio\" },\n { slug: \"video\", label: \"Video\", icon: Film, colorClass: \"text-red-400\", bgClass: \"bg-red-500/10\", apiValue: \"Video\" },\n { slug: \"art\", label: \"Art\", icon: Palette, colorClass: \"text-pink-400\", bgClass: \"bg-pink-500/10\", apiValue: \"Art\" },\n { slug: \"photography\", label: \"Photography\", icon: Camera, colorClass: \"text-amber-400\", bgClass: \"bg-amber-500/10\", apiValue: \"Photography\" },\n { slug: \"nft\", label: \"NFT\", icon: Gem, colorClass: \"text-blue-400\", bgClass: \"bg-blue-500/10\", apiValue: null },\n { slug: \"software\", label: \"Software\", icon: Code, colorClass: \"text-cyan-400\", bgClass: \"bg-cyan-500/10\", apiValue: \"Software\" },\n { slug: \"rwa\", label: \"RWA\", icon: Building, colorClass: \"text-lime-400\", bgClass: \"bg-lime-500/10\", apiValue: \"RWA\" },\n { slug: \"patents\", label: \"Patents\", icon: Award, colorClass: \"text-emerald-400\", bgClass: \"bg-emerald-500/10\", apiValue: \"Patents\" },\n { slug: \"posts\", label: \"Posts\", icon: FileText, colorClass: \"text-orange-400\", bgClass: \"bg-orange-500/10\", apiValue: \"Posts\" },\n { slug: \"publications\", label: \"Publications\", icon: BookOpen, colorClass: \"text-teal-400\", bgClass: \"bg-teal-500/10\", apiValue: \"Publications\" },\n { slug: \"documents\", label: \"Documents\", icon: File, colorClass: \"text-slate-400\", bgClass: \"bg-slate-500/10\", apiValue: \"Documents\" },\n { slug: \"custom\", label: \"Custom\", icon: Layers, colorClass: \"text-indigo-400\", bgClass: \"bg-indigo-500/10\", apiValue: \"Custom\" },\n];\n\nexport const IP_TYPE_MAP = Object.fromEntries(\n IP_TYPE_CONFIG.map((c) => [c.slug, c])\n) as Record<string, IpTypeConfig>;\n\nconst SIZE = {\n sm: { container: \"h-6 w-6\", icon: \"h-3 w-3\" },\n md: { container: \"h-8 w-8\", icon: \"h-4 w-4\" },\n};\n\nexport interface IpTypeBadgeProps {\n ipType: string;\n size?: \"sm\" | \"md\";\n className?: string;\n /** Base URL for IP type pages. Default: \"\" (relative). Example: \"https://medialane.io\" */\n baseUrl?: string;\n}\n\nexport function IpTypeBadge({ ipType, size = \"sm\", className, baseUrl = \"\" }: IpTypeBadgeProps) {\n const config = IP_TYPE_CONFIG.find(\n (c) => c.label === ipType || c.apiValue === ipType\n );\n if (!config) return null;\n const { icon: Icon, colorClass, bgClass, slug, label } = config;\n const { container, icon } = SIZE[size];\n return (\n <a\n href={`${baseUrl}/${slug}`}\n title={label}\n className={cn(\n \"inline-flex items-center justify-center rounded-full\",\n \"transition-opacity hover:opacity-80\",\n bgClass,\n container,\n className\n )}\n onClick={(e) => e.stopPropagation()}\n >\n <Icon className={cn(colorClass, icon)} />\n </a>\n );\n}\n","\"use client\";\n\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport { useTheme } from \"next-themes\";\nimport { useEffect, useState } from \"react\";\n\nexport interface MedialaneIconProps {\n size?: number;\n href?: string;\n className?: string;\n}\n\nexport function MedialaneIcon({ size = 256, href = \"/\", className }: MedialaneIconProps) {\n const { resolvedTheme } = useTheme();\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n if (!mounted) {\n return (\n <Link href={href} className={className}>\n <div style={{ width: size, height: size }} />\n </Link>\n );\n }\n\n return (\n <Link\n href={href}\n className={`transition-opacity hover:opacity-80 drop-shadow-md ${className ?? \"\"}`}\n >\n <Image\n src={resolvedTheme === \"dark\" ? \"/icon.png\" : \"/icon.png\"}\n alt=\"Medialane\"\n width={size}\n height={size}\n priority\n />\n </Link>\n );\n}\n","\"use client\";\n\nimport Link from \"next/link\";\nimport Image from \"next/image\";\nimport { useTheme } from \"next-themes\";\nimport { useEffect, useState } from \"react\";\n\nexport interface MedialaneLogoFullProps {\n width?: number;\n height?: number;\n href?: string;\n className?: string;\n}\n\nexport function MedialaneLogoFull({\n width = 196,\n height = 34,\n href = \"/\",\n className,\n}: MedialaneLogoFullProps) {\n const { resolvedTheme } = useTheme();\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n if (!mounted) {\n return (\n <div className=\"flex items-center space-x-2\">\n <Link href={href} className={className}>\n <div style={{ width, height }} />\n </Link>\n </div>\n );\n }\n\n return (\n <div className=\"flex items-center space-x-2\">\n <Link\n href={href}\n className={`transition-opacity hover:opacity-80 drop-shadow-md ${className ?? \"\"}`}\n >\n {resolvedTheme === \"dark\" ? (\n <Image\n src=\"/medialane-light-logo.png\"\n alt=\"Medialane\"\n width={width}\n height={height}\n priority\n />\n ) : (\n <Image\n src=\"/medialane-dark-logo.png\"\n alt=\"Medialane\"\n width={width}\n height={height}\n priority\n />\n )}\n </Link>\n </div>\n );\n}\n"]}
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ // src/preset/tailwind.ts
4
+ var medialanePreset = {
5
+ theme: {
6
+ extend: {
7
+ colors: {
8
+ "brand-blue": "#3B82F6",
9
+ "brand-navy": "#1E3A5F",
10
+ "brand-rose": "#F43F5E",
11
+ "brand-purple": "#8B5CF6",
12
+ "brand-orange": "#F97316"
13
+ },
14
+ borderRadius: {
15
+ brand: "11px"
16
+ }
17
+ }
18
+ }
19
+ };
20
+ var tailwind_default = medialanePreset;
21
+
22
+ module.exports = tailwind_default;
23
+ //# sourceMappingURL=tailwind.cjs.map
24
+ //# sourceMappingURL=tailwind.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/preset/tailwind.ts"],"names":[],"mappings":";;;AAEA,IAAM,eAAA,GAAmC;AAAA,EACvC,KAAA,EAAO;AAAA,IACL,MAAA,EAAQ;AAAA,MACN,MAAA,EAAQ;AAAA,QACN,YAAA,EAAc,SAAA;AAAA,QACd,YAAA,EAAc,SAAA;AAAA,QACd,YAAA,EAAc,SAAA;AAAA,QACd,cAAA,EAAgB,SAAA;AAAA,QAChB,cAAA,EAAgB;AAAA,OAClB;AAAA,MACA,YAAA,EAAc;AAAA,QACZ,KAAA,EAAO;AAAA;AACT;AACF;AAEJ,CAAA;AAEA,IAAO,gBAAA,GAAQ","file":"tailwind.cjs","sourcesContent":["import type { Config } from \"tailwindcss\";\n\nconst medialanePreset: Partial<Config> = {\n theme: {\n extend: {\n colors: {\n \"brand-blue\": \"#3B82F6\",\n \"brand-navy\": \"#1E3A5F\",\n \"brand-rose\": \"#F43F5E\",\n \"brand-purple\": \"#8B5CF6\",\n \"brand-orange\": \"#F97316\",\n },\n borderRadius: {\n brand: \"11px\",\n },\n },\n },\n};\n\nexport default medialanePreset;\n"]}
@@ -0,0 +1,5 @@
1
+ import { Config } from 'tailwindcss';
2
+
3
+ declare const medialanePreset: Partial<Config>;
4
+
5
+ export { medialanePreset as default };
@@ -0,0 +1,5 @@
1
+ import { Config } from 'tailwindcss';
2
+
3
+ declare const medialanePreset: Partial<Config>;
4
+
5
+ export { medialanePreset as default };
@@ -0,0 +1,22 @@
1
+ // src/preset/tailwind.ts
2
+ var medialanePreset = {
3
+ theme: {
4
+ extend: {
5
+ colors: {
6
+ "brand-blue": "#3B82F6",
7
+ "brand-navy": "#1E3A5F",
8
+ "brand-rose": "#F43F5E",
9
+ "brand-purple": "#8B5CF6",
10
+ "brand-orange": "#F97316"
11
+ },
12
+ borderRadius: {
13
+ brand: "11px"
14
+ }
15
+ }
16
+ }
17
+ };
18
+ var tailwind_default = medialanePreset;
19
+
20
+ export { tailwind_default as default };
21
+ //# sourceMappingURL=tailwind.js.map
22
+ //# sourceMappingURL=tailwind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/preset/tailwind.ts"],"names":[],"mappings":";AAEA,IAAM,eAAA,GAAmC;AAAA,EACvC,KAAA,EAAO;AAAA,IACL,MAAA,EAAQ;AAAA,MACN,MAAA,EAAQ;AAAA,QACN,YAAA,EAAc,SAAA;AAAA,QACd,YAAA,EAAc,SAAA;AAAA,QACd,YAAA,EAAc,SAAA;AAAA,QACd,cAAA,EAAgB,SAAA;AAAA,QAChB,cAAA,EAAgB;AAAA,OAClB;AAAA,MACA,YAAA,EAAc;AAAA,QACZ,KAAA,EAAO;AAAA;AACT;AACF;AAEJ,CAAA;AAEA,IAAO,gBAAA,GAAQ","file":"tailwind.js","sourcesContent":["import type { Config } from \"tailwindcss\";\n\nconst medialanePreset: Partial<Config> = {\n theme: {\n extend: {\n colors: {\n \"brand-blue\": \"#3B82F6\",\n \"brand-navy\": \"#1E3A5F\",\n \"brand-rose\": \"#F43F5E\",\n \"brand-purple\": \"#8B5CF6\",\n \"brand-orange\": \"#F97316\",\n },\n borderRadius: {\n brand: \"11px\",\n },\n },\n },\n};\n\nexport default medialanePreset;\n"]}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@medialane/ui",
3
+ "version": "0.1.0",
4
+ "description": "Shared UI components for Medialane apps",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./preset": {
16
+ "types": "./dist/preset/tailwind.d.ts",
17
+ "import": "./dist/preset/tailwind.js",
18
+ "require": "./dist/preset/tailwind.cjs"
19
+ }
20
+ },
21
+ "license": "MIT",
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "files": ["dist"],
26
+ "scripts": {
27
+ "build": "tsup",
28
+ "dev": "tsup --watch",
29
+ "typecheck": "tsc --noEmit"
30
+ },
31
+ "peerDependencies": {
32
+ "react": ">=18.0.0",
33
+ "react-dom": ">=18.0.0",
34
+ "next": ">=14.0.0",
35
+ "next-themes": ">=0.3.0",
36
+ "lucide-react": ">=0.400.0",
37
+ "tailwind-merge": ">=2.0.0",
38
+ "clsx": ">=2.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "react": "^19.0.0",
42
+ "react-dom": "^19.0.0",
43
+ "next": "^15.0.0",
44
+ "next-themes": "^0.4.0",
45
+ "lucide-react": "^0.400.0",
46
+ "tailwind-merge": "^2.0.0",
47
+ "clsx": "^2.0.0",
48
+ "tailwindcss": "^3.0.0",
49
+ "tsup": "^8.0.0",
50
+ "typescript": "^5.6.0",
51
+ "@types/react": "^19.0.0",
52
+ "@types/react-dom": "^19.0.0"
53
+ }
54
+ }