@srcroot/ui 0.0.33 → 0.0.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +101 -88
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -5,11 +5,12 @@ import { Command } from "commander";
|
|
|
5
5
|
import chalk3 from "chalk";
|
|
6
6
|
|
|
7
7
|
// src/cli/services/project-initializer.ts
|
|
8
|
-
import
|
|
9
|
-
import
|
|
8
|
+
import fs3 from "fs-extra";
|
|
9
|
+
import path3 from "path";
|
|
10
10
|
import ora from "ora";
|
|
11
11
|
import prompts from "prompts";
|
|
12
12
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
13
|
+
import { execa } from "execa";
|
|
13
14
|
|
|
14
15
|
// src/cli/services/theme-service.ts
|
|
15
16
|
import fs from "fs-extra";
|
|
@@ -143,20 +144,21 @@ export default config
|
|
|
143
144
|
`;
|
|
144
145
|
|
|
145
146
|
// src/cli/utils/get-package-manager.ts
|
|
146
|
-
|
|
147
|
+
import fs2 from "fs";
|
|
148
|
+
import path2 from "path";
|
|
149
|
+
function getPackageManager(cwd) {
|
|
147
150
|
const userAgent = process.env.npm_config_user_agent;
|
|
148
|
-
if (
|
|
149
|
-
return "
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
return "
|
|
153
|
-
}
|
|
154
|
-
if (userAgent.startsWith("pnpm")) {
|
|
155
|
-
return "pnpm";
|
|
156
|
-
}
|
|
157
|
-
if (userAgent.startsWith("bun")) {
|
|
158
|
-
return "bun";
|
|
151
|
+
if (userAgent) {
|
|
152
|
+
if (userAgent.startsWith("yarn")) return "yarn";
|
|
153
|
+
if (userAgent.startsWith("pnpm")) return "pnpm";
|
|
154
|
+
if (userAgent.startsWith("bun")) return "bun";
|
|
155
|
+
if (userAgent.startsWith("npm")) return "npm";
|
|
159
156
|
}
|
|
157
|
+
const dir = cwd || process.cwd();
|
|
158
|
+
if (fs2.existsSync(path2.join(dir, "bun.lockb"))) return "bun";
|
|
159
|
+
if (fs2.existsSync(path2.join(dir, "pnpm-lock.yaml"))) return "pnpm";
|
|
160
|
+
if (fs2.existsSync(path2.join(dir, "yarn.lock"))) return "yarn";
|
|
161
|
+
if (fs2.existsSync(path2.join(dir, "package-lock.json"))) return "npm";
|
|
160
162
|
return "npm";
|
|
161
163
|
}
|
|
162
164
|
|
|
@@ -178,7 +180,7 @@ var logger = {
|
|
|
178
180
|
};
|
|
179
181
|
|
|
180
182
|
// src/cli/services/project-initializer.ts
|
|
181
|
-
var __dirname3 =
|
|
183
|
+
var __dirname3 = path3.dirname(fileURLToPath2(import.meta.url));
|
|
182
184
|
var ProjectInitializer = class {
|
|
183
185
|
options;
|
|
184
186
|
config = {};
|
|
@@ -193,16 +195,17 @@ var ProjectInitializer = class {
|
|
|
193
195
|
await this.detectConfiguration();
|
|
194
196
|
await this.promptUser();
|
|
195
197
|
await this.scaffold();
|
|
198
|
+
await this.installDependencies();
|
|
196
199
|
this.printSuccess();
|
|
197
200
|
}
|
|
198
201
|
async validateEnvironment() {
|
|
199
|
-
const cwd =
|
|
200
|
-
const packageJsonPath =
|
|
201
|
-
if (!
|
|
202
|
+
const cwd = path3.resolve(this.options.cwd);
|
|
203
|
+
const packageJsonPath = path3.join(cwd, "package.json");
|
|
204
|
+
if (!fs3.existsSync(packageJsonPath)) {
|
|
202
205
|
logger.error("Error: No package.json found. Please run this in a project directory.");
|
|
203
206
|
process.exit(1);
|
|
204
207
|
}
|
|
205
|
-
const pkg = await
|
|
208
|
+
const pkg = await fs3.readJson(packageJsonPath);
|
|
206
209
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
207
210
|
if (!allDeps["react"]) {
|
|
208
211
|
logger.error("Error: React not found in dependencies. Please initialize this in a React project.");
|
|
@@ -210,33 +213,33 @@ var ProjectInitializer = class {
|
|
|
210
213
|
}
|
|
211
214
|
}
|
|
212
215
|
async detectConfiguration() {
|
|
213
|
-
const cwd =
|
|
214
|
-
const packageManager = getPackageManager();
|
|
216
|
+
const cwd = path3.resolve(this.options.cwd);
|
|
217
|
+
const packageManager = getPackageManager(cwd);
|
|
215
218
|
const installCmd = packageManager === "npm" ? "install" : "add";
|
|
216
|
-
const pkg = await
|
|
219
|
+
const pkg = await fs3.readJson(path3.join(cwd, "package.json"));
|
|
217
220
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
218
221
|
const tailwindVersion = allDeps["tailwindcss"] || "";
|
|
219
222
|
const isTailwind4 = tailwindVersion.includes("^4") || tailwindVersion.startsWith("4") || allDeps["@tailwindcss/postcss"];
|
|
220
|
-
const hasSrc =
|
|
221
|
-
const srcPath = hasSrc ?
|
|
222
|
-
const appPath =
|
|
223
|
-
const pagesPath =
|
|
224
|
-
const hasAppDir =
|
|
225
|
-
const hasPagesDir =
|
|
226
|
-
const libDir =
|
|
227
|
-
const componentsDir =
|
|
223
|
+
const hasSrc = fs3.existsSync(path3.join(cwd, "src"));
|
|
224
|
+
const srcPath = hasSrc ? path3.join(cwd, "src") : cwd;
|
|
225
|
+
const appPath = path3.join(srcPath, "app");
|
|
226
|
+
const pagesPath = path3.join(srcPath, "pages");
|
|
227
|
+
const hasAppDir = fs3.existsSync(appPath);
|
|
228
|
+
const hasPagesDir = fs3.existsSync(pagesPath);
|
|
229
|
+
const libDir = path3.join(srcPath, "lib");
|
|
230
|
+
const componentsDir = path3.join(srcPath, "components", "ui");
|
|
228
231
|
let globalsPath = "";
|
|
229
232
|
if (hasAppDir) {
|
|
230
|
-
if (
|
|
231
|
-
else if (
|
|
232
|
-
else globalsPath =
|
|
233
|
+
if (fs3.existsSync(path3.join(appPath, "globals.css"))) globalsPath = path3.join(appPath, "globals.css");
|
|
234
|
+
else if (fs3.existsSync(path3.join(appPath, "global.css"))) globalsPath = path3.join(appPath, "global.css");
|
|
235
|
+
else globalsPath = path3.join(appPath, "globals.css");
|
|
233
236
|
} else if (hasPagesDir) {
|
|
234
|
-
const stylesPath =
|
|
235
|
-
if (
|
|
236
|
-
else if (
|
|
237
|
-
else globalsPath =
|
|
237
|
+
const stylesPath = path3.join(srcPath, "styles");
|
|
238
|
+
if (fs3.existsSync(path3.join(stylesPath, "globals.css"))) globalsPath = path3.join(stylesPath, "globals.css");
|
|
239
|
+
else if (fs3.existsSync(path3.join(stylesPath, "global.css"))) globalsPath = path3.join(stylesPath, "global.css");
|
|
240
|
+
else globalsPath = path3.join(stylesPath, "globals.css");
|
|
238
241
|
} else {
|
|
239
|
-
globalsPath =
|
|
242
|
+
globalsPath = path3.join(srcPath, "globals.css");
|
|
240
243
|
}
|
|
241
244
|
this.config = {
|
|
242
245
|
cwd,
|
|
@@ -264,7 +267,7 @@ var ProjectInitializer = class {
|
|
|
264
267
|
return;
|
|
265
268
|
}
|
|
266
269
|
const themeChoices = availableThemes.map((theme) => ({
|
|
267
|
-
title:
|
|
270
|
+
title: theme.name,
|
|
268
271
|
value: theme.file.replace(".css", "")
|
|
269
272
|
}));
|
|
270
273
|
const themeResponse = await prompts({
|
|
@@ -284,13 +287,13 @@ var ProjectInitializer = class {
|
|
|
284
287
|
const spinner = ora("Creating project structure...").start();
|
|
285
288
|
const cfg = this.config;
|
|
286
289
|
try {
|
|
287
|
-
await
|
|
288
|
-
await
|
|
289
|
-
const utilsPath =
|
|
290
|
-
const registryUtilsPath =
|
|
290
|
+
await fs3.ensureDir(cfg.libDir);
|
|
291
|
+
await fs3.ensureDir(cfg.componentsDir);
|
|
292
|
+
const utilsPath = path3.join(cfg.libDir, "utils.ts");
|
|
293
|
+
const registryUtilsPath = path3.resolve(__dirname3, "..", "src", "registry", "lib", "utils.ts");
|
|
291
294
|
let utilsContent = "";
|
|
292
|
-
if (
|
|
293
|
-
utilsContent = await
|
|
295
|
+
if (fs3.existsSync(registryUtilsPath)) {
|
|
296
|
+
utilsContent = await fs3.readFile(registryUtilsPath, "utf-8");
|
|
294
297
|
} else {
|
|
295
298
|
utilsContent = `import { type ClassValue, clsx } from "clsx"
|
|
296
299
|
import { twMerge } from "tailwind-merge"
|
|
@@ -301,15 +304,15 @@ export function cn(...inputs: ClassValue[]) {
|
|
|
301
304
|
`;
|
|
302
305
|
spinner.warn(`Could not find registry/utils.ts, using fallback content.`);
|
|
303
306
|
}
|
|
304
|
-
await
|
|
305
|
-
spinner.succeed(`Created ${
|
|
307
|
+
await fs3.writeFile(utilsPath, utilsContent);
|
|
308
|
+
spinner.succeed(`Created ${path3.relative(cfg.cwd, utilsPath)}`);
|
|
306
309
|
spinner.start(`Setting up ${cfg.selectedTheme} theme...`);
|
|
307
|
-
const stylesDir =
|
|
308
|
-
await
|
|
310
|
+
const stylesDir = path3.dirname(cfg.globalsPath);
|
|
311
|
+
await fs3.ensureDir(stylesDir);
|
|
309
312
|
try {
|
|
310
313
|
const cssContent = await this.themeService.getThemeCss(cfg.selectedTheme, cfg.isTailwind4);
|
|
311
|
-
await
|
|
312
|
-
spinner.succeed(`Updated ${
|
|
314
|
+
await fs3.writeFile(cfg.globalsPath, cssContent);
|
|
315
|
+
spinner.succeed(`Updated ${path3.relative(cfg.cwd, cfg.globalsPath)} with ${cfg.selectedTheme} theme (${cfg.isTailwind4 ? "Tailwind 4" : "Tailwind 3"})`);
|
|
313
316
|
} catch (error) {
|
|
314
317
|
spinner.fail(`Failed to load theme: ${cfg.selectedTheme}`);
|
|
315
318
|
console.error(error);
|
|
@@ -317,11 +320,9 @@ export function cn(...inputs: ClassValue[]) {
|
|
|
317
320
|
}
|
|
318
321
|
if (!cfg.isTailwind4) {
|
|
319
322
|
spinner.start("Setting up Tailwind config...");
|
|
320
|
-
const tailwindConfigPath =
|
|
321
|
-
await
|
|
323
|
+
const tailwindConfigPath = path3.join(cfg.cwd, "tailwind.config.ts");
|
|
324
|
+
await fs3.writeFile(tailwindConfigPath, TAILWIND_CONFIG);
|
|
322
325
|
spinner.succeed(`Created tailwind.config.ts`);
|
|
323
|
-
} else {
|
|
324
|
-
spinner.info(`Tailwind 4 detected - skipping tailwind.config.ts`);
|
|
325
326
|
}
|
|
326
327
|
} catch (error) {
|
|
327
328
|
spinner.fail("Failed to initialize project");
|
|
@@ -329,26 +330,38 @@ export function cn(...inputs: ClassValue[]) {
|
|
|
329
330
|
process.exit(1);
|
|
330
331
|
}
|
|
331
332
|
}
|
|
332
|
-
|
|
333
|
+
async installDependencies() {
|
|
333
334
|
const cfg = this.config;
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
console.log(`Tailwind: ${cfg.isTailwind4 ? "v4" : "v3"}`);
|
|
337
|
-
const requiredDeps = [
|
|
335
|
+
const spinner = ora("Installing dependencies...").start();
|
|
336
|
+
const deps = [
|
|
338
337
|
"clsx",
|
|
339
338
|
"tailwind-merge",
|
|
340
339
|
"class-variance-authority",
|
|
341
340
|
"react-icons"
|
|
342
341
|
];
|
|
343
342
|
if (!cfg.isTailwind4) {
|
|
344
|
-
|
|
343
|
+
deps.push("tailwindcss-animate");
|
|
344
|
+
}
|
|
345
|
+
try {
|
|
346
|
+
await execa(cfg.packageManager, [cfg.installCmd, ...deps], {
|
|
347
|
+
cwd: cfg.cwd,
|
|
348
|
+
stdio: "pipe"
|
|
349
|
+
});
|
|
350
|
+
spinner.succeed(`Installed ${deps.length} dependencies`);
|
|
351
|
+
} catch (error) {
|
|
352
|
+
spinner.fail("Failed to install dependencies");
|
|
353
|
+
logger.warn(`
|
|
354
|
+
Manually run: ${cfg.packageManager} ${cfg.installCmd} ${deps.join(" ")}`);
|
|
345
355
|
}
|
|
346
|
-
|
|
347
|
-
|
|
356
|
+
}
|
|
357
|
+
printSuccess() {
|
|
358
|
+
const cfg = this.config;
|
|
359
|
+
logger.success("\n\u2705 Project initialized successfully!\n");
|
|
360
|
+
console.log(`Theme: ${cfg.selectedTheme}`);
|
|
361
|
+
console.log(`Tailwind: ${cfg.isTailwind4 ? "v4" : "v3"}`);
|
|
348
362
|
console.log("\n\u2728 Next steps:");
|
|
349
|
-
console.log(" 1.
|
|
350
|
-
console.log(" 2. npx @srcroot/ui add
|
|
351
|
-
console.log(" 3. npx @srcroot/ui add --all");
|
|
363
|
+
console.log(" 1. npx @srcroot/ui add button");
|
|
364
|
+
console.log(" 2. npx @srcroot/ui add --all");
|
|
352
365
|
console.log();
|
|
353
366
|
}
|
|
354
367
|
};
|
|
@@ -360,8 +373,8 @@ async function init(options) {
|
|
|
360
373
|
}
|
|
361
374
|
|
|
362
375
|
// src/cli/commands/add.ts
|
|
363
|
-
import
|
|
364
|
-
import
|
|
376
|
+
import fs4 from "fs-extra";
|
|
377
|
+
import path4 from "path";
|
|
365
378
|
import ora2 from "ora";
|
|
366
379
|
import prompts2 from "prompts";
|
|
367
380
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -746,9 +759,9 @@ var REGISTRY = {
|
|
|
746
759
|
};
|
|
747
760
|
|
|
748
761
|
// src/cli/commands/add.ts
|
|
749
|
-
var __dirname4 =
|
|
762
|
+
var __dirname4 = path4.dirname(fileURLToPath3(import.meta.url));
|
|
750
763
|
async function add(components, options) {
|
|
751
|
-
const cwd =
|
|
764
|
+
const cwd = path4.resolve(options.cwd);
|
|
752
765
|
if (options.all) {
|
|
753
766
|
components = Object.keys(REGISTRY);
|
|
754
767
|
}
|
|
@@ -811,16 +824,16 @@ async function add(components, options) {
|
|
|
811
824
|
}
|
|
812
825
|
console.log();
|
|
813
826
|
const spinner = ora2("Adding components...").start();
|
|
814
|
-
const hasSrc =
|
|
815
|
-
const srcPath = hasSrc ?
|
|
816
|
-
const componentsDir =
|
|
827
|
+
const hasSrc = fs4.existsSync(path4.join(cwd, "src"));
|
|
828
|
+
const srcPath = hasSrc ? path4.join(cwd, "src") : cwd;
|
|
829
|
+
const componentsDir = path4.join(srcPath, "components", "ui");
|
|
817
830
|
try {
|
|
818
|
-
await
|
|
831
|
+
await fs4.ensureDir(componentsDir);
|
|
819
832
|
for (const name of componentsToAdd) {
|
|
820
833
|
const comp = REGISTRY[name];
|
|
821
|
-
const fileName =
|
|
822
|
-
const targetPath =
|
|
823
|
-
if (
|
|
834
|
+
const fileName = path4.basename(comp.file);
|
|
835
|
+
const targetPath = path4.join(componentsDir, fileName);
|
|
836
|
+
if (fs4.existsSync(targetPath) && !options.overwrite) {
|
|
824
837
|
spinner.stop();
|
|
825
838
|
const { overwrite } = await prompts2({
|
|
826
839
|
type: "confirm",
|
|
@@ -835,13 +848,13 @@ async function add(components, options) {
|
|
|
835
848
|
}
|
|
836
849
|
spinner.start("Adding components...");
|
|
837
850
|
}
|
|
838
|
-
const registryPath =
|
|
839
|
-
if (!
|
|
851
|
+
const registryPath = path4.resolve(__dirname4, "..", "src", "registry", comp.file);
|
|
852
|
+
if (!fs4.existsSync(registryPath)) {
|
|
840
853
|
spinner.warn(`Registry file not found for ${name}: ${registryPath}`);
|
|
841
854
|
continue;
|
|
842
855
|
}
|
|
843
|
-
const content = await
|
|
844
|
-
await
|
|
856
|
+
const content = await fs4.readFile(registryPath, "utf-8");
|
|
857
|
+
await fs4.writeFile(targetPath, content);
|
|
845
858
|
if (componentsToAdd.length > 10) {
|
|
846
859
|
spinner.text = `Adding ${fileName}...`;
|
|
847
860
|
} else {
|
|
@@ -891,19 +904,19 @@ async function list() {
|
|
|
891
904
|
}
|
|
892
905
|
|
|
893
906
|
// src/cli/utils/get-package-info.ts
|
|
894
|
-
import
|
|
895
|
-
import
|
|
907
|
+
import path5 from "path";
|
|
908
|
+
import fs5 from "fs-extra";
|
|
896
909
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
897
910
|
function getPackageInfo() {
|
|
898
911
|
const __filename2 = fileURLToPath4(import.meta.url);
|
|
899
|
-
const __dirname5 =
|
|
912
|
+
const __dirname5 = path5.dirname(__filename2);
|
|
900
913
|
const pathsToCheck = [
|
|
901
|
-
|
|
902
|
-
|
|
914
|
+
path5.resolve(__dirname5, "..", "package.json"),
|
|
915
|
+
path5.resolve(__dirname5, "..", "..", "..", "package.json")
|
|
903
916
|
];
|
|
904
917
|
for (const pkgPath of pathsToCheck) {
|
|
905
|
-
if (
|
|
906
|
-
return
|
|
918
|
+
if (fs5.existsSync(pkgPath)) {
|
|
919
|
+
return fs5.readJSONSync(pkgPath);
|
|
907
920
|
}
|
|
908
921
|
}
|
|
909
922
|
return { version: "0.0.0" };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@srcroot/ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.35",
|
|
4
4
|
"description": "A UI library with polymorphic, accessible React components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"chalk": "^5.3.0",
|
|
27
27
|
"commander": "^12.1.0",
|
|
28
|
+
"execa": "^9.6.1",
|
|
28
29
|
"fs-extra": "^11.2.0",
|
|
29
30
|
"ora": "^8.1.1",
|
|
30
31
|
"prompts": "^2.4.2"
|