easy-forms-core 1.0.2 → 1.0.4

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/schema-parser.ts","../src/utils/styles.ts","../src/utils/masks.ts","../src/utils/index.ts","../src/core/validation-engine.ts","../src/core/condition-engine.ts","../src/core/state-manager.ts","../src/components/inputs/base-input.ts","../src/utils/mask-helpers.ts","../src/core/mask-engine.ts","../src/components/inputs/text-input.ts","../src/components/inputs/number-input.ts","../src/components/inputs/textarea-input.ts","../src/components/inputs/select-input.ts","../src/components/inputs/checkbox-input.ts","../src/components/inputs/radio-input.ts","../src/components/inputs/switch-input.ts","../src/components/inputs/date-input.ts","../src/components/inputs/file-input.ts","../src/components/inputs/index.ts","../src/components/easy-form.ts"],"sourcesContent":["import type { FormSchema, Field, Step } from '../types'\n\n/**\n * Parser del schema JSON\n */\nexport class SchemaParser {\n /**\n * Parsea y valida un schema\n */\n parse(schema: FormSchema): ParsedSchema {\n if (!schema) {\n throw new Error('Schema es requerido')\n }\n\n // Validar que tenga fields o steps\n if (!schema.fields && !schema.steps) {\n throw new Error('Schema debe tener fields o steps')\n }\n\n // Si tiene steps, validar que todos los steps tengan fields\n if (schema.steps) {\n for (const step of schema.steps) {\n if (!step.fields || step.fields.length === 0) {\n throw new Error('Cada step debe tener al menos un field')\n }\n }\n }\n\n // Normalizar campos\n const normalizedFields = schema.fields\n ? this.normalizeFields(schema.fields)\n : []\n\n const normalizedSteps = schema.steps\n ? schema.steps.map((step) => ({\n ...step,\n fields: this.normalizeFields(step.fields),\n }))\n : undefined\n\n return {\n fields: normalizedFields,\n steps: normalizedSteps,\n isWizard: Boolean(schema.steps && schema.steps.length > 0),\n }\n }\n\n /**\n * Normaliza y valida campos\n */\n private normalizeFields(fields: Field[]): Field[] {\n return fields.map((field, index) => {\n // Validar que tenga type y name\n if (!field.type) {\n throw new Error(`Field en índice ${index} debe tener un type`)\n }\n if (!field.name) {\n throw new Error(`Field en índice ${index} debe tener un name`)\n }\n\n // Validar tipos específicos\n this.validateFieldType(field, index)\n\n // Aplicar valores por defecto\n return this.applyDefaults(field)\n })\n }\n\n /**\n * Valida el tipo de campo\n */\n private validateFieldType(field: Field, index: number): void {\n const validTypes = [\n 'text',\n 'email',\n 'number',\n 'password',\n 'textarea',\n 'select',\n 'checkbox',\n 'radio',\n 'switch',\n 'date',\n 'file',\n 'array',\n 'group',\n 'custom',\n ]\n\n if (!validTypes.includes(field.type)) {\n throw new Error(\n `Field en índice ${index} tiene un type inválido: ${field.type}`\n )\n }\n\n // Validaciones específicas por tipo\n switch (field.type) {\n case 'select':\n case 'radio':\n if (!('options' in field) || !field.options || field.options.length === 0) {\n throw new Error(\n `Field \"${field.name}\" de tipo ${field.type} debe tener options`\n )\n }\n break\n case 'array':\n if (!('itemSchema' in field) || !field.itemSchema) {\n throw new Error(\n `Field \"${field.name}\" de tipo array debe tener itemSchema`\n )\n }\n break\n case 'group':\n if (!('fields' in field) || !field.fields || field.fields.length === 0) {\n throw new Error(\n `Field \"${field.name}\" de tipo group debe tener fields`\n )\n }\n break\n }\n }\n\n /**\n * Aplica valores por defecto a un campo\n */\n private applyDefaults(field: Field): Field {\n const defaults: any = {\n disabled: false,\n hidden: false,\n }\n\n // Aplicar defaults específicos por tipo\n switch (field.type) {\n case 'checkbox':\n case 'switch':\n if (!('checked' in field)) {\n defaults.checked = false\n }\n break\n case 'select':\n if (!('multiple' in field)) {\n defaults.multiple = false\n }\n break\n case 'file':\n if (!('multiple' in field)) {\n defaults.multiple = false\n }\n break\n }\n\n return { ...defaults, ...field } as Field\n }\n\n /**\n * Obtiene todos los campos de un schema (incluyendo nested)\n */\n getAllFields(schema: FormSchema): Field[] {\n const parsed = this.parse(schema)\n const allFields: Field[] = []\n\n const extractFields = (fields: Field[]) => {\n for (const field of fields) {\n allFields.push(field)\n if (field.type === 'group' && 'fields' in field) {\n extractFields(field.fields)\n }\n if (field.type === 'array' && 'itemSchema' in field && field.itemSchema.fields) {\n extractFields(field.itemSchema.fields)\n }\n }\n }\n\n if (parsed.fields) {\n extractFields(parsed.fields)\n }\n\n if (parsed.steps) {\n for (const step of parsed.steps) {\n extractFields(step.fields)\n }\n }\n\n return allFields\n }\n}\n\n/**\n * Schema parseado\n */\nexport interface ParsedSchema {\n fields: Field[]\n steps?: Step[]\n isWizard: boolean\n}\n","import type { FormTheme, FormColors } from '../types'\n\n/**\n * Colores por defecto\n */\nconst defaultColors: Required<FormColors> = {\n primary: '#007bff',\n secondary: '#6c757d',\n error: '#dc3545',\n success: '#28a745',\n text: '#212529',\n border: '#ddd',\n background: '#ffffff',\n}\n\n/**\n * Obtiene los colores con valores por defecto\n */\nexport function getColors(colors?: FormColors): Required<FormColors> {\n return { ...defaultColors, ...colors }\n}\n\n/**\n * Genera estilos CSS para un tema específico\n */\nexport function getThemeStyles(theme: FormTheme, colors: Required<FormColors>): string {\n const baseStyles = getBaseStyles(colors)\n const themeStyles = getThemeSpecificStyles(theme, colors)\n return baseStyles + themeStyles\n}\n\n/**\n * Estilos base comunes a todos los temas\n */\nfunction getBaseStyles(colors: Required<FormColors>): string {\n return `\n :host {\n display: block;\n --easy-form-primary: ${colors.primary};\n --easy-form-secondary: ${colors.secondary};\n --easy-form-error: ${colors.error};\n --easy-form-success: ${colors.success};\n --easy-form-text: ${colors.text};\n --easy-form-border: ${colors.border};\n --easy-form-background: ${colors.background};\n }\n .easy-form-field {\n margin-bottom: 1rem;\n }\n .easy-form-label {\n display: block;\n margin-bottom: 0.5rem;\n font-weight: 500;\n color: var(--easy-form-text);\n }\n .easy-form-required {\n color: var(--easy-form-error);\n }\n .easy-form-input-error {\n border-color: var(--easy-form-error) !important;\n }\n .easy-form-error {\n color: var(--easy-form-error);\n font-size: 0.875rem;\n margin-top: 0.25rem;\n }\n .easy-form-description {\n font-size: 0.875rem;\n color: #666;\n margin-top: 0.25rem;\n }\n .easy-form-submit {\n padding: 0.5rem 1rem;\n background: var(--easy-form-primary);\n color: white;\n border: none;\n cursor: pointer;\n font-size: 1rem;\n transition: all 0.2s ease;\n }\n .easy-form-submit:hover {\n opacity: 0.9;\n }\n .easy-form-submit:active {\n transform: scale(0.98);\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n width: 100%;\n padding: 0.5rem;\n font-size: 1rem;\n color: var(--easy-form-text);\n background: var(--easy-form-background);\n transition: all 0.2s ease;\n }\n input[type=\"checkbox\"],\n input[type=\"radio\"] {\n width: 18px !important;\n height: 18px !important;\n min-width: 18px !important;\n min-height: 18px !important;\n max-width: 18px !important;\n margin: 0;\n padding: 0;\n cursor: pointer;\n accent-color: var(--easy-form-primary);\n flex-shrink: 0;\n }\n input:focus, textarea:focus, select:focus {\n outline: none;\n }\n .easy-form-group {\n padding: 1rem;\n margin-bottom: 1rem;\n }\n .easy-form-radio-group {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n margin-top: 0.5rem;\n }\n .easy-form-radio-option {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.5rem;\n border-radius: 6px;\n transition: background-color 0.2s ease;\n }\n .easy-form-radio-option:hover {\n background-color: rgba(0, 0, 0, 0.03);\n }\n .easy-form-radio-option input[type=\"radio\"] {\n margin: 0;\n flex-shrink: 0;\n }\n .easy-form-radio-label {\n cursor: pointer;\n user-select: none;\n color: var(--easy-form-text);\n font-weight: 400;\n }\n .easy-form-label-checkbox,\n .easy-form-label-switch {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n cursor: pointer;\n user-select: none;\n padding: 0.5rem;\n border-radius: 6px;\n transition: background-color 0.2s ease;\n color: var(--easy-form-text);\n }\n .easy-form-label-checkbox input[type=\"checkbox\"],\n .easy-form-label-switch input[type=\"checkbox\"] {\n margin: 0;\n flex-shrink: 0;\n }\n .easy-form-label-checkbox:hover,\n .easy-form-label-switch:hover {\n background-color: rgba(0, 0, 0, 0.03);\n }\n .easy-form-wizard-steps {\n display: flex;\n gap: 1rem;\n margin-bottom: 2rem;\n }\n .easy-form-wizard-step {\n padding: 0.5rem 1rem;\n transition: all 0.2s ease;\n }\n .easy-form-wizard-step.active {\n background: var(--easy-form-primary);\n color: white;\n }\n .easy-form-wizard-step.completed {\n background: var(--easy-form-success);\n color: white;\n }\n .easy-form-wizard-nav {\n display: flex;\n gap: 1rem;\n margin-top: 1rem;\n }\n .easy-form-array-item {\n padding: 1rem;\n margin-bottom: 1rem;\n }\n .easy-form-array-add,\n .easy-form-array-remove {\n padding: 0.25rem 0.5rem;\n background: var(--easy-form-secondary);\n color: white;\n border: none;\n cursor: pointer;\n font-size: 0.875rem;\n transition: all 0.2s ease;\n }\n .easy-form-array-remove {\n background: var(--easy-form-error);\n }\n .easy-form-array-add:hover,\n .easy-form-array-remove:hover {\n opacity: 0.9;\n }\n `\n}\n\n/**\n * Estilos específicos por tema\n */\nfunction getThemeSpecificStyles(theme: FormTheme, colors: Required<FormColors>): string {\n switch (theme) {\n case 'plano':\n return getPlanoStyles(colors)\n case 'tradicional':\n return getTradicionalStyles(colors)\n case 'material':\n return getMaterialStyles(colors)\n case 'rounded-shadow':\n return getRoundedShadowStyles(colors)\n case 'lines':\n return getLinesStyles(colors)\n default:\n return getPlanoStyles(colors)\n }\n}\n\n/**\n * Estilo Plano - Minimalista sin bordes ni sombras\n */\nfunction getPlanoStyles(_colors: Required<FormColors>): string {\n return `\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n border: none;\n border-bottom: 2px solid var(--easy-form-border);\n border-radius: 0;\n padding: 0.75rem 0;\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]):focus, textarea:focus, select:focus {\n border-bottom-color: var(--easy-form-primary);\n }\n .easy-form-submit {\n border-radius: 0;\n font-weight: 600;\n }\n .easy-form-group {\n border: none;\n border-bottom: 1px solid var(--easy-form-border);\n border-radius: 0;\n }\n .easy-form-wizard-step {\n border: none;\n border-bottom: 2px solid var(--easy-form-border);\n border-radius: 0;\n }\n .easy-form-array-item {\n border: none;\n border-bottom: 1px solid var(--easy-form-border);\n border-radius: 0;\n }\n `\n}\n\n/**\n * Estilo Tradicional - Bordes clásicos y estructura tradicional\n */\nfunction getTradicionalStyles(_colors: Required<FormColors>): string {\n return `\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n border: 2px solid var(--easy-form-border);\n border-radius: 4px;\n padding: 0.625rem;\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]):focus, textarea:focus, select:focus {\n border-color: var(--easy-form-primary);\n box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);\n }\n .easy-form-submit {\n border-radius: 4px;\n font-weight: 500;\n }\n .easy-form-group {\n border: 2px solid var(--easy-form-border);\n border-radius: 4px;\n background: #f8f9fa;\n }\n .easy-form-wizard-step {\n border: 2px solid var(--easy-form-border);\n border-radius: 4px;\n background: #f8f9fa;\n }\n .easy-form-wizard-step.active {\n border-color: var(--easy-form-primary);\n }\n .easy-form-array-item {\n border: 2px solid var(--easy-form-border);\n border-radius: 4px;\n background: #f8f9fa;\n }\n `\n}\n\n/**\n * Estilo Material - Inspirado en Material Design\n */\nfunction getMaterialStyles(_colors: Required<FormColors>): string {\n return `\n .easy-form-label {\n font-size: 0.875rem;\n font-weight: 500;\n margin-bottom: 0.25rem;\n color: rgba(0, 0, 0, 0.6);\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n border: none;\n border-bottom: 1px solid rgba(0, 0, 0, 0.42);\n border-radius: 4px 4px 0 0;\n padding: 0.75rem 0.75rem 0.5rem 0.75rem;\n background: transparent;\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]):focus, textarea:focus, select:focus {\n border-bottom-color: var(--easy-form-primary);\n border-bottom-width: 2px;\n padding-bottom: calc(0.5rem - 1px);\n }\n .easy-form-submit {\n border-radius: 4px;\n text-transform: uppercase;\n font-weight: 500;\n letter-spacing: 0.5px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n }\n .easy-form-submit:hover {\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);\n }\n .easy-form-group {\n border: none;\n border-radius: 4px;\n background: #f5f5f5;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);\n }\n .easy-form-wizard-step {\n border: none;\n border-radius: 4px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);\n }\n .easy-form-array-item {\n border: none;\n border-radius: 4px;\n background: #f5f5f5;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);\n }\n `\n}\n\n/**\n * Estilo Rounded Shadow - Bordes redondeados con sombras\n */\nfunction getRoundedShadowStyles(_colors: Required<FormColors>): string {\n return `\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n border: 1px solid var(--easy-form-border);\n border-radius: 12px;\n padding: 0.75rem 1rem;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]):focus, textarea:focus, select:focus {\n border-color: var(--easy-form-primary);\n box-shadow: 0 4px 12px rgba(0, 123, 255, 0.15);\n transform: translateY(-1px);\n }\n .easy-form-submit {\n border-radius: 12px;\n font-weight: 600;\n box-shadow: 0 4px 12px rgba(0, 123, 255, 0.3);\n }\n .easy-form-submit:hover {\n box-shadow: 0 6px 16px rgba(0, 123, 255, 0.4);\n transform: translateY(-2px);\n }\n .easy-form-group {\n border: 1px solid var(--easy-form-border);\n border-radius: 16px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n background: var(--easy-form-background);\n }\n .easy-form-wizard-step {\n border: 1px solid var(--easy-form-border);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n .easy-form-wizard-step.active {\n box-shadow: 0 4px 16px rgba(0, 123, 255, 0.3);\n }\n .easy-form-array-item {\n border: 1px solid var(--easy-form-border);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n background: var(--easy-form-background);\n }\n `\n}\n\n/**\n * Estilo Lines - Solo líneas como separadores\n */\nfunction getLinesStyles(_colors: Required<FormColors>): string {\n return `\n .easy-form-field {\n border-bottom: 1px solid var(--easy-form-border);\n padding-bottom: 1rem;\n margin-bottom: 1.5rem;\n }\n .easy-form-field:last-child {\n border-bottom: none;\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n border: none;\n border-radius: 0;\n padding: 0.5rem 0;\n background: transparent;\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]):focus, textarea:focus, select:focus {\n border-bottom: 2px solid var(--easy-form-primary);\n padding-bottom: calc(0.5rem - 1px);\n }\n .easy-form-submit {\n border-radius: 0;\n border-bottom: 3px solid var(--easy-form-primary);\n background: transparent;\n color: var(--easy-form-primary);\n font-weight: 600;\n padding: 0.75rem 0;\n }\n .easy-form-submit:hover {\n background: rgba(0, 123, 255, 0.05);\n }\n .easy-form-group {\n border: none;\n border-bottom: 2px solid var(--easy-form-border);\n border-radius: 0;\n padding-bottom: 1rem;\n }\n .easy-form-wizard-step {\n border: none;\n border-bottom: 3px solid var(--easy-form-border);\n border-radius: 0;\n background: transparent;\n }\n .easy-form-wizard-step.active {\n border-bottom-color: var(--easy-form-primary);\n background: transparent;\n color: var(--easy-form-primary);\n }\n .easy-form-wizard-step.completed {\n border-bottom-color: var(--easy-form-success);\n background: transparent;\n color: var(--easy-form-success);\n }\n .easy-form-array-item {\n border: none;\n border-bottom: 1px solid var(--easy-form-border);\n border-radius: 0;\n }\n `\n}\n","import type { PredefinedMask, CustomMask } from '../types'\n\n/**\n * Máscaras predefinidas\n */\nexport const PREDEFINED_MASKS: Record<PredefinedMask, CustomMask> = {\n 'phone': {\n pattern: '(999) 999-9999',\n placeholder: '_',\n },\n 'phone-us': {\n pattern: '(999) 999-9999',\n placeholder: '_',\n },\n 'phone-international': {\n pattern: '+99 999 999 9999',\n placeholder: '_',\n },\n 'date': {\n pattern: '99/99/9999',\n placeholder: '_',\n },\n 'date-us': {\n pattern: '99/99/9999',\n placeholder: '_',\n },\n 'date-eu': {\n pattern: '99-99-9999',\n placeholder: '_',\n },\n 'credit-card': {\n pattern: '9999 9999 9999 9999',\n placeholder: '_',\n },\n 'ssn': {\n pattern: '999-99-9999',\n placeholder: '_',\n },\n 'zip-code': {\n pattern: '99999',\n placeholder: '_',\n },\n 'currency': {\n pattern: '$999,999.99',\n placeholder: '_',\n transform: (value: string) => {\n // Remover caracteres no numéricos excepto punto decimal\n const cleaned = value.replace(/[^\\d.]/g, '')\n const num = parseFloat(cleaned) || 0\n return num.toFixed(2)\n },\n },\n 'percentage': {\n pattern: '999%',\n placeholder: '_',\n transform: (value: string) => {\n const cleaned = value.replace(/[^\\d]/g, '')\n return cleaned\n },\n },\n 'time': {\n pattern: '99:99',\n placeholder: '_',\n },\n 'datetime': {\n pattern: '99/99/9999 99:99',\n placeholder: '_',\n },\n}\n\n/**\n * Obtiene una máscara predefinida\n */\nexport function getPredefinedMask(type: PredefinedMask): CustomMask {\n return PREDEFINED_MASKS[type]\n}\n","/**\n * Utilidades generales\n */\n\n/**\n * Convierte un valor a string para atributos HTML\n */\nexport function attributeValue(value: any): string {\n if (value === null || value === undefined) {\n return ''\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false'\n }\n if (typeof value === 'object') {\n return JSON.stringify(value)\n }\n return String(value)\n}\n\n/**\n * Parsea un valor desde un atributo HTML\n */\nexport function parseAttributeValue(value: string | null): any {\n if (!value) {\n return null\n }\n try {\n return JSON.parse(value)\n } catch {\n return value\n }\n}\n\n/**\n * Genera un ID único\n */\nexport function generateId(prefix = 'ef'): string {\n return `${prefix}-${Math.random().toString(36).substr(2, 9)}`\n}\n\n/**\n * Obtiene el valor anidado de un objeto usando notación de punto\n */\nexport function getNestedValue(obj: Record<string, any>, path: string): any {\n return path.split('.').reduce((current, key) => current?.[key], obj)\n}\n\n/**\n * Establece un valor anidado en un objeto usando notación de punto\n */\nexport function setNestedValue(\n obj: Record<string, any>,\n path: string,\n value: any\n): void {\n const keys = path.split('.')\n const lastKey = keys.pop()!\n const target = keys.reduce((current, key) => {\n if (!current[key] || typeof current[key] !== 'object') {\n current[key] = {}\n }\n return current[key]\n }, obj)\n target[lastKey] = value\n}\n\n/**\n * Valida si un email es válido\n */\nexport function isValidEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n return emailRegex.test(email)\n}\n\n/**\n * Sanitiza un string para usar como ID de HTML\n */\nexport function sanitizeId(str: string): string {\n return str.replace(/[^a-zA-Z0-9-_]/g, '-')\n}\n\n// Exportar funciones de estilos\nexport { getThemeStyles, getColors } from './styles'\n\n// Exportar máscaras\nexport { PREDEFINED_MASKS, getPredefinedMask } from './masks'\n","import type {\n Validation,\n Field,\n MinLengthValidation,\n MaxLengthValidation,\n MinValidation,\n MaxValidation,\n CustomValidation,\n} from '../types'\nimport { isValidEmail } from '../utils'\n\n/**\n * Resultado de una validación\n */\nexport interface ValidationResult {\n isValid: boolean\n message?: string\n}\n\n/**\n * Motor de validaciones\n */\nexport class ValidationEngine {\n /**\n * Valida un campo con todas sus validaciones\n */\n async validateField(\n field: Field,\n value: any\n ): Promise<string[]> {\n return this.validateFieldWithValidations(field, value, field.validations || [])\n }\n\n /**\n * Valida un campo con validaciones específicas\n */\n async validateFieldWithValidations(\n _field: Field,\n value: any,\n validations: Validation[]\n ): Promise<string[]> {\n const errors: string[] = []\n\n if (!validations || validations.length === 0) {\n return errors\n }\n\n for (const validation of validations) {\n const result = await this.validateValue(validation, value)\n if (!result.isValid) {\n errors.push(result.message || this.getDefaultMessage(validation))\n }\n }\n\n return errors\n }\n\n /**\n * Valida un valor con una validación específica\n */\n private async validateValue(\n validation: Validation,\n value: any\n ): Promise<ValidationResult> {\n switch (validation.type) {\n case 'required':\n return this.validateRequired(value)\n case 'email':\n return this.validateEmail(value)\n case 'minLength':\n return this.validateMinLength(value, validation.value)\n case 'maxLength':\n return this.validateMaxLength(value, validation.value)\n case 'min':\n return this.validateMin(value, validation.value)\n case 'max':\n return this.validateMax(value, validation.value)\n case 'pattern':\n return this.validatePattern(value, validation.value)\n case 'custom':\n return await this.validateCustom(value, validation)\n default:\n return { isValid: true }\n }\n }\n\n /**\n * Valida campo requerido\n */\n private validateRequired(value: any): ValidationResult {\n const isValid =\n value !== null &&\n value !== undefined &&\n value !== '' &&\n !(Array.isArray(value) && value.length === 0)\n return {\n isValid,\n message: isValid ? undefined : 'Este campo es requerido',\n }\n }\n\n /**\n * Valida email\n */\n private validateEmail(value: any): ValidationResult {\n if (!value) {\n return { isValid: true } // Si está vacío, required debe manejarlo\n }\n const isValid = typeof value === 'string' && isValidEmail(value)\n return {\n isValid,\n message: isValid ? undefined : 'Debe ser un email válido',\n }\n }\n\n /**\n * Valida longitud mínima\n */\n private validateMinLength(\n value: any,\n minLength: number\n ): ValidationResult {\n if (!value) {\n return { isValid: true }\n }\n const str = String(value)\n const isValid = str.length >= minLength\n return {\n isValid,\n message: isValid\n ? undefined\n : `Debe tener al menos ${minLength} caracteres`,\n }\n }\n\n /**\n * Valida longitud máxima\n */\n private validateMaxLength(\n value: any,\n maxLength: number\n ): ValidationResult {\n if (!value) {\n return { isValid: true }\n }\n const str = String(value)\n const isValid = str.length <= maxLength\n return {\n isValid,\n message: isValid\n ? undefined\n : `Debe tener máximo ${maxLength} caracteres`,\n }\n }\n\n /**\n * Valida valor mínimo\n */\n private validateMin(value: any, min: number): ValidationResult {\n if (value === null || value === undefined || value === '') {\n return { isValid: true }\n }\n const num = Number(value)\n const isValid = !isNaN(num) && num >= min\n return {\n isValid,\n message: isValid ? undefined : `Debe ser mayor o igual a ${min}`,\n }\n }\n\n /**\n * Valida valor máximo\n */\n private validateMax(value: any, max: number): ValidationResult {\n if (value === null || value === undefined || value === '') {\n return { isValid: true }\n }\n const num = Number(value)\n const isValid = !isNaN(num) && num <= max\n return {\n isValid,\n message: isValid ? undefined : `Debe ser menor o igual a ${max}`,\n }\n }\n\n /**\n * Valida patrón regex\n */\n private validatePattern(value: any, pattern: string | RegExp): ValidationResult {\n if (!value) {\n return { isValid: true }\n }\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern\n const isValid = regex.test(String(value))\n return {\n isValid,\n message: isValid ? undefined : 'El formato no es válido',\n }\n }\n\n /**\n * Valida con función personalizada\n */\n private async validateCustom(\n value: any,\n validation: CustomValidation\n ): Promise<ValidationResult> {\n try {\n const result = await validation.validator(value)\n return {\n isValid: Boolean(result),\n message: result ? undefined : validation.message || 'Validación fallida',\n }\n } catch (error) {\n return {\n isValid: false,\n message: validation.message || 'Error en la validación',\n }\n }\n }\n\n /**\n * Obtiene mensaje por defecto para una validación\n */\n private getDefaultMessage(validation: Validation): string {\n switch (validation.type) {\n case 'required':\n return 'Este campo es requerido'\n case 'email':\n return 'Debe ser un email válido'\n case 'minLength':\n return `Debe tener al menos ${(validation as MinLengthValidation).value} caracteres`\n case 'maxLength':\n return `Debe tener máximo ${(validation as MaxLengthValidation).value} caracteres`\n case 'min':\n return `Debe ser mayor o igual a ${(validation as MinValidation).value}`\n case 'max':\n return `Debe ser menor o igual a ${(validation as MaxValidation).value}`\n case 'pattern':\n return 'El formato no es válido'\n case 'custom':\n return 'Validación fallida'\n default:\n return 'Campo inválido'\n }\n }\n\n /**\n * Valida todos los campos de un formulario\n */\n async validateForm(\n fields: Field[],\n values: Record<string, any>\n ): Promise<Record<string, string[]>> {\n const errors: Record<string, string[]> = {}\n\n for (const field of fields) {\n const value = values[field.name]\n const fieldErrors = await this.validateField(field, value)\n if (fieldErrors.length > 0) {\n errors[field.name] = fieldErrors\n }\n }\n\n return errors\n }\n}\n","import type {\n FieldCondition,\n FieldDependencies,\n ConditionOperator,\n} from '../types'\n\n/**\n * Motor de evaluación de condiciones\n */\nexport class ConditionEngine {\n /**\n * Evalúa una condición individual\n */\n evaluateCondition(\n condition: FieldCondition,\n formValues: Record<string, any>\n ): boolean {\n const fieldValue = this.getFieldValue(condition.field, formValues)\n return this.compareValues(fieldValue, condition.operator, condition.value)\n }\n\n /**\n * Evalúa múltiples condiciones (AND por defecto, soportar OR)\n */\n evaluateConditions(\n conditions: FieldCondition | FieldCondition[],\n formValues: Record<string, any>,\n logic: 'and' | 'or' = 'and'\n ): boolean {\n const conditionsArray = Array.isArray(conditions) ? conditions : [conditions]\n\n if (conditionsArray.length === 0) {\n return true\n }\n\n if (logic === 'and') {\n return conditionsArray.every((condition) =>\n this.evaluateCondition(condition, formValues)\n )\n } else {\n return conditionsArray.some((condition) =>\n this.evaluateCondition(condition, formValues)\n )\n }\n }\n\n /**\n * Evalúa dependencias de un campo\n */\n evaluateDependencies(\n dependencies: FieldDependencies,\n formValues: Record<string, any>\n ): {\n visible: boolean\n enabled: boolean\n required: boolean\n } {\n let visible = true\n let enabled = true\n let required = false\n\n // Evaluar show/hide\n if (dependencies.show) {\n visible = this.evaluateConditions(dependencies.show, formValues)\n }\n if (dependencies.hide) {\n const shouldHide = this.evaluateConditions(dependencies.hide, formValues)\n visible = visible && !shouldHide\n }\n\n // Evaluar enable/disable\n if (dependencies.enable) {\n enabled = this.evaluateConditions(dependencies.enable, formValues)\n }\n if (dependencies.disable) {\n const shouldDisable = this.evaluateConditions(\n dependencies.disable,\n formValues\n )\n enabled = enabled && !shouldDisable\n }\n\n // Evaluar required/optional\n if (dependencies.required) {\n required = this.evaluateConditions(dependencies.required, formValues)\n }\n if (dependencies.optional) {\n const shouldBeOptional = this.evaluateConditions(\n dependencies.optional,\n formValues\n )\n required = required && !shouldBeOptional\n }\n\n return { visible, enabled, required }\n }\n\n /**\n * Obtiene el valor de un campo (soporta nested paths)\n */\n private getFieldValue(\n fieldName: string,\n formValues: Record<string, any>\n ): any {\n const parts = fieldName.split('.')\n let value = formValues\n\n for (const part of parts) {\n if (value === null || value === undefined) {\n return null\n }\n value = value[part]\n }\n\n return value\n }\n\n /**\n * Compara valores según el operador\n */\n private compareValues(\n fieldValue: any,\n operator: ConditionOperator,\n compareValue: any\n ): boolean {\n switch (operator) {\n case 'equals':\n return this.deepEqual(fieldValue, compareValue)\n\n case 'notEquals':\n return !this.deepEqual(fieldValue, compareValue)\n\n case 'contains':\n if (Array.isArray(fieldValue)) {\n return fieldValue.includes(compareValue)\n }\n if (typeof fieldValue === 'string') {\n return fieldValue.includes(String(compareValue))\n }\n return false\n\n case 'notContains':\n return !this.compareValues(fieldValue, 'contains', compareValue)\n\n case 'greaterThan':\n return this.toNumber(fieldValue) > this.toNumber(compareValue)\n\n case 'lessThan':\n return this.toNumber(fieldValue) < this.toNumber(compareValue)\n\n case 'greaterThanOrEqual':\n return this.toNumber(fieldValue) >= this.toNumber(compareValue)\n\n case 'lessThanOrEqual':\n return this.toNumber(fieldValue) <= this.toNumber(compareValue)\n\n case 'in':\n if (Array.isArray(compareValue)) {\n return compareValue.includes(fieldValue)\n }\n return false\n\n case 'notIn':\n return !this.compareValues(fieldValue, 'in', compareValue)\n\n case 'isEmpty':\n return (\n fieldValue === null ||\n fieldValue === undefined ||\n fieldValue === '' ||\n (Array.isArray(fieldValue) && fieldValue.length === 0)\n )\n\n case 'isNotEmpty':\n return !this.compareValues(fieldValue, 'isEmpty', compareValue)\n\n case 'regex':\n try {\n const regex =\n typeof compareValue === 'string'\n ? new RegExp(compareValue)\n : compareValue\n return regex.test(String(fieldValue || ''))\n } catch {\n return false\n }\n\n default:\n return false\n }\n }\n\n /**\n * Comparación profunda de valores\n */\n private deepEqual(a: any, b: any): boolean {\n if (a === b) {\n return true\n }\n\n if (a === null || b === null || a === undefined || b === undefined) {\n return a === b\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false\n }\n return a.every((val, index) => this.deepEqual(val, b[index]))\n }\n\n if (typeof a === 'object') {\n const keysA = Object.keys(a)\n const keysB = Object.keys(b)\n\n if (keysA.length !== keysB.length) {\n return false\n }\n\n return keysA.every((key) => this.deepEqual(a[key], b[key]))\n }\n\n return false\n }\n\n /**\n * Convierte un valor a número\n */\n private toNumber(value: any): number {\n if (typeof value === 'number') {\n return value\n }\n if (typeof value === 'string') {\n const parsed = parseFloat(value)\n return isNaN(parsed) ? 0 : parsed\n }\n return 0\n }\n}\n","import type {\n FormState,\n WizardState,\n Field,\n FormSchema,\n} from '../types'\nimport { SchemaParser, type ParsedSchema } from './schema-parser'\nimport { ValidationEngine } from './validation-engine'\nimport { ConditionEngine } from './condition-engine'\nimport { getNestedValue, setNestedValue } from '../utils'\n\n/**\n * Gestor de estado del formulario\n */\nexport class StateManager {\n private state: FormState\n private wizardState: WizardState | null = null\n private schema: ParsedSchema | null = null\n private parser: SchemaParser\n private validator: ValidationEngine\n private conditionEngine: ConditionEngine\n private dependencyCache: Map<string, { visible: boolean; enabled: boolean; required: boolean }> = new Map()\n private fieldDependencies: Map<string, Set<string>> = new Map() // campo observado -> campos dependientes\n\n constructor() {\n this.parser = new SchemaParser()\n this.validator = new ValidationEngine()\n this.conditionEngine = new ConditionEngine()\n this.state = this.createInitialState()\n }\n\n /**\n * Crea el estado inicial\n */\n private createInitialState(): FormState {\n return {\n values: {},\n errors: {},\n touched: {},\n isValid: true,\n isSubmitting: false,\n }\n }\n\n /**\n * Inicializa el schema\n */\n initializeSchema(schema: FormSchema): void {\n this.schema = this.parser.parse(schema)\n this.initializeValues()\n this.initializeWizard()\n this.buildDependencyMap()\n }\n\n /**\n * Construye el mapa de dependencias para optimizar re-evaluaciones\n */\n private buildDependencyMap(): void {\n this.fieldDependencies.clear()\n this.dependencyCache.clear()\n\n if (!this.schema) return\n\n const allFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields\n\n for (const field of allFields) {\n if (!field.dependencies) continue\n\n // Extraer todos los campos observados\n const observedFields = this.extractObservedFields(field.dependencies)\n \n for (const observedField of observedFields) {\n if (!this.fieldDependencies.has(observedField)) {\n this.fieldDependencies.set(observedField, new Set())\n }\n this.fieldDependencies.get(observedField)!.add(field.name)\n }\n }\n }\n\n /**\n * Extrae los nombres de campos observados de las dependencias\n */\n private extractObservedFields(dependencies: any): Set<string> {\n const fields = new Set<string>()\n\n const extractFromCondition = (condition: any) => {\n if (condition && condition.field) {\n fields.add(condition.field)\n }\n }\n\n const extractFromConditions = (conditions: any) => {\n if (Array.isArray(conditions)) {\n conditions.forEach(extractFromCondition)\n } else if (conditions) {\n extractFromCondition(conditions)\n }\n }\n\n if (dependencies.show) extractFromConditions(dependencies.show)\n if (dependencies.hide) extractFromConditions(dependencies.hide)\n if (dependencies.enable) extractFromConditions(dependencies.enable)\n if (dependencies.disable) extractFromConditions(dependencies.disable)\n if (dependencies.required) extractFromConditions(dependencies.required)\n if (dependencies.optional) extractFromConditions(dependencies.optional)\n\n return fields\n }\n\n /**\n * Inicializa los valores por defecto\n */\n private initializeValues(): void {\n if (!this.schema) return\n\n const allFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields\n\n // Preservar valores existentes\n const existingValues = { ...this.state.values }\n const values: Record<string, any> = {}\n\n for (const field of allFields) {\n // Si el campo ya tiene un valor, preservarlo\n const existingValue = getNestedValue(existingValues, field.name)\n if (existingValue !== undefined && existingValue !== null) {\n values[field.name] = existingValue\n } else {\n // Solo inicializar si no existe valor previo\n this.initializeFieldValue(field, values)\n }\n }\n\n // Preservar valores de campos que no están en el schema actual (por si acaso)\n for (const key in existingValues) {\n if (!(key in values)) {\n values[key] = existingValues[key]\n }\n }\n\n this.state.values = values\n }\n\n /**\n * Inicializa el valor de un campo\n */\n private initializeFieldValue(\n field: Field,\n values: Record<string, any>\n ): void {\n if (field.defaultValue !== undefined) {\n values[field.name] = field.defaultValue\n } else {\n switch (field.type) {\n case 'checkbox':\n case 'switch':\n values[field.name] = field.checked || false\n break\n case 'select':\n if ('multiple' in field && field.multiple) {\n values[field.name] = []\n } else {\n values[field.name] = null\n }\n break\n case 'array':\n values[field.name] = []\n break\n case 'group':\n values[field.name] = {}\n if ('fields' in field) {\n for (const subField of field.fields) {\n this.initializeFieldValue(subField, values[field.name] as Record<string, any>)\n }\n }\n break\n default:\n values[field.name] = null\n }\n }\n }\n\n /**\n * Inicializa el estado del wizard\n */\n private initializeWizard(): void {\n if (!this.schema || !this.schema.isWizard) {\n this.wizardState = null\n return\n }\n\n this.wizardState = {\n currentStep: 0,\n totalSteps: this.schema.steps!.length,\n completedSteps: [],\n }\n }\n\n /**\n * Obtiene el estado actual\n */\n getState(): FormState {\n return { ...this.state }\n }\n\n /**\n * Obtiene el estado del wizard\n */\n getWizardState(): WizardState | null {\n return this.wizardState ? { ...this.wizardState } : null\n }\n\n /**\n * Obtiene un valor del formulario\n */\n getValue(fieldName: string): any {\n return getNestedValue(this.state.values, fieldName)\n }\n\n /**\n * Establece un valor\n */\n async setValue(fieldName: string, value: any): Promise<void> {\n setNestedValue(this.state.values, fieldName, value)\n this.state.touched[fieldName] = true\n\n // Invalidar cache de dependencias para campos que dependen de este\n this.invalidateDependencyCache(fieldName)\n\n // Validar el campo si está touched\n if (this.state.touched[fieldName] && this.schema) {\n await this.validateField(fieldName)\n }\n\n // Validar campos dependientes que ahora pueden tener diferentes validaciones\n const dependentFields = this.fieldDependencies.get(fieldName)\n if (dependentFields) {\n for (const dependentField of dependentFields) {\n await this.validateField(dependentField)\n }\n }\n\n this.updateValidity()\n }\n\n /**\n * Invalida el cache de dependencias para campos dependientes\n */\n private invalidateDependencyCache(fieldName: string): void {\n const dependentFields = this.fieldDependencies.get(fieldName)\n if (dependentFields) {\n for (const dependentField of dependentFields) {\n this.dependencyCache.delete(dependentField)\n }\n }\n }\n\n /**\n * Establece un valor sin validar (útil para preservar valores durante re-renderizado)\n */\n setValueWithoutValidation(fieldName: string, value: any): void {\n setNestedValue(this.state.values, fieldName, value)\n // No marcar como touched ni validar\n }\n\n /**\n * Valida un campo específico\n */\n async validateField(fieldName: string): Promise<void> {\n if (!this.schema) return\n\n const allFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields\n\n const field = allFields.find((f) => f.name === fieldName)\n if (!field) return\n\n // Si el campo no es visible, no validar\n if (!this.getFieldVisibility(fieldName)) {\n delete this.state.errors[fieldName]\n return\n }\n\n const value = this.getValue(fieldName)\n \n // Obtener validaciones activas (incluyendo condicionales)\n const activeValidations = this.getActiveValidations(field)\n \n const errors = await this.validator.validateFieldWithValidations(\n field,\n value,\n activeValidations\n )\n\n if (errors.length > 0) {\n this.state.errors[fieldName] = errors\n } else {\n delete this.state.errors[fieldName]\n }\n }\n\n /**\n * Obtiene las validaciones activas para un campo (incluyendo condicionales)\n */\n private getActiveValidations(field: Field): any[] {\n let validations = [...(field.validations || [])]\n\n // Agregar validaciones condicionales si se cumplen las condiciones\n if (field.conditionalValidations) {\n for (const conditional of field.conditionalValidations) {\n const conditionMet = this.conditionEngine.evaluateConditions(\n conditional.condition,\n this.state.values\n )\n if (conditionMet) {\n validations = [...validations, ...conditional.validations]\n }\n }\n }\n\n return validations\n }\n\n /**\n * Valida todo el formulario\n */\n async validateForm(): Promise<Record<string, string[]>> {\n if (!this.schema) {\n return {}\n }\n\n const allFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields\n\n const errors = await this.validator.validateForm(\n allFields,\n this.state.values\n )\n\n this.state.errors = errors\n this.updateValidity()\n\n return errors\n }\n\n /**\n * Actualiza la validez del formulario\n */\n private updateValidity(): void {\n this.state.isValid = Object.keys(this.state.errors).length === 0\n }\n\n /**\n * Marca un campo como touched\n */\n setTouched(fieldName: string): void {\n this.state.touched[fieldName] = true\n }\n\n /**\n * Obtiene los errores de un campo\n */\n getErrors(fieldName: string): string[] {\n return this.state.errors[fieldName] || []\n }\n\n /**\n * Obtiene todos los errores\n */\n getAllErrors(): Record<string, string[]> {\n return { ...this.state.errors }\n }\n\n /**\n * Resetea el formulario\n */\n reset(): void {\n this.state = this.createInitialState()\n if (this.schema) {\n this.initializeValues()\n this.initializeWizard()\n }\n }\n\n /**\n * Avanza al siguiente step del wizard\n */\n nextStep(): boolean {\n if (!this.wizardState) return false\n if (this.wizardState.currentStep < this.wizardState.totalSteps - 1) {\n this.wizardState.currentStep++\n return true\n }\n return false\n }\n\n /**\n * Retrocede al step anterior del wizard\n */\n previousStep(): boolean {\n if (!this.wizardState) return false\n if (this.wizardState.currentStep > 0) {\n this.wizardState.currentStep--\n return true\n }\n return false\n }\n\n /**\n * Va a un step específico\n */\n goToStep(stepIndex: number): boolean {\n if (!this.wizardState) return false\n if (stepIndex >= 0 && stepIndex < this.wizardState.totalSteps) {\n this.wizardState.currentStep = stepIndex\n return true\n }\n return false\n }\n\n /**\n * Marca un step como completado\n */\n completeStep(stepIndex: number): void {\n if (!this.wizardState) return\n if (!this.wizardState.completedSteps.includes(stepIndex)) {\n this.wizardState.completedSteps.push(stepIndex)\n }\n }\n\n /**\n * Establece el estado de submitting\n */\n setSubmitting(isSubmitting: boolean): void {\n this.state.isSubmitting = isSubmitting\n }\n\n /**\n * Obtiene los campos del step actual\n */\n getCurrentStepFields(): Field[] {\n if (!this.schema || !this.schema.isWizard || !this.wizardState) {\n return this.schema?.fields || []\n }\n return this.schema.steps![this.wizardState.currentStep].fields\n }\n\n /**\n * Obtiene la visibilidad de un campo basándose en dependencias\n */\n getFieldVisibility(fieldName: string): boolean {\n // Verificar cache primero\n const cached = this.dependencyCache.get(fieldName)\n if (cached !== undefined) {\n return cached.visible\n }\n\n if (!this.schema) return true\n\n const allFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields\n\n const field = allFields.find((f) => f.name === fieldName)\n if (!field || !field.dependencies) {\n return !field?.hidden\n }\n\n const result = this.conditionEngine.evaluateDependencies(\n field.dependencies,\n this.state.values\n )\n\n // Cachear resultado\n this.dependencyCache.set(fieldName, result)\n\n return result.visible && !field.hidden\n }\n\n /**\n * Obtiene si un campo está habilitado basándose en dependencias\n */\n getFieldEnabled(fieldName: string): boolean {\n // Verificar cache primero\n const cached = this.dependencyCache.get(fieldName)\n if (cached !== undefined) {\n return cached.enabled\n }\n\n if (!this.schema) return true\n\n const allFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields\n\n const field = allFields.find((f) => f.name === fieldName)\n if (!field) return true\n\n if (field.disabled) return false\n\n if (!field.dependencies) {\n return true\n }\n\n const result = this.conditionEngine.evaluateDependencies(\n field.dependencies,\n this.state.values\n )\n\n // Cachear resultado\n this.dependencyCache.set(fieldName, result)\n\n return result.enabled\n }\n\n /**\n * Obtiene si un campo es requerido basándose en dependencias\n */\n getFieldRequired(fieldName: string): boolean {\n // Verificar cache primero\n const cached = this.dependencyCache.get(fieldName)\n if (cached !== undefined) {\n return cached.required\n }\n\n if (!this.schema) return false\n\n const allFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields\n\n const field = allFields.find((f) => f.name === fieldName)\n if (!field) return false\n\n // Verificar si tiene validación required estándar\n const hasRequired = field.validations?.some((v) => v.type === 'required') || false\n\n if (!field.dependencies) {\n return hasRequired\n }\n\n const result = this.conditionEngine.evaluateDependencies(\n field.dependencies,\n this.state.values\n )\n\n // Cachear resultado\n this.dependencyCache.set(fieldName, result)\n\n return result.required || hasRequired\n }\n\n /**\n * Obtiene los campos que dependen de un campo específico\n */\n getDependentFields(fieldName: string): string[] {\n return Array.from(this.fieldDependencies.get(fieldName) || [])\n }\n}\n","import type { Field } from '../../types'\n\n/**\n * Clase base para inputs\n */\nexport abstract class BaseInput {\n protected field: Field\n protected value: any\n protected error?: string\n protected onChange: (value: any) => void\n protected onBlur: () => void\n\n constructor(\n field: Field,\n value: any,\n error: string | undefined,\n onChange: (value: any) => void,\n onBlur: () => void\n ) {\n this.field = field\n this.value = value\n this.error = error\n this.onChange = onChange\n this.onBlur = onBlur\n }\n\n /**\n * Renderiza el input\n */\n abstract render(): HTMLElement\n\n /**\n * Crea un contenedor con label y error\n */\n protected createFieldContainer(input: HTMLElement): HTMLElement {\n const container = document.createElement('div')\n container.className = 'easy-form-field'\n\n // Label\n if (this.field.label) {\n const label = document.createElement('label')\n label.className = 'easy-form-label'\n label.setAttribute('for', this.getFieldId())\n label.textContent = this.field.label\n // El required se maneja dinámicamente desde EasyForm basado en dependencias\n // Aquí solo mostramos si está en validations estáticas\n if (this.field.validations?.some((v) => v.type === 'required')) {\n const required = document.createElement('span')\n required.className = 'easy-form-required'\n required.textContent = ' *'\n label.appendChild(required)\n }\n container.appendChild(label)\n }\n\n // Input\n container.appendChild(input)\n\n // Description\n if (this.field.description) {\n const description = document.createElement('p')\n description.className = 'easy-form-description'\n description.textContent = this.field.description\n container.appendChild(description)\n }\n\n // Error\n if (this.error) {\n const errorEl = document.createElement('p')\n errorEl.className = 'easy-form-error'\n errorEl.textContent = this.error\n container.appendChild(errorEl)\n }\n\n return container\n }\n\n /**\n * Obtiene el ID del campo\n */\n protected getFieldId(): string {\n return `easy-form-${this.field.name}`\n }\n\n /**\n * Aplica props comunes a un elemento\n */\n protected applyCommonProps(element: HTMLElement): void {\n element.id = this.getFieldId()\n element.setAttribute('name', this.field.name)\n\n if (this.field.disabled) {\n element.setAttribute('disabled', 'true')\n element.classList.add('easy-form-input-disabled')\n }\n\n if (this.field.hidden) {\n element.style.display = 'none'\n element.classList.add('easy-form-field-hidden')\n }\n\n if (this.error) {\n element.classList.add('easy-form-input-error')\n }\n\n if (this.field.props) {\n for (const [key, value] of Object.entries(this.field.props)) {\n if (key.startsWith('data-') || key.startsWith('aria-')) {\n element.setAttribute(key, String(value))\n }\n }\n }\n }\n}\n","/**\n * Token de máscara\n */\nexport interface MaskToken {\n type: 'digit' | 'letter' | 'any' | 'literal'\n char: string\n editable: boolean\n}\n\n/**\n * Parsea un patrón de máscara en tokens\n */\nexport function parseMaskPattern(pattern: string): MaskToken[] {\n const tokens: MaskToken[] = []\n\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i]\n\n switch (char) {\n case '9':\n tokens.push({ type: 'digit', char: '9', editable: true })\n break\n case 'a':\n case 'A':\n tokens.push({ type: 'letter', char: char, editable: true })\n break\n case '*':\n tokens.push({ type: 'any', char: '*', editable: true })\n break\n default:\n tokens.push({ type: 'literal', char: char, editable: false })\n break\n }\n }\n\n return tokens\n}\n\n/**\n * Formatea un valor según los tokens de máscara\n */\nexport function formatValue(value: string, tokens: MaskToken[]): string {\n let result = ''\n let valueIndex = 0\n\n for (const token of tokens) {\n if (!token.editable) {\n result += token.char\n continue\n }\n\n if (valueIndex >= value.length) {\n break\n }\n\n const char = value[valueIndex]\n\n // Validar según el tipo de token\n if (token.type === 'digit' && !/\\d/.test(char)) {\n continue // Saltar caracteres no numéricos\n } else if (token.type === 'letter' && !/[a-zA-Z]/.test(char)) {\n continue // Saltar caracteres no alfabéticos\n } else if (token.type === 'any') {\n // Aceptar cualquier carácter\n } else if (token.type !== 'any' && token.type !== 'digit' && token.type !== 'letter') {\n continue\n }\n\n result += char\n valueIndex++\n }\n\n return result\n}\n\n/**\n * Remueve el formato de un valor (obtiene solo los caracteres editables)\n */\nexport function unformatValue(value: string, tokens: MaskToken[]): string {\n if (!value) return ''\n\n let result = ''\n let tokenIndex = 0\n\n for (let i = 0; i < value.length && tokenIndex < tokens.length; i++) {\n const char = value[i]\n const token = tokens[tokenIndex]\n\n if (token.editable) {\n // Verificar si el carácter coincide con el tipo de token\n if (token.type === 'digit' && /\\d/.test(char)) {\n result += char\n tokenIndex++\n } else if (token.type === 'letter' && /[a-zA-Z]/.test(char)) {\n result += char\n tokenIndex++\n } else if (token.type === 'any') {\n result += char\n tokenIndex++\n } else {\n // Carácter no válido para este token, avanzar al siguiente token editable\n tokenIndex++\n i-- // Revisar el mismo carácter con el siguiente token\n }\n } else {\n // Token literal, verificar si coincide\n if (char === token.char) {\n tokenIndex++\n } else {\n // El carácter no coincide con el literal esperado, puede ser un carácter editable extra\n // Intentar extraerlo si es válido\n if (tokenIndex < tokens.length - 1) {\n const nextToken = tokens[tokenIndex + 1]\n if (nextToken && nextToken.editable) {\n if (nextToken.type === 'digit' && /\\d/.test(char)) {\n result += char\n tokenIndex += 2\n } else if (nextToken.type === 'letter' && /[a-zA-Z]/.test(char)) {\n result += char\n tokenIndex += 2\n } else if (nextToken.type === 'any') {\n result += char\n tokenIndex += 2\n } else {\n tokenIndex++\n }\n } else {\n tokenIndex++\n }\n } else {\n break\n }\n }\n }\n }\n\n return result\n}\n\n/**\n * Obtiene la siguiente posición editable\n */\nexport function getNextEditablePosition(\n position: number,\n tokens: MaskToken[],\n direction: 'forward' | 'backward' = 'forward'\n): number {\n if (direction === 'forward') {\n for (let i = position + 1; i < tokens.length; i++) {\n if (tokens[i].editable) {\n return i\n }\n }\n return tokens.length\n } else {\n for (let i = position - 1; i >= 0; i--) {\n if (tokens[i].editable) {\n return i\n }\n }\n return 0\n }\n}\n\n/**\n * Obtiene el placeholder completo para una máscara\n */\nexport function getMaskPlaceholder(tokens: MaskToken[], placeholder: string = '_'): string {\n return tokens\n .map((token) => (token.editable ? placeholder : token.char))\n .join('')\n}\n\n/**\n * Calcula la posición del cursor después de aplicar máscara\n */\nexport function calculateCursorPosition(\n oldValue: string,\n newValue: string,\n oldCursorPosition: number,\n tokens: MaskToken[]\n): number {\n // Contar caracteres editables antes de la posición anterior\n let editableBeforeOld = 0\n for (let i = 0; i < Math.min(oldCursorPosition, oldValue.length); i++) {\n const tokenIndex = i\n if (tokenIndex < tokens.length && tokens[tokenIndex].editable) {\n editableBeforeOld++\n }\n }\n\n // Encontrar la posición correspondiente en el nuevo valor\n let editableCount = 0\n for (let i = 0; i < newValue.length && i < tokens.length; i++) {\n if (tokens[i].editable) {\n editableCount++\n if (editableCount > editableBeforeOld) {\n return i + 1\n }\n }\n }\n\n // Si no encontramos, buscar la siguiente posición editable\n return getNextEditablePosition(\n Math.min(oldCursorPosition, newValue.length - 1),\n tokens,\n 'forward'\n )\n}\n","import type { MaskConfig, CustomMask } from '../types'\nimport { getPredefinedMask } from '../utils/masks'\nimport {\n parseMaskPattern,\n formatValue,\n unformatValue,\n getNextEditablePosition,\n getMaskPlaceholder,\n calculateCursorPosition,\n type MaskToken,\n} from '../utils/mask-helpers'\n\n/**\n * Motor de máscaras\n */\nexport class MaskEngine {\n private tokenCache: Map<string, MaskToken[]> = new Map()\n\n /**\n * Obtiene la configuración de máscara personalizada\n */\n private getCustomMask(mask: MaskConfig): CustomMask | null {\n if (mask.custom) {\n return mask.custom\n }\n if (mask.type) {\n return getPredefinedMask(mask.type)\n }\n return null\n }\n\n /**\n * Obtiene los tokens parseados de una máscara (con cache)\n */\n private getTokens(mask: MaskConfig): MaskToken[] | null {\n const customMask = this.getCustomMask(mask)\n if (!customMask) {\n return null\n }\n\n const cacheKey = customMask.pattern\n if (this.tokenCache.has(cacheKey)) {\n return this.tokenCache.get(cacheKey)!\n }\n\n const tokens = parseMaskPattern(customMask.pattern)\n this.tokenCache.set(cacheKey, tokens)\n return tokens\n }\n\n /**\n * Aplica máscara a un valor\n */\n applyMask(value: string, mask: MaskConfig): string {\n const tokens = this.getTokens(mask)\n if (!tokens) {\n return value\n }\n\n const customMask = this.getCustomMask(mask)!\n const unformatted = this.removeMask(value, mask)\n let formatted = formatValue(unformatted, tokens)\n\n // Aplicar transformación si existe\n if (customMask.transform) {\n formatted = customMask.transform(formatted)\n // Re-formatear después de la transformación\n formatted = formatValue(formatted, tokens)\n }\n\n return formatted\n }\n\n /**\n * Remueve máscara de un valor (obtiene valor raw)\n */\n removeMask(value: string, mask: MaskConfig): string {\n const tokens = this.getTokens(mask)\n if (!tokens) {\n return value\n }\n\n return unformatValue(value, tokens)\n }\n\n /**\n * Obtiene el placeholder para una máscara\n */\n getMaskPlaceholder(mask: MaskConfig): string {\n const tokens = this.getTokens(mask)\n if (!tokens) {\n return ''\n }\n\n const customMask = this.getCustomMask(mask)!\n return getMaskPlaceholder(tokens, customMask.placeholder || '_')\n }\n\n /**\n * Valida si un carácter puede ser insertado en una posición\n */\n canInsertChar(char: string, position: number, mask: MaskConfig): boolean {\n const tokens = this.getTokens(mask)\n if (!tokens || position >= tokens.length) {\n return false\n }\n\n const token = tokens[position]\n if (!token.editable) {\n return false\n }\n\n switch (token.type) {\n case 'digit':\n return /\\d/.test(char)\n case 'letter':\n return /[a-zA-Z]/.test(char)\n case 'any':\n return true\n default:\n return false\n }\n }\n\n /**\n * Procesa entrada del usuario aplicando máscara en tiempo real\n */\n processInput(\n input: string,\n previousValue: string,\n mask: MaskConfig,\n cursorPosition: number\n ): { value: string; cursorPosition: number } {\n const tokens = this.getTokens(mask)\n if (!tokens) {\n return { value: input, cursorPosition: input.length }\n }\n\n // Obtener el valor sin formato del input actual\n const unformattedInput = unformatValue(input, tokens)\n\n // Aplicar máscara al nuevo valor\n let formatted = formatValue(unformattedInput, tokens)\n\n // Aplicar transformación si existe\n const customMask = this.getCustomMask(mask)!\n if (customMask.transform) {\n formatted = customMask.transform(formatted)\n formatted = formatValue(formatted, tokens)\n }\n\n // Calcular nueva posición del cursor\n const newCursorPosition = calculateCursorPosition(\n previousValue,\n formatted,\n cursorPosition,\n tokens\n )\n\n return {\n value: formatted,\n cursorPosition: Math.min(newCursorPosition, formatted.length),\n }\n }\n\n /**\n * Procesa entrada con manejo de backspace/delete\n */\n processKeyInput(\n key: string,\n currentValue: string,\n cursorPosition: number,\n mask: MaskConfig,\n isBackspace: boolean = false\n ): { value: string; cursorPosition: number } {\n const tokens = this.getTokens(mask)\n if (!tokens) {\n return { value: currentValue, cursorPosition: cursorPosition }\n }\n\n if (isBackspace) {\n // Manejar backspace\n if (cursorPosition === 0) {\n return { value: currentValue, cursorPosition: 0 }\n }\n\n // Encontrar la posición editable anterior\n const prevEditable = getNextEditablePosition(cursorPosition - 1, tokens, 'backward')\n \n // Remover el carácter en esa posición\n const before = currentValue.substring(0, prevEditable)\n const after = currentValue.substring(cursorPosition)\n const newValue = before + after\n\n // Re-aplicar máscara\n const unformatted = this.removeMask(newValue, mask)\n const formatted = this.applyMask(unformatted, mask)\n\n // Calcular nueva posición\n const newPos = Math.max(0, prevEditable - 1)\n const nextEditable = getNextEditablePosition(newPos, tokens, 'forward')\n\n return {\n value: formatted,\n cursorPosition: nextEditable,\n }\n }\n\n // Manejar entrada normal\n if (key.length === 1 && this.canInsertChar(key, cursorPosition, mask)) {\n // Insertar carácter en la posición actual\n const before = currentValue.substring(0, cursorPosition)\n const after = currentValue.substring(cursorPosition)\n const newValue = before + key + after\n\n return this.processInput(newValue, currentValue, mask, cursorPosition)\n }\n\n return { value: currentValue, cursorPosition: cursorPosition }\n }\n}\n","import { BaseInput } from './base-input'\nimport type { Field } from '../../types'\nimport { MaskEngine } from '../../core/mask-engine'\n\nexport class TextInput extends BaseInput {\n private maskEngine: MaskEngine | null = null\n private previousValue: string = ''\n\n constructor(\n field: Field,\n value: any,\n error: string | undefined,\n onChange: (value: any) => void,\n onBlur: () => void\n ) {\n super(field, value, error, onChange, onBlur)\n \n if (field.mask) {\n this.maskEngine = new MaskEngine()\n }\n }\n\n render(): HTMLElement {\n const input = document.createElement('input')\n input.type = this.field.type === 'email' ? 'email' : this.field.type === 'password' ? 'password' : 'text'\n \n // Aplicar máscara si existe\n let displayValue = this.value ?? ''\n if (this.maskEngine && this.field.mask) {\n if (displayValue) {\n displayValue = this.maskEngine.applyMask(String(displayValue), this.field.mask)\n }\n this.previousValue = displayValue\n }\n \n input.value = displayValue\n\n this.applyCommonProps(input)\n\n // Aplicar placeholder de máscara si existe\n if (this.maskEngine && this.field.mask && !this.field.placeholder) {\n const maskPlaceholder = this.maskEngine.getMaskPlaceholder(this.field.mask)\n if (maskPlaceholder) {\n input.placeholder = maskPlaceholder\n }\n }\n\n // Manejar eventos de entrada con máscara\n if (this.maskEngine && this.field.mask) {\n input.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n const inputValue = target.value\n\n const result = this.maskEngine!.processInput(\n inputValue,\n this.previousValue,\n this.field.mask!,\n cursorPosition\n )\n\n // Actualizar valor y cursor\n target.value = result.value\n this.previousValue = result.value\n\n // Restaurar posición del cursor\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n // Emitir valor según configuración (con o sin formato)\n const valueToEmit = this.field.mask!.keepFormat\n ? result.value\n : this.maskEngine!.removeMask(result.value, this.field.mask!)\n\n this.onChange(valueToEmit)\n })\n\n input.addEventListener('keydown', (e) => {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n\n if (e.key === 'Backspace' || e.key === 'Delete') {\n e.preventDefault()\n \n const isBackspace = e.key === 'Backspace'\n const result = this.maskEngine!.processKeyInput(\n '',\n target.value,\n cursorPosition,\n this.field.mask!,\n isBackspace\n )\n\n target.value = result.value\n this.previousValue = result.value\n\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n const valueToEmit = this.field.mask!.keepFormat\n ? result.value\n : this.maskEngine!.removeMask(result.value, this.field.mask!)\n\n this.onChange(valueToEmit)\n }\n })\n\n input.addEventListener('paste', (e) => {\n e.preventDefault()\n const pastedText = (e.clipboardData || (window as any).clipboardData).getData('text')\n \n if (pastedText) {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n \n // Insertar texto pegado\n const before = target.value.substring(0, cursorPosition)\n const after = target.value.substring(cursorPosition)\n const newValue = before + pastedText + after\n\n const result = this.maskEngine!.processInput(\n newValue,\n this.previousValue,\n this.field.mask!,\n cursorPosition\n )\n\n target.value = result.value\n this.previousValue = result.value\n\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n const valueToEmit = this.field.mask!.keepFormat\n ? result.value\n : this.maskEngine!.removeMask(result.value, this.field.mask!)\n\n this.onChange(valueToEmit)\n }\n })\n } else {\n // Sin máscara, comportamiento normal\n input.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement\n this.onChange(target.value)\n })\n }\n\n input.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(input)\n }\n}\n","import { BaseInput } from './base-input'\nimport type { NumberField } from '../../types'\nimport { MaskEngine } from '../../core/mask-engine'\n\nexport class NumberInput extends BaseInput {\n private maskEngine: MaskEngine | null = null\n private previousValue: string = ''\n\n constructor(\n field: NumberField,\n value: any,\n error: string | undefined,\n onChange: (value: any) => void,\n onBlur: () => void\n ) {\n super(field, value, error, onChange, onBlur)\n \n if (field.mask) {\n this.maskEngine = new MaskEngine()\n }\n }\n\n render(): HTMLElement {\n const input = document.createElement('input')\n \n // Si tiene máscara, usar tipo text para mejor control\n if (this.maskEngine && this.field.mask) {\n input.type = 'text'\n \n // Aplicar máscara al valor inicial\n let displayValue = this.value ?? ''\n if (displayValue !== null && displayValue !== '') {\n if (this.field.mask.type === 'currency') {\n displayValue = this.maskEngine.applyMask(String(displayValue), this.field.mask)\n } else if (this.field.mask.type === 'percentage') {\n displayValue = this.maskEngine.applyMask(String(displayValue), this.field.mask)\n }\n }\n this.previousValue = displayValue\n input.value = displayValue\n } else {\n input.type = 'number'\n input.value = this.value ?? ''\n }\n \n input.placeholder = this.field.placeholder || ''\n\n const numberField = this.field as NumberField\n if (!this.maskEngine && input.type === 'number') {\n if (numberField.min !== undefined) {\n input.min = String(numberField.min)\n }\n if (numberField.max !== undefined) {\n input.max = String(numberField.max)\n }\n if (numberField.step !== undefined) {\n input.step = String(numberField.step)\n }\n }\n\n this.applyCommonProps(input)\n\n // Aplicar placeholder de máscara si existe\n if (this.maskEngine && this.field.mask && !this.field.placeholder) {\n const maskPlaceholder = this.maskEngine.getMaskPlaceholder(this.field.mask)\n if (maskPlaceholder) {\n input.placeholder = maskPlaceholder\n }\n }\n\n // Manejar eventos con máscara\n if (this.maskEngine && this.field.mask) {\n input.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n const inputValue = target.value\n\n const result = this.maskEngine!.processInput(\n inputValue,\n this.previousValue,\n this.field.mask!,\n cursorPosition\n )\n\n target.value = result.value\n this.previousValue = result.value\n\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n // Convertir a número según el tipo de máscara\n let numValue: number | null = null\n if (this.field.mask!.type === 'currency') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted.replace(/[^\\d.]/g, '')) : null\n } else if (this.field.mask!.type === 'percentage') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted) : null\n }\n\n this.onChange(numValue)\n })\n\n input.addEventListener('keydown', (e) => {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n\n if (e.key === 'Backspace' || e.key === 'Delete') {\n e.preventDefault()\n \n const isBackspace = e.key === 'Backspace'\n const result = this.maskEngine!.processKeyInput(\n '',\n target.value,\n cursorPosition,\n this.field.mask!,\n isBackspace\n )\n\n target.value = result.value\n this.previousValue = result.value\n\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n let numValue: number | null = null\n if (this.field.mask!.type === 'currency') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted.replace(/[^\\d.]/g, '')) : null\n } else if (this.field.mask!.type === 'percentage') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted) : null\n }\n\n this.onChange(numValue)\n }\n })\n\n input.addEventListener('paste', (e) => {\n e.preventDefault()\n const pastedText = (e.clipboardData || (window as any).clipboardData).getData('text')\n \n if (pastedText) {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n \n const before = target.value.substring(0, cursorPosition)\n const after = target.value.substring(cursorPosition)\n const newValue = before + pastedText + after\n\n const result = this.maskEngine!.processInput(\n newValue,\n this.previousValue,\n this.field.mask!,\n cursorPosition\n )\n\n target.value = result.value\n this.previousValue = result.value\n\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n let numValue: number | null = null\n if (this.field.mask!.type === 'currency') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted.replace(/[^\\d.]/g, '')) : null\n } else if (this.field.mask!.type === 'percentage') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted) : null\n }\n\n this.onChange(numValue)\n }\n })\n } else {\n // Sin máscara, comportamiento normal\n input.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement\n const numValue = target.value === '' ? null : Number(target.value)\n this.onChange(numValue)\n })\n }\n\n input.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(input)\n }\n}\n","import { BaseInput } from './base-input'\nimport type { TextareaField } from '../../types'\n\nexport class TextareaInput extends BaseInput {\n render(): HTMLElement {\n const textarea = document.createElement('textarea')\n textarea.value = this.value ?? ''\n textarea.placeholder = this.field.placeholder || ''\n\n const textareaField = this.field as TextareaField\n if (textareaField.rows) {\n textarea.rows = textareaField.rows\n }\n if (textareaField.cols) {\n textarea.cols = textareaField.cols\n }\n\n this.applyCommonProps(textarea)\n\n textarea.addEventListener('input', (e) => {\n const target = e.target as HTMLTextAreaElement\n this.onChange(target.value)\n })\n\n textarea.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(textarea)\n }\n}\n","import { BaseInput } from './base-input'\nimport type { SelectField } from '../../types'\n\nexport class SelectInput extends BaseInput {\n render(): HTMLElement {\n const select = document.createElement('select')\n const selectField = this.field as SelectField\n\n if (selectField.multiple) {\n select.multiple = true\n }\n\n // Crear opciones\n for (const option of selectField.options) {\n const optionEl = document.createElement('option')\n if (typeof option === 'string') {\n optionEl.value = option\n optionEl.textContent = option\n } else {\n optionEl.value = String(option.value)\n optionEl.textContent = option.label\n }\n select.appendChild(optionEl)\n }\n\n // Establecer valor\n if (selectField.multiple && Array.isArray(this.value)) {\n for (const option of select.options) {\n option.selected = this.value.includes(option.value)\n }\n } else {\n select.value = this.value ?? ''\n }\n\n this.applyCommonProps(select)\n\n select.addEventListener('change', (e) => {\n const target = e.target as HTMLSelectElement\n if (selectField.multiple) {\n const selectedValues = Array.from(target.selectedOptions).map(\n (opt) => opt.value\n )\n this.onChange(selectedValues)\n } else {\n this.onChange(target.value || null)\n }\n })\n\n select.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(select)\n }\n}\n","import { BaseInput } from './base-input'\n\nexport class CheckboxInput extends BaseInput {\n render(): HTMLElement {\n const checkbox = document.createElement('input')\n checkbox.type = 'checkbox'\n checkbox.checked = Boolean(this.value)\n\n this.applyCommonProps(checkbox)\n\n checkbox.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement\n this.onChange(target.checked)\n })\n\n checkbox.addEventListener('blur', () => {\n this.onBlur()\n })\n\n const container = document.createElement('div')\n container.className = 'easy-form-field'\n\n // Label (checkbox primero, luego label)\n const label = document.createElement('label')\n label.className = 'easy-form-label-checkbox'\n label.setAttribute('for', this.getFieldId())\n label.appendChild(checkbox)\n if (this.field.label) {\n const labelText = document.createTextNode(this.field.label)\n label.appendChild(labelText)\n }\n container.appendChild(label)\n\n // Description\n if (this.field.description) {\n const description = document.createElement('p')\n description.className = 'easy-form-description'\n description.textContent = this.field.description\n container.appendChild(description)\n }\n\n // Error\n if (this.error) {\n const errorEl = document.createElement('p')\n errorEl.className = 'easy-form-error'\n errorEl.textContent = this.error\n container.appendChild(errorEl)\n }\n\n return container\n }\n}\n","import { BaseInput } from './base-input'\nimport type { RadioField } from '../../types'\n\nexport class RadioInput extends BaseInput {\n render(): HTMLElement {\n const container = document.createElement('div')\n container.className = 'easy-form-field'\n\n // Label\n if (this.field.label) {\n const label = document.createElement('label')\n label.className = 'easy-form-label'\n label.textContent = this.field.label\n if (this.field.validations?.some((v) => v.type === 'required')) {\n const required = document.createElement('span')\n required.className = 'easy-form-required'\n required.textContent = ' *'\n label.appendChild(required)\n }\n container.appendChild(label)\n }\n\n // Radio buttons\n const radioGroup = document.createElement('div')\n radioGroup.className = 'easy-form-radio-group'\n\n const radioField = this.field as RadioField\n for (const option of radioField.options) {\n const optionValue = typeof option === 'string' ? option : option.value\n const optionLabel = typeof option === 'string' ? option : option.label\n\n const radioContainer = document.createElement('div')\n radioContainer.className = 'easy-form-radio-option'\n\n const radio = document.createElement('input')\n radio.type = 'radio'\n radio.name = this.field.name\n radio.id = `${this.getFieldId()}-${optionValue}`\n radio.value = String(optionValue)\n radio.checked = String(this.value) === String(optionValue)\n\n if (this.field.disabled) {\n radio.disabled = true\n }\n\n const label = document.createElement('label')\n label.setAttribute('for', radio.id)\n label.textContent = optionLabel\n label.className = 'easy-form-radio-label'\n\n radio.addEventListener('change', () => {\n this.onChange(optionValue)\n })\n\n radio.addEventListener('blur', () => {\n this.onBlur()\n })\n\n radioContainer.appendChild(radio)\n radioContainer.appendChild(label)\n radioGroup.appendChild(radioContainer)\n }\n\n container.appendChild(radioGroup)\n\n // Description\n if (this.field.description) {\n const description = document.createElement('p')\n description.className = 'easy-form-description'\n description.textContent = this.field.description\n container.appendChild(description)\n }\n\n // Error\n if (this.error) {\n const errorEl = document.createElement('p')\n errorEl.className = 'easy-form-error'\n errorEl.textContent = this.error\n container.appendChild(errorEl)\n }\n\n return container\n }\n}\n","import { BaseInput } from './base-input'\n\nexport class SwitchInput extends BaseInput {\n render(): HTMLElement {\n const switchEl = document.createElement('input')\n switchEl.type = 'checkbox'\n switchEl.className = 'easy-form-switch'\n switchEl.checked = Boolean(this.value)\n\n this.applyCommonProps(switchEl)\n\n switchEl.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement\n this.onChange(target.checked)\n })\n\n switchEl.addEventListener('blur', () => {\n this.onBlur()\n })\n\n const container = document.createElement('div')\n container.className = 'easy-form-field'\n\n // Label con switch\n const label = document.createElement('label')\n label.className = 'easy-form-label-switch'\n label.setAttribute('for', this.getFieldId())\n if (this.field.label) {\n const labelText = document.createTextNode(this.field.label)\n label.appendChild(labelText)\n }\n label.appendChild(switchEl)\n container.appendChild(label)\n\n // Description\n if (this.field.description) {\n const description = document.createElement('p')\n description.className = 'easy-form-description'\n description.textContent = this.field.description\n container.appendChild(description)\n }\n\n // Error\n if (this.error) {\n const errorEl = document.createElement('p')\n errorEl.className = 'easy-form-error'\n errorEl.textContent = this.error\n container.appendChild(errorEl)\n }\n\n return container\n }\n}\n","import { BaseInput } from './base-input'\nimport type { DateField } from '../../types'\n\nexport class DateInput extends BaseInput {\n render(): HTMLElement {\n const input = document.createElement('input')\n input.type = 'date'\n \n const dateField = this.field as DateField\n if (dateField.min) {\n input.min = dateField.min\n }\n if (dateField.max) {\n input.max = dateField.max\n }\n\n if (this.value) {\n const date = this.value instanceof Date \n ? this.value.toISOString().split('T')[0]\n : String(this.value)\n input.value = date\n }\n\n this.applyCommonProps(input)\n\n input.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement\n this.onChange(target.value || null)\n })\n\n input.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(input)\n }\n}\n","import { BaseInput } from './base-input'\nimport type { FileField } from '../../types'\n\nexport class FileInput extends BaseInput {\n render(): HTMLElement {\n const input = document.createElement('input')\n input.type = 'file'\n \n const fileField = this.field as FileField\n if (fileField.accept) {\n input.accept = fileField.accept\n }\n if (fileField.multiple) {\n input.multiple = true\n }\n\n this.applyCommonProps(input)\n\n input.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement\n if (target.files) {\n if (fileField.multiple) {\n this.onChange(Array.from(target.files))\n } else {\n this.onChange(target.files[0] || null)\n }\n }\n })\n\n input.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(input)\n }\n}\n","import { TextInput } from './text-input'\nimport { NumberInput } from './number-input'\nimport { TextareaInput } from './textarea-input'\nimport { SelectInput } from './select-input'\nimport { CheckboxInput } from './checkbox-input'\nimport { RadioInput } from './radio-input'\nimport { SwitchInput } from './switch-input'\nimport { DateInput } from './date-input'\nimport { FileInput } from './file-input'\nimport type { Field, CustomComponent } from '../../types'\n\n/**\n * Factory para crear inputs\n */\nexport function createInput(\n field: Field,\n value: any,\n error: string | undefined,\n onChange: (value: any) => void,\n onBlur: () => void\n): HTMLElement {\n switch (field.type) {\n case 'text':\n case 'email':\n case 'password':\n return new TextInput(field, value, error, onChange, onBlur).render()\n case 'number':\n return new NumberInput(field, value, error, onChange, onBlur).render()\n case 'textarea':\n return new TextareaInput(field, value, error, onChange, onBlur).render()\n case 'select':\n return new SelectInput(field, value, error, onChange, onBlur).render()\n case 'checkbox':\n return new CheckboxInput(field, value, error, onChange, onBlur).render()\n case 'radio':\n return new RadioInput(field, value, error, onChange, onBlur).render()\n case 'switch':\n return new SwitchInput(field, value, error, onChange, onBlur).render()\n case 'date':\n return new DateInput(field, value, error, onChange, onBlur).render()\n case 'file':\n return new FileInput(field, value, error, onChange, onBlur).render()\n default:\n const div = document.createElement('div')\n div.textContent = `Tipo de campo no soportado: ${field.type}`\n return div\n }\n}\n\n/**\n * Registro de componentes personalizados\n */\nlet customComponents: Map<string, CustomComponent> = new Map()\n\n/**\n * Registra un componente personalizado\n */\nexport function registerComponent(\n type: string,\n component: CustomComponent\n): void {\n customComponents.set(type, component)\n}\n\n/**\n * Registra múltiples componentes\n */\nexport function registerComponents(\n components: Record<string, CustomComponent>\n): void {\n for (const [type, component] of Object.entries(components)) {\n registerComponent(type, component)\n }\n}\n\n/**\n * Obtiene un componente personalizado\n */\nexport function getCustomComponent(type: string): CustomComponent | undefined {\n return customComponents.get(type)\n}\n","import { StateManager } from '../core/state-manager'\nimport { createInput, getCustomComponent, registerComponents } from './inputs'\nimport type {\n FormSchema,\n Field,\n ComponentRegistry,\n SubmitEventDetail,\n ChangeEventDetail,\n ErrorEventDetail,\n StepChangeEventDetail,\n FormTheme,\n FormColors,\n} from '../types'\nimport { attributeValue, parseAttributeValue } from '../utils'\nimport { getThemeStyles, getColors } from '../utils/styles'\n\n// Verificar si estamos en un entorno del navegador\nconst BrowserHTMLElement = typeof HTMLElement !== 'undefined' ? HTMLElement : class {} as typeof HTMLElement\n\n/**\n * Web Component principal EasyForm\n */\nexport class EasyForm extends BrowserHTMLElement {\n private stateManager: StateManager\n protected shadow: ShadowRoot\n private customComponents: ComponentRegistry = {}\n private isRendering: boolean = false\n\n static get observedAttributes() {\n return ['schema', 'theme', 'colors']\n }\n\n constructor() {\n if (typeof HTMLElement === 'undefined') {\n throw new Error('EasyForm can only be used in a browser environment')\n }\n super()\n this.stateManager = new StateManager()\n this.shadow = this.attachShadow({ mode: 'open' })\n // Los estilos se aplicarán en connectedCallback cuando los atributos estén disponibles\n }\n\n /**\n * Obtiene el schema\n */\n get schema(): FormSchema | null {\n const schemaAttr = this.getAttribute('schema')\n if (!schemaAttr) return null\n return parseAttributeValue(schemaAttr)\n }\n\n /**\n * Establece el schema\n */\n set schema(value: FormSchema | null) {\n if (value) {\n this.setAttribute('schema', attributeValue(value))\n } else {\n this.removeAttribute('schema')\n }\n }\n\n /**\n * Se llama cuando el componente se conecta al DOM\n */\n connectedCallback() {\n // Asegurar que los estilos estén aplicados con los atributos actuales\n this.setupStyles()\n this.render()\n }\n\n /**\n * Se llama cuando un atributo cambia\n */\n attributeChangedCallback(name: string, oldValue: string, newValue: string) {\n if (name === 'schema' && newValue !== oldValue) {\n this.handleSchemaChange()\n }\n if ((name === 'theme' || name === 'colors') && newValue !== oldValue) {\n this.setupStyles()\n }\n }\n\n /**\n * Maneja el cambio de schema\n */\n private handleSchemaChange() {\n const schema = this.schema\n if (schema) {\n this.stateManager.initializeSchema(schema)\n this.render()\n }\n }\n\n /**\n * Renderiza el formulario\n */\n private async render() {\n // Evitar renderizados simultáneos\n if (this.isRendering) {\n return\n }\n \n this.isRendering = true\n \n try {\n const schema = this.schema\n if (!schema) {\n // Eliminar solo el formulario, mantener los estilos\n const form = this.shadow.querySelector('form')\n if (form && form.parentNode === this.shadow) {\n form.remove()\n }\n return\n }\n\n // Preservar valores actuales del DOM antes de re-renderizar\n const preservedValues = this.preserveCurrentValues()\n\n // Guardar los valores preservados en el estado sin validar\n // Esto evita disparar validaciones de todos los campos\n if (preservedValues && Object.keys(preservedValues).length > 0) {\n for (const [key, value] of Object.entries(preservedValues)) {\n this.stateManager.setValueWithoutValidation(key, value)\n }\n }\n\n this.stateManager.initializeSchema(schema)\n const wizardState = this.stateManager.getWizardState()\n\n // Crear formulario\n const newFormElement = document.createElement('form')\n newFormElement.addEventListener('submit', (e) => this.handleSubmit(e))\n\n // Renderizar campos o steps\n if (wizardState) {\n this.renderWizard(newFormElement, wizardState)\n } else {\n this.renderFields(newFormElement, schema.fields || [])\n }\n\n // Botón submit\n const submitButton = document.createElement('button')\n submitButton.type = 'submit'\n submitButton.textContent = 'Enviar'\n submitButton.className = 'easy-form-submit'\n newFormElement.appendChild(submitButton)\n\n // Eliminar solo el formulario anterior si existe y está en el DOM, mantener los estilos\n const oldForm = this.shadow.querySelector('form')\n if (oldForm && oldForm.parentNode === this.shadow && oldForm !== newFormElement) {\n try {\n oldForm.remove()\n } catch (e) {\n // Ignorar errores si el elemento ya fue eliminado\n console.warn('Error al eliminar formulario anterior:', e)\n }\n }\n \n // Agregar el nuevo formulario\n this.shadow.appendChild(newFormElement)\n } finally {\n this.isRendering = false\n }\n }\n\n /**\n * Preserva los valores actuales del DOM antes de re-renderizar\n * Retorna un objeto con los valores preservados\n */\n private preserveCurrentValues(): Record<string, any> {\n const form = this.shadow.querySelector('form')\n const preservedValues: Record<string, any> = {}\n \n if (!form) return preservedValues\n\n // Obtener todos los inputs, textareas y selects del formulario\n const inputs = form.querySelectorAll('input, textarea, select')\n \n for (const input of inputs) {\n const name = input.getAttribute('name')\n if (!name) continue\n\n let value: any\n \n if (input instanceof HTMLInputElement) {\n if (input.type === 'checkbox') {\n value = input.checked\n } else if (input.type === 'radio') {\n if (input.checked) {\n value = input.value\n } else {\n continue // Solo guardar el radio seleccionado\n }\n } else if (input.type === 'number') {\n value = input.value === '' ? null : Number(input.value)\n } else {\n value = input.value\n }\n } else if (input instanceof HTMLTextAreaElement) {\n value = input.value\n } else if (input instanceof HTMLSelectElement) {\n if (input.multiple) {\n value = Array.from(input.selectedOptions).map(opt => opt.value)\n } else {\n value = input.value || null\n }\n }\n\n // Guardar el valor (incluso strings vacíos para preservar el estado)\n if (value !== undefined) {\n preservedValues[name] = value === '' ? null : value\n }\n }\n \n return preservedValues\n }\n\n /**\n * Renderiza campos normales\n */\n private renderFields(container: HTMLElement, fields: Field[]) {\n for (const field of fields) {\n const fieldElement = this.renderField(field)\n if (fieldElement) {\n container.appendChild(fieldElement)\n }\n }\n }\n\n /**\n * Renderiza un campo\n */\n private renderField(field: Field): HTMLElement | null {\n // Verificar visibilidad basada en dependencias\n const isVisible = this.stateManager.getFieldVisibility(field.name)\n const isEnabled = this.stateManager.getFieldEnabled(field.name)\n\n // Campos especiales\n if (field.type === 'group') {\n const groupElement = this.renderGroup(field)\n if (!isVisible) {\n groupElement.style.display = 'none'\n groupElement.classList.add('easy-form-field-hidden')\n }\n if (!isEnabled) {\n groupElement.classList.add('easy-form-field-disabled')\n }\n return groupElement\n }\n if (field.type === 'array') {\n const arrayElement = this.renderArray(field)\n if (!isVisible) {\n arrayElement.style.display = 'none'\n arrayElement.classList.add('easy-form-field-hidden')\n }\n if (!isEnabled) {\n arrayElement.classList.add('easy-form-field-disabled')\n }\n return arrayElement\n }\n if (field.type === 'custom') {\n const customElement = this.renderCustom(field)\n if (customElement) {\n if (!isVisible) {\n customElement.style.display = 'none'\n customElement.classList.add('easy-form-field-hidden')\n }\n if (!isEnabled) {\n customElement.classList.add('easy-form-field-disabled')\n }\n }\n return customElement\n }\n\n // Campos normales\n const value = this.stateManager.getValue(field.name)\n const errors = this.stateManager.getErrors(field.name)\n const error = errors.length > 0 ? errors[0] : undefined\n\n // Aplicar disabled basado en dependencias\n const fieldWithDependencies = {\n ...field,\n disabled: !isEnabled || field.disabled,\n }\n\n const customComponent = getCustomComponent(field.type)\n if (customComponent) {\n const element = customComponent({\n field: fieldWithDependencies,\n value,\n error,\n onChange: (val) => this.handleFieldChange(field.name, val),\n onBlur: () => this.handleFieldBlur(field.name),\n })\n if (element && !isVisible) {\n element.style.display = 'none'\n element.classList.add('easy-form-field-hidden')\n }\n return element\n }\n\n const inputElement = createInput(\n fieldWithDependencies,\n value,\n error,\n (val) => this.handleFieldChange(field.name, val),\n () => this.handleFieldBlur(field.name)\n )\n\n // Agregar atributo para identificar el campo\n const fieldContainer = inputElement.querySelector('.easy-form-field') || inputElement\n if (fieldContainer instanceof HTMLElement) {\n fieldContainer.setAttribute('data-field-name', field.name)\n }\n\n // Aplicar clases para visibilidad\n if (!isVisible) {\n inputElement.style.display = 'none'\n inputElement.classList.add('easy-form-field-hidden')\n }\n\n return inputElement\n }\n\n /**\n * Renderiza un grupo de campos\n */\n private renderGroup(field: Field): HTMLElement {\n const groupContainer = document.createElement('div')\n groupContainer.className = 'easy-form-group'\n\n if (field.label) {\n const label = document.createElement('h3')\n label.className = 'easy-form-group-label'\n label.textContent = field.label\n groupContainer.appendChild(label)\n }\n\n if ('fields' in field && field.fields) {\n for (const subField of field.fields) {\n const fieldElement = this.renderField(subField)\n if (fieldElement) {\n groupContainer.appendChild(fieldElement)\n }\n }\n }\n\n return groupContainer\n }\n\n /**\n * Renderiza un array dinámico\n */\n private renderArray(field: Field): HTMLElement {\n const arrayContainer = document.createElement('div')\n arrayContainer.className = 'easy-form-array'\n\n if (field.label) {\n const label = document.createElement('label')\n label.className = 'easy-form-label'\n label.textContent = field.label\n arrayContainer.appendChild(label)\n }\n\n const values = this.stateManager.getValue(field.name) || []\n const arrayField = field as any\n\n // Renderizar items existentes\n const itemsContainer = document.createElement('div')\n itemsContainer.className = 'easy-form-array-items'\n\n for (let i = 0; i < values.length; i++) {\n const itemContainer = document.createElement('div')\n itemContainer.className = 'easy-form-array-item'\n\n if (arrayField.itemSchema?.fields) {\n for (const itemField of arrayField.itemSchema.fields) {\n const itemFieldWithName = {\n ...itemField,\n name: `${field.name}.${i}.${itemField.name}`,\n }\n const fieldElement = this.renderField(itemFieldWithName)\n if (fieldElement) {\n itemContainer.appendChild(fieldElement)\n }\n }\n }\n\n // Botón eliminar\n const removeButton = document.createElement('button')\n removeButton.type = 'button'\n removeButton.textContent = 'Eliminar'\n removeButton.className = 'easy-form-array-remove'\n removeButton.addEventListener('click', () => {\n const newValues = [...values]\n newValues.splice(i, 1)\n this.handleFieldChange(field.name, newValues)\n })\n itemContainer.appendChild(removeButton)\n\n itemsContainer.appendChild(itemContainer)\n }\n\n arrayContainer.appendChild(itemsContainer)\n\n // Botón agregar\n const addButton = document.createElement('button')\n addButton.type = 'button'\n addButton.textContent = 'Agregar'\n addButton.className = 'easy-form-array-add'\n addButton.addEventListener('click', () => {\n const newValues = [...values, {}]\n this.handleFieldChange(field.name, newValues)\n })\n arrayContainer.appendChild(addButton)\n\n return arrayContainer\n }\n\n /**\n * Renderiza un campo custom\n */\n private renderCustom(field: Field): HTMLElement | null {\n const customComponent = getCustomComponent('custom')\n if (!customComponent) {\n const div = document.createElement('div')\n div.textContent = `Componente custom no registrado para: ${field.name}`\n return div\n }\n\n const value = this.stateManager.getValue(field.name)\n const errors = this.stateManager.getErrors(field.name)\n const error = errors.length > 0 ? errors[0] : undefined\n\n return customComponent({\n field,\n value,\n error,\n onChange: (val) => this.handleFieldChange(field.name, val),\n onBlur: () => this.handleFieldBlur(field.name),\n })\n }\n\n /**\n * Renderiza wizard\n */\n private renderWizard(container: HTMLElement, wizardState: any) {\n const wizardContainer = document.createElement('div')\n wizardContainer.className = 'easy-form-wizard'\n\n // Indicador de steps\n const stepsIndicator = document.createElement('div')\n stepsIndicator.className = 'easy-form-wizard-steps'\n const schema = this.schema\n if (schema?.steps) {\n for (let i = 0; i < schema.steps.length; i++) {\n const stepEl = document.createElement('div')\n stepEl.className = 'easy-form-wizard-step'\n if (i === wizardState.currentStep) {\n stepEl.classList.add('active')\n }\n if (wizardState.completedSteps.includes(i)) {\n stepEl.classList.add('completed')\n }\n stepEl.textContent = schema.steps[i].title\n stepsIndicator.appendChild(stepEl)\n }\n }\n wizardContainer.appendChild(stepsIndicator)\n\n // Campos del step actual\n const fieldsContainer = document.createElement('div')\n fieldsContainer.className = 'easy-form-wizard-fields'\n const currentFields = this.stateManager.getCurrentStepFields()\n for (const field of currentFields) {\n const fieldElement = this.renderField(field)\n if (fieldElement) {\n fieldsContainer.appendChild(fieldElement)\n }\n }\n wizardContainer.appendChild(fieldsContainer)\n\n // Botones de navegación\n const navContainer = document.createElement('div')\n navContainer.className = 'easy-form-wizard-nav'\n\n const prevButton = document.createElement('button')\n prevButton.type = 'button'\n prevButton.textContent = 'Anterior'\n prevButton.className = 'easy-form-wizard-prev'\n prevButton.disabled = wizardState.currentStep === 0\n prevButton.addEventListener('click', () => {\n if (this.stateManager.previousStep()) {\n this.render()\n this.emitStepChange()\n }\n })\n navContainer.appendChild(prevButton)\n\n const nextButton = document.createElement('button')\n nextButton.type = 'button'\n nextButton.textContent =\n wizardState.currentStep === wizardState.totalSteps - 1\n ? 'Enviar'\n : 'Siguiente'\n nextButton.className = 'easy-form-wizard-next'\n nextButton.addEventListener('click', async () => {\n if (wizardState.currentStep === wizardState.totalSteps - 1) {\n await this.handleSubmit(new Event('submit') as SubmitEvent)\n } else {\n // Validar step actual antes de avanzar\n const currentFields = this.stateManager.getCurrentStepFields()\n const errors = await this.stateManager.validateForm()\n const hasErrors = currentFields.some(\n (f) => errors[f.name] && errors[f.name].length > 0\n )\n\n if (!hasErrors) {\n this.stateManager.completeStep(wizardState.currentStep)\n if (this.stateManager.nextStep()) {\n this.render()\n this.emitStepChange()\n }\n } else {\n this.emitError(errors)\n }\n }\n })\n navContainer.appendChild(nextButton)\n\n wizardContainer.appendChild(navContainer)\n container.appendChild(wizardContainer)\n }\n\n /**\n * Maneja el cambio de un campo\n */\n private async handleFieldChange(fieldName: string, value: any) {\n await this.stateManager.setValue(fieldName, value)\n \n // Obtener campos dependientes que necesitan re-renderizarse\n const dependentFields = this.stateManager.getDependentFields(fieldName)\n \n // Re-renderizar campos dependientes si hay cambios en dependencias\n if (dependentFields.length > 0) {\n // Usar un pequeño delay para agrupar múltiples cambios\n if (this.dependencyRenderTimeout) {\n clearTimeout(this.dependencyRenderTimeout)\n }\n \n this.dependencyRenderTimeout = setTimeout(() => {\n this.renderDependentFields(dependentFields)\n this.emitDependencyChange(fieldName, dependentFields)\n }, 10)\n }\n\n // Emitir evento change\n const changeEvent = new CustomEvent<ChangeEventDetail>('change', {\n detail: {\n field: fieldName,\n value,\n values: this.stateManager.getState().values,\n },\n bubbles: true,\n composed: true,\n })\n this.dispatchEvent(changeEvent)\n }\n\n private dependencyRenderTimeout: ReturnType<typeof setTimeout> | null = null\n\n /**\n * Re-renderiza campos dependientes\n */\n private renderDependentFields(fieldNames: string[]): void {\n const form = this.shadow.querySelector('form')\n if (!form) return\n\n const schema = this.schema\n if (!schema) return\n\n for (const fieldName of fieldNames) {\n const fieldContainer = form.querySelector(\n `.easy-form-field[name=\"${fieldName}\"], [data-field-name=\"${fieldName}\"]`\n )?.closest('.easy-form-field')\n\n if (fieldContainer) {\n const field = this.findFieldInSchema(schema, fieldName)\n if (!field) continue\n\n // Re-renderizar el campo\n const newFieldElement = this.renderField(field)\n if (newFieldElement && fieldContainer.parentNode) {\n fieldContainer.parentNode.replaceChild(newFieldElement, fieldContainer)\n }\n }\n }\n }\n\n /**\n * Emite evento de cambio de dependencia\n */\n private emitDependencyChange(\n changedField: string,\n affectedFields: string[]\n ): void {\n const dependencyEvent = new CustomEvent('dependencyChange', {\n detail: {\n changedField,\n affectedFields,\n },\n bubbles: true,\n composed: true,\n })\n this.dispatchEvent(dependencyEvent)\n }\n\n /**\n * Maneja el blur de un campo\n */\n private async handleFieldBlur(fieldName: string) {\n this.stateManager.setTouched(fieldName)\n // Validar solo el campo que perdió el foco\n await this.stateManager.validateField(fieldName)\n // Actualizar solo el campo específico sin re-renderizar todo el formulario\n this.updateSingleField(fieldName)\n }\n\n /**\n * Actualiza solo un campo específico sin re-renderizar todo el formulario\n */\n private updateSingleField(fieldName: string) {\n const schema = this.schema\n if (!schema) return\n\n const field = this.findFieldInSchema(schema, fieldName)\n if (!field) return\n\n const errors = this.stateManager.getErrors(fieldName)\n const error = errors.length > 0 ? errors[0] : undefined\n\n // Buscar el contenedor del campo en el DOM\n const fieldContainer = this.shadow.querySelector(`[name=\"${fieldName}\"]`)?.closest('.easy-form-field')\n if (!fieldContainer) return\n\n // Actualizar el error\n const errorElement = fieldContainer.querySelector('.easy-form-error')\n if (error) {\n if (!errorElement) {\n const errorEl = document.createElement('p')\n errorEl.className = 'easy-form-error'\n errorEl.textContent = error\n fieldContainer.appendChild(errorEl)\n } else {\n errorElement.textContent = error\n }\n // Agregar clase de error al input\n const input = fieldContainer.querySelector('input, textarea, select') as HTMLElement\n input?.classList.add('easy-form-input-error')\n } else {\n errorElement?.remove()\n const input = fieldContainer.querySelector('input, textarea, select') as HTMLElement\n input?.classList.remove('easy-form-input-error')\n }\n }\n\n /**\n * Busca un campo por nombre en el schema\n */\n private findFieldInSchema(schema: FormSchema, name: string): Field | null {\n const fields = schema.fields || []\n for (const field of fields) {\n if (field.name === name) {\n return field\n }\n if (field.type === 'group' && 'fields' in field) {\n const found = this.findFieldInSchema({ fields: field.fields }, name)\n if (found) return found\n }\n }\n return null\n }\n\n /**\n * Maneja el submit del formulario\n */\n private async handleSubmit(event: Event) {\n event.preventDefault()\n\n const errors = await this.stateManager.validateForm()\n const state = this.stateManager.getState()\n\n if (Object.keys(errors).length > 0) {\n this.emitError(errors)\n this.render()\n return\n }\n\n // Emitir evento submit\n const submitEvent = new CustomEvent<SubmitEventDetail>('submit', {\n detail: {\n values: state.values,\n isValid: true,\n errors: {},\n },\n bubbles: true,\n composed: true,\n })\n this.dispatchEvent(submitEvent)\n }\n\n /**\n * Emite evento de error\n */\n private emitError(errors: Record<string, string[]>) {\n const errorEvent = new CustomEvent<ErrorEventDetail>('error', {\n detail: {\n errors,\n },\n bubbles: true,\n composed: true,\n })\n this.dispatchEvent(errorEvent)\n }\n\n /**\n * Emite evento de cambio de step\n */\n private emitStepChange() {\n const wizardState = this.stateManager.getWizardState()\n if (!wizardState) return\n\n const stepChangeEvent = new CustomEvent<StepChangeEventDetail>(\n 'stepChange',\n {\n detail: {\n currentStep: wizardState.currentStep,\n previousStep:\n wizardState.currentStep > 0\n ? wizardState.currentStep - 1\n : wizardState.currentStep,\n totalSteps: wizardState.totalSteps,\n },\n bubbles: true,\n composed: true,\n }\n )\n this.dispatchEvent(stepChangeEvent)\n }\n\n /**\n * Registra componentes personalizados\n */\n public registerComponents(components: ComponentRegistry): void {\n this.customComponents = { ...this.customComponents, ...components }\n registerComponents(components)\n }\n\n /**\n * Obtiene el tema del formulario\n */\n get theme(): FormTheme {\n const themeAttr = this.getAttribute('theme')\n if (themeAttr && ['plano', 'tradicional', 'material', 'rounded-shadow', 'lines'].includes(themeAttr)) {\n return themeAttr as FormTheme\n }\n return 'plano' // Tema por defecto\n }\n\n /**\n * Establece el tema del formulario\n */\n set theme(value: FormTheme) {\n if (value) {\n this.setAttribute('theme', value)\n } else {\n this.removeAttribute('theme')\n }\n }\n\n /**\n * Obtiene los colores personalizados\n */\n get colors(): FormColors | null {\n const colorsAttr = this.getAttribute('colors')\n if (!colorsAttr) return null\n return parseAttributeValue(colorsAttr)\n }\n\n /**\n * Establece los colores personalizados\n */\n set colors(value: FormColors | null) {\n if (value) {\n this.setAttribute('colors', attributeValue(value))\n } else {\n this.removeAttribute('colors')\n }\n }\n\n /**\n * Configura estilos básicos\n */\n private setupStyles() {\n // Eliminar estilos anteriores si existen\n const existingStyle = this.shadow.querySelector('style')\n if (existingStyle) {\n existingStyle.remove()\n }\n\n const theme = this.theme\n const colors = getColors(this.colors || undefined)\n const styles = getThemeStyles(theme, colors)\n\n const style = document.createElement('style')\n style.textContent = styles\n \n // Insertar estilos ANTES de cualquier otro contenido para asegurar que se apliquen\n if (this.shadow.firstChild) {\n this.shadow.insertBefore(style, this.shadow.firstChild)\n } else {\n this.shadow.appendChild(style)\n }\n }\n}\n\n// Registrar el Web Component solo en el navegador\nif (typeof window !== 'undefined' && typeof customElements !== 'undefined' && !customElements.get('easy-form')) {\n customElements.define('easy-form', EasyForm)\n}\n"],"mappings":"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","names":["currentFields"]}
1
+ {"version":3,"sources":["../src/core/schema-parser.ts","../src/utils/styles.ts","../src/utils/masks.ts","../src/utils/index.ts","../src/core/validation-engine.ts","../src/core/condition-engine.ts","../src/core/state-manager.ts","../src/components/inputs/base-input.ts","../src/utils/mask-helpers.ts","../src/core/mask-engine.ts","../src/components/inputs/text-input.ts","../src/components/inputs/number-input.ts","../src/components/inputs/textarea-input.ts","../src/components/inputs/select-input.ts","../src/components/inputs/checkbox-input.ts","../src/components/inputs/radio-input.ts","../src/components/inputs/switch-input.ts","../src/components/inputs/date-input.ts","../src/components/inputs/file-input.ts","../src/components/inputs/index.ts","../src/components/easy-form.ts"],"sourcesContent":["import type { FormSchema, Field, Step } from '../types'\n\n/**\n * Parser del schema JSON\n */\nexport class SchemaParser {\n /**\n * Parsea y valida un schema\n */\n parse(schema: FormSchema): ParsedSchema {\n if (!schema) {\n throw new Error('Schema es requerido')\n }\n\n // Validar que tenga fields o steps\n if (!schema.fields && !schema.steps) {\n throw new Error('Schema debe tener fields o steps')\n }\n\n // Si tiene steps, validar que todos los steps tengan fields\n if (schema.steps) {\n for (const step of schema.steps) {\n if (!step.fields || step.fields.length === 0) {\n throw new Error('Cada step debe tener al menos un field')\n }\n }\n }\n\n // Normalizar campos\n const normalizedFields = schema.fields\n ? this.normalizeFields(schema.fields)\n : []\n\n const normalizedSteps = schema.steps\n ? schema.steps.map((step) => ({\n ...step,\n fields: this.normalizeFields(step.fields),\n }))\n : undefined\n\n return {\n fields: normalizedFields,\n steps: normalizedSteps,\n isWizard: Boolean(schema.steps && schema.steps.length > 0),\n }\n }\n\n /**\n * Normaliza y valida campos\n */\n private normalizeFields(fields: Field[]): Field[] {\n return fields.map((field, index) => {\n // Validar que tenga type y name\n if (!field.type) {\n throw new Error(`Field en índice ${index} debe tener un type`)\n }\n if (!field.name) {\n throw new Error(`Field en índice ${index} debe tener un name`)\n }\n\n // Validar tipos específicos\n this.validateFieldType(field, index)\n\n // Aplicar valores por defecto\n return this.applyDefaults(field)\n })\n }\n\n /**\n * Valida el tipo de campo\n */\n private validateFieldType(field: Field, index: number): void {\n const validTypes = [\n 'text',\n 'email',\n 'number',\n 'password',\n 'textarea',\n 'select',\n 'checkbox',\n 'radio',\n 'switch',\n 'date',\n 'file',\n 'array',\n 'group',\n 'row',\n 'custom',\n ]\n\n if (!validTypes.includes(field.type)) {\n throw new Error(\n `Field en índice ${index} tiene un type inválido: ${field.type}`\n )\n }\n\n // Validaciones específicas por tipo\n switch (field.type) {\n case 'select':\n case 'radio':\n if (!('options' in field) || !field.options || field.options.length === 0) {\n throw new Error(\n `Field \"${field.name}\" de tipo ${field.type} debe tener options`\n )\n }\n break\n case 'array':\n if (!('itemSchema' in field) || !field.itemSchema) {\n throw new Error(\n `Field \"${field.name}\" de tipo array debe tener itemSchema`\n )\n }\n break\n case 'group':\n if (!('fields' in field) || !field.fields || field.fields.length === 0) {\n throw new Error(\n `Field \"${field.name}\" de tipo group debe tener fields`\n )\n }\n break\n case 'row':\n if (!('fields' in field) || !field.fields || field.fields.length === 0) {\n throw new Error(\n `Field \"${field.name}\" de tipo row debe tener fields`\n )\n }\n break\n }\n }\n\n /**\n * Aplica valores por defecto a un campo\n */\n private applyDefaults(field: Field): Field {\n const defaults: any = {\n disabled: false,\n hidden: false,\n }\n\n // Aplicar defaults específicos por tipo\n switch (field.type) {\n case 'checkbox':\n case 'switch':\n if (!('checked' in field)) {\n defaults.checked = false\n }\n break\n case 'select':\n if (!('multiple' in field)) {\n defaults.multiple = false\n }\n break\n case 'file':\n if (!('multiple' in field)) {\n defaults.multiple = false\n }\n break\n }\n\n return { ...defaults, ...field } as Field\n }\n\n /**\n * Obtiene todos los campos de un schema (incluyendo nested)\n */\n getAllFields(schema: FormSchema): Field[] {\n const parsed = this.parse(schema)\n const allFields: Field[] = []\n\n const extractFields = (fields: Field[]) => {\n for (const field of fields) {\n allFields.push(field)\n if (field.type === 'group' && 'fields' in field) {\n extractFields(field.fields)\n }\n if (field.type === 'row' && 'fields' in field) {\n extractFields(field.fields)\n }\n if (field.type === 'array' && 'itemSchema' in field && field.itemSchema.fields) {\n extractFields(field.itemSchema.fields)\n }\n }\n }\n\n if (parsed.fields) {\n extractFields(parsed.fields)\n }\n\n if (parsed.steps) {\n for (const step of parsed.steps) {\n extractFields(step.fields)\n }\n }\n\n return allFields\n }\n}\n\n/**\n * Schema parseado\n */\nexport interface ParsedSchema {\n fields: Field[]\n steps?: Step[]\n isWizard: boolean\n}\n","import type { FormTheme, FormColors } from '../types'\n\n/**\n * Colores por defecto\n */\nconst defaultColors: Required<FormColors> = {\n primary: '#007bff',\n secondary: '#6c757d',\n error: '#dc3545',\n success: '#28a745',\n text: '#212529',\n border: '#ddd',\n background: '#ffffff',\n}\n\n/**\n * Obtiene los colores con valores por defecto\n */\nexport function getColors(colors?: FormColors): Required<FormColors> {\n return { ...defaultColors, ...colors }\n}\n\n/**\n * Genera estilos CSS para un tema específico\n */\nexport function getThemeStyles(theme: FormTheme, colors: Required<FormColors>): string {\n const baseStyles = getBaseStyles(colors)\n const themeStyles = getThemeSpecificStyles(theme, colors)\n return baseStyles + themeStyles\n}\n\n/**\n * Estilos base comunes a todos los temas\n */\nfunction getBaseStyles(colors: Required<FormColors>): string {\n return `\n :host {\n display: block;\n --easy-form-primary: ${colors.primary};\n --easy-form-secondary: ${colors.secondary};\n --easy-form-error: ${colors.error};\n --easy-form-success: ${colors.success};\n --easy-form-text: ${colors.text};\n --easy-form-border: ${colors.border};\n --easy-form-background: ${colors.background};\n }\n .easy-form-field {\n margin-bottom: 1rem;\n }\n .easy-form-label {\n display: block;\n margin-bottom: 0.5rem;\n font-weight: 500;\n color: var(--easy-form-text);\n }\n .easy-form-required {\n color: var(--easy-form-error);\n }\n .easy-form-input-error {\n border-color: var(--easy-form-error) !important;\n }\n .easy-form-error {\n color: var(--easy-form-error);\n font-size: 0.875rem;\n margin-top: 0.25rem;\n }\n .easy-form-description {\n font-size: 0.875rem;\n color: #666;\n margin-top: 0.25rem;\n }\n .easy-form-submit {\n padding: 0.5rem 1rem;\n background: var(--easy-form-primary);\n color: white;\n border: none;\n cursor: pointer;\n font-size: 1rem;\n transition: all 0.2s ease;\n }\n .easy-form-submit:hover {\n opacity: 0.9;\n }\n .easy-form-submit:active {\n transform: scale(0.98);\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n width: 100%;\n padding: 0.5rem;\n font-size: 1rem;\n color: var(--easy-form-text);\n background: var(--easy-form-background);\n transition: all 0.2s ease;\n }\n input[type=\"checkbox\"],\n input[type=\"radio\"] {\n width: 18px !important;\n height: 18px !important;\n min-width: 18px !important;\n min-height: 18px !important;\n max-width: 18px !important;\n margin: 0;\n padding: 0;\n cursor: pointer;\n accent-color: var(--easy-form-primary);\n flex-shrink: 0;\n }\n input:focus, textarea:focus, select:focus {\n outline: none;\n }\n .easy-form-group {\n padding: 1rem;\n margin-bottom: 1rem;\n }\n .easy-form-row {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n margin-bottom: 1rem;\n align-items: stretch;\n }\n .easy-form-row > div {\n flex: 1;\n min-width: 0;\n }\n @media (max-width: 768px) {\n .easy-form-row {\n flex-direction: column;\n }\n .easy-form-row > div {\n flex: none;\n width: 100%;\n }\n }\n .easy-form-radio-group {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n margin-top: 0.5rem;\n }\n .easy-form-radio-option {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.5rem;\n border-radius: 6px;\n transition: background-color 0.2s ease;\n }\n .easy-form-radio-option:hover {\n background-color: rgba(0, 0, 0, 0.03);\n }\n .easy-form-radio-option input[type=\"radio\"] {\n margin: 0;\n flex-shrink: 0;\n }\n .easy-form-radio-label {\n cursor: pointer;\n user-select: none;\n color: var(--easy-form-text);\n font-weight: 400;\n }\n .easy-form-label-checkbox,\n .easy-form-label-switch {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n cursor: pointer;\n user-select: none;\n padding: 0.5rem;\n border-radius: 6px;\n transition: background-color 0.2s ease;\n color: var(--easy-form-text);\n }\n .easy-form-label-checkbox input[type=\"checkbox\"],\n .easy-form-label-switch input[type=\"checkbox\"] {\n margin: 0;\n flex-shrink: 0;\n }\n .easy-form-label-checkbox:hover,\n .easy-form-label-switch:hover {\n background-color: rgba(0, 0, 0, 0.03);\n }\n .easy-form-wizard-steps {\n display: flex;\n gap: 1rem;\n margin-bottom: 2rem;\n }\n .easy-form-wizard-step {\n padding: 0.5rem 1rem;\n transition: all 0.2s ease;\n }\n .easy-form-wizard-step.active {\n background: var(--easy-form-primary);\n color: white;\n }\n .easy-form-wizard-step.completed {\n background: var(--easy-form-success);\n color: white;\n }\n .easy-form-wizard-nav {\n display: flex;\n gap: 1rem;\n margin-top: 1rem;\n }\n .easy-form-array-item {\n padding: 1rem;\n margin-bottom: 1rem;\n }\n .easy-form-array-add,\n .easy-form-array-remove {\n padding: 0.25rem 0.5rem;\n background: var(--easy-form-secondary);\n color: white;\n border: none;\n cursor: pointer;\n font-size: 0.875rem;\n transition: all 0.2s ease;\n }\n .easy-form-array-remove {\n background: var(--easy-form-error);\n }\n .easy-form-array-add:hover,\n .easy-form-array-remove:hover {\n opacity: 0.9;\n }\n `\n}\n\n/**\n * Estilos específicos por tema\n */\nfunction getThemeSpecificStyles(theme: FormTheme, colors: Required<FormColors>): string {\n switch (theme) {\n case 'plano':\n return getPlanoStyles(colors)\n case 'tradicional':\n return getTradicionalStyles(colors)\n case 'material':\n return getMaterialStyles(colors)\n case 'rounded-shadow':\n return getRoundedShadowStyles(colors)\n case 'lines':\n return getLinesStyles(colors)\n default:\n return getPlanoStyles(colors)\n }\n}\n\n/**\n * Estilo Plano - Minimalista sin bordes ni sombras\n */\nfunction getPlanoStyles(_colors: Required<FormColors>): string {\n return `\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n border: none;\n border-bottom: 2px solid var(--easy-form-border);\n border-radius: 0;\n padding: 0.75rem 0;\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]):focus, textarea:focus, select:focus {\n border-bottom-color: var(--easy-form-primary);\n }\n .easy-form-submit {\n border-radius: 0;\n font-weight: 600;\n }\n .easy-form-group {\n border: none;\n border-bottom: 1px solid var(--easy-form-border);\n border-radius: 0;\n }\n .easy-form-wizard-step {\n border: none;\n border-bottom: 2px solid var(--easy-form-border);\n border-radius: 0;\n }\n .easy-form-array-item {\n border: none;\n border-bottom: 1px solid var(--easy-form-border);\n border-radius: 0;\n }\n `\n}\n\n/**\n * Estilo Tradicional - Bordes clásicos y estructura tradicional\n */\nfunction getTradicionalStyles(_colors: Required<FormColors>): string {\n return `\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n border: 2px solid var(--easy-form-border);\n border-radius: 4px;\n padding: 0.625rem;\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]):focus, textarea:focus, select:focus {\n border-color: var(--easy-form-primary);\n box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);\n }\n .easy-form-submit {\n border-radius: 4px;\n font-weight: 500;\n }\n .easy-form-group {\n border: 2px solid var(--easy-form-border);\n border-radius: 4px;\n background: #f8f9fa;\n }\n .easy-form-wizard-step {\n border: 2px solid var(--easy-form-border);\n border-radius: 4px;\n background: #f8f9fa;\n }\n .easy-form-wizard-step.active {\n border-color: var(--easy-form-primary);\n }\n .easy-form-array-item {\n border: 2px solid var(--easy-form-border);\n border-radius: 4px;\n background: #f8f9fa;\n }\n `\n}\n\n/**\n * Estilo Material - Inspirado en Material Design\n */\nfunction getMaterialStyles(_colors: Required<FormColors>): string {\n return `\n .easy-form-label {\n font-size: 0.875rem;\n font-weight: 500;\n margin-bottom: 0.25rem;\n color: var(--easy-form-text);\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n border: none;\n border-bottom: 1px solid rgba(0, 0, 0, 0.42);\n border-radius: 4px 4px 0 0;\n padding: 0.75rem 0.75rem 0.5rem 0.75rem;\n background: transparent;\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]):focus, textarea:focus, select:focus {\n border-bottom-color: var(--easy-form-primary);\n border-bottom-width: 2px;\n padding-bottom: calc(0.5rem - 1px);\n }\n .easy-form-submit {\n border-radius: 4px;\n text-transform: uppercase;\n font-weight: 500;\n letter-spacing: 0.5px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n }\n .easy-form-submit:hover {\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);\n }\n .easy-form-group {\n border: none;\n border-radius: 4px;\n background: #f5f5f5;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);\n }\n .easy-form-wizard-step {\n border: none;\n border-radius: 4px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);\n }\n .easy-form-array-item {\n border: none;\n border-radius: 4px;\n background: #f5f5f5;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);\n }\n `\n}\n\n/**\n * Estilo Rounded Shadow - Bordes redondeados con sombras\n */\nfunction getRoundedShadowStyles(_colors: Required<FormColors>): string {\n return `\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n border: 1px solid var(--easy-form-border);\n border-radius: 12px;\n padding: 0.75rem 1rem;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]):focus, textarea:focus, select:focus {\n border-color: var(--easy-form-primary);\n box-shadow: 0 4px 12px rgba(0, 123, 255, 0.15);\n transform: translateY(-1px);\n }\n .easy-form-submit {\n border-radius: 12px;\n font-weight: 600;\n box-shadow: 0 4px 12px rgba(0, 123, 255, 0.3);\n }\n .easy-form-submit:hover {\n box-shadow: 0 6px 16px rgba(0, 123, 255, 0.4);\n transform: translateY(-2px);\n }\n .easy-form-group {\n border: 1px solid var(--easy-form-border);\n border-radius: 16px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n background: var(--easy-form-background);\n }\n .easy-form-wizard-step {\n border: 1px solid var(--easy-form-border);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n .easy-form-wizard-step.active {\n box-shadow: 0 4px 16px rgba(0, 123, 255, 0.3);\n }\n .easy-form-array-item {\n border: 1px solid var(--easy-form-border);\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n background: var(--easy-form-background);\n }\n `\n}\n\n/**\n * Estilo Lines - Solo líneas como separadores\n */\nfunction getLinesStyles(_colors: Required<FormColors>): string {\n return `\n .easy-form-field {\n border-bottom: 1px solid var(--easy-form-border);\n padding-bottom: 1rem;\n margin-bottom: 1.5rem;\n }\n .easy-form-field:last-child {\n border-bottom: none;\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]), textarea, select {\n border: none;\n border-radius: 0;\n padding: 0.5rem 0;\n background: transparent;\n }\n input:not([type=\"checkbox\"]):not([type=\"radio\"]):focus, textarea:focus, select:focus {\n border-bottom: 2px solid var(--easy-form-primary);\n padding-bottom: calc(0.5rem - 1px);\n }\n .easy-form-submit {\n border-radius: 0;\n border-bottom: 3px solid var(--easy-form-primary);\n background: transparent;\n color: var(--easy-form-primary);\n font-weight: 600;\n padding: 0.75rem 0;\n }\n .easy-form-submit:hover {\n background: rgba(0, 123, 255, 0.05);\n }\n .easy-form-group {\n border: none;\n border-bottom: 2px solid var(--easy-form-border);\n border-radius: 0;\n padding-bottom: 1rem;\n }\n .easy-form-wizard-step {\n border: none;\n border-bottom: 3px solid var(--easy-form-border);\n border-radius: 0;\n background: transparent;\n }\n .easy-form-wizard-step.active {\n border-bottom-color: var(--easy-form-primary);\n background: transparent;\n color: var(--easy-form-primary);\n }\n .easy-form-wizard-step.completed {\n border-bottom-color: var(--easy-form-success);\n background: transparent;\n color: var(--easy-form-success);\n }\n .easy-form-array-item {\n border: none;\n border-bottom: 1px solid var(--easy-form-border);\n border-radius: 0;\n }\n `\n}\n","import type { PredefinedMask, CustomMask } from '../types'\n\n/**\n * Máscaras predefinidas\n */\nexport const PREDEFINED_MASKS: Record<PredefinedMask, CustomMask> = {\n 'phone': {\n pattern: '(999) 999-9999',\n placeholder: '_',\n },\n 'phone-us': {\n pattern: '(999) 999-9999',\n placeholder: '_',\n },\n 'phone-international': {\n pattern: '+99 999 999 9999',\n placeholder: '_',\n },\n 'date': {\n pattern: '99/99/9999',\n placeholder: '_',\n },\n 'date-us': {\n pattern: '99/99/9999',\n placeholder: '_',\n },\n 'date-eu': {\n pattern: '99-99-9999',\n placeholder: '_',\n },\n 'credit-card': {\n pattern: '9999 9999 9999 9999',\n placeholder: '_',\n },\n 'ssn': {\n pattern: '999-99-9999',\n placeholder: '_',\n },\n 'zip-code': {\n pattern: '99999',\n placeholder: '_',\n },\n 'currency': {\n pattern: '$999,999.99',\n placeholder: '_',\n transform: (value: string) => {\n // Remover caracteres no numéricos excepto punto decimal\n const cleaned = value.replace(/[^\\d.]/g, '')\n const num = parseFloat(cleaned) || 0\n return num.toFixed(2)\n },\n },\n 'percentage': {\n pattern: '999%',\n placeholder: '_',\n transform: (value: string) => {\n const cleaned = value.replace(/[^\\d]/g, '')\n return cleaned\n },\n },\n 'time': {\n pattern: '99:99',\n placeholder: '_',\n },\n 'datetime': {\n pattern: '99/99/9999 99:99',\n placeholder: '_',\n },\n}\n\n/**\n * Obtiene una máscara predefinida\n */\nexport function getPredefinedMask(type: PredefinedMask): CustomMask {\n return PREDEFINED_MASKS[type]\n}\n","/**\n * Utilidades generales\n */\n\n/**\n * Convierte un valor a string para atributos HTML\n */\nexport function attributeValue(value: any): string {\n if (value === null || value === undefined) {\n return ''\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false'\n }\n if (typeof value === 'object') {\n return JSON.stringify(value)\n }\n return String(value)\n}\n\n/**\n * Parsea un valor desde un atributo HTML\n */\nexport function parseAttributeValue(value: string | null): any {\n if (!value) {\n return null\n }\n try {\n return JSON.parse(value)\n } catch {\n return value\n }\n}\n\n/**\n * Genera un ID único\n */\nexport function generateId(prefix = 'ef'): string {\n return `${prefix}-${Math.random().toString(36).substr(2, 9)}`\n}\n\n/**\n * Obtiene el valor anidado de un objeto usando notación de punto\n */\nexport function getNestedValue(obj: Record<string, any>, path: string): any {\n return path.split('.').reduce((current, key) => current?.[key], obj)\n}\n\n/**\n * Establece un valor anidado en un objeto usando notación de punto\n */\nexport function setNestedValue(\n obj: Record<string, any>,\n path: string,\n value: any\n): void {\n const keys = path.split('.')\n const lastKey = keys.pop()!\n const target = keys.reduce((current, key) => {\n if (!current[key] || typeof current[key] !== 'object') {\n current[key] = {}\n }\n return current[key]\n }, obj)\n target[lastKey] = value\n}\n\n/**\n * Valida si un email es válido\n */\nexport function isValidEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n return emailRegex.test(email)\n}\n\n/**\n * Sanitiza un string para usar como ID de HTML\n */\nexport function sanitizeId(str: string): string {\n return str.replace(/[^a-zA-Z0-9-_]/g, '-')\n}\n\n// Exportar funciones de estilos\nexport { getThemeStyles, getColors } from './styles'\n\n// Exportar máscaras\nexport { PREDEFINED_MASKS, getPredefinedMask } from './masks'\n","import type {\n Validation,\n Field,\n MinLengthValidation,\n MaxLengthValidation,\n MinValidation,\n MaxValidation,\n CustomValidation,\n} from '../types'\nimport { isValidEmail } from '../utils'\n\n/**\n * Resultado de una validación\n */\nexport interface ValidationResult {\n isValid: boolean\n message?: string\n}\n\n/**\n * Motor de validaciones\n */\nexport class ValidationEngine {\n /**\n * Valida un campo con todas sus validaciones\n */\n async validateField(\n field: Field,\n value: any\n ): Promise<string[]> {\n return this.validateFieldWithValidations(field, value, field.validations || [])\n }\n\n /**\n * Valida un campo con validaciones específicas\n */\n async validateFieldWithValidations(\n _field: Field,\n value: any,\n validations: Validation[]\n ): Promise<string[]> {\n const errors: string[] = []\n\n if (!validations || validations.length === 0) {\n return errors\n }\n\n for (const validation of validations) {\n const result = await this.validateValue(validation, value)\n if (!result.isValid) {\n errors.push(result.message || this.getDefaultMessage(validation))\n }\n }\n\n return errors\n }\n\n /**\n * Valida un valor con una validación específica\n */\n private async validateValue(\n validation: Validation,\n value: any\n ): Promise<ValidationResult> {\n switch (validation.type) {\n case 'required':\n return this.validateRequired(value)\n case 'email':\n return this.validateEmail(value)\n case 'minLength':\n return this.validateMinLength(value, validation.value)\n case 'maxLength':\n return this.validateMaxLength(value, validation.value)\n case 'min':\n return this.validateMin(value, validation.value)\n case 'max':\n return this.validateMax(value, validation.value)\n case 'pattern':\n return this.validatePattern(value, validation.value)\n case 'custom':\n return await this.validateCustom(value, validation)\n default:\n return { isValid: true }\n }\n }\n\n /**\n * Valida campo requerido\n */\n private validateRequired(value: any): ValidationResult {\n const isValid =\n value !== null &&\n value !== undefined &&\n value !== '' &&\n !(Array.isArray(value) && value.length === 0)\n return {\n isValid,\n message: isValid ? undefined : 'Este campo es requerido',\n }\n }\n\n /**\n * Valida email\n */\n private validateEmail(value: any): ValidationResult {\n if (!value) {\n return { isValid: true } // Si está vacío, required debe manejarlo\n }\n const isValid = typeof value === 'string' && isValidEmail(value)\n return {\n isValid,\n message: isValid ? undefined : 'Debe ser un email válido',\n }\n }\n\n /**\n * Valida longitud mínima\n */\n private validateMinLength(\n value: any,\n minLength: number\n ): ValidationResult {\n if (!value) {\n return { isValid: true }\n }\n const str = String(value)\n const isValid = str.length >= minLength\n return {\n isValid,\n message: isValid\n ? undefined\n : `Debe tener al menos ${minLength} caracteres`,\n }\n }\n\n /**\n * Valida longitud máxima\n */\n private validateMaxLength(\n value: any,\n maxLength: number\n ): ValidationResult {\n if (!value) {\n return { isValid: true }\n }\n const str = String(value)\n const isValid = str.length <= maxLength\n return {\n isValid,\n message: isValid\n ? undefined\n : `Debe tener máximo ${maxLength} caracteres`,\n }\n }\n\n /**\n * Valida valor mínimo\n */\n private validateMin(value: any, min: number): ValidationResult {\n if (value === null || value === undefined || value === '') {\n return { isValid: true }\n }\n const num = Number(value)\n const isValid = !isNaN(num) && num >= min\n return {\n isValid,\n message: isValid ? undefined : `Debe ser mayor o igual a ${min}`,\n }\n }\n\n /**\n * Valida valor máximo\n */\n private validateMax(value: any, max: number): ValidationResult {\n if (value === null || value === undefined || value === '') {\n return { isValid: true }\n }\n const num = Number(value)\n const isValid = !isNaN(num) && num <= max\n return {\n isValid,\n message: isValid ? undefined : `Debe ser menor o igual a ${max}`,\n }\n }\n\n /**\n * Valida patrón regex\n */\n private validatePattern(value: any, pattern: string | RegExp): ValidationResult {\n if (!value) {\n return { isValid: true }\n }\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern\n const isValid = regex.test(String(value))\n return {\n isValid,\n message: isValid ? undefined : 'El formato no es válido',\n }\n }\n\n /**\n * Valida con función personalizada\n */\n private async validateCustom(\n value: any,\n validation: CustomValidation\n ): Promise<ValidationResult> {\n try {\n const result = await validation.validator(value)\n return {\n isValid: Boolean(result),\n message: result ? undefined : validation.message || 'Validación fallida',\n }\n } catch (error) {\n return {\n isValid: false,\n message: validation.message || 'Error en la validación',\n }\n }\n }\n\n /**\n * Obtiene mensaje por defecto para una validación\n */\n private getDefaultMessage(validation: Validation): string {\n switch (validation.type) {\n case 'required':\n return 'Este campo es requerido'\n case 'email':\n return 'Debe ser un email válido'\n case 'minLength':\n return `Debe tener al menos ${(validation as MinLengthValidation).value} caracteres`\n case 'maxLength':\n return `Debe tener máximo ${(validation as MaxLengthValidation).value} caracteres`\n case 'min':\n return `Debe ser mayor o igual a ${(validation as MinValidation).value}`\n case 'max':\n return `Debe ser menor o igual a ${(validation as MaxValidation).value}`\n case 'pattern':\n return 'El formato no es válido'\n case 'custom':\n return 'Validación fallida'\n default:\n return 'Campo inválido'\n }\n }\n\n /**\n * Valida todos los campos de un formulario\n */\n async validateForm(\n fields: Field[],\n values: Record<string, any>\n ): Promise<Record<string, string[]>> {\n const errors: Record<string, string[]> = {}\n\n for (const field of fields) {\n const value = values[field.name]\n const fieldErrors = await this.validateField(field, value)\n if (fieldErrors.length > 0) {\n errors[field.name] = fieldErrors\n }\n }\n\n return errors\n }\n}\n","import type {\n FieldCondition,\n FieldDependencies,\n ConditionOperator,\n} from '../types'\n\n/**\n * Motor de evaluación de condiciones\n */\nexport class ConditionEngine {\n /**\n * Evalúa una condición individual\n */\n evaluateCondition(\n condition: FieldCondition,\n formValues: Record<string, any>\n ): boolean {\n const fieldValue = this.getFieldValue(condition.field, formValues)\n return this.compareValues(fieldValue, condition.operator, condition.value)\n }\n\n /**\n * Evalúa múltiples condiciones (AND por defecto, soportar OR)\n */\n evaluateConditions(\n conditions: FieldCondition | FieldCondition[],\n formValues: Record<string, any>,\n logic: 'and' | 'or' = 'and'\n ): boolean {\n const conditionsArray = Array.isArray(conditions) ? conditions : [conditions]\n\n if (conditionsArray.length === 0) {\n return true\n }\n\n if (logic === 'and') {\n return conditionsArray.every((condition) =>\n this.evaluateCondition(condition, formValues)\n )\n } else {\n return conditionsArray.some((condition) =>\n this.evaluateCondition(condition, formValues)\n )\n }\n }\n\n /**\n * Evalúa dependencias de un campo\n */\n evaluateDependencies(\n dependencies: FieldDependencies,\n formValues: Record<string, any>\n ): {\n visible: boolean\n enabled: boolean\n required: boolean\n } {\n let visible = true\n let enabled = true\n let required = false\n\n // Evaluar show/hide\n if (dependencies.show) {\n visible = this.evaluateConditions(dependencies.show, formValues)\n }\n if (dependencies.hide) {\n const shouldHide = this.evaluateConditions(dependencies.hide, formValues)\n visible = visible && !shouldHide\n }\n\n // Evaluar enable/disable\n if (dependencies.enable) {\n enabled = this.evaluateConditions(dependencies.enable, formValues)\n }\n if (dependencies.disable) {\n const shouldDisable = this.evaluateConditions(\n dependencies.disable,\n formValues\n )\n enabled = enabled && !shouldDisable\n }\n\n // Evaluar required/optional\n if (dependencies.required) {\n required = this.evaluateConditions(dependencies.required, formValues)\n }\n if (dependencies.optional) {\n const shouldBeOptional = this.evaluateConditions(\n dependencies.optional,\n formValues\n )\n required = required && !shouldBeOptional\n }\n\n return { visible, enabled, required }\n }\n\n /**\n * Obtiene el valor de un campo (soporta nested paths)\n */\n private getFieldValue(\n fieldName: string,\n formValues: Record<string, any>\n ): any {\n const parts = fieldName.split('.')\n let value = formValues\n\n for (const part of parts) {\n if (value === null || value === undefined) {\n return null\n }\n value = value[part]\n }\n\n return value\n }\n\n /**\n * Compara valores según el operador\n */\n private compareValues(\n fieldValue: any,\n operator: ConditionOperator,\n compareValue: any\n ): boolean {\n switch (operator) {\n case 'equals':\n return this.deepEqual(fieldValue, compareValue)\n\n case 'notEquals':\n return !this.deepEqual(fieldValue, compareValue)\n\n case 'contains':\n if (Array.isArray(fieldValue)) {\n return fieldValue.includes(compareValue)\n }\n if (typeof fieldValue === 'string') {\n return fieldValue.includes(String(compareValue))\n }\n return false\n\n case 'notContains':\n return !this.compareValues(fieldValue, 'contains', compareValue)\n\n case 'greaterThan':\n return this.toNumber(fieldValue) > this.toNumber(compareValue)\n\n case 'lessThan':\n return this.toNumber(fieldValue) < this.toNumber(compareValue)\n\n case 'greaterThanOrEqual':\n return this.toNumber(fieldValue) >= this.toNumber(compareValue)\n\n case 'lessThanOrEqual':\n return this.toNumber(fieldValue) <= this.toNumber(compareValue)\n\n case 'in':\n if (Array.isArray(compareValue)) {\n return compareValue.includes(fieldValue)\n }\n return false\n\n case 'notIn':\n return !this.compareValues(fieldValue, 'in', compareValue)\n\n case 'isEmpty':\n return (\n fieldValue === null ||\n fieldValue === undefined ||\n fieldValue === '' ||\n (Array.isArray(fieldValue) && fieldValue.length === 0)\n )\n\n case 'isNotEmpty':\n return !this.compareValues(fieldValue, 'isEmpty', compareValue)\n\n case 'regex':\n try {\n const regex =\n typeof compareValue === 'string'\n ? new RegExp(compareValue)\n : compareValue\n return regex.test(String(fieldValue || ''))\n } catch {\n return false\n }\n\n default:\n return false\n }\n }\n\n /**\n * Comparación profunda de valores\n */\n private deepEqual(a: any, b: any): boolean {\n if (a === b) {\n return true\n }\n\n if (a === null || b === null || a === undefined || b === undefined) {\n return a === b\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false\n }\n return a.every((val, index) => this.deepEqual(val, b[index]))\n }\n\n if (typeof a === 'object') {\n const keysA = Object.keys(a)\n const keysB = Object.keys(b)\n\n if (keysA.length !== keysB.length) {\n return false\n }\n\n return keysA.every((key) => this.deepEqual(a[key], b[key]))\n }\n\n return false\n }\n\n /**\n * Convierte un valor a número\n */\n private toNumber(value: any): number {\n if (typeof value === 'number') {\n return value\n }\n if (typeof value === 'string') {\n const parsed = parseFloat(value)\n return isNaN(parsed) ? 0 : parsed\n }\n return 0\n }\n}\n","import type {\n FormState,\n WizardState,\n Field,\n FormSchema,\n} from '../types'\nimport { SchemaParser, type ParsedSchema } from './schema-parser'\nimport { ValidationEngine } from './validation-engine'\nimport { ConditionEngine } from './condition-engine'\nimport { getNestedValue, setNestedValue } from '../utils'\n\n/**\n * Gestor de estado del formulario\n */\nexport class StateManager {\n private state: FormState\n private wizardState: WizardState | null = null\n private schema: ParsedSchema | null = null\n private parser: SchemaParser\n private validator: ValidationEngine\n private conditionEngine: ConditionEngine\n private dependencyCache: Map<string, { visible: boolean; enabled: boolean; required: boolean }> = new Map()\n private fieldDependencies: Map<string, Set<string>> = new Map() // campo observado -> campos dependientes\n\n constructor() {\n this.parser = new SchemaParser()\n this.validator = new ValidationEngine()\n this.conditionEngine = new ConditionEngine()\n this.state = this.createInitialState()\n }\n\n /**\n * Crea el estado inicial\n */\n private createInitialState(): FormState {\n return {\n values: {},\n errors: {},\n touched: {},\n isValid: true,\n isSubmitting: false,\n }\n }\n\n /**\n * Inicializa el schema\n */\n initializeSchema(schema: FormSchema, initialData?: Record<string, any>): void {\n this.schema = this.parser.parse(schema)\n this.initializeValues(initialData)\n this.initializeWizard()\n this.buildDependencyMap()\n }\n\n /**\n * Extrae todos los campos recursivamente (incluyendo groups, rows, arrays)\n */\n private extractAllFields(fields: Field[]): Field[] {\n const allFields: Field[] = []\n \n for (const field of fields) {\n allFields.push(field)\n \n if (field.type === 'group' && 'fields' in field) {\n allFields.push(...this.extractAllFields(field.fields))\n }\n if (field.type === 'row' && 'fields' in field) {\n allFields.push(...this.extractAllFields(field.fields))\n }\n if (field.type === 'array' && 'itemSchema' in field && field.itemSchema.fields) {\n allFields.push(...this.extractAllFields(field.itemSchema.fields))\n }\n }\n \n return allFields\n }\n\n /**\n * Construye el mapa de dependencias para optimizar re-evaluaciones\n */\n private buildDependencyMap(): void {\n this.fieldDependencies.clear()\n this.dependencyCache.clear()\n\n if (!this.schema) return\n\n const topLevelFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields || []\n\n const allFields = this.extractAllFields(topLevelFields)\n\n for (const field of allFields) {\n if (!field.dependencies) continue\n\n // Extraer todos los campos observados\n const observedFields = this.extractObservedFields(field.dependencies)\n \n for (const observedField of observedFields) {\n if (!this.fieldDependencies.has(observedField)) {\n this.fieldDependencies.set(observedField, new Set())\n }\n this.fieldDependencies.get(observedField)!.add(field.name)\n }\n }\n }\n\n /**\n * Extrae los nombres de campos observados de las dependencias\n */\n private extractObservedFields(dependencies: any): Set<string> {\n const fields = new Set<string>()\n\n const extractFromCondition = (condition: any) => {\n if (condition && condition.field) {\n fields.add(condition.field)\n }\n }\n\n const extractFromConditions = (conditions: any) => {\n if (Array.isArray(conditions)) {\n conditions.forEach(extractFromCondition)\n } else if (conditions) {\n extractFromCondition(conditions)\n }\n }\n\n if (dependencies.show) extractFromConditions(dependencies.show)\n if (dependencies.hide) extractFromConditions(dependencies.hide)\n if (dependencies.enable) extractFromConditions(dependencies.enable)\n if (dependencies.disable) extractFromConditions(dependencies.disable)\n if (dependencies.required) extractFromConditions(dependencies.required)\n if (dependencies.optional) extractFromConditions(dependencies.optional)\n\n return fields\n }\n\n /**\n * Inicializa los valores por defecto\n */\n private initializeValues(initialData?: Record<string, any>): void {\n if (!this.schema) return\n\n const topLevelFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields || []\n\n const allFields = this.extractAllFields(topLevelFields)\n\n // Preservar valores existentes\n const existingValues = { ...this.state.values }\n const values: Record<string, any> = {}\n\n // Primero, cargar valores desde initialData si está disponible\n if (initialData) {\n for (const key in initialData) {\n const value = initialData[key]\n if (value !== undefined && value !== null) {\n setNestedValue(values, key, value)\n }\n }\n }\n\n // Luego, inicializar campos desde defaultValue o valores por defecto\n for (const field of allFields) {\n // Verificar si ya hay un valor desde initialData\n const existingValue = getNestedValue(values, field.name)\n \n // Si el campo ya tiene un valor desde initialData o existingValues, preservarlo\n if (existingValue !== undefined && existingValue !== null) {\n // Ya está inicializado desde initialData\n continue\n }\n \n // Verificar si hay un valor previo en existingValues\n const prevValue = getNestedValue(existingValues, field.name)\n if (prevValue !== undefined && prevValue !== null) {\n setNestedValue(values, field.name, prevValue)\n } else {\n // Solo inicializar si no existe valor previo\n this.initializeFieldValue(field, values)\n }\n }\n\n // Preservar valores de campos que no están en el schema actual (por si acaso)\n for (const key in existingValues) {\n if (!(key in values)) {\n values[key] = existingValues[key]\n }\n }\n\n this.state.values = values\n }\n\n /**\n * Inicializa el valor de un campo\n */\n private initializeFieldValue(\n field: Field,\n values: Record<string, any>\n ): void {\n if (field.defaultValue !== undefined) {\n values[field.name] = field.defaultValue\n } else {\n switch (field.type) {\n case 'checkbox':\n case 'switch':\n values[field.name] = field.checked || false\n break\n case 'select':\n if ('multiple' in field && field.multiple) {\n values[field.name] = []\n } else {\n values[field.name] = null\n }\n break\n case 'array':\n values[field.name] = []\n break\n case 'group':\n values[field.name] = {}\n if ('fields' in field) {\n for (const subField of field.fields) {\n this.initializeFieldValue(subField, values[field.name] as Record<string, any>)\n }\n }\n break\n default:\n values[field.name] = null\n }\n }\n }\n\n /**\n * Inicializa el estado del wizard\n */\n private initializeWizard(): void {\n if (!this.schema || !this.schema.isWizard) {\n this.wizardState = null\n return\n }\n\n this.wizardState = {\n currentStep: 0,\n totalSteps: this.schema.steps!.length,\n completedSteps: [],\n }\n }\n\n /**\n * Obtiene el estado actual\n */\n getState(): FormState {\n return { ...this.state }\n }\n\n /**\n * Obtiene el estado del wizard\n */\n getWizardState(): WizardState | null {\n return this.wizardState ? { ...this.wizardState } : null\n }\n\n /**\n * Obtiene un valor del formulario\n */\n getValue(fieldName: string): any {\n return getNestedValue(this.state.values, fieldName)\n }\n\n /**\n * Establece un valor\n */\n async setValue(fieldName: string, value: any): Promise<void> {\n setNestedValue(this.state.values, fieldName, value)\n this.state.touched[fieldName] = true\n\n // Invalidar cache de dependencias para campos que dependen de este\n this.invalidateDependencyCache(fieldName)\n\n // Validar el campo si está touched\n if (this.state.touched[fieldName] && this.schema) {\n await this.validateField(fieldName)\n }\n\n // Validar campos dependientes que ahora pueden tener diferentes validaciones\n const dependentFields = this.fieldDependencies.get(fieldName)\n if (dependentFields) {\n for (const dependentField of dependentFields) {\n await this.validateField(dependentField)\n }\n }\n\n this.updateValidity()\n }\n\n /**\n * Invalida el cache de dependencias para campos dependientes\n */\n private invalidateDependencyCache(fieldName: string): void {\n const dependentFields = this.fieldDependencies.get(fieldName)\n if (dependentFields) {\n for (const dependentField of dependentFields) {\n this.dependencyCache.delete(dependentField)\n }\n }\n }\n\n /**\n * Establece un valor sin validar (útil para preservar valores durante re-renderizado)\n */\n setValueWithoutValidation(fieldName: string, value: any): void {\n setNestedValue(this.state.values, fieldName, value)\n // No marcar como touched ni validar\n }\n\n /**\n * Valida un campo específico\n */\n async validateField(fieldName: string): Promise<void> {\n if (!this.schema) return\n\n const topLevelFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields || []\n\n const allFields = this.extractAllFields(topLevelFields)\n const field = allFields.find((f) => f.name === fieldName)\n if (!field) return\n\n // Si el campo no es visible, no validar\n if (!this.getFieldVisibility(fieldName)) {\n delete this.state.errors[fieldName]\n return\n }\n\n const value = this.getValue(fieldName)\n \n // Obtener validaciones activas (incluyendo condicionales)\n const activeValidations = this.getActiveValidations(field)\n \n const errors = await this.validator.validateFieldWithValidations(\n field,\n value,\n activeValidations\n )\n\n if (errors.length > 0) {\n this.state.errors[fieldName] = errors\n } else {\n delete this.state.errors[fieldName]\n }\n }\n\n /**\n * Obtiene las validaciones activas para un campo (incluyendo condicionales)\n */\n private getActiveValidations(field: Field): any[] {\n let validations = [...(field.validations || [])]\n\n // Agregar validaciones condicionales si se cumplen las condiciones\n if (field.conditionalValidations) {\n for (const conditional of field.conditionalValidations) {\n const conditionMet = this.conditionEngine.evaluateConditions(\n conditional.condition,\n this.state.values\n )\n if (conditionMet) {\n validations = [...validations, ...conditional.validations]\n }\n }\n }\n\n return validations\n }\n\n /**\n * Valida todo el formulario\n */\n async validateForm(): Promise<Record<string, string[]>> {\n if (!this.schema) {\n return {}\n }\n\n const topLevelFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields || []\n\n const allFields = this.extractAllFields(topLevelFields)\n const errors = await this.validator.validateForm(\n allFields,\n this.state.values\n )\n\n this.state.errors = errors\n this.updateValidity()\n\n return errors\n }\n\n /**\n * Actualiza la validez del formulario\n */\n private updateValidity(): void {\n this.state.isValid = Object.keys(this.state.errors).length === 0\n }\n\n /**\n * Marca un campo como touched\n */\n setTouched(fieldName: string): void {\n this.state.touched[fieldName] = true\n }\n\n /**\n * Obtiene los errores de un campo\n */\n getErrors(fieldName: string): string[] {\n return this.state.errors[fieldName] || []\n }\n\n /**\n * Obtiene todos los errores\n */\n getAllErrors(): Record<string, string[]> {\n return { ...this.state.errors }\n }\n\n /**\n * Resetea el formulario\n */\n reset(): void {\n this.state = this.createInitialState()\n if (this.schema) {\n this.initializeValues()\n this.initializeWizard()\n }\n }\n\n /**\n * Avanza al siguiente step del wizard\n */\n nextStep(): boolean {\n if (!this.wizardState) return false\n if (this.wizardState.currentStep < this.wizardState.totalSteps - 1) {\n this.wizardState.currentStep++\n return true\n }\n return false\n }\n\n /**\n * Retrocede al step anterior del wizard\n */\n previousStep(): boolean {\n if (!this.wizardState) return false\n if (this.wizardState.currentStep > 0) {\n this.wizardState.currentStep--\n return true\n }\n return false\n }\n\n /**\n * Va a un step específico\n */\n goToStep(stepIndex: number): boolean {\n if (!this.wizardState) return false\n if (stepIndex >= 0 && stepIndex < this.wizardState.totalSteps) {\n this.wizardState.currentStep = stepIndex\n return true\n }\n return false\n }\n\n /**\n * Marca un step como completado\n */\n completeStep(stepIndex: number): void {\n if (!this.wizardState) return\n if (!this.wizardState.completedSteps.includes(stepIndex)) {\n this.wizardState.completedSteps.push(stepIndex)\n }\n }\n\n /**\n * Establece el estado de submitting\n */\n setSubmitting(isSubmitting: boolean): void {\n this.state.isSubmitting = isSubmitting\n }\n\n /**\n * Obtiene los campos del step actual\n */\n getCurrentStepFields(): Field[] {\n if (!this.schema || !this.schema.isWizard || !this.wizardState) {\n return this.schema?.fields || []\n }\n return this.schema.steps![this.wizardState.currentStep].fields\n }\n\n /**\n * Obtiene la visibilidad de un campo basándose en dependencias\n */\n getFieldVisibility(fieldName: string): boolean {\n // Verificar cache primero\n const cached = this.dependencyCache.get(fieldName)\n if (cached !== undefined) {\n return cached.visible\n }\n\n if (!this.schema) return true\n\n const topLevelFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields || []\n\n const allFields = this.extractAllFields(topLevelFields)\n const field = allFields.find((f) => f.name === fieldName)\n if (!field || !field.dependencies) {\n return !field?.hidden\n }\n\n const result = this.conditionEngine.evaluateDependencies(\n field.dependencies,\n this.state.values\n )\n\n // Cachear resultado\n this.dependencyCache.set(fieldName, result)\n\n return result.visible && !field.hidden\n }\n\n /**\n * Obtiene si un campo está habilitado basándose en dependencias\n */\n getFieldEnabled(fieldName: string): boolean {\n // Verificar cache primero\n const cached = this.dependencyCache.get(fieldName)\n if (cached !== undefined) {\n return cached.enabled\n }\n\n if (!this.schema) return true\n\n const topLevelFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields || []\n\n const allFields = this.extractAllFields(topLevelFields)\n const field = allFields.find((f) => f.name === fieldName)\n if (!field) return true\n\n if (field.disabled) return false\n\n if (!field.dependencies) {\n return true\n }\n\n const result = this.conditionEngine.evaluateDependencies(\n field.dependencies,\n this.state.values\n )\n\n // Cachear resultado\n this.dependencyCache.set(fieldName, result)\n\n return result.enabled\n }\n\n /**\n * Obtiene si un campo es requerido basándose en dependencias\n */\n getFieldRequired(fieldName: string): boolean {\n // Verificar cache primero\n const cached = this.dependencyCache.get(fieldName)\n if (cached !== undefined) {\n return cached.required\n }\n\n if (!this.schema) return false\n\n const topLevelFields = this.schema.isWizard\n ? this.schema.steps!.flatMap((step) => step.fields)\n : this.schema.fields || []\n\n const allFields = this.extractAllFields(topLevelFields)\n\n const field = allFields.find((f) => f.name === fieldName)\n if (!field) return false\n\n // Verificar si tiene validación required estándar\n const hasRequired = field.validations?.some((v) => v.type === 'required') || false\n\n if (!field.dependencies) {\n return hasRequired\n }\n\n const result = this.conditionEngine.evaluateDependencies(\n field.dependencies,\n this.state.values\n )\n\n // Cachear resultado\n this.dependencyCache.set(fieldName, result)\n\n return result.required || hasRequired\n }\n\n /**\n * Obtiene los campos que dependen de un campo específico\n */\n getDependentFields(fieldName: string): string[] {\n return Array.from(this.fieldDependencies.get(fieldName) || [])\n }\n}\n","import type { Field } from '../../types'\n\n/**\n * Clase base para inputs\n */\nexport abstract class BaseInput {\n protected field: Field\n protected value: any\n protected error?: string\n protected onChange: (value: any) => void\n protected onBlur: () => void\n\n constructor(\n field: Field,\n value: any,\n error: string | undefined,\n onChange: (value: any) => void,\n onBlur: () => void\n ) {\n this.field = field\n this.value = value\n this.error = error\n this.onChange = onChange\n this.onBlur = onBlur\n }\n\n /**\n * Renderiza el input\n */\n abstract render(): HTMLElement\n\n /**\n * Crea un contenedor con label y error\n */\n protected createFieldContainer(input: HTMLElement): HTMLElement {\n const container = document.createElement('div')\n container.className = 'easy-form-field'\n\n // Label\n if (this.field.label) {\n const label = document.createElement('label')\n label.className = 'easy-form-label'\n label.setAttribute('for', this.getFieldId())\n label.textContent = this.field.label\n // El required se maneja dinámicamente desde EasyForm basado en dependencias\n // Aquí solo mostramos si está en validations estáticas\n if (this.field.validations?.some((v) => v.type === 'required')) {\n const required = document.createElement('span')\n required.className = 'easy-form-required'\n required.textContent = ' *'\n label.appendChild(required)\n }\n container.appendChild(label)\n }\n\n // Input\n container.appendChild(input)\n\n // Description\n if (this.field.description) {\n const description = document.createElement('p')\n description.className = 'easy-form-description'\n description.textContent = this.field.description\n container.appendChild(description)\n }\n\n // Error\n if (this.error) {\n const errorEl = document.createElement('p')\n errorEl.className = 'easy-form-error'\n errorEl.textContent = this.error\n container.appendChild(errorEl)\n }\n\n return container\n }\n\n /**\n * Obtiene el ID del campo\n */\n protected getFieldId(): string {\n return `easy-form-${this.field.name}`\n }\n\n /**\n * Aplica props comunes a un elemento\n */\n protected applyCommonProps(element: HTMLElement): void {\n element.id = this.getFieldId()\n element.setAttribute('name', this.field.name)\n\n if (this.field.disabled) {\n element.setAttribute('disabled', 'true')\n element.classList.add('easy-form-input-disabled')\n }\n\n if (this.field.hidden) {\n element.style.display = 'none'\n element.classList.add('easy-form-field-hidden')\n }\n\n if (this.error) {\n element.classList.add('easy-form-input-error')\n }\n\n if (this.field.props) {\n for (const [key, value] of Object.entries(this.field.props)) {\n if (key.startsWith('data-') || key.startsWith('aria-')) {\n element.setAttribute(key, String(value))\n }\n }\n }\n }\n}\n","/**\n * Token de máscara\n */\nexport interface MaskToken {\n type: 'digit' | 'letter' | 'any' | 'literal'\n char: string\n editable: boolean\n}\n\n/**\n * Parsea un patrón de máscara en tokens\n */\nexport function parseMaskPattern(pattern: string): MaskToken[] {\n const tokens: MaskToken[] = []\n\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i]\n\n switch (char) {\n case '9':\n tokens.push({ type: 'digit', char: '9', editable: true })\n break\n case 'a':\n case 'A':\n tokens.push({ type: 'letter', char: char, editable: true })\n break\n case '*':\n tokens.push({ type: 'any', char: '*', editable: true })\n break\n default:\n tokens.push({ type: 'literal', char: char, editable: false })\n break\n }\n }\n\n return tokens\n}\n\n/**\n * Formatea un valor según los tokens de máscara\n */\nexport function formatValue(value: string, tokens: MaskToken[]): string {\n let result = ''\n let valueIndex = 0\n\n for (const token of tokens) {\n if (!token.editable) {\n result += token.char\n continue\n }\n\n if (valueIndex >= value.length) {\n break\n }\n\n const char = value[valueIndex]\n\n // Validar según el tipo de token\n if (token.type === 'digit' && !/\\d/.test(char)) {\n continue // Saltar caracteres no numéricos\n } else if (token.type === 'letter' && !/[a-zA-Z]/.test(char)) {\n continue // Saltar caracteres no alfabéticos\n } else if (token.type === 'any') {\n // Aceptar cualquier carácter\n } else if (token.type !== 'any' && token.type !== 'digit' && token.type !== 'letter') {\n continue\n }\n\n result += char\n valueIndex++\n }\n\n return result\n}\n\n/**\n * Remueve el formato de un valor (obtiene solo los caracteres editables)\n */\nexport function unformatValue(value: string, tokens: MaskToken[]): string {\n if (!value) return ''\n\n let result = ''\n let tokenIndex = 0\n\n for (let i = 0; i < value.length && tokenIndex < tokens.length; i++) {\n const char = value[i]\n const token = tokens[tokenIndex]\n\n if (token.editable) {\n // Verificar si el carácter coincide con el tipo de token\n if (token.type === 'digit' && /\\d/.test(char)) {\n result += char\n tokenIndex++\n } else if (token.type === 'letter' && /[a-zA-Z]/.test(char)) {\n result += char\n tokenIndex++\n } else if (token.type === 'any') {\n result += char\n tokenIndex++\n } else {\n // Carácter no válido para este token, avanzar al siguiente token editable\n tokenIndex++\n i-- // Revisar el mismo carácter con el siguiente token\n }\n } else {\n // Token literal, verificar si coincide\n if (char === token.char) {\n tokenIndex++\n } else {\n // El carácter no coincide con el literal esperado, puede ser un carácter editable extra\n // Intentar extraerlo si es válido\n if (tokenIndex < tokens.length - 1) {\n const nextToken = tokens[tokenIndex + 1]\n if (nextToken && nextToken.editable) {\n if (nextToken.type === 'digit' && /\\d/.test(char)) {\n result += char\n tokenIndex += 2\n } else if (nextToken.type === 'letter' && /[a-zA-Z]/.test(char)) {\n result += char\n tokenIndex += 2\n } else if (nextToken.type === 'any') {\n result += char\n tokenIndex += 2\n } else {\n tokenIndex++\n }\n } else {\n tokenIndex++\n }\n } else {\n break\n }\n }\n }\n }\n\n return result\n}\n\n/**\n * Obtiene la siguiente posición editable\n */\nexport function getNextEditablePosition(\n position: number,\n tokens: MaskToken[],\n direction: 'forward' | 'backward' = 'forward'\n): number {\n if (direction === 'forward') {\n for (let i = position + 1; i < tokens.length; i++) {\n if (tokens[i].editable) {\n return i\n }\n }\n return tokens.length\n } else {\n for (let i = position - 1; i >= 0; i--) {\n if (tokens[i].editable) {\n return i\n }\n }\n return 0\n }\n}\n\n/**\n * Obtiene el placeholder completo para una máscara\n */\nexport function getMaskPlaceholder(tokens: MaskToken[], placeholder: string = '_'): string {\n return tokens\n .map((token) => (token.editable ? placeholder : token.char))\n .join('')\n}\n\n/**\n * Calcula la posición del cursor después de aplicar máscara\n */\nexport function calculateCursorPosition(\n oldValue: string,\n newValue: string,\n oldCursorPosition: number,\n tokens: MaskToken[]\n): number {\n // Contar caracteres editables antes de la posición anterior\n let editableBeforeOld = 0\n for (let i = 0; i < Math.min(oldCursorPosition, oldValue.length); i++) {\n const tokenIndex = i\n if (tokenIndex < tokens.length && tokens[tokenIndex].editable) {\n editableBeforeOld++\n }\n }\n\n // Encontrar la posición correspondiente en el nuevo valor\n let editableCount = 0\n for (let i = 0; i < newValue.length && i < tokens.length; i++) {\n if (tokens[i].editable) {\n editableCount++\n if (editableCount > editableBeforeOld) {\n return i + 1\n }\n }\n }\n\n // Si no encontramos, buscar la siguiente posición editable\n return getNextEditablePosition(\n Math.min(oldCursorPosition, newValue.length - 1),\n tokens,\n 'forward'\n )\n}\n","import type { MaskConfig, CustomMask } from '../types'\nimport { getPredefinedMask } from '../utils/masks'\nimport {\n parseMaskPattern,\n formatValue,\n unformatValue,\n getNextEditablePosition,\n getMaskPlaceholder,\n calculateCursorPosition,\n type MaskToken,\n} from '../utils/mask-helpers'\n\n/**\n * Motor de máscaras\n */\nexport class MaskEngine {\n private tokenCache: Map<string, MaskToken[]> = new Map()\n\n /**\n * Obtiene la configuración de máscara personalizada\n */\n private getCustomMask(mask: MaskConfig): CustomMask | null {\n if (mask.custom) {\n return mask.custom\n }\n if (mask.type) {\n return getPredefinedMask(mask.type)\n }\n return null\n }\n\n /**\n * Obtiene los tokens parseados de una máscara (con cache)\n */\n private getTokens(mask: MaskConfig): MaskToken[] | null {\n const customMask = this.getCustomMask(mask)\n if (!customMask) {\n return null\n }\n\n const cacheKey = customMask.pattern\n if (this.tokenCache.has(cacheKey)) {\n return this.tokenCache.get(cacheKey)!\n }\n\n const tokens = parseMaskPattern(customMask.pattern)\n this.tokenCache.set(cacheKey, tokens)\n return tokens\n }\n\n /**\n * Aplica máscara a un valor\n */\n applyMask(value: string, mask: MaskConfig): string {\n const tokens = this.getTokens(mask)\n if (!tokens) {\n return value\n }\n\n const customMask = this.getCustomMask(mask)!\n const unformatted = this.removeMask(value, mask)\n let formatted = formatValue(unformatted, tokens)\n\n // Aplicar transformación si existe\n if (customMask.transform) {\n formatted = customMask.transform(formatted)\n // Re-formatear después de la transformación\n formatted = formatValue(formatted, tokens)\n }\n\n return formatted\n }\n\n /**\n * Remueve máscara de un valor (obtiene valor raw)\n */\n removeMask(value: string, mask: MaskConfig): string {\n const tokens = this.getTokens(mask)\n if (!tokens) {\n return value\n }\n\n return unformatValue(value, tokens)\n }\n\n /**\n * Obtiene el placeholder para una máscara\n */\n getMaskPlaceholder(mask: MaskConfig): string {\n const tokens = this.getTokens(mask)\n if (!tokens) {\n return ''\n }\n\n const customMask = this.getCustomMask(mask)!\n return getMaskPlaceholder(tokens, customMask.placeholder || '_')\n }\n\n /**\n * Valida si un carácter puede ser insertado en una posición\n */\n canInsertChar(char: string, position: number, mask: MaskConfig): boolean {\n const tokens = this.getTokens(mask)\n if (!tokens || position >= tokens.length) {\n return false\n }\n\n const token = tokens[position]\n if (!token.editable) {\n return false\n }\n\n switch (token.type) {\n case 'digit':\n return /\\d/.test(char)\n case 'letter':\n return /[a-zA-Z]/.test(char)\n case 'any':\n return true\n default:\n return false\n }\n }\n\n /**\n * Procesa entrada del usuario aplicando máscara en tiempo real\n */\n processInput(\n input: string,\n previousValue: string,\n mask: MaskConfig,\n cursorPosition: number\n ): { value: string; cursorPosition: number } {\n const tokens = this.getTokens(mask)\n if (!tokens) {\n return { value: input, cursorPosition: input.length }\n }\n\n // Obtener el valor sin formato del input actual\n const unformattedInput = unformatValue(input, tokens)\n\n // Aplicar máscara al nuevo valor\n let formatted = formatValue(unformattedInput, tokens)\n\n // Aplicar transformación si existe\n const customMask = this.getCustomMask(mask)!\n if (customMask.transform) {\n formatted = customMask.transform(formatted)\n formatted = formatValue(formatted, tokens)\n }\n\n // Calcular nueva posición del cursor\n const newCursorPosition = calculateCursorPosition(\n previousValue,\n formatted,\n cursorPosition,\n tokens\n )\n\n return {\n value: formatted,\n cursorPosition: Math.min(newCursorPosition, formatted.length),\n }\n }\n\n /**\n * Procesa entrada con manejo de backspace/delete\n */\n processKeyInput(\n key: string,\n currentValue: string,\n cursorPosition: number,\n mask: MaskConfig,\n isBackspace: boolean = false\n ): { value: string; cursorPosition: number } {\n const tokens = this.getTokens(mask)\n if (!tokens) {\n return { value: currentValue, cursorPosition: cursorPosition }\n }\n\n if (isBackspace) {\n // Manejar backspace\n if (cursorPosition === 0) {\n return { value: currentValue, cursorPosition: 0 }\n }\n\n // Encontrar la posición editable anterior\n const prevEditable = getNextEditablePosition(cursorPosition - 1, tokens, 'backward')\n \n // Remover el carácter en esa posición\n const before = currentValue.substring(0, prevEditable)\n const after = currentValue.substring(cursorPosition)\n const newValue = before + after\n\n // Re-aplicar máscara\n const unformatted = this.removeMask(newValue, mask)\n const formatted = this.applyMask(unformatted, mask)\n\n // Calcular nueva posición\n const newPos = Math.max(0, prevEditable - 1)\n const nextEditable = getNextEditablePosition(newPos, tokens, 'forward')\n\n return {\n value: formatted,\n cursorPosition: nextEditable,\n }\n }\n\n // Manejar entrada normal\n if (key.length === 1 && this.canInsertChar(key, cursorPosition, mask)) {\n // Insertar carácter en la posición actual\n const before = currentValue.substring(0, cursorPosition)\n const after = currentValue.substring(cursorPosition)\n const newValue = before + key + after\n\n return this.processInput(newValue, currentValue, mask, cursorPosition)\n }\n\n return { value: currentValue, cursorPosition: cursorPosition }\n }\n}\n","import { BaseInput } from './base-input'\nimport type { Field } from '../../types'\nimport { MaskEngine } from '../../core/mask-engine'\n\nexport class TextInput extends BaseInput {\n private maskEngine: MaskEngine | null = null\n private previousValue: string = ''\n\n constructor(\n field: Field,\n value: any,\n error: string | undefined,\n onChange: (value: any) => void,\n onBlur: () => void\n ) {\n super(field, value, error, onChange, onBlur)\n \n if (field.mask) {\n this.maskEngine = new MaskEngine()\n }\n }\n\n render(): HTMLElement {\n const input = document.createElement('input')\n input.type = this.field.type === 'email' ? 'email' : this.field.type === 'password' ? 'password' : 'text'\n \n // Aplicar máscara si existe\n let displayValue = this.value ?? ''\n if (this.maskEngine && this.field.mask) {\n if (displayValue) {\n displayValue = this.maskEngine.applyMask(String(displayValue), this.field.mask)\n }\n this.previousValue = displayValue\n }\n \n input.value = displayValue\n\n this.applyCommonProps(input)\n\n // Aplicar placeholder de máscara si existe\n if (this.maskEngine && this.field.mask && !this.field.placeholder) {\n const maskPlaceholder = this.maskEngine.getMaskPlaceholder(this.field.mask)\n if (maskPlaceholder) {\n input.placeholder = maskPlaceholder\n }\n }\n\n // Manejar eventos de entrada con máscara\n if (this.maskEngine && this.field.mask) {\n input.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n const inputValue = target.value\n\n const result = this.maskEngine!.processInput(\n inputValue,\n this.previousValue,\n this.field.mask!,\n cursorPosition\n )\n\n // Actualizar valor y cursor\n target.value = result.value\n this.previousValue = result.value\n\n // Restaurar posición del cursor\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n // Emitir valor según configuración (con o sin formato)\n const valueToEmit = this.field.mask!.keepFormat\n ? result.value\n : this.maskEngine!.removeMask(result.value, this.field.mask!)\n\n this.onChange(valueToEmit)\n })\n\n input.addEventListener('keydown', (e) => {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n\n if (e.key === 'Backspace' || e.key === 'Delete') {\n e.preventDefault()\n \n const isBackspace = e.key === 'Backspace'\n const result = this.maskEngine!.processKeyInput(\n '',\n target.value,\n cursorPosition,\n this.field.mask!,\n isBackspace\n )\n\n target.value = result.value\n this.previousValue = result.value\n\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n const valueToEmit = this.field.mask!.keepFormat\n ? result.value\n : this.maskEngine!.removeMask(result.value, this.field.mask!)\n\n this.onChange(valueToEmit)\n }\n })\n\n input.addEventListener('paste', (e) => {\n e.preventDefault()\n const pastedText = (e.clipboardData || (window as any).clipboardData).getData('text')\n \n if (pastedText) {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n \n // Insertar texto pegado\n const before = target.value.substring(0, cursorPosition)\n const after = target.value.substring(cursorPosition)\n const newValue = before + pastedText + after\n\n const result = this.maskEngine!.processInput(\n newValue,\n this.previousValue,\n this.field.mask!,\n cursorPosition\n )\n\n target.value = result.value\n this.previousValue = result.value\n\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n const valueToEmit = this.field.mask!.keepFormat\n ? result.value\n : this.maskEngine!.removeMask(result.value, this.field.mask!)\n\n this.onChange(valueToEmit)\n }\n })\n } else {\n // Sin máscara, comportamiento normal\n input.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement\n this.onChange(target.value)\n })\n }\n\n input.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(input)\n }\n}\n","import { BaseInput } from './base-input'\nimport type { NumberField } from '../../types'\nimport { MaskEngine } from '../../core/mask-engine'\n\nexport class NumberInput extends BaseInput {\n private maskEngine: MaskEngine | null = null\n private previousValue: string = ''\n\n constructor(\n field: NumberField,\n value: any,\n error: string | undefined,\n onChange: (value: any) => void,\n onBlur: () => void\n ) {\n super(field, value, error, onChange, onBlur)\n \n if (field.mask) {\n this.maskEngine = new MaskEngine()\n }\n }\n\n render(): HTMLElement {\n const input = document.createElement('input')\n \n // Si tiene máscara, usar tipo text para mejor control\n if (this.maskEngine && this.field.mask) {\n input.type = 'text'\n \n // Aplicar máscara al valor inicial\n let displayValue = this.value ?? ''\n if (displayValue !== null && displayValue !== '') {\n if (this.field.mask.type === 'currency') {\n displayValue = this.maskEngine.applyMask(String(displayValue), this.field.mask)\n } else if (this.field.mask.type === 'percentage') {\n displayValue = this.maskEngine.applyMask(String(displayValue), this.field.mask)\n }\n }\n this.previousValue = displayValue\n input.value = displayValue\n } else {\n input.type = 'number'\n input.value = this.value ?? ''\n }\n \n input.placeholder = this.field.placeholder || ''\n\n const numberField = this.field as NumberField\n if (!this.maskEngine && input.type === 'number') {\n if (numberField.min !== undefined) {\n input.min = String(numberField.min)\n }\n if (numberField.max !== undefined) {\n input.max = String(numberField.max)\n }\n if (numberField.step !== undefined) {\n input.step = String(numberField.step)\n }\n }\n\n this.applyCommonProps(input)\n\n // Aplicar placeholder de máscara si existe\n if (this.maskEngine && this.field.mask && !this.field.placeholder) {\n const maskPlaceholder = this.maskEngine.getMaskPlaceholder(this.field.mask)\n if (maskPlaceholder) {\n input.placeholder = maskPlaceholder\n }\n }\n\n // Manejar eventos con máscara\n if (this.maskEngine && this.field.mask) {\n input.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n const inputValue = target.value\n\n const result = this.maskEngine!.processInput(\n inputValue,\n this.previousValue,\n this.field.mask!,\n cursorPosition\n )\n\n target.value = result.value\n this.previousValue = result.value\n\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n // Convertir a número según el tipo de máscara\n let numValue: number | null = null\n if (this.field.mask!.type === 'currency') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted.replace(/[^\\d.]/g, '')) : null\n } else if (this.field.mask!.type === 'percentage') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted) : null\n }\n\n this.onChange(numValue)\n })\n\n input.addEventListener('keydown', (e) => {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n\n if (e.key === 'Backspace' || e.key === 'Delete') {\n e.preventDefault()\n \n const isBackspace = e.key === 'Backspace'\n const result = this.maskEngine!.processKeyInput(\n '',\n target.value,\n cursorPosition,\n this.field.mask!,\n isBackspace\n )\n\n target.value = result.value\n this.previousValue = result.value\n\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n let numValue: number | null = null\n if (this.field.mask!.type === 'currency') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted.replace(/[^\\d.]/g, '')) : null\n } else if (this.field.mask!.type === 'percentage') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted) : null\n }\n\n this.onChange(numValue)\n }\n })\n\n input.addEventListener('paste', (e) => {\n e.preventDefault()\n const pastedText = (e.clipboardData || (window as any).clipboardData).getData('text')\n \n if (pastedText) {\n const target = e.target as HTMLInputElement\n const cursorPosition = target.selectionStart || 0\n \n const before = target.value.substring(0, cursorPosition)\n const after = target.value.substring(cursorPosition)\n const newValue = before + pastedText + after\n\n const result = this.maskEngine!.processInput(\n newValue,\n this.previousValue,\n this.field.mask!,\n cursorPosition\n )\n\n target.value = result.value\n this.previousValue = result.value\n\n setTimeout(() => {\n target.setSelectionRange(result.cursorPosition, result.cursorPosition)\n }, 0)\n\n let numValue: number | null = null\n if (this.field.mask!.type === 'currency') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted.replace(/[^\\d.]/g, '')) : null\n } else if (this.field.mask!.type === 'percentage') {\n const unformatted = this.maskEngine!.removeMask(result.value, this.field.mask!)\n numValue = unformatted ? parseFloat(unformatted) : null\n }\n\n this.onChange(numValue)\n }\n })\n } else {\n // Sin máscara, comportamiento normal\n input.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement\n const numValue = target.value === '' ? null : Number(target.value)\n this.onChange(numValue)\n })\n }\n\n input.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(input)\n }\n}\n","import { BaseInput } from './base-input'\nimport type { TextareaField } from '../../types'\n\nexport class TextareaInput extends BaseInput {\n render(): HTMLElement {\n const textarea = document.createElement('textarea')\n textarea.value = this.value ?? ''\n textarea.placeholder = this.field.placeholder || ''\n\n const textareaField = this.field as TextareaField\n if (textareaField.rows) {\n textarea.rows = textareaField.rows\n }\n if (textareaField.cols) {\n textarea.cols = textareaField.cols\n }\n\n this.applyCommonProps(textarea)\n\n textarea.addEventListener('input', (e) => {\n const target = e.target as HTMLTextAreaElement\n this.onChange(target.value)\n })\n\n textarea.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(textarea)\n }\n}\n","import { BaseInput } from './base-input'\nimport type { SelectField } from '../../types'\n\nexport class SelectInput extends BaseInput {\n render(): HTMLElement {\n const select = document.createElement('select')\n const selectField = this.field as SelectField\n\n if (selectField.multiple) {\n select.multiple = true\n }\n\n // Crear opciones\n for (const option of selectField.options) {\n const optionEl = document.createElement('option')\n if (typeof option === 'string') {\n optionEl.value = option\n optionEl.textContent = option\n } else {\n optionEl.value = String(option.value)\n optionEl.textContent = option.label\n }\n select.appendChild(optionEl)\n }\n\n // Establecer valor\n if (selectField.multiple && Array.isArray(this.value)) {\n for (const option of select.options) {\n option.selected = this.value.includes(option.value)\n }\n } else {\n select.value = this.value ?? ''\n }\n\n this.applyCommonProps(select)\n\n select.addEventListener('change', (e) => {\n const target = e.target as HTMLSelectElement\n if (selectField.multiple) {\n const selectedValues = Array.from(target.selectedOptions).map(\n (opt) => opt.value\n )\n this.onChange(selectedValues)\n } else {\n this.onChange(target.value || null)\n }\n })\n\n select.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(select)\n }\n}\n","import { BaseInput } from './base-input'\n\nexport class CheckboxInput extends BaseInput {\n render(): HTMLElement {\n const checkbox = document.createElement('input')\n checkbox.type = 'checkbox'\n checkbox.checked = Boolean(this.value)\n\n this.applyCommonProps(checkbox)\n\n checkbox.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement\n this.onChange(target.checked)\n })\n\n checkbox.addEventListener('blur', () => {\n this.onBlur()\n })\n\n const container = document.createElement('div')\n container.className = 'easy-form-field'\n\n // Label (checkbox primero, luego label)\n const label = document.createElement('label')\n label.className = 'easy-form-label-checkbox'\n label.setAttribute('for', this.getFieldId())\n label.appendChild(checkbox)\n if (this.field.label) {\n const labelText = document.createTextNode(this.field.label)\n label.appendChild(labelText)\n }\n container.appendChild(label)\n\n // Description\n if (this.field.description) {\n const description = document.createElement('p')\n description.className = 'easy-form-description'\n description.textContent = this.field.description\n container.appendChild(description)\n }\n\n // Error\n if (this.error) {\n const errorEl = document.createElement('p')\n errorEl.className = 'easy-form-error'\n errorEl.textContent = this.error\n container.appendChild(errorEl)\n }\n\n return container\n }\n}\n","import { BaseInput } from './base-input'\nimport type { RadioField } from '../../types'\n\nexport class RadioInput extends BaseInput {\n render(): HTMLElement {\n const container = document.createElement('div')\n container.className = 'easy-form-field'\n\n // Label\n if (this.field.label) {\n const label = document.createElement('label')\n label.className = 'easy-form-label'\n label.textContent = this.field.label\n if (this.field.validations?.some((v) => v.type === 'required')) {\n const required = document.createElement('span')\n required.className = 'easy-form-required'\n required.textContent = ' *'\n label.appendChild(required)\n }\n container.appendChild(label)\n }\n\n // Radio buttons\n const radioGroup = document.createElement('div')\n radioGroup.className = 'easy-form-radio-group'\n\n const radioField = this.field as RadioField\n for (const option of radioField.options) {\n const optionValue = typeof option === 'string' ? option : option.value\n const optionLabel = typeof option === 'string' ? option : option.label\n\n const radioContainer = document.createElement('div')\n radioContainer.className = 'easy-form-radio-option'\n\n const radio = document.createElement('input')\n radio.type = 'radio'\n radio.name = this.field.name\n radio.id = `${this.getFieldId()}-${optionValue}`\n radio.value = String(optionValue)\n radio.checked = String(this.value) === String(optionValue)\n\n if (this.field.disabled) {\n radio.disabled = true\n }\n\n const label = document.createElement('label')\n label.setAttribute('for', radio.id)\n label.textContent = optionLabel\n label.className = 'easy-form-radio-label'\n\n radio.addEventListener('change', () => {\n this.onChange(optionValue)\n })\n\n radio.addEventListener('blur', () => {\n this.onBlur()\n })\n\n radioContainer.appendChild(radio)\n radioContainer.appendChild(label)\n radioGroup.appendChild(radioContainer)\n }\n\n container.appendChild(radioGroup)\n\n // Description\n if (this.field.description) {\n const description = document.createElement('p')\n description.className = 'easy-form-description'\n description.textContent = this.field.description\n container.appendChild(description)\n }\n\n // Error\n if (this.error) {\n const errorEl = document.createElement('p')\n errorEl.className = 'easy-form-error'\n errorEl.textContent = this.error\n container.appendChild(errorEl)\n }\n\n return container\n }\n}\n","import { BaseInput } from './base-input'\n\nexport class SwitchInput extends BaseInput {\n render(): HTMLElement {\n const switchEl = document.createElement('input')\n switchEl.type = 'checkbox'\n switchEl.className = 'easy-form-switch'\n switchEl.checked = Boolean(this.value)\n\n this.applyCommonProps(switchEl)\n\n switchEl.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement\n this.onChange(target.checked)\n })\n\n switchEl.addEventListener('blur', () => {\n this.onBlur()\n })\n\n const container = document.createElement('div')\n container.className = 'easy-form-field'\n\n // Label con switch\n const label = document.createElement('label')\n label.className = 'easy-form-label-switch'\n label.setAttribute('for', this.getFieldId())\n if (this.field.label) {\n const labelText = document.createTextNode(this.field.label)\n label.appendChild(labelText)\n }\n label.appendChild(switchEl)\n container.appendChild(label)\n\n // Description\n if (this.field.description) {\n const description = document.createElement('p')\n description.className = 'easy-form-description'\n description.textContent = this.field.description\n container.appendChild(description)\n }\n\n // Error\n if (this.error) {\n const errorEl = document.createElement('p')\n errorEl.className = 'easy-form-error'\n errorEl.textContent = this.error\n container.appendChild(errorEl)\n }\n\n return container\n }\n}\n","import { BaseInput } from './base-input'\nimport type { DateField } from '../../types'\n\nexport class DateInput extends BaseInput {\n render(): HTMLElement {\n const input = document.createElement('input')\n input.type = 'date'\n \n const dateField = this.field as DateField\n if (dateField.min) {\n input.min = dateField.min\n }\n if (dateField.max) {\n input.max = dateField.max\n }\n\n if (this.value) {\n const date = this.value instanceof Date \n ? this.value.toISOString().split('T')[0]\n : String(this.value)\n input.value = date\n }\n\n this.applyCommonProps(input)\n\n input.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement\n this.onChange(target.value || null)\n })\n\n input.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(input)\n }\n}\n","import { BaseInput } from './base-input'\nimport type { FileField } from '../../types'\n\nexport class FileInput extends BaseInput {\n render(): HTMLElement {\n const input = document.createElement('input')\n input.type = 'file'\n \n const fileField = this.field as FileField\n if (fileField.accept) {\n input.accept = fileField.accept\n }\n if (fileField.multiple) {\n input.multiple = true\n }\n\n this.applyCommonProps(input)\n\n input.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement\n if (target.files) {\n if (fileField.multiple) {\n this.onChange(Array.from(target.files))\n } else {\n this.onChange(target.files[0] || null)\n }\n }\n })\n\n input.addEventListener('blur', () => {\n this.onBlur()\n })\n\n return this.createFieldContainer(input)\n }\n}\n","import { TextInput } from './text-input'\nimport { NumberInput } from './number-input'\nimport { TextareaInput } from './textarea-input'\nimport { SelectInput } from './select-input'\nimport { CheckboxInput } from './checkbox-input'\nimport { RadioInput } from './radio-input'\nimport { SwitchInput } from './switch-input'\nimport { DateInput } from './date-input'\nimport { FileInput } from './file-input'\nimport type { Field, CustomComponent } from '../../types'\n\n/**\n * Factory para crear inputs\n */\nexport function createInput(\n field: Field,\n value: any,\n error: string | undefined,\n onChange: (value: any) => void,\n onBlur: () => void\n): HTMLElement {\n switch (field.type) {\n case 'text':\n case 'email':\n case 'password':\n return new TextInput(field, value, error, onChange, onBlur).render()\n case 'number':\n return new NumberInput(field, value, error, onChange, onBlur).render()\n case 'textarea':\n return new TextareaInput(field, value, error, onChange, onBlur).render()\n case 'select':\n return new SelectInput(field, value, error, onChange, onBlur).render()\n case 'checkbox':\n return new CheckboxInput(field, value, error, onChange, onBlur).render()\n case 'radio':\n return new RadioInput(field, value, error, onChange, onBlur).render()\n case 'switch':\n return new SwitchInput(field, value, error, onChange, onBlur).render()\n case 'date':\n return new DateInput(field, value, error, onChange, onBlur).render()\n case 'file':\n return new FileInput(field, value, error, onChange, onBlur).render()\n default:\n const div = document.createElement('div')\n div.textContent = `Tipo de campo no soportado: ${field.type}`\n return div\n }\n}\n\n/**\n * Registro de componentes personalizados\n */\nlet customComponents: Map<string, CustomComponent> = new Map()\n\n/**\n * Registra un componente personalizado\n */\nexport function registerComponent(\n type: string,\n component: CustomComponent\n): void {\n customComponents.set(type, component)\n}\n\n/**\n * Registra múltiples componentes\n */\nexport function registerComponents(\n components: Record<string, CustomComponent>\n): void {\n for (const [type, component] of Object.entries(components)) {\n registerComponent(type, component)\n }\n}\n\n/**\n * Obtiene un componente personalizado\n */\nexport function getCustomComponent(type: string): CustomComponent | undefined {\n return customComponents.get(type)\n}\n","import { StateManager } from '../core/state-manager'\nimport { createInput, getCustomComponent, registerComponents } from './inputs'\nimport type {\n FormSchema,\n Field,\n ComponentRegistry,\n SubmitEventDetail,\n ChangeEventDetail,\n ErrorEventDetail,\n StepChangeEventDetail,\n FormTheme,\n FormColors,\n} from '../types'\nimport { attributeValue, parseAttributeValue } from '../utils'\nimport { getThemeStyles, getColors } from '../utils/styles'\n\n// Verificar si estamos en un entorno del navegador\nconst BrowserHTMLElement = typeof HTMLElement !== 'undefined' ? HTMLElement : class {} as typeof HTMLElement\n\n/**\n * Web Component principal EasyForm\n */\nexport class EasyForm extends BrowserHTMLElement {\n private stateManager: StateManager\n protected shadow: ShadowRoot\n private customComponents: ComponentRegistry = {}\n private isRendering: boolean = false\n\n static get observedAttributes() {\n return ['schema', 'theme', 'colors', 'initialData']\n }\n\n constructor() {\n if (typeof HTMLElement === 'undefined') {\n throw new Error('EasyForm can only be used in a browser environment')\n }\n super()\n this.stateManager = new StateManager()\n this.shadow = this.attachShadow({ mode: 'open' })\n // Los estilos se aplicarán en connectedCallback cuando los atributos estén disponibles\n }\n\n /**\n * Obtiene el schema\n */\n get schema(): FormSchema | null {\n const schemaAttr = this.getAttribute('schema')\n if (!schemaAttr) return null\n return parseAttributeValue(schemaAttr)\n }\n\n /**\n * Establece el schema\n */\n set schema(value: FormSchema | null) {\n if (value) {\n this.setAttribute('schema', attributeValue(value))\n } else {\n this.removeAttribute('schema')\n }\n }\n\n /**\n * Se llama cuando el componente se conecta al DOM\n */\n connectedCallback() {\n // Asegurar que los estilos estén aplicados con los atributos actuales\n this.setupStyles()\n this.render()\n }\n\n /**\n * Se llama cuando un atributo cambia\n */\n attributeChangedCallback(name: string, oldValue: string, newValue: string) {\n if (name === 'schema' && newValue !== oldValue) {\n this.handleSchemaChange()\n }\n if (name === 'initialData' && newValue !== oldValue) {\n this.handleSchemaChange()\n }\n if ((name === 'theme' || name === 'colors') && newValue !== oldValue) {\n this.setupStyles()\n }\n }\n\n /**\n * Maneja el cambio de schema\n */\n private handleSchemaChange() {\n const schema = this.schema\n if (schema) {\n const initialData = this.initialData\n this.stateManager.initializeSchema(schema, initialData || undefined)\n this.render()\n }\n }\n\n /**\n * Renderiza el formulario\n */\n private async render() {\n // Evitar renderizados simultáneos\n if (this.isRendering) {\n return\n }\n \n this.isRendering = true\n \n try {\n const schema = this.schema\n if (!schema) {\n // Eliminar solo el formulario, mantener los estilos\n const form = this.shadow.querySelector('form')\n if (form && form.parentNode === this.shadow) {\n form.remove()\n }\n return\n }\n\n // Preservar valores actuales del DOM antes de re-renderizar\n const preservedValues = this.preserveCurrentValues()\n\n // Guardar los valores preservados en el estado sin validar\n // Esto evita disparar validaciones de todos los campos\n if (preservedValues && Object.keys(preservedValues).length > 0) {\n for (const [key, value] of Object.entries(preservedValues)) {\n this.stateManager.setValueWithoutValidation(key, value)\n }\n }\n\n const initialData = this.initialData\n this.stateManager.initializeSchema(schema, initialData || undefined)\n const wizardState = this.stateManager.getWizardState()\n\n // Crear formulario\n const newFormElement = document.createElement('form')\n newFormElement.addEventListener('submit', (e) => this.handleSubmit(e))\n\n // Renderizar campos o steps\n if (wizardState) {\n this.renderWizard(newFormElement, wizardState)\n } else {\n this.renderFields(newFormElement, schema.fields || [])\n }\n\n // Botón submit\n const submitButton = document.createElement('button')\n submitButton.type = 'submit'\n submitButton.textContent = 'Enviar'\n submitButton.className = 'easy-form-submit'\n newFormElement.appendChild(submitButton)\n\n // Eliminar solo el formulario anterior si existe y está en el DOM, mantener los estilos\n const oldForm = this.shadow.querySelector('form')\n if (oldForm && oldForm.parentNode === this.shadow && oldForm !== newFormElement) {\n try {\n oldForm.remove()\n } catch (e) {\n // Ignorar errores si el elemento ya fue eliminado\n console.warn('Error al eliminar formulario anterior:', e)\n }\n }\n \n // Agregar el nuevo formulario\n this.shadow.appendChild(newFormElement)\n } finally {\n this.isRendering = false\n }\n }\n\n /**\n * Preserva los valores actuales del DOM antes de re-renderizar\n * Retorna un objeto con los valores preservados\n */\n private preserveCurrentValues(): Record<string, any> {\n const form = this.shadow.querySelector('form')\n const preservedValues: Record<string, any> = {}\n \n if (!form) return preservedValues\n\n // Obtener todos los inputs, textareas y selects del formulario\n const inputs = form.querySelectorAll('input, textarea, select')\n \n for (const input of inputs) {\n const name = input.getAttribute('name')\n if (!name) continue\n\n let value: any\n \n if (input instanceof HTMLInputElement) {\n if (input.type === 'checkbox') {\n value = input.checked\n } else if (input.type === 'radio') {\n if (input.checked) {\n value = input.value\n } else {\n continue // Solo guardar el radio seleccionado\n }\n } else if (input.type === 'number') {\n value = input.value === '' ? null : Number(input.value)\n } else {\n value = input.value\n }\n } else if (input instanceof HTMLTextAreaElement) {\n value = input.value\n } else if (input instanceof HTMLSelectElement) {\n if (input.multiple) {\n value = Array.from(input.selectedOptions).map(opt => opt.value)\n } else {\n value = input.value || null\n }\n }\n\n // Guardar el valor (incluso strings vacíos para preservar el estado)\n if (value !== undefined) {\n preservedValues[name] = value === '' ? null : value\n }\n }\n \n return preservedValues\n }\n\n /**\n * Renderiza campos normales\n */\n private renderFields(container: HTMLElement, fields: Field[]) {\n for (const field of fields) {\n const fieldElement = this.renderField(field)\n if (fieldElement) {\n container.appendChild(fieldElement)\n }\n }\n }\n\n /**\n * Renderiza un campo\n */\n private renderField(field: Field): HTMLElement | null {\n // Verificar visibilidad basada en dependencias\n const isVisible = this.stateManager.getFieldVisibility(field.name)\n const isEnabled = this.stateManager.getFieldEnabled(field.name)\n\n // Campos especiales\n if (field.type === 'group') {\n const groupElement = this.renderGroup(field)\n if (!isVisible) {\n groupElement.style.display = 'none'\n groupElement.classList.add('easy-form-field-hidden')\n }\n if (!isEnabled) {\n groupElement.classList.add('easy-form-field-disabled')\n }\n return groupElement\n }\n if (field.type === 'row') {\n const rowElement = this.renderRow(field)\n if (!isVisible) {\n rowElement.style.display = 'none'\n rowElement.classList.add('easy-form-field-hidden')\n }\n if (!isEnabled) {\n rowElement.classList.add('easy-form-field-disabled')\n }\n return rowElement\n }\n if (field.type === 'array') {\n const arrayElement = this.renderArray(field)\n if (!isVisible) {\n arrayElement.style.display = 'none'\n arrayElement.classList.add('easy-form-field-hidden')\n }\n if (!isEnabled) {\n arrayElement.classList.add('easy-form-field-disabled')\n }\n return arrayElement\n }\n if (field.type === 'custom') {\n const customElement = this.renderCustom(field)\n if (customElement) {\n if (!isVisible) {\n customElement.style.display = 'none'\n customElement.classList.add('easy-form-field-hidden')\n }\n if (!isEnabled) {\n customElement.classList.add('easy-form-field-disabled')\n }\n }\n return customElement\n }\n\n // Campos normales\n const value = this.stateManager.getValue(field.name)\n const errors = this.stateManager.getErrors(field.name)\n const error = errors.length > 0 ? errors[0] : undefined\n\n // Aplicar disabled basado en dependencias\n const fieldWithDependencies = {\n ...field,\n disabled: !isEnabled || field.disabled,\n }\n\n const customComponent = getCustomComponent(field.type)\n if (customComponent) {\n const element = customComponent({\n field: fieldWithDependencies,\n value,\n error,\n onChange: (val) => this.handleFieldChange(field.name, val),\n onBlur: () => this.handleFieldBlur(field.name),\n })\n if (element && !isVisible) {\n element.style.display = 'none'\n element.classList.add('easy-form-field-hidden')\n }\n return element\n }\n\n const inputElement = createInput(\n fieldWithDependencies,\n value,\n error,\n (val) => this.handleFieldChange(field.name, val),\n () => this.handleFieldBlur(field.name)\n )\n\n // Agregar atributo para identificar el campo\n const fieldContainer = inputElement.querySelector('.easy-form-field') || inputElement\n if (fieldContainer instanceof HTMLElement) {\n fieldContainer.setAttribute('data-field-name', field.name)\n }\n\n // Aplicar clases para visibilidad\n if (!isVisible) {\n inputElement.style.display = 'none'\n inputElement.classList.add('easy-form-field-hidden')\n }\n\n return inputElement\n }\n\n /**\n * Renderiza un grupo de campos\n */\n private renderGroup(field: Field): HTMLElement {\n const groupContainer = document.createElement('div')\n groupContainer.className = 'easy-form-group'\n\n if (field.label) {\n const label = document.createElement('h3')\n label.className = 'easy-form-group-label'\n label.textContent = field.label\n groupContainer.appendChild(label)\n }\n\n if ('fields' in field && field.fields) {\n for (const subField of field.fields) {\n const fieldElement = this.renderField(subField)\n if (fieldElement) {\n groupContainer.appendChild(fieldElement)\n }\n }\n }\n\n return groupContainer\n }\n\n /**\n * Renderiza una fila de campos\n */\n private renderRow(field: Field): HTMLElement {\n const rowContainer = document.createElement('div')\n rowContainer.className = 'easy-form-row'\n\n const rowField = field as any\n\n // Aplicar estilos flexbox\n rowContainer.style.display = 'flex'\n rowContainer.style.flexWrap = 'wrap'\n rowContainer.style.alignItems = rowField.align || 'stretch'\n\n // Aplicar gap\n if (rowField.gap !== undefined) {\n const gapValue = typeof rowField.gap === 'number' ? `${rowField.gap}px` : rowField.gap\n rowContainer.style.gap = gapValue\n } else {\n rowContainer.style.gap = '1rem'\n }\n\n // Renderizar campos dentro de la fila\n if ('fields' in field && field.fields) {\n for (const subField of field.fields) {\n const fieldElement = this.renderField(subField)\n if (fieldElement) {\n // Hacer que cada campo en la fila tenga flex: 1 para distribuirse equitativamente\n const fieldWrapper = document.createElement('div')\n fieldWrapper.style.flex = '1'\n fieldWrapper.style.minWidth = '0' // Permite que los campos se reduzcan\n fieldWrapper.appendChild(fieldElement)\n rowContainer.appendChild(fieldWrapper)\n }\n }\n }\n\n return rowContainer\n }\n\n /**\n * Renderiza un array dinámico\n */\n private renderArray(field: Field): HTMLElement {\n const arrayContainer = document.createElement('div')\n arrayContainer.className = 'easy-form-array'\n\n if (field.label) {\n const label = document.createElement('label')\n label.className = 'easy-form-label'\n label.textContent = field.label\n arrayContainer.appendChild(label)\n }\n\n const values = this.stateManager.getValue(field.name) || []\n const arrayField = field as any\n\n // Renderizar items existentes\n const itemsContainer = document.createElement('div')\n itemsContainer.className = 'easy-form-array-items'\n\n for (let i = 0; i < values.length; i++) {\n const itemContainer = document.createElement('div')\n itemContainer.className = 'easy-form-array-item'\n\n if (arrayField.itemSchema?.fields) {\n for (const itemField of arrayField.itemSchema.fields) {\n const itemFieldWithName = {\n ...itemField,\n name: `${field.name}.${i}.${itemField.name}`,\n }\n const fieldElement = this.renderField(itemFieldWithName)\n if (fieldElement) {\n itemContainer.appendChild(fieldElement)\n }\n }\n }\n\n // Botón eliminar\n const removeButton = document.createElement('button')\n removeButton.type = 'button'\n removeButton.textContent = 'Eliminar'\n removeButton.className = 'easy-form-array-remove'\n removeButton.addEventListener('click', () => {\n const newValues = [...values]\n newValues.splice(i, 1)\n this.handleFieldChange(field.name, newValues)\n })\n itemContainer.appendChild(removeButton)\n\n itemsContainer.appendChild(itemContainer)\n }\n\n arrayContainer.appendChild(itemsContainer)\n\n // Botón agregar\n const addButton = document.createElement('button')\n addButton.type = 'button'\n addButton.textContent = 'Agregar'\n addButton.className = 'easy-form-array-add'\n addButton.addEventListener('click', () => {\n const newValues = [...values, {}]\n this.handleFieldChange(field.name, newValues)\n })\n arrayContainer.appendChild(addButton)\n\n return arrayContainer\n }\n\n /**\n * Renderiza un campo custom\n */\n private renderCustom(field: Field): HTMLElement | null {\n const customComponent = getCustomComponent('custom')\n if (!customComponent) {\n const div = document.createElement('div')\n div.textContent = `Componente custom no registrado para: ${field.name}`\n return div\n }\n\n const value = this.stateManager.getValue(field.name)\n const errors = this.stateManager.getErrors(field.name)\n const error = errors.length > 0 ? errors[0] : undefined\n\n return customComponent({\n field,\n value,\n error,\n onChange: (val) => this.handleFieldChange(field.name, val),\n onBlur: () => this.handleFieldBlur(field.name),\n })\n }\n\n /**\n * Renderiza wizard\n */\n private renderWizard(container: HTMLElement, wizardState: any) {\n const wizardContainer = document.createElement('div')\n wizardContainer.className = 'easy-form-wizard'\n\n // Indicador de steps\n const stepsIndicator = document.createElement('div')\n stepsIndicator.className = 'easy-form-wizard-steps'\n const schema = this.schema\n if (schema?.steps) {\n for (let i = 0; i < schema.steps.length; i++) {\n const stepEl = document.createElement('div')\n stepEl.className = 'easy-form-wizard-step'\n if (i === wizardState.currentStep) {\n stepEl.classList.add('active')\n }\n if (wizardState.completedSteps.includes(i)) {\n stepEl.classList.add('completed')\n }\n stepEl.textContent = schema.steps[i].title\n stepsIndicator.appendChild(stepEl)\n }\n }\n wizardContainer.appendChild(stepsIndicator)\n\n // Campos del step actual\n const fieldsContainer = document.createElement('div')\n fieldsContainer.className = 'easy-form-wizard-fields'\n const currentFields = this.stateManager.getCurrentStepFields()\n for (const field of currentFields) {\n const fieldElement = this.renderField(field)\n if (fieldElement) {\n fieldsContainer.appendChild(fieldElement)\n }\n }\n wizardContainer.appendChild(fieldsContainer)\n\n // Botones de navegación\n const navContainer = document.createElement('div')\n navContainer.className = 'easy-form-wizard-nav'\n\n const prevButton = document.createElement('button')\n prevButton.type = 'button'\n prevButton.textContent = 'Anterior'\n prevButton.className = 'easy-form-wizard-prev'\n prevButton.disabled = wizardState.currentStep === 0\n prevButton.addEventListener('click', () => {\n if (this.stateManager.previousStep()) {\n this.render()\n this.emitStepChange()\n }\n })\n navContainer.appendChild(prevButton)\n\n const nextButton = document.createElement('button')\n nextButton.type = 'button'\n nextButton.textContent =\n wizardState.currentStep === wizardState.totalSteps - 1\n ? 'Enviar'\n : 'Siguiente'\n nextButton.className = 'easy-form-wizard-next'\n nextButton.addEventListener('click', async () => {\n if (wizardState.currentStep === wizardState.totalSteps - 1) {\n await this.handleSubmit(new Event('submit') as SubmitEvent)\n } else {\n // Validar step actual antes de avanzar\n const currentFields = this.stateManager.getCurrentStepFields()\n const errors = await this.stateManager.validateForm()\n const hasErrors = currentFields.some(\n (f) => errors[f.name] && errors[f.name].length > 0\n )\n\n if (!hasErrors) {\n this.stateManager.completeStep(wizardState.currentStep)\n if (this.stateManager.nextStep()) {\n this.render()\n this.emitStepChange()\n }\n } else {\n this.emitError(errors)\n }\n }\n })\n navContainer.appendChild(nextButton)\n\n wizardContainer.appendChild(navContainer)\n container.appendChild(wizardContainer)\n }\n\n /**\n * Maneja el cambio de un campo\n */\n private async handleFieldChange(fieldName: string, value: any) {\n await this.stateManager.setValue(fieldName, value)\n \n // Obtener campos dependientes que necesitan re-renderizarse\n const dependentFields = this.stateManager.getDependentFields(fieldName)\n \n // Re-renderizar campos dependientes si hay cambios en dependencias\n if (dependentFields.length > 0) {\n // Usar un pequeño delay para agrupar múltiples cambios\n if (this.dependencyRenderTimeout) {\n clearTimeout(this.dependencyRenderTimeout)\n }\n \n this.dependencyRenderTimeout = setTimeout(() => {\n this.renderDependentFields(dependentFields)\n this.emitDependencyChange(fieldName, dependentFields)\n }, 10)\n }\n\n // Emitir evento change\n const changeEvent = new CustomEvent<ChangeEventDetail>('change', {\n detail: {\n field: fieldName,\n value,\n values: this.stateManager.getState().values,\n },\n bubbles: true,\n composed: true,\n })\n this.dispatchEvent(changeEvent)\n }\n\n private dependencyRenderTimeout: ReturnType<typeof setTimeout> | null = null\n\n /**\n * Re-renderiza campos dependientes\n */\n private renderDependentFields(fieldNames: string[]): void {\n const form = this.shadow.querySelector('form')\n if (!form) return\n\n const schema = this.schema\n if (!schema) return\n\n for (const fieldName of fieldNames) {\n const fieldContainer = form.querySelector(\n `.easy-form-field[name=\"${fieldName}\"], [data-field-name=\"${fieldName}\"]`\n )?.closest('.easy-form-field')\n\n if (fieldContainer) {\n const field = this.findFieldInSchema(schema, fieldName)\n if (!field) continue\n\n // Re-renderizar el campo\n const newFieldElement = this.renderField(field)\n if (newFieldElement && fieldContainer.parentNode) {\n fieldContainer.parentNode.replaceChild(newFieldElement, fieldContainer)\n }\n }\n }\n }\n\n /**\n * Emite evento de cambio de dependencia\n */\n private emitDependencyChange(\n changedField: string,\n affectedFields: string[]\n ): void {\n const dependencyEvent = new CustomEvent('dependencyChange', {\n detail: {\n changedField,\n affectedFields,\n },\n bubbles: true,\n composed: true,\n })\n this.dispatchEvent(dependencyEvent)\n }\n\n /**\n * Maneja el blur de un campo\n */\n private async handleFieldBlur(fieldName: string) {\n this.stateManager.setTouched(fieldName)\n // Validar solo el campo que perdió el foco\n await this.stateManager.validateField(fieldName)\n // Actualizar solo el campo específico sin re-renderizar todo el formulario\n this.updateSingleField(fieldName)\n }\n\n /**\n * Actualiza solo un campo específico sin re-renderizar todo el formulario\n */\n private updateSingleField(fieldName: string) {\n const schema = this.schema\n if (!schema) return\n\n const field = this.findFieldInSchema(schema, fieldName)\n if (!field) return\n\n const errors = this.stateManager.getErrors(fieldName)\n const error = errors.length > 0 ? errors[0] : undefined\n\n // Buscar el contenedor del campo en el DOM\n const fieldContainer = this.shadow.querySelector(`[name=\"${fieldName}\"]`)?.closest('.easy-form-field')\n if (!fieldContainer) return\n\n // Actualizar el error\n const errorElement = fieldContainer.querySelector('.easy-form-error')\n if (error) {\n if (!errorElement) {\n const errorEl = document.createElement('p')\n errorEl.className = 'easy-form-error'\n errorEl.textContent = error\n fieldContainer.appendChild(errorEl)\n } else {\n errorElement.textContent = error\n }\n // Agregar clase de error al input\n const input = fieldContainer.querySelector('input, textarea, select') as HTMLElement\n input?.classList.add('easy-form-input-error')\n } else {\n errorElement?.remove()\n const input = fieldContainer.querySelector('input, textarea, select') as HTMLElement\n input?.classList.remove('easy-form-input-error')\n }\n }\n\n /**\n * Busca un campo por nombre en el schema\n */\n private findFieldInSchema(schema: FormSchema, name: string): Field | null {\n const fields = schema.fields || []\n for (const field of fields) {\n if (field.name === name) {\n return field\n }\n if (field.type === 'group' && 'fields' in field) {\n const found = this.findFieldInSchema({ fields: field.fields }, name)\n if (found) return found\n }\n if (field.type === 'row' && 'fields' in field) {\n const found = this.findFieldInSchema({ fields: field.fields }, name)\n if (found) return found\n }\n }\n return null\n }\n\n /**\n * Maneja el submit del formulario\n */\n private async handleSubmit(event: Event) {\n event.preventDefault()\n\n const errors = await this.stateManager.validateForm()\n const state = this.stateManager.getState()\n\n if (Object.keys(errors).length > 0) {\n this.emitError(errors)\n this.render()\n return\n }\n\n // Emitir evento submit\n const submitEvent = new CustomEvent<SubmitEventDetail>('submit', {\n detail: {\n values: state.values,\n isValid: true,\n errors: {},\n },\n bubbles: true,\n composed: true,\n })\n this.dispatchEvent(submitEvent)\n }\n\n /**\n * Emite evento de error\n */\n private emitError(errors: Record<string, string[]>) {\n const errorEvent = new CustomEvent<ErrorEventDetail>('error', {\n detail: {\n errors,\n },\n bubbles: true,\n composed: true,\n })\n this.dispatchEvent(errorEvent)\n }\n\n /**\n * Emite evento de cambio de step\n */\n private emitStepChange() {\n const wizardState = this.stateManager.getWizardState()\n if (!wizardState) return\n\n const stepChangeEvent = new CustomEvent<StepChangeEventDetail>(\n 'stepChange',\n {\n detail: {\n currentStep: wizardState.currentStep,\n previousStep:\n wizardState.currentStep > 0\n ? wizardState.currentStep - 1\n : wizardState.currentStep,\n totalSteps: wizardState.totalSteps,\n },\n bubbles: true,\n composed: true,\n }\n )\n this.dispatchEvent(stepChangeEvent)\n }\n\n /**\n * Registra componentes personalizados\n */\n public registerComponents(components: ComponentRegistry): void {\n this.customComponents = { ...this.customComponents, ...components }\n registerComponents(components)\n }\n\n /**\n * Obtiene el tema del formulario\n */\n get theme(): FormTheme {\n const themeAttr = this.getAttribute('theme')\n if (themeAttr && ['plano', 'tradicional', 'material', 'rounded-shadow', 'lines'].includes(themeAttr)) {\n return themeAttr as FormTheme\n }\n return 'plano' // Tema por defecto\n }\n\n /**\n * Establece el tema del formulario\n */\n set theme(value: FormTheme) {\n if (value) {\n this.setAttribute('theme', value)\n } else {\n this.removeAttribute('theme')\n }\n }\n\n /**\n * Obtiene los colores personalizados\n */\n get colors(): FormColors | null {\n const colorsAttr = this.getAttribute('colors')\n if (!colorsAttr) return null\n return parseAttributeValue(colorsAttr)\n }\n\n /**\n * Establece los colores personalizados\n */\n set colors(value: FormColors | null) {\n if (value) {\n this.setAttribute('colors', attributeValue(value))\n } else {\n this.removeAttribute('colors')\n }\n }\n\n /**\n * Obtiene los datos iniciales\n */\n get initialData(): Record<string, any> | null {\n const initialDataAttr = this.getAttribute('initialData')\n if (!initialDataAttr) return null\n return parseAttributeValue(initialDataAttr)\n }\n\n /**\n * Establece los datos iniciales\n */\n set initialData(value: Record<string, any> | null) {\n if (value) {\n this.setAttribute('initialData', attributeValue(value))\n } else {\n this.removeAttribute('initialData')\n }\n }\n\n /**\n * Configura estilos básicos\n */\n private setupStyles() {\n // Eliminar estilos anteriores si existen\n const existingStyle = this.shadow.querySelector('style')\n if (existingStyle) {\n existingStyle.remove()\n }\n\n const theme = this.theme\n const colors = getColors(this.colors || undefined)\n const styles = getThemeStyles(theme, colors)\n\n const style = document.createElement('style')\n style.textContent = styles\n \n // Insertar estilos ANTES de cualquier otro contenido para asegurar que se apliquen\n if (this.shadow.firstChild) {\n this.shadow.insertBefore(style, this.shadow.firstChild)\n } else {\n this.shadow.appendChild(style)\n }\n }\n}\n\n// Registrar el Web Component solo en el navegador\nif (typeof window !== 'undefined' && typeof customElements !== 'undefined' && !customElements.get('easy-form')) {\n customElements.define('easy-form', EasyForm)\n}\n"],"mappings":"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","names":["currentFields"]}