easy-forms-core
v1.5.2
Published
Librería agnóstica de framework para construir formularios dinámicos a partir de JSON usando Web Components
Maintainers
Readme
EasyFormsCore
EasyFormsCore es una librería agnóstica de framework para construir formularios dinámicos a partir de JSON usando Web Components.
Permite crear formularios completos únicamente describiendo un schema JSON.
Compatibilidad
Funciona en:
- Vue
- React
- Svelte
- Nuxt
- Next
- Astro
- HTML vanilla
No depende de ningún framework.
Instalación
bun add easy-forms-core
# o
npm install easy-forms-core
# o
pnpm add easy-forms-coreCampo map: EasyForms no incluye Leaflet. Si usas el tipo map, instala e importa Leaflet tú mismo: npm install leaflet, luego import 'leaflet' y import 'leaflet/dist/leaflet.css'. Ver documentación.
Uso Básico
HTML Vanilla
<easy-form id="form"></easy-form>import 'easy-forms-core'
const form = document.querySelector('#form')
form.schema = {
fields: [
{
type: 'text',
name: 'email',
label: 'Email',
validations: [
{ type: 'required' },
{ type: 'email' }
]
}
]
}
form.addEventListener('submit', (event) => {
console.log(event.detail)
})Con Rows y Datos Iniciales
<easy-form
id="form"
initialData='{"firstName": "Juan", "lastName": "Pérez", "email": "[email protected]"}'>
</easy-form>import 'easy-forms-core'
const form = document.querySelector('#form')
form.schema = {
fields: [
{
type: 'row',
name: 'nameRow',
fields: [
{
type: 'text',
name: 'firstName',
label: 'Nombre',
validations: [{ type: 'required' }]
},
{
type: 'text',
name: 'lastName',
label: 'Apellido',
validations: [{ type: 'required' }]
}
],
gap: '1rem',
align: 'stretch'
},
{
type: 'email',
name: 'email',
label: 'Email',
validations: [
{ type: 'required' },
{ type: 'email' }
]
}
]
}Slots con inserción por fila (row)
Puedes insertar contenido HTML personalizado en posiciones concretas del formulario usando hijos directos del componente con el atributo row. El índice es 0-based (cada campo o fila del schema cuenta como una posición). Usa row="-1" para insertar al final, antes del botón de envío.
| Valor | Comportamiento |
|--------|-----------------|
| row="0" | Antes del primer campo |
| row="1" | Entre el primer y el segundo campo |
| row="-1" | Al final del formulario (antes del submit) |
| Sin row o valor inválido | Se trata como -1 (al final) |
HTML Vanilla
<easy-form id="form">
<div row="0">Mensaje al inicio</div>
<div row="2">Mensaje después del segundo campo</div>
<div row="-1">Mensaje al final</div>
</easy-form>import 'easy-forms-core'
const form = document.querySelector('#form')
form.schema = {
fields: [
{ type: 'text', name: 'name', label: 'Nombre' },
{ type: 'email', name: 'email', label: 'Email' },
{ type: 'textarea', name: 'message', label: 'Mensaje' }
]
}React
import 'easy-forms-core'
function MyForm() {
return (
<easy-form schema={{ fields: [...] }}>
<div row="0">Contenido al inicio</div>
<div row="-1">Contenido al final</div>
</easy-form>
)
}Vue
<template>
<easy-form :schema="schema">
<div row="0">Contenido al inicio</div>
<div row="-1">Contenido al final</div>
</easy-form>
</template>Los slots son solo visuales: los inputs dentro de un slot no forman parte del estado ni del envío del formulario. En formularios por pasos (wizard), el índice row es relativo al paso actual.
React
import 'easy-forms-core'
function MyForm() {
return (
<easy-form
schema={{
fields: [
{ type: 'text', name: 'name', label: 'Nombre' }
]
}}
/>
)
}Vue
<script setup>
import 'easy-forms-core'
const schema = {
fields: [
{ type: 'text', name: 'name', label: 'Nombre' }
]
}
</script>
<template>
<easy-form :schema="schema" />
</template>Templates Pre-construidos
EasyForms incluye templates pre-construidos para formularios comunes. Puedes usar el atributo template en lugar de schema. Los templates y schemas son mutuamente excluyentes.
Uso Básico de Templates
<!-- HTML Vanilla -->
<easy-form template="login"></easy-form>import 'easy-forms-core'
const form = document.querySelector('easy-form')
form.template = 'register'// React
<easy-form template="contact" /><!-- Vue -->
<easy-form template="login" />Templates Disponibles
- login - Login form (email, password, remember me)
- register - Registration form (name, email, password, confirm password)
- otp - OTP verification (6-digit code)
- contact - Contact form (name, email, subject, message)
- password-reset - Password reset request (email)
- password-change - Change password (current, new, confirm)
- profile - User profile edit (name, email, phone, bio, avatar)
- checkout - Checkout form (billing address, payment method, shipping)
- feedback - Feedback form (rating, comment, email)
- subscription - Newsletter subscription (email, preferences)
- booking - Booking/reservation (date, time, guests, special requests)
- review - Review/rating form (rating, title, comment)
Extender Templates
Puedes extender un template agregando campos adicionales usando el atributo template-extend:
<easy-form
template="contact"
template-extend='[{"type": "text", "name": "phone", "label": "Phone", "validations": [{"type": "required"}]}]'>
</easy-form>O programáticamente:
import { extendTemplate } from 'easy-forms-core'
const extendedSchema = extendTemplate('register', [
{
type: 'text',
name: 'company',
label: 'Company',
validations: [{ type: 'required' }]
}
])
form.schema = extendedSchemaMutua Exclusividad
Los atributos template y schema son mutuamente excluyentes. Si estableces uno, el otro será removido automáticamente:
// Si estableces template, schema será removido
form.template = 'login'
// schema ahora es null
// Si estableces schema, template será removido
form.schema = { fields: [...] }
// template ahora es nullPersonalización de Estilos
EasyFormsCore utiliza variables CSS que puedes sobrescribir para personalizar completamente la apariencia de tus formularios. Todas las variables están definidas en el scope del componente (:host), lo que permite un control total sobre los colores y estilos.
Variables CSS Disponibles
Puedes sobrescribir estas variables CSS para personalizar los colores de tu formulario:
easy-form {
--easy-form-primary: #007bff; /* Color principal (botones, focus, etc.) */
--easy-form-secondary: #6c757d; /* Color secundario */
--easy-form-error: #dc3545; /* Color de error */
--easy-form-success: #28a745; /* Color de éxito */
--easy-form-text: #212529; /* Color del texto */
--easy-form-label-color: #212529; /* Color de las etiquetas */
--easy-form-border: #ddd; /* Color de los bordes */
--easy-form-background: #ffffff; /* Color de fondo */
}Ejemplo de Personalización de Colores
<style>
easy-form {
--easy-form-primary: #8b5cf6;
--easy-form-secondary: #64748b;
--easy-form-error: #ef4444;
--easy-form-success: #10b981;
--easy-form-text: #1e293b;
--easy-form-label-color: #334155;
--easy-form-border: #e2e8f0;
--easy-form-background: #ffffff;
}
</style>
<easy-form id="form"></easy-form>Sobrescribir Estilos con Clases CSS
Puedes sobrescribir cualquier estilo usando las clases CSS del componente. Todas las clases utilizan el prefijo easy-form- para evitar conflictos.
Clases Principales
.easy-form-field- Contenedor de cada campo.easy-form-label- Etiquetas de los campos.easy-form-required- Indicador de campo requerido (asterisco).easy-form-input-error- Input con error.easy-form-error- Mensaje de error.easy-form-description- Descripción del campo.easy-form-submit- Botón de envío
Clases de Grupos y Filas
.easy-form-group- Contenedor de grupo de campos.easy-form-group-label- Etiqueta del grupo.easy-form-row- Fila horizontal de campos.easy-form-array- Contenedor de array dinámico.easy-form-array-item- Item individual del array.easy-form-array-add- Botón para agregar items.easy-form-array-remove- Botón para remover items
Clases de Wizard/Steps
.easy-form-wizard- Contenedor del wizard.easy-form-wizard-steps- Contenedor de los pasos.easy-form-wizard-step- Paso individual.easy-form-wizard-step.active- Paso activo.easy-form-wizard-step.completed- Paso completado.easy-form-wizard-nav- Navegación del wizard.easy-form-wizard-prev- Botón anterior.easy-form-wizard-next- Botón siguiente.easy-form-wizard-fields- Contenedor de campos del paso actual
Clases de Inputs Especiales
.easy-form-radio-group- Grupo de radio buttons.easy-form-radio-option- Opción de radio.easy-form-radio-label- Etiqueta de radio.easy-form-label-checkbox- Etiqueta de checkbox.easy-form-label-switch- Etiqueta de switch.easy-form-quantity-container- Contenedor de quantity input.easy-form-quantity-wrapper- Wrapper del quantity.easy-form-quantity-btn- Botón +/- del quantity.easy-form-quantity-input- Input del quantity.easy-form-accordion-select-container- Contenedor de accordion select.easy-form-accordion-item- Item del accordion.easy-form-accordion-item.selected- Item seleccionado.easy-form-accordion-item.open- Item abierto.easy-form-accordion-header- Header del accordion.easy-form-accordion-content- Contenido del accordion.easy-form-image-grid-container- Contenedor de image grid.easy-form-image-grid-item- Item del grid.easy-form-image-grid-item.selected- Item seleccionado.easy-form-otp-container- Contenedor de OTP.easy-form-otp-input- Input individual de OTP
Clases de Estado
.easy-form-field-hidden- Campo oculto.easy-form-field-disabled- Campo deshabilitado
Ejemplo de Sobrescritura de Estilos
<style>
/* Personalizar colores con variables CSS */
easy-form {
--easy-form-primary: #6366f1;
--easy-form-error: #f43f5e;
}
/* Sobrescribir estilos específicos */
easy-form .easy-form-label {
font-weight: 700;
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
easy-form .easy-form-submit {
border-radius: 12px;
padding: 0.875rem 2rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.1em;
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);
}
easy-form .easy-form-submit:hover {
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);
}
/* Personalizar inputs */
easy-form input:not([type="checkbox"]):not([type="radio"]),
easy-form textarea,
easy-form select {
border-radius: 8px;
border-width: 2px;
padding: 0.75rem 1rem;
transition: all 0.2s ease;
}
easy-form input:focus,
easy-form textarea:focus,
easy-form select:focus {
outline: none;
box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1);
}
</style>
<easy-form id="form"></easy-form>Notas Importantes
Especificidad: Los estilos del componente tienen especificidad media. Si necesitas sobrescribir estilos con
!important, puedes hacerlo, pero se recomienda usar variables CSS cuando sea posible.Shadow DOM: El componente utiliza Shadow DOM, por lo que los estilos globales no afectan directamente al contenido interno. Debes usar el selector
easy-formo las variables CSS.Variables CSS: Las variables CSS son la forma recomendada de personalizar colores, ya que se propagan correctamente dentro del Shadow DOM.
Temas: Los temas predefinidos (plano, tradicional, material, etc.) también respetan las variables CSS que definas, por lo que puedes cambiar los colores manteniendo el estilo del tema.
Características
- Web Component nativo
- Escrito en TypeScript
- JSON → Form automático
- Templates pre-construidos - 12 templates comunes listos para usar
- Validaciones integradas
- Steps / wizard forms
- Formularios anidados
- Arrays dinámicos
- Rows (filas horizontales) - Agrupa campos en filas
- Slots (row) - Inserta contenido HTML en posiciones concretas del formulario
- Campo password - Opciones
showToggle(ver/ocultar) ycharacterSeparated(entrada por caracteres, tipo OTP) - Datos iniciales - Carga valores iniciales desde datos externos
- Componentes visuales personalizables
- Eventos de submit, change y error
- Testing friendly
- Listo para producción
Desarrollo
# Instalar dependencias
bun install
# Desarrollo con watch
bun run dev
# Desarrollo de documentación
bun run dev:docs
# Build
bun run build
# Tests
bun testLicencia
MIT
