purvex-ui 1.0.6 ā 1.0.8
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.js +61 -86
- package/src/commands/setup.js +1 -1
package/package.json
CHANGED
package/src/commands/add.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
const fs = require('fs');
|
|
2
3
|
const path = require('path');
|
|
3
4
|
const chalk = require('chalk');
|
|
@@ -6,112 +7,86 @@ async function addComponent(componentName, options) {
|
|
|
6
7
|
try {
|
|
7
8
|
console.log(chalk.blue.bold(`\nš Adding ${componentName}...\n`));
|
|
8
9
|
|
|
9
|
-
//
|
|
10
|
-
const
|
|
11
|
-
button: `import React from "react";
|
|
12
|
-
import { cn } from "@/lib/utils";
|
|
13
|
-
|
|
14
|
-
const Button = React.forwardRef(function Button(
|
|
15
|
-
{ className, variant = "default", size = "default", children, ...props },
|
|
16
|
-
ref
|
|
17
|
-
) {
|
|
18
|
-
return (
|
|
19
|
-
<button
|
|
20
|
-
className={cn(
|
|
21
|
-
"inline-flex items-center justify-center rounded-lg px-5 py-2",
|
|
22
|
-
"bg-primary text-primary-foreground hover:bg-primary/90",
|
|
23
|
-
"font-bold text-sm transition-all",
|
|
24
|
-
className
|
|
25
|
-
)}
|
|
26
|
-
ref={ref}
|
|
27
|
-
{...props}
|
|
28
|
-
>
|
|
29
|
-
{children}
|
|
30
|
-
</button>
|
|
31
|
-
);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
Button.displayName = "Button";
|
|
35
|
-
|
|
36
|
-
export { Button };`,
|
|
37
|
-
|
|
38
|
-
card: `import React from 'react';
|
|
39
|
-
import { cn } from '@/lib/utils';
|
|
40
|
-
|
|
41
|
-
const Card = React.forwardRef(function Card({ className, ...props }, ref) {
|
|
42
|
-
return (
|
|
43
|
-
<div
|
|
44
|
-
ref={ref}
|
|
45
|
-
className={cn("rounded-2xl border bg-card p-6", className)}
|
|
46
|
-
{...props}
|
|
47
|
-
/>
|
|
48
|
-
);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
Card.displayName = "Card";
|
|
52
|
-
|
|
53
|
-
export { Card };`,
|
|
54
|
-
|
|
55
|
-
avatar: `import React from 'react';
|
|
56
|
-
import { cn } from '@/lib/utils';
|
|
57
|
-
|
|
58
|
-
const Avatar = React.forwardRef(function Avatar({
|
|
59
|
-
src,
|
|
60
|
-
alt = "avatar",
|
|
61
|
-
size = 72,
|
|
62
|
-
className,
|
|
63
|
-
...props
|
|
64
|
-
}, ref) {
|
|
65
|
-
return (
|
|
66
|
-
<div
|
|
67
|
-
ref={ref}
|
|
68
|
-
className={cn("rounded-full overflow-hidden shrink-0", className)}
|
|
69
|
-
style={{ width: \`\${size}px\`, height: \`\${size}px\` }}
|
|
70
|
-
{...props}
|
|
71
|
-
>
|
|
72
|
-
<img src={src} alt={alt} className="w-full h-full object-cover" />
|
|
73
|
-
</div>
|
|
74
|
-
);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
Avatar.displayName = "Avatar";
|
|
78
|
-
|
|
79
|
-
export { Avatar };`
|
|
80
|
-
};
|
|
10
|
+
// Available components
|
|
11
|
+
const availableComponents = ['button', 'card', 'avatar'];
|
|
81
12
|
|
|
82
|
-
|
|
83
|
-
if (!TEMPLATES[componentName]) {
|
|
13
|
+
if (!availableComponents.includes(componentName)) {
|
|
84
14
|
console.log(chalk.red(`ā Component "${componentName}" not available`));
|
|
85
|
-
console.log(chalk.yellow('\nAvailable
|
|
86
|
-
console.log(chalk.cyan(
|
|
87
|
-
|
|
88
|
-
|
|
15
|
+
console.log(chalk.yellow('\nAvailable:'));
|
|
16
|
+
availableComponents.forEach(c => console.log(chalk.cyan(` ⢠${c}`)));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// === CARI FILE TEMPLATE ===
|
|
21
|
+
// 1. Cari di local CLI package (development)
|
|
22
|
+
let templatePath = path.join(__dirname, '..', 'templates', `${componentName}.jsx`);
|
|
23
|
+
|
|
24
|
+
// 2. Jika tidak ada, cari di installed package (production)
|
|
25
|
+
if (!fs.existsSync(templatePath)) {
|
|
26
|
+
templatePath = path.join(__dirname, '..', '..', '..', 'templates', `${componentName}.jsx`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 3. Jika masih tidak ada, cari di node_modules
|
|
30
|
+
if (!fs.existsSync(templatePath)) {
|
|
31
|
+
templatePath = path.join(process.cwd(), 'node_modules', 'purvex-ui', 'templates', `${componentName}.jsx`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 4. Jika TETAP tidak ada, ERROR
|
|
35
|
+
if (!fs.existsSync(templatePath)) {
|
|
36
|
+
console.log(chalk.red(`ā Template file for "${componentName}" not found!`));
|
|
37
|
+
console.log(chalk.yellow('Expected at:'));
|
|
38
|
+
console.log(chalk.gray(` ${path.join(__dirname, '..', 'templates', `${componentName}.jsx`)}`));
|
|
39
|
+
console.log(chalk.gray(` ${path.join(process.cwd(), 'node_modules', 'purvex-ui', 'templates', `${componentName}.jsx`)}`));
|
|
89
40
|
return;
|
|
90
41
|
}
|
|
91
42
|
|
|
92
|
-
|
|
43
|
+
console.log(chalk.gray(`š Using template: ${templatePath}`));
|
|
44
|
+
|
|
45
|
+
// === BACA FILE TEMPLATE ===
|
|
46
|
+
const templateContent = fs.readFileSync(templatePath, 'utf-8');
|
|
47
|
+
|
|
48
|
+
// === BUAT DIRECTORY ===
|
|
93
49
|
const targetDir = path.join(process.cwd(), 'src', 'components', 'ui');
|
|
94
50
|
if (!fs.existsSync(targetDir)) {
|
|
95
51
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
96
|
-
console.log(chalk.green(`ā
Created
|
|
52
|
+
console.log(chalk.green(`ā
Created: ${path.relative(process.cwd(), targetDir)}`));
|
|
97
53
|
}
|
|
98
54
|
|
|
99
|
-
//
|
|
55
|
+
// === TULIS FILE ===
|
|
100
56
|
const filePath = path.join(targetDir, `${componentName}.jsx`);
|
|
101
|
-
fs.writeFileSync(filePath,
|
|
57
|
+
fs.writeFileSync(filePath, templateContent);
|
|
102
58
|
|
|
103
59
|
console.log(chalk.green(`ā
Created: ${path.relative(process.cwd(), filePath)}`));
|
|
104
60
|
|
|
105
|
-
//
|
|
106
|
-
|
|
61
|
+
// === COPY utils.js JIKA PERLU ===
|
|
62
|
+
const utilsSource = path.join(path.dirname(templatePath), 'utils.js');
|
|
63
|
+
const utilsTarget = path.join(process.cwd(), 'src', 'lib', 'utils.js');
|
|
64
|
+
|
|
65
|
+
if (fs.existsSync(utilsSource) && !fs.existsSync(path.join(process.cwd(), 'src', 'lib'))) {
|
|
66
|
+
fs.mkdirSync(path.join(process.cwd(), 'src', 'lib'), { recursive: true });
|
|
67
|
+
fs.copyFileSync(utilsSource, utilsTarget);
|
|
68
|
+
console.log(chalk.green(`ā
Created: src/lib/utils.js`));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// === SUCCESS MESSAGE ===
|
|
72
|
+
console.log(chalk.green.bold(`\nš ${componentName} added successfully!`));
|
|
107
73
|
console.log(chalk.white('\nUsage:'));
|
|
108
74
|
console.log(chalk.cyan(` import { ${componentName.charAt(0).toUpperCase() + componentName.slice(1)} } from "@/components/ui/${componentName}";`));
|
|
75
|
+
|
|
76
|
+
if (componentName === 'button') {
|
|
77
|
+
console.log(chalk.white('\nExample:'));
|
|
78
|
+
console.log(chalk.gray(` <Button variant="default">Click me</Button>`));
|
|
79
|
+
console.log(chalk.gray(` <Button variant="destructive">Delete</Button>`));
|
|
80
|
+
console.log(chalk.gray(` <Button variant="outline">Outline</Button>`));
|
|
81
|
+
}
|
|
82
|
+
|
|
109
83
|
console.log(chalk.white('\nStart dev server:'));
|
|
110
|
-
console.log(chalk.cyan(' npm run dev'));
|
|
84
|
+
console.log(chalk.cyan(' npm run dev\n'));
|
|
111
85
|
|
|
112
86
|
} catch (error) {
|
|
113
87
|
console.error(chalk.red('ā Error:'), error.message);
|
|
88
|
+
console.log(chalk.yellow('\nš” Tip: Make sure templates/ directory exists in the package.'));
|
|
114
89
|
}
|
|
115
90
|
}
|
|
116
91
|
|
|
117
|
-
module.exports = { addComponent };
|
|
92
|
+
module.exports = { addComponent };
|
package/src/commands/setup.js
CHANGED
|
@@ -115,7 +115,7 @@ export default defineConfig({
|
|
|
115
115
|
configContent = configContent.replace(
|
|
116
116
|
/plugins:\s*\[([\s\S]*?)\]/,
|
|
117
117
|
`plugins: [
|
|
118
|
-
|
|
118
|
+
$1\n, tailwindcss(),]`
|
|
119
119
|
);
|
|
120
120
|
// Tutup bracket dengan benar
|
|
121
121
|
configContent = configContent.replace(/tailwindcss\(\),\s*$/, 'tailwindcss(),\n ]');
|