@form-eng/core 1.0.0

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.
@@ -0,0 +1,1457 @@
1
+ import * as react_hook_form from 'react-hook-form';
2
+ import { FieldError, UseFormSetValue } from 'react-hook-form';
3
+ import React from 'react';
4
+ import * as react_jsx_runtime from 'react/jsx-runtime';
5
+
6
+ /** Dropdown/select option */
7
+ interface IOption {
8
+ /** The option value (used for selection state) */
9
+ value: string | number;
10
+ /** Display label shown to the user */
11
+ label: string;
12
+ /** Whether this option is disabled (visible but not selectable) */
13
+ disabled?: boolean;
14
+ /** Grouping label for option groups (e.g., select optgroup) */
15
+ group?: string;
16
+ /** Icon identifier for rendering alongside the label */
17
+ icon?: string;
18
+ /** Color indicator (e.g., for status badges) */
19
+ color?: string;
20
+ }
21
+
22
+ /**
23
+ * Condition types for the v2 rule engine.
24
+ *
25
+ * Conditions can be field-level comparisons or logical combinations (AND/OR/NOT).
26
+ * Used in IRule.when, IValidationRule.when, and IWizardStepCondition.
27
+ */
28
+ /** A condition that compares a single field's value */
29
+ interface IFieldCondition {
30
+ /** The field name to evaluate */
31
+ field: string;
32
+ /** Comparison operator */
33
+ operator: "equals" | "notEquals" | "greaterThan" | "lessThan" | "greaterThanOrEqual" | "lessThanOrEqual" | "contains" | "notContains" | "startsWith" | "endsWith" | "in" | "notIn" | "isEmpty" | "isNotEmpty" | "matches";
34
+ /** The value to compare against. Not required for isEmpty/isNotEmpty. */
35
+ value?: unknown;
36
+ }
37
+ /** A logical combination of conditions */
38
+ interface ILogicalCondition {
39
+ /** Logical operator to combine child conditions */
40
+ operator: "and" | "or" | "not";
41
+ /** Child conditions to combine */
42
+ conditions: ICondition[];
43
+ }
44
+ /** Union type: either a field comparison or a logical combination */
45
+ type ICondition = IFieldCondition | ILogicalCondition;
46
+ /** Type guard: checks if a condition is a logical condition (and/or/not) */
47
+ declare function isLogicalCondition(condition: ICondition): condition is ILogicalCondition;
48
+ /** Type guard: checks if a condition is a field condition */
49
+ declare function isFieldCondition(condition: ICondition): condition is IFieldCondition;
50
+
51
+ /**
52
+ * Unified validation rule configuration.
53
+ *
54
+ * Handles sync, async, and cross-field validation through a single interface.
55
+ * Validators are resolved by name from the unified ValidationRegistry.
56
+ */
57
+ interface IValidationRule {
58
+ /** Validator name (resolved from the unified ValidationRegistry) */
59
+ name: string;
60
+ /** Parameters passed to the validator function */
61
+ params?: Record<string, unknown>;
62
+ /** Custom error message (overrides the validator's default) */
63
+ message?: string;
64
+ /** Whether this validator is async (returns a Promise) */
65
+ async?: boolean;
66
+ /** Debounce delay in ms for async validators */
67
+ debounceMs?: number;
68
+ /** Conditional validation: only run when this condition is met */
69
+ when?: ICondition;
70
+ }
71
+
72
+ /**
73
+ * Effects applied by a rule when its condition is met (or in the else branch).
74
+ *
75
+ * Any property set here overrides the field's base config.
76
+ * The `fields` property can affect OTHER fields (cross-field effects).
77
+ */
78
+ interface IFieldEffect {
79
+ /** Override required state */
80
+ required?: boolean;
81
+ /** Override hidden state */
82
+ hidden?: boolean;
83
+ /** Override readOnly state */
84
+ readOnly?: boolean;
85
+ /** Override field label */
86
+ label?: string;
87
+ /** Swap the component type (preferred over component) */
88
+ type?: string;
89
+ /** Swap the component type (deprecated, use type instead) */
90
+ component?: string;
91
+ /** Replace dropdown options */
92
+ options?: IOption[];
93
+ /** Replace validation rules */
94
+ validate?: IValidationRule[];
95
+ /** Override computed value expression */
96
+ computedValue?: string;
97
+ /** Override field ordering */
98
+ fieldOrder?: string[];
99
+ /** Apply effects to OTHER fields (keyed by field name) */
100
+ fields?: Record<string, IFieldEffect>;
101
+ }
102
+
103
+ /**
104
+ * A declarative rule that conditionally modifies field state.
105
+ *
106
+ * Rules replace the v1 dependencies, dependencyRules, dropdownDependencies,
107
+ * and orderDependencies with a single unified system.
108
+ */
109
+ interface IRule {
110
+ /** Optional rule identifier (for debugging/tracing) */
111
+ id?: string;
112
+ /** Condition that determines whether this rule fires */
113
+ when: ICondition;
114
+ /** Effects applied when the condition is true */
115
+ then: IFieldEffect;
116
+ /** Effects applied when the condition is false */
117
+ else?: IFieldEffect;
118
+ /** Priority for conflict resolution (higher = wins). Default: 0. */
119
+ priority?: number;
120
+ }
121
+
122
+ /**
123
+ * Static configuration for a single form field (v2 schema).
124
+ *
125
+ * This is the primary consumer-facing type used to define forms.
126
+ * All dependency, validation, and state-management concerns use
127
+ * the unified `rules` and `validate` arrays.
128
+ */
129
+ interface IFieldConfig {
130
+ /** UI component type key (e.g., "Textbox", "Dropdown", "Toggle"). Must match a registered component. */
131
+ type: string;
132
+ /** Display label for the field (required in v2). */
133
+ label: string;
134
+ /** Whether the field is required for form submission. Can be overridden by rules. */
135
+ required?: boolean;
136
+ /** Whether the field is hidden by default. Can be toggled by rules. */
137
+ hidden?: boolean;
138
+ /** Whether the field is read-only (rendered but not editable). Can be toggled by rules. */
139
+ readOnly?: boolean;
140
+ /** Default value applied when the field is visible and its current value is null/undefined. */
141
+ defaultValue?: unknown;
142
+ /** Computed value expression. Uses $values.fieldName for references, $fn.name() for value functions. */
143
+ computedValue?: string;
144
+ /** If true, computedValue only runs during create (not edit). */
145
+ computeOnCreateOnly?: boolean;
146
+ /** Static dropdown/select options. */
147
+ options?: IOption[];
148
+ /** Validation rules (unified: sync, async, cross-field, conditional). */
149
+ validate?: IValidationRule[];
150
+ /** Business rules (unified: replaces dependencies, dependencyRules, dropdownDependencies, orderDependencies). */
151
+ rules?: IRule[];
152
+ /** Field array item configs (full IFieldConfig, not stripped). Keys are field names within an item. */
153
+ items?: Record<string, IFieldConfig>;
154
+ /** Minimum number of items in a field array. */
155
+ minItems?: number;
156
+ /** Maximum number of items in a field array. */
157
+ maxItems?: number;
158
+ /** Arbitrary metadata passed through to the field component (e.g., icons, sort settings). */
159
+ config?: Record<string, unknown>;
160
+ /** Short description shown as field tooltip or help text. */
161
+ description?: string;
162
+ /** Placeholder text for empty fields. */
163
+ placeholder?: string;
164
+ /** Extended help text (e.g., shown in a popover or below the field). */
165
+ helpText?: string;
166
+ /** Whether changing this field triggers a confirmation modal before save. */
167
+ confirmInput?: boolean;
168
+ /** If true, the field is not rendered when the form is in create mode. */
169
+ hideOnCreate?: boolean;
170
+ /** If true, the field ignores the layout-level disabled/readOnly override. */
171
+ skipLayoutReadOnly?: boolean;
172
+ /** Whether the field is disabled at the layout level. */
173
+ disabled?: boolean;
174
+ }
175
+
176
+ /** Configuration for a single wizard step */
177
+ interface IWizardStep {
178
+ /** Unique step identifier */
179
+ id: string;
180
+ /** Step title displayed to the user */
181
+ title: string;
182
+ /** Optional step description */
183
+ description?: string;
184
+ /** Field names included in this step */
185
+ fields: string[];
186
+ /** Condition under which this step is visible (uses v2 condition system) */
187
+ visibleWhen?: ICondition;
188
+ }
189
+ /** Wizard configuration */
190
+ interface IWizardConfig {
191
+ /** Step definitions */
192
+ steps: IWizardStep[];
193
+ /** If true, users must complete steps in order (no skipping ahead) */
194
+ linearNavigation?: boolean;
195
+ /** If true, validate the current step before allowing navigation */
196
+ validateOnStepChange?: boolean;
197
+ /** If true, save form data when navigating between steps */
198
+ saveOnStepChange?: boolean;
199
+ }
200
+
201
+ /**
202
+ * Analytics/telemetry callback hooks for form lifecycle events.
203
+ *
204
+ * All callbacks are optional -- if not provided, the corresponding events are silently ignored.
205
+ */
206
+ interface IAnalyticsCallbacks {
207
+ /** Fired when a field receives focus. */
208
+ onFieldFocus?: (fieldName: string) => void;
209
+ /** Fired when a field loses focus. `timeSpentMs` is the duration since the matching onFieldFocus. */
210
+ onFieldBlur?: (fieldName: string, timeSpentMs: number) => void;
211
+ /** Fired when a field value changes. */
212
+ onFieldChange?: (fieldName: string, oldValue: unknown, newValue: unknown) => void;
213
+ /** Fired when field validation fails. */
214
+ onValidationError?: (fieldName: string, errors: string[]) => void;
215
+ /** Fired on successful form submission. `durationMs` is elapsed time since form mount. */
216
+ onFormSubmit?: (values: Record<string, unknown>, durationMs: number) => void;
217
+ /** Fired when the user navigates away with unsaved changes. */
218
+ onFormAbandonment?: (filledFields: string[], emptyRequiredFields: string[]) => void;
219
+ /** Fired when the wizard step changes. */
220
+ onWizardStepChange?: (fromStep: number, toStep: number) => void;
221
+ /** Fired when a rule is evaluated. */
222
+ onRuleTriggered?: (event: {
223
+ fieldName: string;
224
+ ruleIndex: number;
225
+ conditionMet: boolean;
226
+ }) => void;
227
+ }
228
+
229
+ /**
230
+ * Top-level form configuration (v2 schema).
231
+ *
232
+ * Wraps all field definitions, ordering, wizard config, and form-level settings
233
+ * into a single versioned object. This replaces the loose Dictionary<IFieldConfig> pattern.
234
+ */
235
+ interface IFormConfig {
236
+ /** Schema version. Must be 2. */
237
+ version: 2;
238
+ /** Field definitions keyed by field name. */
239
+ fields: Record<string, IFieldConfig>;
240
+ /** Default field display order. If omitted, uses Object.keys(fields) order. */
241
+ fieldOrder?: string[];
242
+ /** Multi-step wizard configuration. */
243
+ wizard?: IWizardConfig;
244
+ /** Form-level settings. */
245
+ settings?: IFormSettings;
246
+ }
247
+ /** Form-level settings */
248
+ interface IFormSettings {
249
+ /** Whether the form is in manual save mode (no auto-save on field change). */
250
+ manualSave?: boolean;
251
+ /** Timeout in ms for each save attempt. */
252
+ saveTimeoutMs?: number;
253
+ /** Maximum save retry attempts. */
254
+ maxSaveRetries?: number;
255
+ /** Number of visible fields before collapse. */
256
+ expandCutoffCount?: number;
257
+ /** Max height in px when collapsed. */
258
+ collapsedMaxHeight?: number;
259
+ /** Enable field filter/search input. */
260
+ enableFilter?: boolean;
261
+ /** Analytics/telemetry callbacks for form lifecycle events. */
262
+ analytics?: IAnalyticsCallbacks;
263
+ }
264
+
265
+ /**
266
+ * Props passed to injected field components (v2 schema).
267
+ *
268
+ * This replaces the v1 IHookFieldSharedProps type.
269
+ * The generic parameter T types the `config` metadata object.
270
+ */
271
+ interface IFieldProps<T = Record<string, unknown>> {
272
+ /** Field name (unique identifier within the form) */
273
+ fieldName?: string;
274
+ /** Entity ID */
275
+ entityId?: string;
276
+ /** Entity type */
277
+ entityType?: string;
278
+ /** Program name */
279
+ programName?: string;
280
+ /** Parent entity ID */
281
+ parentEntityId?: string;
282
+ /** Parent entity type */
283
+ parentEntityType?: string;
284
+ /** Whether the field is read-only */
285
+ readOnly?: boolean;
286
+ /** Whether the field is required */
287
+ required?: boolean;
288
+ /** Current field error */
289
+ error?: FieldError;
290
+ /** Total error count across all fields */
291
+ errorCount?: number;
292
+ /** Whether the field is currently saving */
293
+ saving?: boolean;
294
+ /** Whether save is pending due to errors */
295
+ savePending?: boolean;
296
+ /** Current field value */
297
+ value?: unknown;
298
+ /** Field-specific config metadata (was `meta` in v1) */
299
+ config?: T;
300
+ /** Dropdown/select options (was `dropdownOptions` in v1) */
301
+ options?: IOption[];
302
+ /** Field label */
303
+ label?: string;
304
+ /** Component type string */
305
+ type?: string;
306
+ /** Description text */
307
+ description?: string;
308
+ /** Placeholder text */
309
+ placeholder?: string;
310
+ /** Help text */
311
+ helpText?: string;
312
+ /** Callback to set a field's value */
313
+ setFieldValue?: (fieldName: string, fieldValue: unknown, skipSave?: boolean, timeout?: number) => void;
314
+ }
315
+
316
+ /**
317
+ * Runtime state for a single field after all rules have been evaluated.
318
+ *
319
+ * This replaces the v1 IBusinessRule type. Contains the evaluated state
320
+ * consumed by form components to determine rendering behavior.
321
+ */
322
+ interface IRuntimeFieldState {
323
+ /** UI component type to render. May be swapped by rules. */
324
+ type?: string;
325
+ /** Whether the field is required for form submission. */
326
+ required?: boolean;
327
+ /** Whether the field is hidden (not rendered). Hidden fields skip validation. */
328
+ hidden?: boolean;
329
+ /** Whether the field is read-only (rendered but not editable). */
330
+ readOnly?: boolean;
331
+ /** Current validation rules (may be modified by rules). */
332
+ validate?: IValidationRule[];
333
+ /** Computed value expression (may be set by rules). */
334
+ computedValue?: string;
335
+ /** Whether changing this field triggers a confirmation modal. */
336
+ confirmInput?: boolean;
337
+ /** Available options for dropdown-type fields (may be filtered by rules). */
338
+ options?: IOption[];
339
+ /** Override field label (may be set by rules). */
340
+ label?: string;
341
+ /** Default value to set when the field value is null and the field is visible. */
342
+ defaultValue?: unknown;
343
+ /** If true, computedValue only runs during create. */
344
+ computeOnCreateOnly?: boolean;
345
+ /** Fields that this field's rules affect (forward dependencies). */
346
+ dependentFields?: string[];
347
+ /** Fields whose values affect this field (reverse dependencies). */
348
+ dependsOnFields?: string[];
349
+ /** The source rules that produced this state (for tracing/debugging). */
350
+ activeRuleIds?: string[];
351
+ }
352
+ /**
353
+ * Runtime state for the entire form.
354
+ *
355
+ * This replaces the v1 IConfigBusinessRules + IBusinessRulesState types.
356
+ */
357
+ interface IRuntimeFormState {
358
+ /** Per-field runtime state keyed by field name. */
359
+ fieldStates: Record<string, IRuntimeFieldState>;
360
+ /** Current field display order. */
361
+ fieldOrder: string[];
362
+ }
363
+ /**
364
+ * State stored in the rules engine provider (keyed by config name).
365
+ *
366
+ * This replaces the v1 IBusinessRulesState type.
367
+ */
368
+ interface IRulesEngineState {
369
+ configs: Record<string, IRuntimeFormState>;
370
+ }
371
+
372
+ /** Action type keys for the rules engine reducer */
373
+ declare enum RulesEngineActionType {
374
+ SET = "RULES_ENGINE_SET",
375
+ UPDATE = "RULES_ENGINE_UPDATE",
376
+ CLEAR = "RULES_ENGINE_CLEAR"
377
+ }
378
+ interface ISetRulesAction {
379
+ readonly type: RulesEngineActionType.SET;
380
+ readonly payload: {
381
+ readonly configName: string;
382
+ readonly formState: IRuntimeFormState;
383
+ };
384
+ }
385
+ interface IUpdateRulesAction {
386
+ readonly type: RulesEngineActionType.UPDATE;
387
+ readonly payload: {
388
+ readonly configName: string;
389
+ readonly formState: IRuntimeFormState;
390
+ };
391
+ }
392
+ interface IClearRulesAction {
393
+ readonly type: RulesEngineActionType.CLEAR;
394
+ readonly payload: {
395
+ readonly configName?: string;
396
+ };
397
+ }
398
+ type RulesEngineAction = ISetRulesAction | IUpdateRulesAction | IClearRulesAction;
399
+
400
+ /** All localizable string keys used by the core package */
401
+ interface ICoreLocaleStrings {
402
+ autoSavePending: string;
403
+ savePending: string;
404
+ saving: string;
405
+ saveError: string;
406
+ save: string;
407
+ cancel: string;
408
+ create: string;
409
+ update: string;
410
+ confirm: string;
411
+ add: string;
412
+ edit: string;
413
+ deleteLabel: string;
414
+ remove: string;
415
+ close: string;
416
+ clear: string;
417
+ required: string;
418
+ remaining: string;
419
+ na: string;
420
+ unknown: string;
421
+ loading: string;
422
+ noResultsFound: string;
423
+ clickToClear: string;
424
+ linkTitleLabel: string;
425
+ linkUrlLabel: string;
426
+ urlRequired: string;
427
+ seeLess: string;
428
+ expand: string;
429
+ openExpandedTextEditor: string;
430
+ closeExpandedTextEditor: string;
431
+ unsavedChanges: string;
432
+ returnToEditing: string;
433
+ dontSave: string;
434
+ overview: string;
435
+ by: string;
436
+ filterFields: string;
437
+ saved: string;
438
+ saveFailed: string;
439
+ validating: string;
440
+ stepOf: (current: number, total: number) => string;
441
+ formWizard: string;
442
+ itemOfTotal: (index: number, total: number, label: string) => string;
443
+ saveChangesTo: (title: string) => string;
444
+ invalidUrl: string;
445
+ invalidEmail: string;
446
+ invalidPhoneNumber: string;
447
+ invalidYear: string;
448
+ contentExceedsMaxSize: (maxKb: number) => string;
449
+ noSpecialCharacters: string;
450
+ invalidCurrencyFormat: string;
451
+ duplicateValue: (value: string) => string;
452
+ mustBeAtLeastChars: (min: number) => string;
453
+ mustBeAtMostChars: (max: number) => string;
454
+ mustBeANumber: string;
455
+ mustBeBetween: (min: number, max: number) => string;
456
+ thisFieldIsRequired: string;
457
+ saveRetrying: string;
458
+ saveTimeout: string;
459
+ draftRecovered: string;
460
+ discardDraft: string;
461
+ unsavedChangesWarning: string;
462
+ }
463
+
464
+ /**
465
+ * A field config where rule targets are constrained to known field names.
466
+ * Provides compile-time checking that cross-field rule effects reference valid fields.
467
+ */
468
+ type TypedFieldConfig<TFields extends string> = Omit<IFieldConfig, "rules"> & {
469
+ /**
470
+ * Business rules with type-safe cross-field effect targets.
471
+ * Field names in `then.fields` and `else.fields` are checked against TFields.
472
+ */
473
+ rules?: Array<{
474
+ id?: string;
475
+ when: ICondition;
476
+ then: Omit<IFieldEffect, "fields"> & {
477
+ fields?: Partial<Record<TFields, IFieldEffect>>;
478
+ };
479
+ else?: Omit<IFieldEffect, "fields"> & {
480
+ fields?: Partial<Record<TFields, IFieldEffect>>;
481
+ };
482
+ priority?: number;
483
+ }>;
484
+ };
485
+ /**
486
+ * Define field configs with type-safe rule references.
487
+ * TypeScript will error if a rule's cross-field effect targets a field name that doesn't exist.
488
+ *
489
+ * At runtime this is a no-op -- it just returns the input. The value is purely at compile time.
490
+ *
491
+ * @example
492
+ * const config = defineFormConfig({
493
+ * name: { type: "Textbox", label: "Name" },
494
+ * status: {
495
+ * type: "Dropdown",
496
+ * label: "Status",
497
+ * options: [{ value: "Active", label: "Active" }, { value: "Inactive", label: "Inactive" }],
498
+ * rules: [{
499
+ * when: { field: "status", operator: "equals", value: "Active" },
500
+ * then: { fields: { name: { required: true } } }, // "name" checked at compile time
501
+ * }],
502
+ * },
503
+ * });
504
+ */
505
+ declare function defineFormConfig<T extends Record<string, TypedFieldConfig<Extract<keyof T, string>>>>(fields: T): Record<string, IFieldConfig>;
506
+
507
+ /**
508
+ * Interface to track the confirm input modal props
509
+ */
510
+ interface IConfirmInputModalProps {
511
+ /**
512
+ * The field that triggered the modal
513
+ */
514
+ confirmInputsTriggeredBy?: string;
515
+ /**
516
+ * The fields that need need to be updated within the Confirm Input Modal
517
+ */
518
+ dependentFieldNames?: string[];
519
+ /**
520
+ * Dirty fields that can be saved w/o confirmation
521
+ */
522
+ otherDirtyFields?: string[];
523
+ }
524
+
525
+ interface IFieldToRender {
526
+ /**
527
+ * Field Name
528
+ */
529
+ fieldName: string;
530
+ /**
531
+ * Soft Hidden means render the controller for hook forms but not the field input
532
+ */
533
+ softHidden?: boolean;
534
+ }
535
+
536
+ /** Generic dictionary type */
537
+ type Dictionary<T> = Record<string, T>;
538
+ /** Entity data type */
539
+ type IEntityData = Record<string, unknown>;
540
+ /** Sub-entity value type */
541
+ type SubEntityType = string | number | boolean | Date | object | null | undefined;
542
+ declare function isEmpty(value: unknown): boolean;
543
+ declare function isNull(value: unknown): value is null | undefined;
544
+ declare function isStringEmpty(value: string | null | undefined): boolean;
545
+ declare function deepCopy<T>(obj: T): T;
546
+ declare function convertBooleanToYesOrNoText(value: boolean | null | undefined): string;
547
+ /** Sort options alphabetically by label */
548
+ declare function sortDropdownOptions(a: {
549
+ label?: string;
550
+ }, b: {
551
+ label?: string;
552
+ }): number;
553
+ /** Create an option from a value string (value and label are the same) */
554
+ declare function createOption(value: string): {
555
+ value: string;
556
+ label: string;
557
+ };
558
+
559
+ interface IFormEngineSharedProps {
560
+ entityId?: string;
561
+ entityType?: string;
562
+ programName: string;
563
+ configName: string;
564
+ parentEntityId?: string;
565
+ parentEntityType?: string;
566
+ entityPath?: string;
567
+ areAllFieldsReadonly?: boolean;
568
+ expandCutoffCount?: number;
569
+ collapsedMaxHeight?: number;
570
+ isCreate?: boolean;
571
+ customSaveKey?: string;
572
+ customSaveCallbackKey?: string;
573
+ enableFilter?: boolean;
574
+ /** Current user's identifier for value functions like setLoggedInUser */
575
+ currentUserId?: string;
576
+ /** Callback when save error occurs */
577
+ onSaveError?: (error: string) => void;
578
+ /** Parent entity data for value functions like inheritFromParent */
579
+ parentEntity?: IEntityData;
580
+ }
581
+
582
+ declare const FIELD_PARENT_PREFIX = "Parent.";
583
+ /** Component type constants */
584
+ declare const ComponentTypes: {
585
+ readonly Textbox: "Textbox";
586
+ readonly Dropdown: "Dropdown";
587
+ readonly Toggle: "Toggle";
588
+ readonly Number: "Number";
589
+ readonly MultiSelect: "Multiselect";
590
+ readonly DateControl: "DateControl";
591
+ readonly Slider: "Slider";
592
+ readonly Fragment: "DynamicFragment";
593
+ readonly SimpleDropdown: "SimpleDropdown";
594
+ readonly MultiSelectSearch: "MultiSelectSearch";
595
+ readonly PopOutEditor: "PopOutEditor";
596
+ readonly RichText: "RichText";
597
+ readonly Textarea: "Textarea";
598
+ readonly DocumentLinks: "DocumentLinks";
599
+ readonly StatusDropdown: "StatusDropdown";
600
+ readonly ReadOnly: "ReadOnly";
601
+ readonly ReadOnlyArray: "ReadOnlyArray";
602
+ readonly ReadOnlyDateTime: "ReadOnlyDateTime";
603
+ readonly ReadOnlyCumulativeNumber: "ReadOnlyCumulativeNumber";
604
+ readonly ReadOnlyRichText: "ReadOnlyRichText";
605
+ readonly ReadOnlyWithButton: "ReadOnlyWithButton";
606
+ readonly ChoiceSet: "ChoiceSet";
607
+ readonly FieldArray: "FieldArray";
608
+ };
609
+ /** Form-level constants */
610
+ declare const FormConstants: {
611
+ readonly defaultExpandCutoffCount: 12;
612
+ readonly loadingShimmerCount: 12;
613
+ readonly loadingFieldShimmerHeight: 32;
614
+ readonly na: "n/a";
615
+ readonly panelActionKeys: {
616
+ readonly cancel: "Cancel";
617
+ readonly close: "Close";
618
+ readonly create: "Create";
619
+ readonly update: "Update";
620
+ };
621
+ readonly urlRegex: RegExp;
622
+ readonly errorColor: "#a4262c";
623
+ };
624
+
625
+ /**
626
+ * User-facing string literals (v2).
627
+ * All properties resolve through the locale registry.
628
+ */
629
+ declare const FormStrings: {
630
+ readonly autoSavePending: string;
631
+ readonly savePending: string;
632
+ readonly remaining: string;
633
+ readonly saving: string;
634
+ readonly seeLess: string;
635
+ readonly expand: string;
636
+ readonly required: string;
637
+ readonly save: string;
638
+ readonly cancel: string;
639
+ readonly create: string;
640
+ readonly update: string;
641
+ readonly na: string;
642
+ readonly saveError: string;
643
+ readonly confirm: string;
644
+ readonly linkTitleLabel: string;
645
+ readonly linkUrlLabel: string;
646
+ readonly add: string;
647
+ readonly edit: string;
648
+ readonly deleteLabel: string;
649
+ readonly remove: string;
650
+ readonly unknown: string;
651
+ readonly close: string;
652
+ readonly loading: string;
653
+ readonly noResultsFound: string;
654
+ readonly clickToClear: string;
655
+ readonly clear: string;
656
+ readonly urlRequired: string;
657
+ readonly openExpandedTextEditor: string;
658
+ readonly closeExpandedTextEditor: string;
659
+ readonly unsavedChanges: string;
660
+ readonly returnToEditing: string;
661
+ readonly dontSave: string;
662
+ readonly overview: string;
663
+ readonly by: string;
664
+ readonly filterFields: string;
665
+ readonly saved: string;
666
+ readonly saveFailed: string;
667
+ readonly validating: string;
668
+ readonly stepOf: (current: number, total: number) => string;
669
+ readonly formWizard: string;
670
+ readonly itemOfTotal: (index: number, total: number, label: string) => string;
671
+ readonly saveChangesTo: (title: string) => string;
672
+ readonly draftRecovered: string;
673
+ readonly discardDraft: string;
674
+ readonly unsavedChangesWarning: string;
675
+ readonly saveRetrying: string;
676
+ readonly saveTimeout: string;
677
+ };
678
+
679
+ interface IRulesEngineProvider {
680
+ rulesState: IRulesEngineState;
681
+ initFormState: (configName: string, defaultValues: IEntityData, fields: Record<string, IFieldConfig>, areAllFieldsReadonly?: boolean) => IRuntimeFormState;
682
+ processFieldChange: (entityData: IEntityData, configName: string, fieldName: string, fields: Record<string, IFieldConfig>) => void;
683
+ clearFormState: (configName?: string) => void;
684
+ }
685
+
686
+ declare function UseRulesEngineContext(): IRulesEngineProvider;
687
+ declare const RulesEngineProvider: React.FC<React.PropsWithChildren<{}>>;
688
+
689
+ interface IInjectedFieldProvider {
690
+ injectedFields: Record<string, React.JSX.Element>;
691
+ setInjectedFields: (injectedFields: Record<string, React.JSX.Element>) => void;
692
+ }
693
+
694
+ declare function UseInjectedFieldContext(): IInjectedFieldProvider;
695
+ interface InjectedFieldProviderProps {
696
+ /** Optional initial field registry. If provided, fields are set immediately. */
697
+ injectedFields?: Record<string, React.JSX.Element>;
698
+ children?: React.ReactNode;
699
+ }
700
+ declare const InjectedFieldProvider: React.FC<InjectedFieldProviderProps>;
701
+
702
+ /**
703
+ * Builds the dependency graph from field configs.
704
+ * Returns adjacency lists: for each field, which other fields depend on it.
705
+ */
706
+ declare function buildDependencyGraph(fields: Record<string, IFieldConfig>): Record<string, Set<string>>;
707
+ /**
708
+ * Topological sort of field names using Kahn's algorithm.
709
+ * Returns fields in dependency order. Detects cycles.
710
+ */
711
+ declare function topologicalSort(graph: Record<string, Set<string>>): {
712
+ sorted: string[];
713
+ hasCycle: boolean;
714
+ cycleFields: string[];
715
+ };
716
+ /**
717
+ * Builds the default runtime field state from static field configs.
718
+ */
719
+ declare function buildDefaultFieldStates(fields: Record<string, IFieldConfig>, areAllFieldsReadonly?: boolean): Record<string, IRuntimeFieldState>;
720
+ /**
721
+ * Evaluates all rules for all fields against current values.
722
+ * Returns the full runtime form state.
723
+ */
724
+ declare function evaluateAllRules(fields: Record<string, IFieldConfig>, values: IEntityData, areAllFieldsReadonly?: boolean): IRuntimeFormState;
725
+ /**
726
+ * Evaluates rules for fields that are transitively affected by a changed field.
727
+ * Returns only the changed field states (incremental update).
728
+ */
729
+ declare function evaluateAffectedFields(changedField: string, fields: Record<string, IFieldConfig>, values: IEntityData, currentState: IRuntimeFormState): IRuntimeFormState;
730
+
731
+ /**
732
+ * Evaluates a condition tree against the current form values.
733
+ *
734
+ * Supports all 15 field operators and AND/OR/NOT logical operators.
735
+ */
736
+ declare function evaluateCondition(condition: ICondition, values: IEntityData): boolean;
737
+ /**
738
+ * Extracts all field names referenced in a condition tree.
739
+ */
740
+ declare function extractConditionDependencies(condition: ICondition): string[];
741
+
742
+ declare const GetChildEntity: (entityId?: string, entity?: IEntityData, entityPath?: string, idField?: string) => IEntityData | undefined;
743
+ declare const IsExpandVisible: (fieldStates: Record<string, IRuntimeFieldState>, expandCutoffCount?: number) => boolean;
744
+ declare const GetConfirmInputModalProps: (dirtyFieldNames: string[], fieldStates: Record<string, IRuntimeFieldState>) => IConfirmInputModalProps;
745
+ interface IExecuteComputedValue {
746
+ fieldName: string;
747
+ expression: string;
748
+ }
749
+ declare const GetComputedValuesOnDirtyFields: (dirtyFieldNames: string[], fieldStates: Record<string, IRuntimeFieldState>) => IExecuteComputedValue[];
750
+ declare const GetComputedValuesOnCreate: (fieldStates: Record<string, IRuntimeFieldState>) => IExecuteComputedValue[];
751
+ declare const ExecuteComputedValue: (expression: string, values: IEntityData, fieldName?: string, parentEntity?: IEntityData, currentUserId?: string) => SubEntityType;
752
+ declare const CheckFieldValidationRules: (value: unknown, fieldName: string, entityData: IEntityData, state: IRuntimeFieldState) => string | undefined;
753
+ declare const CheckAsyncFieldValidationRules: (value: unknown, fieldName: string, entityData: IEntityData, state: IRuntimeFieldState, signal?: AbortSignal) => Promise<string | undefined>;
754
+ declare const CheckValidDropdownOptions: (fieldStates: Record<string, IRuntimeFieldState>, formValues: IEntityData, setValue: UseFormSetValue<IEntityData>) => void;
755
+ declare const CheckDefaultValues: (fieldStates: Record<string, IRuntimeFieldState>, formValues: IEntityData, setValue: UseFormSetValue<IEntityData>) => void;
756
+ declare const InitOnCreateFormState: (configName: string, fields: Record<string, IFieldConfig>, defaultValues: IEntityData, parentEntity: IEntityData, userId: string, setValue: UseFormSetValue<IEntityData>, initFormState: (configName: string, defaultValues: IEntityData, fields: Record<string, IFieldConfig>, areAllFieldsReadonly?: boolean) => IRuntimeFormState) => {
757
+ formState: IRuntimeFormState;
758
+ initEntityData: IEntityData;
759
+ };
760
+ declare const InitOnEditFormState: (configName: string, fields: Record<string, IFieldConfig>, defaultValues: IEntityData, areAllFieldsReadonly: boolean, initFormState: (configName: string, defaultValues: IEntityData, fields: Record<string, IFieldConfig>, areAllFieldsReadonly?: boolean) => IRuntimeFormState) => {
761
+ formState: IRuntimeFormState;
762
+ initEntityData: IEntityData;
763
+ };
764
+ declare const ShowField: (filterText?: string, value?: SubEntityType, label?: string) => boolean;
765
+ declare const GetFieldsToRender: (fieldRenderLimit: number, fieldOrder: string[], fieldStates?: Record<string, IRuntimeFieldState>) => IFieldToRender[];
766
+ /** Sort options alphabetically by label */
767
+ declare const SortOptions$1: (options: IOption[]) => IOption[];
768
+
769
+ /** Sort options alphabetically by label */
770
+ declare function SortOptions(options: IOption[]): IOption[];
771
+
772
+ interface ICycleError {
773
+ type: "dependency" | "self";
774
+ fields: string[];
775
+ message: string;
776
+ }
777
+ /**
778
+ * Detects circular dependencies in field rules using Kahn's algorithm.
779
+ * Operates on the dependency graph built from IFieldConfig.rules.
780
+ */
781
+ declare function detectDependencyCycles(fields: Record<string, IFieldConfig>): ICycleError[];
782
+ /**
783
+ * Detects self-dependencies (a field's rule references itself in a way that causes loops).
784
+ */
785
+ declare function detectSelfDependencies(fields: Record<string, IFieldConfig>): ICycleError[];
786
+ /**
787
+ * Validates the full dependency graph of field configs.
788
+ * Logs warnings in development, returns errors for programmatic use.
789
+ */
790
+ declare function validateDependencyGraph(fields: Record<string, IFieldConfig>): ICycleError[];
791
+
792
+ /**
793
+ * Unified validator function signature.
794
+ * Handles sync, async, and cross-field validation.
795
+ *
796
+ * @param value - The field's current value
797
+ * @param params - Parameters from IValidationRule.params
798
+ * @param context - Full form context (values, field name, abort signal)
799
+ * @returns Error message string, undefined if valid, or a Promise for async
800
+ */
801
+ type ValidatorFn = (value: unknown, params: Record<string, unknown> | undefined, context: IValidationContext) => string | undefined | Promise<string | undefined>;
802
+ interface IValidationContext {
803
+ fieldName: string;
804
+ values: IEntityData;
805
+ signal?: AbortSignal;
806
+ }
807
+ /** Register custom validators (merge into registry) */
808
+ declare function registerValidators(custom: Record<string, ValidatorFn>): void;
809
+ /** Get a validator by name */
810
+ declare function getValidator(name: string): ValidatorFn | undefined;
811
+ /** Get a copy of the full registry */
812
+ declare function getValidatorRegistry(): Record<string, ValidatorFn>;
813
+ /** Reset registry to defaults (for testing) */
814
+ declare function resetValidatorRegistry(): void;
815
+ /**
816
+ * Run all validation rules for a field value.
817
+ * Handles sync, async, and conditional validation.
818
+ */
819
+ declare function runValidations(value: unknown, rules: IValidationRule[], context: IValidationContext): Promise<string | undefined>;
820
+ /**
821
+ * Run only sync validation rules (no await, fast fail).
822
+ */
823
+ declare function runSyncValidations(value: unknown, rules: IValidationRule[], context: IValidationContext): string | undefined;
824
+ declare function createMinLengthRule(min: number, message?: string): IValidationRule;
825
+ declare function createMaxLengthRule(max: number, message?: string): IValidationRule;
826
+ declare function createNumericRangeRule(min: number, max: number, message?: string): IValidationRule;
827
+ declare function createPatternRule(pattern: string, message: string): IValidationRule;
828
+ declare function createRequiredIfRule(field: string, values: string[], message?: string): IValidationRule;
829
+
830
+ /**
831
+ * Value function signature (v2).
832
+ * Used in computed value expressions via $fn.name() syntax.
833
+ */
834
+ type ValueFunction = (context: IValueFunctionContext) => SubEntityType;
835
+ interface IValueFunctionContext {
836
+ fieldName: string;
837
+ fieldValue?: SubEntityType;
838
+ values: IEntityData;
839
+ parentEntity?: IEntityData;
840
+ currentUserId?: string;
841
+ }
842
+ /** Register custom value functions (merge into registry) */
843
+ declare function registerValueFunctions(custom: Record<string, ValueFunction>): void;
844
+ /** Get a value function by name */
845
+ declare function getValueFunction(name: string): ValueFunction | undefined;
846
+ /** Execute a named value function */
847
+ declare function executeValueFunction(fieldName: string, functionName: string, values: IEntityData, fieldValue?: SubEntityType, parentEntity?: IEntityData, currentUserId?: string): SubEntityType;
848
+ /** Reset registry to defaults (for testing) */
849
+ declare function resetValueFunctionRegistry(): void;
850
+
851
+ interface IConfigValidationError {
852
+ type: "missing_rule_target" | "unregistered_component" | "unregistered_validator" | "circular_dependency" | "self_dependency" | "missing_options" | "invalid_condition";
853
+ fieldName: string;
854
+ message: string;
855
+ details?: string;
856
+ }
857
+ /**
858
+ * Validates field configs for common issues at dev time.
859
+ *
860
+ * Checks:
861
+ * - Rule conditions reference existing fields
862
+ * - Cross-field effects target existing fields
863
+ * - Component types are registered (if registry provided)
864
+ * - Validators are registered
865
+ * - Dropdown fields have options or rules providing them
866
+ * - No circular/self dependencies
867
+ */
868
+ declare function validateFieldConfigs(fields: Record<string, IFieldConfig>, registeredComponents?: Set<string>): IConfigValidationError[];
869
+
870
+ /**
871
+ * Register a partial or full locale override. Unspecified keys fall back to English defaults.
872
+ * Can be called multiple times; each call merges into the current locale.
873
+ */
874
+ declare function registerLocale(partial: Partial<ICoreLocaleStrings>): void;
875
+ /**
876
+ * Get a locale string by key. Returns the registered locale value or the English default.
877
+ */
878
+ declare function getLocaleString<K extends keyof ICoreLocaleStrings>(key: K): ICoreLocaleStrings[K];
879
+ /**
880
+ * Reset the locale to English defaults. Useful for testing.
881
+ */
882
+ declare function resetLocale(): void;
883
+ /**
884
+ * Get the full current locale object. Useful for debugging or bulk operations.
885
+ */
886
+ declare function getCurrentLocale(): ICoreLocaleStrings;
887
+
888
+ interface IWizardNavigationProps {
889
+ steps: IWizardStep[];
890
+ currentStepIndex: number;
891
+ goToStep: (index: number) => void;
892
+ canGoNext: boolean;
893
+ canGoPrev: boolean;
894
+ goNext: () => void;
895
+ goPrev: () => void;
896
+ }
897
+ interface IWizardStepHeaderProps {
898
+ step: IWizardStep;
899
+ stepIndex: number;
900
+ totalSteps: number;
901
+ }
902
+ interface IWizardFormProps {
903
+ wizardConfig: IWizardConfig;
904
+ entityData: IEntityData;
905
+ fieldStates?: Record<string, IRuntimeFieldState>;
906
+ errors?: Record<string, unknown>;
907
+ renderStepContent: (fields: string[]) => React.ReactNode;
908
+ renderStepNavigation?: (props: IWizardNavigationProps) => React.ReactNode;
909
+ renderStepHeader?: (props: IWizardStepHeaderProps) => React.ReactNode;
910
+ onStepChange?: (fromIndex: number, toIndex: number) => void;
911
+ /** Analytics callback for wizard step changes. */
912
+ onAnalyticsStepChange?: (fromStep: number, toStep: number) => void;
913
+ }
914
+ declare const WizardForm: React.FC<IWizardFormProps>;
915
+
916
+ declare function getVisibleSteps(steps: IWizardStep[], entityData: IEntityData): IWizardStep[];
917
+ declare function getStepFields(step: IWizardStep, fieldStates?: Record<string, IRuntimeFieldState>): string[];
918
+ declare function getStepFieldOrder(steps: IWizardStep[], entityData: IEntityData): string[];
919
+ declare function validateStepFields(step: IWizardStep, errors: Record<string, unknown>): string[];
920
+ declare function isStepValid(step: IWizardStep, errors: Record<string, unknown>): boolean;
921
+ declare function getStepIndex(steps: IWizardStep[], stepId: string): number;
922
+
923
+ interface IFieldArrayProps {
924
+ fieldName: string;
925
+ config: IFieldConfig;
926
+ renderItem: (itemFieldNames: string[], index: number, remove: () => void) => React.ReactNode;
927
+ renderAddButton?: (append: () => void, canAdd: boolean) => React.ReactNode;
928
+ }
929
+ declare const FieldArray: React.FC<IFieldArrayProps>;
930
+
931
+ interface IFormEngineProps extends IFormEngineSharedProps {
932
+ /** v2 form config (preferred). If provided, fieldConfigs is ignored. */
933
+ formConfig?: IFormConfig;
934
+ /** v1-style field configs (for migration). Use formConfig instead. */
935
+ fieldConfigs?: Record<string, IFieldConfig>;
936
+ defaultValues: IEntityData;
937
+ isChildEntity?: boolean;
938
+ saveData?: (entityData: IEntityData, dirtyFieldNames?: string[]) => Promise<IEntityData>;
939
+ saveTimeoutMs?: number;
940
+ maxSaveRetries?: number;
941
+ renderExpandButton?: (props: {
942
+ isExpanded: boolean;
943
+ onToggle: () => void;
944
+ }) => React.JSX.Element;
945
+ renderFilterInput?: (props: {
946
+ onChange: (value: string) => void;
947
+ }) => React.JSX.Element;
948
+ renderDialog?: (props: {
949
+ isOpen: boolean;
950
+ onSave: () => void;
951
+ onCancel: () => void;
952
+ children: React.ReactNode;
953
+ }) => React.JSX.Element;
954
+ isManualSave?: boolean;
955
+ renderSaveButton?: (props: {
956
+ onSave: () => void;
957
+ isDirty: boolean;
958
+ isValid: boolean;
959
+ isSubmitting: boolean;
960
+ }) => React.ReactNode;
961
+ formErrors?: string[];
962
+ renderLabel?: (props: {
963
+ id: string;
964
+ labelId: string;
965
+ label?: string;
966
+ required?: boolean;
967
+ }) => React.ReactNode;
968
+ renderError?: (props: {
969
+ id: string;
970
+ error?: react_hook_form.FieldError;
971
+ errorCount?: number;
972
+ }) => React.ReactNode;
973
+ renderStatus?: (props: {
974
+ id: string;
975
+ saving?: boolean;
976
+ savePending?: boolean;
977
+ errorCount?: number;
978
+ isManualSave?: boolean;
979
+ }) => React.ReactNode;
980
+ }
981
+ declare const FormEngine: React.FC<IFormEngineProps>;
982
+
983
+ /**
984
+ * Stable wrapper functions for analytics callbacks.
985
+ * Each function is a no-op when the corresponding callback is not provided.
986
+ */
987
+ interface IFormAnalytics {
988
+ trackFieldFocus: (fieldName: string) => void;
989
+ trackFieldBlur: (fieldName: string) => void;
990
+ trackFieldChange: (fieldName: string, oldValue: unknown, newValue: unknown) => void;
991
+ trackValidationError: (fieldName: string, errors: string[]) => void;
992
+ trackFormSubmit: (values: Record<string, unknown>) => void;
993
+ trackFormAbandonment: (filledFields: string[], emptyRequiredFields: string[]) => void;
994
+ trackWizardStepChange: (fromStep: number, toStep: number) => void;
995
+ trackRuleTriggered: (event: {
996
+ fieldName: string;
997
+ ruleIndex: number;
998
+ conditionMet: boolean;
999
+ }) => void;
1000
+ /** Timestamp (ms) when the hook was first created -- used for form duration. */
1001
+ formStartTime: number;
1002
+ }
1003
+ /**
1004
+ * Hook that wraps IAnalyticsCallbacks into safe, memoized wrapper functions.
1005
+ * Tracks form start time for duration calculations and per-field focus times.
1006
+ */
1007
+ declare function useFormAnalytics(callbacks?: IAnalyticsCallbacks): IFormAnalytics;
1008
+
1009
+ interface IFormFieldsProps {
1010
+ entityId?: string;
1011
+ entityType?: string;
1012
+ programName?: string;
1013
+ parentEntityId?: string;
1014
+ parentEntityType?: string;
1015
+ isExpanded?: boolean;
1016
+ expandEnabled?: boolean;
1017
+ fieldOrder?: string[];
1018
+ inPanel?: boolean;
1019
+ collapsedMaxHeight?: number;
1020
+ formState?: IRuntimeFormState;
1021
+ fields?: Record<string, IFieldConfig>;
1022
+ setFieldValue: (fieldName: string, fieldValue: unknown, skipSave?: boolean) => void;
1023
+ isManualSave?: boolean;
1024
+ isCreate?: boolean;
1025
+ filterText?: string;
1026
+ fieldRenderLimit?: number;
1027
+ renderLabel?: (props: {
1028
+ id: string;
1029
+ labelId: string;
1030
+ label?: string;
1031
+ required?: boolean;
1032
+ }) => React.ReactNode;
1033
+ renderError?: (props: {
1034
+ id: string;
1035
+ error?: react_hook_form.FieldError;
1036
+ errorCount?: number;
1037
+ }) => React.ReactNode;
1038
+ renderStatus?: (props: {
1039
+ id: string;
1040
+ saving?: boolean;
1041
+ savePending?: boolean;
1042
+ errorCount?: number;
1043
+ isManualSave?: boolean;
1044
+ }) => React.ReactNode;
1045
+ analytics?: IFormAnalytics;
1046
+ }
1047
+ declare const FormFields: (props: IFormFieldsProps) => react_jsx_runtime.JSX.Element;
1048
+
1049
+ interface IFieldWrapperProps {
1050
+ id?: string;
1051
+ readonly label?: string;
1052
+ readonly required?: boolean;
1053
+ readonly error?: FieldError;
1054
+ readonly errorCount?: number;
1055
+ readonly savePending?: boolean;
1056
+ readonly saving?: boolean;
1057
+ readonly labelClassName?: string;
1058
+ readonly fieldClassName?: string;
1059
+ readonly showControlonSide?: boolean;
1060
+ readonly ariaLabel?: string;
1061
+ readonly ariaDescription?: string;
1062
+ readonly containerClassName?: string;
1063
+ readonly additionalInfo?: string;
1064
+ readonly additionalInfoIcon?: string;
1065
+ readonly additionalInfoComponent?: React.ReactNode;
1066
+ isManualSave?: boolean;
1067
+ renderLabel?: (props: {
1068
+ id: string;
1069
+ labelId: string;
1070
+ label?: string;
1071
+ required?: boolean;
1072
+ }) => React.ReactNode;
1073
+ renderError?: (props: {
1074
+ id: string;
1075
+ error?: FieldError;
1076
+ errorCount?: number;
1077
+ }) => React.ReactNode;
1078
+ renderStatus?: (props: {
1079
+ id: string;
1080
+ saving?: boolean;
1081
+ savePending?: boolean;
1082
+ errorCount?: number;
1083
+ isManualSave?: boolean;
1084
+ }) => React.ReactNode;
1085
+ }
1086
+ declare const FieldWrapper: React.FunctionComponent<React.PropsWithChildren<IFieldWrapperProps>>;
1087
+
1088
+ interface IRenderFieldProps {
1089
+ fieldName: string;
1090
+ entityId?: string;
1091
+ entityType?: string;
1092
+ programName?: string;
1093
+ type: string;
1094
+ hidden?: boolean;
1095
+ required?: boolean;
1096
+ readOnly?: boolean;
1097
+ disabled?: boolean;
1098
+ options?: IOption[];
1099
+ validate?: IValidationRule[];
1100
+ parentEntityId?: string;
1101
+ parentEntityType?: string;
1102
+ isManualSave?: boolean;
1103
+ setFieldValue: (fieldName: string, fieldValue: unknown, skipSave?: boolean) => void;
1104
+ isCreate?: boolean;
1105
+ filterText?: string;
1106
+ softHidden?: boolean;
1107
+ label?: string;
1108
+ skipLayoutReadOnly?: boolean;
1109
+ hideOnCreate?: boolean;
1110
+ config?: Record<string, unknown>;
1111
+ description?: string;
1112
+ placeholder?: string;
1113
+ helpText?: string;
1114
+ renderLabel?: (props: {
1115
+ id: string;
1116
+ labelId: string;
1117
+ label?: string;
1118
+ required?: boolean;
1119
+ }) => React.ReactNode;
1120
+ renderError?: (props: {
1121
+ id: string;
1122
+ error?: react_hook_form.FieldError;
1123
+ errorCount?: number;
1124
+ }) => React.ReactNode;
1125
+ renderStatus?: (props: {
1126
+ id: string;
1127
+ saving?: boolean;
1128
+ savePending?: boolean;
1129
+ errorCount?: number;
1130
+ isManualSave?: boolean;
1131
+ }) => React.ReactNode;
1132
+ analytics?: IFormAnalytics;
1133
+ }
1134
+ declare const _default: React.MemoExoticComponent<(props: IRenderFieldProps) => react_jsx_runtime.JSX.Element>;
1135
+
1136
+ interface IConfirmInputsModalProps {
1137
+ isOpen?: boolean;
1138
+ configName: string;
1139
+ entityId?: string;
1140
+ entityType?: string;
1141
+ programName?: string;
1142
+ fields: Record<string, IFieldConfig>;
1143
+ confirmInputFields: string[];
1144
+ saveConfirmInputFields: () => void;
1145
+ cancelConfirmInputFields: () => void;
1146
+ renderDialog?: (props: {
1147
+ isOpen: boolean;
1148
+ onSave: () => void;
1149
+ onCancel: () => void;
1150
+ children: React.ReactNode;
1151
+ }) => React.JSX.Element;
1152
+ }
1153
+ declare const ConfirmInputsModal: (props: IConfirmInputsModalProps) => React.JSX.Element;
1154
+
1155
+ interface IFormErrorBoundaryProps {
1156
+ children: React.ReactNode;
1157
+ fallback?: (error: Error, resetError: () => void) => React.ReactNode;
1158
+ onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
1159
+ }
1160
+ interface IFormErrorBoundaryState {
1161
+ hasError: boolean;
1162
+ error: Error | null;
1163
+ }
1164
+ declare class FormErrorBoundary extends React.Component<IFormErrorBoundaryProps, IFormErrorBoundaryState> {
1165
+ constructor(props: IFormErrorBoundaryProps);
1166
+ static getDerivedStateFromError(error: Error): IFormErrorBoundaryState;
1167
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
1168
+ resetError: () => void;
1169
+ render(): React.ReactNode;
1170
+ }
1171
+
1172
+ interface IFormDevToolsProps {
1173
+ configName: string;
1174
+ formState?: IRuntimeFormState;
1175
+ formValues?: Record<string, unknown>;
1176
+ formErrors?: Record<string, unknown>;
1177
+ dirtyFields?: Record<string, boolean>;
1178
+ enabled?: boolean;
1179
+ }
1180
+ declare const FormDevTools: React.FC<IFormDevToolsProps>;
1181
+
1182
+ /**
1183
+ * JSON Schema node type (supports draft-04 through draft-2020-12 features used by RJSF).
1184
+ */
1185
+ interface IJsonSchemaNode {
1186
+ $ref?: string;
1187
+ definitions?: Record<string, IJsonSchemaNode>;
1188
+ $defs?: Record<string, IJsonSchemaNode>;
1189
+ type?: string | string[];
1190
+ const?: unknown;
1191
+ title?: string;
1192
+ description?: string;
1193
+ default?: unknown;
1194
+ minLength?: number;
1195
+ maxLength?: number;
1196
+ pattern?: string;
1197
+ format?: string;
1198
+ minimum?: number;
1199
+ maximum?: number;
1200
+ exclusiveMinimum?: number;
1201
+ exclusiveMaximum?: number;
1202
+ multipleOf?: number;
1203
+ enum?: unknown[];
1204
+ enumNames?: string[];
1205
+ properties?: Record<string, IJsonSchemaNode>;
1206
+ required?: string[];
1207
+ additionalProperties?: boolean | IJsonSchemaNode;
1208
+ items?: IJsonSchemaNode | IJsonSchemaNode[];
1209
+ minItems?: number;
1210
+ maxItems?: number;
1211
+ uniqueItems?: boolean;
1212
+ oneOf?: IJsonSchemaNode[];
1213
+ anyOf?: IJsonSchemaNode[];
1214
+ allOf?: IJsonSchemaNode[];
1215
+ if?: IJsonSchemaNode;
1216
+ then?: IJsonSchemaNode;
1217
+ else?: IJsonSchemaNode;
1218
+ dependencies?: Record<string, string[] | IJsonSchemaNode>;
1219
+ [key: string]: unknown;
1220
+ }
1221
+ /**
1222
+ * RJSF uiSchema type — controls rendering hints separate from the data schema.
1223
+ */
1224
+ interface IRjsfUiSchema {
1225
+ "ui:widget"?: string;
1226
+ "ui:field"?: string;
1227
+ "ui:options"?: Record<string, unknown>;
1228
+ "ui:order"?: string[];
1229
+ "ui:hidden"?: boolean;
1230
+ "ui:readonly"?: boolean;
1231
+ "ui:disabled"?: boolean;
1232
+ "ui:placeholder"?: string;
1233
+ "ui:title"?: string;
1234
+ "ui:description"?: string;
1235
+ "ui:help"?: string;
1236
+ "ui:autofocus"?: boolean;
1237
+ "ui:enumDisabled"?: unknown[];
1238
+ "ui:enumNames"?: string[];
1239
+ "ui:label"?: boolean;
1240
+ "ui:classNames"?: string;
1241
+ "ui:submitButtonOptions"?: Record<string, unknown>;
1242
+ [fieldName: string]: unknown;
1243
+ }
1244
+ /**
1245
+ * Options for controlling the RJSF-to-IFormConfig conversion.
1246
+ */
1247
+ interface IRjsfConvertOptions {
1248
+ /** "flatten" = dot-notation keys (default), "fieldArray" = FieldArray items */
1249
+ nestedObjectStrategy?: "flatten" | "fieldArray";
1250
+ /** Prefix for generated rule IDs (default: "rjsf") */
1251
+ ruleIdPrefix?: string;
1252
+ }
1253
+
1254
+ /**
1255
+ * Convert an RJSF schema + uiSchema + formData into an IFormConfig (v2).
1256
+ *
1257
+ * This is the main entry point for RJSF migration. It:
1258
+ * 1. Resolves all $ref pointers
1259
+ * 2. Merges allOf if present
1260
+ * 3. Maps properties to IFieldConfig
1261
+ * 4. Applies uiSchema rendering hints
1262
+ * 5. Merges formData as defaultValues
1263
+ * 6. Converts dependencies → IRule[]
1264
+ * 7. Converts if/then/else → IRule[]
1265
+ * 8. Converts oneOf/anyOf → IRule[]
1266
+ * 9. Determines fieldOrder from uiSchema or property order
1267
+ */
1268
+ declare function fromRjsfSchema(schema: IJsonSchemaNode, uiSchema?: IRjsfUiSchema, formData?: Record<string, unknown>, options?: IRjsfConvertOptions): IFormConfig;
1269
+
1270
+ /**
1271
+ * Reverse-convert an IFormConfig to JSON Schema + uiSchema.
1272
+ *
1273
+ * Best-effort: structural fidelity only. Rules, computed values,
1274
+ * and other dynamic features do NOT map back to JSON Schema.
1275
+ */
1276
+ declare function toRjsfSchema(config: IFormConfig): {
1277
+ schema: IJsonSchemaNode;
1278
+ uiSchema: IRjsfUiSchema;
1279
+ };
1280
+
1281
+ /**
1282
+ * Converts a Zod object schema to Record<string, IFieldConfig>.
1283
+ * Does NOT require zod as a dependency — inspects the schema shape at runtime.
1284
+ */
1285
+ declare function zodSchemaToFieldConfig(zodSchema: unknown): Record<string, IFieldConfig>;
1286
+
1287
+ type LazyFieldImport = () => Promise<{
1288
+ default: React.ComponentType<any>;
1289
+ }>;
1290
+ /**
1291
+ * Creates a field registry where components are loaded on-demand via React.lazy().
1292
+ * Fields are only loaded when first rendered, reducing initial bundle size.
1293
+ *
1294
+ * @example
1295
+ * const registry = createLazyFieldRegistry({
1296
+ * Textbox: () => import("./fields/Textbox"),
1297
+ * Dropdown: () => import("./fields/Dropdown"),
1298
+ * });
1299
+ */
1300
+ declare function createLazyFieldRegistry(imports: Record<string, LazyFieldImport>): Dictionary<React.JSX.Element>;
1301
+
1302
+ interface IDraftPersistenceOptions {
1303
+ /** Unique form identifier for storage key */
1304
+ formId: string;
1305
+ /** Current form data to persist */
1306
+ data: IEntityData;
1307
+ /** Auto-save interval in ms (default 30000) */
1308
+ saveIntervalMs?: number;
1309
+ /** Whether persistence is enabled (default true) */
1310
+ enabled?: boolean;
1311
+ /** Custom storage key prefix (default "draft_") */
1312
+ storageKeyPrefix?: string;
1313
+ }
1314
+ interface IDraftState {
1315
+ data: IEntityData;
1316
+ timestamp: number;
1317
+ }
1318
+ interface IUseDraftPersistenceResult {
1319
+ /** Recover a saved draft if one exists */
1320
+ recoverDraft: () => IDraftState | null;
1321
+ /** Clear the saved draft */
1322
+ clearDraft: () => void;
1323
+ /** Whether a draft exists */
1324
+ hasDraft: boolean;
1325
+ /** Manually save current state as draft */
1326
+ saveDraft: () => void;
1327
+ }
1328
+ /**
1329
+ * Hook that persists form draft state to localStorage on a configurable interval.
1330
+ *
1331
+ * Handles localStorage errors gracefully (e.g. private browsing, quota exceeded).
1332
+ */
1333
+ declare function useDraftPersistence(options: IDraftPersistenceOptions): IUseDraftPersistenceResult;
1334
+
1335
+ /**
1336
+ * Hook that warns the user before navigating away when there are unsaved changes.
1337
+ *
1338
+ * @param shouldWarn - Whether the beforeunload warning should be active
1339
+ * @param message - Custom message (modern browsers ignore custom text but still show a prompt)
1340
+ * @param onAbandonment - Optional analytics callback fired when the user leaves with unsaved changes
1341
+ */
1342
+ declare function useBeforeUnload(shouldWarn: boolean, message?: string, onAbandonment?: () => void): void;
1343
+
1344
+ /**
1345
+ * Serialize form state to a JSON string, preserving Date objects
1346
+ * with a special `__type` marker so they can be round-tripped.
1347
+ */
1348
+ declare function serializeFormState(data: IEntityData): string;
1349
+ /**
1350
+ * Deserialize a JSON string back to form state, restoring Date objects
1351
+ * that were serialized with `serializeFormState`.
1352
+ */
1353
+ declare function deserializeFormState(json: string): IEntityData;
1354
+
1355
+ /**
1356
+ * Evaluates an expression string against form values.
1357
+ *
1358
+ * Supports:
1359
+ * - $values.fieldName for field references (including nested paths)
1360
+ * - $fn.name() for value function calls
1361
+ * - $parent.fieldName for parent entity references
1362
+ * - $root.fieldName alias for $values.fieldName
1363
+ * - Math functions: Math.round, Math.floor, Math.ceil, Math.abs, Math.min, Math.max
1364
+ * - Arithmetic: +, -, *, /
1365
+ * - Comparison: >, <, >=, <=, ===, !==
1366
+ * - Logical: &&, ||
1367
+ * - String concatenation via +
1368
+ *
1369
+ * @example
1370
+ * "$values.quantity * $values.unitPrice"
1371
+ * "$fn.setDate()"
1372
+ * "$parent.category"
1373
+ * "Math.round($values.total * 100) / 100"
1374
+ */
1375
+ declare function evaluateExpression(expression: string, values: IEntityData, fieldName?: string, parentEntity?: IEntityData, currentUserId?: string): unknown;
1376
+ /**
1377
+ * Extracts field names referenced in an expression via $values.fieldName or $root.fieldName.
1378
+ */
1379
+ declare function extractExpressionDependencies(expression: string): string[];
1380
+ /**
1381
+ * Extracts value function names referenced via $fn.name() syntax.
1382
+ */
1383
+ declare function extractFunctionDependencies(expression: string): string[];
1384
+
1385
+ interface IRuleTraceEvent {
1386
+ timestamp: number;
1387
+ type: "evaluate" | "apply" | "revert" | "init";
1388
+ triggerField: string;
1389
+ triggerValue: unknown;
1390
+ affectedField: string;
1391
+ ruleId?: string;
1392
+ previousState?: Partial<IRuntimeFieldState>;
1393
+ newState?: Partial<IRuntimeFieldState>;
1394
+ }
1395
+ declare function enableRuleTracing(callback?: (event: IRuleTraceEvent) => void): void;
1396
+ declare function disableRuleTracing(): void;
1397
+ declare function traceRuleEvent(event: Omit<IRuleTraceEvent, "timestamp">): void;
1398
+ declare function getRuleTraceLog(): IRuleTraceEvent[];
1399
+ declare function clearRuleTraceLog(): void;
1400
+ declare function isRuleTracingEnabled(): boolean;
1401
+
1402
+ /**
1403
+ * RenderTracker — Module-level render count tracking for FormDevTools.
1404
+ *
1405
+ * Tracks per-field render counts and which fields re-rendered on the last change.
1406
+ */
1407
+ /**
1408
+ * Record a render for the given field. Call this from RenderField.
1409
+ */
1410
+ declare function trackRender(fieldName: string): void;
1411
+ /**
1412
+ * Call once per form render cycle to snapshot which fields rendered.
1413
+ */
1414
+ declare function flushRenderCycle(): void;
1415
+ /**
1416
+ * Returns the current render counts for all tracked fields.
1417
+ */
1418
+ declare function getRenderCounts(): Map<string, number>;
1419
+ /**
1420
+ * Returns the set of field names that rendered in the last cycle.
1421
+ */
1422
+ declare function getLastRenderedFields(): Set<string>;
1423
+ /**
1424
+ * Returns total form render count.
1425
+ */
1426
+ declare function getTotalFormRenders(): number;
1427
+ /**
1428
+ * Reset all tracking data.
1429
+ */
1430
+ declare function resetRenderTracker(): void;
1431
+
1432
+ /**
1433
+ * EventTimeline — Module-level chronological event log for FormDevTools.
1434
+ *
1435
+ * Logs timestamped events from the rules engine, field changes, and validations.
1436
+ */
1437
+ type TimelineEventType = "field_change" | "rule_evaluated" | "validation_run" | "form_submit";
1438
+ interface ITimelineEvent {
1439
+ timestamp: number;
1440
+ type: TimelineEventType;
1441
+ fieldName: string;
1442
+ details: string;
1443
+ }
1444
+ /**
1445
+ * Log a new event to the timeline.
1446
+ */
1447
+ declare function logEvent(type: TimelineEventType, fieldName: string, details: string): void;
1448
+ /**
1449
+ * Returns a copy of the full timeline.
1450
+ */
1451
+ declare function getTimeline(): ITimelineEvent[];
1452
+ /**
1453
+ * Clear all timeline events.
1454
+ */
1455
+ declare function clearTimeline(): void;
1456
+
1457
+ export { CheckAsyncFieldValidationRules, CheckDefaultValues, CheckFieldValidationRules, CheckValidDropdownOptions, ComponentTypes, ConfirmInputsModal, type Dictionary, ExecuteComputedValue, FIELD_PARENT_PREFIX, FieldArray, FieldWrapper, FormConstants, FormDevTools, FormEngine, FormErrorBoundary, FormFields, FormStrings, GetChildEntity, GetComputedValuesOnCreate, GetComputedValuesOnDirtyFields, GetConfirmInputModalProps, GetFieldsToRender, type IAnalyticsCallbacks, type IClearRulesAction, type ICondition, type IConfigValidationError, type IConfirmInputModalProps, type ICoreLocaleStrings, type ICycleError, type IDraftPersistenceOptions, type IDraftState, type IEntityData, type IFieldArrayProps, type IFieldCondition, type IFieldConfig, type IFieldEffect, type IFieldProps, type IFieldToRender, type IFormAnalytics, type IFormConfig, type IFormDevToolsProps, type IFormEngineSharedProps, type IFormSettings, type IInjectedFieldProvider, type IJsonSchemaNode, type ILogicalCondition, type IOption, type IRjsfConvertOptions, type IRjsfUiSchema, type IRule, type IRuleTraceEvent, type IRulesEngineProvider, type IRulesEngineState, type IRuntimeFieldState, type IRuntimeFormState, type ISetRulesAction, type ITimelineEvent, type IUpdateRulesAction, type IUseDraftPersistenceResult, type IValidationContext, type IValidationRule, type IValueFunctionContext, type IWizardConfig, type IWizardFormProps, type IWizardNavigationProps, type IWizardStep, type IWizardStepHeaderProps, InitOnCreateFormState, InitOnEditFormState, InjectedFieldProvider, IsExpandVisible, _default as RenderField, type RulesEngineAction, RulesEngineActionType, RulesEngineProvider, ShowField, SortOptions as SortDropdownOptions, SortOptions$1 as SortOptions, type SubEntityType, type TimelineEventType, type TypedFieldConfig, UseInjectedFieldContext, UseRulesEngineContext, type ValidatorFn, type ValueFunction, WizardForm, buildDefaultFieldStates, buildDependencyGraph, clearRuleTraceLog, clearTimeline, convertBooleanToYesOrNoText, createLazyFieldRegistry, createMaxLengthRule, createMinLengthRule, createNumericRangeRule, createOption, createPatternRule, createRequiredIfRule, deepCopy, defineFormConfig, deserializeFormState, detectDependencyCycles, detectSelfDependencies, disableRuleTracing, enableRuleTracing, evaluateAffectedFields, evaluateAllRules, evaluateCondition, evaluateExpression, executeValueFunction, extractConditionDependencies, extractExpressionDependencies, extractFunctionDependencies, flushRenderCycle, fromRjsfSchema, getCurrentLocale, getLastRenderedFields, getLocaleString, getRenderCounts, getRuleTraceLog, getStepFieldOrder, getStepFields, getStepIndex, getTimeline, getTotalFormRenders, getValidator, getValidatorRegistry, getValueFunction, getVisibleSteps, isEmpty, isFieldCondition, isLogicalCondition, isNull, isRuleTracingEnabled, isStepValid, isStringEmpty, logEvent, registerLocale, registerValidators, registerValueFunctions, resetLocale, resetRenderTracker, resetValidatorRegistry, resetValueFunctionRegistry, runSyncValidations, runValidations, serializeFormState, sortDropdownOptions, toRjsfSchema, topologicalSort, traceRuleEvent, trackRender, useBeforeUnload, useDraftPersistence, useFormAnalytics, validateDependencyGraph, validateFieldConfigs, validateStepFields, zodSchemaToFieldConfig };