@dropi/ui 0.1.14 → 0.1.16
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 +4 -1
- package/readme.md +23 -51
- package/scripts/postinstall.js +30 -251
- package/scripts/setup.js +162 -0
- package/skills/install-dropi-ui/cursor.mdc +2 -7
- package/skills/install-dropi-ui/skill.md +25 -173
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dropi/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "Dropi Design System — Web Components for Angular, React and Vue",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
"skills/",
|
|
33
33
|
"scripts/"
|
|
34
34
|
],
|
|
35
|
+
"bin": {
|
|
36
|
+
"@dropi/ui": "scripts/setup.js"
|
|
37
|
+
},
|
|
35
38
|
"scripts": {
|
|
36
39
|
"build": "stencil build && cd ../dropi-ui-react && npm run build",
|
|
37
40
|
"start": "stencil build --dev --watch --serve",
|
package/readme.md
CHANGED
|
@@ -3,70 +3,42 @@
|
|
|
3
3
|
Librería de Web Components del Design System de Dropi, construida con **Stencil.js v4**.
|
|
4
4
|
Genera componentes reutilizables para Angular, React y Vue desde una única base de código.
|
|
5
5
|
|
|
6
|
-
- **Paquete npm:** `@dropi/ui` (v0.1.
|
|
6
|
+
- **Paquete npm:** `@dropi/ui` (v0.1.15)
|
|
7
7
|
- **React wrappers:** `@dropi/ui-react`
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## ⚡ Quick Start (Recomendado)
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|---|---|
|
|
15
|
-
| React | `npm install @dropi/ui-react` |
|
|
16
|
-
| Angular / Vue / Vanilla | `npm install @dropi/ui` |
|
|
17
|
-
|
|
18
|
-
> **¿Por qué dos paquetes?**
|
|
19
|
-
> `@dropi/ui` contiene los Web Components puros (estándares del navegador).
|
|
20
|
-
> `@dropi/ui-react` son wrappers React auto-generados por Stencil que los envuelven con props tipadas, eventos estilo React (`onDropiChange`) y autocompletado en VSCode.
|
|
21
|
-
> `@dropi/ui-react` depende internamente de `@dropi/ui` — no necesitas instalar los dos.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Setup
|
|
26
|
-
|
|
27
|
-
### React (`main.tsx`)
|
|
28
|
-
|
|
29
|
-
Con `@dropi/ui-react` **no necesitas** llamar `defineCustomElements()` — cada wrapper registra su Web Component automáticamente al importarlo.
|
|
30
|
-
|
|
31
|
-
```typescript
|
|
32
|
-
import '@dropi/ui/dist/dropi-ui/dropi-ui.css' // estilos globales y tokens
|
|
33
|
-
|
|
34
|
-
// No se necesita defineCustomElements()
|
|
35
|
-
// Solo importa y usa los componentes directamente
|
|
36
|
-
```
|
|
13
|
+
La forma más rápida y segura de integrar la librería es usando nuestro configurador automático.
|
|
37
14
|
|
|
38
|
-
###
|
|
15
|
+
### Con IA (Claude / Cursor / Windsurf)
|
|
16
|
+
Si usas un asistente de IA, simplemente dile:
|
|
17
|
+
> **`/install-dropi-ui`** o **"configura dropi-ui en este proyecto"**
|
|
39
18
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
defineCustomElements()
|
|
45
|
-
bootstrapApplication(AppComponent, appConfig)
|
|
19
|
+
### Manual (Terminal)
|
|
20
|
+
Ejecuta el siguiente comando en la raíz de tu proyecto:
|
|
21
|
+
```bash
|
|
22
|
+
npx @dropi/ui setup
|
|
46
23
|
```
|
|
24
|
+
*Este comando detectará tu framework (Angular, React o Vue), instalará las dependencias necesarias y configurará estilos e iconos automáticamente.*
|
|
47
25
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```typescript
|
|
51
|
-
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'
|
|
52
|
-
|
|
53
|
-
@NgModule({ schemas: [CUSTOM_ELEMENTS_SCHEMA] })
|
|
54
|
-
// o en standalone:
|
|
55
|
-
@Component({ schemas: [CUSTOM_ELEMENTS_SCHEMA] })
|
|
56
|
-
```
|
|
26
|
+
---
|
|
57
27
|
|
|
58
|
-
|
|
28
|
+
## 🛠️ Instalación Manual
|
|
59
29
|
|
|
60
|
-
|
|
30
|
+
Si prefieres realizar la configuración paso a paso, consulta la [Guía de Integración Detallada](DROPI_UI_SETUP.md) o sigue estos pasos:
|
|
61
31
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
```
|
|
32
|
+
### 1. Paquetes
|
|
33
|
+
| Framework | Paquete a instalar |
|
|
34
|
+
|---|---|
|
|
35
|
+
| React | `npm install @dropi/ui @dropi/ui-react` |
|
|
36
|
+
| Angular / Vue / Vanilla | `npm install @dropi/ui` |
|
|
68
37
|
|
|
69
|
-
|
|
38
|
+
### 2. Estilos e Iconos
|
|
39
|
+
- **CSS**: Importar `@dropi/ui/dist/dropi-ui/dropi-ui.css` en tu entry point.
|
|
40
|
+
- **Loader**: Llamar a `defineCustomElements()` de `@dropi/ui/loader`.
|
|
41
|
+
- **Iconos**: El componente `<dropi-icon>` requiere que el sprite SVG esté en `/assets/icons/symbol/svg/sprite.css.svg`.
|
|
70
42
|
|
|
71
43
|
---
|
|
72
44
|
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,259 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* postinstall.js — @dropi/ui
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* 2. Copia skills para Claude Code, Cursor, Windsurf, Copilot
|
|
8
|
-
* 3. Parchea vite.config → optimizeDeps.exclude
|
|
9
|
-
* 4. Parchea tsconfig.app.json → skipLibCheck: true
|
|
10
|
-
* 5. Copia el sprite SVG al directorio público
|
|
4
|
+
*
|
|
5
|
+
* Este script se ejecuta tras la instalación.
|
|
6
|
+
* Ya no realiza cambios automáticos por seguridad y transparencia.
|
|
11
7
|
*/
|
|
12
8
|
|
|
13
|
-
const fs = require('fs');
|
|
14
9
|
const path = require('path');
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
//
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
## Contexto detectado
|
|
45
|
-
- Framework: **${framework}**
|
|
46
|
-
- Bundler: **${isVite ? 'Vite' : isAngular ? 'Angular CLI' : 'desconocido'}**
|
|
47
|
-
- Gestor de paquetes: **${pkgMgr.split(' ')[0]}**
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## Pasos a ejecutar
|
|
52
|
-
|
|
53
|
-
### 1 — Instalar dependencias (si no están instaladas)
|
|
54
|
-
\`\`\`bash
|
|
55
|
-
${isReact ? `${pkgMgr} @dropi/ui @dropi/ui-react` : `${pkgMgr} @dropi/ui`}
|
|
56
|
-
\`\`\`
|
|
57
|
-
|
|
58
|
-
### 2 — Fix Vite obligatorio ⚠️ (sin esto los componentes no cargan)
|
|
59
|
-
${isVite ? `Abre \`vite.config.ts\` (o \`.js\`) y agrega \`optimizeDeps\`:
|
|
60
|
-
|
|
61
|
-
\`\`\`ts
|
|
62
|
-
export default defineConfig({
|
|
63
|
-
plugins: [...],
|
|
64
|
-
optimizeDeps: {
|
|
65
|
-
exclude: ['@dropi/ui/loader', '@dropi/ui'],
|
|
66
|
-
},
|
|
67
|
-
})
|
|
68
|
-
\`\`\`
|
|
69
|
-
Resuelve: \`Failed to fetch dynamically imported module\`, \`Constructor not found\`, \`Missing field moduleType\`` : '_No aplica (no es proyecto Vite)_'}
|
|
70
|
-
|
|
71
|
-
### 3 — Inyectar estilos globales
|
|
72
|
-
${isAngular
|
|
73
|
-
? `Agregar al inicio de \`src/styles.scss\`:\n\`\`\`scss\n@import '@dropi/ui/dist/dropi-ui/dropi-ui.css';\n\`\`\``
|
|
74
|
-
: `Agregar al inicio de \`src/main.tsx\` o \`src/main.ts\`:\n\`\`\`ts\nimport '@dropi/ui/dist/dropi-ui/dropi-ui.css'\n\`\`\``}
|
|
75
|
-
|
|
76
|
-
### 4 — Registrar con lazy loader (OBLIGATORIO — nunca importar componentes directamente)
|
|
77
|
-
${isAngular
|
|
78
|
-
? `En \`src/main.ts\` o \`app.config.ts\`:\n\`\`\`ts\nimport { defineCustomElements } from '@dropi/ui/loader'\ndefineCustomElements()\n\`\`\`\nAgregar \`CUSTOM_ELEMENTS_SCHEMA\` al módulo o standalone config.`
|
|
79
|
-
: isReact
|
|
80
|
-
? `En \`src/main.tsx\`:\n\`\`\`tsx\nimport { defineCustomElements } from '@dropi/ui/loader'\ndefineCustomElements() // ← antes del createRoot\n\`\`\`\nEn los componentes, importar desde \`@dropi/ui-react\`:\n\`\`\`tsx\nimport { DropiButton, DropiSelect } from '@dropi/ui-react'\n\`\`\``
|
|
81
|
-
: `En \`src/main.ts\`:\n\`\`\`ts\nimport { defineCustomElements } from '@dropi/ui/loader'\ndefineCustomElements()\n\`\`\``}
|
|
82
|
-
|
|
83
|
-
### 5 — Copiar sprite de íconos
|
|
84
|
-
\`\`\`bash
|
|
85
|
-
node -e "const fs=require('fs');const src='node_modules/@dropi/ui/assets/icons/symbol/svg/sprite.css.svg';const dest='${isAngular ? 'src/assets' : 'public/assets'}/icons/symbol/svg/sprite.css.svg';fs.mkdirSync(require('path').dirname(dest),{recursive:true});if(!fs.existsSync(dest))fs.copyFileSync(src,dest);console.log('Sprite copiado ✅')"
|
|
86
|
-
\`\`\`
|
|
87
|
-
|
|
88
|
-
### 6 — Verificar tsconfig.app.json
|
|
89
|
-
Asegurarse de que tenga \`"skipLibCheck": true\` en \`compilerOptions\` para evitar errores de tipos de node_modules.
|
|
90
|
-
|
|
91
|
-
### 7 — Validar
|
|
92
|
-
\`\`\`bash
|
|
93
|
-
${pkgMgr.replace('add','run').replace('install','run')} build
|
|
94
|
-
\`\`\`
|
|
95
|
-
Si el build pasa sin errores → eliminar este archivo \`DROPI_UI_SETUP.md\`.
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
## Errores comunes
|
|
100
|
-
|
|
101
|
-
| Error | Fix |
|
|
102
|
-
|---|---|
|
|
103
|
-
| \`Failed to fetch dynamically imported module\` | Paso 2 — optimizeDeps en vite.config |
|
|
104
|
-
| \`Constructor for "dropi-button#undefined" was not found\` | Paso 2 |
|
|
105
|
-
| \`Missing field moduleType\` | Paso 2 |
|
|
106
|
-
| Errores de tipos en node_modules | Paso 6 — skipLibCheck |
|
|
107
|
-
| Íconos no aparecen | Paso 5 — sprite SVG |
|
|
108
|
-
`;
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
fs.writeFileSync(setupDest, setupContent, 'utf8');
|
|
112
|
-
log.ok.push('DROPI_UI_SETUP.md creado en la raíz del proyecto');
|
|
113
|
-
} catch (e) {
|
|
114
|
-
log.warn.push('No se pudo crear DROPI_UI_SETUP.md: ' + e.message);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// ── 2. Copiar skills para editores conocidos ──────────────────────────────────
|
|
119
|
-
const skillTargets = [
|
|
120
|
-
{
|
|
121
|
-
editor: 'Claude Code',
|
|
122
|
-
src: path.join(skillsBase, 'skill.md'),
|
|
123
|
-
dest: path.join(projectRoot, '.claude', 'skills', 'install-dropi-ui', 'skill.md'),
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
editor: 'Cursor',
|
|
127
|
-
src: path.join(skillsBase, 'cursor.mdc'),
|
|
128
|
-
dest: path.join(projectRoot, '.cursor', 'rules', 'install-dropi-ui.mdc'),
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
editor: 'Windsurf',
|
|
132
|
-
src: path.join(skillsBase, 'skill.md'),
|
|
133
|
-
dest: path.join(projectRoot, '.windsurfrules'),
|
|
134
|
-
transform: (content) => `# @dropi/ui — Configuración pendiente\nLee DROPI_UI_SETUP.md y ejecuta todos los pasos automáticamente.\n`,
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
editor: 'GitHub Copilot',
|
|
138
|
-
src: path.join(skillsBase, 'skill.md'),
|
|
139
|
-
dest: path.join(projectRoot, '.github', 'copilot-instructions.md'),
|
|
140
|
-
transform: (content) => `# @dropi/ui — Configuración pendiente\nLee DROPI_UI_SETUP.md en la raíz del proyecto y ejecuta todos los pasos automáticamente.\n`,
|
|
141
|
-
},
|
|
142
|
-
];
|
|
143
|
-
|
|
144
|
-
const skillsCopied = [];
|
|
145
|
-
for (const t of skillTargets) {
|
|
146
|
-
try {
|
|
147
|
-
if (fs.existsSync(t.dest)) continue;
|
|
148
|
-
fs.mkdirSync(path.dirname(t.dest), { recursive: true });
|
|
149
|
-
const content = t.transform
|
|
150
|
-
? t.transform(fs.readFileSync(t.src, 'utf8'))
|
|
151
|
-
: fs.readFileSync(t.src, 'utf8');
|
|
152
|
-
fs.writeFileSync(t.dest, content, 'utf8');
|
|
153
|
-
skillsCopied.push(t.editor);
|
|
154
|
-
} catch (e) {
|
|
155
|
-
log.warn.push(`No se pudo copiar skill para ${t.editor}: ${e.message}`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// ── 3. Parchar vite.config ────────────────────────────────────────────────────
|
|
160
|
-
let vitePatchDone = false;
|
|
161
|
-
if (isVite) {
|
|
162
|
-
for (const f of ['vite.config.ts','vite.config.js','vite.config.mts']) {
|
|
163
|
-
const p = path.join(projectRoot, f);
|
|
164
|
-
if (!fs.existsSync(p)) continue;
|
|
165
|
-
const content = fs.readFileSync(p, 'utf8');
|
|
166
|
-
if (content.includes('@dropi/ui/loader') && content.includes("exclude")) { vitePatchDone = 'ya'; break; }
|
|
167
|
-
const patch = `\n optimizeDeps: {\n exclude: ['@dropi/ui/loader', '@dropi/ui'],\n },`;
|
|
168
|
-
const updated = content.replace(/defineConfig\(\{/, `defineConfig({${patch}`);
|
|
169
|
-
if (updated !== content) { fs.writeFileSync(p, updated, 'utf8'); vitePatchDone = true; }
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// ── 4. Parchar tsconfig.app.json ──────────────────────────────────────────────
|
|
175
|
-
let tsconfigPatchDone = false;
|
|
176
|
-
const tsconfigPath = path.join(projectRoot, 'tsconfig.app.json');
|
|
177
|
-
if (fs.existsSync(tsconfigPath)) {
|
|
178
|
-
try {
|
|
179
|
-
const tsconfig = JSON.parse(fs.readFileSync(tsconfigPath, 'utf8'));
|
|
180
|
-
if (!tsconfig.compilerOptions?.skipLibCheck) {
|
|
181
|
-
if (!tsconfig.compilerOptions) tsconfig.compilerOptions = {};
|
|
182
|
-
tsconfig.compilerOptions.skipLibCheck = true;
|
|
183
|
-
fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\n', 'utf8');
|
|
184
|
-
tsconfigPatchDone = true;
|
|
185
|
-
}
|
|
186
|
-
} catch (e) { log.warn.push('No se pudo parchear tsconfig: ' + e.message); }
|
|
11
|
+
// Solo mostrar el mensaje si se instala como dependencia, no en desarrollo local
|
|
12
|
+
if (__dirname.includes('node_modules')) {
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const projectRoot = path.resolve(__dirname, '../../..');
|
|
15
|
+
const skillsBase = path.join(__dirname, '..', 'skills', 'install-dropi-ui');
|
|
16
|
+
|
|
17
|
+
// 1. Copiar Skills para IAs (Claude, Cursor, etc.)
|
|
18
|
+
const skillTargets = [
|
|
19
|
+
{ editor: 'Claude', src: 'skill.md', dest: path.join(projectRoot, '.claude', 'skills', 'install-dropi-ui', 'skill.md') },
|
|
20
|
+
{ editor: 'Cursor', src: 'cursor.mdc', dest: path.join(projectRoot, '.cursor', 'rules', 'install-dropi-ui.mdc') },
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
skillTargets.forEach(t => {
|
|
24
|
+
try {
|
|
25
|
+
if (fs.existsSync(t.dest)) return;
|
|
26
|
+
fs.mkdirSync(path.dirname(t.dest), { recursive: true });
|
|
27
|
+
fs.copyFileSync(path.join(skillsBase, t.src), t.dest);
|
|
28
|
+
} catch (e) { /* silent fail for skills */ }
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
console.log('\x1b[36m%s\x1b[0m', '\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
32
|
+
console.log('\x1b[1m%s\x1b[0m', ' 🎨 @dropi/ui instalado exitosamente');
|
|
33
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
34
|
+
console.log('\n Para configurar estilos, iconos y soporte React, ejecuta:');
|
|
35
|
+
console.log('\x1b[33m%s\x1b[0m', ' npx @dropi/ui setup');
|
|
36
|
+
console.log('\x1b[32m%s\x1b[0m', ' o simplemente pídele a tu IA: "/install-dropi-ui"');
|
|
37
|
+
console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
187
38
|
}
|
|
188
|
-
|
|
189
|
-
// ── 5. Copiar sprite SVG ──────────────────────────────────────────────────────
|
|
190
|
-
let spriteDone = false;
|
|
191
|
-
const spriteDest = path.join(projectRoot, isAngular ? 'src' : 'public', 'assets', 'icons', 'symbol', 'svg', 'sprite.css.svg');
|
|
192
|
-
try {
|
|
193
|
-
if (!fs.existsSync(spriteDest) && fs.existsSync(spriteSrc)) {
|
|
194
|
-
fs.mkdirSync(path.dirname(spriteDest), { recursive: true });
|
|
195
|
-
fs.copyFileSync(spriteSrc, spriteDest);
|
|
196
|
-
spriteDone = true;
|
|
197
|
-
}
|
|
198
|
-
} catch (e) { log.warn.push('No se pudo copiar sprite: ' + e.message); }
|
|
199
|
-
|
|
200
|
-
// ── 6. Auto-instalar @dropi/ui-react si es proyecto React ────────────────────
|
|
201
|
-
let reactInstalled = false;
|
|
202
|
-
if (isReact) {
|
|
203
|
-
try {
|
|
204
|
-
const pkg = JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8'));
|
|
205
|
-
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
206
|
-
if (!allDeps['@dropi/ui-react']) {
|
|
207
|
-
const { execSync } = require('child_process');
|
|
208
|
-
const pkgMgrCmd = fs.existsSync(path.join(projectRoot, 'yarn.lock')) ? 'yarn add'
|
|
209
|
-
: fs.existsSync(path.join(projectRoot, 'pnpm-lock.yaml')) ? 'pnpm add'
|
|
210
|
-
: 'npm install';
|
|
211
|
-
console.log(' Proyecto React detectado → instalando @dropi/ui-react...');
|
|
212
|
-
execSync(`${pkgMgrCmd} @dropi/ui-react`, { cwd: projectRoot, stdio: 'inherit' });
|
|
213
|
-
reactInstalled = true;
|
|
214
|
-
} else {
|
|
215
|
-
reactInstalled = 'ya';
|
|
216
|
-
}
|
|
217
|
-
} catch (e) { log.warn.push('No se pudo auto-instalar @dropi/ui-react: ' + e.message); }
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// ── 7. Output final ───────────────────────────────────────────────────────────
|
|
221
|
-
const hasClaudeCode = fs.existsSync(path.join(projectRoot, '.claude'));
|
|
222
|
-
const hasCursor = fs.existsSync(path.join(projectRoot, '.cursor')) || fs.existsSync(path.join(projectRoot, '.cursorrules'));
|
|
223
|
-
const hasWindsurf = fs.existsSync(path.join(projectRoot, '.windsurfrules'));
|
|
224
|
-
const hasCopilot = fs.existsSync(path.join(projectRoot, '.github', 'copilot-instructions.md'));
|
|
225
|
-
|
|
226
|
-
console.log('');
|
|
227
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
228
|
-
console.log(' ✅ @dropi/ui instalado');
|
|
229
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
230
|
-
console.log('');
|
|
231
|
-
console.log(' Configuración automática aplicada:');
|
|
232
|
-
if (vitePatchDone === true) console.log(' ✓ vite.config → optimizeDeps.exclude');
|
|
233
|
-
if (vitePatchDone === 'ya') console.log(' ✓ vite.config → ya estaba configurado');
|
|
234
|
-
if (tsconfigPatchDone) console.log(' ✓ tsconfig → skipLibCheck: true');
|
|
235
|
-
if (spriteDone) console.log(' ✓ Sprite SVG → ' + path.relative(projectRoot, spriteDest));
|
|
236
|
-
if (reactInstalled === true) console.log(' ✓ @dropi/ui-react → instalado automáticamente');
|
|
237
|
-
if (reactInstalled === 'ya') console.log(' ✓ @dropi/ui-react → ya estaba instalado');
|
|
238
|
-
if (log.ok.length > 0) log.ok.forEach(m => console.log(' ✓ ' + m));
|
|
239
|
-
if (skillsCopied.length > 0) console.log(' ✓ Skills IA → ' + skillsCopied.join(', '));
|
|
240
|
-
if (log.warn.length > 0) { console.log(''); log.warn.forEach(w => console.warn(' ⚠️ ' + w)); }
|
|
241
|
-
console.log('');
|
|
242
|
-
console.log(' ── Completa la configuración con tu IA ──');
|
|
243
|
-
console.log('');
|
|
244
|
-
|
|
245
|
-
if (hasClaudeCode) {
|
|
246
|
-
console.log(' Claude Code → /install-dropi-ui');
|
|
247
|
-
} else if (hasCursor) {
|
|
248
|
-
console.log(' Cursor → "configura dropi-ui en este proyecto"');
|
|
249
|
-
} else if (hasWindsurf) {
|
|
250
|
-
console.log(' Windsurf → "configura dropi-ui en este proyecto"');
|
|
251
|
-
} else if (hasCopilot) {
|
|
252
|
-
console.log(' Copilot → "configura dropi-ui en este proyecto"');
|
|
253
|
-
} else {
|
|
254
|
-
console.log(' Cualquier IA → "lee DROPI_UI_SETUP.md y ejecuta los pasos"');
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
console.log('');
|
|
258
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
259
|
-
console.log('');
|
package/scripts/setup.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* setup.js — @dropi/ui CLI
|
|
4
|
+
*
|
|
5
|
+
* Uso: npx @dropi/ui setup
|
|
6
|
+
*
|
|
7
|
+
* Este script configura automáticamente la librería en proyectos:
|
|
8
|
+
* - React (Vite)
|
|
9
|
+
* - Angular
|
|
10
|
+
* - Vue (Vite)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { execSync } = require('child_process');
|
|
16
|
+
|
|
17
|
+
// Determinar la raíz del proyecto consumidor
|
|
18
|
+
const projectRoot = process.cwd();
|
|
19
|
+
const isDependency = __dirname.includes('node_modules');
|
|
20
|
+
const libraryPkgPath = isDependency
|
|
21
|
+
? path.join(__dirname, '..', 'package.json')
|
|
22
|
+
: path.join(__dirname, '..', 'package.json');
|
|
23
|
+
|
|
24
|
+
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
25
|
+
const getPkg = () => {
|
|
26
|
+
try { return JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8')); }
|
|
27
|
+
catch { return {}; }
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const getPkgMgr = () => {
|
|
31
|
+
if (fs.existsSync(path.join(projectRoot, 'yarn.lock'))) return 'yarn';
|
|
32
|
+
if (fs.existsSync(path.join(projectRoot, 'pnpm-lock.yaml'))) return 'pnpm';
|
|
33
|
+
return 'npm';
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const log = (msg, type = 'info') => {
|
|
37
|
+
const colors = { info: '\x1b[36m', ok: '\x1b[32m', warn: '\x1b[33m', error: '\x1b[31m', reset: '\x1b[0m' };
|
|
38
|
+
const icons = { info: 'ℹ️', ok: '✅', warn: '⚠️', error: '❌' };
|
|
39
|
+
console.log(`${colors[type]}${icons[type]} ${msg}${colors.reset}`);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// ── Main ─────────────────────────────────────────────────────────────────────
|
|
43
|
+
async function run() {
|
|
44
|
+
console.log('\n\x1b[1m\x1b[35m%s\x1b[0m', ' 🚀 @dropi/ui — Configurator');
|
|
45
|
+
console.log(' ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
46
|
+
|
|
47
|
+
const pkg = getPkg();
|
|
48
|
+
if (!pkg.name) {
|
|
49
|
+
log('No se encontró package.json en la raíz. Ejecuta este comando desde la raíz de tu proyecto.', 'error');
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 1. Detección de Framework
|
|
54
|
+
const hasDep = (name) => !!(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
|
|
55
|
+
const isAngular = hasDep('@angular/core');
|
|
56
|
+
const isReact = hasDep('react');
|
|
57
|
+
const isVue = hasDep('vue');
|
|
58
|
+
const framework = isAngular ? 'Angular' : isReact ? 'React' : isVue ? 'Vue' : 'Desconocido';
|
|
59
|
+
|
|
60
|
+
log(`Entorno detectado: ${framework}`);
|
|
61
|
+
|
|
62
|
+
// 2. Instalación de Dependencias
|
|
63
|
+
const pkgMgr = getPkgMgr();
|
|
64
|
+
const installCmd = pkgMgr === 'yarn' ? 'yarn add' : pkgMgr === 'pnpm' ? 'pnpm add' : 'npm install';
|
|
65
|
+
|
|
66
|
+
if (isReact && !hasDep('@dropi/ui-react')) {
|
|
67
|
+
log(`Proyecto React detectado → Instalando @dropi/ui-react...`);
|
|
68
|
+
try {
|
|
69
|
+
execSync(`${installCmd} @dropi/ui-react`, { stdio: 'inherit', cwd: projectRoot });
|
|
70
|
+
log('@dropi/ui-react instalado.', 'ok');
|
|
71
|
+
} catch (e) {
|
|
72
|
+
log('Error instalando @dropi/ui-react. Intenta instalarlo manualmente.', 'warn');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 3. Estilos Globales
|
|
77
|
+
const cssImport = "import '@dropi/ui/dist/dropi-ui/dropi-ui.css';";
|
|
78
|
+
let styleTarget = null;
|
|
79
|
+
|
|
80
|
+
if (isAngular) {
|
|
81
|
+
const scssPath = path.join(projectRoot, 'src', 'styles.scss');
|
|
82
|
+
if (fs.existsSync(scssPath)) {
|
|
83
|
+
let content = fs.readFileSync(scssPath, 'utf8');
|
|
84
|
+
if (!content.includes('dropi-ui.css')) {
|
|
85
|
+
content = `@import '@dropi/ui/dist/dropi-ui/dropi-ui.css';\n` + content;
|
|
86
|
+
fs.writeFileSync(scssPath, content);
|
|
87
|
+
log('Estilos agregados a src/styles.scss', 'ok');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
// React o Vue (Vite)
|
|
92
|
+
const entryPoints = ['src/main.tsx', 'src/main.ts', 'src/index.tsx', 'src/index.js'];
|
|
93
|
+
styleTarget = entryPoints.find(f => fs.existsSync(path.join(projectRoot, f)));
|
|
94
|
+
|
|
95
|
+
if (styleTarget) {
|
|
96
|
+
let content = fs.readFileSync(path.join(projectRoot, styleTarget), 'utf8');
|
|
97
|
+
if (!content.includes('dropi-ui.css')) {
|
|
98
|
+
content = `${cssImport}\n` + content;
|
|
99
|
+
|
|
100
|
+
// 4. Loader (defineCustomElements) si no es React wrapper
|
|
101
|
+
if (!isReact || !content.includes('defineCustomElements')) {
|
|
102
|
+
if (!content.includes('defineCustomElements')) {
|
|
103
|
+
content = `import { defineCustomElements } from '@dropi/ui/loader';\n` + content;
|
|
104
|
+
if (content.includes('createRoot')) {
|
|
105
|
+
content = content.replace('createRoot', 'defineCustomElements();\ncreateRoot');
|
|
106
|
+
} else {
|
|
107
|
+
content += `\ndefineCustomElements();\n`;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
fs.writeFileSync(path.join(projectRoot, styleTarget), content);
|
|
113
|
+
log(`Configuración aplicada en ${styleTarget}`, 'ok');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 5. Iconos (Symlink)
|
|
119
|
+
const publicDir = isAngular ? 'src/assets' : 'public';
|
|
120
|
+
const iconDestDir = path.join(projectRoot, publicDir, 'assets', 'icons', 'symbol', 'svg');
|
|
121
|
+
const spriteName = 'sprite.css.svg';
|
|
122
|
+
const spriteDest = path.join(iconDestDir, spriteName);
|
|
123
|
+
|
|
124
|
+
// Encontrar origen del sprite dentro de node_modules
|
|
125
|
+
const spriteSrc = path.join(projectRoot, 'node_modules', '@dropi/ui', 'assets', 'icons', 'symbol', 'svg', spriteName);
|
|
126
|
+
|
|
127
|
+
if (fs.existsSync(spriteSrc)) {
|
|
128
|
+
if (!fs.existsSync(iconDestDir)) fs.mkdirSync(iconDestDir, { recursive: true });
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
if (fs.existsSync(spriteDest)) fs.unlinkSync(spriteDest);
|
|
132
|
+
// Usar symlink para mantenerlo actualizado
|
|
133
|
+
fs.symlinkSync(spriteSrc, spriteDest, 'file');
|
|
134
|
+
log(`Portal de iconos configurado en ${publicDir}/assets/... (Symlink ✅)`, 'ok');
|
|
135
|
+
} catch (e) {
|
|
136
|
+
// Fallback a copia si falla el symlink (ej. en Windows sin permisos)
|
|
137
|
+
fs.copyFileSync(spriteSrc, spriteDest);
|
|
138
|
+
log(`Sprite de iconos copiado a ${publicDir}/assets/... (Copia ✅)`, 'ok');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// 6. Vite Patch (optimizeDeps)
|
|
143
|
+
const viteFiles = ['vite.config.ts', 'vite.config.js'];
|
|
144
|
+
const viteFile = viteFiles.find(f => fs.existsSync(path.join(projectRoot, f)));
|
|
145
|
+
if (viteFile) {
|
|
146
|
+
let content = fs.readFileSync(path.join(projectRoot, viteFile), 'utf8');
|
|
147
|
+
if (!content.includes('optimizeDeps')) {
|
|
148
|
+
const patch = `\n optimizeDeps: {\n exclude: ['@dropi/ui/loader', '@dropi/ui'],\n },`;
|
|
149
|
+
content = content.replace(/defineConfig\(\{/, `defineConfig({${patch}`);
|
|
150
|
+
fs.writeFileSync(path.join(projectRoot, viteFile), content);
|
|
151
|
+
log('Vite: optimizeDeps.exclude configurado.', 'ok');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
console.log('\n\x1b[32m%s\x1b[0m', ' ✨ ¡Configuración completada!');
|
|
156
|
+
console.log(' Vuelve a iniciar tu servidor de desarrollo para ver lo cambios.\n');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
run().catch(err => {
|
|
160
|
+
console.error('\n❌ Error en el setup:', err);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
});
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Instala y configura automáticamente @dropi/ui en Angular, React o Vue
|
|
3
|
-
globs: ["package.json"]
|
|
4
|
-
alwaysApply: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
1
|
# @dropi/ui — Configuración pendiente
|
|
8
2
|
|
|
9
3
|
Este proyecto tiene `@dropi/ui` instalado pero necesita configuración.
|
|
10
|
-
|
|
4
|
+
Ejecuta el script de instalación oficial: `node node_modules/@dropi/ui/scripts/setup.js`.
|
|
5
|
+
Una vez completado, verifica los estilos y el sprite de iconos en la carpeta public.
|
|
@@ -24,190 +24,42 @@ import { DropiButton } from '@dropi/ui/dist/components'
|
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
## Instrucciones
|
|
27
|
+
## Instrucciones de Instalación
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Para configurar la librería, el asistente de IA debe ejecutar el script de automatización oficial incluido en el paquete. Esto garantiza que la detección de framework y la configuración de iconos/estilos se realicen correctamente según los estándares de Dropi.
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
- **Framework**: Angular (`@angular/core`), React (`react`), Vue (`vue`)
|
|
33
|
-
- **Package manager**: `yarn.lock` → yarn | `pnpm-lock.yaml` → pnpm | `package-lock.json` → npm
|
|
34
|
-
- **Bundler**: existe `vite.config.ts` o `vite.config.js` → es Vite (aplica pasos especiales)
|
|
31
|
+
### 1. Ejecutar el script de Setup
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
Ejecuta el siguiente comando en la terminal del proyecto:
|
|
37
34
|
|
|
38
|
-
**Angular / Vue:**
|
|
39
35
|
```bash
|
|
40
|
-
|
|
41
|
-
# o
|
|
42
|
-
npm install @dropi/ui
|
|
36
|
+
node node_modules/@dropi/ui/scripts/setup.js
|
|
43
37
|
```
|
|
44
38
|
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
yarn add @dropi/ui @dropi/ui-react
|
|
48
|
-
# o
|
|
49
|
-
npm install @dropi/ui @dropi/ui-react
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Paso 3 — Fix obligatorio para Vite (React y Vue) ⚠️
|
|
53
|
-
|
|
54
|
-
**Sin esto los componentes NO cargan.** Abre `vite.config.ts` y agrega `optimizeDeps`:
|
|
55
|
-
|
|
56
|
-
```ts
|
|
57
|
-
import { defineConfig } from 'vite'
|
|
58
|
-
import react from '@vitejs/plugin-react' // o vue si aplica
|
|
59
|
-
|
|
60
|
-
export default defineConfig({
|
|
61
|
-
plugins: [react()],
|
|
62
|
-
optimizeDeps: {
|
|
63
|
-
exclude: ['@dropi/ui/loader', '@dropi/ui'],
|
|
64
|
-
},
|
|
65
|
-
})
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Esto resuelve estos errores:
|
|
69
|
-
- `Failed to fetch dynamically imported module: .../dropi-button.entry.js`
|
|
70
|
-
- `Constructor for "dropi-button#undefined" was not found`
|
|
71
|
-
- `Missing field moduleType` (Vite 6+/8+)
|
|
72
|
-
|
|
73
|
-
### Paso 4 — Inyectar estilos globales
|
|
74
|
-
|
|
75
|
-
**Angular** — al inicio de `src/styles.scss`:
|
|
76
|
-
```scss
|
|
77
|
-
@import '@dropi/ui/dist/dropi-ui/dropi-ui.css';
|
|
78
|
-
```
|
|
79
|
-
Verificar también `angular.json` bajo `styles[]`.
|
|
80
|
-
|
|
81
|
-
**React / Vue** — al inicio de `src/main.tsx` o `src/main.ts`:
|
|
82
|
-
```ts
|
|
83
|
-
import '@dropi/ui/dist/dropi-ui/dropi-ui.css'
|
|
84
|
-
```
|
|
39
|
+
### 2. Verificación
|
|
85
40
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
import { defineCustomElements } from '@dropi/ui/loader'
|
|
91
|
-
defineCustomElements()
|
|
92
|
-
```
|
|
93
|
-
Agregar `CUSTOM_ELEMENTS_SCHEMA` al módulo standalone:
|
|
94
|
-
```ts
|
|
95
|
-
// app.config.ts
|
|
96
|
-
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'
|
|
97
|
-
export const appConfig: ApplicationConfig = {
|
|
98
|
-
providers: [
|
|
99
|
-
importProvidersFrom({ schemas: [CUSTOM_ELEMENTS_SCHEMA] })
|
|
100
|
-
]
|
|
101
|
-
}
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
**Vue** — en `src/main.ts`:
|
|
105
|
-
```ts
|
|
106
|
-
import { defineCustomElements } from '@dropi/ui/loader'
|
|
107
|
-
defineCustomElements()
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**React** — en `src/main.tsx`:
|
|
111
|
-
```tsx
|
|
112
|
-
import { defineCustomElements } from '@dropi/ui/loader'
|
|
113
|
-
import '@dropi/ui/dist/dropi-ui/dropi-ui.css'
|
|
114
|
-
import './index.css'
|
|
41
|
+
Una vez finalizado el script, verifica que:
|
|
42
|
+
- Los iconos carguen correctamente (sin errores 404 en el sprite).
|
|
43
|
+
- Los estilos globales estén inyectados en el punto de entrada principal (`main.tsx`, `main.ts`, etc.).
|
|
44
|
+
- Si es React, el paquete `@dropi/ui-react` esté instalado.
|
|
115
45
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
createRoot(document.getElementById('root')!).render(
|
|
119
|
-
<StrictMode>
|
|
120
|
-
<App />
|
|
121
|
-
</StrictMode>,
|
|
122
|
-
)
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
En los componentes React, importar desde `@dropi/ui-react` (NO del core):
|
|
126
|
-
```tsx
|
|
127
|
-
import { DropiButton, DropiSelect, DropiBadge } from '@dropi/ui-react'
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### Paso 6 — Verificar tsconfig.app.json (React + TypeScript)
|
|
131
|
-
|
|
132
|
-
Asegurarse de que `tsconfig.app.json` tenga `skipLibCheck: true` para evitar errores de tipado de las librerías:
|
|
133
|
-
|
|
134
|
-
```json
|
|
135
|
-
{
|
|
136
|
-
"compilerOptions": {
|
|
137
|
-
"skipLibCheck": true,
|
|
138
|
-
"target": "ES2023",
|
|
139
|
-
"lib": ["ES2023", "DOM", "DOM.Iterable"],
|
|
140
|
-
"module": "ESNext",
|
|
141
|
-
"moduleResolution": "bundler",
|
|
142
|
-
"jsx": "react-jsx",
|
|
143
|
-
"strict": true,
|
|
144
|
-
"noEmit": true
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
Si `skipLibCheck` no está → agregar. Sin esto pueden aparecer errores de tipos en `node_modules`.
|
|
150
|
-
|
|
151
|
-
### Paso 7 — Copiar sprite de íconos
|
|
152
|
-
|
|
153
|
-
**Linux / Mac:**
|
|
154
|
-
```bash
|
|
155
|
-
# Angular
|
|
156
|
-
mkdir -p src/assets/icons/symbol/svg
|
|
157
|
-
cp node_modules/@dropi/ui/assets/icons/symbol/svg/sprite.css.svg src/assets/icons/symbol/svg/
|
|
158
|
-
|
|
159
|
-
# React / Vue (Vite)
|
|
160
|
-
mkdir -p public/assets/icons/symbol/svg
|
|
161
|
-
cp node_modules/@dropi/ui/assets/icons/symbol/svg/sprite.css.svg public/assets/icons/symbol/svg/
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
**Windows (usar Node para compatibilidad):**
|
|
165
|
-
```bash
|
|
166
|
-
# React / Vue (Vite)
|
|
167
|
-
node -e "const fs=require('fs');fs.mkdirSync('public/assets/icons/symbol/svg',{recursive:true});fs.copyFileSync('node_modules/@dropi/ui/assets/icons/symbol/svg/sprite.css.svg','public/assets/icons/symbol/svg/sprite.css.svg');console.log('Sprite copiado ✅')"
|
|
168
|
-
|
|
169
|
-
# Angular
|
|
170
|
-
node -e "const fs=require('fs');fs.mkdirSync('src/assets/icons/symbol/svg',{recursive:true});fs.copyFileSync('node_modules/@dropi/ui/assets/icons/symbol/svg/sprite.css.svg','src/assets/icons/symbol/svg/sprite.css.svg');console.log('Sprite copiado ✅')"
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Paso 8 — Validar instalación
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
yarn build # o npm run build / pnpm build
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
Errores comunes y solución:
|
|
180
|
-
| Error | Causa | Fix |
|
|
181
|
-
|---|---|---|
|
|
182
|
-
| `Failed to fetch dynamically imported module` | Falta `optimizeDeps.exclude` en vite.config | Paso 3 |
|
|
183
|
-
| `Constructor for "dropi-button#undefined" was not found` | Mismo | Paso 3 |
|
|
184
|
-
| `Missing field moduleType` | Vite 6+/8+ sin optimizeDeps | Paso 3 |
|
|
185
|
-
| Errores de tipos en node_modules | Falta `skipLibCheck: true` | Paso 6 |
|
|
186
|
-
| Íconos no aparecen | Sprite no copiado | Paso 7 |
|
|
187
|
-
|
|
188
|
-
### Paso 9 — Reporte final
|
|
189
|
-
|
|
190
|
-
```
|
|
191
|
-
✅ @dropi/ui instalado exitosamente en [FRAMEWORK]
|
|
192
|
-
|
|
193
|
-
- Dependencia: @dropi/ui@X.X.X [+ @dropi/ui-react]
|
|
194
|
-
- vite.config: optimizeDeps.exclude ✓
|
|
195
|
-
- Estilos: [archivo] ✓
|
|
196
|
-
- Loader (lazy): defineCustomElements() en [archivo] ✓
|
|
197
|
-
- Sprite: [ruta destino] ✓
|
|
198
|
-
- skipLibCheck: true ✓
|
|
46
|
+
---
|
|
199
47
|
|
|
200
|
-
|
|
201
|
-
import { DropiButton } from '@dropi/ui-react'
|
|
202
|
-
<DropiButton text="Hola Dropi" type="default" severity="primary" size="normal" />
|
|
48
|
+
## Fallback Manual (Solo si el script falla)
|
|
203
49
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
```
|
|
50
|
+
> [!WARNING]
|
|
51
|
+
> Usa estos pasos solo si el comando anterior no puede ejecutarse por restricciones del entorno.
|
|
207
52
|
|
|
208
|
-
|
|
53
|
+
1. **Instalar dependencias**: `npm install @dropi/ui` (y `@dropi/ui-react` si es React).
|
|
54
|
+
2. **Vite Fix**: Agregar `optimizeDeps.exclude: ['@dropi/ui/loader', '@dropi/ui']` en `vite.config`.
|
|
55
|
+
3. **Estilos**: Importar `@dropi/ui/dist/dropi-ui/dropi-ui.css` en el entry point.
|
|
56
|
+
4. **Loader**: Llamar a `defineCustomElements()` de `@dropi/ui/loader` antes del renderizado.
|
|
57
|
+
5. **Iconos**: Crear un enlace simbólico del sprite:
|
|
58
|
+
`ln -sf $(pwd)/node_modules/@dropi/ui/assets/icons/symbol/svg/sprite.css.svg public/assets/icons/symbol/svg/sprite.css.svg`
|
|
59
|
+
6. **TS Config**: Asegurar `skipLibCheck: true`.
|
|
60
|
+
7. **Validar**: Ejecutar `npm run build`.
|
|
209
61
|
|
|
210
|
-
|
|
211
|
-
-
|
|
212
|
-
-
|
|
62
|
+
## Reglas Críticas
|
|
63
|
+
- **Lazy Loading**: NUNCA importar componentes directamente. Usar siempre el loader.
|
|
64
|
+
- **Iconos**: El sprite DEBE estar en `public/assets/icons/symbol/svg/sprite.css.svg` para que `<dropi-icon>` funcione.
|
|
213
65
|
- Si el build falla, mostrar el error exacto y resolverlo antes de reportar éxito
|