iq-line-form-builder-renderer 1.0.13 → 1.0.15

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/README.md CHANGED
@@ -260,26 +260,9 @@ axios.interceptors.request.use((config) => {
260
260
  import 'iq-line-form-builder-renderer/styles';
261
261
  ```
262
262
 
263
- ### CSS Scoping
263
+ ### Custom Styling
264
264
 
265
- This package uses scoped CSS to prevent conflicts with your application's styles.
266
-
267
- #### CSS Scope
268
-
269
- All styles are scoped to the `.iq-line-form-renderer` class. The FormRenderer component automatically wraps all content in this class, ensuring that:
270
-
271
- - ✅ No global CSS conflicts with your application
272
- - ✅ Works seamlessly with shadcn/ui components
273
- - ✅ Compatible with other CSS frameworks
274
- - ✅ Styles only apply within FormRenderer
275
-
276
- #### CSS Variables
277
-
278
- CSS variables (defined in `:root`) are kept global and won't conflict with your app's variables. The package uses its own variable namespace for theming.
279
-
280
- #### Custom Styling
281
-
282
- You can override styles by targeting the scoped class:
265
+ The renderer uses Tailwind CSS. You can override styles by:
283
266
 
284
267
  1. **Using className prop**:
285
268
  ```tsx
@@ -292,11 +275,6 @@ You can override styles by targeting the scoped class:
292
275
  2. **CSS Overrides**:
293
276
  ```css
294
277
  /* Override form styles */
295
- .iq-line-form-renderer input {
296
- border-color: #your-color;
297
- }
298
-
299
- /* Or use your custom class */
300
278
  .custom-form-class input {
301
279
  border-color: #your-color;
302
280
  }
@@ -304,16 +282,6 @@ You can override styles by targeting the scoped class:
304
282
 
305
283
  3. **Tailwind Configuration**: If your app uses Tailwind, ensure the renderer's Tailwind classes are included in your config.
306
284
 
307
- #### Compatibility
308
-
309
- This package is designed to work alongside:
310
- - ✅ shadcn/ui components
311
- - ✅ Tailwind CSS
312
- - ✅ Other CSS frameworks
313
- - ✅ Global CSS stylesheets
314
-
315
- The scoped CSS ensures no conflicts with your application's global styles.
316
-
317
285
  ## Advanced Usage
318
286
 
319
287
  ### Using Form Schema Directly
@@ -1,4 +1,4 @@
1
- import { g as O, a as P } from "./index-Clh0z6_i.mjs";
1
+ import { g as O, a as P } from "./index-lGTPtpcE.mjs";
2
2
  function S(e, u) {
3
3
  const i = {};
4
4
  let p = !1, o, t, s, c, d;
@@ -92,4 +92,4 @@ export {
92
92
  S as transformFieldToBulkPayload,
93
93
  E as transformFieldsToBulkPayload
94
94
  };
95
- //# sourceMappingURL=fieldApiTransformer-DpvHi_69.mjs.map
95
+ //# sourceMappingURL=fieldApiTransformer-Bx1Es8H0.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"fieldApiTransformer-DpvHi_69.mjs","sources":["../src/modules/formbuilder/utils/fieldApiTransformer.ts"],"sourcesContent":["// Purpose: Transform frontend FormField to API bulk create format\r\n// Scope: Converts FormField to the format expected by /api/form-builder/form-fields/bulk\r\n\r\nimport type { FormField } from '../types/field';\r\nimport { getApiDataFromProperties, getNonApiMetadata } from './apiDataHelpers';\r\n\r\nexport interface BulkFieldPayload {\r\n formDefinitionId: string;\r\n fieldKey: string;\r\n fieldType: string;\r\n label: string;\r\n placeholder?: string;\r\n defaultValue?: string;\r\n isRequired: boolean;\r\n \r\n // Position (both nested and flat for backend compatibility)\r\n position: {\r\n row: number;\r\n column: number;\r\n width: number;\r\n order: number;\r\n };\r\n positionRow: number;\r\n positionColumn: number;\r\n positionWidth: number;\r\n positionOrder: number;\r\n \r\n // Validation (both nested and flat for backend compatibility)\r\n validation?: Record<string, any>;\r\n validationRequired: boolean;\r\n validationMinLength?: number;\r\n validationMaxLength?: number;\r\n validationMin?: number;\r\n validationMax?: number;\r\n validationPattern?: string;\r\n \r\n // Field state\r\n disabled?: boolean;\r\n readOnly?: boolean;\r\n hidden?: boolean;\r\n \r\n // Appearance\r\n size?: string;\r\n labelPosition?: string;\r\n hideLabel?: boolean;\r\n customClass?: string;\r\n \r\n // Options for select/radio/checkbox fields (JSON string)\r\n options?: string;\r\n \r\n // Additional metadata (JSON string) - non-API fields only\r\n metadata?: string;\r\n \r\n // API data (new structure, preferred)\r\n apidata?: {\r\n apiKey?: string;\r\n valueSource?: string;\r\n apiEndpoint?: string;\r\n apiAutoDetect?: boolean;\r\n apiLabelField?: string;\r\n apiValueField?: string;\r\n apiMethod?: string;\r\n apiRealtime?: boolean;\r\n apiQueryParams?: {\r\n limit?: string;\r\n page?: string;\r\n sort?: string;\r\n orderBy?: string;\r\n custom?: Array<{ key: string; value: string }>;\r\n };\r\n apiClientFilter?: {\r\n filterField: string;\r\n matchField: string;\r\n };\r\n };\r\n \r\n // Help text\r\n helpText?: string;\r\n}\r\n\r\n/**\r\n * Transforms a frontend FormField to the API bulk create format\r\n */\r\nexport function transformFieldToBulkPayload(\r\n field: FormField,\r\n formDefinitionId: string\r\n): BulkFieldPayload {\r\n // Extract validation rules\r\n const validation: Record<string, any> = {};\r\n let isRequired = false;\r\n let validationMinLength: number | undefined;\r\n let validationMaxLength: number | undefined;\r\n let validationMin: number | undefined;\r\n let validationMax: number | undefined;\r\n let validationPattern: string | undefined;\r\n\r\n if (field.validation && Array.isArray(field.validation)) {\r\n field.validation.forEach((rule) => {\r\n if (rule.type === 'required') {\r\n isRequired = true;\r\n validation.required = true;\r\n } else if (rule.type === 'minLength' && typeof rule.value === 'number') {\r\n validationMinLength = rule.value;\r\n validation.minLength = rule.value;\r\n } else if (rule.type === 'maxLength' && typeof rule.value === 'number') {\r\n validationMaxLength = rule.value;\r\n validation.maxLength = rule.value;\r\n } else if (rule.type === 'min' && typeof rule.value === 'number') {\r\n validationMin = rule.value;\r\n validation.min = rule.value;\r\n } else if (rule.type === 'max' && typeof rule.value === 'number') {\r\n validationMax = rule.value;\r\n validation.max = rule.value;\r\n } else if (rule.type === 'pattern' && typeof rule.value === 'string') {\r\n validationPattern = rule.value;\r\n validation.pattern = rule.value;\r\n } else {\r\n // Store other validation rules (including character restrictions)\r\n validation[rule.type] = rule.value;\r\n }\r\n });\r\n }\r\n\r\n // Check if field is required from field properties\r\n if (field.properties && typeof field.properties === 'object') {\r\n const props = field.properties as any;\r\n if (props.required === true) {\r\n isRequired = true;\r\n validation.required = true;\r\n }\r\n }\r\n\r\n // Extract options for select/radio/checkbox fields\r\n let optionsString: string | undefined;\r\n if (field.properties && typeof field.properties === 'object') {\r\n const props = field.properties as any;\r\n if (props.options && Array.isArray(props.options)) {\r\n optionsString = JSON.stringify(props.options);\r\n }\r\n }\r\n\r\n // Extract appearance properties\r\n const appearance = field.appearance || {};\r\n const size = appearance.size || 'md';\r\n const labelPosition = appearance.labelPlacement || 'top';\r\n const hideLabel = appearance.hideLabel || false;\r\n const customClass = appearance.className || '';\r\n\r\n // Separate API fields from non-API metadata\r\n let apidata: any = undefined;\r\n let metadata: Record<string, any> = {};\r\n\r\n if (field.properties) {\r\n const props = field.properties as any;\r\n \r\n // Extract API data (new structure)\r\n const apiData = getApiDataFromProperties(props);\r\n if (apiData) {\r\n apidata = apiData;\r\n console.log(`[fieldApiTransformer] Field \"${field.name}\" (${field.type}) API config being saved in apidata:`, {\r\n apiEndpoint: apiData.apiEndpoint,\r\n apiMethod: apiData.apiMethod || 'GET',\r\n apiRealtime: apiData.apiRealtime ?? false,\r\n apiAutoDetect: apiData.apiAutoDetect ?? false,\r\n apiLabelField: apiData.apiLabelField,\r\n apiValueField: apiData.apiValueField,\r\n });\r\n }\r\n\r\n // Extract non-API metadata (searchable, clearable, etc.)\r\n metadata = getNonApiMetadata(props);\r\n }\r\n\r\n // Always include field state in metadata (also sent as top-level fields)\r\n metadata.disabled = field.disabled ?? false;\r\n metadata.readOnly = field.readOnly ?? false;\r\n metadata.hidden = field.hidden ?? false;\r\n \r\n // Include hideLabel in metadata if present (from appearance or properties)\r\n // This ensures it's available when loading from backend\r\n if (hideLabel !== undefined) {\r\n metadata.hideLabel = hideLabel;\r\n }\r\n // Also check properties.hideLabel for button fields\r\n if (field.properties && (field.properties as any).hideLabel !== undefined) {\r\n metadata.hideLabel = (field.properties as any).hideLabel;\r\n }\r\n \r\n const metadataString = JSON.stringify(metadata);\r\n\r\n // Position values\r\n const positionRow = field.position.order;\r\n const positionColumn = field.position.column || 1;\r\n const positionWidth = field.position.columnSpan || 1;\r\n const positionOrder = field.position.order;\r\n\r\n // Build payload, only including validation fields if they have values\r\n const payload: BulkFieldPayload = {\r\n formDefinitionId,\r\n fieldKey: field.name,\r\n fieldType: field.type,\r\n label: field.label,\r\n placeholder: field.placeholder,\r\n defaultValue: field.defaultValue ? String(field.defaultValue) : undefined,\r\n isRequired,\r\n \r\n // Position (both formats)\r\n position: {\r\n row: positionRow,\r\n column: positionColumn,\r\n width: positionWidth,\r\n order: positionOrder,\r\n },\r\n positionRow,\r\n positionColumn,\r\n positionWidth,\r\n positionOrder,\r\n \r\n // Validation (both formats)\r\n validation: Object.keys(validation).length > 0 ? validation : undefined,\r\n validationRequired: isRequired,\r\n \r\n // Field state (ensure boolean values, default to false)\r\n disabled: field.disabled ?? false,\r\n readOnly: field.readOnly ?? false,\r\n hidden: field.hidden ?? false,\r\n \r\n // Appearance\r\n size,\r\n labelPosition,\r\n hideLabel,\r\n customClass,\r\n \r\n // Options and metadata\r\n options: optionsString,\r\n metadata: metadataString,\r\n \r\n // API data (new structure, preferred)\r\n ...(apidata && { apidata }),\r\n \r\n // Help text\r\n helpText: field.description,\r\n };\r\n \r\n // Only include validation fields if they have actual values (not undefined/null)\r\n // Note: 0 is a valid value for minLength/maxLength, so we explicitly check for null/undefined\r\n if (validationMinLength !== undefined && validationMinLength !== null) {\r\n payload.validationMinLength = validationMinLength;\r\n }\r\n // Omit the field if undefined/null to let backend handle defaults\r\n if (validationMaxLength !== undefined && validationMaxLength !== null) {\r\n payload.validationMaxLength = validationMaxLength;\r\n }\r\n // Omit the field if undefined/null to let backend handle defaults\r\n if (validationMin !== undefined && validationMin !== null) {\r\n payload.validationMin = validationMin;\r\n }\r\n // Omit the field if undefined/null to let backend handle defaults\r\n if (validationMax !== undefined && validationMax !== null) {\r\n payload.validationMax = validationMax;\r\n }\r\n // Omit the field if undefined/null/empty to let backend handle defaults\r\n if (validationPattern !== undefined && validationPattern !== null && validationPattern !== '') {\r\n payload.validationPattern = validationPattern;\r\n }\r\n \r\n return payload;\r\n}\r\n\r\n/**\r\n * Transforms an array of FormFields to bulk create payload\r\n */\r\nexport function transformFieldsToBulkPayload(\r\n fields: FormField[],\r\n formDefinitionId: string\r\n): BulkFieldPayload[] {\r\n const filteredFields = fields.filter((field) => {\r\n // Filter out layout-only fields (section, divider, header, spacer)\r\n const layoutFields = ['section', 'divider', 'header', 'spacer'];\r\n return !layoutFields.includes(field.type);\r\n });\r\n\r\n const payloads = filteredFields.map((field) => transformFieldToBulkPayload(field, formDefinitionId));\r\n\r\n // Log summary of API configuration fields\r\n const apiFields = payloads.filter((p) => {\r\n try {\r\n const metadata = p.metadata ? JSON.parse(p.metadata) : {};\r\n return !!metadata.apiEndpoint;\r\n } catch {\r\n return false;\r\n }\r\n });\r\n\r\n if (apiFields.length > 0) {\r\n console.log(`[fieldApiTransformer] Summary: ${apiFields.length} field(s) with API configuration:`, \r\n apiFields.map((f) => ({\r\n fieldKey: f.fieldKey,\r\n fieldType: f.fieldType,\r\n apiEndpoint: f.metadata ? (() => {\r\n try {\r\n const meta = JSON.parse(f.metadata);\r\n return meta.apiEndpoint;\r\n } catch {\r\n return 'parse-error';\r\n }\r\n })() : 'no-metadata',\r\n }))\r\n );\r\n }\r\n\r\n return payloads;\r\n}\r\n\r\n/**\r\n * Utility to sync fields to localStorage.\r\n */\r\nexport function syncFieldsToLocalStorage(formId: string | undefined, fields: FormField[]) {\r\n if (!formId) return;\r\n try {\r\n localStorage.setItem(`formsmith_fields_${formId}`, JSON.stringify(fields));\r\n } catch (e) {\r\n console.error('Failed to save fields to localStorage:', e);\r\n }\r\n}\r\n\r\n/**\r\n * Utility to get fields from localStorage.\r\n */\r\nexport function getFieldsFromLocalStorage(formId: string | undefined): FormField[] | null {\r\n if (!formId) return null;\r\n try {\r\n const stored = localStorage.getItem(`formsmith_fields_${formId}`);\r\n if (stored) {\r\n return JSON.parse(stored);\r\n }\r\n return null;\r\n } catch (e) {\r\n console.error('Failed to load fields from localStorage:', e);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Utility to clear fields from localStorage.\r\n */\r\nexport function clearFieldsFromLocalStorage(formId: string | undefined) {\r\n if (!formId) return;\r\n try {\r\n localStorage.removeItem(`formsmith_fields_${formId}`);\r\n console.log(`[clearFieldsFromLocalStorage] Cleared fields for form ${formId}`);\r\n } catch (e) {\r\n console.error('Failed to clear fields from localStorage:', e);\r\n }\r\n}\r\n"],"names":["transformFieldToBulkPayload","field","formDefinitionId","validation","isRequired","validationMinLength","validationMaxLength","validationMin","validationMax","validationPattern","rule","optionsString","props","appearance","size","labelPosition","hideLabel","customClass","apidata","metadata","apiData","getApiDataFromProperties","getNonApiMetadata","metadataString","positionRow","positionColumn","positionWidth","positionOrder","payload","transformFieldsToBulkPayload","fields","payloads","apiFields","p","f"],"mappings":"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"}
1
+ {"version":3,"file":"fieldApiTransformer-Bx1Es8H0.mjs","sources":["../src/modules/formbuilder/utils/fieldApiTransformer.ts"],"sourcesContent":["// Purpose: Transform frontend FormField to API bulk create format\r\n// Scope: Converts FormField to the format expected by /api/form-builder/form-fields/bulk\r\n\r\nimport type { FormField } from '../types/field';\r\nimport { getApiDataFromProperties, getNonApiMetadata } from './apiDataHelpers';\r\n\r\nexport interface BulkFieldPayload {\r\n formDefinitionId: string;\r\n fieldKey: string;\r\n fieldType: string;\r\n label: string;\r\n placeholder?: string;\r\n defaultValue?: string;\r\n isRequired: boolean;\r\n \r\n // Position (both nested and flat for backend compatibility)\r\n position: {\r\n row: number;\r\n column: number;\r\n width: number;\r\n order: number;\r\n };\r\n positionRow: number;\r\n positionColumn: number;\r\n positionWidth: number;\r\n positionOrder: number;\r\n \r\n // Validation (both nested and flat for backend compatibility)\r\n validation?: Record<string, any>;\r\n validationRequired: boolean;\r\n validationMinLength?: number;\r\n validationMaxLength?: number;\r\n validationMin?: number;\r\n validationMax?: number;\r\n validationPattern?: string;\r\n \r\n // Field state\r\n disabled?: boolean;\r\n readOnly?: boolean;\r\n hidden?: boolean;\r\n \r\n // Appearance\r\n size?: string;\r\n labelPosition?: string;\r\n hideLabel?: boolean;\r\n customClass?: string;\r\n \r\n // Options for select/radio/checkbox fields (JSON string)\r\n options?: string;\r\n \r\n // Additional metadata (JSON string) - non-API fields only\r\n metadata?: string;\r\n \r\n // API data (new structure, preferred)\r\n apidata?: {\r\n apiKey?: string;\r\n valueSource?: string;\r\n apiEndpoint?: string;\r\n apiAutoDetect?: boolean;\r\n apiLabelField?: string;\r\n apiValueField?: string;\r\n apiMethod?: string;\r\n apiRealtime?: boolean;\r\n apiQueryParams?: {\r\n limit?: string;\r\n page?: string;\r\n sort?: string;\r\n orderBy?: string;\r\n custom?: Array<{ key: string; value: string }>;\r\n };\r\n apiClientFilter?: {\r\n filterField: string;\r\n matchField: string;\r\n };\r\n };\r\n \r\n // Help text\r\n helpText?: string;\r\n}\r\n\r\n/**\r\n * Transforms a frontend FormField to the API bulk create format\r\n */\r\nexport function transformFieldToBulkPayload(\r\n field: FormField,\r\n formDefinitionId: string\r\n): BulkFieldPayload {\r\n // Extract validation rules\r\n const validation: Record<string, any> = {};\r\n let isRequired = false;\r\n let validationMinLength: number | undefined;\r\n let validationMaxLength: number | undefined;\r\n let validationMin: number | undefined;\r\n let validationMax: number | undefined;\r\n let validationPattern: string | undefined;\r\n\r\n if (field.validation && Array.isArray(field.validation)) {\r\n field.validation.forEach((rule) => {\r\n if (rule.type === 'required') {\r\n isRequired = true;\r\n validation.required = true;\r\n } else if (rule.type === 'minLength' && typeof rule.value === 'number') {\r\n validationMinLength = rule.value;\r\n validation.minLength = rule.value;\r\n } else if (rule.type === 'maxLength' && typeof rule.value === 'number') {\r\n validationMaxLength = rule.value;\r\n validation.maxLength = rule.value;\r\n } else if (rule.type === 'min' && typeof rule.value === 'number') {\r\n validationMin = rule.value;\r\n validation.min = rule.value;\r\n } else if (rule.type === 'max' && typeof rule.value === 'number') {\r\n validationMax = rule.value;\r\n validation.max = rule.value;\r\n } else if (rule.type === 'pattern' && typeof rule.value === 'string') {\r\n validationPattern = rule.value;\r\n validation.pattern = rule.value;\r\n } else {\r\n // Store other validation rules (including character restrictions)\r\n validation[rule.type] = rule.value;\r\n }\r\n });\r\n }\r\n\r\n // Check if field is required from field properties\r\n if (field.properties && typeof field.properties === 'object') {\r\n const props = field.properties as any;\r\n if (props.required === true) {\r\n isRequired = true;\r\n validation.required = true;\r\n }\r\n }\r\n\r\n // Extract options for select/radio/checkbox fields\r\n let optionsString: string | undefined;\r\n if (field.properties && typeof field.properties === 'object') {\r\n const props = field.properties as any;\r\n if (props.options && Array.isArray(props.options)) {\r\n optionsString = JSON.stringify(props.options);\r\n }\r\n }\r\n\r\n // Extract appearance properties\r\n const appearance = field.appearance || {};\r\n const size = appearance.size || 'md';\r\n const labelPosition = appearance.labelPlacement || 'top';\r\n const hideLabel = appearance.hideLabel || false;\r\n const customClass = appearance.className || '';\r\n\r\n // Separate API fields from non-API metadata\r\n let apidata: any = undefined;\r\n let metadata: Record<string, any> = {};\r\n\r\n if (field.properties) {\r\n const props = field.properties as any;\r\n \r\n // Extract API data (new structure)\r\n const apiData = getApiDataFromProperties(props);\r\n if (apiData) {\r\n apidata = apiData;\r\n console.log(`[fieldApiTransformer] Field \"${field.name}\" (${field.type}) API config being saved in apidata:`, {\r\n apiEndpoint: apiData.apiEndpoint,\r\n apiMethod: apiData.apiMethod || 'GET',\r\n apiRealtime: apiData.apiRealtime ?? false,\r\n apiAutoDetect: apiData.apiAutoDetect ?? false,\r\n apiLabelField: apiData.apiLabelField,\r\n apiValueField: apiData.apiValueField,\r\n });\r\n }\r\n\r\n // Extract non-API metadata (searchable, clearable, etc.)\r\n metadata = getNonApiMetadata(props);\r\n }\r\n\r\n // Always include field state in metadata (also sent as top-level fields)\r\n metadata.disabled = field.disabled ?? false;\r\n metadata.readOnly = field.readOnly ?? false;\r\n metadata.hidden = field.hidden ?? false;\r\n \r\n // Include hideLabel in metadata if present (from appearance or properties)\r\n // This ensures it's available when loading from backend\r\n if (hideLabel !== undefined) {\r\n metadata.hideLabel = hideLabel;\r\n }\r\n // Also check properties.hideLabel for button fields\r\n if (field.properties && (field.properties as any).hideLabel !== undefined) {\r\n metadata.hideLabel = (field.properties as any).hideLabel;\r\n }\r\n \r\n const metadataString = JSON.stringify(metadata);\r\n\r\n // Position values\r\n const positionRow = field.position.order;\r\n const positionColumn = field.position.column || 1;\r\n const positionWidth = field.position.columnSpan || 1;\r\n const positionOrder = field.position.order;\r\n\r\n // Build payload, only including validation fields if they have values\r\n const payload: BulkFieldPayload = {\r\n formDefinitionId,\r\n fieldKey: field.name,\r\n fieldType: field.type,\r\n label: field.label,\r\n placeholder: field.placeholder,\r\n defaultValue: field.defaultValue ? String(field.defaultValue) : undefined,\r\n isRequired,\r\n \r\n // Position (both formats)\r\n position: {\r\n row: positionRow,\r\n column: positionColumn,\r\n width: positionWidth,\r\n order: positionOrder,\r\n },\r\n positionRow,\r\n positionColumn,\r\n positionWidth,\r\n positionOrder,\r\n \r\n // Validation (both formats)\r\n validation: Object.keys(validation).length > 0 ? validation : undefined,\r\n validationRequired: isRequired,\r\n \r\n // Field state (ensure boolean values, default to false)\r\n disabled: field.disabled ?? false,\r\n readOnly: field.readOnly ?? false,\r\n hidden: field.hidden ?? false,\r\n \r\n // Appearance\r\n size,\r\n labelPosition,\r\n hideLabel,\r\n customClass,\r\n \r\n // Options and metadata\r\n options: optionsString,\r\n metadata: metadataString,\r\n \r\n // API data (new structure, preferred)\r\n ...(apidata && { apidata }),\r\n \r\n // Help text\r\n helpText: field.description,\r\n };\r\n \r\n // Only include validation fields if they have actual values (not undefined/null)\r\n // Note: 0 is a valid value for minLength/maxLength, so we explicitly check for null/undefined\r\n if (validationMinLength !== undefined && validationMinLength !== null) {\r\n payload.validationMinLength = validationMinLength;\r\n }\r\n // Omit the field if undefined/null to let backend handle defaults\r\n if (validationMaxLength !== undefined && validationMaxLength !== null) {\r\n payload.validationMaxLength = validationMaxLength;\r\n }\r\n // Omit the field if undefined/null to let backend handle defaults\r\n if (validationMin !== undefined && validationMin !== null) {\r\n payload.validationMin = validationMin;\r\n }\r\n // Omit the field if undefined/null to let backend handle defaults\r\n if (validationMax !== undefined && validationMax !== null) {\r\n payload.validationMax = validationMax;\r\n }\r\n // Omit the field if undefined/null/empty to let backend handle defaults\r\n if (validationPattern !== undefined && validationPattern !== null && validationPattern !== '') {\r\n payload.validationPattern = validationPattern;\r\n }\r\n \r\n return payload;\r\n}\r\n\r\n/**\r\n * Transforms an array of FormFields to bulk create payload\r\n */\r\nexport function transformFieldsToBulkPayload(\r\n fields: FormField[],\r\n formDefinitionId: string\r\n): BulkFieldPayload[] {\r\n const filteredFields = fields.filter((field) => {\r\n // Filter out layout-only fields (section, divider, header, spacer)\r\n const layoutFields = ['section', 'divider', 'header', 'spacer'];\r\n return !layoutFields.includes(field.type);\r\n });\r\n\r\n const payloads = filteredFields.map((field) => transformFieldToBulkPayload(field, formDefinitionId));\r\n\r\n // Log summary of API configuration fields\r\n const apiFields = payloads.filter((p) => {\r\n try {\r\n const metadata = p.metadata ? JSON.parse(p.metadata) : {};\r\n return !!metadata.apiEndpoint;\r\n } catch {\r\n return false;\r\n }\r\n });\r\n\r\n if (apiFields.length > 0) {\r\n console.log(`[fieldApiTransformer] Summary: ${apiFields.length} field(s) with API configuration:`, \r\n apiFields.map((f) => ({\r\n fieldKey: f.fieldKey,\r\n fieldType: f.fieldType,\r\n apiEndpoint: f.metadata ? (() => {\r\n try {\r\n const meta = JSON.parse(f.metadata);\r\n return meta.apiEndpoint;\r\n } catch {\r\n return 'parse-error';\r\n }\r\n })() : 'no-metadata',\r\n }))\r\n );\r\n }\r\n\r\n return payloads;\r\n}\r\n\r\n/**\r\n * Utility to sync fields to localStorage.\r\n */\r\nexport function syncFieldsToLocalStorage(formId: string | undefined, fields: FormField[]) {\r\n if (!formId) return;\r\n try {\r\n localStorage.setItem(`formsmith_fields_${formId}`, JSON.stringify(fields));\r\n } catch (e) {\r\n console.error('Failed to save fields to localStorage:', e);\r\n }\r\n}\r\n\r\n/**\r\n * Utility to get fields from localStorage.\r\n */\r\nexport function getFieldsFromLocalStorage(formId: string | undefined): FormField[] | null {\r\n if (!formId) return null;\r\n try {\r\n const stored = localStorage.getItem(`formsmith_fields_${formId}`);\r\n if (stored) {\r\n return JSON.parse(stored);\r\n }\r\n return null;\r\n } catch (e) {\r\n console.error('Failed to load fields from localStorage:', e);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Utility to clear fields from localStorage.\r\n */\r\nexport function clearFieldsFromLocalStorage(formId: string | undefined) {\r\n if (!formId) return;\r\n try {\r\n localStorage.removeItem(`formsmith_fields_${formId}`);\r\n console.log(`[clearFieldsFromLocalStorage] Cleared fields for form ${formId}`);\r\n } catch (e) {\r\n console.error('Failed to clear fields from localStorage:', e);\r\n }\r\n}\r\n"],"names":["transformFieldToBulkPayload","field","formDefinitionId","validation","isRequired","validationMinLength","validationMaxLength","validationMin","validationMax","validationPattern","rule","optionsString","props","appearance","size","labelPosition","hideLabel","customClass","apidata","metadata","apiData","getApiDataFromProperties","getNonApiMetadata","metadataString","positionRow","positionColumn","positionWidth","positionOrder","payload","transformFieldsToBulkPayload","fields","payloads","apiFields","p","f"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { F as r, b as s, c as d, d as o, u as F, e as i, f as m } from "./index-Clh0z6_i.mjs";
1
+ import { F as r, b as s, c as d, d as o, u as F, e as i, f as m } from "./index-lGTPtpcE.mjs";
2
2
  export {
3
3
  r as FIELD_TYPE_REGISTRY,
4
4
  s as FieldRenderer,