form-builder-pro 1.4.0 → 1.4.1

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.css CHANGED
@@ -1071,6 +1071,9 @@ body {
1071
1071
  -moz-user-select: none;
1072
1072
  user-select: none;
1073
1073
  }
1074
+ .resize-none {
1075
+ resize: none;
1076
+ }
1074
1077
  .resize-y {
1075
1078
  resize: vertical;
1076
1079
  }
@@ -1227,6 +1230,10 @@ body {
1227
1230
  --tw-border-opacity: 1;
1228
1231
  border-color: rgb(1 159 162 / var(--tw-border-opacity, 1));
1229
1232
  }
1233
+ .border-\[\#635bff\] {
1234
+ --tw-border-opacity: 1;
1235
+ border-color: rgb(99 91 255 / var(--tw-border-opacity, 1));
1236
+ }
1230
1237
  .border-\[\#635bff\]\/35 {
1231
1238
  border-color: rgb(99 91 255 / 0.35);
1232
1239
  }
@@ -1784,6 +1791,11 @@ input[type="radio"]:checked::after {
1784
1791
  content: var(--tw-content);
1785
1792
  }
1786
1793
 
1794
+ .hover\:border-\[\#635bff\]:hover {
1795
+ --tw-border-opacity: 1;
1796
+ border-color: rgb(99 91 255 / var(--tw-border-opacity, 1));
1797
+ }
1798
+
1787
1799
  .hover\:border-blue-200:hover {
1788
1800
  --tw-border-opacity: 1;
1789
1801
  border-color: rgb(191 219 254 / var(--tw-border-opacity, 1));
@@ -1856,6 +1868,11 @@ input[type="radio"]:checked::after {
1856
1868
  background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
1857
1869
  }
1858
1870
 
1871
+ .hover\:text-\[\#635bff\]:hover {
1872
+ --tw-text-opacity: 1;
1873
+ color: rgb(99 91 255 / var(--tw-text-opacity, 1));
1874
+ }
1875
+
1859
1876
  .hover\:text-blue-700:hover {
1860
1877
  --tw-text-opacity: 1;
1861
1878
  color: rgb(29 78 216 / var(--tw-text-opacity, 1));
@@ -1881,6 +1898,11 @@ input[type="radio"]:checked::after {
1881
1898
  color: rgb(239 68 68 / var(--tw-text-opacity, 1));
1882
1899
  }
1883
1900
 
1901
+ .hover\:text-red-700:hover {
1902
+ --tw-text-opacity: 1;
1903
+ color: rgb(185 28 28 / var(--tw-text-opacity, 1));
1904
+ }
1905
+
1884
1906
  .hover\:text-white:hover {
1885
1907
  --tw-text-opacity: 1;
1886
1908
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import * as zustand_vanilla from 'zustand/vanilla';
3
3
 
4
- type FieldType = 'text' | 'textarea' | 'number' | 'date' | 'datetime' | 'select' | 'checkbox' | 'radio' | 'toggle' | 'binary_choice' | 'repeater' | 'file' | 'image' | 'email' | 'phone' | 'name_generator';
4
+ type FieldType = 'text' | 'textarea' | 'number' | 'date' | 'datetime' | 'select' | 'checkbox' | 'radio' | 'toggle' | 'binary_choice' | 'repeater' | 'file' | 'image' | 'email' | 'phone' | 'name_generator' | 'formula';
5
5
  /** Name generator format options for name_generator field type */
6
6
  type NameGeneratorFormat = 'TEXT_HYPHEN_ID' | 'TEXT_UNDERSCORE_ID' | 'TEXT_SLASH_ID' | 'TEXT_ID' | 'ID_HYPHEN_TEXT' | 'ID_UNDERSCORE_TEXT' | 'TEXT_YEAR_ID' | 'TEXT_MONTH_ID' | 'TEXT_YEAR_MONTH_ID' | 'TEXT_ACCOUNT_CODE_ID' | 'TEXT_BRANCH_ID' | 'PREFIX_TEXT_ID' | 'TEXT_ID_SUFFIX' | 'TEXT_RANDOM_4' | 'TEXT_YEAR_MONTH_DAY_ID' | 'TEXT_HYPHEN_USER_INPUT' | 'TEXT_UNDERSCORE_USER_INPUT' | 'TEXT_SLASH_USER_INPUT' | 'USER_INPUT_HYPHEN_TEXT' | 'USER_INPUT_UNDERSCORE_TEXT';
7
7
  type FieldWidth = '25%' | '33%' | '50%' | '66%' | '75%' | '100%' | number;
@@ -135,6 +135,7 @@ interface FormField {
135
135
  nameGeneratorPrefix?: string;
136
136
  nameGeneratorSuffix?: string;
137
137
  nameGeneratorIdPadding?: number;
138
+ formulaConfig?: FormulaConfig;
138
139
  }
139
140
  /**
140
141
  * Conditional date constraint — evaluated at runtime against the current date or another field's value.
@@ -146,6 +147,32 @@ interface DateConstraint {
146
147
  compareWith: 'CURRENT_DATE' | 'FIELD';
147
148
  fieldName?: string;
148
149
  }
150
+ /**
151
+ * A single condition row for multi-condition formula fields.
152
+ * When the compare field equals `value`, evaluate `expression`.
153
+ */
154
+ interface FormulaCondition {
155
+ value: string;
156
+ expression: string;
157
+ }
158
+ /**
159
+ * Configuration for the formula field type.
160
+ * Supports two modes: single expression or multiple conditions.
161
+ */
162
+ interface FormulaConfig {
163
+ mode: 'single' | 'multiple';
164
+ /** Used when mode === 'single' */
165
+ single: {
166
+ expression: string;
167
+ };
168
+ /** Used when mode === 'multiple' */
169
+ multiple: {
170
+ compareField: string;
171
+ conditions: FormulaCondition[];
172
+ fallbackExpression: string;
173
+ };
174
+ decimalPlaces: number;
175
+ }
149
176
  /**
150
177
  * ISD (International Subscriber Dialing) configuration for phone fields
151
178
  */
@@ -509,6 +536,52 @@ declare function getNumericFieldsForFormula(schema: FormSchema, excludeFieldId?:
509
536
  fieldName: string;
510
537
  label: string;
511
538
  }[];
539
+ /**
540
+ * Extracts `{fieldName}` placeholder references from a formula expression.
541
+ * Returns unique field names in order of first appearance.
542
+ */
543
+ declare function extractBracketFields(expression: string): string[];
544
+ /**
545
+ * Evaluates a formula expression that uses `{fieldName}` placeholders.
546
+ * Placeholders are resolved to numeric values from `values` before evaluation.
547
+ * Missing/non-numeric values default to 0.
548
+ * Returns NaN on divide-by-zero or syntax error.
549
+ */
550
+ declare function evaluateFormulaExpression(expression: string, values: Record<string, number | string | undefined>): number;
551
+ /**
552
+ * Evaluates a complete FormulaConfig using the provided field values.
553
+ * For `multiple` mode, `compareValue` is the current value of the compare field.
554
+ * Returns `{ result, error? }`.
555
+ */
556
+ declare function evaluateFormulaConfig(config: FormulaConfig, values: Record<string, number | string | undefined>, compareValue?: string): {
557
+ result: number;
558
+ error?: string;
559
+ };
560
+ /**
561
+ * Validates a `{fieldName}` expression for the formula field type.
562
+ * Checks that all `{ref}` names exist in `availableFieldNames` and parentheses are balanced.
563
+ */
564
+ declare function validateFormulaExpression(expression: string, availableFieldNames: string[]): {
565
+ valid: true;
566
+ } | {
567
+ valid: false;
568
+ error: string;
569
+ };
570
+ /**
571
+ * Get all fields usable as formula references for a 'formula' type field.
572
+ * Includes numeric (number) and other formula-type fields (excluding the field itself).
573
+ * Returns all non-excluded fields so users can reference any form value.
574
+ */
575
+ declare function getFieldsForFormula(schema: FormSchema, excludeFieldId?: string): {
576
+ id: string;
577
+ fieldName: string;
578
+ label: string;
579
+ }[];
580
+ /**
581
+ * Detects circular dependencies for a 'formula' type field.
582
+ * Builds a dependency graph from all expression placeholders and checks for cycles.
583
+ */
584
+ declare function detectFormulaFieldCircularDependency(schema: FormSchema, formulaFieldId: string, config: FormulaConfig): boolean;
512
585
 
513
586
  /** Reset counter (for testing or new form load) */
514
587
  declare function resetNameGeneratorCounter(): void;
@@ -523,4 +596,4 @@ declare const initFormBuilder: (options: FormBuilderOptions & {
523
596
  containerId: string;
524
597
  }) => FormBuilder;
525
598
 
526
- export { type AsyncOptionSource, type DateConstraint, type FieldType, type FieldValidations, type FieldWidth, FormBuilder, type FormBuilderOptions, type FormField, FormRenderer, type FormSchema, FormSchemaValidation, type FormSection, type GroupPosition, type ISDConfig, LOOKUP_SOURCE_TYPE_OPTIONS, type LookupSourceType, type MasterType, type NameGeneratorFormat, type ValidationObject, type ValidationRule, builderToPlatform, cleanFormSchema, convertValidationObjectToArray, detectCircularDependency, evaluateFormula, formStore, generateName, getColSpanFromWidth, getNumericFieldsForFormula, getValidationConfigForAngular, initFormBuilder, parseFormulaDependencies, parseWidth, platformToBuilder, resetNameGeneratorCounter, validateFormula };
599
+ export { type AsyncOptionSource, type DateConstraint, type FieldType, type FieldValidations, type FieldWidth, FormBuilder, type FormBuilderOptions, type FormField, FormRenderer, type FormSchema, FormSchemaValidation, type FormSection, type FormulaCondition, type FormulaConfig, type GroupPosition, type ISDConfig, LOOKUP_SOURCE_TYPE_OPTIONS, type LookupSourceType, type MasterType, type NameGeneratorFormat, type ValidationObject, type ValidationRule, builderToPlatform, cleanFormSchema, convertValidationObjectToArray, detectCircularDependency, detectFormulaFieldCircularDependency, evaluateFormula, evaluateFormulaConfig, evaluateFormulaExpression, extractBracketFields, formStore, generateName, getColSpanFromWidth, getFieldsForFormula, getNumericFieldsForFormula, getValidationConfigForAngular, initFormBuilder, parseFormulaDependencies, parseWidth, platformToBuilder, resetNameGeneratorCounter, validateFormula, validateFormulaExpression };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import * as zustand_vanilla from 'zustand/vanilla';
3
3
 
4
- type FieldType = 'text' | 'textarea' | 'number' | 'date' | 'datetime' | 'select' | 'checkbox' | 'radio' | 'toggle' | 'binary_choice' | 'repeater' | 'file' | 'image' | 'email' | 'phone' | 'name_generator';
4
+ type FieldType = 'text' | 'textarea' | 'number' | 'date' | 'datetime' | 'select' | 'checkbox' | 'radio' | 'toggle' | 'binary_choice' | 'repeater' | 'file' | 'image' | 'email' | 'phone' | 'name_generator' | 'formula';
5
5
  /** Name generator format options for name_generator field type */
6
6
  type NameGeneratorFormat = 'TEXT_HYPHEN_ID' | 'TEXT_UNDERSCORE_ID' | 'TEXT_SLASH_ID' | 'TEXT_ID' | 'ID_HYPHEN_TEXT' | 'ID_UNDERSCORE_TEXT' | 'TEXT_YEAR_ID' | 'TEXT_MONTH_ID' | 'TEXT_YEAR_MONTH_ID' | 'TEXT_ACCOUNT_CODE_ID' | 'TEXT_BRANCH_ID' | 'PREFIX_TEXT_ID' | 'TEXT_ID_SUFFIX' | 'TEXT_RANDOM_4' | 'TEXT_YEAR_MONTH_DAY_ID' | 'TEXT_HYPHEN_USER_INPUT' | 'TEXT_UNDERSCORE_USER_INPUT' | 'TEXT_SLASH_USER_INPUT' | 'USER_INPUT_HYPHEN_TEXT' | 'USER_INPUT_UNDERSCORE_TEXT';
7
7
  type FieldWidth = '25%' | '33%' | '50%' | '66%' | '75%' | '100%' | number;
@@ -135,6 +135,7 @@ interface FormField {
135
135
  nameGeneratorPrefix?: string;
136
136
  nameGeneratorSuffix?: string;
137
137
  nameGeneratorIdPadding?: number;
138
+ formulaConfig?: FormulaConfig;
138
139
  }
139
140
  /**
140
141
  * Conditional date constraint — evaluated at runtime against the current date or another field's value.
@@ -146,6 +147,32 @@ interface DateConstraint {
146
147
  compareWith: 'CURRENT_DATE' | 'FIELD';
147
148
  fieldName?: string;
148
149
  }
150
+ /**
151
+ * A single condition row for multi-condition formula fields.
152
+ * When the compare field equals `value`, evaluate `expression`.
153
+ */
154
+ interface FormulaCondition {
155
+ value: string;
156
+ expression: string;
157
+ }
158
+ /**
159
+ * Configuration for the formula field type.
160
+ * Supports two modes: single expression or multiple conditions.
161
+ */
162
+ interface FormulaConfig {
163
+ mode: 'single' | 'multiple';
164
+ /** Used when mode === 'single' */
165
+ single: {
166
+ expression: string;
167
+ };
168
+ /** Used when mode === 'multiple' */
169
+ multiple: {
170
+ compareField: string;
171
+ conditions: FormulaCondition[];
172
+ fallbackExpression: string;
173
+ };
174
+ decimalPlaces: number;
175
+ }
149
176
  /**
150
177
  * ISD (International Subscriber Dialing) configuration for phone fields
151
178
  */
@@ -509,6 +536,52 @@ declare function getNumericFieldsForFormula(schema: FormSchema, excludeFieldId?:
509
536
  fieldName: string;
510
537
  label: string;
511
538
  }[];
539
+ /**
540
+ * Extracts `{fieldName}` placeholder references from a formula expression.
541
+ * Returns unique field names in order of first appearance.
542
+ */
543
+ declare function extractBracketFields(expression: string): string[];
544
+ /**
545
+ * Evaluates a formula expression that uses `{fieldName}` placeholders.
546
+ * Placeholders are resolved to numeric values from `values` before evaluation.
547
+ * Missing/non-numeric values default to 0.
548
+ * Returns NaN on divide-by-zero or syntax error.
549
+ */
550
+ declare function evaluateFormulaExpression(expression: string, values: Record<string, number | string | undefined>): number;
551
+ /**
552
+ * Evaluates a complete FormulaConfig using the provided field values.
553
+ * For `multiple` mode, `compareValue` is the current value of the compare field.
554
+ * Returns `{ result, error? }`.
555
+ */
556
+ declare function evaluateFormulaConfig(config: FormulaConfig, values: Record<string, number | string | undefined>, compareValue?: string): {
557
+ result: number;
558
+ error?: string;
559
+ };
560
+ /**
561
+ * Validates a `{fieldName}` expression for the formula field type.
562
+ * Checks that all `{ref}` names exist in `availableFieldNames` and parentheses are balanced.
563
+ */
564
+ declare function validateFormulaExpression(expression: string, availableFieldNames: string[]): {
565
+ valid: true;
566
+ } | {
567
+ valid: false;
568
+ error: string;
569
+ };
570
+ /**
571
+ * Get all fields usable as formula references for a 'formula' type field.
572
+ * Includes numeric (number) and other formula-type fields (excluding the field itself).
573
+ * Returns all non-excluded fields so users can reference any form value.
574
+ */
575
+ declare function getFieldsForFormula(schema: FormSchema, excludeFieldId?: string): {
576
+ id: string;
577
+ fieldName: string;
578
+ label: string;
579
+ }[];
580
+ /**
581
+ * Detects circular dependencies for a 'formula' type field.
582
+ * Builds a dependency graph from all expression placeholders and checks for cycles.
583
+ */
584
+ declare function detectFormulaFieldCircularDependency(schema: FormSchema, formulaFieldId: string, config: FormulaConfig): boolean;
512
585
 
513
586
  /** Reset counter (for testing or new form load) */
514
587
  declare function resetNameGeneratorCounter(): void;
@@ -523,4 +596,4 @@ declare const initFormBuilder: (options: FormBuilderOptions & {
523
596
  containerId: string;
524
597
  }) => FormBuilder;
525
598
 
526
- export { type AsyncOptionSource, type DateConstraint, type FieldType, type FieldValidations, type FieldWidth, FormBuilder, type FormBuilderOptions, type FormField, FormRenderer, type FormSchema, FormSchemaValidation, type FormSection, type GroupPosition, type ISDConfig, LOOKUP_SOURCE_TYPE_OPTIONS, type LookupSourceType, type MasterType, type NameGeneratorFormat, type ValidationObject, type ValidationRule, builderToPlatform, cleanFormSchema, convertValidationObjectToArray, detectCircularDependency, evaluateFormula, formStore, generateName, getColSpanFromWidth, getNumericFieldsForFormula, getValidationConfigForAngular, initFormBuilder, parseFormulaDependencies, parseWidth, platformToBuilder, resetNameGeneratorCounter, validateFormula };
599
+ export { type AsyncOptionSource, type DateConstraint, type FieldType, type FieldValidations, type FieldWidth, FormBuilder, type FormBuilderOptions, type FormField, FormRenderer, type FormSchema, FormSchemaValidation, type FormSection, type FormulaCondition, type FormulaConfig, type GroupPosition, type ISDConfig, LOOKUP_SOURCE_TYPE_OPTIONS, type LookupSourceType, type MasterType, type NameGeneratorFormat, type ValidationObject, type ValidationRule, builderToPlatform, cleanFormSchema, convertValidationObjectToArray, detectCircularDependency, detectFormulaFieldCircularDependency, evaluateFormula, evaluateFormulaConfig, evaluateFormulaExpression, extractBracketFields, formStore, generateName, getColSpanFromWidth, getFieldsForFormula, getNumericFieldsForFormula, getValidationConfigForAngular, initFormBuilder, parseFormulaDependencies, parseWidth, platformToBuilder, resetNameGeneratorCounter, validateFormula, validateFormulaExpression };