@mriqbox/ui-kit 2.0.0 → 2.1.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.
Files changed (3) hide show
  1. package/README.md +9 -6
  2. package/bin/cli.js +151 -0
  3. package/package.json +9 -2
package/README.md CHANGED
@@ -22,10 +22,10 @@ npm install @mriqbox/ui-kit
22
22
 
23
23
  **Uso:**
24
24
  ```tsx
25
- import { Button } from '@mriqbox/ui-kit';
25
+ import { MriButton } from '@mriqbox/ui-kit';
26
26
 
27
27
  export default function MyComponent() {
28
- return <Button>Clique aqui</Button>;
28
+ return <MriButton>Clique aqui</MriButton>;
29
29
  }
30
30
  ```
31
31
 
@@ -34,12 +34,15 @@ Ideal se você quer ter o código dos componentes no seu projeto para customizá
34
34
 
35
35
  Este projeto contém um arquivo `components.json` na raiz, permitindo o uso da CLI do shadcn.
36
36
 
37
- **Adicionar componente via CLI:**
38
- No diretório raiz deste projeto:
37
+ **Adicionar componente via CLI (Novo):**
38
+ Você pode adicionar componentes individualmente (estilo Shadcn) direto do nosso repositório:
39
+
39
40
  ```bash
40
- npx shadcn-ui@latest add button
41
+ npx @mriqbox/ui-kit add mri-button
41
42
  ```
42
- Isso irá baixar o código do componente `Button` para `src/components/ui/button.tsx`.
43
+ Isso irá baixar o código fonte do `MriButton.tsx` para `src/components/ui/MriButton.tsx` (ou diretório configurado, se detectado).
44
+
45
+ **Nota:** A CLI irá baixar apenas o arquivo do componente. Verifique se ele possui dependências de outros componentes `Mri*` e adicione-os também se necessário.
43
46
 
44
47
  ## ⚙️ Configuração (Para uso via NPM)
45
48
 
package/bin/cli.js ADDED
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Simple CLI to add Mri UI components to a project.
5
+ * Usage: npx @mriqbox/ui-kit add <component-name>
6
+ * Example: npx @mriqbox/ui-kit add mri-button
7
+ */
8
+
9
+ import { Command } from 'commander';
10
+ import chalk from 'chalk';
11
+ import fs from 'fs';
12
+ import path from 'path';
13
+ import https from 'https';
14
+
15
+ const program = new Command();
16
+ const BASE_URL = 'https://raw.githubusercontent.com/mri-Qbox-Brasil/mri-ui-kit/main/src/components/ui';
17
+
18
+ function toPascalCase(str) {
19
+ return str
20
+ .replace(/(^\w|-\w)/g, (clear) => clear.replace(/-/, "").toUpperCase());
21
+ }
22
+ function ensureDirectory(dir) {
23
+ if (!fs.existsSync(dir)) {
24
+ fs.mkdirSync(dir, { recursive: true });
25
+ }
26
+ }
27
+
28
+ function downloadFile(url, dest) {
29
+ return new Promise((resolve, reject) => {
30
+ const file = fs.createWriteStream(dest);
31
+ https.get(url, (response) => {
32
+ if (response.statusCode === 200) {
33
+ response.pipe(file);
34
+ file.on('finish', () => {
35
+ file.close(resolve);
36
+ });
37
+ } else {
38
+ fs.unlink(dest, () => { });
39
+ reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`));
40
+ }
41
+ }).on('error', (err) => {
42
+ fs.unlink(dest, () => { });
43
+ reject(err);
44
+ });
45
+ });
46
+ }
47
+
48
+ const visited = new Set();
49
+
50
+ async function processComponent(componentName, installDir) {
51
+ let targetName = componentName;
52
+
53
+ let fileName = componentName;
54
+ let isVariant = componentName.includes('variants');
55
+
56
+ if (!isVariant) {
57
+ if (!fileName.startsWith('Mri') && !fileName.match(/^[A-Z]/)) {
58
+ fileName = toPascalCase(fileName);
59
+ }
60
+ if (!fileName.startsWith('Mri')) {
61
+ fileName = `Mri${fileName}`;
62
+ }
63
+ if (!fileName.endsWith('.tsx')) fileName += '.tsx';
64
+ } else {
65
+ if (!fileName.endsWith('.ts')) fileName += '.ts';
66
+ }
67
+ if (visited.has(fileName)) return;
68
+ visited.add(fileName);
69
+
70
+ const destPath = path.join(installDir, fileName);
71
+ const fileUrl = `${BASE_URL}/${fileName}`;
72
+
73
+ if (fs.existsSync(destPath)) {
74
+ console.log(chalk.gray(` ${fileName} already exists.`));
75
+ // Even if exists, we should scan it for dependencies?
76
+ // Maybe the user has an outdated version.
77
+ // For detailed recursion, strictly we should read it.
78
+ // But let's assume if it exists, its deps are likely handled or user manages it.
79
+ // To be safe for "fresh" installs, let's scan it anyway if we can read it.
80
+ // But standard 'add' usually skips or prompts overwrite.
81
+ // Let's just skip download but continues to scan deps if we want to be thorough.
82
+ // For this "Simple CLI", let's stop at existence to avoid overwriting user changes.
83
+ // BUT we must check its imports to ensure children exist.
84
+ checkDependencies(destPath, installDir);
85
+ return;
86
+ }
87
+
88
+ console.log(chalk.cyan(`⬇️ Downloading ${fileName}...`));
89
+ try {
90
+ await downloadFile(fileUrl, destPath);
91
+ console.log(chalk.green(`✅ ${fileName} added.`));
92
+
93
+ await checkDependencies(destPath, installDir);
94
+
95
+ } catch (err) {
96
+ console.error(chalk.red(`❌ Error downloading ${fileName}: ${err.message}`));
97
+ }
98
+ }
99
+
100
+ async function checkDependencies(filePath, installDir) {
101
+ try {
102
+ const content = fs.readFileSync(filePath, 'utf8');
103
+ const importRegex = /from\s+['"](?:@\/components\/ui\/|\.\/)([^'"]+)['"]/g;
104
+ let match;
105
+
106
+ while ((match = importRegex.exec(content)) !== null) {
107
+ const depName = match[1];
108
+ if (depName.startsWith('Mri') || depName.includes('variants')) {
109
+ await processComponent(depName, installDir);
110
+ }
111
+ }
112
+ } catch (e) {
113
+ console.warn(chalk.yellow(`Could not parse dependencies for ${filePath}`));
114
+ }
115
+ }
116
+
117
+ program
118
+ .name('mri-ui')
119
+ .description('Add Mri UI components to your project')
120
+ .version('2.0.0');
121
+
122
+ program
123
+ .command('add <component>')
124
+ .description('Add a component to your project')
125
+ .action(async (componentName) => {
126
+ try {
127
+ console.log(chalk.blue(`🔹 Resolving ${componentName}...`));
128
+
129
+ let installDir = './src/components/ui';
130
+ if (fs.existsSync('components.json')) {
131
+ try {
132
+ if (fs.existsSync('./components/ui')) installDir = './components/ui';
133
+ } catch (e) { }
134
+ } else if (fs.existsSync('./components/ui')) {
135
+ installDir = './components/ui';
136
+ }
137
+
138
+ console.log(chalk.gray(` Target directory: ${installDir}`));
139
+ ensureDirectory(installDir);
140
+
141
+ await processComponent(componentName, installDir);
142
+
143
+ console.log(chalk.blue(`\n🎉 Done!`));
144
+ console.log(chalk.gray(` Don't forget to install external libraries if prompted by your linter (lucide-react, etc).`));
145
+
146
+ } catch (error) {
147
+ console.error(chalk.red('An unexpected error occurred:'), error);
148
+ }
149
+ });
150
+
151
+ program.parse();
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "2.0.0",
6
+ "version": "2.1.0",
7
7
  "type": "module",
8
8
  "main": "./dist/index.umd.js",
9
9
  "module": "./dist/index.es.js",
@@ -17,19 +17,26 @@
17
17
  "./dist/style.css": "./dist/style.css"
18
18
  },
19
19
  "files": [
20
- "dist"
20
+ "dist",
21
+ "bin"
21
22
  ],
23
+ "bin": {
24
+ "mri-ui": "./bin/cli.js"
25
+ },
22
26
  "dependencies": {
23
27
  "@radix-ui/react-dialog": "^1.0.5",
24
28
  "@radix-ui/react-popover": "^1.0.7",
25
29
  "@radix-ui/react-scroll-area": "^1.2.10",
26
30
  "@radix-ui/react-slot": "^1.0.2",
31
+ "chalk": "^5.6.2",
27
32
  "class-variance-authority": "^0.7.0",
28
33
  "clsx": "^2.1.0",
29
34
  "cmdk": "^1.0.0",
35
+ "commander": "^14.0.2",
30
36
  "date-fns": "^4.1.0",
31
37
  "lucide-react": "^0.344.0",
32
38
  "next-themes": "^0.4.6",
39
+ "prompts": "^2.4.2",
33
40
  "react": "^18.2.0",
34
41
  "react-day-picker": "^8.10.1",
35
42
  "react-dom": "^18.2.0",