@dropi/ui
v0.1.52
Published
Dropi Design System — Web Components for Angular, React and Vue
Downloads
4,394
Readme
@dropi/ui 🚀
Librería de Web Components del Design System de Dropi, construida con Stencil.js v4. Genera componentes de alto rendimiento para Angular, React y Next.js desde una única base de código.
- Paquete npm: @dropi/ui (v0.1.44)
- React wrappers: @dropi/ui-react (v0.1.18)
[!NOTE] Esta es una librería de uso interno y para partners autorizados. La documentación detallada del código fuente reside en nuestro repositorio privado de Bitbucket.
⚡ Quick Start (Recomendado)
Si estás en un proyecto de React o Angular, la forma más rápida de configurar todo es:
npx @dropi/ui setupEste comando detectará tu framework e instalará automáticamente las dependencias y configuraciones necesarias.
🛠️ Instalación Manual
Si prefieres realizar la configuración paso a paso, consulta la Guía de Integración Detallada o sigue estos pasos:
1. Paquetes
| Framework | Paquete a instalar |
|---|---|
| Angular | npm install @dropi/ui @dropi/ui-angular |
| React | npm install @dropi/ui @dropi/ui-react |
| Next.js SSR | npm install @dropi/ui @dropi/ui-react && npm install --save-dev @stencil/ssr --legacy-peer-deps |
2. Estilos e Iconos
- CSS: Importar
@dropi/ui/dist/dropi-ui/dropi-ui.css. - CSS Resets: Añade este reset para evitar saltos de layout en los iconos:
dropi-icon:not(.hydrated) { width: 20px; height: 20px; display: inline-flex; } - Registro: No hace falta llamar
defineCustomElements(). - SSR (Next.js): Configurar
next.config.tse importar siempre desde/next. - Iconos: El sprite SVG debe estar en
public/assets/icons/symbol/svg/sprite.css.svg.
🚀 Soporte para Next.js (SSR / Zero Flash)
Para habilitar el Server Side Rendering (SSR) y eliminar cualquier parpadeo visual, sigue estos pasos:
1. Configuración de Next.js
Envuelve tu configuración en el plugin withStencil:
// next.config.ts
import withStencil from "@stencil/ssr/next";
const nextConfig = {
transpilePackages: ["@dropi/ui-react", "@dropi/ui"],
};
export default withStencil({
from: "@dropi/ui-react",
module: import("@dropi/ui-react/next"),
hydrateModule: import("@dropi/ui/hydrate"),
})(nextConfig);2. Scripts en package.json (Next.js 16)
Next.js 16 usa Turbopack por defecto, que es incompatible con @stencil/ssr. Agrega --webpack:
"dev": "next dev --webpack",
"build": "next build --webpack"3. Configuración del Layout (Crítico)
Añade suppressHydrationWarning al <body> en layout.tsx para evitar que el DevTools o extensiones rompan la hidratación.
<body suppressHydrationWarning>{children}</body>4. Importar desde /next en Server Components
En páginas o layouts (Server Components), importa desde @dropi/ui-react/next:
import { DropiButton, DropiInput } from "@dropi/ui-react/next";En componentes con "use client", importa desde @dropi/ui-react normalmente.
Cómo pasar props
Hay dos formas válidas, ambas funcionan:
Forma 1 — Props individuales (React / Vanilla)
<DropiSelect
label="País"
placeholder="Seleccionar"
options={options}
onOnChangeSelect={(e) => setSelected(e.detail)}
/>Forma 2 — Objeto de compatibilidad Angular (equivalente al core)
Los componentes principales aceptan un prop-objeto que replica la API del @Input() del core Angular:
| Componente | Prop objeto | Equivale al @Input() Angular |
|---|---|---|
| dropi-select | [selectProperties]="selectProperties" | SelectProperties |
| dropi-input | [inputProperties]="inputProperties" | InputProperties |
| dropi-text-area | [textAreaProperties]="textAreaProperties" | TextAreaProperties |
| dropi-alert-modal | [params]="params" | ModalParams |
<!-- Angular — forma idéntica al core -->
<dropi-select [selectProperties]="selectProperties" (onChangeSelect)="onChange($event)" />
<dropi-alert-modal [visible]="visible" [params]="params" (primaryButtonEvent)="onPrimary($event)" />Intellisense en VSCode: si al hacer hover sobre un componente no aparecen las props, significa que
@dropi/ui-reactnecesita ser compilado (npm run builden la carpetadropi-ui-react). Después de cualquier cambio en la librería siempre hay que correr el build.
Nota importante sobre eventos
Todos los eventos son CustomEvent. El valor emitido siempre viene en e.detail, no en e directamente.
// ❌ Incorrecto — e es el CustomEvent completo, no el valor
onOnInput={(e) => console.log(e)}
// ✅ Correcto — e.detail tiene el valor real
onOnInput={(e) => console.log(e.detail)}Nombres de eventos en React: Los wrappers React siguen el patrón
on<EventName>. Si el evento Stencil empieza conon(ej.onClick), el wrapper lo duplica:onOnClick. Si empieza condropi(ej.dropiChange), quedaonDropiChange.
📋 Soporte para Formularios Nativos
Todos los componentes de entrada (DropiInput, DropiSelect, DropiCheckbox, DropiSwitch, DropiPhoneInput, DropiCountrySelector, DropiOtpSendCode) soportan la asociación nativa a formularios.
Esto permite capturar sus valores de forma instantánea usando el estándar del navegador:
Ejemplo en React (Estilo FormData)
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
// Extrae todos los valores automáticamente
const formData = new FormData(e.currentTarget);
const data = Object.fromEntries(formData.entries());
console.log(data); // { email: "...", country: "CO", phone: "+57..." }
};
return (
<form onSubmit={handleSubmit}>
<DropiInput name="email" label="Email" required />
<DropiCountrySelector name="country" label="País" />
<DropiPhoneInput name="phone" label="Celular" />
<DropiButton nativeType="submit" text="Enviar Registro" />
</form>
);[!IMPORTANT] Para que un componente sea capturado por el formulario, debe tener la prop
namedefinida.
Uso en React (Métodos Imperativos)
Componentes como DropiModal y DropiToast tienen métodos que deben llamarse vía ref. Dado que los wrappers son generados, a veces es necesario castear a any para acceder a show() o hide().
const modalRef = useRef<any>(null);
const Modal = DropiModal as any; // Cast opcional para mejor DX
<Modal ref={modalRef} header="Título">
<p>Contenido</p>
</Modal>
<button onClick={() => modalRef.current?.show()}>Abrir</button>Componentes
<dropi-button>
Botón de acción principal con múltiples variantes de tipo, apariencia, tamaño y estado.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| type | 'legacy' \| 'default' \| 'success' \| 'info' \| 'error' \| 'warning' \| 'dropdown' | 'default' | Paleta de color |
| severity | 'primary' \| 'secondary' \| 'tertiary' | 'primary' | Relleno: filled / outlined / ghost |
| size | 'large' \| 'normal' \| 'small' | 'normal' | Tamaño |
| state | 'default' \| 'disabled' \| 'loading' | 'default' | Estado |
| text | string | '' | Texto del label |
| preIcon | string | '' | Ícono antes del texto |
| postIcon | string | '' | Ícono después del texto |
| nativeType | 'button' \| 'submit' \| 'reset' | 'button' | Tipo de botón nativo HTML |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onOnClick | MouseEvent | Al hacer click (no se emite si state es disabled o loading) |
Ejemplo React
<DropiButton
text="Guardar"
severity="primary"
size="normal"
onOnClick={(e) => console.log(e.detail)}
/>Ejemplo Angular
<dropi-button text="Guardar" severity="primary" (onClick)="onSave($event)"></dropi-button><dropi-checkbox>
Checkbox estilizado con soporte para formularios nativos.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| checked | boolean | false | Estado del checkbox |
| disabled | boolean | false | Deshabilita el checkbox |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onOnChange | boolean | Al cambiar el estado (true = marcado, false = desmarcado) |
e.detailes el boolean directamente. Si ves "el objeto completo" es porque estás leyendoeen vez dee.detail.
Ejemplo React
const [checked, setChecked] = useState(false)
<DropiCheckbox
checked={checked}
onOnChange={(e) => setChecked(e.detail)}
/>Ejemplo Angular
<dropi-checkbox [checked]="checked" (onChange)="checked = $event.detail"></dropi-checkbox><dropi-switch>
Toggle switch on/off.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| isChecked | boolean | false | Estado del switch |
| disabled | boolean | false | Deshabilita el switch |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onOnChange | boolean | Al togglear (true = encendido, false = apagado) |
Ejemplo React
const [on, setOn] = useState(false)
<DropiSwitch isChecked={on} onOnChange={(e) => setOn(e.detail)} /><dropi-input>
Campo de texto con label flotante, validación, ícono, toggle de contraseña, formato monetario y asociación nativa a formularios.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| value | string | '' | Valor controlado |
| label | string | '' | Label flotante o fija |
| placeholder | string | ' ' | Placeholder |
| name | string | '' | Nombre para formularios nativos |
| inputId | string | '' | ID del input (default: valor del label) |
| disabled | boolean | false | Deshabilita el campo |
| required | boolean | false | Marca como requerido |
| showAsterisk | boolean | true | Muestra asterisco cuando required |
| fixedLabel | boolean | false | Label fija arriba en vez de flotante |
| inputMode | 'text' \| 'numeric' \| 'decimal' \| 'tel' \| 'email' \| 'url' \| 'search' | 'text' | Teclado en móvil |
| maxlength | number | — | Longitud máxima |
| invalid | boolean | false | Marca el campo como inválido |
| helperText | string | '' | Texto de ayuda o error debajo |
| showHelperOnlyOnError | boolean | false | Solo muestra helperText cuando inválido |
| passwordInput | boolean | false | Modo contraseña con toggle ojo |
| moneyFormat | boolean | false | Formato $1,000,000 |
| thousandSeparator | boolean | false | Formato 1,000,000 sin símbolo |
| onlyNumbers | boolean | false | Solo permite números |
| allowDecimals | boolean | false | Permite decimales (con onlyNumbers) |
| onlyLetters | boolean | false | Solo permite letras |
| icon | string | '' | Nombre del ícono (visible solo si hay valor) |
| iconColor | string | 'Gray-Gray-400' | Token de color del ícono |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onOnInput | string | En cada tecla (keystroke) |
| onOnChange | string | Al perder el foco (blur) |
| onOnFocus | void | Al enfocar el campo |
| onOnBlur | void | Al desenfocar el campo |
Ejemplo React
const [value, setValue] = useState('')
<DropiInput
label="Nombre"
value={value}
onOnInput={(e) => setValue(e.detail)}
onOnChange={(e) => console.log('blur:', e.detail)}
required
invalid={value.length < 3}
helperText="Mínimo 3 caracteres"
/><dropi-text-area>
Área de texto multi-línea con label, contador de caracteres, validación y asociación nativa a formularios.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| value | string | '' | Valor controlado |
| label | string | '' | Label superior |
| placeholder | string | '' | Placeholder |
| name | string | '' | Nombre para formularios nativos |
| inputId | string | '' | ID del textarea |
| rows | number | 4 | Número de filas visibles |
| maxlength | number | — | Longitud máxima (muestra contador) |
| minlength | number | 0 | Longitud mínima |
| resize | 'none' \| 'both' \| 'horizontal' \| 'vertical' | 'vertical' | Comportamiento de resize |
| disabled | boolean | false | Deshabilita el campo |
| required | boolean | false | Marca como requerido |
| showAsterisk | boolean | false | Muestra asterisco cuando required |
| invalid | boolean | false | Marca el campo como inválido |
| helperText | string | '' | Texto de ayuda o error |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onDropiInput | string | En cada tecla (keystroke) |
| onDropiChange | string | Al perder el foco (blur) |
| onDropiFocus | void | Al enfocar el campo |
| onDropiBlur | void | Al desenfocar el campo |
Ejemplo React
const [text, setText] = useState('')
<DropiTextArea
label="Descripción"
value={text}
maxlength={200}
rows={5}
onDropiInput={(e) => setText(e.detail)}
/><dropi-select>
Select avanzado con búsqueda, multi-selección, opciones agrupadas, flags de países y opciones radio con imagen.
Tipos
interface SelectOption {
id: string | number
label: string
shortLabel?: string // para showCountryFlags
secondLabel?: string // subtítulo en radioOptions
countryCode?: string // código de país para flags
countryId?: string // id de país para flags
imageUrl?: string // imagen en radioOptions
preIcon?: string // ícono izquierdo
disabled?: boolean
}
interface SelectOptionGroup {
category: string // título del grupo
options: SelectOption[]
}Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| options | SelectOption[] \| SelectOptionGroup[] | [] | Lista de opciones |
| label | string | '' | Label superior |
| placeholder | string | 'Seleccionar' | Texto sin selección |
| name | string | '' | Nombre para formularios nativos |
| value | SelectOption \| null | null | Opción seleccionada (controlado) |
| defaultSelectedId | string \| number | '' | Pre-seleccionar por id |
| disabled | boolean | false | Deshabilita el select |
| invalid | boolean | false | Estado inválido |
| errorText | string | '' | Texto de error |
| helperText | string | '' | Texto de ayuda |
| showObligatory | boolean | false | Muestra asterisco de obligatorio |
| searchEnabled | boolean | false | Habilita búsqueda en el dropdown |
| multiSelect | boolean | false | Permite múltiples selecciones |
| dropdownType | boolean | false | Trigger sin borde (inline) |
| showCountryFlags | boolean | false | Muestra flag de país |
| radioOptions | boolean | false | Opciones estilo radio con imagen |
| placeHolderSearch | string | 'Buscar' | Placeholder del buscador |
| preIcon | string | '' | Ícono antes del label del trigger |
Métodos públicos
| Método | Descripción |
|---|---|
| setById(id) | Selecciona una opción por su id |
| setByLabel(label) | Selecciona una opción por su label |
| clearSelection() | Limpia la selección actual |
| resetMultiSelect() | Limpia la selección múltiple |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onOnChangeSelect | SelectOption (single) o SelectOption[] (multi) | Al seleccionar una opción |
| onOnClear | void | Al limpiar la selección |
| onOnSearch | string | Al escribir en el buscador |
| onScrolledToEnd | void | Al llegar al final del scroll (paginación) |
| onOnKeyEnter | KeyboardEvent | Al presionar Enter en el buscador |
Ejemplo React
const [selected, setSelected] = useState(null)
const options = [
{ id: 1, label: 'Colombia' },
{ id: 2, label: 'México' },
]
<DropiSelect
label="País"
options={options}
searchEnabled
onOnChangeSelect={(e) => setSelected(e.detail)}
/><dropi-radio-button>
Radio button estilizado con label y soporte para grupos.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| label | string | '' | Texto del label |
| name | string | 'radio' | Nombre para agrupar radios |
| inputId | string | 'radioButton' | ID del input |
| checked | boolean | false | Estado seleccionado |
| resetTrigger | boolean | false | Al poner true resetea a desmarcado |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onOnChange | Event (evento nativo) | Al seleccionar el radio |
A diferencia del checkbox, emite el
Eventnativo. Para controlar el estado, maneja la propcheckeddesde el padre.
Ejemplo React
const [selected, setSelected] = useState('a')
<DropiRadioButton label="Opción A" name="grupo" inputId="opt-a" checked={selected === 'a'} onOnChange={() => setSelected('a')} />
<DropiRadioButton label="Opción B" name="grupo" inputId="opt-b" checked={selected === 'b'} onOnChange={() => setSelected('b')} /><dropi-badge>
Badge de estado para cuentas o usuarios. Sin eventos.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| state | 'pending' \| 'active' \| 'canceled' \| 'frozen' | 'pending' | Estado a mostrar |
| State | Texto mostrado |
|---|---|
| pending | Pendiente |
| active | Activo |
| canceled | Cancelado |
| frozen | Congelado |
Ejemplo React
<DropiBadge state="active" />
<DropiBadge state="pending" /><dropi-tag>
Tag/chip de color para categorías, estados o etiquetas. Sin eventos.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| type | 'primary' \| 'secondary' | 'primary' | primary = relleno, secondary = suave |
| state | 'default' \| 'success' \| 'info' \| 'warning' \| 'error' \| 'legacy' | 'default' | Color del tag |
| text | string | '' | Texto del tag |
| showIcon | boolean | false | Mostrar ícono |
| icon | string | '' | Nombre del ícono del sprite |
Ejemplo React
<DropiTag text="Activo" state="success" type="primary" />
<DropiTag text="Pendiente" state="warning" type="secondary" />
<DropiTag text="Error" state="error" showIcon icon="Warning-circle" /><dropi-icon>
Renderiza íconos SVG desde el sprite de Dropi. Sin eventos.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| name | string | '' | Nombre del ícono en el sprite (ej. 'Home', 'Search') |
| width | string | '24px' | Ancho (valor CSS) |
| height | string | '24px' | Alto (valor CSS) |
| color | string | 'currentColor' | Hex #ff0000, token sin -- (Primary-Primary-500), o currentColor |
Requiere el sprite en
/assets/icons/symbol/svg/sprite.css.svgde la app consumidora.
Ejemplo React
<DropiIcon name="Home" width="24px" height="24px" color="Primary-Primary-500" />
<DropiIcon name="Search" color="#333333" />
<DropiIcon name="Warning-circle" color="Error-Error-500" /><dropi-tabs>
Sistema de pestañas con contadores y estados.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| tabs | TabItem[] | [] | Lista de tabs { id, label, counter, active, disabled, completed } |
| showIcon | boolean | false | Mostrar check si completed |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onOnIndexChanged | TabItem | Al cambiar de tab |
Ejemplo React
<DropiTabs
tabs={[{ id: 1, label: 'Activos', counter: 5 }]}
onOnIndexChanged={(e) => console.log(e.detail)}
/><dropi-accordion>
Contenedor colapsable.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| header | string | '' | Título del acordeón |
| preIcon | string | '' | Ícono izquierdo |
| disabled | boolean | false | Deshabilitar |
Ejemplo React
<DropiAccordion header="¿Cómo funciona?">
<p>Contenido interno</p>
</DropiAccordion><dropi-skeleton>
Indicadores de carga.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| variant | 'text' \| 'circle' \| 'rect' | 'text' | Forma |
| width | string | '100%' | Ancho CSS |
| height | string | '16px' | Alto CSS |
<dropi-paginator>
Control de paginación.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| total | number | 0 | Total de registros |
| rows | number | 10 | Registros por página |
| showPageSizeSelector | boolean | false | Selector de cantidad por página |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onPageChange | number | Al cambiar de página |
Ejemplo React
<DropiPaginator
total={100}
onPageChange={(e) => console.log(e.detail)}
/><dropi-empty-state>
Pantalla de "no hay datos".
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| header | string | '' | Título principal |
| description | string | '' | Subtítulo descriptivo |
| actionLabel | string | '' | Texto botón principal |
| secondaryLabel | string | '' | Texto botón secundario |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onButtonClickEvent | void | Al hacer click en el botón principal |
<dropi-tooltip> (V2)
Burbuja de información al hover.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| text | string | '' | Mensaje del tooltip |
| position | 'top' \| 'bottom' \| 'left' \| 'right' | 'top' | Posición |
| maxWidth | string | '280px' | Ancho máximo |
Ejemplo React
<DropiTooltip text="Guardar cambios" position="bottom">
<DropiButton text="Hover me" />
</DropiTooltip><dropi-table>
Tabla de datos con paginación local/backend, ordenación, búsqueda y checkbox de selección.
⚠️ Las filas van en formato TypedField (no objetos planos):
{ name: { type: 'text', value: 'Ana' } }
Props principales
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| headers | DropiTableColumn[] | [] | Columnas { key, label, sortable } |
| data | DropiTableRow[] | [] | Filas en formato TypedField |
| dropiTableConfiguration | DropiTableConfiguration | null | Config: paginación, búsqueda, acciones |
| loading | boolean | false | Indicador de carga |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onDropiSelection | number[] | Checkbox cambia selección |
| onDropiSort | { key: string; dir: SortDir } | Click en columna ordenable |
| onDropiPageChange | number | Cambio de página (backend) |
| onDropiAction | { row: TableRow; action: any } | Click en acción de fila |
| onDropiRowClick | { row: TableRow; index: number } | Click en una fila |
| onDropiSearch | string | Al buscar |
Ejemplo Angular
<dropi-table
[headers]="headers"
[data]="data"
[dropiTableConfiguration]="{ backendPagination: false, showPaginator: true, pageSizeConfiguration: [5, 10, 25] }"
[loading]="loading"
(dropiSort)="onSort($event)"
(dropiSelection)="onSelect($event)"
/><dropi-modal>
Ventana de diálogo con overlays.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| header | string | '' | Título del modal |
| size | 's' \| 'm' \| 'l' \| 'full' ... | 'm' | Tamaño |
| visible | boolean | false | Controlar visibilidad vía prop |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onOnShow | void | Al abrir el modal |
| onOnHide | void | Al cerrar el modal |
| onVisibleChange | boolean | Al cambiar visible |
Ejemplo React (Imperativo)
const modalRef = useRef<any>(null);
const Modal = DropiModal as any;
<Modal ref={modalRef} header="Mi Modal" onOnHide={() => console.log('cerrado')}>
<p>Contenido</p>
<div slot="footer">
<DropiButton text="Cerrar" onOnClick={() => modalRef.current.hide()} />
</div>
</Modal>Ejemplo React (Declarativo con visible)
const [open, setOpen] = useState(false);
<DropiModal visible={open} header="Confirmar" onOnHide={() => setOpen(false)}>
<p>¿Estás seguro?</p>
</DropiModal><dropi-phone-input>
Input de teléfono con selector de país y sincronización nativa con dropi-core_front.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| name | string | '' | Nombre para formularios nativos |
| codArea | string | '57' | Código de área inicial (sin +) |
| ngModelPhone | string | '' | Valor del teléfono |
| phoneNumberPlaceholder | string | null | Placeholder del campo numérico |
| disabledInput | boolean | false | Deshabilita el input |
| isValidPhone | boolean | undefined | Estado de validación manual |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onDropiCodChange | string | Cambia el código de área |
| onDropiPhoneChange | string | Cambia el número de teléfono |
<dropi-country-selector>
Selector de países con buscador y flags.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| name | string | '' | Nombre para formularios nativos |
| label | string | '' | Label superior |
| placeholder | string | 'Seleccionar' | Texto por defecto |
| currentSelection | string | '' | Código ISO del país seleccionado (ej. 'CO') |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onDropiChangeSelect | CountryItem | Se selecciona un país |
<dropi-otp-send-code>
Campo de validación OTP (Código de seguridad).
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| name | string | '' | Nombre para formularios nativos |
| digitsCount | number | 6 | Cantidad de dígitos |
| engine | 'email' \| 'phone' | 'email' | Ícono y texto descriptivo |
| labelContact | string | '' | Correo o Teléfono al que se envió |
Eventos
| Evento React | e.detail | Cuándo |
|---|---|---|
| onCodeAccepted | string | El código se ha completado |
<dropi-date-picker>
Selector de fechas individual o por rangos.
Props
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| name | string | '' | Nombre para formularios nativos |
| label | string | '' | Label |
| isRange | boolean | false | Habilita selección de rango |
| placeholder | string | '' | Placeholder |
<dropi-toast>
Notificaciones tipo push con animaciones Lottie.
Mapeo de Severidad a Lottie:
success->success.jsonerror->failure.jsonwarn->warning.jsoninfo->question.json
Ejemplo React
const toastRef = useRef<any>(null);
const Toast = DropiToast as any;
<Toast ref={toastRef} position="top-right" />
<button onClick={() => toastRef.current.show({
severity: 'success',
summary: '¡Éxito!',
detail: 'Usuario creado.'
})}>
Lanzar Toast
</button>🏛️ Catálogo Completo de Componentes (65)
A continuación se listan todos los componentes disponibles en la librería, organizados por su función principal.
⌨️ Entradas y Formularios
| Componente | Función |
|---|---|
| <dropi-input> | Campo de texto versátil con validación |
| <dropi-select> | Selector avanzado (búsqueda, flags, multiselect) |
| <dropi-text-area> | Área de texto con contador |
| <dropi-phone-input> | Input de celular con selector de país |
| <dropi-country-selector> | Selector global de países |
| <dropi-checkbox> | Checkbox estilizado |
| <dropi-switch> | Interruptor On/Off |
| <dropi-radio-button> | Opción de selección única |
| <dropi-otp-send-code> | Campo de validación de código OTP |
| <dropi-date-picker> | Selector de fecha individual |
| <dropi-date-picker-range> | Selector de rangos de fecha |
| <dropi-color-picker> | Selector de colores |
| <dropi-city-selector> | Selector de ciudades por departamentos |
| <dropi-file-upload> | Zona de carga de archivos |
| <dropi-checkbox-selection-list> | Lista larga de checkboxes con buscador |
| <dropi-radio-selection-list> | Lista larga de radio buttons con buscador |
| <dropi-search> | Barra de búsqueda especializada |
📊 Visualización de Datos y Status
| Componente | Función |
|---|---|
| <dropi-table> | Tabla de datos profesional (sort, filter, paginador) |
| <dropi-badge> | Estado de cuenta/usuario |
| <dropi-badge-legacy> | Badges de contador y estados legacy |
| <dropi-tag> | Etiquetas de colores y semánticas |
| <dropi-tag-type-product> | Tags específicos para tipos de producto |
| <dropi-progress-bar> | Barra de progreso visual |
| <dropi-skeleton> | Placeholder de carga (text, circle, rect) |
| <dropi-avatars> | Foto de perfil o iniciales |
| <dropi-icon> | Renderizador de íconos del sistema |
| <dropi-ilustration-icon> | Ilustraciones de estado White Label |
| <dropi-logo> | Logotipos oficiales de Dropi |
| <dropi-chips> | Etiquetas con opción de cierre |
| <dropi-image-miniature> | Galería de miniaturas de imágenes |
| <dropi-country-flags> | Renderizador de banderas por código |
🔔 Feedback y Overlays
| Componente | Función |
|---|---|
| <dropi-modal> | Ventana de diálogo base |
| <dropi-alert-modal> | Modal de confirmación con Lottie |
| <dropi-toast> | Notificaciones push flotantes |
| <dropi-alert> | Banner de alerta (inline/flag) |
| <dropi-alert-legacy> | Alerta simple para compatibilidad Angular |
| <dropi-drawer> | Panel lateral deslizable |
| <dropi-tooltip> | Burbuja de información (hover) |
| <dropi-tooltip-v2> | Tooltip mejorado con posiciones avanzadas |
| <dropi-empty-state> | Pantalla "Sin resultados" con acciones |
| <dropi-banner-external> | Banner publicitario/informativo externo |
| <dropi-lottie-loader> | Cargador animado Lottie genérico |
🗺️ Navegación y Estructura
| Componente | Función |
|---|---|
| <dropi-navbar> | Barra de navegación superior |
| <dropi-sidebar> | Menú lateral de navegación |
| <dropi-tabs> | Sistema de pestañas con contadores |
| <dropi-breadcrumb> | Migas de pan para navegación |
| <dropi-paginator> | Control de páginas para listas |
| <dropi-steps> | Indicador de pasos horizontal |
| <dropi-vertical-steps> | Indicador de pasos vertical |
| <dropi-simple-stepper> | Stepper simplificado para flujos rápidos |
| <dropi-accordion> | Acordeón simple |
| <dropi-accordion-item> | Item individual de acordeón |
🎥 Multimedia y Otros
| Componente | Función |
|---|---|
| <dropi-media-player> | Reproductor de Audio/Video personalizado |
| <dropi-youtube-lazy-video> | Carga diferida de videos de YT |
| <dropi-image-overlay> | Visualizador de imagen a pantalla completa |
| <dropi-read-more> | Truncado de texto con "Ver más" |
| <dropi-time-line> | Línea de tiempo de eventos/tracking |
| <dropi-file-upload-progress-bar> | Barra de progreso individual por archivo |
| <dropi-carousel> | Carrusel de imágenes/contenido |
🤖 AI Skills & Automation
Esta librería está diseñada para ser mantenida por IAs (Claude Code, Cursor, Windsurf).
Skills Universales (Compatibles con Claude, Cursor, Windsurf)
Todos los skills han sido estandarizados en la carpeta /skills.
/install-dropi-ui—skills/install-dropi-ui/skill.md/update-context—skills/update-context/skill.md
Build (desarrollo)
npm run build # compilar
npm run start # dev con watch
npm test # unit tests