@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.
- package/assets/icons/symbol/svg/sprite.css.svg +1 -0
- package/dist/cjs/dropi-input.cjs.entry.js +1 -1
- package/dist/collection/components/dropi-input/dropi-input.css +12 -8
- package/dist/components/dropi-input.js +1 -1
- package/dist/dropi-ui/dropi-ui.esm.js +1 -1
- package/dist/dropi-ui/p-a46a05a6.entry.js +1 -0
- package/dist/esm/dropi-input.entry.js +1 -1
- package/package.json +7 -3
- package/readme.md +79 -61
- package/scripts/postinstall.js +237 -0
- package/skills/install-dropi-ui/cursor.mdc +10 -0
- package/skills/install-dropi-ui/skill.md +209 -0
- package/dist/dropi-ui/p-1a28b8f5.entry.js +0 -1
|
@@ -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}
|