@kawaiininja/layouts 1.2.0 → 2.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/PcLayout.js CHANGED
@@ -16,10 +16,10 @@ const RailNavThemeToggle = () => {
16
16
  const { isDark, toggleTheme } = useTheme();
17
17
  return (_jsx("button", { onClick: toggleTheme, className: "mt-auto mb-6 mx-auto p-3 rounded-xl text-[rgb(var(--text-tertiary))] hover:text-[rgb(var(--text-primary))] hover:bg-[rgb(var(--bg-tertiary))] transition-all active:scale-90 group", title: isDark ? "Switch to Light Mode" : "Switch to Dark Mode", children: isDark ? (_jsx(Sun, { size: 20, className: "duration-500 group-hover:rotate-180 text-[rgb(var(--color-accent))]" })) : (_jsx(Moon, { size: 20, className: "duration-300 group-hover:-rotate-12 text-[rgb(var(--color-secondary))]" })) }));
18
18
  };
19
- const QuickMenu = ({ visible, items, positionY, selectedIndex, onSelect, }) => {
19
+ const QuickMenu = ({ visible, items, positionY, selectedIndex, onSelect, onMouseEnter, onMouseLeave, }) => {
20
20
  if (!visible || !items || items.length === 0)
21
21
  return null;
22
- return (_jsxs("aside", { className: "fixed right-20 z-[100] min-w-[200px] bg-[rgb(var(--bg-elevated))]/95 backdrop-blur-xl rounded-2xl shadow-2xl p-2 border border-[rgb(var(--color-border))] flex flex-col gap-1 transition-all duration-200 ease-out origin-right", style: {
22
+ return (_jsxs("aside", { onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, className: "fixed right-20 z-[100] min-w-[200px] bg-[rgb(var(--bg-elevated))]/95 backdrop-blur-xl rounded-2xl shadow-2xl p-2 border border-[rgb(var(--color-border))] flex flex-col gap-1 transition-all duration-200 ease-out origin-right", style: {
23
23
  top: positionY,
24
24
  transform: "translateY(-50%) scale(1)",
25
25
  animation: "popIn 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275)",
@@ -143,6 +143,26 @@ const OnyxPcLayoutBase = ({ tabs, user, drawers = {}, onSignOut, onRefresh, isRe
143
143
  selectedIndex: -1,
144
144
  tabId: "",
145
145
  });
146
+ const closeTimer = useRef(null);
147
+ const handleMouseEnter = (tab, e) => {
148
+ if (tab.quickActions?.length > 0) {
149
+ if (closeTimer.current)
150
+ clearTimeout(closeTimer.current);
151
+ const rect = e.currentTarget.getBoundingClientRect();
152
+ setQuickMenu({
153
+ visible: true,
154
+ items: tab.quickActions,
155
+ positionY: rect.top + rect.height / 2,
156
+ selectedIndex: -1,
157
+ tabId: tab.id,
158
+ });
159
+ }
160
+ };
161
+ const handleMouseLeave = () => {
162
+ closeTimer.current = setTimeout(() => {
163
+ setQuickMenu((p) => ({ ...p, visible: false }));
164
+ }, 300);
165
+ };
146
166
  const sidebarWidth = isSidebarOpen ? 260 : 0;
147
167
  // Sync subtab if tab changes
148
168
  useEffect(() => {
@@ -240,19 +260,11 @@ const OnyxPcLayoutBase = ({ tabs, user, drawers = {}, onSignOut, onRefresh, isRe
240
260
  }
241
261
  setQuickMenu((p) => ({ ...p, visible: false }));
242
262
  };
243
- return (_jsxs("div", { className: "bg-[rgb(var(--bg-main))] flex h-screen w-full overflow-hidden text-[rgb(var(--text-primary))]", children: [_jsx(Sidebar, {}), _jsxs("div", { className: "flex-1 flex flex-col min-w-0 relative bg-[rgb(var(--bg-main))]", children: [_jsx(Header, { title: currentTabConfig?.navTitle || currentTabConfig?.label || "App", onMenuClick: () => setIsSidebarOpen(!isSidebarOpen), rightAction: currentTabConfig?.rightAction || rightAction }), _jsx(HorizontalTabs, { tabs: subTabs, active: subTab, onChange: (label) => navigateTo(undefined, label) }), _jsxs("main", { className: "flex-1 overflow-y-auto no-scrollbar relative min-h-0", children: [isRefreshing && (_jsx("div", { className: "absolute top-4 left-1/2 -translate-x-1/2 z-10 p-2 bg-[rgb(var(--bg-surface))] rounded-full shadow-xl border border-[rgb(var(--color-border-subtle))] animate-spin text-[rgb(var(--color-accent))]", children: _jsx(Loader2, { size: 18 }) })), _jsx(AnimatePresence, { mode: "popLayout", custom: motionData, initial: false, children: _jsx(motion.div, { custom: motionData, variants: variants, initial: "enter", animate: "center", exit: "exit", className: "w-full min-h-full", children: _jsx("div", { className: "p-6 md:p-8 max-w-7xl mx-auto", children: subTabs.find((st) => st.label === subTab)?.view &&
244
- React.createElement(subTabs.find((st) => st.label === subTab).view, { onOpenDrawer: setActiveDrawer }) }) }, `${activeTab}-${subTab}`) })] })] }), _jsxs("nav", { className: "w-16 bg-[rgb(var(--bg-surface))] border-l border-[rgb(var(--color-border-subtle))] flex flex-col z-50", children: [_jsxs("div", { ref: scrollContainerRef, className: "flex-1 overflow-y-auto no-scrollbar py-4 w-full relative", children: [_jsx(RailNavIndicator, { height: activeHeight, offset: activeOffset }), tabs.map((tab, idx) => (_jsx(RailNavButton, { title: tab.label, icon: tab.icon, active: activeTab === tab.id, onClick: () => handleNavClick(tab.id), onMouseEnter: (e) => {
245
- if (tab.quickActions?.length > 0) {
246
- const rect = e.currentTarget.getBoundingClientRect();
247
- setQuickMenu({
248
- visible: true,
249
- items: tab.quickActions,
250
- positionY: rect.top + rect.height / 2,
251
- selectedIndex: -1,
252
- tabId: tab.id,
253
- });
254
- }
255
- }, onRegisterRef: (el) => registerButtonRef(idx, el) }, tab.id)))] }), _jsx(RailNavThemeToggle, {})] }), quickMenu.visible && (_jsx("div", { className: "fixed inset-0 z-[90]", onClick: () => setQuickMenu((p) => ({ ...p, visible: false })) })), _jsx(QuickMenu, { ...quickMenu, onSelect: handleQuickAction }), Object.entries(drawers || {}).map(([key, DrawerComp]) => (_jsx(DrawerComp, { isOpen: activeDrawer === key, onClose: () => setActiveDrawer(null) }, key))), _jsx("style", { children: `
263
+ return (_jsxs("div", { className: "bg-[rgb(var(--bg-main))] flex h-screen w-full overflow-hidden text-[rgb(var(--text-primary))]", children: [_jsx(Sidebar, {}), _jsxs("div", { className: "flex-1 flex flex-col min-w-0 relative bg-[rgb(var(--bg-main))]", children: [_jsx(Header, { title: currentTabConfig?.navTitle || currentTabConfig?.label || "App", onMenuClick: () => setIsSidebarOpen(!isSidebarOpen), rightAction: currentTabConfig?.rightAction || rightAction }), _jsx(HorizontalTabs, { tabs: subTabs, active: subTab, onChange: (label) => navigateTo(undefined, label) }), _jsxs("main", { className: "flex-1 overflow-y-auto no-scrollbar relative min-h-0", children: [isRefreshing && (_jsx("div", { className: "absolute top-4 left-1/2 -translate-x-1/2 z-10 p-2 bg-[rgb(var(--bg-surface))] rounded-full shadow-xl border border-[rgb(var(--color-border-subtle))] animate-spin text-[rgb(var(--color-accent))]", children: _jsx(Loader2, { size: 18 }) })), _jsx(AnimatePresence, { mode: "popLayout", custom: motionData, initial: false, children: _jsx(motion.div, { custom: motionData, variants: variants, initial: "enter", animate: "center", exit: "exit", className: "w-full min-h-full", children: _jsx("div", { className: "p-6 md:p-8 max-w-8xl mx-auto", children: subTabs.find((st) => st.label === subTab)?.view &&
264
+ React.createElement(subTabs.find((st) => st.label === subTab).view, { onOpenDrawer: setActiveDrawer }) }) }, `${activeTab}-${subTab}`) })] })] }), _jsxs("nav", { className: "w-16 bg-[rgb(var(--bg-surface))] border-l border-[rgb(var(--color-border-subtle))] flex flex-col z-50", children: [_jsxs("div", { ref: scrollContainerRef, className: "flex-1 overflow-y-auto no-scrollbar py-4 w-full relative", children: [_jsx(RailNavIndicator, { height: activeHeight, offset: activeOffset }), tabs.map((tab, idx) => (_jsx(RailNavButton, { title: tab.label, icon: tab.icon, active: activeTab === tab.id, onClick: () => handleNavClick(tab.id), onMouseEnter: (e) => handleMouseEnter(tab, e), onMouseLeave: handleMouseLeave, onRegisterRef: (el) => registerButtonRef(idx, el) }, tab.id)))] }), _jsx(RailNavThemeToggle, {})] }), _jsx(QuickMenu, { ...quickMenu, onSelect: handleQuickAction, onMouseEnter: () => {
265
+ if (closeTimer.current)
266
+ clearTimeout(closeTimer.current);
267
+ }, onMouseLeave: handleMouseLeave }), Object.entries(drawers || {}).map(([key, DrawerComp]) => (_jsx(DrawerComp, { isOpen: activeDrawer === key, onClose: () => setActiveDrawer(null) }, key))), _jsx("style", { children: `
256
268
  .no-scrollbar::-webkit-scrollbar { display: none; }
257
269
  .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
258
270
  ` })] }));
@@ -0,0 +1,2 @@
1
+ import { AssetStoreProps } from "./types";
2
+ export declare function AssetStore({ config, onPurchase, onDownload, onSupport, onLike, onSearch, isLoggedIn, userCredits, search: externalSearch, onLoadMore, hasMore, isLoading, }: AssetStoreProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,334 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { AlertTriangle, ArrowLeft, BookOpen, Check, ChevronRight, Code, Copy, CreditCard, Download, Gavel, Hash, Heart, Info, Layers, Loader2, Moon, Package, Pause, Play, Search, Shield, Sun, Terminal, } from "lucide-react";
3
+ import React, { useEffect, useMemo, useState } from "react";
4
+ const SyntaxHighlighter = ({ code }) => {
5
+ const highlight = (text) => {
6
+ let html = text
7
+ .replace(/&/g, "&")
8
+ .replace(/</g, "&lt;")
9
+ .replace(/>/g, "&gt;");
10
+ const tokens = [
11
+ {
12
+ name: "comment",
13
+ regex: /\/\/.*|\/\*[\s\S]*?\*\//,
14
+ color: "text-muted italic",
15
+ },
16
+ {
17
+ name: "string",
18
+ regex: /"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`/,
19
+ color: "text-success",
20
+ },
21
+ {
22
+ name: "entity",
23
+ regex: /&amp;|&lt;|&gt;|&quot;|&apos;/,
24
+ color: "text-accent",
25
+ },
26
+ {
27
+ name: "keyword",
28
+ regex: /\b(?:import|from|export|default|function|return|const|let|var|if|else|for|while|try|catch|new|class|extends|await|async)\b/,
29
+ color: "text-accent font-bold",
30
+ },
31
+ {
32
+ name: "number",
33
+ regex: /\b\d+(?:\.\d+)?\b/,
34
+ color: "text-info",
35
+ },
36
+ {
37
+ name: "component",
38
+ regex: /\b[A-Z][a-zA-Z0-9]*\b/,
39
+ color: "text-secondary font-semibold",
40
+ },
41
+ {
42
+ name: "function",
43
+ regex: /\b[a-z0-9_]+(?=\s*\()/,
44
+ color: "text-info font-medium",
45
+ },
46
+ {
47
+ name: "attr",
48
+ regex: /\b[a-z-]+(?==)/i,
49
+ color: "text-accent/80 italic",
50
+ },
51
+ {
52
+ name: "punct",
53
+ regex: /[{}()\[\];,.=+\-*/!%&|<>?:]/,
54
+ color: "text-muted",
55
+ },
56
+ {
57
+ name: "ident",
58
+ regex: /\b[a-z_][a-z0-9_]*\b/i,
59
+ color: "text-primary",
60
+ },
61
+ ];
62
+ const masterRegex = new RegExp(tokens.map((t) => `(${t.regex.source})`).join("|"), "g");
63
+ return html.replace(masterRegex, (match, ...args) => {
64
+ for (let i = 0; i < tokens.length; i++) {
65
+ if (args[i] !== undefined && args[i] === match) {
66
+ return `<span class="${tokens[i].color}">${match}</span>`;
67
+ }
68
+ }
69
+ return match;
70
+ });
71
+ };
72
+ const htmlContent = highlight(code);
73
+ return (_jsxs("div", { className: "bg-elevated rounded-xl p-6 border border-subtle shadow-inner overflow-hidden", children: [_jsxs("div", { className: "flex gap-1.5 mb-6 opacity-30", children: [_jsx("div", { className: "w-2 h-2 rounded-full bg-error" }), _jsx("div", { className: "w-2 h-2 rounded-full bg-warning" }), _jsx("div", { className: "w-2 h-2 rounded-full bg-success" })] }), _jsx("pre", { className: "font-mono text-sm leading-relaxed overflow-x-auto whitespace-pre selection:bg-accent/20 custom-scrollbar", dangerouslySetInnerHTML: { __html: htmlContent } })] }));
74
+ };
75
+ const Badge = ({ children, variant = "default" }) => {
76
+ const styles = {
77
+ default: "text-muted",
78
+ paid: "text-warning",
79
+ free: "text-success",
80
+ accent: "text-accent",
81
+ indigo: "text-accent",
82
+ };
83
+ return (_jsx("span", { className: `text-[10px] font-bold uppercase tracking-widest ${styles[variant] || styles.default}`, children: children }));
84
+ };
85
+ const AssetCardSkeleton = () => (_jsxs("div", { className: "flex flex-col md:flex-row gap-10 items-start animate-pulse", children: [_jsx("div", { className: "shrink-0 w-full md:w-64 aspect-[16/10] bg-surface rounded-xl border border-subtle opacity-50" }), _jsxs("div", { className: "flex-1 w-full py-1 space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "h-4 w-16 bg-surface rounded opacity-60" }), _jsx("div", { className: "h-4 w-8 bg-surface rounded opacity-30" })] }), _jsx("div", { className: "h-5 w-16 bg-surface rounded-full opacity-60" })] }), _jsx("div", { className: "h-7 w-3/4 bg-surface rounded opacity-80" }), _jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "h-3 w-full bg-surface rounded opacity-50" }), _jsx("div", { className: "h-3 w-2/3 bg-surface rounded opacity-50" })] }), _jsxs("div", { className: "flex items-center justify-between pt-4", children: [_jsx("div", { className: "h-3 w-24 bg-surface rounded opacity-30" }), _jsx("div", { className: "h-8 w-24 bg-surface rounded-lg opacity-60" })] })] })] }));
86
+ export function AssetStore({ config, onPurchase, onDownload, onSupport, onLike, onSearch, isLoggedIn = false, userCredits = 0, search: externalSearch, onLoadMore, hasMore = false, isLoading = false, }) {
87
+ const [view, setView] = useState({
88
+ type: "home",
89
+ id: null,
90
+ });
91
+ const [copied, setCopied] = useState(false);
92
+ const [isPlaying, setIsPlaying] = useState(false);
93
+ const [isAudioPlaying, setIsAudioPlaying] = useState(false);
94
+ const videoRef = React.useRef(null);
95
+ const audioRef = React.useRef(null);
96
+ const detailScrollRef = React.useRef(null);
97
+ const handleScroll = (e) => {
98
+ const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
99
+ if (scrollHeight - scrollTop <= clientHeight + 100) {
100
+ if (hasMore && onLoadMore) {
101
+ onLoadMore();
102
+ }
103
+ }
104
+ };
105
+ const toggleVideo = () => {
106
+ if (videoRef.current) {
107
+ if (isPlaying) {
108
+ videoRef.current.pause();
109
+ }
110
+ else {
111
+ videoRef.current.play();
112
+ }
113
+ setIsPlaying(!isPlaying);
114
+ }
115
+ };
116
+ const toggleAudio = () => {
117
+ if (audioRef.current) {
118
+ if (isAudioPlaying) {
119
+ audioRef.current.pause();
120
+ }
121
+ else {
122
+ audioRef.current.play();
123
+ }
124
+ setIsAudioPlaying(!isAudioPlaying);
125
+ }
126
+ };
127
+ const [internalSearch, setInternalSearch] = useState("");
128
+ const search = externalSearch !== undefined ? externalSearch : internalSearch;
129
+ const handleSearchChange = (value) => {
130
+ if (externalSearch === undefined) {
131
+ setInternalSearch(value);
132
+ }
133
+ onSearch?.(value);
134
+ };
135
+ const [isDark, setIsDark] = useState(true);
136
+ const [wishlist, setWishlist] = useState([]);
137
+ const toggleWishlist = (e, id) => {
138
+ if (e)
139
+ e.stopPropagation();
140
+ const item = (config.products || []).find((p) => p.id === id);
141
+ if (item)
142
+ onLike?.(item);
143
+ setWishlist((prev) => prev.includes(id) ? prev.filter((i) => i !== id) : [...prev, id]);
144
+ };
145
+ const filteredItems = useMemo(() => {
146
+ return (config.products || []).filter((item) => item.name.toLowerCase().includes(search.toLowerCase()));
147
+ }, [config.products, search]);
148
+ const activeItem = useMemo(() => (config.products || []).find((i) => i.id === view.id), [config.products, view.id]);
149
+ useEffect(() => {
150
+ if (view.type === "detail" && detailScrollRef.current) {
151
+ detailScrollRef.current.scrollTop = 0;
152
+ }
153
+ }, [view.type, view.id]);
154
+ useEffect(() => {
155
+ if (view.type === "detail" && activeItem) {
156
+ const authorName = activeItem.author?.name || "onyx";
157
+ const authorSlug = authorName
158
+ .toLowerCase()
159
+ .replace(/[^a-z0-9]+/g, "-")
160
+ .replace(/^-+|-+$/g, "");
161
+ const productSlug = activeItem.id;
162
+ const newUrl = new URL(window.location.href);
163
+ newUrl.searchParams.set("product", `@${authorSlug}/${productSlug}`);
164
+ window.history.pushState({}, "", newUrl.toString());
165
+ }
166
+ else if (view.type === "home") {
167
+ const newUrl = new URL(window.location.href);
168
+ newUrl.searchParams.delete("product");
169
+ window.history.pushState({}, "", newUrl.toString());
170
+ }
171
+ }, [view, activeItem]);
172
+ const renderContent = (content) => {
173
+ const processText = (text) => {
174
+ // Regex for Bold (**), Italic (*), Code (`), Link ([...](...))
175
+ const combinedRegex = /(\*\*[^*]+\*\*)|(\*[^*]+\*)|(`[^`]+`)|(\[([^\]]+)\]\((https?:\/\/[^)]+)\))/g;
176
+ const parts = [];
177
+ let lastIndex = 0;
178
+ let match;
179
+ while ((match = combinedRegex.exec(text)) !== null) {
180
+ if (match.index > lastIndex) {
181
+ parts.push(text.substring(lastIndex, match.index));
182
+ }
183
+ const fullMatch = match[0];
184
+ // Bold (**text**)
185
+ if (fullMatch.startsWith("**")) {
186
+ parts.push(_jsx("strong", { className: "font-bold text-primary", children: fullMatch.slice(2, -2) }, match.index));
187
+ }
188
+ // Italic (*text*)
189
+ else if (fullMatch.startsWith("*")) {
190
+ parts.push(_jsx("em", { className: "italic text-secondary", children: fullMatch.slice(1, -1) }, match.index));
191
+ }
192
+ // Inline Code (`text`)
193
+ else if (fullMatch.startsWith("`")) {
194
+ parts.push(_jsx("code", { className: "font-mono text-xs bg-surface border border-subtle px-1.5 py-0.5 rounded text-accent font-bold", children: fullMatch.slice(1, -1) }, match.index));
195
+ }
196
+ // Link ([label](url))
197
+ else if (fullMatch.startsWith("[")) {
198
+ const label = match[5];
199
+ const url = match[6];
200
+ parts.push(_jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: "text-accent underline decoration-accent/30 underline-offset-4 hover:decoration-accent transition-all font-medium", children: label }, match.index));
201
+ }
202
+ lastIndex = combinedRegex.lastIndex;
203
+ }
204
+ if (lastIndex < text.length) {
205
+ parts.push(text.substring(lastIndex));
206
+ }
207
+ return parts.length > 0 ? parts : text;
208
+ };
209
+ const lines = Array.isArray(content) ? content : content.split("\n");
210
+ return lines.map((line, i) => {
211
+ const trimmed = line.trim();
212
+ // Blockquote (> text)
213
+ if (trimmed.startsWith(">")) {
214
+ return (_jsx("blockquote", { className: "border-l-4 border-accent pl-4 py-1 my-2 italic text-muted bg-surface/50 rounded-r-lg", children: processText(trimmed.substring(1).trim()) }, i));
215
+ }
216
+ // Bullet points (+, -, *)
217
+ if (/^[\+\-\*]\s/.test(trimmed)) {
218
+ return (_jsxs("div", { className: "flex items-start gap-2 my-1 pl-4", children: [_jsx("span", { className: "text-accent font-bold mt-1.5 w-1.5 h-1.5 rounded-full bg-current shrink-0" }), _jsx("span", { children: processText(trimmed.substring(2).trim()) })] }, i));
219
+ }
220
+ return (_jsx("div", { className: "mb-1", children: processText(line) }, i));
221
+ });
222
+ };
223
+ const toggleTheme = () => setIsDark(!isDark);
224
+ const ThemeToggleBtn = () => (_jsx("button", { onClick: toggleTheme, className: "p-2.5 rounded-xl hover:bg-surface text-secondary transition-all active:scale-95 border border-subtle shadow-sm", title: isDark ? "Switch to Light Mode" : "Switch to Dark Mode", children: isDark ? _jsx(Sun, { size: 18 }) : _jsx(Moon, { size: 18 }) }));
225
+ return (_jsxs("div", { className: "h-screen-ui flex flex-col font-sans overflow-hidden", "data-theme": isDark ? "dark" : "light", children: [_jsx("div", { className: "flex-1 flex flex-col bg-main text-primary transition-colors duration-normal overflow-hidden selection:bg-accent/20", children: view.type === "detail" && activeItem ? (_jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", children: [_jsxs("nav", { className: "shrink-0 px-8 py-6 flex items-center justify-between border-b border-subtle bg-surface/50 backdrop-blur-md z-header", children: [_jsxs("button", { onClick: () => setView({ type: "home", id: null }), className: "flex items-center gap-2 text-xs font-bold text-secondary hover:text-accent transition-colors", children: [_jsx(ArrowLeft, { size: 16 }), " Library Overview"] }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsx(ThemeToggleBtn, {}), _jsx("button", { onClick: () => onSupport?.(activeItem), className: "hidden md:block px-5 py-2 border border-subtle bg-surface text-secondary hover:text-primary rounded-lg text-xs font-bold transition-all active:scale-95", children: "Enterprise Support" }), _jsx("button", { onClick: () => activeItem.pricing?.type === "paid"
226
+ ? onPurchase?.(activeItem)
227
+ : onDownload?.(activeItem), className: "hidden md:block px-6 py-2 bg-accent text-primary rounded-lg text-xs font-bold transition-all hover:brightness-110 active:scale-95 shadow-glow", children: !isLoggedIn
228
+ ? "Login to Access"
229
+ : activeItem.pricing?.type === "paid"
230
+ ? "Buy"
231
+ : activeItem.pricing?.credits
232
+ ? `Use ${activeItem.pricing.credits} Credits`
233
+ : "Download" })] })] }), _jsx("main", { ref: detailScrollRef, className: "flex-1 overflow-y-auto custom-scrollbar scroll-smooth", children: _jsx("div", { className: "max-w-[1600px] mx-auto px-8 md:px-16 py-20 w-full", children: _jsxs("div", { className: "flex flex-col xl:flex-row gap-24 relative", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("header", { className: "mb-20", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-6", children: [_jsx("span", { className: "text-accent text-[10px] font-bold uppercase tracking-[0.2em]", children: "PROTOCOL" }), _jsx(ChevronRight, { size: 10, className: "text-muted" }), _jsx("span", { className: "text-muted text-[10px] font-bold uppercase tracking-[0.2em]", children: activeItem.category }), activeItem.tags?.map((tag) => (_jsxs(React.Fragment, { children: [_jsx(ChevronRight, { size: 10, className: "text-muted" }), _jsxs("span", { className: "text-accent text-[10px] font-bold uppercase tracking-[0.2em] bg-accent/5 px-2 py-0.5 rounded", children: ["#", tag] })] }, tag)))] }), _jsx("h1", { className: "text-4xl lg:text-6xl font-extrabold tracking-tight mb-8 leading-[1.1] uppercase italic transition-colors text-primary", children: activeItem.name }), activeItem.author && (_jsxs("div", { className: "flex items-center gap-3 mb-8", children: [_jsx("img", { src: activeItem.author.avatar, alt: activeItem.author.name, className: "w-8 h-8 rounded-full border border-subtle object-cover" }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-[10px] uppercase tracking-widest text-muted font-bold", children: "Created By" }), _jsx("span", { className: "text-sm font-bold text-primary", children: activeItem.author.name })] })] })), activeItem.type === "audio" && activeItem.previewUrl ? (_jsxs("div", { className: "mb-12 relative group isolation-auto rounded-3xl", children: [activeItem.image && (_jsxs(_Fragment, { children: [_jsx("div", { className: `absolute inset-0 bg-cover bg-center blur-3xl transition-all duration-[3000ms] ease-in-out ${isAudioPlaying
234
+ ? "opacity-80 scale-125 saturate-150"
235
+ : "opacity-30 scale-100 saturate-50"}`, style: {
236
+ backgroundImage: `url(${activeItem.image})`,
237
+ } }), _jsx("div", { className: `absolute inset-0 bg-cover bg-center blur-2xl mix-blend-overlay transition-all duration-700 ${isAudioPlaying
238
+ ? "animate-pulse opacity-90 scale-110"
239
+ : "opacity-0 scale-95"}`, style: {
240
+ backgroundImage: `url(${activeItem.image})`,
241
+ animationDuration: "3s",
242
+ } }), _jsx("div", { className: `absolute inset-0 bg-cover bg-center blur-xl mix-blend-screen transition-all duration-300 ${isAudioPlaying
243
+ ? "animate-pulse opacity-60 scale-105"
244
+ : "opacity-0 scale-90"}`, style: {
245
+ backgroundImage: `url(${activeItem.image})`,
246
+ animationDuration: "1.5s",
247
+ } })] })), _jsxs("div", { className: "relative rounded-3xl overflow-hidden border border-subtle aspect-square md:aspect-video bg-black/40 backdrop-blur-xl flex items-center justify-center shadow-2xl", children: [activeItem.image && (_jsx("div", { className: "absolute inset-0 w-full h-full object-cover opacity-30 mix-blend-overlay", children: _jsx("img", { src: activeItem.image, className: "w-full h-full object-cover" }) })), _jsxs("div", { className: "relative z-10 w-full max-w-xs md:max-w-md p-6 md:p-8 bg-surface/30 backdrop-blur-md rounded-3xl border border-white/10 shadow-xl flex flex-col items-center gap-6 md:gap-8 mx-4", children: [activeItem.image && (_jsxs("div", { className: `relative w-40 h-40 rounded-full shadow-[0_0_40px_-5px_rgba(var(--color-accent),0.4)] transition-all duration-700 ${isAudioPlaying
248
+ ? "animate-[spin_4s_linear_infinite]"
249
+ : ""}`, children: [_jsx("img", { src: activeItem.image, alt: "Album Art", className: "w-full h-full rounded-full object-cover border-4 border-surface/50" }), _jsx("div", { className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-8 h-8 bg-surface/80 rounded-full border border-white/20" })] })), _jsxs("div", { className: "w-full text-center space-y-4", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-2xl font-black text-white mb-2 tracking-tight drop-shadow-md", children: activeItem.name }), _jsx("p", { className: "text-xs text-white/60 uppercase tracking-[0.2em] font-bold", children: "High Fidelity Audio Preview" })] }), _jsx("button", { onClick: toggleAudio, className: "w-16 h-16 rounded-full bg-white text-black flex items-center justify-center mx-auto hover:scale-110 active:scale-95 transition-all shadow-lg shadow-white/20", children: isAudioPlaying ? (_jsx(Pause, { size: 24, className: "fill-black" })) : (_jsx(Play, { size: 24, className: "fill-black ml-1" })) }), _jsx("audio", { ref: audioRef, src: activeItem.previewUrl, onContextMenu: (e) => e.preventDefault(), onEnded: () => setIsAudioPlaying(false), className: "hidden" })] })] })] })] })) : (activeItem.type === "video" ||
250
+ activeItem.type === "app" ||
251
+ activeItem.type === "software") &&
252
+ activeItem.previewUrl ? (_jsxs("div", { className: "mb-12 relative group isolation-auto", children: [_jsx("div", { className: "absolute inset-0 bg-cover bg-center blur-3xl opacity-50 scale-110 transition-opacity duration-700", style: {
253
+ backgroundImage: `url(${activeItem.image})`,
254
+ } }), _jsxs("div", { className: "relative rounded-3xl overflow-hidden border border-subtle aspect-video bg-black shadow-2xl", children: [_jsx("video", { ref: videoRef, src: activeItem.previewUrl, className: "w-full h-full object-cover", poster: activeItem.image, onEnded: () => setIsPlaying(false), onContextMenu: (e) => e.preventDefault() }), _jsx("button", { onClick: toggleVideo, className: "absolute inset-0 flex items-center justify-center bg-black/20 hover:bg-black/10 transition-colors group z-20", children: _jsx("div", { className: `w-20 h-20 rounded-full bg-surface/20 backdrop-blur-md flex items-center justify-center border border-white/20 transition-all transform ${isPlaying
255
+ ? "scale-90 opacity-0 group-hover:opacity-100"
256
+ : "scale-100 opacity-100 hover:scale-110"}`, children: isPlaying ? (_jsx(Pause, { size: 32, className: "text-white fill-white" })) : (_jsx(Play, { size: 32, className: "text-white fill-white ml-2" })) }) })] })] })) : activeItem.images && activeItem.images.length > 0 ? (_jsxs("div", { className: "mb-12 space-y-4", children: [_jsx("div", { className: "rounded-3xl overflow-hidden border border-subtle aspect-video bg-tertiary", children: _jsx("img", { src: activeItem.images[0], id: "gallery-main", alt: activeItem.name, className: "w-full h-full object-cover" }) }), _jsx("div", { className: "flex gap-4 overflow-x-auto pb-2 scrollbar-none", children: activeItem.images.map((img, idx) => (_jsx("button", { onClick: () => {
257
+ const mainEl = document.getElementById("gallery-main");
258
+ if (mainEl)
259
+ mainEl.src = img;
260
+ }, className: "shrink-0 w-32 aspect-video rounded-xl overflow-hidden border border-subtle hover:border-accent transition-all active:scale-95", children: _jsx("img", { src: img, className: "w-full h-full object-cover", alt: `${activeItem.name} preview ${idx}` }, idx) }, idx))) })] })) : (activeItem.image && (_jsx("div", { className: "mb-12 rounded-3xl overflow-hidden border border-subtle aspect-video bg-tertiary", children: _jsx("img", { src: activeItem.image, alt: activeItem.name, className: "w-full h-full object-cover" }) }))), _jsx("div", { className: "text-xl font-light leading-relaxed max-w-3xl transition-colors text-secondary", children: activeItem.description }), _jsxs("div", { className: "mt-12 flex items-center gap-10 py-6 border-y transition-colors border-subtle", children: [activeItem.type === "code" && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-[9px] font-bold text-muted uppercase tracking-[0.2em]", children: "Version" }), _jsxs("span", { className: "text-sm font-bold transition-colors text-primary", children: ["v", activeItem.version] })] }), _jsx("div", { className: "w-[1px] h-8 transition-colors bg-subtle" })] })), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-[9px] font-bold text-muted uppercase tracking-[0.2em]", children: "Last Update" }), _jsx("span", { className: "text-sm font-bold transition-colors text-primary", children: activeItem.updated })] }), activeItem.type === "code" && (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-[1px] h-8 transition-colors bg-subtle" }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-[9px] font-bold text-muted uppercase tracking-[0.2em]", children: "Framework" }), _jsx("span", { className: "text-sm font-bold transition-colors text-primary", children: activeItem.framework })] })] }))] })] }), _jsxs("div", { className: "space-y-32", children: [(activeItem.type === "code" ||
261
+ activeItem.type === "app") &&
262
+ activeItem.installation && (_jsxs("section", { id: "setup", className: "scroll-mt-32", children: [_jsx("h3", { className: "text-[10px] font-bold text-muted uppercase tracking-[0.2em] mb-8 flex items-center gap-2", children: activeItem.installation.npm ? (_jsxs(_Fragment, { children: [_jsx(Terminal, { size: 14, className: "text-accent" }), " ", "Installation Command"] })) : (_jsxs(_Fragment, { children: [_jsx(Download, { size: 14, className: "text-accent" }), " ", "Downloads"] })) }), activeItem.installation.npm && (_jsxs("div", { className: "bg-elevated rounded-xl p-5 font-mono text-sm border border-subtle flex justify-between items-center group transition-colors shadow-sm mb-4", children: [_jsx("code", { className: "text-accent font-bold", children: activeItem.installation.npm }), copied ? (_jsx(Check, { size: 16, className: "text-success animate-bounce" })) : (_jsx("button", { onPointerDown: () => {
263
+ navigator.clipboard.writeText(activeItem.installation.npm);
264
+ setCopied(true);
265
+ setTimeout(() => setCopied(false), 2000);
266
+ }, className: "p-1 hover:bg-surface rounded transition-colors touch-manipulation", children: _jsx(Copy, { size: 16, className: "text-muted opacity-40 group-hover:opacity-100 cursor-pointer transition-opacity" }) }))] })), activeItem.installation.downloads && (_jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: activeItem.installation.downloads.map((download, i) => (_jsxs("a", { href: download.url, target: "_blank", rel: "noopener noreferrer", className: "flex items-center gap-4 bg-tertiary hover:bg-surface border border-subtle rounded-xl p-4 transition-all group", children: [_jsx("div", { className: "p-2 bg-main rounded-lg text-accent", children: _jsx(Download, { size: 20 }) }), _jsxs("div", { children: [_jsx("div", { className: "font-bold capitalize", children: download.platform }), _jsx("div", { className: "text-xs text-muted", children: "Direct Download" })] })] }, i))) }))] })), activeItem.type === "code" && activeItem.usage && (_jsxs("section", { id: "usage", className: "scroll-mt-32", children: [_jsxs("h3", { className: "text-[10px] font-bold text-muted uppercase tracking-[0.2em] mb-8 flex items-center gap-2", children: [_jsx(Code, { size: 14, className: "text-accent" }), " ", "Implementation Steps"] }), activeItem.usage.steps ? (_jsx("div", { className: "space-y-10", children: activeItem.usage.steps.map((step, idx) => (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "flex items-center justify-center w-6 h-6 rounded-full bg-accent/10 text-accent text-[10px] font-bold border border-accent/20 shadow-glow shadow-accent/20", children: idx + 1 }), _jsx("h4", { className: "text-sm font-bold text-primary tracking-tight", children: step.title })] }), _jsx(SyntaxHighlighter, { code: step.code })] }, idx))) })) : (_jsx(SyntaxHighlighter, { code: activeItem.usage.example }))] })), activeItem.guide && (_jsxs("section", { id: "docs", className: "space-y-20 scroll-mt-32", children: [_jsx("h3", { className: "text-[10px] font-bold text-muted uppercase tracking-[0.2em] mb-12 flex items-center gap-2", children: activeItem.type !== "code" ? (_jsxs(_Fragment, { children: [_jsx(Info, { size: 14, className: "text-accent" }), " Asset Specifications"] })) : (_jsxs(_Fragment, { children: [_jsx(BookOpen, { size: 14, className: "text-accent" }), " ", "Technical Guide & Documentation"] })) }), _jsx("div", { className: "flex flex-col gap-20", children: activeItem.guide.map((g, i) => {
267
+ return (_jsxs("article", { id: `sec-${i}`, className: "group scroll-mt-32", children: [_jsxs("div", { className: "flex items-center gap-4 mb-6", children: [_jsxs("span", { className: "text-[10px] font-bold px-2.5 py-1 rounded tracking-widest uppercase transition-all group-hover:scale-110 bg-tertiary text-accent", children: ["SEC ", String(i + 1).padStart(2, "0")] }), _jsxs("h2", { className: "text-2xl font-bold flex items-center gap-2 transition-colors group-hover:text-accent text-primary", children: [g.title, _jsx(Hash, { size: 18, className: "opacity-0 group-hover:opacity-100 transition-all translate-x-[-10px] group-hover:translate-x-0 text-muted/30" })] })] }), _jsxs("div", { className: "leading-relaxed text-lg font-light transition-colors text-secondary space-y-4", children: [_jsx("div", { children: renderContent(g.detail) }), g.example && (_jsxs("div", { className: "mt-6", children: [_jsx("h5", { className: "text-[10px] font-bold text-muted uppercase tracking-widest mb-3", children: "Usage Example" }), _jsx(SyntaxHighlighter, { code: g.example })] }))] })] }, i));
268
+ }) })] })), activeItem.type === "code" && activeItem.props && (_jsxs("section", { id: "api", className: "scroll-mt-32", children: [_jsxs("h3", { className: "text-[10px] font-bold text-muted uppercase tracking-[0.2em] mb-8 flex items-center gap-2", children: [_jsx(Layers, { size: 14, className: "text-accent" }), " API Reference"] }), _jsx("div", { className: "border border-subtle rounded-xl overflow-hidden bg-surface shadow-sm", children: _jsxs("table", { className: "w-full text-left text-sm", children: [_jsx("thead", { children: _jsxs("tr", { className: "bg-tertiary text-muted font-bold border-b border-subtle", children: [_jsx("th", { className: "px-6 py-5", children: "Property" }), _jsx("th", { className: "px-6 py-5", children: "Type Definition" }), _jsx("th", { className: "px-6 py-5", children: "Initial State" }), _jsx("th", { className: "px-6 py-5", children: "Description" })] }) }), _jsx("tbody", { className: "divide-y divide-subtle", children: activeItem.props.map((p, i) => (_jsxs("tr", { className: "hover:bg-tertiary/50 transition-colors", children: [_jsx("td", { className: "px-6 py-5 font-mono text-accent text-xs font-bold", children: p.name }), _jsx("td", { className: "px-6 py-5 text-secondary", children: Array.isArray(p.type) ? (_jsx("div", { className: "flex flex-wrap gap-1", children: p.type.map((t, k) => (_jsx("code", { className: "text-[10px] px-1.5 py-0.5 rounded border border-subtle bg-surface text-secondary font-bold font-mono", children: t }, k))) })) : (_jsx("code", { className: "text-xs font-mono text-secondary", children: p.type })) }), _jsx("td", { className: "px-6 py-5 text-muted font-mono text-xs", children: p.default }), _jsx("td", { className: "px-6 py-5 text-secondary text-xs leading-relaxed max-w-xs", children: p.description || "-" })] }, i))) })] }) })] })), (activeItem.type === "app" ||
269
+ activeItem.type === "software") && (_jsxs("section", { id: "meta", className: "grid grid-cols-1 md:grid-cols-3 gap-6 scroll-mt-32", children: [activeItem.size && (_jsxs("div", { className: "bg-elevated rounded-xl p-5 border border-subtle h-full", children: [_jsx("h4", { className: "text-[10px] font-bold text-muted uppercase tracking-[0.2em] mb-2", children: "Size" }), _jsx("p", { className: "text-primary font-bold text-lg", children: activeItem.size })] })), activeItem.requirements && (_jsxs("div", { className: "bg-elevated rounded-xl p-5 border border-subtle h-full", children: [_jsx("h4", { className: "text-[10px] font-bold text-muted uppercase tracking-[0.2em] mb-2", children: "Requirements" }), _jsx("p", { className: "text-primary font-bold text-lg", children: activeItem.requirements })] })), activeItem.languages && (_jsxs("div", { className: "bg-elevated rounded-xl p-5 border border-subtle h-full", children: [_jsx("h4", { className: "text-[10px] font-bold text-muted uppercase tracking-[0.2em] mb-3", children: "Languages" }), _jsx("div", { className: "flex flex-wrap gap-2", children: activeItem.languages.map((lang, i) => (_jsx("span", { className: "text-[10px] font-bold px-2 py-1 bg-surface border border-subtle rounded text-secondary uppercase tracking-wider", children: lang }, i))) })] }))] })), activeItem.protectionPolicy && (_jsxs("section", { id: "policy", className: "scroll-mt-32", children: [_jsxs("h3", { className: "text-[10px] font-bold text-muted uppercase tracking-[0.2em] mb-12 flex items-center gap-2", children: [_jsx(Shield, { size: 14, className: activeItem.protectionPolicy.isStrict
270
+ ? "text-error"
271
+ : "text-accent" }), " ", "Policy & Rights"] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "flex items-start gap-4", children: [_jsx(AlertTriangle, { size: 18, className: activeItem.protectionPolicy.isStrict
272
+ ? "text-error/60"
273
+ : "text-muted" }), _jsxs("div", { className: "space-y-2", children: [_jsx("h4", { className: "text-sm font-bold text-primary", children: activeItem.protectionPolicy.isStrict
274
+ ? "Strict Intellectual Property Enforcement"
275
+ : "Ownership & Usage Rights" }), _jsx("div", { className: "text-secondary text-sm leading-relaxed font-light", children: renderContent(activeItem.protectionPolicy.text) })] })] }), activeItem.protectionPolicy.isStrict && (_jsxs("div", { className: "flex items-center gap-2 text-[10px] font-bold text-error uppercase tracking-widest pl-8 opacity-80", children: [_jsx(Gavel, { size: 12 }), " Legal Action initiated upon violation"] }))] })] })), _jsxs("section", { className: "pt-20 pb-40 border-t border-subtle text-center", children: [_jsx("h3", { className: "text-[10px] font-bold text-muted uppercase tracking-[0.4em] mb-12", children: "Production Ready Modules" }), _jsxs("button", { onClick: () => activeItem.pricing?.type === "paid"
276
+ ? onPurchase?.(activeItem)
277
+ : onDownload?.(activeItem), className: "group relative px-12 py-6 bg-accent text-primary rounded-2xl text-lg font-black uppercase tracking-[0.2em] transition-all hover:brightness-110 active:scale-95 shadow-[0_0_50px_-12px_rgba(var(--color-accent),0.5)] shadow-glow flex items-center gap-4 mx-auto overflow-hidden", children: [_jsx("span", { className: "relative z-10 transition-transform duration-300 group-hover:-translate-x-1", children: !isLoggedIn
278
+ ? "Login to Access"
279
+ : activeItem.pricing?.type === "paid"
280
+ ? `Purchase ${activeItem.name}`
281
+ : activeItem.pricing?.credits
282
+ ? `Use ${activeItem.pricing.credits} Credits`
283
+ : activeItem.type === "code"
284
+ ? "Download Source"
285
+ : activeItem.type === "app" ||
286
+ activeItem.type === "software"
287
+ ? "Download App"
288
+ : "Download Original Asset" }), activeItem.pricing.type === "paid" ? (_jsx(CreditCard, { size: 22, className: "relative z-10 transition-all duration-300 opacity-0 -translate-x-4 group-hover:opacity-100 group-hover:translate-x-0" })) : (_jsx(Download, { size: 22, className: "relative z-10 transition-all duration-300 opacity-0 -translate-x-4 group-hover:opacity-100 group-hover:translate-x-0" }))] }), _jsxs("p", { className: "mt-8 text-xs text-muted font-medium", children: ["Includes ", activeItem.license?.name || "MIT License", " & Lifetime Updates"] })] })] })] }), _jsxs("aside", { className: "hidden xl:block w-72 sticky top-0 self-start pt-4 h-fit", children: [_jsx("h4", { className: "text-[10px] font-bold text-muted uppercase tracking-widest mb-8 px-1", children: activeItem.type !== "code"
289
+ ? "Asset Info"
290
+ : "On this page" }), _jsx("nav", { className: "space-y-6", children: (activeItem.type === "code" || activeItem.type === "app"
291
+ ? [
292
+ { id: "setup", title: "Installation" },
293
+ ...(activeItem.usage
294
+ ? [{ id: "usage", title: "Implementation" }]
295
+ : []),
296
+ { id: "docs", title: "Documentation" },
297
+ { id: "api", title: "API Reference" },
298
+ ...(activeItem.protectionPolicy
299
+ ? [{ id: "policy", title: "Policy" }]
300
+ : []),
301
+ ]
302
+ : [
303
+ { id: "docs", title: "Overview" },
304
+ ...(activeItem.protectionPolicy
305
+ ? [{ id: "policy", title: "Policy" }]
306
+ : []),
307
+ ]).map((section) => (_jsx("a", { href: `#${section.id}`, className: "block text-[11px] font-bold uppercase tracking-[0.2em] truncate border-l-2 border-transparent pl-4 transition-all hover:border-accent hover:text-accent text-muted", children: section.title }, section.id))) })] })] }) }) })] })) : (_jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", children: [_jsxs("header", { className: "shrink-0 px-8 md:px-16 py-12 border-b border-subtle flex flex-col md:flex-row md:items-center justify-between gap-10 bg-surface/30 backdrop-blur-sm z-header", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs("h1", { className: "text-3xl font-bold tracking-tight", children: [config.title, " ", _jsx("span", { className: "text-accent", children: config.accentTitle })] }), _jsx("p", { className: "text-sm text-secondary font-medium", children: config.description })] }), _jsxs("div", { className: "flex items-center gap-6", children: [_jsxs("div", { className: "relative w-full max-w-xs group", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 text-muted group-focus-within:text-accent transition-colors", size: 18 }), _jsx("input", { type: "text", placeholder: "Search library...", className: "w-full pl-10 pr-4 py-3 bg-tertiary border border-subtle rounded-xl focus:border-accent focus:ring-1 focus:ring-accent outline-none text-sm transition-all text-primary", value: search, onChange: (e) => handleSearchChange(e.target.value) })] }), _jsx(ThemeToggleBtn, {})] })] }), _jsx("main", { className: "flex-1 overflow-y-auto p-8 md:p-16 custom-scrollbar", onScroll: handleScroll, children: _jsxs("div", { className: "max-w-7xl mx-auto", children: [_jsxs("div", { className: "flex flex-col gap-16", children: [isLoading &&
308
+ Array.from({ length: 3 }).map((_, i) => (_jsx(AssetCardSkeleton, {}, i))), !isLoading &&
309
+ filteredItems.map((item) => (_jsxs("div", { onClick: () => setView({ type: "detail", id: item.id }), className: "group cursor-pointer flex flex-col md:flex-row gap-10 items-start transition-all", children: [_jsxs("div", { className: "shrink-0 w-full md:w-64 aspect-[16/10] relative flex items-center justify-center transition-all bg-tertiary rounded-xl group-hover:bg-accent/5 border border-subtle group-hover:border-accent/30 overflow-hidden", children: [_jsx("button", { onClick: (e) => toggleWishlist(e, item.id), className: `absolute top-3 right-3 p-2 rounded-lg backdrop-blur-md transition-all active:scale-90 z-10 ${wishlist.includes(item.id)
310
+ ? "bg-accent/20 text-accent"
311
+ : "bg-main/50 text-muted hover:text-accent opacity-0 group-hover:opacity-100"}`, children: _jsx(Heart, { size: 14, fill: wishlist.includes(item.id)
312
+ ? "currentColor"
313
+ : "none" }) }), item.images && item.images.length > 0 ? (_jsx("img", { src: item.images[0], alt: item.name, className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-110" })) : item.image ? (_jsx("img", { src: item.image, alt: item.name, className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-110" })) : (_jsx(Package, { size: 40, className: "text-muted group-hover:text-accent transition-all duration-normal" }))] }), _jsxs("div", { className: "flex-1 py-1", children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Badge, { variant: "accent", children: item.category }), item.type === "code" && (_jsxs("span", { className: "text-muted text-[10px] uppercase tracking-widest font-bold opacity-50", children: ["v", item.version] }))] }), _jsx(Badge, { variant: item.pricing?.type === "paid" ? "paid" : "free", children: item.pricing?.type === "paid"
314
+ ? `$${item.pricing.price}`
315
+ : item.pricing?.credits
316
+ ? `${item.pricing.credits} CR`
317
+ : "FREE" })] }), _jsx("h3", { className: "text-2xl font-bold mb-3 group-hover:text-accent transition-colors", children: item.name }), _jsx("p", { className: "text-secondary leading-relaxed mb-6 line-clamp-2", children: item.description }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2 text-[10px] font-bold text-muted uppercase tracking-[0.2em] transition-colors group-hover:text-primary", children: ["Explore Asset", " ", _jsx(ChevronRight, { size: 14, className: "group-hover:translate-x-1 transition-transform" })] }), _jsx("button", { onClick: (e) => {
318
+ e.stopPropagation();
319
+ if (item.pricing.type === "paid") {
320
+ onPurchase?.(item);
321
+ }
322
+ else {
323
+ onDownload?.(item);
324
+ }
325
+ }, className: "px-6 py-2.5 bg-accent text-primary rounded-lg text-[10px] font-bold uppercase tracking-widest transition-all hover:brightness-110 active:scale-95 shadow-glow", children: item.pricing.type === "paid"
326
+ ? "Buy Pro"
327
+ : "Get Free" })] })] })] }, item.id)))] }), hasMore && (_jsx("div", { className: "flex justify-center py-12", children: _jsx(Loader2, { className: "animate-spin text-accent", size: 32 }) })), filteredItems.length === 0 && (_jsxs("div", { className: "text-center py-32", children: [_jsx("div", { className: "inline-flex items-center justify-center w-20 h-20 rounded-full bg-tertiary mb-6", children: _jsx(Search, { size: 32, className: "text-muted" }) }), _jsxs("p", { className: "text-secondary font-medium", children: ["No assets found matching \"", search, "\""] })] }))] }) })] })) }), _jsx("style", { children: `
328
+ .custom-scrollbar::-webkit-scrollbar { width: 6px; height: 6px; }
329
+ .custom-scrollbar::-webkit-scrollbar-track { background: transparent; }
330
+ .custom-scrollbar::-webkit-scrollbar-thumb { background: rgb(var(--color-border)); border-radius: 20px; }
331
+ .custom-scrollbar::-webkit-scrollbar-thumb:hover { background: rgb(var(--color-accent)); }
332
+ [data-theme="light"] .custom-scrollbar::-webkit-scrollbar-thumb { background: #cbd5e1; }
333
+ ` })] }));
334
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./AssetStore";
2
+ export * from "./types";
@@ -0,0 +1,2 @@
1
+ export * from "./AssetStore";
2
+ export * from "./types";
@@ -0,0 +1,83 @@
1
+ export interface AssetProduct {
2
+ id: string;
3
+ name: string;
4
+ version: string;
5
+ category: string;
6
+ framework: string;
7
+ description: string;
8
+ type?: "code" | "image" | "audio" | "video" | "book" | "app" | "software";
9
+ previewUrl?: string;
10
+ tags?: string[];
11
+ pricing: {
12
+ type: "free" | "paid";
13
+ price?: number;
14
+ currency?: string;
15
+ credits?: number;
16
+ };
17
+ installation?: {
18
+ npm?: string;
19
+ npx?: string;
20
+ downloads?: {
21
+ platform: "windows" | "mac" | "linux" | "android" | "ios";
22
+ url: string;
23
+ }[];
24
+ };
25
+ usage?: {
26
+ import: string;
27
+ example: string;
28
+ steps?: {
29
+ title: string;
30
+ code: string;
31
+ }[];
32
+ };
33
+ props?: {
34
+ name: string;
35
+ type: string | string[];
36
+ default: string;
37
+ description?: string;
38
+ }[];
39
+ license: {
40
+ type: string;
41
+ name: string;
42
+ };
43
+ updated: string;
44
+ guide?: {
45
+ title: string;
46
+ detail: string | string[];
47
+ example?: string;
48
+ }[];
49
+ image?: string;
50
+ images?: string[];
51
+ author?: {
52
+ name: string;
53
+ avatar: string;
54
+ };
55
+ legalNotice?: string;
56
+ protectionPolicy?: {
57
+ isStrict: boolean;
58
+ text: string;
59
+ };
60
+ size?: string;
61
+ requirements?: string;
62
+ languages?: string[];
63
+ }
64
+ export interface AssetStoreConfig {
65
+ title: string;
66
+ accentTitle: string;
67
+ description: string;
68
+ products: AssetProduct[];
69
+ }
70
+ export interface AssetStoreProps {
71
+ config: AssetStoreConfig;
72
+ isLoggedIn?: boolean;
73
+ userCredits?: number;
74
+ onPurchase?: (product: AssetProduct) => void;
75
+ onDownload?: (product: AssetProduct) => void;
76
+ onSupport?: (product: AssetProduct) => void;
77
+ onLike?: (product: AssetProduct) => void;
78
+ onSearch?: (query: string) => void;
79
+ search?: string;
80
+ onLoadMore?: () => void;
81
+ hasMore?: boolean;
82
+ isLoading?: boolean;
83
+ }
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export * from "./asset-store/AssetStore";
2
+ export * from "./asset-store/types";
1
3
  export * from "./MobileLayout";
2
4
  export * from "./PcLayout";
3
5
  export * from "./ResponsiveLayout";
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ export * from "./asset-store/AssetStore";
2
+ export * from "./asset-store/types";
1
3
  export * from "./MobileLayout";
2
4
  export * from "./PcLayout";
3
5
  export * from "./ResponsiveLayout";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kawaiininja/layouts",
3
- "version": "1.2.0",
3
+ "version": "2.1.0",
4
4
  "description": "High-performance, premium mobile-first layouts for the Onyx Framework, featuring gesture-driven navigation, radial quick actions, and integrated theme support.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",