slashh-ui 1.3.2
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/README.md +36 -0
- package/dist/__registry__/index.d.ts +1 -0
- package/dist/__registry__/index.js +492 -0
- package/dist/app/(auth)/layout.d.ts +5 -0
- package/dist/app/(auth)/layout.js +8 -0
- package/dist/app/(auth)/login/page.d.ts +1 -0
- package/dist/app/(auth)/login/page.js +45 -0
- package/dist/app/(protected)/component/[id]/page.d.ts +5 -0
- package/dist/app/(protected)/component/[id]/page.js +13 -0
- package/dist/app/(protected)/component/page.d.ts +2 -0
- package/dist/app/(protected)/component/page.js +26 -0
- package/dist/app/(protected)/docs/page.d.ts +2 -0
- package/dist/app/(protected)/docs/page.js +43 -0
- package/dist/app/account/page.d.ts +1 -0
- package/dist/app/account/page.js +38 -0
- package/dist/app/api/me/route.d.ts +8 -0
- package/dist/app/api/me/route.js +20 -0
- package/dist/app/layout.d.ts +6 -0
- package/dist/app/layout.js +21 -0
- package/dist/app/page.d.ts +2 -0
- package/dist/app/page.js +11 -0
- package/dist/app/pricing/page.d.ts +2 -0
- package/dist/app/pricing/page.js +5 -0
- package/dist/bin/index.d.ts +2 -0
- package/dist/bin/index.js +27 -0
- package/dist/components/smooth-scroll.d.ts +4 -0
- package/dist/components/smooth-scroll.js +21 -0
- package/dist/components/toast.d.ts +11 -0
- package/dist/components/toast.js +39 -0
- package/dist/components/ui/IndustryProof.d.ts +1 -0
- package/dist/components/ui/IndustryProof.js +55 -0
- package/dist/components/ui/ShowcaseContainer.d.ts +8 -0
- package/dist/components/ui/ShowcaseContainer.js +139 -0
- package/dist/components/ui/dot-cursor.d.ts +2 -0
- package/dist/components/ui/dot-cursor.js +70 -0
- package/dist/components/ui/featuredComponents.d.ts +2 -0
- package/dist/components/ui/featuredComponents.js +14 -0
- package/dist/components/ui/footer.d.ts +2 -0
- package/dist/components/ui/footer.js +5 -0
- package/dist/components/ui/hero.d.ts +3 -0
- package/dist/components/ui/hero.js +21 -0
- package/dist/components/ui/navbar.d.ts +3 -0
- package/dist/components/ui/navbar.js +102 -0
- package/dist/components/ui/pricing.d.ts +2 -0
- package/dist/components/ui/pricing.js +26 -0
- package/dist/hooks/use-component-search.d.ts +5 -0
- package/dist/hooks/use-component-search.js +37 -0
- package/dist/lib/actions/auth.action.d.ts +8 -0
- package/dist/lib/actions/auth.action.js +66 -0
- package/dist/lib/auth.d.ts +1 -0
- package/dist/lib/auth.js +15 -0
- package/dist/lib/email.d.ts +1 -0
- package/dist/lib/email.js +42 -0
- package/dist/lib/prisma.d.ts +2 -0
- package/dist/lib/prisma.js +8 -0
- package/dist/lib/registry.d.ts +1 -0
- package/dist/lib/registry.js +16 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +5 -0
- package/dist/middleware/middleware.d.ts +5 -0
- package/dist/middleware/middleware.js +19 -0
- package/dist/next.config.d.ts +3 -0
- package/dist/next.config.js +4 -0
- package/dist/prisma.config.d.ts +3 -0
- package/dist/prisma.config.js +13 -0
- package/dist/registry/details/buttons/neubrutal-button-details.d.ts +2 -0
- package/dist/registry/details/buttons/neubrutal-button-details.js +25 -0
- package/dist/registry/details/cursor/dot-cursor-details.d.ts +2 -0
- package/dist/registry/details/cursor/dot-cursor-details.js +5 -0
- package/dist/registry/details/navbar/floating-navbar-details.d.ts +2 -0
- package/dist/registry/details/navbar/floating-navbar-details.js +5 -0
- package/dist/registry/details/scrollbars/minimal-scrollbar-details.d.ts +0 -0
- package/dist/registry/details/scrollbars/minimal-scrollbar-details.js +1 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.js +31 -0
- package/dist/registry/ui/buttons/neubrutal-button.d.ts +6 -0
- package/dist/registry/ui/buttons/neubrutal-button.js +18 -0
- package/dist/registry/ui/cursors/dot-cursor.d.ts +2 -0
- package/dist/registry/ui/cursors/dot-cursor.js +70 -0
- package/dist/registry/ui/navbars/floating-navbar.d.ts +2 -0
- package/dist/registry/ui/navbars/floating-navbar.js +35 -0
- package/dist/registry/ui/scrollbars/minimal-scrollbar.d.ts +2 -0
- package/dist/registry/ui/scrollbars/minimal-scrollbar.js +171 -0
- package/dist/scripts/build-registry.d.ts +1 -0
- package/dist/scripts/build-registry.js +47 -0
- package/dist/src/commands/add.d.ts +1 -0
- package/dist/src/commands/add.js +64 -0
- package/dist/src/commands/init.d.ts +1 -0
- package/dist/src/commands/init.js +88 -0
- package/dist/src/commands/list.d.ts +1 -0
- package/dist/src/commands/list.js +37 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +28 -0
- package/dist/src/utils/get-pkg-manager.d.ts +1 -0
- package/dist/src/utils/get-pkg-manager.js +10 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { Copy, Check, Terminal, Code2, ChevronRight, Command, Moon, Info, Maximize2, PanelLeft, Home, } from 'lucide-react';
|
|
5
|
+
const TechIcons = {
|
|
6
|
+
Framer: () => (_jsx("svg", { width: '14', height: '14', viewBox: '0 0 24 24', fill: 'currentColor', children: _jsx("path", { d: 'M0 0l12 12L24 0H0zm0 12l12 12V12H0z' }) })),
|
|
7
|
+
Tailwind: () => (_jsx("svg", { width: '14', height: '14', viewBox: '0 0 24 24', fill: '#38BDF8', children: _jsx("path", { d: 'M12.001 4.8c-3.2 0-5.2 1.6-6 4.8 1.2-1.6 2.6-2.2 4.2-1.8.913.228 1.565.89 2.288 1.624C13.666 10.618 15.027 12 18.001 12c3.2 0 5.2-1.6 6-4.8-1.2 1.6-2.6 2.2-4.2 1.8-.913-.228-1.565-.89-2.288-1.624C16.337 6.182 14.976 4.8 12.001 4.8zm-6 7.2c-3.2 0-5.2 1.6-6 4.8 1.2-1.6 2.6-2.2 4.2-1.8.913.228 1.565.89 2.288 1.624 1.177 1.194 2.538 2.576 5.512 2.576 3.2 0 5.2-1.6 6-4.8-1.2 1.6-2.6 2.2-4.2 1.8-.913-.228-1.565-.89-2.288-1.624C10.337 13.382 8.976 12 6.001 12z' }) })),
|
|
8
|
+
React: () => (_jsx("svg", { xmlns: 'http://www.w3.org/2000/svg', width: '24px', height: '14px', viewBox: '0 0 569 512', children: _jsxs("g", { fill: '#58C4DC', children: [_jsx("path", { d: 'M285.5,201 C255.400481,201 231,225.400481 231,255.5 C231,285.599519 255.400481,310 285.5,310 C315.599519,310 340,285.599519 340,255.5 C340,225.400481 315.599519,201 285.5,201' }), _jsx("path", { d: 'M568.959856,255.99437 C568.959856,213.207656 529.337802,175.68144 466.251623,150.985214 C467.094645,145.423543 467.85738,139.922107 468.399323,134.521063 C474.621631,73.0415145 459.808523,28.6686204 426.709856,9.5541429 C389.677085,-11.8291748 337.36955,3.69129898 284.479928,46.0162134 C231.590306,3.69129898 179.282771,-11.8291748 142.25,9.5541429 C109.151333,28.6686204 94.3382249,73.0415145 100.560533,134.521063 C101.102476,139.922107 101.845139,145.443621 102.708233,151.02537 C97.4493791,153.033193 92.2908847,155.161486 87.3331099,157.39017 C31.0111824,182.708821 0,217.765415 0,255.99437 C0,298.781084 39.6220545,336.307301 102.708233,361.003527 C101.845139,366.565197 101.102476,372.066633 100.560533,377.467678 C94.3382249,438.947226 109.151333,483.32012 142.25,502.434597 C153.629683,508.887578 166.52439,512.186771 179.603923,511.991836 C210.956328,511.991836 247.567589,495.487529 284.479928,465.972527 C321.372196,495.487529 358.003528,511.991836 389.396077,511.991836 C402.475265,512.183856 415.36922,508.884856 426.75,502.434597 C459.848667,483.32012 474.661775,438.947226 468.439467,377.467678 C467.897524,372.066633 467.134789,366.565197 466.291767,361.003527 C529.377946,336.347457 569,298.761006 569,255.99437' })] }) })),
|
|
9
|
+
Gsap: () => (_jsxs("svg", { xmlns: 'http://www.w3.org/2000/svg', width: '24', height: '24', fill: 'currentColor', viewBox: '0 0 24 24', children: [_jsx("path", { d: 'm7.83,11.76h0s-.26,1.15-.26,1.15c-.01.06-.08.11-.15.11h-.32s-.04.02-.05.04c-.29.99-.69,1.68-1.21,2.09-.45.35-1,.51-1.73.51-.66,0-1.1-.21-1.48-.63-.5-.55-.7-1.46-.58-2.55.22-2.05,1.29-4.12,3.34-4.12.62,0,1.11.19,1.45.57.36.41.54,1.02.54,1.82,0,.07-.06.13-.13.13h-1.5c-.05,0-.1-.05-.1-.1-.01-.55-.18-.82-.5-.82-.58,0-.91.78-1.09,1.21-.25.6-.38,1.26-.35,1.92.01.3.06.73.35.91.26.16.62.05.84-.12.22-.17.4-.48.47-.75.01-.04.01-.07,0-.08-.01-.01-.04-.02-.06-.02h-.39s-.08-.02-.11-.05c-.02-.02-.03-.06-.02-.09l.26-1.14c.01-.06.07-.1.13-.11h0s2.53,0,2.53,0c0,0,.01,0,.02,0,.07,0,.11.07.11.14h0Z' }), _jsx("path", { d: 'm12.18,10.45c0,.07-.06.13-.13.13h-1.38c-.09,0-.17-.07-.17-.16,0-.4-.14-.6-.42-.6s-.47.18-.47.48c0,.34.19.65.74,1.18.72.68,1.01,1.28,1,2.08-.02,1.29-.9,2.12-2.23,2.12-.68,0-1.2-.18-1.54-.54-.35-.36-.51-.9-.48-1.59,0-.07.06-.13.13-.13h1.43s.08.02.1.05c.02.03.03.06.03.09-.02.25.03.43.13.54.06.07.15.1.26.1.26,0,.42-.19.42-.51,0-.28-.08-.53-.57-1.03-.63-.61-1.19-1.24-1.17-2.23.01-.58.24-1.1.64-1.48.43-.4,1.01-.61,1.69-.61.68,0,1.2.2,1.53.58.32.36.47.88.46,1.54h0Z' }), _jsx("path", { d: 'm16.47,15.43v-6.84c.01-.07-.05-.13-.12-.13,0,0,0,0,0,0h-2.14c-.07,0-.1.06-.12.1l-3.1,6.82h0s0,0,0,0c-.03.08.03.17.12.17h1.5c.08,0,.13-.02.16-.08l.3-.71c.04-.09.04-.1.15-.1h1.43c.1,0,.1,0,.1.1l-.03.66c0,.07.06.13.13.13,0,0,0,0,0,0h1.51s.07-.02.1-.04c.02-.02.03-.06.03-.09Zm-2.65-2.28s-.02,0-.03,0c-.02,0-.03-.02-.03-.04,0,0,0,0,0,0,0-.01,0-.02.01-.04l1.07-2.65s.02-.05.03-.08c.02-.04.04-.04.05-.01,0,.02-.12,2.72-.12,2.72-.01.1-.01.11-.11.11h-.86s0-.01,0-.01h0s0,0,0,0Z' }), _jsx("path", { d: 'm19.51,8.46h-1.14c-.06,0-.13.03-.14.1l-1.58,6.86s0,.06.02.09c.03.03.07.05.11.05h1.42c.08,0,.13-.04.14-.1,0,0,.17-.78.17-.78.01-.06,0-.11-.06-.14-.03-.01-.05-.03-.08-.04l-.25-.13-.24-.13-.09-.05s-.03-.02-.02-.04c0-.03.02-.05.05-.05h.78c.23,0,.47-.01.69-.05,1.61-.3,2.68-1.59,2.71-3.34.03-1.5-.81-2.26-2.48-2.26,0,0,0,0,0,0Zm-.39,4.08h-.03c-.07,0-.08,0-.08,0,0,0,.45-1.98.45-1.98.01-.06.01-.09-.02-.11-.05-.02-.7-.37-.7-.37-.02,0-.03-.02-.02-.04,0-.03.02-.05.05-.05h1.04c.32,0,.5.3.49.79-.01.85-.42,1.74-1.17,1.77h0Z' })] })),
|
|
10
|
+
Clsx: () => (_jsx("svg", { width: '14', height: '14', viewBox: '0 0 128 128', children: _jsx("path", { fill: '#cb3837', d: 'M2 38.5h124v43.71H64v7.29H36.44v-7.29H2zm6.89 36.43h13.78V53.07h6.89v21.86h6.89V45.79H8.89zm34.44-29.14v36.42h13.78v-7.28h13.78V45.79zm13.78 7.29H64v14.56h-6.89zm20.67-7.29v29.14h13.78V53.07h6.89v21.86h6.89V53.07h6.89v21.86h6.89V45.79z' }) })),
|
|
11
|
+
LucideReact: () => (_jsxs("svg", { xmlns: 'http://www.w3.org/2000/svg', width: '15', height: '15', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round', children: [_jsx("path", { d: 'M14 12C14 9.79086 12.2091 8 10 8C7.79086 8 6 9.79086 6 12C6 16.4183 9.58172 20 14 20C18.4183 20 22 16.4183 22 12C22 8.446 20.455 5.25285 18 3.05557', stroke: '#fff' }), _jsx("path", { d: 'M10 12C10 14.2091 11.7909 16 14 16C16.2091 16 18 14.2091 18 12C18 7.58172 14.4183 4 10 4C5.58172 4 2 7.58172 2 12C2 15.5841 3.57127 18.8012 6.06253 21', stroke: '#F56565' })] })),
|
|
12
|
+
};
|
|
13
|
+
const PrerequisiteTag = ({ name, icon, packageName, }) => {
|
|
14
|
+
const [copied, setCopied] = useState(false);
|
|
15
|
+
const handleCopy = (e) => {
|
|
16
|
+
e.stopPropagation();
|
|
17
|
+
navigator.clipboard.writeText(`npm install ${packageName}`);
|
|
18
|
+
setCopied(true);
|
|
19
|
+
setTimeout(() => setCopied(false), 2000);
|
|
20
|
+
};
|
|
21
|
+
return (_jsxs("div", { onClick: handleCopy, className: 'flex items-center gap-2 px-3 py-1.5 bg-[#0c0c0c] border border-white/5 rounded-lg hover:border-white/10 transition-all group cursor-pointer active:scale-95', children: [_jsx("span", { className: 'group-hover:scale-110 transition-transform duration-300', children: copied ? _jsx(Check, { size: 12, className: "text-white" }) : icon }), _jsx("span", { className: 'text-sm font-medium text-zinc-400 group-hover:text-zinc-200 transition-colors', children: copied ? 'Copied!' : name })] }));
|
|
22
|
+
};
|
|
23
|
+
const DocsPage = () => {
|
|
24
|
+
const [copiedCli, setCopiedCli] = useState(false);
|
|
25
|
+
const [copiedInstall, setCopiedInstall] = useState(false);
|
|
26
|
+
const [copiedUtils, setCopiedUtils] = useState(false);
|
|
27
|
+
const cliCommand = 'npx slash-ui@latest init';
|
|
28
|
+
const installDeps = 'npm add clsx framer-motion lucide-react tailwind-merge';
|
|
29
|
+
const utilsCode = `import clsx, { ClassValue } from "clsx"
|
|
30
|
+
import { twMerge } from "tailwind-merge"
|
|
31
|
+
|
|
32
|
+
export function cn(...inputs: ClassValue[]) {
|
|
33
|
+
return twMerge(clsx(inputs))
|
|
34
|
+
}`;
|
|
35
|
+
const handleCopy = (text, setter) => {
|
|
36
|
+
navigator.clipboard.writeText(text);
|
|
37
|
+
setter(true);
|
|
38
|
+
setTimeout(() => setter(false), 2000);
|
|
39
|
+
};
|
|
40
|
+
return (_jsxs("div", { className: 'min-h-screen text-white font-sans selection:bg-white/20', children: [_jsxs("header", { className: 'max-w-3xl mx-auto pt-40 pb-20 px-6', children: [_jsxs("div", { className: 'flex items-center gap-2 text-zinc-500 text-md font-mono mb-8 tracking-[0.2em] uppercase', children: ["Docs ", _jsx(ChevronRight, { size: 10 }), " Introduction"] }), _jsx("h1", { className: 'text-5xl md:text-7xl font-bold text-white mb-8 tracking-tighter leading-[0.9]', children: "Quick Start" }), _jsx("p", { className: 'text-sm font-cartographCF leading-relaxed mb-12 max-w-2xl', children: "Slash UI is a collection of high-end animation registries. It's designed to be highly performant and easy to use." }), _jsxs("div", { onClick: () => handleCopy(cliCommand, setCopiedCli), className: 'group relative bg-[#0c0c0c] border border-white/5 rounded-2xl p-6 transition-all hover:border-white/20 shadow-2xl cursor-pointer', children: [_jsxs("div", { className: 'flex items-center justify-between mb-4', children: [_jsxs("div", { className: 'flex items-center gap-2 text-sm font-bold text-zinc-600 uppercase tracking-widest font-mono', children: [_jsx(Terminal, { size: 14 }), " CLI"] }), copiedCli ? _jsx(Check, { size: 16, className: "text-emerald-500" }) : _jsx(Copy, { size: 16, className: 'text-zinc-500 group-hover:text-white transition-colors' })] }), _jsxs("div", { className: 'flex items-center gap-3 text-sm', children: [_jsx("span", { className: 'text-zinc-800 font-cartographCF text-md select-none', children: "$" }), _jsx("code", { className: 'text-white font-cartographCF text-md', children: cliCommand })] })] })] }), _jsxs("section", { className: 'max-w-3xl mx-auto py-24 px-6 border-t border-white/5', children: [_jsx("h2", { className: 'text-3xl font-switzer font-bold text-white mb-4 tracking-tight', children: "Interface Symbols" }), _jsxs("div", { className: 'divide-y divide-white/[0.03] font-cartographCF', children: [_jsx(SymbolRow, { icon: _jsx(Home, { size: 20 }), label: 'Home', desc: 'Navigate to the home page' }), _jsx(SymbolRow, { icon: _jsx(Code2, { size: 20 }), label: 'Source code', desc: 'Copy the component logic' }), _jsx(SymbolRow, { icon: _jsx(Command, { size: 20 }), label: 'Search', desc: 'Search components quickly' }), _jsx(SymbolRow, { icon: _jsx(Moon, { size: 20 }), label: 'Theme Toggle', desc: 'Change between light & dark modes' }), _jsx(SymbolRow, { icon: _jsx(Info, { size: 20 }), label: 'Component Info', desc: 'View component metadata' }), _jsx(SymbolRow, { icon: _jsx(Maximize2, { size: 20 }), label: 'Fullscreen View', desc: 'View component in fullscreen' }), _jsx(SymbolRow, { icon: _jsx(PanelLeft, { size: 20 }), label: 'Panel Left', desc: 'Toggle left panel visibility' })] })] }), _jsxs("section", { className: 'max-w-3xl mx-auto py-24 px-6 border-t border-white/5', children: [_jsx("h2", { className: 'text-3xl font-switzer font-bold text-white mb-12', children: "Prerequisites" }), _jsxs("div", { className: 'flex flex-wrap gap-3 mb-16 font-cartographCF', children: [_jsx(PrerequisiteTag, { name: 'framer-motion', icon: _jsx(TechIcons.Framer, {}), packageName: "framer-motion" }), _jsx(PrerequisiteTag, { name: 'tailwindcss', icon: _jsx(TechIcons.Tailwind, {}), packageName: "tailwindcss" }), _jsx(PrerequisiteTag, { name: 'react', icon: _jsx(TechIcons.React, {}), packageName: "react" }), _jsx(PrerequisiteTag, { name: 'clsx', icon: _jsx(TechIcons.Clsx, {}), packageName: "clsx" }), _jsx(PrerequisiteTag, { name: 'gsap', icon: _jsx(TechIcons.Gsap, {}), packageName: "gsap" }), _jsx(PrerequisiteTag, { name: 'Lucide React', icon: _jsx(TechIcons.LucideReact, {}), packageName: "lucide-react" })] }), _jsxs("div", { className: 'mt-16', children: [_jsx("p", { className: 'text-md font-mono text-zinc-600 uppercase tracking-widest mb-6', children: "Install Dependencies" }), _jsxs("div", { onClick: () => handleCopy(installDeps, setCopiedInstall), className: 'bg-[#0c0c0c] border border-white/5 rounded-xl p-5 flex items-center justify-between group hover:border-white/10 transition-all cursor-pointer', children: [_jsx("code", { className: 'text-sm font-cartographCF text-zinc-400', children: installDeps }), copiedInstall ? _jsx(Check, { size: 14, className: "text-emerald-500" }) : _jsx(Copy, { size: 14, className: 'text-zinc-700 group-hover:text-white transition-colors' })] })] }), _jsxs("div", { className: 'mt-20', children: [_jsx("p", { className: 'text-md font-mono text-zinc-600 uppercase tracking-widest mb-6', children: "Setup Lib" }), _jsxs("div", { className: 'bg-[#0c0c0c] border border-white/5 rounded-2xl p-8 relative font-cartographCF text-sm leading-relaxed overflow-hidden', children: [_jsx("div", { className: 'text-zinc-600 mb-4 select-none', children: "// lib/utils.ts" }), _jsxs("div", { className: 'space-y-1', children: [_jsxs("p", { children: [_jsx("span", { className: 'text-pink-400', children: "import" }), " clsx, { ClassValue } ", _jsx("span", { className: 'text-pink-400', children: "from" }), " ", _jsx("span", { className: 'text-emerald-400', children: "\"clsx\"" })] }), _jsxs("p", { children: [_jsx("span", { className: 'text-pink-400', children: "import" }), " { twMerge } ", _jsx("span", { className: 'text-pink-400', children: "from" }), " ", _jsx("span", { className: 'text-emerald-400', children: "\"tailwind-merge\"" })] }), _jsx("div", { className: 'h-4' }), _jsxs("p", { children: [_jsx("span", { className: 'text-pink-400', children: "export function" }), " ", _jsx("span", { className: 'text-red-400', children: "cn" }), "(...inputs: ClassValue[]) {"] }), _jsxs("p", { className: 'pl-6', children: [_jsx("span", { className: 'text-pink-400', children: "return" }), " ", _jsx("span", { className: 'text-red-400', children: "twMerge" }), "(", _jsx("span", { className: 'text-red-400', children: "clsx" }), "(inputs))"] }), _jsx("p", { children: "}" })] }), _jsx("div", { onClick: () => handleCopy(utilsCode, setCopiedUtils), className: "absolute top-8 right-8 cursor-pointer", children: copiedUtils ? _jsx(Check, { size: 14, className: "text-emerald-500" }) : _jsx(Copy, { size: 14, className: 'text-zinc-700 hover:text-white transition-colors' }) })] })] }), _jsxs("div", { className: 'mt-32', children: [_jsx("h2", { className: 'text-md font-mono text-zinc-600 uppercase tracking-widest mb-6', children: "Keep In Mind" }), _jsx("p", { className: 'text-md font-cartographCF text-white leading-relaxed tracking-tight', children: "Most components here are recreations of the best out there. I don't claim to be the original creator. This is my attempt to reverse-engineer and add extra features." })] })] }), _jsx("footer", { className: 'max-w-3xl mx-auto py-40 px-6 border-t border-white/5 text-center', children: _jsx("div", { className: 'mb-10 text-6xl font-hoshiko tracking-wider text-white', children: "Slash/Ui" }) })] }));
|
|
41
|
+
};
|
|
42
|
+
const SymbolRow = ({ icon, label, desc }) => (_jsxs("div", { className: 'flex items-center justify-between py-6 group', children: [_jsxs("div", { className: 'flex items-center gap-10', children: [_jsx("span", { className: 'text-zinc-600 group-hover:text-white transition-all duration-300', children: icon }), _jsx("span", { className: 'text-zinc-300 font-medium text-sm tracking-tight', children: label })] }), _jsx("span", { className: 'text-[11px] text-zinc-600 font-mono opacity-0 group-hover:opacity-100 transition-opacity', children: desc })] }));
|
|
43
|
+
export default DocsPage;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function UserProfile(): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cookies } from 'next/headers';
|
|
3
|
+
import { redirect } from 'next/navigation';
|
|
4
|
+
import { prisma } from '@/lib/prisma';
|
|
5
|
+
import { logout } from '@/lib/actions/auth.action';
|
|
6
|
+
import jwt from 'jsonwebtoken';
|
|
7
|
+
import Link from 'next/link';
|
|
8
|
+
export default async function UserProfile() {
|
|
9
|
+
var _a;
|
|
10
|
+
const cookieStore = await cookies();
|
|
11
|
+
const token = (_a = cookieStore.get('access_token')) === null || _a === void 0 ? void 0 : _a.value;
|
|
12
|
+
if (!token) {
|
|
13
|
+
redirect('/login');
|
|
14
|
+
}
|
|
15
|
+
let email;
|
|
16
|
+
try {
|
|
17
|
+
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
|
18
|
+
email = decoded.email;
|
|
19
|
+
}
|
|
20
|
+
catch (_b) {
|
|
21
|
+
redirect('/login');
|
|
22
|
+
}
|
|
23
|
+
const user = await prisma.user.findUnique({
|
|
24
|
+
where: { email },
|
|
25
|
+
});
|
|
26
|
+
if (!user) {
|
|
27
|
+
redirect('/login');
|
|
28
|
+
}
|
|
29
|
+
const formattedDate = new Date(user.createdAt).toLocaleDateString('en-IN', {
|
|
30
|
+
year: 'numeric',
|
|
31
|
+
month: 'long',
|
|
32
|
+
day: 'numeric',
|
|
33
|
+
});
|
|
34
|
+
return (_jsx("div", { className: 'min-h-screen text-white flex items-center justify-center px-4', children: _jsxs("main", { className: 'w-full max-w-xl', children: [_jsxs("header", { className: 'mb-10 text-center', children: [_jsx("p", { className: 'text-[10px] uppercase tracking-[0.2em] text-gray-500 font-medium mb-3', children: "Logged in as" }), _jsx("h1", { className: 'text-2xl md:text-3xl font-semibold tracking-tight break-all', children: email })] }), _jsxs("div", { className: 'space-y-0 text-sm', children: [_jsxs("div", { className: 'flex justify-between py-2 border-b border-white/5 text-[10px] uppercase tracking-widest text-gray-500 mb-2', children: [_jsx("span", { children: "Type" }), _jsx("span", { children: "Details" })] }), _jsx(Row, { label: 'Action', value: 'Logout', isAction: true, action: logout }), _jsx(Row, { label: 'Date of join', value: formattedDate }), _jsx(Row, { label: 'Membership', value: 'Free' }), _jsx(Row, { label: 'Components Access', value: '36+' })] }), _jsx(Link, { href: '/pricing', className: 'block text-center py-4 mt-5 w-full bg-zinc-900 hover:bg-zinc-800 transition-all duration-400 rounded-xl cursor-pointer', children: "Unlock full access" })] }) }));
|
|
35
|
+
}
|
|
36
|
+
function Row({ label, value, isAction = false, action, }) {
|
|
37
|
+
return (_jsxs("div", { className: 'flex items-center justify-between py-5 border-b border-white/10', children: [_jsx("span", { className: 'text-gray-200', children: label }), isAction && action ? (_jsx("form", { action: action, children: _jsx("button", { type: 'submit', className: 'text-white hover:text-red-400 transition-colors cursor-pointer', children: value }) })) : (_jsx("span", { className: 'text-gray-400', children: value }))] }));
|
|
38
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { cookies } from 'next/headers';
|
|
2
|
+
import { NextResponse } from 'next/server';
|
|
3
|
+
import jwt from 'jsonwebtoken';
|
|
4
|
+
export async function GET() {
|
|
5
|
+
var _a;
|
|
6
|
+
const cookieStore = await cookies();
|
|
7
|
+
const token = (_a = cookieStore.get('access_token')) === null || _a === void 0 ? void 0 : _a.value;
|
|
8
|
+
if (!token) {
|
|
9
|
+
return NextResponse.json({ user: null });
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
|
13
|
+
return NextResponse.json({
|
|
14
|
+
user: { email: decoded.email },
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
catch (_b) {
|
|
18
|
+
return NextResponse.json({ user: null });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Geist, Geist_Mono } from 'next/font/google';
|
|
3
|
+
import './globals.css';
|
|
4
|
+
import Navbar from '@/components/ui/navbar';
|
|
5
|
+
import { SearchProvider } from '@/hooks/use-component-search';
|
|
6
|
+
import SmoothScroll from '@/components/smooth-scroll';
|
|
7
|
+
const geistSans = Geist({
|
|
8
|
+
variable: '--font-geist-sans',
|
|
9
|
+
subsets: ['latin'],
|
|
10
|
+
});
|
|
11
|
+
const geistMono = Geist_Mono({
|
|
12
|
+
variable: '--font-geist-mono',
|
|
13
|
+
subsets: ['latin'],
|
|
14
|
+
});
|
|
15
|
+
export const metadata = {
|
|
16
|
+
title: 'Slash/U!',
|
|
17
|
+
description: '',
|
|
18
|
+
};
|
|
19
|
+
export default function RootLayout({ children, }) {
|
|
20
|
+
return (_jsx("html", { lang: 'en', children: _jsx("body", { className: `${geistSans.variable} ${geistMono.variable} antialiased text-white`, children: _jsx(SmoothScroll, { children: _jsxs(SearchProvider, { children: [_jsx(Navbar, {}), children] }) }) }) }));
|
|
21
|
+
}
|
package/dist/app/page.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Navbar from '@/components/ui/navbar';
|
|
3
|
+
import Hero from '@/components/ui/hero';
|
|
4
|
+
import Footer from '@/components/ui/footer';
|
|
5
|
+
import FeaturedComponents from '@/components/ui/featuredComponents';
|
|
6
|
+
import Pricing from '@/components/ui/pricing';
|
|
7
|
+
import IndustryProof from '@/components/ui/IndustryProof';
|
|
8
|
+
const page = () => {
|
|
9
|
+
return (_jsxs("div", { children: [_jsx(Navbar, {}), _jsx(Hero, {}), _jsx(FeaturedComponents, {}), _jsx(IndustryProof, {}), _jsx(Pricing, {}), _jsx(Footer, {})] }));
|
|
10
|
+
};
|
|
11
|
+
export default page;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { addCommand } from '../src/commands/add.js';
|
|
4
|
+
import { listCommand } from '../src/commands/list.js';
|
|
5
|
+
import { initCommand } from '../src/commands/init.js'; // 1. Import your new initCommand
|
|
6
|
+
const program = new Command();
|
|
7
|
+
program
|
|
8
|
+
.name('slash-ui')
|
|
9
|
+
.description('CLI for Slash-UI component library')
|
|
10
|
+
.version('1.2.9'); // 2. Bump version for the new release
|
|
11
|
+
// 3. Register the 'init' command
|
|
12
|
+
program
|
|
13
|
+
.command('init')
|
|
14
|
+
.description('Initialize your project for Slash UI')
|
|
15
|
+
.action(initCommand);
|
|
16
|
+
// Register the 'add' command
|
|
17
|
+
program
|
|
18
|
+
.command('add')
|
|
19
|
+
.description('Add a component to your project')
|
|
20
|
+
.argument('<component>', 'the component to add')
|
|
21
|
+
.action(addCommand);
|
|
22
|
+
// Register the 'list' command
|
|
23
|
+
program
|
|
24
|
+
.command('list')
|
|
25
|
+
.description('List all available components')
|
|
26
|
+
.action(listCommand);
|
|
27
|
+
program.parse();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect } from 'react';
|
|
4
|
+
import Lenis from 'lenis';
|
|
5
|
+
export default function SmoothScroll({ children }) {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const lenis = new Lenis({
|
|
8
|
+
duration: 1.2,
|
|
9
|
+
smoothWheel: true,
|
|
10
|
+
});
|
|
11
|
+
function raf(time) {
|
|
12
|
+
lenis.raf(time);
|
|
13
|
+
requestAnimationFrame(raf);
|
|
14
|
+
}
|
|
15
|
+
requestAnimationFrame(raf);
|
|
16
|
+
return () => {
|
|
17
|
+
lenis.destroy();
|
|
18
|
+
};
|
|
19
|
+
}, []);
|
|
20
|
+
return _jsx(_Fragment, { children: children });
|
|
21
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface ToastProps {
|
|
2
|
+
message: string;
|
|
3
|
+
duration?: number;
|
|
4
|
+
onClose?: () => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function Toast({ message, duration, onClose }: ToastProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function useToast(): {
|
|
8
|
+
showToast: (message: string, duration?: number) => void;
|
|
9
|
+
ToastContainer: () => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
};
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect, useCallback } from "react";
|
|
4
|
+
export function Toast({ message, duration = 3000, onClose }) {
|
|
5
|
+
const [visible, setVisible] = useState(false);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const enterTimer = setTimeout(() => setVisible(true), 10);
|
|
8
|
+
const exitTimer = setTimeout(() => {
|
|
9
|
+
setVisible(false);
|
|
10
|
+
setTimeout(() => onClose === null || onClose === void 0 ? void 0 : onClose(), 300);
|
|
11
|
+
}, duration);
|
|
12
|
+
return () => {
|
|
13
|
+
clearTimeout(enterTimer);
|
|
14
|
+
clearTimeout(exitTimer);
|
|
15
|
+
};
|
|
16
|
+
}, [duration, onClose]);
|
|
17
|
+
return (_jsx("div", { className: "fixed top-6 left-1/2 -translate-x-1/2 z-50 pointer-events-none", role: "status", "aria-live": "polite", children: _jsxs("div", { className: `
|
|
18
|
+
inline-flex items-center gap-2.5
|
|
19
|
+
bg-[#1c1c1e] text-[#f5f5f5]
|
|
20
|
+
px-5 py-3 rounded-full
|
|
21
|
+
text-sm font-medium tracking-wide
|
|
22
|
+
shadow-[0_2px_8px_rgba(0,0,0,0.35),0_0_0_1px_rgba(255,255,255,0.06)]
|
|
23
|
+
whitespace-nowrap
|
|
24
|
+
transition-all duration-300 ease-out
|
|
25
|
+
${visible ? "opacity-100 translate-y-0 scale-100" : "opacity-0 -translate-y-2 scale-95"}
|
|
26
|
+
`, children: [_jsx("span", { className: "w-[18px] h-[18px] rounded-full bg-white flex items-center justify-center flex-shrink-0", children: _jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: _jsx("path", { d: "M2 5.5L4 7.5L8 3", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), message] }) }));
|
|
27
|
+
}
|
|
28
|
+
export function useToast() {
|
|
29
|
+
const [toasts, setToasts] = useState([]);
|
|
30
|
+
const showToast = useCallback((message, duration = 3000) => {
|
|
31
|
+
const id = Date.now();
|
|
32
|
+
setToasts((prev) => [...prev, { id, message, duration }]);
|
|
33
|
+
}, []);
|
|
34
|
+
const removeToast = useCallback((id) => {
|
|
35
|
+
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
36
|
+
}, []);
|
|
37
|
+
const ToastContainer = useCallback(() => (_jsx(_Fragment, { children: toasts.map((t) => (_jsx(Toast, { message: t.message, duration: t.duration, onClose: () => removeToast(t.id) }, t.id))) })), [toasts, removeToast]);
|
|
38
|
+
return { showToast, ToastContainer };
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function IndustryProof(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronRight } from 'lucide-react';
|
|
4
|
+
import { useRef, useState, useEffect } from 'react';
|
|
5
|
+
import Link from 'next/link';
|
|
6
|
+
const inspirations = [
|
|
7
|
+
'Codegrid',
|
|
8
|
+
'Manu Arora',
|
|
9
|
+
'Shadcn',
|
|
10
|
+
'Skiper-Ui',
|
|
11
|
+
];
|
|
12
|
+
const techStack = [
|
|
13
|
+
{ name: 'Tailwind CSS', icon: '' },
|
|
14
|
+
{ name: 'Next.js', icon: '' },
|
|
15
|
+
{ name: 'Motion.dev', icon: '' },
|
|
16
|
+
{ name: 'Framer Motion', icon: '' },
|
|
17
|
+
{ name: 'GSAP', icon: '' },
|
|
18
|
+
{ name: 'TypeScript', icon: '' },
|
|
19
|
+
{ name: 'React', icon: '' },
|
|
20
|
+
{ name: 'Vercel', icon: '' },
|
|
21
|
+
];
|
|
22
|
+
const ScrollMarquee = ({ items, direction = 1 }) => {
|
|
23
|
+
const trackRef = useRef(null);
|
|
24
|
+
const animRef = useRef(0);
|
|
25
|
+
const posRef = useRef(0);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const track = trackRef.current;
|
|
28
|
+
if (!track)
|
|
29
|
+
return;
|
|
30
|
+
const step = () => {
|
|
31
|
+
posRef.current -= direction * 0.5;
|
|
32
|
+
const halfWidth = track.scrollWidth / 2;
|
|
33
|
+
if (direction > 0 && Math.abs(posRef.current) >= halfWidth) {
|
|
34
|
+
posRef.current = 0;
|
|
35
|
+
}
|
|
36
|
+
else if (direction < 0 && posRef.current >= 0) {
|
|
37
|
+
posRef.current = -halfWidth;
|
|
38
|
+
}
|
|
39
|
+
track.style.transform = `translateX(${posRef.current}px)`;
|
|
40
|
+
animRef.current = requestAnimationFrame(step);
|
|
41
|
+
};
|
|
42
|
+
animRef.current = requestAnimationFrame(step);
|
|
43
|
+
return () => cancelAnimationFrame(animRef.current);
|
|
44
|
+
}, [direction]);
|
|
45
|
+
return (_jsx("div", { className: 'overflow-hidden w-full [mask-image:linear-gradient(to_right,transparent,black_10%,black_90%,transparent)]', children: _jsx("div", { ref: trackRef, className: 'flex gap-12 whitespace-nowrap will-change-transform', style: { width: 'max-content' }, children: [...items, ...items].map((item, i) => (_jsx("span", { className: 'inline-flex items-center gap-3 text-base font-medium text-white/75 tracking-widest', children: typeof item === 'string' ? (_jsxs(_Fragment, { children: [_jsx("span", { className: 'text-white/75 text-[10px]', children: "\u25C6" }), item] })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: 'text-white/75 text-[13px]', children: item.icon }), item.name] })) }, i))) }) }));
|
|
46
|
+
};
|
|
47
|
+
const DashedDivider = ({ label }) => (_jsxs("div", { className: 'flex items-center gap-4 w-full my-10', children: [_jsx("div", { className: 'flex-1 h-px bg-gradient-to-r from-transparent to-white/20' }), _jsx("span", { className: 'text-[9px] tracking-[0.2em] text-white/30 font-mono uppercase shrink-0', children: label }), _jsx("div", { className: 'flex-1 h-px bg-gradient-to-l from-transparent to-white/20' })] }));
|
|
48
|
+
export default function IndustryProof() {
|
|
49
|
+
const [visible, setVisible] = useState(false);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
const t = setTimeout(() => setVisible(true), 100);
|
|
52
|
+
return () => clearTimeout(t);
|
|
53
|
+
}, []);
|
|
54
|
+
return (_jsx("section", { className: 'relative min-h-screen flex flex-col items-center justify-center px-6 overflow-hidden ', children: _jsxs("div", { className: `relative z-10 w-full max-w-[860px] transition-all duration-[1000ms] ease-out ${visible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4'}`, children: [_jsx(DashedDivider, { label: 'Inspired & Legends' }), _jsx("div", { className: 'mb-4', children: _jsx(ScrollMarquee, { items: inspirations, direction: 1 }) }), _jsx("div", { className: 'mb-12', children: _jsx(ScrollMarquee, { items: [...inspirations].reverse(), direction: -1 }) }), _jsx(DashedDivider, { label: 'Tools & Stack' }), _jsx("div", { className: 'mb-4', children: _jsx(ScrollMarquee, { items: techStack, direction: 1 }) }), _jsx("div", { className: 'mb-12', children: _jsx(ScrollMarquee, { items: [...techStack].reverse(), direction: -1 }) }), _jsx("div", { className: 'mt-8 flex justify-center', children: _jsxs(Link, { href: '/pricing', className: 'relative z-30 h-12 px-6 rounded-lg text-sm text-white transition-all flex items-center gap-2 group', children: ["Be a part now", _jsx("div", { className: 'flex items-center justify-center transition-transform group-hover:translate-x-1', children: _jsx(ChevronRight, { size: 18 }) })] }) })] }) }));
|
|
55
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export default function ShowcaseContainer({ children, title, code: propsCode, description: propsDescription, install: propsInstall, }: {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
title: string;
|
|
5
|
+
code?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
install?: string;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { atomDark as theme } from 'react-syntax-highlighter/dist/esm/styles/prism';
|
|
4
|
+
import ReactMarkdown from 'react-markdown';
|
|
5
|
+
import remarkGfm from 'remark-gfm';
|
|
6
|
+
import { useState, useEffect } from 'react';
|
|
7
|
+
import Link from 'next/link';
|
|
8
|
+
import { useParams } from 'next/navigation';
|
|
9
|
+
import { Code2, Command, PanelLeft, Info, Check, X, Search, Box, Copy, Loader2, Maximize, Home, LoaderCircle, MousePointer2, Rocket, } from 'lucide-react';
|
|
10
|
+
import { AnimatePresence, motion } from 'framer-motion';
|
|
11
|
+
import { Index } from '@/__registry__';
|
|
12
|
+
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
|
13
|
+
import { getComponentSource } from '@/lib/registry';
|
|
14
|
+
export default function ShowcaseContainer({ children, title, code: propsCode, description: propsDescription, install: propsInstall, }) {
|
|
15
|
+
const [isSidebarOpen, setSidebarOpen] = useState(false);
|
|
16
|
+
const [activePanel, setActivePanel] = useState(null);
|
|
17
|
+
const [copied, setCopied] = useState(false);
|
|
18
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
19
|
+
const { id } = useParams();
|
|
20
|
+
const [sourceCode, setSourceCode] = useState(null);
|
|
21
|
+
const [isLoadingCode, setIsLoadingCode] = useState(false);
|
|
22
|
+
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
23
|
+
const [isSearchOpen, setIsSearchOpen] = useState(false);
|
|
24
|
+
const componentsList = Object.values(Index['default']);
|
|
25
|
+
const activeItem = Index['default'][id];
|
|
26
|
+
// Sync state if user exits via ESC or uses Cmd+K
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const handleKeyDown = (e) => {
|
|
29
|
+
if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
|
|
30
|
+
e.preventDefault();
|
|
31
|
+
setIsSearchOpen((prev) => !prev);
|
|
32
|
+
}
|
|
33
|
+
if (e.key === 'Escape') {
|
|
34
|
+
setIsSearchOpen(false);
|
|
35
|
+
setActivePanel(null);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const handleFullscreenChange = () => {
|
|
39
|
+
setIsFullscreen(!!document.fullscreenElement);
|
|
40
|
+
};
|
|
41
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
42
|
+
document.addEventListener('fullscreenchange', handleFullscreenChange);
|
|
43
|
+
return () => {
|
|
44
|
+
document.removeEventListener('keydown', handleKeyDown);
|
|
45
|
+
document.removeEventListener('fullscreenchange', handleFullscreenChange);
|
|
46
|
+
};
|
|
47
|
+
}, []);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
async function fetchSource() {
|
|
50
|
+
if (activePanel === 'code' && (activeItem === null || activeItem === void 0 ? void 0 : activeItem.files)) {
|
|
51
|
+
setIsLoadingCode(true);
|
|
52
|
+
const code = await getComponentSource(activeItem.files);
|
|
53
|
+
setSourceCode(code !== null && code !== void 0 ? code : '// Error: Source code not found.');
|
|
54
|
+
setIsLoadingCode(false);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
fetchSource();
|
|
58
|
+
}, [activePanel, activeItem, id]);
|
|
59
|
+
const getContainerStyle = () => {
|
|
60
|
+
switch (id) {
|
|
61
|
+
case 'neubrutal-button':
|
|
62
|
+
return 'bg-[#538F37]';
|
|
63
|
+
case 'dot-cursor':
|
|
64
|
+
case 'flaoting-navbar':
|
|
65
|
+
return '';
|
|
66
|
+
default:
|
|
67
|
+
return 'bg-[#0a0908]';
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const toggleFullscreen = () => {
|
|
71
|
+
if (!document.fullscreenElement) {
|
|
72
|
+
document.documentElement
|
|
73
|
+
.requestFullscreen()
|
|
74
|
+
.then(() => setIsFullscreen(true));
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
document.exitFullscreen().then(() => setIsFullscreen(false));
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const copyToClipboard = async (text) => {
|
|
81
|
+
await navigator.clipboard.writeText(text);
|
|
82
|
+
setCopied(true);
|
|
83
|
+
setTimeout(() => setCopied(false), 2000);
|
|
84
|
+
};
|
|
85
|
+
const dynamicCode = propsCode ||
|
|
86
|
+
sourceCode ||
|
|
87
|
+
(activeItem === null || activeItem === void 0 ? void 0 : activeItem.content) ||
|
|
88
|
+
'// No source code found.';
|
|
89
|
+
const dynamicDescription = propsDescription ||
|
|
90
|
+
(activeItem === null || activeItem === void 0 ? void 0 : activeItem.description) ||
|
|
91
|
+
`Premium ${title} component.`;
|
|
92
|
+
const dynamicInstall = propsInstall ||
|
|
93
|
+
(activeItem === null || activeItem === void 0 ? void 0 : activeItem.install) ||
|
|
94
|
+
'npm install framer-motion lucide-react';
|
|
95
|
+
// Filter logic for the search modal
|
|
96
|
+
const filteredComponents = componentsList.filter((comp) => comp.name.toLowerCase().includes(searchQuery.toLowerCase()));
|
|
97
|
+
const staticSearchItems = [
|
|
98
|
+
{ icon: _jsx(Home, { size: 16 }), label: 'Home', category: 'Pages', path: '/' },
|
|
99
|
+
{
|
|
100
|
+
icon: _jsx(LoaderCircle, { size: 16 }),
|
|
101
|
+
label: 'Loader',
|
|
102
|
+
category: 'Pages',
|
|
103
|
+
path: '/loader',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
icon: _jsx(MousePointer2, { size: 16 }),
|
|
107
|
+
label: 'Cursor',
|
|
108
|
+
category: 'Pages',
|
|
109
|
+
path: '/cursor',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
icon: _jsx(Box, { size: 16 }),
|
|
113
|
+
label: 'All Components',
|
|
114
|
+
category: 'Pages',
|
|
115
|
+
path: '/component',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
icon: _jsx(Rocket, { size: 16 }),
|
|
119
|
+
label: 'Quick Start',
|
|
120
|
+
category: 'Get Started',
|
|
121
|
+
path: '/docs',
|
|
122
|
+
},
|
|
123
|
+
];
|
|
124
|
+
return (_jsx("div", { className: 'h-screen w-screen bg-black p-2 overflow-hidden text-white font-sans', children: _jsxs("div", { className: 'h-full w-full rounded-[30px] border border-white/5 overflow-hidden flex relative bg-[#0A0A0A]', children: [_jsx("aside", { className: `absolute top-0 left-0 z-[150] h-full w-[320px] transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] bg-[#0A0A0A]/80 backdrop-blur-2xl border-r border-white/5 ${isSidebarOpen ? 'translate-x-0 opacity-100' : '-translate-x-full opacity-0 pointer-events-none'}`, children: _jsxs("div", { className: 'flex flex-col h-full p-10', children: [_jsxs("div", { className: 'flex items-center justify-between mb-12', children: [_jsx("div", { className: 'text-sm text-zinc-500', children: "Navigation" }), _jsx("button", { onClick: () => setSidebarOpen(false), className: 'p-2 text-zinc-500 hover:text-white transition-colors cursor-pointer', children: _jsx(X, { size: 16 }) })] }), _jsx("nav", { className: 'flex-1 overflow-y-auto custom-scrollbar space-y-2', children: componentsList.map((comp, index) => (_jsxs(Link, { href: `/component/${comp.name}`, onClick: () => setSidebarOpen(false), className: 'group flex items-center gap-4 py-2', children: [_jsx("div", { className: `h-px transition-all duration-300 ${id === comp.name ? 'w-6 bg-white' : 'w-3 bg-zinc-800 group-hover:bg-zinc-500'}` }), _jsxs("span", { className: `text-[13px] transition-colors ${id === comp.name ? 'text-white font-medium' : 'text-zinc-500 group-hover:text-zinc-300'}`, children: [_jsx("span", { className: 'font-mono mr-2 opacity-30', children: String(index + 1).padStart(2, '0') }), comp.name] })] }, comp.name))) })] }) }), _jsx(AnimatePresence, { children: isSidebarOpen && (_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, onClick: () => setSidebarOpen(false), className: 'absolute inset-0 bg-black/40 z-[140] backdrop-blur-sm cursor-pointer' })) }), _jsxs("div", { className: 'flex w-full h-full relative', children: [_jsxs("main", { className: `flex-1 relative flex flex-col items-center justify-center transition-all duration-700 ${getContainerStyle()} ease-in-out ${activePanel || isSearchOpen ? 'scale-[0.9] opacity-50' : 'scale-100 opacity-100'}`, children: [!isFullscreen && (_jsxs(_Fragment, { children: [_jsx("button", { onClick: (e) => {
|
|
125
|
+
e.stopPropagation();
|
|
126
|
+
setSidebarOpen(true);
|
|
127
|
+
}, className: 'absolute top-8 left-8 z-[110] p-3 bg-[#161616]/80 backdrop-blur-md border border-white/10 rounded-2xl text-zinc-400 hover:text-white transition-all cursor-pointer shadow-xl', children: _jsx(PanelLeft, { size: 20 }) }), _jsx("div", { className: 'absolute top-10 right-10 text-right pointer-events-none', children: _jsx("h2", { className: 'text-2xl text-white font-black uppercase tracking-tighter', children: title }) })] })), _jsx("div", { className: 'transition-transform duration-700', children: children }), _jsxs("div", { className: 'absolute bottom-10 left-1/2 -translate-x-1/2 flex items-center gap-1 bg-[#161616]/90 border border-white/10 p-1.5 rounded-2xl shadow-2xl backdrop-blur-xl z-[120]', children: [_jsx("button", { onClick: toggleFullscreen, className: 'p-2.5 rounded-xl cursor-pointer text-zinc-500 hover:text-white hover:bg-white/5 transition-all', children: _jsx(Maximize, { size: 18 }) }), _jsx("button", { onClick: () => setActivePanel(activePanel === 'info' ? null : 'info'), className: `p-2.5 rounded-xl cursor-pointer transition-all ${activePanel === 'info' ? 'bg-white text-black' : 'text-zinc-500 hover:text-white hover:bg-white/5'}`, children: _jsx(Info, { size: 18 }) }), _jsx("div", { className: 'w-px h-4 bg-white/10 mx-1' }), _jsx("button", { onClick: () => setActivePanel(activePanel === 'code' ? null : 'code'), className: `p-2.5 rounded-xl transition-all cursor-pointer ${activePanel === 'code' ? 'bg-white text-black' : 'text-zinc-500 hover:text-white hover:bg-white/5'}`, children: _jsx(Code2, { size: 18 }) }), _jsx("button", { onClick: () => setIsSearchOpen(true), className: `p-2.5 rounded-xl transition-all cursor-pointer text-zinc-500 hover:text-white hover:bg-white/5`, children: _jsx(Command, { size: 18 }) })] })] }), _jsx("aside", { className: `h-full bg-[#080808] border-l border-white/5 transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] overflow-hidden relative z-[130] ${activePanel ? 'w-[45%] opacity-100' : 'w-0 opacity-0'}`, children: _jsxs("div", { className: 'p-12 h-full flex flex-col min-w-[450px]', children: [_jsxs("div", { className: 'flex items-center justify-between mb-12', children: [_jsx("h3", { className: 'text-sm uppercase font-beVietnamPro text-zinc-500', children: activePanel === 'code' ? 'Source Code' : 'Documentation' }), _jsx("button", { onClick: () => setActivePanel(null), className: 'p-2 hover:bg-white/5 rounded-lg text-zinc-500 hover:text-white cursor-pointer transition-colors', children: _jsx(X, { size: 18 }) })] }), _jsx("div", { className: 'flex-1 overflow-y-auto custom-scrollbar pr-4', children: _jsx(AnimatePresence, { mode: 'wait', children: activePanel === 'code' ? (_jsx(motion.div, { initial: { opacity: 0, x: 20 }, animate: { opacity: 1, x: 0 }, exit: { opacity: 0, x: 20 }, className: 'relative rounded-2xl bg-black border border-white/10 overflow-hidden', children: isLoadingCode ? (_jsxs("div", { className: 'flex flex-col items-center justify-center py-32 text-zinc-600 gap-4', children: [_jsx(Loader2, { className: 'animate-spin', size: 24 }), _jsx("span", { className: 'text-[10px] uppercase tracking-widest font-bold', children: "Fetching Code" })] })) : (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => copyToClipboard(dynamicCode), className: 'absolute top-4 right-4 p-2 bg-white/5 rounded-md text-zinc-400 cursor-pointer z-10 hover:bg-white/10', children: copied ? (_jsx(Check, { size: 14, className: 'text-white' })) : (_jsx(Copy, { size: 14 })) }), _jsx(SyntaxHighlighter, { language: 'tsx', style: theme, customStyle: {
|
|
128
|
+
margin: 0,
|
|
129
|
+
padding: '32px',
|
|
130
|
+
fontSize: '13px',
|
|
131
|
+
background: 'transparent',
|
|
132
|
+
lineHeight: '1.7',
|
|
133
|
+
}, children: dynamicCode })] })) }, 'code')) : activePanel === 'info' ? (_jsx(motion.div, { initial: { opacity: 0, x: 20 }, animate: { opacity: 1, x: 0 }, exit: { opacity: 0, x: 20 }, children: _jsxs("section", { className: 'space-y-12', children: [_jsxs("div", { children: [_jsx("h4", { className: 'text-[10px] font-black uppercase tracking-[0.4em] text-zinc-600 mb-6', children: "Description" }), _jsx("div", { className: 'prose prose-invert prose-sm text-zinc-400', children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: dynamicDescription }) })] }), _jsxs("div", { children: [_jsx("h4", { className: 'text-[10px] font-black uppercase tracking-[0.4em] text-zinc-600 mb-6', children: "Installation" }), _jsxs("div", { className: 'bg-black p-6 rounded-2xl border border-white/10 font-mono text-xs flex items-center justify-between', children: [_jsx("span", { className: 'text-zinc-300', children: dynamicInstall }), _jsx("button", { onClick: () => copyToClipboard(dynamicInstall), className: 'p-2 hover:bg-white/5 rounded-md text-zinc-500', children: copied ? (_jsx(Check, { size: 14 })) : (_jsx(Copy, { size: 14 })) })] })] })] }) }, 'info')) : null }) })] }) })] }), _jsx(AnimatePresence, { children: isSearchOpen && (_jsxs("div", { className: 'fixed inset-0 z-[200] flex items-start justify-center pt-[18vh] px-4', children: [_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, onClick: () => setIsSearchOpen(false), className: 'absolute inset-0 bg-black/60 backdrop-blur-md' }), _jsxs(motion.div, { initial: { opacity: 0, scale: 0.95, y: -20 }, animate: { opacity: 1, scale: 1, y: 0 }, exit: { opacity: 0, scale: 0.95, y: -20 }, className: 'relative w-full max-w-[600px] bg-zinc-950 border border-zinc-800 rounded-xl shadow-2xl overflow-hidden', children: [_jsxs("div", { className: 'flex items-center px-4 border-b border-zinc-800', children: [_jsx(Search, { className: 'text-zinc-500', size: 18 }), _jsx("input", { autoFocus: true, value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: 'Search components or pages...', className: 'w-full h-14 bg-transparent border-none outline-none px-4 text-white text-sm placeholder:text-zinc-600' })] }), _jsx("div", { className: 'max-h-[400px] overflow-y-auto p-2 custom-scrollbar', children: searchQuery.length > 0 ? (_jsxs("div", { className: 'p-2', children: [_jsx("p", { className: 'px-3 py-2 text-[10px] font-semibold text-zinc-500 uppercase tracking-wider', children: "Component Results" }), filteredComponents.length > 0 ? (filteredComponents.map((comp) => (_jsxs(Link, { href: `/component/${comp.name}`, onClick: () => {
|
|
134
|
+
setIsSearchOpen(false);
|
|
135
|
+
setSearchQuery('');
|
|
136
|
+
}, className: 'flex items-center gap-3 px-3 py-2.5 rounded-lg hover:bg-white/5 transition-all group', children: [_jsx(Box, { size: 16, className: 'text-zinc-500 group-hover:text-white' }), _jsx("span", { className: 'text-sm text-zinc-300 group-hover:text-white', children: comp.name })] }, comp.name)))) : (_jsx("p", { className: 'px-3 py-4 text-sm text-zinc-600', children: "No components found..." }))] })) : (['Pages', 'Get Started'].map((category) => (_jsxs("div", { className: 'mb-2', children: [_jsx("p", { className: 'px-3 py-2 text-[10px] font-semibold text-zinc-500 uppercase tracking-wider', children: category }), staticSearchItems
|
|
137
|
+
.filter((item) => item.category === category)
|
|
138
|
+
.map((item) => (_jsxs(Link, { href: item.path, onClick: () => setIsSearchOpen(false), className: 'flex items-center gap-3 px-3 py-2.5 rounded-lg hover:bg-white/5 transition-all group', children: [_jsx("div", { className: 'text-zinc-500 group-hover:text-white', children: item.icon }), _jsx("span", { className: 'text-sm text-zinc-300 group-hover:text-white', children: item.label })] }, item.label)))] }, category)))) }), _jsxs("div", { className: 'px-4 py-3 border-t border-zinc-800 bg-zinc-900/30 flex justify-between items-center text-[10px] text-zinc-500 font-medium', children: [_jsxs("div", { className: 'flex gap-3', children: [_jsxs("span", { className: 'flex items-center gap-1', children: [_jsx(Command, { size: 10 }), " to select"] }), _jsx("span", { className: 'flex items-center gap-1', children: "Enter to open" })] }), _jsx("span", { children: "ESC to close" })] })] })] })) })] }) }));
|
|
139
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect } from 'react';
|
|
4
|
+
const CustomCursor = () => {
|
|
5
|
+
const [position, setPosition] = useState({ x: 0, y: 0 });
|
|
6
|
+
const [isHovering, setIsHovering] = useState(false);
|
|
7
|
+
const [isDarkBackground, setIsDarkBackground] = useState(false);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
// document.body.style.cursor = 'none';
|
|
10
|
+
const updatePosition = (e) => {
|
|
11
|
+
setPosition({ x: e.clientX, y: e.clientY });
|
|
12
|
+
const element = document.elementFromPoint(e.clientX, e.clientY);
|
|
13
|
+
if (element) {
|
|
14
|
+
const bgColor = window.getComputedStyle(element).backgroundColor;
|
|
15
|
+
const brightness = getBrightness(bgColor);
|
|
16
|
+
setIsDarkBackground(brightness < 128);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const handleMouseOver = (e) => {
|
|
20
|
+
const target = e.target;
|
|
21
|
+
if (target.tagName === 'A' ||
|
|
22
|
+
target.tagName === 'BUTTON' ||
|
|
23
|
+
target.onclick !== null ||
|
|
24
|
+
window.getComputedStyle(target).cursor === 'pointer') {
|
|
25
|
+
setIsHovering(true);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const handleMouseOut = () => {
|
|
29
|
+
setIsHovering(false);
|
|
30
|
+
};
|
|
31
|
+
window.addEventListener('mousemove', updatePosition);
|
|
32
|
+
document.addEventListener('mouseover', handleMouseOver);
|
|
33
|
+
document.addEventListener('mouseout', handleMouseOut);
|
|
34
|
+
return () => {
|
|
35
|
+
window.removeEventListener('mousemove', updatePosition);
|
|
36
|
+
document.removeEventListener('mouseover', handleMouseOver);
|
|
37
|
+
document.removeEventListener('mouseout', handleMouseOut);
|
|
38
|
+
};
|
|
39
|
+
}, []);
|
|
40
|
+
const getBrightness = (color) => {
|
|
41
|
+
const rgb = color.match(/d+/g);
|
|
42
|
+
if (!rgb)
|
|
43
|
+
return 255;
|
|
44
|
+
const r = parseInt(rgb[0]);
|
|
45
|
+
const g = parseInt(rgb[1]);
|
|
46
|
+
const b = parseInt(rgb[2]);
|
|
47
|
+
return (r * 299 + g * 587 + b * 114) / 1000;
|
|
48
|
+
};
|
|
49
|
+
return (_jsx("div", { style: {
|
|
50
|
+
cursor: 'none',
|
|
51
|
+
width: '100vw',
|
|
52
|
+
height: '100vh',
|
|
53
|
+
position: 'fixed',
|
|
54
|
+
top: 0,
|
|
55
|
+
left: 0,
|
|
56
|
+
pointerEvents: 'none'
|
|
57
|
+
}, children: _jsx("div", { style: {
|
|
58
|
+
position: 'fixed',
|
|
59
|
+
left: `${position.x}px`,
|
|
60
|
+
top: `${position.y}px`,
|
|
61
|
+
pointerEvents: 'none',
|
|
62
|
+
transform: `translate(-50%, -50%) scale(${isHovering ? 1.5 : 1})`,
|
|
63
|
+
transition: 'transform 0.2s ease',
|
|
64
|
+
zIndex: 9999,
|
|
65
|
+
}, children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", style: {
|
|
66
|
+
display: 'block',
|
|
67
|
+
transition: 'all 0.2s ease',
|
|
68
|
+
}, children: _jsx("path", { fill: isDarkBackground ? '#ffffff' : '#000000', stroke: isDarkBackground ? '#000000' : '#ffffff', strokeWidth: "2", d: "M5.5 3.21V20.8c0 .45.54.67.85.35l4.86-4.86a.5.5 0 0 1 .35-.15h6.87a.5.5 0 0 0 .35-.85L6.35 2.85a.5.5 0 0 0-.85.35Z" }) }) }) }));
|
|
69
|
+
};
|
|
70
|
+
export default CustomCursor;
|