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.
@@ -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
  * Componente personalizado para inyección
@@ -320,6 +330,10 @@ declare class EasyForm extends BrowserHTMLElement {
320
330
  * Renderiza un grupo de campos
321
331
  */
322
332
  private renderGroup;
333
+ /**
334
+ * Renderiza una fila de campos
335
+ */
336
+ private renderRow;
323
337
  /**
324
338
  * Renderiza un array dinámico
325
339
  */
@@ -389,6 +403,14 @@ declare class EasyForm extends BrowserHTMLElement {
389
403
  * Establece los colores personalizados
390
404
  */
391
405
  set colors(value: FormColors | null);
406
+ /**
407
+ * Obtiene los datos iniciales
408
+ */
409
+ get initialData(): Record<string, any> | null;
410
+ /**
411
+ * Establece los datos iniciales
412
+ */
413
+ set initialData(value: Record<string, any> | null);
392
414
  /**
393
415
  * Configura estilos básicos
394
416
  */
package/dist/easy-form.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;
@@ -1086,12 +1117,31 @@ var StateManager = class {
1086
1117
  /**
1087
1118
  * Inicializa el schema
1088
1119
  */
1089
- initializeSchema(schema) {
1120
+ initializeSchema(schema, initialData) {
1090
1121
  this.schema = this.parser.parse(schema);
1091
- this.initializeValues();
1122
+ this.initializeValues(initialData);
1092
1123
  this.initializeWizard();
1093
1124
  this.buildDependencyMap();
1094
1125
  }
1126
+ /**
1127
+ * Extrae todos los campos recursivamente (incluyendo groups, rows, arrays)
1128
+ */
1129
+ extractAllFields(fields) {
1130
+ const allFields = [];
1131
+ for (const field of fields) {
1132
+ allFields.push(field);
1133
+ if (field.type === "group" && "fields" in field) {
1134
+ allFields.push(...this.extractAllFields(field.fields));
1135
+ }
1136
+ if (field.type === "row" && "fields" in field) {
1137
+ allFields.push(...this.extractAllFields(field.fields));
1138
+ }
1139
+ if (field.type === "array" && "itemSchema" in field && field.itemSchema.fields) {
1140
+ allFields.push(...this.extractAllFields(field.itemSchema.fields));
1141
+ }
1142
+ }
1143
+ return allFields;
1144
+ }
1095
1145
  /**
1096
1146
  * Construye el mapa de dependencias para optimizar re-evaluaciones
1097
1147
  */
@@ -1099,7 +1149,8 @@ var StateManager = class {
1099
1149
  this.fieldDependencies.clear();
1100
1150
  this.dependencyCache.clear();
1101
1151
  if (!this.schema) return;
1102
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1152
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1153
+ const allFields = this.extractAllFields(topLevelFields);
1103
1154
  for (const field of allFields) {
1104
1155
  if (!field.dependencies) continue;
1105
1156
  const observedFields = this.extractObservedFields(field.dependencies);
@@ -1139,15 +1190,28 @@ var StateManager = class {
1139
1190
  /**
1140
1191
  * Inicializa los valores por defecto
1141
1192
  */
1142
- initializeValues() {
1193
+ initializeValues(initialData) {
1143
1194
  if (!this.schema) return;
1144
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1195
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1196
+ const allFields = this.extractAllFields(topLevelFields);
1145
1197
  const existingValues = { ...this.state.values };
1146
1198
  const values = {};
1199
+ if (initialData) {
1200
+ for (const key in initialData) {
1201
+ const value = initialData[key];
1202
+ if (value !== void 0 && value !== null) {
1203
+ setNestedValue(values, key, value);
1204
+ }
1205
+ }
1206
+ }
1147
1207
  for (const field of allFields) {
1148
- const existingValue = getNestedValue(existingValues, field.name);
1208
+ const existingValue = getNestedValue(values, field.name);
1149
1209
  if (existingValue !== void 0 && existingValue !== null) {
1150
- values[field.name] = existingValue;
1210
+ continue;
1211
+ }
1212
+ const prevValue = getNestedValue(existingValues, field.name);
1213
+ if (prevValue !== void 0 && prevValue !== null) {
1214
+ setNestedValue(values, field.name, prevValue);
1151
1215
  } else {
1152
1216
  this.initializeFieldValue(field, values);
1153
1217
  }
@@ -1266,7 +1330,8 @@ var StateManager = class {
1266
1330
  */
1267
1331
  async validateField(fieldName) {
1268
1332
  if (!this.schema) return;
1269
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1333
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1334
+ const allFields = this.extractAllFields(topLevelFields);
1270
1335
  const field = allFields.find((f) => f.name === fieldName);
1271
1336
  if (!field) return;
1272
1337
  if (!this.getFieldVisibility(fieldName)) {
@@ -1311,7 +1376,8 @@ var StateManager = class {
1311
1376
  if (!this.schema) {
1312
1377
  return {};
1313
1378
  }
1314
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1379
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1380
+ const allFields = this.extractAllFields(topLevelFields);
1315
1381
  const errors = await this.validator.validateForm(
1316
1382
  allFields,
1317
1383
  this.state.values
@@ -1420,7 +1486,8 @@ var StateManager = class {
1420
1486
  return cached.visible;
1421
1487
  }
1422
1488
  if (!this.schema) return true;
1423
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1489
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1490
+ const allFields = this.extractAllFields(topLevelFields);
1424
1491
  const field = allFields.find((f) => f.name === fieldName);
1425
1492
  if (!field || !field.dependencies) {
1426
1493
  return !field?.hidden;
@@ -1441,7 +1508,8 @@ var StateManager = class {
1441
1508
  return cached.enabled;
1442
1509
  }
1443
1510
  if (!this.schema) return true;
1444
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1511
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1512
+ const allFields = this.extractAllFields(topLevelFields);
1445
1513
  const field = allFields.find((f) => f.name === fieldName);
1446
1514
  if (!field) return true;
1447
1515
  if (field.disabled) return false;
@@ -1464,7 +1532,8 @@ var StateManager = class {
1464
1532
  return cached.required;
1465
1533
  }
1466
1534
  if (!this.schema) return false;
1467
- const allFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields;
1535
+ const topLevelFields = this.schema.isWizard ? this.schema.steps.flatMap((step) => step.fields) : this.schema.fields || [];
1536
+ const allFields = this.extractAllFields(topLevelFields);
1468
1537
  const field = allFields.find((f) => f.name === fieldName);
1469
1538
  if (!field) return false;
1470
1539
  const hasRequired = field.validations?.some((v) => v.type === "required") || false;
@@ -2448,7 +2517,7 @@ var EasyForm = class extends BrowserHTMLElement {
2448
2517
  this.shadow = this.attachShadow({ mode: "open" });
2449
2518
  }
2450
2519
  static get observedAttributes() {
2451
- return ["schema", "theme", "colors"];
2520
+ return ["schema", "theme", "colors", "initialData"];
2452
2521
  }
2453
2522
  /**
2454
2523
  * Obtiene el schema
@@ -2482,6 +2551,9 @@ var EasyForm = class extends BrowserHTMLElement {
2482
2551
  if (name === "schema" && newValue !== oldValue) {
2483
2552
  this.handleSchemaChange();
2484
2553
  }
2554
+ if (name === "initialData" && newValue !== oldValue) {
2555
+ this.handleSchemaChange();
2556
+ }
2485
2557
  if ((name === "theme" || name === "colors") && newValue !== oldValue) {
2486
2558
  this.setupStyles();
2487
2559
  }
@@ -2492,7 +2564,8 @@ var EasyForm = class extends BrowserHTMLElement {
2492
2564
  handleSchemaChange() {
2493
2565
  const schema = this.schema;
2494
2566
  if (schema) {
2495
- this.stateManager.initializeSchema(schema);
2567
+ const initialData = this.initialData;
2568
+ this.stateManager.initializeSchema(schema, initialData || void 0);
2496
2569
  this.render();
2497
2570
  }
2498
2571
  }
@@ -2519,7 +2592,8 @@ var EasyForm = class extends BrowserHTMLElement {
2519
2592
  this.stateManager.setValueWithoutValidation(key, value);
2520
2593
  }
2521
2594
  }
2522
- this.stateManager.initializeSchema(schema);
2595
+ const initialData = this.initialData;
2596
+ this.stateManager.initializeSchema(schema, initialData || void 0);
2523
2597
  const wizardState = this.stateManager.getWizardState();
2524
2598
  const newFormElement = document.createElement("form");
2525
2599
  newFormElement.addEventListener("submit", (e) => this.handleSubmit(e));
@@ -2616,6 +2690,17 @@ var EasyForm = class extends BrowserHTMLElement {
2616
2690
  }
2617
2691
  return groupElement;
2618
2692
  }
2693
+ if (field.type === "row") {
2694
+ const rowElement = this.renderRow(field);
2695
+ if (!isVisible) {
2696
+ rowElement.style.display = "none";
2697
+ rowElement.classList.add("easy-form-field-hidden");
2698
+ }
2699
+ if (!isEnabled) {
2700
+ rowElement.classList.add("easy-form-field-disabled");
2701
+ }
2702
+ return rowElement;
2703
+ }
2619
2704
  if (field.type === "array") {
2620
2705
  const arrayElement = this.renderArray(field);
2621
2706
  if (!isVisible) {
@@ -2701,6 +2786,36 @@ var EasyForm = class extends BrowserHTMLElement {
2701
2786
  }
2702
2787
  return groupContainer;
2703
2788
  }
2789
+ /**
2790
+ * Renderiza una fila de campos
2791
+ */
2792
+ renderRow(field) {
2793
+ const rowContainer = document.createElement("div");
2794
+ rowContainer.className = "easy-form-row";
2795
+ const rowField = field;
2796
+ rowContainer.style.display = "flex";
2797
+ rowContainer.style.flexWrap = "wrap";
2798
+ rowContainer.style.alignItems = rowField.align || "stretch";
2799
+ if (rowField.gap !== void 0) {
2800
+ const gapValue = typeof rowField.gap === "number" ? `${rowField.gap}px` : rowField.gap;
2801
+ rowContainer.style.gap = gapValue;
2802
+ } else {
2803
+ rowContainer.style.gap = "1rem";
2804
+ }
2805
+ if ("fields" in field && field.fields) {
2806
+ for (const subField of field.fields) {
2807
+ const fieldElement = this.renderField(subField);
2808
+ if (fieldElement) {
2809
+ const fieldWrapper = document.createElement("div");
2810
+ fieldWrapper.style.flex = "1";
2811
+ fieldWrapper.style.minWidth = "0";
2812
+ fieldWrapper.appendChild(fieldElement);
2813
+ rowContainer.appendChild(fieldWrapper);
2814
+ }
2815
+ }
2816
+ }
2817
+ return rowContainer;
2818
+ }
2704
2819
  /**
2705
2820
  * Renderiza un array dinámico
2706
2821
  */
@@ -2966,6 +3081,10 @@ var EasyForm = class extends BrowserHTMLElement {
2966
3081
  const found = this.findFieldInSchema({ fields: field.fields }, name);
2967
3082
  if (found) return found;
2968
3083
  }
3084
+ if (field.type === "row" && "fields" in field) {
3085
+ const found = this.findFieldInSchema({ fields: field.fields }, name);
3086
+ if (found) return found;
3087
+ }
2969
3088
  }
2970
3089
  return null;
2971
3090
  }
@@ -3070,6 +3189,24 @@ var EasyForm = class extends BrowserHTMLElement {
3070
3189
  this.removeAttribute("colors");
3071
3190
  }
3072
3191
  }
3192
+ /**
3193
+ * Obtiene los datos iniciales
3194
+ */
3195
+ get initialData() {
3196
+ const initialDataAttr = this.getAttribute("initialData");
3197
+ if (!initialDataAttr) return null;
3198
+ return parseAttributeValue(initialDataAttr);
3199
+ }
3200
+ /**
3201
+ * Establece los datos iniciales
3202
+ */
3203
+ set initialData(value) {
3204
+ if (value) {
3205
+ this.setAttribute("initialData", attributeValue(value));
3206
+ } else {
3207
+ this.removeAttribute("initialData");
3208
+ }
3209
+ }
3073
3210
  /**
3074
3211
  * Configura estilos básicos
3075
3212
  */