npm package: @juancamargodev/vue-dynamic-forms
Description: Una librería de componentes Vue 3 ligera, potente y totalmente declarativa para generar formularios complejos a partir de un simple objeto de configuración. Creada con TypeScript y Vite.
Author: juancamargodev
Latest version: 1.0.3

# Librería de Formularios Dinámicos para Vue 3

Una librería de componentes Vue 3 ligera, potente y totalmente declarativa para generar formularios complejos a partir de un simple objeto de configuración. Creada con TypeScript y Vite.

- **Totalmente Declarativa:** Define formularios enteros, incluyendo validaciones complejas y botones de acción, en un solo objeto de configuración.
- **Validación Integrada:** Utiliza Vuelidate por debajo para una validación robusta y extensible.
- **Componentes Personalizados:** Permite la carga dinámica de tus propios componentes Vue o de librerías de UI como PrimeVue.
- **Seguridad de Tipos:** Escrita en TypeScript para una experiencia de desarrollo sólida y con autocompletado.

## Instalación

```bash
npm install @juancamargodev/vue-dynamic-forms
```

## Uso Básico

Para usar la librería, importa el componente `DynamicForm` y su CSS en tu proyecto.

**1. Importa el CSS (ej. en `main.ts`):**

```typescript
import { createApp } from 'vue'
import App from './App.vue'
import '@juancamargodev/vue-dynamic-forms/style.css'; // <-- Importa los estilos

createApp(App).mount('#app')
```

**2. Usa el Componente en tu Aplicación:**

```vue
<template>
  <DynamicForm
    :schema="myFormConfig"
    v-model="formData"
    @submit="handleFormSubmit"
  />
  <pre>{{ formData }}</pre>
</template>

<script setup>
import { ref } from 'vue';
import { DynamicForm } from '@juancamargodev/vue-dynamic-forms';

const formData = ref({});

const myFormConfig = {
  fields: [
    {
      name: 'fullName',
      type: 'text',
      label: 'Nombre Completo',
      validationRules: {
        required: { message: 'El nombre es obligatorio.' }
      }
    }
  ],
  actions: [
    { name: 'submit', type: 'submit', label: 'Enviar', disabledWhenInvalid: true }
  ]
};

const handleFormSubmit = (data) => {
  console.log('Formulario enviado:', data);
  alert('¡Formulario enviado con éxito!');
};
</script>
```

## API de Configuración (`FormConfig`)

El componente se controla con un único objeto de configuración con la siguiente estructura:

* `layout?: object`: Define las clases CSS para el contenedor principal del grid.
* `fields: FieldConfig[]`: Un arreglo que define cada campo del formulario.
* `actions?: ActionConfig[]`: Un arreglo opcional para definir los botones de acción.

### `FieldConfig` (Configuración de Campo)

Cada objeto en el arreglo `fields` puede tener las siguientes propiedades:

| Propiedad | Tipo | Descripción |
| :--- | :--- | :--- |
| `name` | `string` | **Requerido.** Identificador único del campo. |
| `type` | `string` | **Requerido.** Tipo de campo (`text`, `password`, `select`, `checkbox`, `file`, `custom`, etc.). |
| `label` | `string` | Etiqueta de texto visible para el campo. |
| `defaultValue` | `any` | Valor inicial del campo. |
| `placeholder` | `string` | Texto de ayuda para campos de entrada. |
| `options` | `array` | Arreglo de opciones para `select` y `radio`. |
| `props` | `object` | Props adicionales para pasar al input o componente custom (ej. `{ size: 2097152 }`). |
| `fieldClasses` | `string` | Clases CSS para el `div` contenedor del campo (ideal para layout responsivo). |
| `validationRules` | `object` | Objeto que define las reglas de validación para el campo. |

### `ActionConfig` (Configuración de Acción)

Cada objeto en el arreglo `actions` define un botón:

| Propiedad | Tipo | Descripción |
| :--- | :--- | :--- |
| `name` | `string` | **Requerido.** Identificador único de la acción. |
| `type` | `string` | **Requerido.** Tipo de botón HTML (`submit`, `button`, `reset`). |
| `label` | `string` | Texto que se muestra en el botón. |
| `classes` | `string` | Clases CSS para estilizar el botón. |
| `disabledWhenInvalid` | `boolean` | Si es `true`, el botón se deshabilita si el formulario no es válido. |
| `emits` | `string` | Para `type: 'button'`, el nombre del evento a emitir. |


## Validaciones

Define las reglas en la propiedad `validationRules` de un `fieldConfig`.

**Reglas de Vuelidate por Nombre:**
```javascript
validationRules: {
  required: { message: 'Campo requerido.' },
  minLength: { value: 8, message: 'Mínimo 8 caracteres.' }
}
```

**Reglas Funcionales (ej. `sameAs`):**
```javascript
validationRules: {
  passwordConfirmation: {
    function: 'sameAs', // Nombre de la función del helper a usar
    value: 'password',   // Argumento (el nombre del otro campo)
    message: 'Las contraseñas no coinciden.'
  }
}
```

**Reglas 100% Personalizadas:**
```javascript
validationRules: {
  mustBeCool: {
    validator: (value) => value === 'cool',
    message: 'El valor debe ser "cool".'
  }
}
```

## Eventos

El componente `DynamicForm` emite los siguientes eventos:

* **`@submit(formData)`**: Se emite cuando se envía un formulario válido.
* **`@action(payload)`**: Se emite cuando se hace clic en un botón de `type: 'button'` que tiene la propiedad `emits`. El `payload` es `{ actionName: string, eventName: string }`.
* **`@update:modelValue(formData)`**: Emitido por `v-model`.