@dropi/ui 0.1.3 → 0.1.5
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/dist/cjs/dropi-radio-button.cjs.entry.js +1 -1
- package/dist/collection/components/dropi-radio-button/dropi-radio-button.css +6 -3
- package/dist/components/dropi-radio-button.js +1 -1
- package/dist/dropi-ui/dropi-ui.esm.js +1 -1
- package/dist/dropi-ui/p-bda1427f.entry.js +1 -0
- package/dist/esm/dropi-radio-button.entry.js +1 -1
- package/dist/types/index.d.ts +1 -0
- package/package.json +2 -2
- package/readme.md +466 -59
- package/scripts/postinstall.js +1 -1
- package/skills/install-dropi-ui/skill.md +5 -1
- package/dist/dropi-ui/p-54502c46.entry.js +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var index = require('./index-CuGLZVqo.js');
|
|
4
4
|
|
|
5
|
-
const dropiRadioButtonCss = () => `:host{display:inline-block}*,*::before,*::after{box-sizing:border-box}.dropi-radio-button{display:flex;align-items:center;justify-content:flex-start;gap:20px}label{display:flex;align-items:center;gap:8px;cursor:pointer;color:var(--Gray-Gray-700, #32394d);font-size:var(--font-size-s, 12px);font-weight:var(--font-weight-regular, 400);line-height:1.5}input[type='radio']{appearance:none;width:20px;height:20px;border:2px solid var(--Gray-Gray-200, #c3c9d9);border-radius:50%;background-color:transparent;position:relative;cursor:pointer;outline:none;flex-shrink:0;
|
|
5
|
+
const dropiRadioButtonCss = () => `:host{display:inline-block}*,*::before,*::after{box-sizing:border-box}.dropi-radio-button{display:flex;align-items:center;justify-content:flex-start;gap:20px}label{display:flex;flex-direction:row;align-items:center;gap:8px;cursor:pointer;color:var(--Gray-Gray-700, #32394d);font-size:var(--font-size-s, 12px);font-weight:var(--font-weight-regular, 400);line-height:1.5}input[type='radio']{appearance:none;-webkit-appearance:none;width:20px;height:20px;min-width:20px;border:2px solid var(--Gray-Gray-200, #c3c9d9);border-radius:50%;background-color:transparent;position:relative;cursor:pointer;outline:none;flex-shrink:0;align-self:center;vertical-align:middle;margin:0}input[type='radio']::before{content:'';position:absolute;top:3px;left:3px;width:10px;height:10px;background-color:var(--Primary-Primary-400, #f7b46f);border-radius:50%;display:none}input[type='radio']:checked{border:2px solid var(--Primary-Primary-500, #f49a3d)}input[type='radio']:checked::before{display:block}`;
|
|
6
6
|
|
|
7
7
|
const DropiRadioButton = class {
|
|
8
8
|
constructor(hostRef) {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
label {
|
|
15
15
|
display: flex;
|
|
16
|
+
flex-direction: row;
|
|
16
17
|
align-items: center;
|
|
17
18
|
gap: 8px;
|
|
18
19
|
cursor: pointer;
|
|
@@ -24,8 +25,10 @@ label {
|
|
|
24
25
|
|
|
25
26
|
input[type='radio'] {
|
|
26
27
|
appearance: none;
|
|
28
|
+
-webkit-appearance: none;
|
|
27
29
|
width: 20px;
|
|
28
30
|
height: 20px;
|
|
31
|
+
min-width: 20px;
|
|
29
32
|
border: 2px solid var(--Gray-Gray-200, #c3c9d9);
|
|
30
33
|
border-radius: 50%;
|
|
31
34
|
background-color: transparent;
|
|
@@ -33,9 +36,9 @@ input[type='radio'] {
|
|
|
33
36
|
cursor: pointer;
|
|
34
37
|
outline: none;
|
|
35
38
|
flex-shrink: 0;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
align-self: center;
|
|
40
|
+
vertical-align: middle;
|
|
41
|
+
margin: 0;
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
input[type='radio']::before {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e,p as
|
|
1
|
+
import{t as e,p as r,H as t,c as i,h as o}from"./index.js";const n=r(class extends t{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.dropiChange=i(this,"dropiChange")}label="";name="radio";inputId="radioButton";checked=!1;resetTrigger=!1;dropiChange;onResetTrigger(e){e&&(this.checked=!1)}handleChange(e){this.checked=e.target.checked,this.dropiChange.emit(e)}render(){return o("div",{key:"3b31699bf088bee52465981074c0aea48b6fe112",class:"dropi-radio-button"},o("label",{key:"072d19bd9c88739b849db0e264c65183eaab2132",htmlFor:this.inputId},o("input",{key:"82d1600002e9dc2795cdc5c731997742adc8e2db",id:this.inputId,type:"radio",name:this.name,checked:this.checked,onChange:e=>this.handleChange(e)}),this.label))}static get formAssociated(){return!0}static get watchers(){return{resetTrigger:[{onResetTrigger:0}]}}static get style(){return":host{display:inline-block}*,*::before,*::after{box-sizing:border-box}.dropi-radio-button{display:flex;align-items:center;justify-content:flex-start;gap:20px}label{display:flex;flex-direction:row;align-items:center;gap:8px;cursor:pointer;color:var(--Gray-Gray-700, #32394d);font-size:var(--font-size-s, 12px);font-weight:var(--font-weight-regular, 400);line-height:1.5}input[type='radio']{appearance:none;-webkit-appearance:none;width:20px;height:20px;min-width:20px;border:2px solid var(--Gray-Gray-200, #c3c9d9);border-radius:50%;background-color:transparent;position:relative;cursor:pointer;outline:none;flex-shrink:0;align-self:center;vertical-align:middle;margin:0}input[type='radio']::before{content:'';position:absolute;top:3px;left:3px;width:10px;height:10px;background-color:var(--Primary-Primary-400, #f7b46f);border-radius:50%;display:none}input[type='radio']:checked{border:2px solid var(--Primary-Primary-500, #f49a3d)}input[type='radio']:checked::before{display:block}"}},[577,"dropi-radio-button",{label:[1],name:[1],inputId:[1,"input-id"],checked:[1540],resetTrigger:[4,"reset-trigger"]},void 0,{resetTrigger:[{onResetTrigger:0}]}]);function a(){"undefined"!=typeof customElements&&["dropi-radio-button"].forEach((r=>{"dropi-radio-button"===r&&(customElements.get(e(r))||customElements.define(e(r),n))}))}a();const s=n,d=a;export{s as DropiRadioButton,d as defineCustomElement}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{p as e,g as o,b as t}from"./p-DFz-gwFP.js";export{s as setNonce}from"./p-DFz-gwFP.js";(()=>{const o=import.meta.url,t={};return""!==o&&(t.resourcesUrl=new URL(".",o).href),e(t)})().then((async e=>(await o(),t([["p-6f0aa619",[[513,"dropi-icon",{name:[1],width:[1],height:[1],color:[1]},null,{color:[{colorChanged:0}]}]]],["p-21abf91a",[[769,"dropi-button",{type:[1],severity:[1],size:[1],state:[1],preIcon:[1,"pre-icon"],postIcon:[1,"post-icon"],text:[1]}]]],["p-a46a05a6",[[577,"dropi-input",{inputId:[1,"input-id"],name:[1],label:[1],placeholder:[1],value:[1025],maxlength:[2],disabled:[516],required:[516],showAsterisk:[4,"show-asterisk"],fixedLabel:[4,"fixed-label"],inputMode:[1,"input-mode"],passwordInput:[4,"password-input"],moneyFormat:[4,"money-format"],thousandSeparator:[4,"thousand-separator"],onlyNumbers:[4,"only-numbers"],allowDecimals:[4,"allow-decimals"],onlyLetters:[4,"only-letters"],icon:[1],iconColor:[1,"icon-color"],invalid:[4],helperText:[1,"helper-text"],showHelperOnlyOnError:[4,"show-helper-only-on-error"],showPassword:[32],touched:[32]},null,{value:[{valueChanged:0}],disabled:[{disabledChanged:0}]}]]],["p-c7b9cbda",[[577,"dropi-select",{label:[1],placeholder:[1],options:[1040],name:[1],disabled:[516],invalid:[4],errorText:[1,"error-text"],helperText:[1,"helper-text"],showObligatory:[4,"show-obligatory"],searchEnabled:[4,"search-enabled"],multiSelect:[4,"multi-select"],dropdownType:[4,"dropdown-type"],showCountryFlags:[4,"show-country-flags"],radioOptions:[4,"radio-options"],placeHolderSearch:[1,"place-holder-search"],preIcon:[1,"pre-icon"],defaultSelectedId:[1032,"default-selected-id"],value:[1040],isOpen:[32],selectedOption:[32],multiSelected:[32],filteredOptions:[32],searchTerm:[32],dropdownStyle:[32],setById:[64],setByLabel:[64],clearSelection:[64],resetMultiSelect:[64]},[[4,"click","handleOutsideClick"]],{options:[{optionsChanged:0}],defaultSelectedId:[{defaultChanged:0}],value:[{valueChanged:0}]}]]],["p-52291024",[[513,"dropi-tag",{type:[1],state:[1],showIcon:[4,"show-icon"],icon:[1],text:[1]},null,{type:[{propsChanged:0}],state:[{propsChanged:0}]}]]],["p-9c7076d3",[[577,"dropi-text-area",{inputId:[1,"input-id"],name:[1],label:[1],placeholder:[1],value:[1025],maxlength:[2],minlength:[2],rows:[2],resize:[1],disabled:[516],required:[516],showAsterisk:[4,"show-asterisk"],helperText:[1,"helper-text"],invalid:[4],touched:[32]},null,{value:[{valueChanged:0}]}]]],["p-f785011f",[[513,"dropi-badge",{state:[1]}]]],["p-dd089a60",[[577,"dropi-checkbox",{checked:[1540],disabled:[516]}]]],["p-
|
|
1
|
+
import{p as e,g as o,b as t}from"./p-DFz-gwFP.js";export{s as setNonce}from"./p-DFz-gwFP.js";(()=>{const o=import.meta.url,t={};return""!==o&&(t.resourcesUrl=new URL(".",o).href),e(t)})().then((async e=>(await o(),t([["p-6f0aa619",[[513,"dropi-icon",{name:[1],width:[1],height:[1],color:[1]},null,{color:[{colorChanged:0}]}]]],["p-21abf91a",[[769,"dropi-button",{type:[1],severity:[1],size:[1],state:[1],preIcon:[1,"pre-icon"],postIcon:[1,"post-icon"],text:[1]}]]],["p-a46a05a6",[[577,"dropi-input",{inputId:[1,"input-id"],name:[1],label:[1],placeholder:[1],value:[1025],maxlength:[2],disabled:[516],required:[516],showAsterisk:[4,"show-asterisk"],fixedLabel:[4,"fixed-label"],inputMode:[1,"input-mode"],passwordInput:[4,"password-input"],moneyFormat:[4,"money-format"],thousandSeparator:[4,"thousand-separator"],onlyNumbers:[4,"only-numbers"],allowDecimals:[4,"allow-decimals"],onlyLetters:[4,"only-letters"],icon:[1],iconColor:[1,"icon-color"],invalid:[4],helperText:[1,"helper-text"],showHelperOnlyOnError:[4,"show-helper-only-on-error"],showPassword:[32],touched:[32]},null,{value:[{valueChanged:0}],disabled:[{disabledChanged:0}]}]]],["p-c7b9cbda",[[577,"dropi-select",{label:[1],placeholder:[1],options:[1040],name:[1],disabled:[516],invalid:[4],errorText:[1,"error-text"],helperText:[1,"helper-text"],showObligatory:[4,"show-obligatory"],searchEnabled:[4,"search-enabled"],multiSelect:[4,"multi-select"],dropdownType:[4,"dropdown-type"],showCountryFlags:[4,"show-country-flags"],radioOptions:[4,"radio-options"],placeHolderSearch:[1,"place-holder-search"],preIcon:[1,"pre-icon"],defaultSelectedId:[1032,"default-selected-id"],value:[1040],isOpen:[32],selectedOption:[32],multiSelected:[32],filteredOptions:[32],searchTerm:[32],dropdownStyle:[32],setById:[64],setByLabel:[64],clearSelection:[64],resetMultiSelect:[64]},[[4,"click","handleOutsideClick"]],{options:[{optionsChanged:0}],defaultSelectedId:[{defaultChanged:0}],value:[{valueChanged:0}]}]]],["p-52291024",[[513,"dropi-tag",{type:[1],state:[1],showIcon:[4,"show-icon"],icon:[1],text:[1]},null,{type:[{propsChanged:0}],state:[{propsChanged:0}]}]]],["p-9c7076d3",[[577,"dropi-text-area",{inputId:[1,"input-id"],name:[1],label:[1],placeholder:[1],value:[1025],maxlength:[2],minlength:[2],rows:[2],resize:[1],disabled:[516],required:[516],showAsterisk:[4,"show-asterisk"],helperText:[1,"helper-text"],invalid:[4],touched:[32]},null,{value:[{valueChanged:0}]}]]],["p-f785011f",[[513,"dropi-badge",{state:[1]}]]],["p-dd089a60",[[577,"dropi-checkbox",{checked:[1540],disabled:[516]}]]],["p-bda1427f",[[577,"dropi-radio-button",{label:[1],name:[1],inputId:[1,"input-id"],checked:[1540],resetTrigger:[4,"reset-trigger"]},null,{resetTrigger:[{onResetTrigger:0}]}]]],["p-a1944f3d",[[577,"dropi-switch",{isChecked:[1540,"is-checked"],disabled:[516]}]]]],e))));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e,c as r,h as i}from"./p-DFz-gwFP.js";const t=class{constructor(i){e(this,i),this.dropiChange=r(this,"dropiChange")}label="";name="radio";inputId="radioButton";checked=!1;resetTrigger=!1;dropiChange;onResetTrigger(e){e&&(this.checked=!1)}handleChange(e){this.checked=e.target.checked,this.dropiChange.emit(e)}render(){return i("div",{key:"3b31699bf088bee52465981074c0aea48b6fe112",class:"dropi-radio-button"},i("label",{key:"072d19bd9c88739b849db0e264c65183eaab2132",htmlFor:this.inputId},i("input",{key:"82d1600002e9dc2795cdc5c731997742adc8e2db",id:this.inputId,type:"radio",name:this.name,checked:this.checked,onChange:e=>this.handleChange(e)}),this.label))}static get formAssociated(){return!0}static get watchers(){return{resetTrigger:[{onResetTrigger:0}]}}};t.style=":host{display:inline-block}*,*::before,*::after{box-sizing:border-box}.dropi-radio-button{display:flex;align-items:center;justify-content:flex-start;gap:20px}label{display:flex;flex-direction:row;align-items:center;gap:8px;cursor:pointer;color:var(--Gray-Gray-700, #32394d);font-size:var(--font-size-s, 12px);font-weight:var(--font-weight-regular, 400);line-height:1.5}input[type='radio']{appearance:none;-webkit-appearance:none;width:20px;height:20px;min-width:20px;border:2px solid var(--Gray-Gray-200, #c3c9d9);border-radius:50%;background-color:transparent;position:relative;cursor:pointer;outline:none;flex-shrink:0;align-self:center;vertical-align:middle;margin:0}input[type='radio']::before{content:'';position:absolute;top:3px;left:3px;width:10px;height:10px;background-color:var(--Primary-Primary-400, #f7b46f);border-radius:50%;display:none}input[type='radio']:checked{border:2px solid var(--Primary-Primary-500, #f49a3d)}input[type='radio']:checked::before{display:block}";export{t as dropi_radio_button}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as registerInstance, c as createEvent, h } from './index-DFz-gwFP.js';
|
|
2
2
|
|
|
3
|
-
const dropiRadioButtonCss = () => `:host{display:inline-block}*,*::before,*::after{box-sizing:border-box}.dropi-radio-button{display:flex;align-items:center;justify-content:flex-start;gap:20px}label{display:flex;align-items:center;gap:8px;cursor:pointer;color:var(--Gray-Gray-700, #32394d);font-size:var(--font-size-s, 12px);font-weight:var(--font-weight-regular, 400);line-height:1.5}input[type='radio']{appearance:none;width:20px;height:20px;border:2px solid var(--Gray-Gray-200, #c3c9d9);border-radius:50%;background-color:transparent;position:relative;cursor:pointer;outline:none;flex-shrink:0;
|
|
3
|
+
const dropiRadioButtonCss = () => `:host{display:inline-block}*,*::before,*::after{box-sizing:border-box}.dropi-radio-button{display:flex;align-items:center;justify-content:flex-start;gap:20px}label{display:flex;flex-direction:row;align-items:center;gap:8px;cursor:pointer;color:var(--Gray-Gray-700, #32394d);font-size:var(--font-size-s, 12px);font-weight:var(--font-weight-regular, 400);line-height:1.5}input[type='radio']{appearance:none;-webkit-appearance:none;width:20px;height:20px;min-width:20px;border:2px solid var(--Gray-Gray-200, #c3c9d9);border-radius:50%;background-color:transparent;position:relative;cursor:pointer;outline:none;flex-shrink:0;align-self:center;vertical-align:middle;margin:0}input[type='radio']::before{content:'';position:absolute;top:3px;left:3px;width:10px;height:10px;background-color:var(--Primary-Primary-400, #f7b46f);border-radius:50%;display:none}input[type='radio']:checked{border:2px solid var(--Primary-Primary-500, #f49a3d)}input[type='radio']:checked::before{display:block}`;
|
|
4
4
|
|
|
5
5
|
const DropiRadioButton = class {
|
|
6
6
|
constructor(hostRef) {
|
package/dist/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dropi/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
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",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"scripts/"
|
|
34
34
|
],
|
|
35
35
|
"scripts": {
|
|
36
|
-
"build": "stencil build",
|
|
36
|
+
"build": "stencil build && cd ../dropi-ui-react && npm run build",
|
|
37
37
|
"start": "stencil build --dev --watch --serve",
|
|
38
38
|
"test": "stencil-test",
|
|
39
39
|
"test:watch": "stencil-test --watch",
|
package/readme.md
CHANGED
|
@@ -1,107 +1,514 @@
|
|
|
1
|
-
|
|
1
|
+
# @dropi/ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Librería de Web Components del Design System de Dropi, construida con **Stencil.js v4**.
|
|
4
|
+
Genera componentes reutilizables para Angular, React y Vue desde una única base de código.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
- **Paquete npm:** `@dropi/ui` (v0.1.0)
|
|
7
|
+
- **React wrappers:** `@dropi/ui-react`
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
---
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Instalación
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
| Framework | Paquete a instalar |
|
|
14
|
+
|---|---|
|
|
15
|
+
| React | `npm install @dropi/ui-react` |
|
|
16
|
+
| Angular / Vue / Vanilla | `npm install @dropi/ui` |
|
|
12
17
|
|
|
13
|
-
|
|
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.
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
---
|
|
16
24
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
|
21
36
|
```
|
|
22
37
|
|
|
23
|
-
|
|
38
|
+
### Angular (`main.ts`)
|
|
24
39
|
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
|
|
40
|
+
```typescript
|
|
41
|
+
import { defineCustomElements } from '@dropi/ui/loader'
|
|
42
|
+
import '@dropi/ui/dist/dropi-ui/dropi-ui.css'
|
|
43
|
+
|
|
44
|
+
defineCustomElements()
|
|
45
|
+
bootstrapApplication(AppComponent, appConfig)
|
|
28
46
|
```
|
|
29
47
|
|
|
30
|
-
|
|
48
|
+
En módulos o componentes Angular que usen tags `<dropi-*>`, agregar el schema:
|
|
31
49
|
|
|
32
|
-
```
|
|
33
|
-
|
|
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] })
|
|
34
56
|
```
|
|
35
57
|
|
|
36
|
-
|
|
58
|
+
### Assets (íconos)
|
|
37
59
|
|
|
38
|
-
|
|
39
|
-
|
|
60
|
+
El componente `<dropi-icon>` requiere el sprite en `/assets/icons/symbol/svg/sprite.css.svg`.
|
|
61
|
+
|
|
62
|
+
**Angular** — en `angular.json`:
|
|
63
|
+
```json
|
|
64
|
+
"assets": [
|
|
65
|
+
{ "glob": "sprite.css.svg", "input": "node_modules/@dropi/ui/dist/dropi-ui/assets/icons/symbol/svg/", "output": "assets/icons/symbol/svg/" }
|
|
66
|
+
]
|
|
40
67
|
```
|
|
41
68
|
|
|
42
|
-
|
|
69
|
+
**React/Vite** — copiar a `public/assets/icons/symbol/svg/`.
|
|
43
70
|
|
|
44
|
-
|
|
71
|
+
---
|
|
45
72
|
|
|
46
|
-
|
|
73
|
+
## Cómo pasar props — regla fundamental
|
|
47
74
|
|
|
48
|
-
|
|
75
|
+
Cada prop se pasa **directamente en el JSX**, una por una. No existe un prop contenedor tipo `selectProperties` u `options` agrupadas.
|
|
49
76
|
|
|
50
|
-
|
|
77
|
+
```tsx
|
|
78
|
+
// ❌ Incorrecto — selectProperties no existe como prop
|
|
79
|
+
<DropiSelect selectProperties={{ label: 'País', placeholder: 'Seleccionar' }} />
|
|
80
|
+
|
|
81
|
+
// ✅ Correcto — cada prop va suelta en el tag
|
|
82
|
+
<DropiSelect
|
|
83
|
+
label="País"
|
|
84
|
+
placeholder="Seleccionar"
|
|
85
|
+
options={options}
|
|
86
|
+
onDropiChange={(e) => setSelected(e.detail)}
|
|
87
|
+
/>
|
|
88
|
+
```
|
|
51
89
|
|
|
52
|
-
|
|
90
|
+
Esto aplica para todos los componentes. Las props disponibles están listadas en cada sección de este readme.
|
|
53
91
|
|
|
54
|
-
|
|
92
|
+
> **Intellisense en VSCode:** si al hacer hover sobre un componente no aparecen las props, significa que `@dropi/ui-react` necesita ser compilado (`npm run build` en la carpeta `dropi-ui-react`). Después de cualquier cambio en la librería siempre hay que correr el build.
|
|
55
93
|
|
|
56
|
-
|
|
94
|
+
---
|
|
57
95
|
|
|
58
|
-
|
|
96
|
+
## Nota importante sobre eventos
|
|
59
97
|
|
|
60
|
-
|
|
98
|
+
Todos los eventos son `CustomEvent`. El valor emitido **siempre viene en `e.detail`**, no en `e` directamente.
|
|
61
99
|
|
|
62
|
-
|
|
100
|
+
```typescript
|
|
101
|
+
// ❌ Incorrecto — e es el CustomEvent completo, no el valor
|
|
102
|
+
onDropiChange={(e) => console.log(e)}
|
|
63
103
|
|
|
104
|
+
// ✅ Correcto — e.detail tiene el valor real
|
|
105
|
+
onDropiChange={(e) => console.log(e.detail)}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Componentes
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### `<dropi-button>`
|
|
115
|
+
|
|
116
|
+
Botón de acción principal con múltiples variantes de tipo, apariencia, tamaño y estado.
|
|
117
|
+
|
|
118
|
+
**Props**
|
|
119
|
+
|
|
120
|
+
| Prop | Tipo | Default | Descripción |
|
|
121
|
+
|---|---|---|---|
|
|
122
|
+
| `type` | `'legacy' \| 'default' \| 'success' \| 'info' \| 'error' \| 'warning' \| 'dropdown'` | `'default'` | Paleta de color |
|
|
123
|
+
| `severity` | `'primary' \| 'secondary' \| 'tertiary'` | `'primary'` | Relleno: filled / outlined / ghost |
|
|
124
|
+
| `size` | `'large' \| 'normal' \| 'small'` | `'normal'` | Tamaño |
|
|
125
|
+
| `state` | `'default' \| 'disabled' \| 'loading'` | `'default'` | Estado |
|
|
126
|
+
| `text` | `string` | `''` | Texto del label |
|
|
127
|
+
| `preIcon` | `string` | `''` | Ícono antes del texto |
|
|
128
|
+
| `postIcon` | `string` | `''` | Ícono después del texto |
|
|
129
|
+
|
|
130
|
+
**Eventos**
|
|
131
|
+
|
|
132
|
+
| Evento | `e.detail` | Cuándo |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| `dropiClick` | `MouseEvent` | Al hacer click (no se emite si `state` es `disabled` o `loading`) |
|
|
135
|
+
|
|
136
|
+
**Ejemplo React**
|
|
137
|
+
```tsx
|
|
138
|
+
<DropiButton
|
|
139
|
+
text="Guardar"
|
|
140
|
+
severity="primary"
|
|
141
|
+
size="normal"
|
|
142
|
+
onDropiClick={(e) => console.log(e.detail)}
|
|
143
|
+
/>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Ejemplo Angular**
|
|
64
147
|
```html
|
|
65
|
-
<
|
|
66
|
-
<!--
|
|
67
|
-
To avoid unpkg.com redirects to the actual file, you can also directly import:
|
|
68
|
-
https://unpkg.com/foobar-design-system@0.0.1/dist/foobar-design-system/foobar-design-system.esm.js
|
|
69
|
-
-->
|
|
70
|
-
<my-component first="Stencil" middle="'Don't call me a framework'" last="JS"></my-component>
|
|
148
|
+
<dropi-button text="Guardar" severity="primary" (dropiClick)="onSave($event)"></dropi-button>
|
|
71
149
|
```
|
|
72
150
|
|
|
73
|
-
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
### `<dropi-checkbox>`
|
|
154
|
+
|
|
155
|
+
Checkbox estilizado con soporte para formularios nativos.
|
|
156
|
+
|
|
157
|
+
**Props**
|
|
158
|
+
|
|
159
|
+
| Prop | Tipo | Default | Descripción |
|
|
160
|
+
|---|---|---|---|
|
|
161
|
+
| `checked` | `boolean` | `false` | Estado del checkbox |
|
|
162
|
+
| `disabled` | `boolean` | `false` | Deshabilita el checkbox |
|
|
74
163
|
|
|
75
|
-
|
|
164
|
+
**Eventos**
|
|
76
165
|
|
|
166
|
+
| Evento | `e.detail` | Cuándo |
|
|
167
|
+
|---|---|---|
|
|
168
|
+
| `dropiChange` | `boolean` | Al cambiar el estado (`true` = marcado, `false` = desmarcado) |
|
|
169
|
+
|
|
170
|
+
> `e.detail` es el boolean directamente. Si ves "el objeto completo" es porque estás leyendo `e` en vez de `e.detail`.
|
|
171
|
+
|
|
172
|
+
**Ejemplo React**
|
|
77
173
|
```tsx
|
|
78
|
-
|
|
174
|
+
const [checked, setChecked] = useState(false)
|
|
175
|
+
|
|
176
|
+
<DropiCheckbox
|
|
177
|
+
checked={checked}
|
|
178
|
+
onDropiChange={(e) => setChecked(e.detail)}
|
|
179
|
+
/>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Ejemplo Angular**
|
|
183
|
+
```html
|
|
184
|
+
<dropi-checkbox [checked]="checked" (dropiChange)="checked = $event.detail"></dropi-checkbox>
|
|
79
185
|
```
|
|
80
186
|
|
|
81
|
-
|
|
187
|
+
---
|
|
82
188
|
|
|
83
|
-
###
|
|
189
|
+
### `<dropi-switch>`
|
|
84
190
|
|
|
85
|
-
|
|
191
|
+
Toggle switch on/off.
|
|
86
192
|
|
|
87
|
-
|
|
193
|
+
**Props**
|
|
88
194
|
|
|
89
|
-
|
|
195
|
+
| Prop | Tipo | Default | Descripción |
|
|
196
|
+
|---|---|---|---|
|
|
197
|
+
| `isChecked` | `boolean` | `false` | Estado del switch |
|
|
198
|
+
| `disabled` | `boolean` | `false` | Deshabilita el switch |
|
|
90
199
|
|
|
200
|
+
**Eventos**
|
|
201
|
+
|
|
202
|
+
| Evento | `e.detail` | Cuándo |
|
|
203
|
+
|---|---|---|
|
|
204
|
+
| `dropiChange` | `boolean` | Al togglear (`true` = encendido, `false` = apagado) |
|
|
205
|
+
|
|
206
|
+
**Ejemplo React**
|
|
207
|
+
```tsx
|
|
208
|
+
const [on, setOn] = useState(false)
|
|
209
|
+
|
|
210
|
+
<DropiSwitch isChecked={on} onDropiChange={(e) => setOn(e.detail)} />
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### `<dropi-input>`
|
|
216
|
+
|
|
217
|
+
Campo de texto con label flotante, validación, ícono, toggle de contraseña, formato monetario y asociación nativa a formularios.
|
|
218
|
+
|
|
219
|
+
**Props**
|
|
220
|
+
|
|
221
|
+
| Prop | Tipo | Default | Descripción |
|
|
222
|
+
|---|---|---|---|
|
|
223
|
+
| `value` | `string` | `''` | Valor controlado |
|
|
224
|
+
| `label` | `string` | `''` | Label flotante o fija |
|
|
225
|
+
| `placeholder` | `string` | `' '` | Placeholder |
|
|
226
|
+
| `name` | `string` | `''` | Nombre para formularios nativos |
|
|
227
|
+
| `inputId` | `string` | `''` | ID del input (default: valor del label) |
|
|
228
|
+
| `disabled` | `boolean` | `false` | Deshabilita el campo |
|
|
229
|
+
| `required` | `boolean` | `false` | Marca como requerido |
|
|
230
|
+
| `showAsterisk` | `boolean` | `true` | Muestra asterisco cuando `required` |
|
|
231
|
+
| `fixedLabel` | `boolean` | `false` | Label fija arriba en vez de flotante |
|
|
232
|
+
| `inputMode` | `'text' \| 'numeric' \| 'decimal' \| 'tel' \| 'email' \| 'url' \| 'search'` | `'text'` | Teclado en móvil |
|
|
233
|
+
| `maxlength` | `number` | — | Longitud máxima |
|
|
234
|
+
| `invalid` | `boolean` | `false` | Marca el campo como inválido |
|
|
235
|
+
| `helperText` | `string` | `''` | Texto de ayuda o error debajo |
|
|
236
|
+
| `showHelperOnlyOnError` | `boolean` | `false` | Solo muestra helperText cuando inválido |
|
|
237
|
+
| `passwordInput` | `boolean` | `false` | Modo contraseña con toggle ojo |
|
|
238
|
+
| `moneyFormat` | `boolean` | `false` | Formato `$1,000,000` |
|
|
239
|
+
| `thousandSeparator` | `boolean` | `false` | Formato `1,000,000` sin símbolo |
|
|
240
|
+
| `onlyNumbers` | `boolean` | `false` | Solo permite números |
|
|
241
|
+
| `allowDecimals` | `boolean` | `false` | Permite decimales (con `onlyNumbers`) |
|
|
242
|
+
| `onlyLetters` | `boolean` | `false` | Solo permite letras |
|
|
243
|
+
| `icon` | `string` | `''` | Nombre del ícono (visible solo si hay valor) |
|
|
244
|
+
| `iconColor` | `string` | `'Gray-Gray-400'` | Token de color del ícono |
|
|
245
|
+
|
|
246
|
+
**Eventos**
|
|
247
|
+
|
|
248
|
+
| Evento | `e.detail` | Cuándo |
|
|
249
|
+
|---|---|---|
|
|
250
|
+
| `dropiInput` | `string` | En cada tecla (keystroke) |
|
|
251
|
+
| `dropiChange` | `string` | Al perder el foco (blur) |
|
|
252
|
+
| `dropiFocus` | `void` | Al enfocar el campo |
|
|
253
|
+
| `dropiBlur` | `void` | Al desenfocar el campo |
|
|
254
|
+
|
|
255
|
+
**Ejemplo React**
|
|
91
256
|
```tsx
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
257
|
+
const [value, setValue] = useState('')
|
|
258
|
+
|
|
259
|
+
<DropiInput
|
|
260
|
+
label="Nombre"
|
|
261
|
+
value={value}
|
|
262
|
+
onDropiInput={(e) => setValue(e.detail)}
|
|
263
|
+
onDropiChange={(e) => console.log('blur:', e.detail)}
|
|
264
|
+
required
|
|
265
|
+
invalid={value.length < 3}
|
|
266
|
+
helperText="Mínimo 3 caracteres"
|
|
267
|
+
/>
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
### `<dropi-text-area>`
|
|
273
|
+
|
|
274
|
+
Área de texto multi-línea con label, contador de caracteres, validación y asociación nativa a formularios.
|
|
275
|
+
|
|
276
|
+
**Props**
|
|
277
|
+
|
|
278
|
+
| Prop | Tipo | Default | Descripción |
|
|
279
|
+
|---|---|---|---|
|
|
280
|
+
| `value` | `string` | `''` | Valor controlado |
|
|
281
|
+
| `label` | `string` | `''` | Label superior |
|
|
282
|
+
| `placeholder` | `string` | `''` | Placeholder |
|
|
283
|
+
| `name` | `string` | `''` | Nombre para formularios nativos |
|
|
284
|
+
| `inputId` | `string` | `''` | ID del textarea |
|
|
285
|
+
| `rows` | `number` | `4` | Número de filas visibles |
|
|
286
|
+
| `maxlength` | `number` | — | Longitud máxima (muestra contador) |
|
|
287
|
+
| `minlength` | `number` | `0` | Longitud mínima |
|
|
288
|
+
| `resize` | `'none' \| 'both' \| 'horizontal' \| 'vertical'` | `'vertical'` | Comportamiento de resize |
|
|
289
|
+
| `disabled` | `boolean` | `false` | Deshabilita el campo |
|
|
290
|
+
| `required` | `boolean` | `false` | Marca como requerido |
|
|
291
|
+
| `showAsterisk` | `boolean` | `false` | Muestra asterisco cuando `required` |
|
|
292
|
+
| `invalid` | `boolean` | `false` | Marca el campo como inválido |
|
|
293
|
+
| `helperText` | `string` | `''` | Texto de ayuda o error |
|
|
294
|
+
|
|
295
|
+
**Eventos**
|
|
296
|
+
|
|
297
|
+
| Evento | `e.detail` | Cuándo |
|
|
298
|
+
|---|---|---|
|
|
299
|
+
| `dropiInput` | `string` | En cada tecla (keystroke) |
|
|
300
|
+
| `dropiChange` | `string` | Al perder el foco (blur) |
|
|
301
|
+
| `dropiFocus` | `void` | Al enfocar el campo |
|
|
302
|
+
| `dropiBlur` | `void` | Al desenfocar el campo |
|
|
303
|
+
|
|
304
|
+
**Ejemplo React**
|
|
305
|
+
```tsx
|
|
306
|
+
const [text, setText] = useState('')
|
|
307
|
+
|
|
308
|
+
<DropiTextArea
|
|
309
|
+
label="Descripción"
|
|
310
|
+
value={text}
|
|
311
|
+
maxlength={200}
|
|
312
|
+
rows={5}
|
|
313
|
+
onDropiInput={(e) => setText(e.detail)}
|
|
314
|
+
/>
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
### `<dropi-select>`
|
|
320
|
+
|
|
321
|
+
Select avanzado con búsqueda, multi-selección, opciones agrupadas, flags de países y opciones radio con imagen.
|
|
322
|
+
|
|
323
|
+
**Tipos**
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
interface SelectOption {
|
|
327
|
+
id: string | number
|
|
328
|
+
label: string
|
|
329
|
+
shortLabel?: string // para showCountryFlags
|
|
330
|
+
secondLabel?: string // subtítulo en radioOptions
|
|
331
|
+
countryCode?: string // código de país para flags
|
|
332
|
+
imageUrl?: string // imagen en radioOptions
|
|
333
|
+
preIcon?: string // ícono izquierdo
|
|
334
|
+
disabled?: boolean
|
|
102
335
|
}
|
|
103
336
|
|
|
104
|
-
|
|
337
|
+
interface SelectOptionGroup {
|
|
338
|
+
category: string // título del grupo
|
|
339
|
+
options: SelectOption[]
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Props**
|
|
344
|
+
|
|
345
|
+
| Prop | Tipo | Default | Descripción |
|
|
346
|
+
|---|---|---|---|
|
|
347
|
+
| `options` | `SelectOption[] \| SelectOptionGroup[]` | `[]` | Lista de opciones |
|
|
348
|
+
| `label` | `string` | `''` | Label superior |
|
|
349
|
+
| `placeholder` | `string` | `'Seleccionar'` | Texto sin selección |
|
|
350
|
+
| `name` | `string` | `''` | Nombre para formularios nativos |
|
|
351
|
+
| `value` | `SelectOption \| null` | `null` | Opción seleccionada (controlado) |
|
|
352
|
+
| `defaultSelectedId` | `string \| number` | `''` | Pre-seleccionar por id |
|
|
353
|
+
| `disabled` | `boolean` | `false` | Deshabilita el select |
|
|
354
|
+
| `invalid` | `boolean` | `false` | Estado inválido |
|
|
355
|
+
| `errorText` | `string` | `''` | Texto de error |
|
|
356
|
+
| `helperText` | `string` | `''` | Texto de ayuda |
|
|
357
|
+
| `showObligatory` | `boolean` | `false` | Muestra asterisco de obligatorio |
|
|
358
|
+
| `searchEnabled` | `boolean` | `false` | Habilita búsqueda en el dropdown |
|
|
359
|
+
| `multiSelect` | `boolean` | `false` | Permite múltiples selecciones |
|
|
360
|
+
| `dropdownType` | `boolean` | `false` | Trigger sin borde (inline) |
|
|
361
|
+
| `showCountryFlags` | `boolean` | `false` | Muestra flag de país |
|
|
362
|
+
| `radioOptions` | `boolean` | `false` | Opciones estilo radio con imagen |
|
|
363
|
+
| `placeHolderSearch` | `string` | `'Buscar'` | Placeholder del buscador |
|
|
364
|
+
| `preIcon` | `string` | `''` | Ícono antes del label del trigger |
|
|
365
|
+
|
|
366
|
+
**Métodos públicos**
|
|
367
|
+
|
|
368
|
+
| Método | Descripción |
|
|
369
|
+
|---|---|
|
|
370
|
+
| `setById(id)` | Selecciona una opción por su id |
|
|
371
|
+
| `setByLabel(label)` | Selecciona una opción por su label |
|
|
372
|
+
| `clearSelection()` | Limpia la selección actual |
|
|
373
|
+
| `resetMultiSelect()` | Limpia la selección múltiple |
|
|
374
|
+
|
|
375
|
+
**Eventos**
|
|
376
|
+
|
|
377
|
+
| Evento | `e.detail` | Cuándo |
|
|
378
|
+
|---|---|---|
|
|
379
|
+
| `dropiChange` | `SelectOption` (single) o `SelectOption[]` (multi) | Al seleccionar una opción |
|
|
380
|
+
| `dropiClear` | `void` | Al limpiar la selección |
|
|
381
|
+
| `dropiSearch` | `string` | Al escribir en el buscador |
|
|
382
|
+
| `dropiScrollEnd` | `void` | Al llegar al final del scroll (paginación) |
|
|
383
|
+
| `dropiKeyEnter` | `KeyboardEvent` | Al presionar Enter en el buscador |
|
|
384
|
+
|
|
385
|
+
**Ejemplo React**
|
|
386
|
+
```tsx
|
|
387
|
+
const [selected, setSelected] = useState(null)
|
|
388
|
+
|
|
389
|
+
const options = [
|
|
390
|
+
{ id: 1, label: 'Colombia' },
|
|
391
|
+
{ id: 2, label: 'México' },
|
|
392
|
+
]
|
|
393
|
+
|
|
394
|
+
<DropiSelect
|
|
395
|
+
label="País"
|
|
396
|
+
options={options}
|
|
397
|
+
searchEnabled
|
|
398
|
+
onDropiChange={(e) => setSelected(e.detail)}
|
|
399
|
+
/>
|
|
105
400
|
```
|
|
106
401
|
|
|
107
|
-
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
### `<dropi-radio-button>`
|
|
405
|
+
|
|
406
|
+
Radio button estilizado con label y soporte para grupos.
|
|
407
|
+
|
|
408
|
+
**Props**
|
|
409
|
+
|
|
410
|
+
| Prop | Tipo | Default | Descripción |
|
|
411
|
+
|---|---|---|---|
|
|
412
|
+
| `label` | `string` | `''` | Texto del label |
|
|
413
|
+
| `name` | `string` | `'radio'` | Nombre para agrupar radios |
|
|
414
|
+
| `inputId` | `string` | `'radioButton'` | ID del input |
|
|
415
|
+
| `checked` | `boolean` | `false` | Estado seleccionado |
|
|
416
|
+
| `resetTrigger` | `boolean` | `false` | Al poner `true` resetea a desmarcado |
|
|
417
|
+
|
|
418
|
+
**Eventos**
|
|
419
|
+
|
|
420
|
+
| Evento | `e.detail` | Cuándo |
|
|
421
|
+
|---|---|---|
|
|
422
|
+
| `dropiChange` | `Event` (evento nativo) | Al seleccionar el radio |
|
|
423
|
+
|
|
424
|
+
> A diferencia del checkbox, emite el `Event` nativo. Para controlar el estado, maneja la prop `checked` desde el padre.
|
|
425
|
+
|
|
426
|
+
**Ejemplo React**
|
|
427
|
+
```tsx
|
|
428
|
+
const [selected, setSelected] = useState('a')
|
|
429
|
+
|
|
430
|
+
<DropiRadioButton label="Opción A" name="grupo" inputId="opt-a" checked={selected === 'a'} onDropiChange={() => setSelected('a')} />
|
|
431
|
+
<DropiRadioButton label="Opción B" name="grupo" inputId="opt-b" checked={selected === 'b'} onDropiChange={() => setSelected('b')} />
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
### `<dropi-badge>`
|
|
437
|
+
|
|
438
|
+
Badge de estado para cuentas o usuarios. Sin eventos.
|
|
439
|
+
|
|
440
|
+
**Props**
|
|
441
|
+
|
|
442
|
+
| Prop | Tipo | Default | Descripción |
|
|
443
|
+
|---|---|---|---|
|
|
444
|
+
| `state` | `'pending' \| 'active' \| 'canceled' \| 'frozen'` | `'pending'` | Estado a mostrar |
|
|
445
|
+
|
|
446
|
+
| State | Texto mostrado |
|
|
447
|
+
|---|---|
|
|
448
|
+
| `pending` | Pendiente |
|
|
449
|
+
| `active` | Activo |
|
|
450
|
+
| `canceled` | Cancelado |
|
|
451
|
+
| `frozen` | Congelado |
|
|
452
|
+
|
|
453
|
+
**Ejemplo React**
|
|
454
|
+
```tsx
|
|
455
|
+
<DropiBadge state="active" />
|
|
456
|
+
<DropiBadge state="pending" />
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
### `<dropi-tag>`
|
|
462
|
+
|
|
463
|
+
Tag/chip de color para categorías, estados o etiquetas. Sin eventos.
|
|
464
|
+
|
|
465
|
+
**Props**
|
|
466
|
+
|
|
467
|
+
| Prop | Tipo | Default | Descripción |
|
|
468
|
+
|---|---|---|---|
|
|
469
|
+
| `type` | `'primary' \| 'secondary'` | `'primary'` | `primary` = relleno, `secondary` = suave |
|
|
470
|
+
| `state` | `'default' \| 'success' \| 'info' \| 'warning' \| 'error' \| 'legacy'` | `'default'` | Color del tag |
|
|
471
|
+
| `text` | `string` | `''` | Texto del tag |
|
|
472
|
+
| `showIcon` | `boolean` | `false` | Mostrar ícono |
|
|
473
|
+
| `icon` | `string` | `''` | Nombre del ícono del sprite |
|
|
474
|
+
|
|
475
|
+
**Ejemplo React**
|
|
476
|
+
```tsx
|
|
477
|
+
<DropiTag text="Activo" state="success" type="primary" />
|
|
478
|
+
<DropiTag text="Pendiente" state="warning" type="secondary" />
|
|
479
|
+
<DropiTag text="Error" state="error" showIcon icon="Warning-circle" />
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
### `<dropi-icon>`
|
|
485
|
+
|
|
486
|
+
Renderiza íconos SVG desde el sprite de Dropi. Sin eventos.
|
|
487
|
+
|
|
488
|
+
**Props**
|
|
489
|
+
|
|
490
|
+
| Prop | Tipo | Default | Descripción |
|
|
491
|
+
|---|---|---|---|
|
|
492
|
+
| `name` | `string` | `''` | Nombre del ícono en el sprite (ej. `'Home'`, `'Search'`) |
|
|
493
|
+
| `width` | `string` | `'24px'` | Ancho (valor CSS) |
|
|
494
|
+
| `height` | `string` | `'24px'` | Alto (valor CSS) |
|
|
495
|
+
| `color` | `string` | `'currentColor'` | Hex `#ff0000`, token sin `--` (`Primary-Primary-500`), o `currentColor` |
|
|
496
|
+
|
|
497
|
+
> Requiere el sprite en `/assets/icons/symbol/svg/sprite.css.svg` de la app consumidora.
|
|
498
|
+
|
|
499
|
+
**Ejemplo React**
|
|
500
|
+
```tsx
|
|
501
|
+
<DropiIcon name="Home" width="24px" height="24px" color="Primary-Primary-500" />
|
|
502
|
+
<DropiIcon name="Search" color="#333333" />
|
|
503
|
+
<DropiIcon name="Warning-circle" color="Error-Error-500" />
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## Build (desarrollo)
|
|
509
|
+
|
|
510
|
+
```bash
|
|
511
|
+
npm run build # compilar
|
|
512
|
+
npm run start # dev con watch
|
|
513
|
+
npm test # unit tests
|
|
514
|
+
```
|
package/scripts/postinstall.js
CHANGED
|
@@ -163,7 +163,7 @@ if (isVite) {
|
|
|
163
163
|
const p = path.join(projectRoot, f);
|
|
164
164
|
if (!fs.existsSync(p)) continue;
|
|
165
165
|
const content = fs.readFileSync(p, 'utf8');
|
|
166
|
-
if (content.includes('@dropi/ui')) { vitePatchDone = 'ya'; break; }
|
|
166
|
+
if (content.includes('@dropi/ui/loader') && content.includes("exclude")) { vitePatchDone = 'ya'; break; }
|
|
167
167
|
const patch = `\n optimizeDeps: {\n exclude: ['@dropi/ui/loader', '@dropi/ui'],\n },`;
|
|
168
168
|
const updated = content.replace(/defineConfig\(\{/, `defineConfig({${patch}`);
|
|
169
169
|
if (updated !== content) { fs.writeFileSync(p, updated, 'utf8'); vitePatchDone = true; }
|
|
@@ -197,7 +197,11 @@ Errores comunes y solución:
|
|
|
197
197
|
- Sprite: [ruta destino] ✓
|
|
198
198
|
- skipLibCheck: true ✓
|
|
199
199
|
|
|
200
|
-
Prueba rápida:
|
|
200
|
+
Prueba rápida (React):
|
|
201
|
+
import { DropiButton } from '@dropi/ui-react'
|
|
202
|
+
<DropiButton text="Hola Dropi" type="default" severity="primary" size="normal" />
|
|
203
|
+
|
|
204
|
+
Prueba rápida (Angular/Vue):
|
|
201
205
|
<dropi-button text="Hola Dropi" type="default" severity="primary" size="normal"></dropi-button>
|
|
202
206
|
```
|
|
203
207
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e,c as r,h as t}from"./p-DFz-gwFP.js";const i=class{constructor(t){e(this,t),this.dropiChange=r(this,"dropiChange")}label="";name="radio";inputId="radioButton";checked=!1;resetTrigger=!1;dropiChange;onResetTrigger(e){e&&(this.checked=!1)}handleChange(e){this.checked=e.target.checked,this.dropiChange.emit(e)}render(){return t("div",{key:"3b31699bf088bee52465981074c0aea48b6fe112",class:"dropi-radio-button"},t("label",{key:"072d19bd9c88739b849db0e264c65183eaab2132",htmlFor:this.inputId},t("input",{key:"82d1600002e9dc2795cdc5c731997742adc8e2db",id:this.inputId,type:"radio",name:this.name,checked:this.checked,onChange:e=>this.handleChange(e)}),this.label))}static get formAssociated(){return!0}static get watchers(){return{resetTrigger:[{onResetTrigger:0}]}}};i.style=":host{display:inline-block}*,*::before,*::after{box-sizing:border-box}.dropi-radio-button{display:flex;align-items:center;justify-content:flex-start;gap:20px}label{display:flex;align-items:center;gap:8px;cursor:pointer;color:var(--Gray-Gray-700, #32394d);font-size:var(--font-size-s, 12px);font-weight:var(--font-weight-regular, 400);line-height:1.5}input[type='radio']{appearance:none;width:20px;height:20px;border:2px solid var(--Gray-Gray-200, #c3c9d9);border-radius:50%;background-color:transparent;position:relative;cursor:pointer;outline:none;flex-shrink:0;display:flex;justify-content:center;align-items:center}input[type='radio']::before{content:'';position:absolute;top:3px;left:3px;width:10px;height:10px;background-color:var(--Primary-Primary-400, #f7b46f);border-radius:50%;display:none}input[type='radio']:checked{border:2px solid var(--Primary-Primary-500, #f49a3d)}input[type='radio']:checked::before{display:block}";export{i as dropi_radio_button}
|