@dropi/ui 0.1.0 → 0.1.3

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.
@@ -0,0 +1,209 @@
1
+ ---
2
+ name: install-dropi-ui
3
+ description: Instala y configura automáticamente @dropi/ui en Angular, React o Vue sin intervención manual
4
+ allowed-tools: Bash, Read, Write, Edit, Glob
5
+ ---
6
+
7
+ # Skill: /install-dropi-ui
8
+
9
+ Automatiza la instalación y configuración completa de `@dropi/ui` en el proyecto actual.
10
+
11
+ ## REGLA CRÍTICA — Lazy Loading obligatorio
12
+
13
+ Los componentes SIEMPRE deben cargarse por lazy loading vía el loader:
14
+ ```ts
15
+ import { defineCustomElements } from '@dropi/ui/loader'
16
+ defineCustomElements()
17
+ ```
18
+ **PROHIBIDO** importar componentes directamente:
19
+ ```ts
20
+ // ❌ NUNCA hacer esto
21
+ import '@dropi/ui/dist/components/dropi-button.js'
22
+ import { DropiButton } from '@dropi/ui/dist/components'
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Instrucciones
28
+
29
+ ### Paso 1 — Detectar framework, bundler y gestor de paquetes
30
+
31
+ Lee `package.json` y determina:
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)
35
+
36
+ ### Paso 2 — Instalar dependencias
37
+
38
+ **Angular / Vue:**
39
+ ```bash
40
+ yarn add @dropi/ui
41
+ # o
42
+ npm install @dropi/ui
43
+ ```
44
+
45
+ **React:**
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
+ ```
85
+
86
+ ### Paso 5 — Registrar con lazy loader (OBLIGATORIO, no usar import directo)
87
+
88
+ **Angular** — en `src/main.ts` o `app.config.ts`:
89
+ ```ts
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'
115
+
116
+ defineCustomElements() // ← antes del createRoot
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 ✓
199
+
200
+ Prueba rápida:
201
+ <dropi-button text="Hola Dropi" type="default" severity="primary" size="normal"></dropi-button>
202
+ ```
203
+
204
+ ## Reglas
205
+
206
+ - Lazy loading SIEMPRE via `defineCustomElements` del loader — NUNCA imports directos de componentes
207
+ - NO sobreescribir imports que ya existan
208
+ - En Windows usar el comando `node -e` para operaciones de archivos
209
+ - Si el build falla, mostrar el error exacto y resolverlo antes de reportar éxito
@@ -1 +0,0 @@
1
- import{r as t,c as r,h as e}from"./p-DFz-gwFP.js";const o=class{constructor(e){t(this,e),this.dropiInput=r(this,"dropiInput"),this.dropiChange=r(this,"dropiChange"),this.dropiFocus=r(this,"dropiFocus"),this.dropiBlur=r(this,"dropiBlur"),e.$hostElement$["s-ei"]?this.internals=e.$hostElement$["s-ei"]:(this.internals=e.$hostElement$.attachInternals(),e.$hostElement$["s-ei"]=this.internals)}internals;inputId="";name="";label="";placeholder=" ";value="";maxlength;disabled=!1;required=!1;showAsterisk=!0;fixedLabel=!1;inputMode="text";passwordInput=!1;moneyFormat=!1;thousandSeparator=!1;onlyNumbers=!1;allowDecimals=!1;onlyLetters=!1;icon="";iconColor="Gray-Gray-400";invalid=!1;helperText="";showHelperOnlyOnError=!1;showPassword=!1;touched=!1;dropiInput;dropiChange;dropiFocus;dropiBlur;valueChanged(t){this.internals.setFormValue(t)}disabledChanged(t){this.internals.setValidity(t?{customError:!0}:{},t?"Field is disabled":"")}componentWillLoad(){this.internals.setFormValue(this.value??"")}handleInput(t){let r=t.target.value;this.onlyNumbers&&(r=this.filterNumbers(r)),this.onlyLetters&&(r=this.filterLetters(r)),(this.moneyFormat||this.thousandSeparator)&&(r=this.formatThousands(r,this.moneyFormat)),this.value=r,this.internals.setFormValue(r),this.dropiInput.emit(r)}handleKeyDown(t){this.onlyNumbers&&!this.isAllowedNumberKey(t)&&t.preventDefault(),this.onlyLetters&&!this.isAllowedLetterKey(t)&&t.preventDefault()}handleFocus(){this.dropiFocus.emit()}handleBlur(){this.touched=!0,this.dropiChange.emit(this.value),this.dropiBlur.emit()}togglePassword(){this.disabled||(this.showPassword=!this.showPassword)}filterNumbers(t){return t.replace(this.allowDecimals?/[^0-9.]/g:/[^0-9]/g,"")}filterLetters(t){return t.replace(/[^a-zA-ZáéíóúÁÉÍÓÚñÑüÜ\s]/g,"")}isAllowedNumberKey(t){return!!(["Backspace","Delete","ArrowLeft","ArrowRight","Tab","Enter","Home","End"].includes(t.key)||t.ctrlKey||t.metaKey||/^[0-9]$/.test(t.key)||this.allowDecimals&&"."===t.key)}isAllowedLetterKey(t){return!!["Backspace","Delete","ArrowLeft","ArrowRight","Tab","Enter","Home","End"," "].includes(t.key)||!(!t.ctrlKey&&!t.metaKey)||/^[a-zA-ZáéíóúÁÉÍÓÚñÑüÜ]$/.test(t.key)}formatThousands(t,r){const e=t.replace(/[^0-9.]/g,""),[o,i]=e.split("."),a=o.replace(/\B(?=(\d{3})+(?!\d))/g,","),s=void 0!==i?`${a}.${i}`:a;return r?`$${s}`:s}get resolvedId(){return this.inputId||this.label}get inputType(){return this.passwordInput?this.showPassword?"text":"password":"text"}get showHelper(){return!!this.helperText&&(!this.showHelperOnlyOnError||this.invalid&&this.touched)}get isInvalid(){return this.invalid&&this.touched}render(){const t=this.required&&this.showAsterisk&&!this.disabled,r=!!this.icon&&!!this.value;return e("div",{key:"4ea9c2118e6452345a2a92eedc807e6d94019784",class:{"fixed-label-container":this.fixedLabel}},this.fixedLabel&&e("div",{key:"b8c1269e9d583becd9614f6f3c28f6a2b536f18f",class:"input-label Body-S-Regular"},this.label,t&&e("span",{key:"945665772caab1a1c95f1a054dea1b8dd88287a3",class:"asterisk"}," *")),e("div",{key:"f550584dde83c907429255d9a98b8a59ff322cbb",class:"form-group"},e("div",{key:"6cc46f5822e62d59bb211e7d9eb7909ab2b833c9",class:"input-container"},r&&e("dropi-icon",{key:"c860e808ae7cd805aa9c430d52743f7eab0aaeba",class:"icon-input",name:this.icon,color:this.iconColor,width:"20px",height:"20px"}),this.passwordInput&&e("dropi-icon",{key:"ba571d4d14ec2a911a8b0bd4cdc7a8481aebe746",class:"icon-input-password",name:this.showPassword?"Eye":"Eye-crossed",width:"20px",height:"20px",color:"Gray-Gray-500",onClick:()=>this.togglePassword()}),e("input",{key:"aad18a94d94c9600236bac7c23e38b1c1c41f06a",id:this.resolvedId,class:{"form-control":!0,"form-control-valid":!this.isInvalid&&this.touched&&!!this.value,"form-control-invalid":this.isInvalid,"padding-icon":r,"text-password":this.passwordInput&&!this.showPassword,"fixed-label-input":this.fixedLabel},type:this.inputType,value:this.value,placeholder:this.fixedLabel?this.placeholder:" ",disabled:this.disabled,required:this.required,maxLength:this.maxlength,inputMode:this.inputMode,"data-cy":void 0,onInput:t=>this.handleInput(t),onKeyDown:t=>this.handleKeyDown(t),onFocus:()=>this.handleFocus(),onBlur:()=>this.handleBlur()}),!this.fixedLabel&&e("label",{key:"8ba7ea50525aa8990662d45829ba732094c41f80",class:"Body-S-Regular label-bottom",htmlFor:this.resolvedId},this.label,t&&e("span",{key:"3916d3de6392da62b8086920cd2fce3b96238416",class:"asterisk"}," *")),this.showHelper&&e("div",{key:"83e17f7d0cdb503b86fd035775e1cb45d9f41709",class:"form-control-helper"},this.isInvalid&&e("dropi-icon",{key:"4e034348270853f8a3aafbbbb938a5974076aebd",name:"Warning-circle",width:"12px",height:"12px",color:"Error-Error-500"}),e("span",{key:"7832f200ccc6f6273d65012b9e642c313399a277",class:{"disabled-helper":this.disabled,"invalid-color":this.isInvalid}},this.helperText)))))}static get formAssociated(){return!0}static get watchers(){return{value:[{valueChanged:0}],disabled:[{disabledChanged:0}]}}};o.style=":host{display:block;width:100%;text-align:left}*,*::before,*::after{box-sizing:border-box}.fixed-label-container{display:flex;width:100%;flex-direction:column;align-items:flex-start;gap:8px;text-align:left}.input-label{color:var(--Gray-Gray-600, #475066);font-size:var(--font-size-xs, 10px);font-weight:var(--font-weight-regular, 400)}.asterisk{color:var(--Error-Error-500, #f46a6b)}.form-group{position:relative;width:100%;text-align:left}.input-container{position:relative}.icon-input{position:absolute;top:10px;left:5px;z-index:1}.icon-input-password{position:absolute;top:10px;right:13px;cursor:pointer;z-index:1}.form-control{box-sizing:border-box;width:100%;padding:var(--Size-2, 8px);border:1px solid var(--Gray-Gray-200, #c3c9d9);border-radius:var(--Border-2, 8px);background:var(--Neutral-White, #fff);font-size:var(--font-size-s, 12px);font-family:inherit;color:var(--Gray-Gray-700, #32394d);transition:border-color 0.3s ease-in-out;height:40px;outline:none;appearance:none;text-align:left}.form-control::placeholder{color:transparent;transition:color 0.2s ease-in-out}.form-control:focus::placeholder,.fixed-label-input::placeholder{color:var(--Gray-Gray-400, #858ea6)}.form-control:focus{border-color:var(--Info-Info-500, #50a5f1)}.form-control-valid{border-color:var(--Gray-Gray-400, #858ea6) !important;color:var(--Gray-Gray-600, #475066)}.form-control-invalid{border-color:var(--Error-Error-500, #f46a6b) !important;color:var(--Gray-Gray-600, #475066)}.form-control:disabled{border-color:var(--Gray-Gray-200, #c3c9d9) !important;color:var(--Gray-Gray-400, #858ea6);background-color:var(--Gray-Gray-50, #f7f8fa);cursor:not-allowed}.padding-icon{padding-left:28px}.text-password{-webkit-text-security:disc;text-security:disc}label.label-bottom{position:absolute;font-weight:var(--font-weight-regular, 400);top:10px;font-size:var(--font-size-s, 12px);color:var(--Gray-Gray-500, #69738c);left:10px;transition:all 0.2s ease-in-out;pointer-events:none;overflow:hidden;width:90%;white-space:nowrap}.form-control:focus+label.label-bottom,.form-control:not(:placeholder-shown)+label.label-bottom{top:-22px;left:0;font-size:var(--font-size-xs, 10px);color:var(--Gray-Gray-600, #475066);width:unset}.form-control:disabled+label.label-bottom{color:var(--Gray-Gray-400, #858ea6)}.form-control-helper{display:flex;position:absolute;top:100%;left:0;gap:4px;align-items:center;margin-top:4px}.form-control-helper span{display:block;color:var(--Gray-Gray-600, #475066);font-size:var(--font-size-xs, 10px)}.invalid-color{color:var(--Error-Error-500, #f46a6b) !important}.disabled-helper{color:var(--Gray-Gray-400, #858ea6) !important}";export{o as dropi_input}