@beaket/ui 0.1.8 → 1.0.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/package.json +1 -1
- package/src/commands/add.ts +28 -24
- package/src/commands/init.ts +23 -67
- package/src/index.ts +1 -0
- package/src/utils/config.ts +1 -11
- package/src/utils/files.ts +31 -14
package/package.json
CHANGED
package/src/commands/add.ts
CHANGED
|
@@ -4,7 +4,11 @@ import { getConfig } from "../utils/config.ts";
|
|
|
4
4
|
import { installDependencies, writeComponentFiles } from "../utils/files.ts";
|
|
5
5
|
import { fetchComponent, fetchRegistry } from "../utils/registry.ts";
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
interface AddOptions {
|
|
8
|
+
overwrite?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function add(componentName: string, options: AddOptions) {
|
|
8
12
|
console.log();
|
|
9
13
|
|
|
10
14
|
// Read config
|
|
@@ -16,9 +20,9 @@ export async function add(componentName: string) {
|
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
// Fetch registry
|
|
19
|
-
console.log(`Adding ${pc.cyan(componentName)}...`);
|
|
20
|
-
|
|
21
23
|
const registry = await fetchRegistry();
|
|
24
|
+
console.log(pc.green("✔"), "Checking registry.");
|
|
25
|
+
|
|
22
26
|
const componentDef = registry.components.find((c) => c.name === componentName);
|
|
23
27
|
|
|
24
28
|
if (!componentDef) {
|
|
@@ -31,35 +35,35 @@ export async function add(componentName: string) {
|
|
|
31
35
|
process.exit(1);
|
|
32
36
|
}
|
|
33
37
|
|
|
38
|
+
// Install dependencies
|
|
39
|
+
if (componentDef.dependencies.length > 0) {
|
|
40
|
+
await installDependencies(componentDef.dependencies);
|
|
41
|
+
console.log(pc.green("✔"), "Installing dependencies.");
|
|
42
|
+
}
|
|
43
|
+
|
|
34
44
|
// Fetch component files
|
|
35
45
|
const files = await fetchComponent(componentDef);
|
|
36
46
|
|
|
37
47
|
// Write files
|
|
38
|
-
const componentsDir = path.join(process.cwd(), config.
|
|
39
|
-
await writeComponentFiles(componentsDir,
|
|
48
|
+
const componentsDir = path.join(process.cwd(), config.components);
|
|
49
|
+
const { written, skipped } = await writeComponentFiles(componentsDir, files, options.overwrite);
|
|
40
50
|
|
|
41
|
-
|
|
51
|
+
// Show skipped files
|
|
52
|
+
if (skipped.length > 0) {
|
|
53
|
+
console.log(
|
|
54
|
+
pc.yellow("ℹ"),
|
|
55
|
+
`Skipped ${skipped.length} file(s): (use --overwrite to overwrite)`,
|
|
56
|
+
);
|
|
57
|
+
skipped.forEach((f) => console.log(` - ${f}`));
|
|
58
|
+
}
|
|
42
59
|
|
|
43
|
-
|
|
44
|
-
if (componentDef.dependencies.length > 0) {
|
|
60
|
+
if (written.length === 0) {
|
|
45
61
|
console.log();
|
|
46
|
-
|
|
47
|
-
await installDependencies(componentDef.dependencies);
|
|
48
|
-
console.log(pc.green("✓"), `Installed ${componentDef.dependencies.join(", ")}`);
|
|
62
|
+
return;
|
|
49
63
|
}
|
|
64
|
+
|
|
50
65
|
console.log();
|
|
51
|
-
console.log("
|
|
52
|
-
console.log(
|
|
53
|
-
pc.cyan(
|
|
54
|
-
` import { ${pascalCase(componentName)} } from "${config.aliases.components}/${componentName}";`,
|
|
55
|
-
),
|
|
56
|
-
);
|
|
66
|
+
console.log("Added:");
|
|
67
|
+
written.forEach((f) => console.log(pc.cyan(` ${f}`)));
|
|
57
68
|
console.log();
|
|
58
69
|
}
|
|
59
|
-
|
|
60
|
-
function pascalCase(str: string): string {
|
|
61
|
-
return str
|
|
62
|
-
.split("-")
|
|
63
|
-
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
64
|
-
.join("");
|
|
65
|
-
}
|
package/src/commands/init.ts
CHANGED
|
@@ -3,7 +3,6 @@ import path from "path";
|
|
|
3
3
|
import pc from "picocolors";
|
|
4
4
|
import prompts from "prompts";
|
|
5
5
|
import { writeConfig, type BeaketConfig } from "../utils/config.ts";
|
|
6
|
-
import { installDependencies } from "../utils/files.ts";
|
|
7
6
|
|
|
8
7
|
const CSS_VARIABLES = `
|
|
9
8
|
/* Beaket UI Design System */
|
|
@@ -38,97 +37,54 @@ export async function init() {
|
|
|
38
37
|
const response = await prompts([
|
|
39
38
|
{
|
|
40
39
|
type: "text",
|
|
41
|
-
name: "
|
|
42
|
-
message: "Where
|
|
43
|
-
initial: "src/components",
|
|
40
|
+
name: "components",
|
|
41
|
+
message: "Where should components be installed?",
|
|
42
|
+
initial: "src/components/ui",
|
|
44
43
|
},
|
|
45
44
|
{
|
|
46
45
|
type: "text",
|
|
47
|
-
name: "
|
|
48
|
-
message: "Where would you like to install utilities (cn, etc.)?",
|
|
49
|
-
initial: "src/lib",
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
type: "text",
|
|
53
|
-
name: "tailwindCss",
|
|
46
|
+
name: "css",
|
|
54
47
|
message: "Where is your Tailwind CSS file?",
|
|
55
48
|
initial: "src/index.css",
|
|
56
49
|
},
|
|
57
|
-
{
|
|
58
|
-
type: "text",
|
|
59
|
-
name: "componentsAlias",
|
|
60
|
-
message: "Components import alias",
|
|
61
|
-
initial: "@/components",
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
type: "text",
|
|
65
|
-
name: "utilsAlias",
|
|
66
|
-
message: "Utils import alias",
|
|
67
|
-
initial: "@/lib",
|
|
68
|
-
},
|
|
69
50
|
]);
|
|
70
51
|
|
|
71
|
-
if (!response.
|
|
52
|
+
if (!response.components) {
|
|
72
53
|
console.log(pc.red("Cancelled."));
|
|
73
54
|
process.exit(1);
|
|
74
55
|
}
|
|
75
56
|
|
|
57
|
+
// Write beaket.json (only components path)
|
|
76
58
|
const config: BeaketConfig = {
|
|
77
59
|
$schema: "https://beaket.dev/schema.json",
|
|
78
|
-
|
|
79
|
-
css: response.tailwindCss,
|
|
80
|
-
},
|
|
81
|
-
aliases: {
|
|
82
|
-
components: response.componentsAlias,
|
|
83
|
-
utils: response.utilsAlias,
|
|
84
|
-
},
|
|
85
|
-
paths: {
|
|
86
|
-
components: response.componentsDir,
|
|
87
|
-
utils: response.utilsDir,
|
|
88
|
-
},
|
|
60
|
+
components: response.components,
|
|
89
61
|
};
|
|
90
62
|
|
|
91
|
-
// Write beaket.json
|
|
92
63
|
await writeConfig(config);
|
|
93
|
-
console.log(pc.green("
|
|
64
|
+
console.log(pc.green("✔"), "Created beaket.json");
|
|
94
65
|
|
|
95
66
|
// Inject CSS variables into Tailwind CSS file
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
67
|
+
if (response.css) {
|
|
68
|
+
const cssPath = path.join(process.cwd(), response.css);
|
|
69
|
+
if (await fs.pathExists(cssPath)) {
|
|
70
|
+
const cssContent = await fs.readFile(cssPath, "utf-8");
|
|
71
|
+
if (!cssContent.includes("Beaket UI Design System")) {
|
|
72
|
+
await fs.writeFile(cssPath, cssContent + CSS_VARIABLES);
|
|
73
|
+
console.log(pc.green("✔"), `Added CSS variables to ${response.css}`);
|
|
74
|
+
} else {
|
|
75
|
+
console.log(pc.yellow("ℹ"), "CSS variables already exist");
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
console.log(pc.yellow("!"), `CSS file not found: ${response.css}`);
|
|
79
|
+
console.log(" Add CSS variables manually:");
|
|
80
|
+
console.log(pc.cyan(" https://beaket.github.io/ui/installation"));
|
|
102
81
|
}
|
|
103
|
-
} else {
|
|
104
|
-
console.log(pc.yellow("!"), `CSS file not found: ${response.tailwindCss}`);
|
|
105
82
|
}
|
|
106
83
|
|
|
107
|
-
// Create utils directory and cn function
|
|
108
|
-
const utilsDir = path.join(process.cwd(), response.utilsDir);
|
|
109
|
-
await fs.ensureDir(utilsDir);
|
|
110
|
-
|
|
111
|
-
const cnContent = `import { type ClassValue, clsx } from "clsx";
|
|
112
|
-
import { twMerge } from "tailwind-merge";
|
|
113
|
-
|
|
114
|
-
export function cn(...inputs: ClassValue[]) {
|
|
115
|
-
return twMerge(clsx(inputs));
|
|
116
|
-
}
|
|
117
|
-
`;
|
|
118
|
-
|
|
119
|
-
await fs.writeFile(path.join(utilsDir, "utils.ts"), cnContent);
|
|
120
|
-
console.log(pc.green("✓"), `Created ${response.utilsDir}/utils.ts`);
|
|
121
|
-
|
|
122
|
-
// Install dependencies
|
|
123
|
-
console.log();
|
|
124
|
-
console.log("Installing dependencies...");
|
|
125
|
-
await installDependencies(["clsx", "tailwind-merge"]);
|
|
126
|
-
console.log(pc.green("✓"), "Installed clsx, tailwind-merge");
|
|
127
|
-
|
|
128
84
|
console.log();
|
|
129
85
|
console.log(pc.green("Done!"), "Beaket UI is ready.");
|
|
130
86
|
console.log();
|
|
131
|
-
console.log("
|
|
87
|
+
console.log("Add components:");
|
|
132
88
|
console.log(pc.cyan(" npx @beaket/ui add button"));
|
|
133
89
|
console.log();
|
|
134
90
|
}
|
package/src/index.ts
CHANGED
package/src/utils/config.ts
CHANGED
|
@@ -3,17 +3,7 @@ import path from "path";
|
|
|
3
3
|
|
|
4
4
|
export interface BeaketConfig {
|
|
5
5
|
$schema?: string;
|
|
6
|
-
|
|
7
|
-
css: string;
|
|
8
|
-
};
|
|
9
|
-
aliases: {
|
|
10
|
-
components: string;
|
|
11
|
-
utils: string;
|
|
12
|
-
};
|
|
13
|
-
paths: {
|
|
14
|
-
components: string;
|
|
15
|
-
utils: string;
|
|
16
|
-
};
|
|
6
|
+
components: string;
|
|
17
7
|
}
|
|
18
8
|
|
|
19
9
|
const CONFIG_FILE = "beaket.json";
|
package/src/utils/files.ts
CHANGED
|
@@ -1,32 +1,49 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
2
|
import fs from "fs-extra";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import
|
|
4
|
+
import prompts from "prompts";
|
|
5
5
|
import type { ComponentFile } from "./registry.ts";
|
|
6
6
|
|
|
7
|
+
export interface WriteResult {
|
|
8
|
+
written: string[];
|
|
9
|
+
skipped: string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
7
12
|
export async function writeComponentFiles(
|
|
8
13
|
baseDir: string,
|
|
9
|
-
componentName: string,
|
|
10
14
|
files: ComponentFile[],
|
|
11
|
-
|
|
12
|
-
): Promise<
|
|
15
|
+
overwrite: boolean = false,
|
|
16
|
+
): Promise<WriteResult> {
|
|
17
|
+
const written: string[] = [];
|
|
18
|
+
const skipped: string[] = [];
|
|
19
|
+
|
|
13
20
|
for (const file of files) {
|
|
14
|
-
// Transform file path: components/button
|
|
21
|
+
// Transform file path: components/button.tsx -> button.tsx
|
|
15
22
|
const relativePath = file.path.replace(/^components\//, "");
|
|
16
23
|
const targetPath = path.join(baseDir, relativePath);
|
|
17
24
|
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
// Check if file exists
|
|
26
|
+
if (await fs.pathExists(targetPath)) {
|
|
27
|
+
if (!overwrite) {
|
|
28
|
+
const { confirm } = await prompts({
|
|
29
|
+
type: "confirm",
|
|
30
|
+
name: "confirm",
|
|
31
|
+
message: `${path.basename(targetPath)} already exists. Overwrite?`,
|
|
32
|
+
initial: false,
|
|
33
|
+
});
|
|
34
|
+
if (!confirm) {
|
|
35
|
+
skipped.push(targetPath);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
26
40
|
|
|
27
41
|
await fs.ensureDir(path.dirname(targetPath));
|
|
28
|
-
await fs.writeFile(targetPath, content);
|
|
42
|
+
await fs.writeFile(targetPath, file.content);
|
|
43
|
+
written.push(targetPath);
|
|
29
44
|
}
|
|
45
|
+
|
|
46
|
+
return { written, skipped };
|
|
30
47
|
}
|
|
31
48
|
|
|
32
49
|
export async function installDependencies(deps: string[]): Promise<void> {
|