form-builder-pro 1.0.8 → 1.0.10

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.mts CHANGED
@@ -39,6 +39,7 @@ interface FormField {
39
39
  id: string;
40
40
  name: string;
41
41
  };
42
+ masterTypeName?: string;
42
43
  enabled?: boolean;
43
44
  visible?: boolean;
44
45
  }
@@ -231,6 +232,15 @@ declare class FormRenderer {
231
232
  private render;
232
233
  }
233
234
 
235
+ /**
236
+ * Cleans a form schema by removing invalid properties and normalizing field types
237
+ * - Converts "decimal" type to "number"
238
+ * - Removes empty options arrays from non-select/radio fields
239
+ * - Preserves masterTypeName for select fields with groupName
240
+ * @param schema
241
+ * @returns Cleaned schema
242
+ */
243
+ declare const cleanFormSchema: (schema: any) => FormSchema;
234
244
  /**
235
245
  * Transforms Form Builder JSON to Platform JSON
236
246
  * @param builderSchema
@@ -248,4 +258,4 @@ declare const initFormBuilder: (options: FormBuilderOptions & {
248
258
  containerId: string;
249
259
  }) => FormBuilder;
250
260
 
251
- export { AsyncOptionSource, FieldType, FieldWidth, FormBuilder, FormBuilderOptions, FormField, FormRenderer, FormSchema, FormSchemaValidation, FormSection, MasterType, ValidationRule, builderToPlatform, formStore, initFormBuilder, platformToBuilder };
261
+ export { AsyncOptionSource, FieldType, FieldWidth, FormBuilder, FormBuilderOptions, FormField, FormRenderer, FormSchema, FormSchemaValidation, FormSection, MasterType, ValidationRule, builderToPlatform, cleanFormSchema, formStore, initFormBuilder, platformToBuilder };
package/dist/index.d.ts CHANGED
@@ -39,6 +39,7 @@ interface FormField {
39
39
  id: string;
40
40
  name: string;
41
41
  };
42
+ masterTypeName?: string;
42
43
  enabled?: boolean;
43
44
  visible?: boolean;
44
45
  }
@@ -231,6 +232,15 @@ declare class FormRenderer {
231
232
  private render;
232
233
  }
233
234
 
235
+ /**
236
+ * Cleans a form schema by removing invalid properties and normalizing field types
237
+ * - Converts "decimal" type to "number"
238
+ * - Removes empty options arrays from non-select/radio fields
239
+ * - Preserves masterTypeName for select fields with groupName
240
+ * @param schema
241
+ * @returns Cleaned schema
242
+ */
243
+ declare const cleanFormSchema: (schema: any) => FormSchema;
234
244
  /**
235
245
  * Transforms Form Builder JSON to Platform JSON
236
246
  * @param builderSchema
@@ -248,4 +258,4 @@ declare const initFormBuilder: (options: FormBuilderOptions & {
248
258
  containerId: string;
249
259
  }) => FormBuilder;
250
260
 
251
- export { AsyncOptionSource, FieldType, FieldWidth, FormBuilder, FormBuilderOptions, FormField, FormRenderer, FormSchema, FormSchemaValidation, FormSection, MasterType, ValidationRule, builderToPlatform, formStore, initFormBuilder, platformToBuilder };
261
+ export { AsyncOptionSource, FieldType, FieldWidth, FormBuilder, FormBuilderOptions, FormField, FormRenderer, FormSchema, FormSchemaValidation, FormSection, MasterType, ValidationRule, builderToPlatform, cleanFormSchema, formStore, initFormBuilder, platformToBuilder };
package/dist/index.js CHANGED
@@ -4152,6 +4152,67 @@ var cloneField = (field) => {
4152
4152
  };
4153
4153
  };
4154
4154
 
4155
+ // src/utils/mapper.ts
4156
+ var cleanFormSchema = (schema) => {
4157
+ const cleanField = (field) => {
4158
+ const cleaned = {
4159
+ id: field.id,
4160
+ type: field.type === "decimal" ? "number" : field.type,
4161
+ // Convert decimal to number
4162
+ label: field.label,
4163
+ width: field.width
4164
+ };
4165
+ if (field.placeholder !== void 0)
4166
+ cleaned.placeholder = field.placeholder;
4167
+ if (field.description !== void 0)
4168
+ cleaned.description = field.description;
4169
+ if (field.required !== void 0)
4170
+ cleaned.required = field.required;
4171
+ if (field.defaultValue !== void 0)
4172
+ cleaned.defaultValue = field.defaultValue;
4173
+ if (field.validation !== void 0)
4174
+ cleaned.validation = field.validation;
4175
+ if (field.hidden !== void 0)
4176
+ cleaned.hidden = field.hidden;
4177
+ if (field.position !== void 0)
4178
+ cleaned.position = field.position;
4179
+ if (field.enabled !== void 0)
4180
+ cleaned.enabled = field.enabled;
4181
+ if (field.visible !== void 0)
4182
+ cleaned.visible = field.visible;
4183
+ if (field.optionsSource !== void 0)
4184
+ cleaned.optionsSource = field.optionsSource;
4185
+ if ((field.type === "select" || field.type === "radio") && field.options) {
4186
+ cleaned.options = field.options;
4187
+ }
4188
+ if (field.type === "select" && field.groupName) {
4189
+ cleaned.groupName = field.groupName;
4190
+ }
4191
+ if (field.type === "select" && field.masterTypeName !== void 0) {
4192
+ cleaned.masterTypeName = field.masterTypeName;
4193
+ }
4194
+ return cleaned;
4195
+ };
4196
+ return {
4197
+ id: schema.id,
4198
+ title: schema.title,
4199
+ formName: schema.formName,
4200
+ sections: schema.sections.map((section) => ({
4201
+ id: section.id,
4202
+ title: section.title,
4203
+ fields: section.fields.map(cleanField),
4204
+ isExpanded: section.isExpanded,
4205
+ columns: section.columns
4206
+ }))
4207
+ };
4208
+ };
4209
+ var builderToPlatform = (builderSchema) => {
4210
+ return builderSchema;
4211
+ };
4212
+ var platformToBuilder = (platformSchema) => {
4213
+ return cleanFormSchema(platformSchema);
4214
+ };
4215
+
4155
4216
  // src/core/useFormStore.ts
4156
4217
  var INITIAL_SCHEMA = {
4157
4218
  id: "form_1",
@@ -4170,6 +4231,7 @@ var formStore = createStore((set, get) => ({
4170
4231
  masterTypes: [],
4171
4232
  dropdownOptionsMap: {},
4172
4233
  setSchema: (schema) => {
4234
+ const cleanedSchema = cleanFormSchema(schema);
4173
4235
  const convertIndexesToOptions = (indexes) => {
4174
4236
  if (!indexes || !Array.isArray(indexes) || indexes.length === 0) {
4175
4237
  return [];
@@ -4194,8 +4256,8 @@ var formStore = createStore((set, get) => ({
4194
4256
  );
4195
4257
  };
4196
4258
  const state = get();
4197
- if (state.masterTypes && state.masterTypes.length > 0 && schema.sections) {
4198
- const updatedSections = schema.sections.map((section) => ({
4259
+ if (state.masterTypes && state.masterTypes.length > 0 && cleanedSchema.sections) {
4260
+ const updatedSections = cleanedSchema.sections.map((section) => ({
4199
4261
  ...section,
4200
4262
  fields: section.fields.map((field) => {
4201
4263
  if (field.type === "select" && field.groupName) {
@@ -4228,9 +4290,9 @@ var formStore = createStore((set, get) => ({
4228
4290
  return field;
4229
4291
  })
4230
4292
  }));
4231
- set({ schema: { ...schema, sections: updatedSections } });
4293
+ set({ schema: { ...cleanedSchema, sections: updatedSections } });
4232
4294
  } else {
4233
- set({ schema });
4295
+ set({ schema: cleanedSchema });
4234
4296
  }
4235
4297
  },
4236
4298
  togglePreview: () => {
@@ -7942,6 +8004,7 @@ var FormBuilder = class {
7942
8004
  id: selectedMasterType.id,
7943
8005
  name: selectedMasterType.name
7944
8006
  },
8007
+ masterTypeName: selectedEnumName,
7945
8008
  options: options.length > 0 ? options : void 0
7946
8009
  });
7947
8010
  if (this.options.onGroupSelectionChange) {
@@ -7954,6 +8017,7 @@ var FormBuilder = class {
7954
8017
  } else {
7955
8018
  formStore.getState().updateField(selectedField.id, {
7956
8019
  groupName: void 0,
8020
+ masterTypeName: void 0,
7957
8021
  options: void 0
7958
8022
  // Clear options when groupName is cleared
7959
8023
  });
@@ -7994,8 +8058,6 @@ var FormBuilder = class {
7994
8058
  }
7995
8059
  }
7996
8060
  }
7997
- const validationHeader = createElement("h3", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3 mt-6", text: "Validation Rules" });
7998
- body.appendChild(validationHeader);
7999
8061
  const validations = selectedField.validation || [];
8000
8062
  const updateValidation = (rule) => {
8001
8063
  const newValidations = validations.filter((v) => v.type !== rule.type);
@@ -8005,6 +8067,7 @@ var FormBuilder = class {
8005
8067
  formStore.getState().updateField(selectedField.id, { validation: newValidations });
8006
8068
  };
8007
8069
  const getRuleValue = (type) => validations.find((v) => v.type === type)?.value || "";
8070
+ const validationElements = [];
8008
8071
  if (["text", "textarea", "email", "password"].includes(selectedField.type)) {
8009
8072
  const minLenGroup = createElement("div", { className: "mb-3" });
8010
8073
  minLenGroup.appendChild(createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", text: "Min Length" }));
@@ -8015,7 +8078,7 @@ var FormBuilder = class {
8015
8078
  placeholder: "e.g. 3",
8016
8079
  onchange: (e) => updateValidation({ type: "minLength", value: parseInt(e.target.value) })
8017
8080
  }));
8018
- body.appendChild(minLenGroup);
8081
+ validationElements.push(minLenGroup);
8019
8082
  const maxLenGroup = createElement("div", { className: "mb-3" });
8020
8083
  maxLenGroup.appendChild(createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", text: "Max Length" }));
8021
8084
  maxLenGroup.appendChild(createElement("input", {
@@ -8025,7 +8088,7 @@ var FormBuilder = class {
8025
8088
  placeholder: "e.g. 100",
8026
8089
  onchange: (e) => updateValidation({ type: "maxLength", value: parseInt(e.target.value) })
8027
8090
  }));
8028
- body.appendChild(maxLenGroup);
8091
+ validationElements.push(maxLenGroup);
8029
8092
  const regexGroup = createElement("div", { className: "mb-3" });
8030
8093
  regexGroup.appendChild(createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", text: "Regex Pattern" }));
8031
8094
  regexGroup.appendChild(createElement("input", {
@@ -8043,7 +8106,7 @@ var FormBuilder = class {
8043
8106
  formStore.getState().updateField(selectedField.id, { validation: newValidations });
8044
8107
  }
8045
8108
  }));
8046
- body.appendChild(regexGroup);
8109
+ validationElements.push(regexGroup);
8047
8110
  }
8048
8111
  if (selectedField.type === "number") {
8049
8112
  const minValGroup = createElement("div", { className: "mb-3" });
@@ -8054,7 +8117,7 @@ var FormBuilder = class {
8054
8117
  value: getRuleValue("min"),
8055
8118
  onchange: (e) => updateValidation({ type: "min", value: parseInt(e.target.value) })
8056
8119
  }));
8057
- body.appendChild(minValGroup);
8120
+ validationElements.push(minValGroup);
8058
8121
  const maxValGroup = createElement("div", { className: "mb-3" });
8059
8122
  maxValGroup.appendChild(createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", text: "Max Value" }));
8060
8123
  maxValGroup.appendChild(createElement("input", {
@@ -8063,59 +8126,12 @@ var FormBuilder = class {
8063
8126
  value: getRuleValue("max"),
8064
8127
  onchange: (e) => updateValidation({ type: "max", value: parseInt(e.target.value) })
8065
8128
  }));
8066
- body.appendChild(maxValGroup);
8067
- }
8068
- if (["select", "radio"].includes(selectedField.type)) {
8069
- const optionsHeader = createElement("h3", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3 mt-6", text: "Options Source" });
8070
- body.appendChild(optionsHeader);
8071
- const sourceGroup = createElement("div", { className: "mb-4" });
8072
- sourceGroup.appendChild(createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", text: "Source Type" }));
8073
- const sourceSelect = createElement("select", {
8074
- className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-md bg-transparent",
8075
- onchange: (e) => {
8076
- const isAsync2 = e.target.value === "api";
8077
- if (isAsync2) {
8078
- formStore.getState().updateField(selectedField.id, {
8079
- optionsSource: { api: "https://", method: "GET", labelKey: "name", valueKey: "id" }
8080
- });
8081
- } else {
8082
- formStore.getState().updateField(selectedField.id, { optionsSource: void 0 });
8083
- }
8084
- this.render();
8085
- }
8086
- });
8087
- sourceSelect.appendChild(createElement("option", { value: "static", text: "Static Options", selected: !selectedField.optionsSource }));
8088
- sourceSelect.appendChild(createElement("option", { value: "api", text: "API Endpoint", selected: !!selectedField.optionsSource }));
8089
- sourceGroup.appendChild(sourceSelect);
8090
- body.appendChild(sourceGroup);
8091
- if (selectedField.optionsSource) {
8092
- const apiGroup = createElement("div", { className: "mb-3" });
8093
- apiGroup.appendChild(createElement("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", text: "API URL" }));
8094
- apiGroup.appendChild(createElement("input", {
8095
- className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-md bg-transparent",
8096
- value: selectedField.optionsSource.api,
8097
- oninput: (e) => formStore.getState().updateField(selectedField.id, { optionsSource: { ...selectedField.optionsSource, api: e.target.value } })
8098
- }));
8099
- body.appendChild(apiGroup);
8100
- const keysRow = createElement("div", { className: "flex gap-2 mb-3" });
8101
- const labelKeyGroup = createElement("div", { className: "flex-1" });
8102
- labelKeyGroup.appendChild(createElement("label", { className: "block text-xs font-medium text-gray-500 mb-1", text: "Label Key" }));
8103
- labelKeyGroup.appendChild(createElement("input", {
8104
- className: "w-full px-2 py-1 border border-gray-300 dark:border-gray-700 rounded-md bg-transparent text-sm",
8105
- value: selectedField.optionsSource.labelKey,
8106
- oninput: (e) => formStore.getState().updateField(selectedField.id, { optionsSource: { ...selectedField.optionsSource, labelKey: e.target.value } })
8107
- }));
8108
- const valueKeyGroup = createElement("div", { className: "flex-1" });
8109
- valueKeyGroup.appendChild(createElement("label", { className: "block text-xs font-medium text-gray-500 mb-1", text: "Value Key" }));
8110
- valueKeyGroup.appendChild(createElement("input", {
8111
- className: "w-full px-2 py-1 border border-gray-300 dark:border-gray-700 rounded-md bg-transparent text-sm",
8112
- value: selectedField.optionsSource.valueKey,
8113
- oninput: (e) => formStore.getState().updateField(selectedField.id, { optionsSource: { ...selectedField.optionsSource, valueKey: e.target.value } })
8114
- }));
8115
- keysRow.appendChild(labelKeyGroup);
8116
- keysRow.appendChild(valueKeyGroup);
8117
- body.appendChild(keysRow);
8118
- }
8129
+ validationElements.push(maxValGroup);
8130
+ }
8131
+ if (validationElements.length > 0) {
8132
+ const validationHeader = createElement("h3", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3 mt-6", text: "Validation Rules" });
8133
+ body.appendChild(validationHeader);
8134
+ validationElements.forEach((el) => body.appendChild(el));
8119
8135
  }
8120
8136
  panel.appendChild(body);
8121
8137
  return panel;
@@ -8151,14 +8167,6 @@ var FormBuilder = class {
8151
8167
  }
8152
8168
  };
8153
8169
 
8154
- // src/utils/mapper.ts
8155
- var builderToPlatform = (builderSchema) => {
8156
- return builderSchema;
8157
- };
8158
- var platformToBuilder = (platformSchema) => {
8159
- return platformSchema;
8160
- };
8161
-
8162
8170
  // src/index.ts
8163
8171
  var initFormBuilder = (options) => {
8164
8172
  const container = document.getElementById(options.containerId);
@@ -8182,6 +8190,7 @@ exports.FormBuilder = FormBuilder;
8182
8190
  exports.FormRenderer = FormRenderer;
8183
8191
  exports.FormSchemaValidation = FormSchemaValidation;
8184
8192
  exports.builderToPlatform = builderToPlatform;
8193
+ exports.cleanFormSchema = cleanFormSchema;
8185
8194
  exports.formStore = formStore;
8186
8195
  exports.initFormBuilder = initFormBuilder;
8187
8196
  exports.platformToBuilder = platformToBuilder;