zerozeeker 2.2.9 → 2.3.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/README.md +18 -4
- package/dist/index.js +51 -179
- package/package.json +7 -10
package/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# ZeroZeeker Components
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
**No setup required. No shadcn/ui required. Just install and go.** ✨
|
|
3
|
+
Official CLI for installing production-ready UI components into your React or Next.js projects.
|
|
6
4
|
|
|
7
5
|
[](https://www.npmjs.com/package/zerozeeker)
|
|
8
6
|
[](https://www.typescriptlang.org/)
|
|
@@ -92,8 +90,17 @@ Before using ZeroZeeker components, ensure you have:
|
|
|
92
90
|
|
|
93
91
|
- Node.js 18 or higher
|
|
94
92
|
- An existing React or Next.js project
|
|
93
|
+
- shadcn/ui initialized in your project
|
|
95
94
|
- Tailwind CSS configured
|
|
96
95
|
|
|
96
|
+
### Setup shadcn/ui
|
|
97
|
+
|
|
98
|
+
If you haven't initialized shadcn/ui yet:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx shadcn-ui@latest init
|
|
102
|
+
```
|
|
103
|
+
|
|
97
104
|
---
|
|
98
105
|
|
|
99
106
|
## How to Use Installed Components
|
|
@@ -112,7 +119,7 @@ export default function App() {
|
|
|
112
119
|
}
|
|
113
120
|
```
|
|
114
121
|
|
|
115
|
-
All components follow
|
|
122
|
+
All components follow shadcn/ui conventions. Import from `@/components/ui/<component-name>`.
|
|
116
123
|
|
|
117
124
|
---
|
|
118
125
|
|
|
@@ -151,6 +158,13 @@ Use the full npx command:
|
|
|
151
158
|
npx zerozeeker list
|
|
152
159
|
```
|
|
153
160
|
|
|
161
|
+
### shadcn/ui not initialized
|
|
162
|
+
|
|
163
|
+
Initialize shadcn/ui first:
|
|
164
|
+
```bash
|
|
165
|
+
npx shadcn-ui@latest init
|
|
166
|
+
```
|
|
167
|
+
|
|
154
168
|
### Component won't install
|
|
155
169
|
|
|
156
170
|
Verify the exact component name:
|
package/dist/index.js
CHANGED
|
@@ -3,198 +3,70 @@
|
|
|
3
3
|
// index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { execSync } from "child_process";
|
|
6
|
-
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
7
|
-
import { join, dirname } from "path";
|
|
8
6
|
import ora from "ora";
|
|
9
7
|
import chalk from "chalk";
|
|
10
8
|
var REGISTRY_URL = "https://www.zerozeeker.com/r";
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
9
|
+
var VERSION = "2.3.0";
|
|
10
|
+
var REGISTRY = [
|
|
11
|
+
// Buttons
|
|
12
|
+
{ name: "rainbow-button", category: "Buttons", desc: "Animated rainbow gradient border" },
|
|
13
|
+
{ name: "shimmer-button", category: "Buttons", desc: "Moving border glow effect" },
|
|
14
|
+
{ name: "magnetic-button", category: "Buttons", desc: "Cursor-following magnetic pull effect" },
|
|
15
|
+
{ name: "expand-button", category: "Buttons", desc: "Expanding pill animation on hover" },
|
|
16
|
+
{ name: "flip-button", category: "Buttons", desc: "3D flip card reveal effect" },
|
|
17
|
+
{ name: "circle-reveal-button", category: "Buttons", desc: "Icon-to-pill circle expansion" },
|
|
18
|
+
// Inputs
|
|
19
|
+
{ name: "glow-input", category: "Inputs", desc: "Animated glow ring on focus" },
|
|
20
|
+
{ name: "typewriter-input", category: "Inputs", desc: "Cycling typewriter placeholder" },
|
|
21
|
+
{ name: "shimmer-input", category: "Inputs", desc: "Shimmer border sweep on focus" },
|
|
22
|
+
{ name: "spotlight-input", category: "Inputs", desc: "Mouse-tracked spotlight effect" },
|
|
23
|
+
{ name: "vortex-input", category: "Inputs", desc: "Swirling vortex border animation" },
|
|
24
|
+
{ name: "prism-input", category: "Inputs", desc: "Prism light refraction border" }
|
|
19
25
|
];
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
function ensureDir(filePath) {
|
|
28
|
-
const dir = dirname(filePath);
|
|
29
|
-
if (!existsSync(dir)) {
|
|
30
|
-
mkdirSync(dir, { recursive: true });
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function findProjectRoot() {
|
|
34
|
-
let currentDir = process.cwd();
|
|
35
|
-
while (currentDir !== dirname(currentDir)) {
|
|
36
|
-
if (existsSync(join(currentDir, "package.json"))) {
|
|
37
|
-
return currentDir;
|
|
38
|
-
}
|
|
39
|
-
currentDir = dirname(currentDir);
|
|
40
|
-
}
|
|
41
|
-
throw new Error("Could not find project root (no package.json found)");
|
|
42
|
-
}
|
|
43
|
-
function installDependencies(deps) {
|
|
44
|
-
if (deps.length === 0) return;
|
|
45
|
-
console.log(chalk.dim(` Installing dependencies: ${deps.join(", ")}`));
|
|
46
|
-
try {
|
|
47
|
-
execSync(`npm install ${deps.join(" ")}`, {
|
|
48
|
-
stdio: "pipe",
|
|
49
|
-
encoding: "utf-8"
|
|
50
|
-
});
|
|
51
|
-
} catch {
|
|
52
|
-
console.warn(chalk.yellow(` Warning: Failed to auto-install dependencies. Install manually: npm install ${deps.join(" ")}`));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
async function installRegistryDependencies(deps, projectRoot, installed = /* @__PURE__ */ new Set()) {
|
|
56
|
-
const allFiles = [];
|
|
57
|
-
const allNpmDeps = [];
|
|
58
|
-
for (const dep of deps) {
|
|
59
|
-
if (installed.has(dep)) continue;
|
|
60
|
-
installed.add(dep);
|
|
61
|
-
const url = `${REGISTRY_URL}/${dep}.json`;
|
|
62
|
-
try {
|
|
63
|
-
const registry = await fetchRegistry(url);
|
|
64
|
-
if (registry.registryDependencies && registry.registryDependencies.length > 0) {
|
|
65
|
-
const nested = await installRegistryDependencies(
|
|
66
|
-
registry.registryDependencies,
|
|
67
|
-
projectRoot,
|
|
68
|
-
installed
|
|
69
|
-
);
|
|
70
|
-
allFiles.push(...nested.files);
|
|
71
|
-
allNpmDeps.push(...nested.npmDeps);
|
|
72
|
-
}
|
|
73
|
-
if (registry.files && registry.files.length > 0) {
|
|
74
|
-
for (const file of registry.files) {
|
|
75
|
-
const targetPath = file.target || file.path;
|
|
76
|
-
const fullPath = join(projectRoot, targetPath);
|
|
77
|
-
if (existsSync(fullPath)) {
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
ensureDir(fullPath);
|
|
81
|
-
writeFileSync(fullPath, file.content, "utf-8");
|
|
82
|
-
allFiles.push(targetPath);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
if (registry.dependencies) {
|
|
86
|
-
allNpmDeps.push(...registry.dependencies);
|
|
87
|
-
}
|
|
88
|
-
} catch (error) {
|
|
89
|
-
console.warn(chalk.yellow(` Warning: Could not install registry dependency "${dep}"`));
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return { files: allFiles, npmDeps: allNpmDeps };
|
|
26
|
+
var COMPONENT_NAMES = REGISTRY.map((c) => c.name);
|
|
27
|
+
function printHeader() {
|
|
28
|
+
console.log("");
|
|
29
|
+
console.log(chalk.bold.white(" ZeroZeeker") + chalk.dim(" \xB7 UI Component Library"));
|
|
30
|
+
console.log(chalk.dim(" https://www.zerozeeker.com"));
|
|
31
|
+
console.log("");
|
|
93
32
|
}
|
|
94
33
|
var program = new Command();
|
|
95
|
-
program.name("zerozeeker").description("CLI for installing ZeroZeeker UI components -
|
|
96
|
-
program.command("add <component>").description("Add a component
|
|
97
|
-
if (!
|
|
98
|
-
console.error(chalk.red(`
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
console.log(chalk.dim("\nPro tip: Copy-paste is your friend."));
|
|
34
|
+
program.name("zerozeeker").description("CLI for installing ZeroZeeker UI components").version(VERSION, "-v, --version", "Output the current version");
|
|
35
|
+
program.command("add <component>").description("Add a ZeroZeeker component to your project").action((component) => {
|
|
36
|
+
if (!COMPONENT_NAMES.includes(component)) {
|
|
37
|
+
console.error(chalk.red(` \u2716 Unknown component: "${component}"
|
|
38
|
+
`));
|
|
39
|
+
console.log(chalk.dim(" Available components:"));
|
|
40
|
+
COMPONENT_NAMES.forEach((c) => console.log(chalk.cyan(` ${c}`)));
|
|
41
|
+
console.log(chalk.dim("\n Run " + chalk.white("npx zerozeeker list") + " for full details.\n"));
|
|
104
42
|
process.exit(1);
|
|
105
43
|
}
|
|
106
44
|
const url = `${REGISTRY_URL}/${component}.json`;
|
|
107
|
-
const spinner = ora(`Installing ${chalk.cyan(component)}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
spinner.text = `Fetching ${chalk.cyan(component)} from registry...`;
|
|
111
|
-
const registry = await fetchRegistry(url);
|
|
112
|
-
const filesInstalled = [];
|
|
113
|
-
const allDependencies = [...registry.dependencies || []];
|
|
114
|
-
if (registry.registryDependencies && registry.registryDependencies.length > 0) {
|
|
115
|
-
spinner.text = `Installing registry dependencies...`;
|
|
116
|
-
const registryResult = await installRegistryDependencies(
|
|
117
|
-
registry.registryDependencies,
|
|
118
|
-
projectRoot
|
|
119
|
-
);
|
|
120
|
-
filesInstalled.push(...registryResult.files);
|
|
121
|
-
allDependencies.push(...registryResult.npmDeps);
|
|
122
|
-
}
|
|
123
|
-
if (registry.files && registry.files.length > 0) {
|
|
124
|
-
spinner.text = `Installing ${chalk.cyan(component)} files...`;
|
|
125
|
-
for (const file of registry.files) {
|
|
126
|
-
const targetPath = file.target || file.path;
|
|
127
|
-
const fullPath = join(projectRoot, targetPath);
|
|
128
|
-
if (existsSync(fullPath)) {
|
|
129
|
-
spinner.stop();
|
|
130
|
-
console.warn(chalk.yellow(`
|
|
131
|
-
\u26A0 File already exists: ${targetPath}`));
|
|
132
|
-
console.log(chalk.dim(" Skipping to avoid overwriting your changes."));
|
|
133
|
-
console.log(chalk.dim(` To force reinstall: delete the file and run the command again.
|
|
45
|
+
const spinner = ora({ text: `Installing ${chalk.cyan(component)}`, color: "cyan" }).start();
|
|
46
|
+
spinner.stop();
|
|
47
|
+
console.log(chalk.dim(` \u2192 ${url}
|
|
134
48
|
`));
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (uniqueDeps.length > 0) {
|
|
144
|
-
spinner.text = "Installing npm dependencies...";
|
|
145
|
-
installDependencies(uniqueDeps);
|
|
146
|
-
}
|
|
147
|
-
spinner.stop();
|
|
148
|
-
console.log(chalk.green(`
|
|
149
|
-
\u2713 Successfully installed ${component}`));
|
|
150
|
-
if (filesInstalled.length > 0) {
|
|
151
|
-
console.log(chalk.dim("\n Files added:"));
|
|
152
|
-
filesInstalled.forEach((f) => {
|
|
153
|
-
console.log(chalk.cyan(` ${f}`));
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
if (uniqueDeps.length > 0) {
|
|
157
|
-
console.log(chalk.dim("\n Dependencies installed:"));
|
|
158
|
-
uniqueDeps.forEach((d) => {
|
|
159
|
-
console.log(chalk.cyan(` ${d}`));
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
console.log(chalk.dim("\n Now go make something beautiful. \u2728\n"));
|
|
163
|
-
} catch (error) {
|
|
164
|
-
spinner.stop();
|
|
165
|
-
console.error(chalk.red(`
|
|
166
|
-
\u2717 Failed to install ${component}`));
|
|
167
|
-
if (error instanceof Error) {
|
|
168
|
-
if (error.message.includes("package.json")) {
|
|
169
|
-
console.log(chalk.dim("\n Make sure you're in a React/Next.js project directory."));
|
|
170
|
-
} else if (error.message.includes("fetch")) {
|
|
171
|
-
console.log(chalk.dim("\n Check your internet connection and try again."));
|
|
172
|
-
} else {
|
|
173
|
-
console.log(chalk.dim(`
|
|
174
|
-
${error.message}`));
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
console.log(chalk.dim("\n Need help? https://www.zerozeeker.com/docs\n"));
|
|
49
|
+
try {
|
|
50
|
+
execSync(`npx shadcn@latest add "${url}"`, { stdio: "inherit" });
|
|
51
|
+
console.log("");
|
|
52
|
+
console.log(chalk.green(` \u2714 ${component} installed successfully.`));
|
|
53
|
+
console.log(chalk.dim(" Import it from your components/ui directory and go build something great.\n"));
|
|
54
|
+
} catch {
|
|
55
|
+
console.error(chalk.red(` \u2716 Installation failed.`));
|
|
56
|
+
console.log(chalk.dim(" Check your network connection and try again.\n"));
|
|
178
57
|
process.exit(1);
|
|
179
58
|
}
|
|
180
59
|
});
|
|
181
60
|
program.command("list").description("List all available components").action(() => {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
"
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
COMPONENTS.filter((c) => c !== "index").forEach((component) => {
|
|
193
|
-
console.log(chalk.cyan(` ${component}`));
|
|
194
|
-
console.log(chalk.dim(` ${descriptions[component]}
|
|
195
|
-
`));
|
|
196
|
-
});
|
|
197
|
-
console.log(chalk.dim("Install any component with: ") + chalk.white("npx zerozeeker add <component>"));
|
|
198
|
-
console.log(chalk.dim("More components coming soon. Ship fast. Look good doing it.\n"));
|
|
61
|
+
printHeader();
|
|
62
|
+
const categories = [...new Set(REGISTRY.map((c) => c.category))];
|
|
63
|
+
for (const cat of categories) {
|
|
64
|
+
console.log(chalk.bold.white(` ${cat}`));
|
|
65
|
+
REGISTRY.filter((c) => c.category === cat).forEach(({ name, desc }) => {
|
|
66
|
+
console.log(` ${chalk.cyan(name.padEnd(26))} ${chalk.dim(desc)}`);
|
|
67
|
+
});
|
|
68
|
+
console.log("");
|
|
69
|
+
}
|
|
70
|
+
console.log(chalk.dim(` Install with: `) + chalk.white("npx zerozeeker add <component>") + chalk.dim("\n"));
|
|
199
71
|
});
|
|
200
72
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zerozeeker",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.3.0",
|
|
4
|
+
"description": "CLI for installing ZeroZeeker UI components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"zerozeeker": "dist/index.js"
|
|
@@ -16,24 +16,21 @@
|
|
|
16
16
|
"prepublishOnly": "npm run build"
|
|
17
17
|
},
|
|
18
18
|
"keywords": [
|
|
19
|
-
"
|
|
20
|
-
"ui",
|
|
19
|
+
"shadcn",
|
|
21
20
|
"components",
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"typescript"
|
|
21
|
+
"ui",
|
|
22
|
+
"zerozeeker"
|
|
25
23
|
],
|
|
26
24
|
"author": "ZeroZeeker",
|
|
27
25
|
"license": "MIT",
|
|
28
26
|
"dependencies": {
|
|
29
|
-
"chalk": "^5.3.0",
|
|
30
27
|
"commander": "^12.1.0",
|
|
31
|
-
"ora": "^8.0.1"
|
|
28
|
+
"ora": "^8.0.1",
|
|
29
|
+
"chalk": "^5.3.0"
|
|
32
30
|
},
|
|
33
31
|
"devDependencies": {
|
|
34
32
|
"@types/node": "^20.11.5",
|
|
35
33
|
"tsup": "^8.0.1",
|
|
36
|
-
"tsx": "^4.21.0",
|
|
37
34
|
"typescript": "^5.3.3"
|
|
38
35
|
},
|
|
39
36
|
"engines": {
|