easy-forms-core 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Tipos de campos soportados
3
3
  */
4
- type FieldType = 'text' | 'email' | 'number' | 'password' | 'textarea' | 'select' | 'checkbox' | 'radio' | 'switch' | 'date' | 'file' | 'array' | 'group' | 'custom';
4
+ type FieldType = 'text' | 'email' | 'number' | 'password' | 'textarea' | 'select' | 'checkbox' | 'radio' | 'switch' | 'date' | 'file' | 'array' | 'group' | 'row' | 'custom';
5
5
  /**
6
6
  * Tipos de validaciones soportadas
7
7
  */
@@ -206,6 +206,15 @@ interface GroupField extends BaseField {
206
206
  type: 'group';
207
207
  fields: Field[];
208
208
  }
209
+ /**
210
+ * Campo row
211
+ */
212
+ interface RowField extends BaseField {
213
+ type: 'row';
214
+ fields: Field[];
215
+ gap?: string | number;
216
+ align?: 'start' | 'end' | 'center' | 'stretch';
217
+ }
209
218
  /**
210
219
  * Campo custom
211
220
  */
@@ -216,7 +225,7 @@ interface CustomField extends BaseField {
216
225
  /**
217
226
  * Unión de todos los tipos de campos
218
227
  */
219
- type Field = TextField | NumberField | TextareaField | SelectField | CheckboxField | RadioField | SwitchField | DateField | FileField | ArrayField | GroupField | CustomField;
228
+ type Field = TextField | NumberField | TextareaField | SelectField | CheckboxField | RadioField | SwitchField | DateField | FileField | ArrayField | GroupField | RowField | CustomField;
220
229
  /**
221
230
  * Step para formularios wizard
222
231
  */
@@ -247,6 +256,7 @@ interface FormColors {
247
256
  interface FormSchema {
248
257
  fields?: Field[];
249
258
  steps?: Step[];
259
+ initialData?: Record<string, any>;
250
260
  }
251
261
  /**
252
262
  * Estado del formulario
@@ -369,6 +379,10 @@ declare class EasyForm extends BrowserHTMLElement {
369
379
  * Renderiza un grupo de campos
370
380
  */
371
381
  private renderGroup;
382
+ /**
383
+ * Renderiza una fila de campos
384
+ */
385
+ private renderRow;
372
386
  /**
373
387
  * Renderiza un array dinámico
374
388
  */
@@ -438,6 +452,14 @@ declare class EasyForm extends BrowserHTMLElement {
438
452
  * Establece los colores personalizados
439
453
  */
440
454
  set colors(value: FormColors | null);
455
+ /**
456
+ * Obtiene los datos iniciales
457
+ */
458
+ get initialData(): Record<string, any> | null;
459
+ /**
460
+ * Establece los datos iniciales
461
+ */
462
+ set initialData(value: Record<string, any> | null);
441
463
  /**
442
464
  * Configura estilos básicos
443
465
  */
@@ -464,7 +486,11 @@ declare class StateManager {
464
486
  /**
465
487
  * Inicializa el schema
466
488
  */
467
- initializeSchema(schema: FormSchema): void;
489
+ initializeSchema(schema: FormSchema, initialData?: Record<string, any>): void;
490
+ /**
491
+ * Extrae todos los campos recursivamente (incluyendo groups, rows, arrays)
492
+ */
493
+ private extractAllFields;
468
494
  /**
469
495
  * Construye el mapa de dependencias para optimizar re-evaluaciones
470
496
  */
@@ -825,4 +851,4 @@ declare function registerComponents(components: Record<string, CustomComponent>)
825
851
  */
826
852
  declare function getCustomComponent(type: string): CustomComponent | undefined;
827
853
 
828
- export { type ArrayField, type BaseField, type BaseValidation, type ChangeEventDetail, type CheckboxField, type ComponentRegistry, ConditionEngine, type ConditionOperator, type CustomComponent, type CustomField, type CustomMask, type CustomValidation, type DateField, EasyForm, type EmailValidation, type ErrorEventDetail, type Field, type FieldCondition, type FieldDependencies, type FieldType, type FileField, type FormColors, type FormSchema, type FormState, type FormTheme, type GroupField, type MaskConfig, MaskEngine, type MaxLengthValidation, type MaxValidation, type MinLengthValidation, type MinValidation, type NumberField, PREDEFINED_MASKS, type PatternValidation, type PredefinedMask, type RadioField, type RequiredValidation, SchemaParser, type SelectField, StateManager, type Step, type StepChangeEventDetail, type SubmitEventDetail, type SwitchField, type TextField, type TextareaField, type Validation, ValidationEngine, type ValidationType, type WizardState, attributeValue, createInput, generateId, getColors, getCustomComponent, getNestedValue, getPredefinedMask, getThemeStyles, isValidEmail, parseAttributeValue, registerComponent, registerComponents, sanitizeId, setNestedValue };
854
+ export { type ArrayField, type BaseField, type BaseValidation, type ChangeEventDetail, type CheckboxField, type ComponentRegistry, ConditionEngine, type ConditionOperator, type CustomComponent, type CustomField, type CustomMask, type CustomValidation, type DateField, EasyForm, type EmailValidation, type ErrorEventDetail, type Field, type FieldCondition, type FieldDependencies, type FieldType, type FileField, type FormColors, type FormSchema, type FormState, type FormTheme, type GroupField, type MaskConfig, MaskEngine, type MaxLengthValidation, type MaxValidation, type MinLengthValidation, type MinValidation, type NumberField, PREDEFINED_MASKS, type PatternValidation, type PredefinedMask, type RadioField, type RequiredValidation, type RowField, SchemaParser, type SelectField, StateManager, type Step, type StepChangeEventDetail, type SubmitEventDetail, type SwitchField, type TextField, type TextareaField, type Validation, ValidationEngine, type ValidationType, type WizardState, attributeValue, createInput, generateId, getColors, getCustomComponent, getNestedValue, getPredefinedMask, getThemeStyles, isValidEmail, parseAttributeValue, registerComponent, registerComponents, sanitizeId, setNestedValue };
package/dist/index.js CHANGED
@@ -61,6 +61,7 @@ var SchemaParser = class {
61
61
  "file",
62
62
  "array",
63
63
  "group",
64
+ "row",
64
65
  "custom"
65
66
  ];
66
67
  if (!validTypes.includes(field.type)) {
@@ -91,6 +92,13 @@ var SchemaParser = class {
91
92
  );
92
93
  }
93
94
  break;
95
+ case "row":
96
+ if (!("fields" in field) || !field.fields || field.fields.length === 0) {
97
+ throw new Error(
98
+ `Field "${field.name}" de tipo row debe tener fields`
99
+ );
100
+ }
101
+ break;
94
102
  }
95
103
  }
96
104
  /**
@@ -133,6 +141,9 @@ var SchemaParser = class {
133
141
  if (field.type === "group" && "fields" in field) {
134
142
  extractFields(field.fields);
135
143
  }
144
+ if (field.type === "row" && "fields" in field) {
145
+ extractFields(field.fields);
146
+ }
136
147
  if (field.type === "array" && "itemSchema" in field && field.itemSchema.fields) {
137
148
  extractFields(field.itemSchema.fields);
138
149
  }
@@ -248,6 +259,26 @@ function getBaseStyles(colors) {
248
259
  padding: 1rem;
249
260
  margin-bottom: 1rem;
250
261
  }
262
+ .easy-form-row {
263
+ display: flex;
264
+ flex-wrap: wrap;
265
+ gap: 1rem;
266
+ margin-bottom: 1rem;
267
+ align-items: stretch;
268
+ }
269
+ .easy-form-row > div {
270
+ flex: 1;
271
+ min-width: 0;
272
+ }
273
+ @media (max-width: 768px) {
274
+ .easy-form-row {
275
+ flex-direction: column;
276
+ }
277
+ .easy-form-row > div {
278
+ flex: none;
279
+ width: 100%;
280
+ }
281
+ }
251
282
  .easy-form-radio-group {
252
283
  display: flex;
253
284
  flex-direction: column;
@@ -1092,12 +1123,31 @@ var StateManager = class {
1092
1123
  /**
1093
1124
  * Inicializa el schema
1094
1125
  */
1095
- initializeSchema(schema) {
1126
+ initializeSchema(schema, initialData) {
1096
1127
  this.schema = this.parser.parse(schema);
1097
- this.initializeValues();
1128
+ this.initializeValues(initialData);
1098
1129
  this.initializeWizard();
1099
1130
  this.buildDependencyMap();
1100
1131
  }
1132
+ /**
1133
+ * Extrae todos los campos recursivamente (incluyendo groups, rows, arrays)
1134
+ */
1135
+ extractAllFields(fields) {
1136
+ const allFields = [];
1137
+ for (const field of fields) {
1138
+ allFields.push(field);
1139
+ if (field.type === "group" && "fields" in field) {
1140
+ allFields.push(...this.extractAllFields(field.fields));
1141
+ }
1142
+ if (field.type === "row" && "fields" in field) {
1143
+ allFields.push(...this.extractAllFields(field.fields));
1144
+ }
1145
+ if (field.type === "array" && "itemSchema" in field && field.itemSchema.fields) {
1146
+ allFields.push(...this.extractAllFields(field.itemSchema.fields));
1147
+ }
1148
+ }
1149
+ return allFields;
1150
+ }
1101
1151
  /**
1102
1152
  * Construye el mapa de dependencias para optimizar re-evaluaciones
1103
1153
  */
@@ -1105,7 +1155,8 @@ var StateManager = class {
1105
1155
  this.fieldDependencies.clear();
1106
1156
  this.dependencyCache.clear();
1107
1157
  if (!this.schema) return;
1108
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1158
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1159
+ const allFields = this.extractAllFields(topLevelFields);
1109
1160
  for (const field of allFields) {
1110
1161
  if (!field.dependencies) continue;
1111
1162
  const observedFields = this.extractObservedFields(field.dependencies);
@@ -1145,15 +1196,28 @@ var StateManager = class {
1145
1196
  /**
1146
1197
  * Inicializa los valores por defecto
1147
1198
  */
1148
- initializeValues() {
1199
+ initializeValues(initialData) {
1149
1200
  if (!this.schema) return;
1150
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1201
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1202
+ const allFields = this.extractAllFields(topLevelFields);
1151
1203
  const existingValues = { ...this.state.values };
1152
1204
  const values = {};
1205
+ if (initialData) {
1206
+ for (const key in initialData) {
1207
+ const value = initialData[key];
1208
+ if (value !== void 0 && value !== null) {
1209
+ setNestedValue(values, key, value);
1210
+ }
1211
+ }
1212
+ }
1153
1213
  for (const field of allFields) {
1154
- const existingValue = getNestedValue(existingValues, field.name);
1214
+ const existingValue = getNestedValue(values, field.name);
1155
1215
  if (existingValue !== void 0 && existingValue !== null) {
1156
- values[field.name] = existingValue;
1216
+ continue;
1217
+ }
1218
+ const prevValue = getNestedValue(existingValues, field.name);
1219
+ if (prevValue !== void 0 && prevValue !== null) {
1220
+ setNestedValue(values, field.name, prevValue);
1157
1221
  } else {
1158
1222
  this.initializeFieldValue(field, values);
1159
1223
  }
@@ -1272,7 +1336,8 @@ var StateManager = class {
1272
1336
  */
1273
1337
  async validateField(fieldName) {
1274
1338
  if (!this.schema) return;
1275
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1339
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1340
+ const allFields = this.extractAllFields(topLevelFields);
1276
1341
  const field = allFields.find((f) => f.name === fieldName);
1277
1342
  if (!field) return;
1278
1343
  if (!this.getFieldVisibility(fieldName)) {
@@ -1317,7 +1382,8 @@ var StateManager = class {
1317
1382
  if (!this.schema) {
1318
1383
  return {};
1319
1384
  }
1320
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1385
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1386
+ const allFields = this.extractAllFields(topLevelFields);
1321
1387
  const errors = await this.validator.validateForm(
1322
1388
  allFields,
1323
1389
  this.state.values
@@ -1426,7 +1492,8 @@ var StateManager = class {
1426
1492
  return cached.visible;
1427
1493
  }
1428
1494
  if (!this.schema) return true;
1429
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1495
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1496
+ const allFields = this.extractAllFields(topLevelFields);
1430
1497
  const field = allFields.find((f) => f.name === fieldName);
1431
1498
  if (!field || !field.dependencies) {
1432
1499
  return !field?.hidden;
@@ -1447,7 +1514,8 @@ var StateManager = class {
1447
1514
  return cached.enabled;
1448
1515
  }
1449
1516
  if (!this.schema) return true;
1450
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1517
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1518
+ const allFields = this.extractAllFields(topLevelFields);
1451
1519
  const field = allFields.find((f) => f.name === fieldName);
1452
1520
  if (!field) return true;
1453
1521
  if (field.disabled) return false;
@@ -1470,7 +1538,8 @@ var StateManager = class {
1470
1538
  return cached.required;
1471
1539
  }
1472
1540
  if (!this.schema) return false;
1473
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1541
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1542
+ const allFields = this.extractAllFields(topLevelFields);
1474
1543
  const field = allFields.find((f) => f.name === fieldName);
1475
1544
  if (!field) return false;
1476
1545
  const hasRequired = field.validations?.some((v) => v.type === "required") || false;
@@ -2454,7 +2523,7 @@ var EasyForm = class extends BrowserHTMLElement {
2454
2523
  this.shadow = this.attachShadow({ mode: "open" });
2455
2524
  }
2456
2525
  static get observedAttributes() {
2457
- return ["schema", "theme", "colors"];
2526
+ return ["schema", "theme", "colors", "initialData"];
2458
2527
  }
2459
2528
  /**
2460
2529
  * Obtiene el schema
@@ -2488,6 +2557,9 @@ var EasyForm = class extends BrowserHTMLElement {
2488
2557
  if (name === "schema" && newValue !== oldValue) {
2489
2558
  this.handleSchemaChange();
2490
2559
  }
2560
+ if (name === "initialData" && newValue !== oldValue) {
2561
+ this.handleSchemaChange();
2562
+ }
2491
2563
  if ((name === "theme" || name === "colors") && newValue !== oldValue) {
2492
2564
  this.setupStyles();
2493
2565
  }
@@ -2498,7 +2570,8 @@ var EasyForm = class extends BrowserHTMLElement {
2498
2570
  handleSchemaChange() {
2499
2571
  const schema = this.schema;
2500
2572
  if (schema) {
2501
- this.stateManager.initializeSchema(schema);
2573
+ const initialData = this.initialData;
2574
+ this.stateManager.initializeSchema(schema, initialData || void 0);
2502
2575
  this.render();
2503
2576
  }
2504
2577
  }
@@ -2525,7 +2598,8 @@ var EasyForm = class extends BrowserHTMLElement {
2525
2598
  this.stateManager.setValueWithoutValidation(key, value);
2526
2599
  }
2527
2600
  }
2528
- this.stateManager.initializeSchema(schema);
2601
+ const initialData = this.initialData;
2602
+ this.stateManager.initializeSchema(schema, initialData || void 0);
2529
2603
  const wizardState = this.stateManager.getWizardState();
2530
2604
  const newFormElement = document.createElement("form");
2531
2605
  newFormElement.addEventListener("submit", (e) => this.handleSubmit(e));
@@ -2622,6 +2696,17 @@ var EasyForm = class extends BrowserHTMLElement {
2622
2696
  }
2623
2697
  return groupElement;
2624
2698
  }
2699
+ if (field.type === "row") {
2700
+ const rowElement = this.renderRow(field);
2701
+ if (!isVisible) {
2702
+ rowElement.style.display = "none";
2703
+ rowElement.classList.add("easy-form-field-hidden");
2704
+ }
2705
+ if (!isEnabled) {
2706
+ rowElement.classList.add("easy-form-field-disabled");
2707
+ }
2708
+ return rowElement;
2709
+ }
2625
2710
  if (field.type === "array") {
2626
2711
  const arrayElement = this.renderArray(field);
2627
2712
  if (!isVisible) {
@@ -2707,6 +2792,36 @@ var EasyForm = class extends BrowserHTMLElement {
2707
2792
  }
2708
2793
  return groupContainer;
2709
2794
  }
2795
+ /**
2796
+ * Renderiza una fila de campos
2797
+ */
2798
+ renderRow(field) {
2799
+ const rowContainer = document.createElement("div");
2800
+ rowContainer.className = "easy-form-row";
2801
+ const rowField = field;
2802
+ rowContainer.style.display = "flex";
2803
+ rowContainer.style.flexWrap = "wrap";
2804
+ rowContainer.style.alignItems = rowField.align || "stretch";
2805
+ if (rowField.gap !== void 0) {
2806
+ const gapValue = typeof rowField.gap === "number" ? `${rowField.gap}px` : rowField.gap;
2807
+ rowContainer.style.gap = gapValue;
2808
+ } else {
2809
+ rowContainer.style.gap = "1rem";
2810
+ }
2811
+ if ("fields" in field && field.fields) {
2812
+ for (const subField of field.fields) {
2813
+ const fieldElement = this.renderField(subField);
2814
+ if (fieldElement) {
2815
+ const fieldWrapper = document.createElement("div");
2816
+ fieldWrapper.style.flex = "1";
2817
+ fieldWrapper.style.minWidth = "0";
2818
+ fieldWrapper.appendChild(fieldElement);
2819
+ rowContainer.appendChild(fieldWrapper);
2820
+ }
2821
+ }
2822
+ }
2823
+ return rowContainer;
2824
+ }
2710
2825
  /**
2711
2826
  * Renderiza un array dinámico
2712
2827
  */
@@ -2972,6 +3087,10 @@ var EasyForm = class extends BrowserHTMLElement {
2972
3087
  const found = this.findFieldInSchema({ fields: field.fields }, name);
2973
3088
  if (found) return found;
2974
3089
  }
3090
+ if (field.type === "row" && "fields" in field) {
3091
+ const found = this.findFieldInSchema({ fields: field.fields }, name);
3092
+ if (found) return found;
3093
+ }
2975
3094
  }
2976
3095
  return null;
2977
3096
  }
@@ -3076,6 +3195,24 @@ var EasyForm = class extends BrowserHTMLElement {
3076
3195
  this.removeAttribute("colors");
3077
3196
  }
3078
3197
  }
3198
+ /**
3199
+ * Obtiene los datos iniciales
3200
+ */
3201
+ get initialData() {
3202
+ const initialDataAttr = this.getAttribute("initialData");
3203
+ if (!initialDataAttr) return null;
3204
+ return parseAttributeValue(initialDataAttr);
3205
+ }
3206
+ /**
3207
+ * Establece los datos iniciales
3208
+ */
3209
+ set initialData(value) {
3210
+ if (value) {
3211
+ this.setAttribute("initialData", attributeValue(value));
3212
+ } else {
3213
+ this.removeAttribute("initialData");
3214
+ }
3215
+ }
3079
3216
  /**
3080
3217
  * Configura estilos básicos
3081
3218
  */