New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@rilaykit/forms

Package Overview
Dependencies
Maintainers
1
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rilaykit/forms - npm Package Compare versions

Comparing version
0.1.1
to
0.1.2
+239
README.md
# @rilaykit/forms
The form builder and React rendering layer for [RilayKit](https://rilay.dev) — build type-safe, headless forms from declarative schemas.
`@rilaykit/forms` provides a fluent builder API to define form configurations and headless React components to render them. State management is powered by Zustand with granular selectors for optimal re-render performance.
## Installation
```bash
# pnpm (recommended)
pnpm add @rilaykit/core @rilaykit/forms
# npm
npm install @rilaykit/core @rilaykit/forms
# yarn
yarn add @rilaykit/core @rilaykit/forms
# bun
bun add @rilaykit/core @rilaykit/forms
```
> `@rilaykit/core` is a required peer dependency.
### Requirements
- React >= 18
- React DOM >= 18
## Quick Start
### 1. Create Your Registry
```tsx
import { ril } from '@rilaykit/core';
import { Input } from './components/Input';
const rilay = ril.create()
.addComponent('input', { renderer: Input });
```
### 2. Build a Form
```tsx
import { required, email } from '@rilaykit/core';
const loginForm = rilay
.form('login')
.add({
id: 'email',
type: 'input',
props: { label: 'Email', type: 'email' },
validation: { validate: [required(), email()] },
})
.add({
id: 'password',
type: 'input',
props: { label: 'Password', type: 'password' },
validation: { validate: [required()] },
});
```
### 3. Render It
```tsx
import { Form, FormField } from '@rilaykit/forms';
function LoginForm() {
const handleSubmit = (data: { email: string; password: string }) => {
console.log('Login:', data);
};
return (
<Form formConfig={loginForm} onSubmit={handleSubmit}>
<FormField fieldId="email" />
<FormField fieldId="password" />
<button type="submit">Sign In</button>
</Form>
);
}
```
## Features
### Fluent Form Builder
Construct forms with a chainable, type-safe API. Each field type and its props are validated at compile time.
```tsx
const contactForm = rilay
.form('contact')
.add(
{ id: 'firstName', type: 'input', props: { label: 'First Name' } },
{ id: 'lastName', type: 'input', props: { label: 'Last Name' } },
)
.add({
id: 'message',
type: 'textarea',
props: { label: 'Message', rows: 5 },
validation: { validate: [required()] },
});
// Serialize, clone, inspect
const json = contactForm.toJSON();
const variant = contactForm.clone('contact-v2');
const stats = contactForm.getStats();
```
### Headless React Components
Zero HTML, zero CSS. You provide the renderers, RilayKit handles state, validation, and orchestration.
| Component | Description |
|-----------|-------------|
| `<Form>` | Main wrapper — manages context, state, and submission |
| `<FormProvider>` | Context provider (used separately from Form when needed) |
| `<FormBody>` | Renders the full form body from configuration |
| `<FormField>` | Renders a single field by ID |
| `<FormRow>` | Renders a row of fields |
| `<FormSubmitButton>` | Submit button with loading/disabled state |
### Zustand-Powered Store
Each form instance gets its own Zustand store with granular selectors — only the fields that change trigger re-renders.
```tsx
import {
useFieldValue,
useFieldErrors,
useFieldTouched,
useFieldState,
useFormValues,
useFormValid,
useFormDirty,
useFormSubmitting,
useFieldActions,
useFormActions,
} from '@rilaykit/forms';
function CustomField({ fieldId }: { fieldId: string }) {
const value = useFieldValue(fieldId);
const errors = useFieldErrors(fieldId);
const { setValue, setTouched } = useFieldActions(fieldId);
// ...
}
```
### Conditional Fields
Combined with `@rilaykit/core`'s condition system, fields show/hide reactively based on other field values.
```tsx
import { when } from '@rilaykit/core';
rilay.form('account')
.add({
id: 'accountType',
type: 'select',
props: { options: [{ value: 'business', label: 'Business' }] },
})
.add({
id: 'companyName',
type: 'input',
props: { label: 'Company Name' },
conditions: { visible: when('accountType').equals('business') },
});
```
### Validation
Supports built-in validators, Standard Schema libraries (Zod, Valibot, Yup...), and custom validators — all in the same field.
```tsx
import { z } from 'zod';
import { required } from '@rilaykit/core';
validation: {
validate: [required(), z.string().email()],
validateOnBlur: true,
}
```
## API Overview
### Builder
| Method | Description |
|--------|-------------|
| `form.create(ril, id?)` | Create a new form builder |
| `.add(...fields)` | Add fields (1-3 per row) |
| `.addSeparateRows(fields)` | Each field on its own row |
| `.updateField(id, updates)` | Update a field definition |
| `.removeField(id)` | Remove a field |
| `.setValidation(config)` | Set form-level validation |
| `.addFieldConditions(id, conditions)` | Add conditional logic |
| `.build()` | Produce the final `FormConfiguration` |
| `.toJSON()` / `.fromJSON(json)` | Serialize / deserialize |
| `.clone(newId?)` | Clone the form configuration |
### Hooks
| Hook | Description |
|------|-------------|
| `useFieldValue(id)` | Current field value |
| `useFieldErrors(id)` | Field validation errors |
| `useFieldTouched(id)` | Whether field has been touched |
| `useFieldState(id)` | Combined field state |
| `useFieldActions(id)` | `setValue`, `setTouched`, etc. |
| `useFieldConditions(id)` | Evaluated condition results |
| `useFormValues()` | All form values |
| `useFormValid()` | Whether form is valid |
| `useFormDirty()` | Whether form has unsaved changes |
| `useFormSubmitting()` | Whether form is submitting |
| `useFormActions()` | `submit`, `reset`, `validate`, etc. |
## Architecture
```
@rilaykit/core (registry, types, validation, conditions)
@rilaykit/forms ← you are here
@rilaykit/workflow (multi-step workflows)
```
## Documentation
Full documentation at [rilay.dev](https://rilay.dev):
- [Building Forms](https://rilay.dev/forms/building-forms)
- [Rendering Forms](https://rilay.dev/forms/rendering-forms)
- [Form Validation](https://rilay.dev/forms/validation)
- [Advanced Forms](https://rilay.dev/forms/advanced-forms)
- [Form Hooks](https://rilay.dev/forms/hooks)
- [API Reference](https://rilay.dev/api)
## License
MIT — see [LICENSE](./LICENSE) for details.
+196
-7
import * as react_jsx_runtime from 'react/jsx-runtime';
import { ril, FieldValidationConfig, ConditionalBehavior, FormFieldConfig, FormFieldRow, FormValidationConfig, FormConfiguration, ComponentRendererBaseProps, FormBodyRendererProps, FieldConditions, FormState, ValidationError, ValidationState, FieldState, ValidationResult, MonitoringConfig, FormPerformanceMetrics, FormRowRendererProps, FormSubmitButtonRendererProps } from '@rilaykit/core';
import { ril, FieldValidationConfig, RepeatableFieldConfig, ConditionalBehavior, FormFieldConfig, FormRowEntry, FormValidationConfig, FormConfiguration, ComponentRendererBaseProps, FormBodyRendererProps, FieldConditions, FormState, ValidationError, ValidationState, FieldState, ValidationResult, RepeatableFieldItem, MonitoringConfig, FormPerformanceMetrics, FormRowRendererProps, FormFieldRow, FormSubmitButtonRendererProps } from '@rilaykit/core';
import * as React$1 from 'react';

@@ -8,2 +8,59 @@ import React__default from 'react';

/**
* Fluent builder for configuring repeatable field groups
*
* Used via callback in `form.addRepeatable()`:
* ```typescript
* form.create(ril, "order")
* .addRepeatable("items", r => r
* .add(
* { id: "name", type: "text", props: { label: "Item" } },
* { id: "qty", type: "number", props: { label: "Qty" } }
* )
* .min(1)
* .max(10)
* .defaultValue({ name: "", qty: 1 })
* )
* .build()
* ```
*/
declare class RepeatableBuilder<C extends Record<string, any>> {
private innerForm;
private _min?;
private _max?;
private _defaultValue?;
private _validation?;
constructor(config: ril<C>);
/**
* Add fields to the repeatable template
* Same API as form.add() — variadic ≤3 puts them on the same row
*/
add<T extends keyof C & string>(...fields: FieldConfig<C, T>[]): this;
add<T extends keyof C & string>(fields: FieldConfig<C, T>[]): this;
/**
* Add fields each on their own row
*/
addSeparateRows<T extends keyof C & string>(fields: FieldConfig<C, T>[]): this;
/**
* Set minimum number of items (defaults to 0)
*/
min(value: number): this;
/**
* Set maximum number of items (unlimited if not set)
*/
max(value: number): this;
/**
* Set default values for new items
*/
defaultValue(value: Record<string, unknown>): this;
/**
* Set group-level validation (applied to the entire array)
*/
validation(config: FieldValidationConfig): this;
/** @internal — called by form.addRepeatable */
_build(id: string): RepeatableFieldConfig;
/** @internal — check if the inner builder has repeatables (nesting forbidden) */
_hasRepeatables(): boolean;
}
/**
* Configuration for a form field with type safety

@@ -211,2 +268,26 @@ *

/**
* Adds a repeatable field group to the form
*
* Repeatable fields allow users to add/remove instances of a group of fields
* at runtime (e.g., "Add another item", "Add another contact").
*
* @param id - Unique identifier for the repeatable group (cannot contain [ or ])
* @param configure - Callback receiving a RepeatableBuilder for fluent configuration
* @returns The form builder instance for method chaining
*
* @example
* ```typescript
* builder.addRepeatable("items", r => r
* .add(
* { id: "name", type: "text", props: { label: "Item" } },
* { id: "qty", type: "number", props: { label: "Qty" } }
* )
* .min(1)
* .max(10)
* .defaultValue({ name: "", qty: 1 })
* );
* ```
*/
addRepeatable(id: string, configure: (builder: RepeatableBuilder<C>) => RepeatableBuilder<C>): this;
/**
* Sets the form identifier

@@ -313,3 +394,3 @@ *

*/
getRows(): FormFieldRow[];
getRows(): FormRowEntry[];
/**

@@ -522,7 +603,7 @@ * Clears all fields and rows from the form

getStats(): {
/** Total number of fields across all rows */
/** Total number of static fields across all rows */
totalFields: number;
/** Total number of rows in the form */
totalRows: number;
/** Average number of fields per row */
/** Average number of fields per row (field rows only) */
averageFieldsPerRow: number;

@@ -533,2 +614,6 @@ /** Maximum number of fields in any single row */

minFieldsInRow: number;
/** Total number of repeatable groups */
totalRepeatables: number;
/** Total number of fields across all repeatable templates */
totalRepeatableFields: number;
};

@@ -545,3 +630,3 @@ }

}
declare function Form({ formConfig, defaultValues, onSubmit, onFieldChange, children }: FormProps): react_jsx_runtime.JSX.Element;
declare function Form({ formConfig, defaultValues, onSubmit, onFieldChange, className, children, }: FormProps): react_jsx_runtime.JSX.Element;

@@ -552,2 +637,4 @@ declare const FormBody: React__default.NamedExoticComponent<ComponentRendererBaseProps<FormBodyRendererProps>>;

fieldId: string;
/** Pre-resolved field config (used by RepeatableItem to skip allFields lookup) */
fieldConfig?: FormFieldConfig;
disabled?: boolean;

@@ -636,2 +723,4 @@ customProps?: Record<string, unknown>;

formValues: Record<string, any>;
/** Active repeatable item keys, keyed by repeatable ID */
repeatableOrder?: Record<string, string[]>;
}

@@ -673,3 +762,3 @@ interface UseFormConditionsReturn {

*/
declare function useFormConditions({ formConfig, formValues, }: UseFormConditionsProps): UseFormConditionsReturn;
declare function useFormConditions({ formConfig, formValues, repeatableOrder, }: UseFormConditionsProps): UseFormConditionsReturn;

@@ -679,2 +768,5 @@ interface FormStoreState extends FormState {

_fieldConditions: Record<string, FieldConditions>;
_repeatableConfigs: Record<string, RepeatableFieldConfig>;
_repeatableOrder: Record<string, string[]>;
_repeatableNextKey: Record<string, number>;
_setValue: (fieldId: string, value: unknown) => void;

@@ -689,2 +781,7 @@ _setTouched: (fieldId: string) => void;

_updateIsValid: () => void;
_setRepeatableConfig: (id: string, config: RepeatableFieldConfig) => void;
_appendRepeatableItem: (repeatableId: string, defaultValue?: Record<string, unknown>) => string | null;
_removeRepeatableItem: (repeatableId: string, key: string) => boolean;
_moveRepeatableItem: (repeatableId: string, fromIndex: number, toIndex: number) => void;
_insertRepeatableItem: (repeatableId: string, index: number, defaultValue?: Record<string, unknown>) => string | null;
}

@@ -763,2 +860,6 @@ type FormStore = ReturnType<typeof createFormStore>;

};
/**
* Select ordered keys for a repeatable field — re-renders when the order changes
*/
declare function useRepeatableKeys(repeatableId: string): string[];
interface UseFieldActionsResult {

@@ -813,2 +914,41 @@ setValue: (value: unknown) => void;

interface UseRepeatableFieldReturn {
items: RepeatableFieldItem[];
append: (defaultValue?: Record<string, unknown>) => void;
remove: (key: string) => void;
move: (fromIndex: number, toIndex: number) => void;
canAdd: boolean;
canRemove: boolean;
count: number;
}
/**
* Hook to manage a repeatable field group
*
* Provides the list of items and actions to add, remove, and reorder them.
* Each item contains scoped field configs ready for rendering.
*
* @param repeatableId - The ID of the repeatable group (as defined in addRepeatable)
* @returns Items, actions, and constraints
*
* @example
* ```tsx
* const { items, append, remove, canAdd, canRemove } = useRepeatableField("items");
*
* return (
* <div>
* {items.map(item => (
* <div key={item.key}>
* {item.allFields.map(field => (
* <FormField key={field.id} fieldId={field.id} fieldConfig={field} />
* ))}
* {canRemove && <button onClick={() => remove(item.key)}>Remove</button>}
* </div>
* ))}
* {canAdd && <button onClick={append}>Add</button>}
* </div>
* );
* ```
*/
declare function useRepeatableField(repeatableId: string): UseRepeatableFieldReturn;
interface UseFormMonitoringProps {

@@ -864,2 +1004,51 @@ formConfig: FormConfiguration;

export { type ConditionEvaluationResult, type FieldConfig, Form, FormBody, form as FormBuilder, type FormConfigContextValue, FormField, FormProvider, type FormProviderProps, FormRow, type FormStore, FormStoreContext, type FormStoreState, FormSubmitButton, type UseFieldActionsResult, type UseFieldConditionsLazyOptions, type UseFormActionsResult, type UseFormConditionsProps, type UseFormConditionsReturn, type UseFormMonitoringProps, type UseFormMonitoringReturn, type UseFormSubmissionWithStoreProps, type UseFormValidationWithStoreProps, createFormStore, form, useConditionEvaluation, useConditionEvaluator, useFieldActions, useFieldConditions, useFieldConditionsLazy, useFieldConditionsWithRefresh, useFieldErrors, useFieldState, useFieldTouched, useFieldValidationState, useFieldValue, useFormActions, useFormConditions, useFormConfigContext, useFormDirty, useFormMonitoring, useFormStore, useFormStoreApi, useFormSubmissionWithStore, useFormSubmitState, useFormSubmitting, useFormValid, useFormValidationWithStore, useFormValues, useMultipleConditionEvaluation };
interface RepeatableFieldProps {
repeatableId: string;
repeatableConfig: RepeatableFieldConfig;
className?: string;
}
declare const RepeatableField: React__default.NamedExoticComponent<RepeatableFieldProps>;
interface RepeatableItemProps {
item: RepeatableFieldItem;
index: number;
total: number;
canRemove: boolean;
canMoveUp: boolean;
canMoveDown: boolean;
onRemove: () => void;
onMoveUp: () => void;
onMoveDown: () => void;
}
declare const RepeatableItem: React__default.NamedExoticComponent<RepeatableItemProps>;
/**
* Converts flat store values with composite keys into structured nested data.
*
* Input (store values):
* { customerName: "John", "items[k0].name": "Widget", "items[k0].qty": 2, "items[k1].name": "Gadget", "items[k1].qty": 1 }
*
* Output (structured):
* { customerName: "John", items: [{ name: "Widget", qty: 2 }, { name: "Gadget", qty: 1 }] }
*/
declare function structureFormValues(values: Record<string, unknown>, repeatableConfigs: Record<string, RepeatableFieldConfig>, repeatableOrder: Record<string, string[]>): Record<string, unknown>;
/**
* Converts structured nested data into flat store values with composite keys.
*
* Input (structured):
* { customerName: "John", items: [{ name: "Widget", qty: 2 }, { name: "Gadget", qty: 1 }] }
*
* Output:
* {
* values: { customerName: "John", "items[k0].name": "Widget", "items[k0].qty": 2, "items[k1].name": "Gadget", "items[k1].qty": 1 },
* order: { items: ["k0", "k1"] },
* nextKeys: { items: 2 }
* }
*/
declare function flattenRepeatableValues(data: Record<string, unknown>, repeatableConfigs: Record<string, RepeatableFieldConfig>): {
values: Record<string, unknown>;
order: Record<string, string[]>;
nextKeys: Record<string, number>;
};
export { type ConditionEvaluationResult, type FieldConfig, Form, FormBody, form as FormBuilder, type FormConfigContextValue, FormField, FormProvider, type FormProviderProps, FormRow, type FormStore, FormStoreContext, type FormStoreState, FormSubmitButton, RepeatableBuilder, RepeatableField, RepeatableItem, type UseFieldActionsResult, type UseFieldConditionsLazyOptions, type UseFormActionsResult, type UseFormConditionsProps, type UseFormConditionsReturn, type UseFormMonitoringProps, type UseFormMonitoringReturn, type UseFormSubmissionWithStoreProps, type UseFormValidationWithStoreProps, type UseRepeatableFieldReturn, createFormStore, flattenRepeatableValues, form, structureFormValues, useConditionEvaluation, useConditionEvaluator, useFieldActions, useFieldConditions, useFieldConditionsLazy, useFieldConditionsWithRefresh, useFieldErrors, useFieldState, useFieldTouched, useFieldValidationState, useFieldValue, useFormActions, useFormConditions, useFormConfigContext, useFormDirty, useFormMonitoring, useFormStore, useFormStoreApi, useFormSubmissionWithStore, useFormSubmitState, useFormSubmitting, useFormValid, useFormValidationWithStore, useFormValues, useMultipleConditionEvaluation, useRepeatableField, useRepeatableKeys };
import * as react_jsx_runtime from 'react/jsx-runtime';
import { ril, FieldValidationConfig, ConditionalBehavior, FormFieldConfig, FormFieldRow, FormValidationConfig, FormConfiguration, ComponentRendererBaseProps, FormBodyRendererProps, FieldConditions, FormState, ValidationError, ValidationState, FieldState, ValidationResult, MonitoringConfig, FormPerformanceMetrics, FormRowRendererProps, FormSubmitButtonRendererProps } from '@rilaykit/core';
import { ril, FieldValidationConfig, RepeatableFieldConfig, ConditionalBehavior, FormFieldConfig, FormRowEntry, FormValidationConfig, FormConfiguration, ComponentRendererBaseProps, FormBodyRendererProps, FieldConditions, FormState, ValidationError, ValidationState, FieldState, ValidationResult, RepeatableFieldItem, MonitoringConfig, FormPerformanceMetrics, FormRowRendererProps, FormFieldRow, FormSubmitButtonRendererProps } from '@rilaykit/core';
import * as React$1 from 'react';

@@ -8,2 +8,59 @@ import React__default from 'react';

/**
* Fluent builder for configuring repeatable field groups
*
* Used via callback in `form.addRepeatable()`:
* ```typescript
* form.create(ril, "order")
* .addRepeatable("items", r => r
* .add(
* { id: "name", type: "text", props: { label: "Item" } },
* { id: "qty", type: "number", props: { label: "Qty" } }
* )
* .min(1)
* .max(10)
* .defaultValue({ name: "", qty: 1 })
* )
* .build()
* ```
*/
declare class RepeatableBuilder<C extends Record<string, any>> {
private innerForm;
private _min?;
private _max?;
private _defaultValue?;
private _validation?;
constructor(config: ril<C>);
/**
* Add fields to the repeatable template
* Same API as form.add() — variadic ≤3 puts them on the same row
*/
add<T extends keyof C & string>(...fields: FieldConfig<C, T>[]): this;
add<T extends keyof C & string>(fields: FieldConfig<C, T>[]): this;
/**
* Add fields each on their own row
*/
addSeparateRows<T extends keyof C & string>(fields: FieldConfig<C, T>[]): this;
/**
* Set minimum number of items (defaults to 0)
*/
min(value: number): this;
/**
* Set maximum number of items (unlimited if not set)
*/
max(value: number): this;
/**
* Set default values for new items
*/
defaultValue(value: Record<string, unknown>): this;
/**
* Set group-level validation (applied to the entire array)
*/
validation(config: FieldValidationConfig): this;
/** @internal — called by form.addRepeatable */
_build(id: string): RepeatableFieldConfig;
/** @internal — check if the inner builder has repeatables (nesting forbidden) */
_hasRepeatables(): boolean;
}
/**
* Configuration for a form field with type safety

@@ -211,2 +268,26 @@ *

/**
* Adds a repeatable field group to the form
*
* Repeatable fields allow users to add/remove instances of a group of fields
* at runtime (e.g., "Add another item", "Add another contact").
*
* @param id - Unique identifier for the repeatable group (cannot contain [ or ])
* @param configure - Callback receiving a RepeatableBuilder for fluent configuration
* @returns The form builder instance for method chaining
*
* @example
* ```typescript
* builder.addRepeatable("items", r => r
* .add(
* { id: "name", type: "text", props: { label: "Item" } },
* { id: "qty", type: "number", props: { label: "Qty" } }
* )
* .min(1)
* .max(10)
* .defaultValue({ name: "", qty: 1 })
* );
* ```
*/
addRepeatable(id: string, configure: (builder: RepeatableBuilder<C>) => RepeatableBuilder<C>): this;
/**
* Sets the form identifier

@@ -313,3 +394,3 @@ *

*/
getRows(): FormFieldRow[];
getRows(): FormRowEntry[];
/**

@@ -522,7 +603,7 @@ * Clears all fields and rows from the form

getStats(): {
/** Total number of fields across all rows */
/** Total number of static fields across all rows */
totalFields: number;
/** Total number of rows in the form */
totalRows: number;
/** Average number of fields per row */
/** Average number of fields per row (field rows only) */
averageFieldsPerRow: number;

@@ -533,2 +614,6 @@ /** Maximum number of fields in any single row */

minFieldsInRow: number;
/** Total number of repeatable groups */
totalRepeatables: number;
/** Total number of fields across all repeatable templates */
totalRepeatableFields: number;
};

@@ -545,3 +630,3 @@ }

}
declare function Form({ formConfig, defaultValues, onSubmit, onFieldChange, children }: FormProps): react_jsx_runtime.JSX.Element;
declare function Form({ formConfig, defaultValues, onSubmit, onFieldChange, className, children, }: FormProps): react_jsx_runtime.JSX.Element;

@@ -552,2 +637,4 @@ declare const FormBody: React__default.NamedExoticComponent<ComponentRendererBaseProps<FormBodyRendererProps>>;

fieldId: string;
/** Pre-resolved field config (used by RepeatableItem to skip allFields lookup) */
fieldConfig?: FormFieldConfig;
disabled?: boolean;

@@ -636,2 +723,4 @@ customProps?: Record<string, unknown>;

formValues: Record<string, any>;
/** Active repeatable item keys, keyed by repeatable ID */
repeatableOrder?: Record<string, string[]>;
}

@@ -673,3 +762,3 @@ interface UseFormConditionsReturn {

*/
declare function useFormConditions({ formConfig, formValues, }: UseFormConditionsProps): UseFormConditionsReturn;
declare function useFormConditions({ formConfig, formValues, repeatableOrder, }: UseFormConditionsProps): UseFormConditionsReturn;

@@ -679,2 +768,5 @@ interface FormStoreState extends FormState {

_fieldConditions: Record<string, FieldConditions>;
_repeatableConfigs: Record<string, RepeatableFieldConfig>;
_repeatableOrder: Record<string, string[]>;
_repeatableNextKey: Record<string, number>;
_setValue: (fieldId: string, value: unknown) => void;

@@ -689,2 +781,7 @@ _setTouched: (fieldId: string) => void;

_updateIsValid: () => void;
_setRepeatableConfig: (id: string, config: RepeatableFieldConfig) => void;
_appendRepeatableItem: (repeatableId: string, defaultValue?: Record<string, unknown>) => string | null;
_removeRepeatableItem: (repeatableId: string, key: string) => boolean;
_moveRepeatableItem: (repeatableId: string, fromIndex: number, toIndex: number) => void;
_insertRepeatableItem: (repeatableId: string, index: number, defaultValue?: Record<string, unknown>) => string | null;
}

@@ -763,2 +860,6 @@ type FormStore = ReturnType<typeof createFormStore>;

};
/**
* Select ordered keys for a repeatable field — re-renders when the order changes
*/
declare function useRepeatableKeys(repeatableId: string): string[];
interface UseFieldActionsResult {

@@ -813,2 +914,41 @@ setValue: (value: unknown) => void;

interface UseRepeatableFieldReturn {
items: RepeatableFieldItem[];
append: (defaultValue?: Record<string, unknown>) => void;
remove: (key: string) => void;
move: (fromIndex: number, toIndex: number) => void;
canAdd: boolean;
canRemove: boolean;
count: number;
}
/**
* Hook to manage a repeatable field group
*
* Provides the list of items and actions to add, remove, and reorder them.
* Each item contains scoped field configs ready for rendering.
*
* @param repeatableId - The ID of the repeatable group (as defined in addRepeatable)
* @returns Items, actions, and constraints
*
* @example
* ```tsx
* const { items, append, remove, canAdd, canRemove } = useRepeatableField("items");
*
* return (
* <div>
* {items.map(item => (
* <div key={item.key}>
* {item.allFields.map(field => (
* <FormField key={field.id} fieldId={field.id} fieldConfig={field} />
* ))}
* {canRemove && <button onClick={() => remove(item.key)}>Remove</button>}
* </div>
* ))}
* {canAdd && <button onClick={append}>Add</button>}
* </div>
* );
* ```
*/
declare function useRepeatableField(repeatableId: string): UseRepeatableFieldReturn;
interface UseFormMonitoringProps {

@@ -864,2 +1004,51 @@ formConfig: FormConfiguration;

export { type ConditionEvaluationResult, type FieldConfig, Form, FormBody, form as FormBuilder, type FormConfigContextValue, FormField, FormProvider, type FormProviderProps, FormRow, type FormStore, FormStoreContext, type FormStoreState, FormSubmitButton, type UseFieldActionsResult, type UseFieldConditionsLazyOptions, type UseFormActionsResult, type UseFormConditionsProps, type UseFormConditionsReturn, type UseFormMonitoringProps, type UseFormMonitoringReturn, type UseFormSubmissionWithStoreProps, type UseFormValidationWithStoreProps, createFormStore, form, useConditionEvaluation, useConditionEvaluator, useFieldActions, useFieldConditions, useFieldConditionsLazy, useFieldConditionsWithRefresh, useFieldErrors, useFieldState, useFieldTouched, useFieldValidationState, useFieldValue, useFormActions, useFormConditions, useFormConfigContext, useFormDirty, useFormMonitoring, useFormStore, useFormStoreApi, useFormSubmissionWithStore, useFormSubmitState, useFormSubmitting, useFormValid, useFormValidationWithStore, useFormValues, useMultipleConditionEvaluation };
interface RepeatableFieldProps {
repeatableId: string;
repeatableConfig: RepeatableFieldConfig;
className?: string;
}
declare const RepeatableField: React__default.NamedExoticComponent<RepeatableFieldProps>;
interface RepeatableItemProps {
item: RepeatableFieldItem;
index: number;
total: number;
canRemove: boolean;
canMoveUp: boolean;
canMoveDown: boolean;
onRemove: () => void;
onMoveUp: () => void;
onMoveDown: () => void;
}
declare const RepeatableItem: React__default.NamedExoticComponent<RepeatableItemProps>;
/**
* Converts flat store values with composite keys into structured nested data.
*
* Input (store values):
* { customerName: "John", "items[k0].name": "Widget", "items[k0].qty": 2, "items[k1].name": "Gadget", "items[k1].qty": 1 }
*
* Output (structured):
* { customerName: "John", items: [{ name: "Widget", qty: 2 }, { name: "Gadget", qty: 1 }] }
*/
declare function structureFormValues(values: Record<string, unknown>, repeatableConfigs: Record<string, RepeatableFieldConfig>, repeatableOrder: Record<string, string[]>): Record<string, unknown>;
/**
* Converts structured nested data into flat store values with composite keys.
*
* Input (structured):
* { customerName: "John", items: [{ name: "Widget", qty: 2 }, { name: "Gadget", qty: 1 }] }
*
* Output:
* {
* values: { customerName: "John", "items[k0].name": "Widget", "items[k0].qty": 2, "items[k1].name": "Gadget", "items[k1].qty": 1 },
* order: { items: ["k0", "k1"] },
* nextKeys: { items: 2 }
* }
*/
declare function flattenRepeatableValues(data: Record<string, unknown>, repeatableConfigs: Record<string, RepeatableFieldConfig>): {
values: Record<string, unknown>;
order: Record<string, string[]>;
nextKeys: Record<string, number>;
};
export { type ConditionEvaluationResult, type FieldConfig, Form, FormBody, form as FormBuilder, type FormConfigContextValue, FormField, FormProvider, type FormProviderProps, FormRow, type FormStore, FormStoreContext, type FormStoreState, FormSubmitButton, RepeatableBuilder, RepeatableField, RepeatableItem, type UseFieldActionsResult, type UseFieldConditionsLazyOptions, type UseFormActionsResult, type UseFormConditionsProps, type UseFormConditionsReturn, type UseFormMonitoringProps, type UseFormMonitoringReturn, type UseFormSubmissionWithStoreProps, type UseFormValidationWithStoreProps, type UseRepeatableFieldReturn, createFormStore, flattenRepeatableValues, form, structureFormValues, useConditionEvaluation, useConditionEvaluator, useFieldActions, useFieldConditions, useFieldConditionsLazy, useFieldConditionsWithRefresh, useFieldErrors, useFieldState, useFieldTouched, useFieldValidationState, useFieldValue, useFormActions, useFormConditions, useFormConfigContext, useFormDirty, useFormMonitoring, useFormStore, useFormStoreApi, useFormSubmissionWithStore, useFormSubmitState, useFormSubmitting, useFormValid, useFormValidationWithStore, useFormValues, useMultipleConditionEvaluation, useRepeatableField, useRepeatableKeys };
+1
-1

@@ -1,1 +0,1 @@

'use strict';var Xe=require('react'),core=require('@rilaykit/core'),zustand=require('zustand'),middleware=require('zustand/middleware'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Xe__default=/*#__PURE__*/_interopDefault(Xe);var x=class o{constructor(e,t){this.rows=[];this.idGenerator=new core.IdGenerator;this.config=e,this.formId=t||`form-${Math.random().toString(36).substring(2,15)}`;}static create(e,t){return new o(e,t)}createFormField(e){let t=this.config.getComponent(e.type);if(!t)throw new Error(`No component found with type "${e.type}"`);let i;return (t.validation||e.validation)&&(i={validateOnChange:e.validation?.validateOnChange??t.validation?.validateOnChange,validateOnBlur:e.validation?.validateOnBlur??t.validation?.validateOnBlur,debounceMs:e.validation?.debounceMs??t.validation?.debounceMs,validate:(()=>{let r=t.validation?.validate,n=e.validation?.validate;if(!r)return n;if(!n)return r;let a=Array.isArray(r)?r:[r],s=Array.isArray(n)?n:[n];return [...a,...s]})()}),{id:e.id||this.idGenerator.next("field"),componentId:t.id,props:{...t.defaultProps,...e.props},validation:i,conditions:e.conditions}}createRow(e){if(e.length===0)throw new Error("At least one field is required");if(e.length>3)throw new Error("Maximum 3 fields per row");let t=e.map(i=>this.createFormField(i));return {id:this.idGenerator.next("row"),fields:t,maxColumns:e.length}}add(...e){let t,i=false;if(e.length===1&&Array.isArray(e[0])?(t=e[0],i=true):t=e,t.length===0)throw new Error("At least one field is required");if(i&&t.length>3)throw new Error("Maximum 3 fields per row");if(t.length===1){let r=this.createRow(t);return this.rows.push(r),this}if(t.length<=3){let r=this.createRow(t);return this.rows.push(r),this}for(let r of t){let n=this.createRow([r]);this.rows.push(n);}return this}addSeparateRows(e){for(let t of e)this.add(t);return this}setId(e){return this.formId=e,this}updateField(e,t){let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);return Object.assign(i,{...t,props:{...i.props,...t.props}}),this}findField(e){for(let t of this.rows){let i=t.fields.find(r=>r.id===e);if(i)return i}return null}removeField(e){return this.rows=this.rows.map(t=>({...t,fields:t.fields.filter(i=>i.id!==e)})).filter(t=>t.fields.length>0),this}getField(e){return this.findField(e)||void 0}getFields(){return this.rows.flatMap(e=>e.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.idGenerator.reset(),this}setValidation(e){return this.formValidation=e,this}addFieldValidation(e,t){console.warn("addFieldValidation is deprecated. Use updateField with validation.validate property instead.");let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);let r={...i.validation,...t};return this.updateField(e,{validation:r})}addFieldConditions(e,t){let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);let r={...i.conditions,...t};return this.updateField(e,{conditions:r})}clone(e){let t=new o(this.config,e||`${this.formId}-clone`);return t.rows=core.deepClone(this.rows),t}validate(){let e=[],t=this.getFields(),i=t.map(r=>r.id);try{core.ensureUnique(i,"field");}catch(r){e.push(r instanceof Error?r.message:String(r));}for(let r of t)this.config.hasComponent(r.componentId)||e.push(`Component "${r.componentId}" not found for field "${r.id}"`);for(let r of this.rows)r.fields.length>3&&e.push(`Row "${r.id}" has ${r.fields.length} fields, maximum is 3`),r.fields.length===0&&e.push(`Row "${r.id}" is empty`);return e}build(){let e=this.validate();if(e.length>0)throw new Error(`Form validation failed: ${e.join(", ")}`);return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),config:this.config,renderConfig:this.config.getFormRenderConfig(),validation:this.formValidation}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(e){return e.id&&(this.formId=e.id),e.rows&&(this.rows=e.rows),this}getStats(){let e=this.getFields(),t=this.rows.map(i=>i.fields.length);return {totalFields:e.length,totalRows:this.rows.length,averageFieldsPerRow:this.rows.length>0?e.length/this.rows.length:0,maxFieldsInRow:t.length>0?Math.max(...t):0,minFieldsInRow:t.length>0?Math.min(...t):0}}};function Ft(o,e={},t={}){return Xe.useMemo(()=>{if(!o)return {visible:t.visible??true,disabled:t.disabled??false,required:t.required??false,readonly:t.readonly??false};let i=r=>{try{return r&&typeof r=="object"&&"build"in r?core.evaluateCondition(r.build(),e):core.evaluateCondition(r,e)}catch(n){return console.warn("Error evaluating condition:",n),false}};return {visible:o.visible?i(o.visible):t.visible??true,disabled:o.disabled?i(o.disabled):t.disabled??false,required:o.required?i(o.required):t.required??false,readonly:o.readonly?i(o.readonly):t.readonly??false}},[o,e,t])}function oe(o,e={}){return Xe.useMemo(()=>{let t={};for(let[i,r]of Object.entries(o))if(t[i]={visible:true,disabled:false,required:false,readonly:false},r){let n=a=>{try{return a&&typeof a=="object"&&"build"in a?core.evaluateCondition(a.build(),e):core.evaluateCondition(a,e)}catch(s){return console.warn(`Error evaluating condition for field ${i}:`,s),false}};t[i]={visible:r.visible?n(r.visible):true,disabled:r.disabled?n(r.disabled):false,required:r.required?n(r.required):false,readonly:r.readonly?n(r.readonly):false};}return t},[o,e])}function $(o={}){return zustand.createStore()(middleware.subscribeWithSelector((e,t)=>({values:{...o},errors:{},validationStates:{},touched:{},isDirty:false,isSubmitting:false,isValid:true,_defaultValues:{...o},_fieldConditions:{},_setValue:(i,r)=>{e(n=>({values:{...n.values,[i]:r},isDirty:true}));},_setTouched:i=>{e(r=>({touched:{...r.touched,[i]:true}}));},_setErrors:(i,r)=>{e(n=>{let a={...n.errors,[i]:r},s=r.length>0?"invalid":"valid";return {errors:a,validationStates:{...n.validationStates,[i]:s}}}),t()._updateIsValid();},_clearErrors:i=>{e(r=>{let n={...r.errors};return delete n[i],{errors:n,validationStates:{...r.validationStates,[i]:"idle"}}}),t()._updateIsValid();},_setValidationState:(i,r)=>{e(n=>({validationStates:{...n.validationStates,[i]:r}}));},_setSubmitting:i=>{e({isSubmitting:i});},_reset:i=>{let r=i??t()._defaultValues;e({values:{...r},errors:{},validationStates:{},touched:{},isDirty:false,isSubmitting:false,isValid:true});},_setFieldConditions:(i,r)=>{e(n=>({_fieldConditions:{...n._fieldConditions,[i]:r}}));},_updateIsValid:()=>{let i=t(),r=Object.values(i.errors).some(a=>a&&a.length>0),n=Object.values(i.validationStates).some(a=>a==="invalid");e({isValid:!r&&!n});}})))}var O=Xe.createContext(null);function v(){let o=Xe.useContext(O);if(!o)throw new Error("useFormStore must be used within a FormProvider");return o}var re=[];function N(o){let e=v();return zustand.useStore(e,t=>t.values[o])}function Me(o){let e=v();return zustand.useStore(e,t=>t.errors[o]??re)}function Be(o){let e=v();return zustand.useStore(e,t=>t.touched[o]??false)}function Te(o){let e=v();return zustand.useStore(e,t=>t.validationStates[o]??"idle")}var De={visible:true,disabled:false,required:false,readonly:false};function P(o){let e=v();return zustand.useStore(e,t=>t._fieldConditions[o]??De)}function W(o){let e=v(),t=zustand.useStore(e,s=>s.values[o]),i=zustand.useStore(e,s=>s.errors[o]??re),r=zustand.useStore(e,s=>s.validationStates[o]??"idle"),n=zustand.useStore(e,s=>s.touched[o]??false),a=zustand.useStore(e,s=>s._defaultValues[o]);return {value:t,errors:i,validationState:r,touched:n,dirty:t!==a}}function qe(){let o=v();return zustand.useStore(o,e=>e.isSubmitting)}function Oe(){let o=v();return zustand.useStore(o,e=>e.isValid)}function Ue(){let o=v();return zustand.useStore(o,e=>e.isDirty)}function Ae(){let o=v();return zustand.useStore(o,e=>e.values)}function H(){let o=v(),e=zustand.useStore(o,r=>r.isSubmitting),t=zustand.useStore(o,r=>r.isValid),i=zustand.useStore(o,r=>r.isDirty);return {isSubmitting:e,isValid:t,isDirty:i}}function L(o){let e=v();return {setValue:t=>e.getState()._setValue(o,t),setTouched:()=>e.getState()._setTouched(o),setErrors:t=>e.getState()._setErrors(o,t),clearErrors:()=>e.getState()._clearErrors(o),setValidationState:t=>e.getState()._setValidationState(o,t)}}function Ie(){let o=v();return {setValue:(e,t)=>o.getState()._setValue(e,t),setTouched:e=>o.getState()._setTouched(e),setErrors:(e,t)=>o.getState()._setErrors(e,t),setSubmitting:e=>o.getState()._setSubmitting(e),reset:e=>o.getState()._reset(e),setFieldConditions:(e,t)=>o.getState()._setFieldConditions(e,t)}}function B(){return v()}var se={visible:true,disabled:false,required:false,readonly:false};function ae(o){try{return JSON.stringify(o)}catch{return String(Date.now())}}function U(o,e){if(o)try{return typeof o=="object"&&"build"in o?core.evaluateCondition(o.build(),e):core.evaluateCondition(o,e)}catch(t){console.warn("Error evaluating condition:",t);return}}function j(o,e){if(!o)return se;let t=U(o.visible,e),i=U(o.disabled,e),r=U(o.required,e),n=U(o.readonly,e);return {visible:t??true,disabled:i??false,required:r??false,readonly:n??false}}function Vt(o,e={}){let{conditions:t,skip:i=false}=e,r=B(),n=P(o),a=Xe.useRef(null);if(i||!t)return n;let s=r.getState().values,F=ae(s);if(a.current?.valuesHash===F)return a.current.result;let m=j(t,s);return a.current={result:m,valuesHash:F},m}function xt(){let o=B(),e=Xe.useRef(new Map),t=Xe.useRef("");return Xe.useMemo(()=>function(r,n){if(!n)return se;let a=o.getState().values,s=ae(a);t.current!==s&&(e.current.clear(),t.current=s);let F=e.current.get(r);if(F)return F.result;let m=j(n,a);return e.current.set(r,{result:m,valuesHash:s}),m},[o])}function Pt(o,e){let t=B(),i=P(o),r=Xe.useMemo(()=>()=>{if(!e)return i;let n=t.getState().values;return j(e,n)},[t,e,i]);return {conditions:i,refresh:r}}function de({formConfig:o,formValues:e}){let t=Xe.useMemo(()=>{let l={};for(let u of o.allFields)u.conditions&&(l[u.id]=u.conditions);return l},[o.allFields]),i=Xe.useMemo(()=>Object.keys(t).length>0,[t]),r=oe(i?t:{},i?e:{}),n=Xe.useCallback(l=>r[l],[r]),a=Xe.useCallback(l=>{let u=r[l];return u?u.visible:true},[r]),s=Xe.useCallback(l=>{let u=r[l];return u?u.disabled:false},[r]),F=Xe.useCallback(l=>{let u=r[l];return u?u.required:false},[r]),m=Xe.useCallback(l=>{let u=r[l];return u?u.readonly:false},[r]);return Xe.useMemo(()=>({fieldConditions:r,hasConditionalFields:i,getFieldCondition:n,isFieldVisible:a,isFieldDisabled:s,isFieldRequired:F,isFieldReadonly:m}),[r,i,n,a,s,F,m])}function le({store:o,onSubmit:e,validateForm:t}){let i=Xe.useRef(e);return i.current=e,{submit:Xe.useCallback(async n=>{n?.preventDefault();let a=o.getState();if(a.isSubmitting)return false;a._setSubmitting(true);try{if(!(await t()).isValid)return a._setSubmitting(!1),!1;let F=o.getState().values;return i.current&&await i.current(F),a._setSubmitting(!1),!0}catch(s){return a._setSubmitting(false),console.error("Form submission error:",s),false}},[o,t])}}function A(){return {isValid:true,errors:[]}}function fe({formConfig:o,store:e,conditionsHelpers:t}){let i=Xe.useRef(o),r=Xe.useRef(t);i.current=o,r.current=t;let n=Xe.useCallback(async(s,F)=>{let m=i.current.allFields.find(d=>d.id===s),l=e.getState();if(!m)return A();if(!r.current.isFieldVisible(s))return l._setErrors(s,[]),l._setValidationState(s,"valid"),A();if(!m.validation||!core.hasUnifiedValidation(m.validation))return l._setErrors(s,[]),l._setValidationState(s,"valid"),A();let u=F!==void 0?F:l.values[s],c=core.createValidationContext({fieldId:s,formId:i.current.id,allFormData:{...l.values,[s]:u}});l._setValidationState(s,"validating");try{let d=await core.validateWithUnifiedConfig(m.validation,u,c),f=r.current.isFieldRequired(s),p=u==null||u==="";if(f&&p&&!d.errors.some(g=>g.code==="REQUIRED"||g.message.toLowerCase().includes("required"))){let g={isValid:!1,errors:[{message:"This field is required",code:"CONDITIONAL_REQUIRED"},...d.errors]};return l._setErrors(s,g.errors),l._setValidationState(s,"invalid"),g}return l._setErrors(s,d.errors),l._setValidationState(s,d.isValid?"valid":"invalid"),d}catch(d){let f={isValid:false,errors:[{message:d instanceof Error?d.message:"Validation failed",code:"VALIDATION_ERROR"}]};return l._setErrors(s,f.errors),l._setValidationState(s,"invalid"),f}},[e]),a=Xe.useCallback(async()=>{let s=e.getState(),F=i.current.allFields.filter(d=>{let f=r.current.isFieldVisible(d.id),p=d.validation&&core.hasUnifiedValidation(d.validation);return f&&p}),m=i.current.allFields.filter(d=>!r.current.isFieldVisible(d.id));for(let d of m)s._setErrors(d.id,[]),s._setValidationState(d.id,"valid");let l=await Promise.all(F.map(d=>n(d.id))),u=l.some(d=>!d.isValid),c=A();if(i.current.validation&&core.hasUnifiedValidation(i.current.validation)){let d=Object.keys(s.values).reduce((p,b)=>(r.current.isFieldVisible(b)&&(p[b]=s.values[b]),p),{}),f=core.createValidationContext({formId:i.current.id,allFormData:d});try{c=await core.validateFormWithUnifiedConfig(i.current.validation,d,f);}catch(p){c={isValid:false,errors:[{message:p instanceof Error?p.message:"Form validation failed",code:"FORM_VALIDATION_ERROR"}]};}}return {isValid:!u&&c.isValid,errors:[...l.flatMap(d=>d.errors),...c.errors]}},[e,n]);return {validateField:n,validateForm:a}}function je({formConfig:o,enabled:e=true}){let t=core.getGlobalMonitor(),i=Xe.useRef(null),r=Xe.useRef(0),n=Xe.useRef(0);Xe.useEffect(()=>{t&&e&&(i.current=t.getProfiler());},[t,e]);let a=Xe.useCallback(c=>{if(!t||!e)return;r.current++;let d={formId:o.id,fieldCount:o.allFields.length,timestamp:Date.now(),duration:0,renderDuration:0,validationDuration:0,validationErrors:0,renderCount:c||r.current};t.track("component_render",`form_${o.id}`,{formId:o.id,fieldCount:o.allFields.length,renderCount:r.current},d,"low");},[t,e,o.id,o.allFields.length]),s=Xe.useCallback((c,d)=>{if(!t||!e)return;let f=i.current?.getMetrics(`form_validation_${o.id}`),p={formId:o.id,fieldCount:d||o.allFields.length,timestamp:Date.now(),duration:f?.duration||0,renderDuration:0,validationDuration:f?.duration||0,validationErrors:c,renderCount:r.current};t.track("form_validation",`form_${o.id}`,{formId:o.id,validationErrors:c,fieldCount:d||o.allFields.length},p,c>0?"medium":"low");},[t,e,o.id,o.allFields.length]),F=Xe.useCallback((c,d)=>{if(!t||!e)return;let f=i.current?.getMetrics(`form_submission_${o.id}`),p={formId:o.id,fieldCount:d||o.allFields.length,timestamp:Date.now(),duration:f?.duration||0,renderDuration:0,validationDuration:0,validationErrors:c?0:1,renderCount:r.current};t.track("form_submission",`form_${o.id}`,{formId:o.id,success:c,fieldCount:d||o.allFields.length,fieldChanges:n.current},p,c?"low":"high");},[t,e,o.id,o.allFields.length]),m=Xe.useCallback((c,d)=>{!t||!e||(n.current++,t.track("component_update",`field_${c}`,{formId:o.id,fieldId:c,componentType:d,changeCount:n.current},void 0,"low"));},[t,e,o.id]),l=Xe.useCallback(c=>{!i.current||!e||i.current.start(c,{formId:o.id,renderCount:r.current});},[e,o.id]),u=Xe.useCallback(c=>{if(!i.current||!e)return null;let d=i.current.end(c);return d?{...d,formId:o.id,fieldCount:o.allFields.length,renderDuration:d.duration,validationDuration:0,validationErrors:0}:null},[e,o.id,o.allFields.length]);return {trackFormRender:a,trackFormValidation:s,trackFormSubmission:F,trackFieldChange:m,startPerformanceTracking:l,endPerformanceTracking:u}}var Ce=Xe.createContext(null);function y(){let o=Xe.useContext(Ce);if(!o)throw new Error("useFormConfigContext must be used within a FormProvider");return o}function K({children:o,formConfig:e,defaultValues:t={},onSubmit:i,onFieldChange:r,className:n}){let[a]=Xe.useState(()=>$(t)),s=Xe.useRef(e.id),F=Xe.useRef(r);F.current=r,Xe.useEffect(()=>F.current?a.subscribe(C=>C.values,(C,M)=>{for(let R of Object.keys(C))C[R]!==M[R]&&F.current?.(R,C[R],C);}):void 0,[a]),Xe.useEffect(()=>{s.current!==e.id&&(s.current=e.id,a.getState()._reset(t));},[e.id,a,t]);let[m,l]=Xe.useState(()=>a.getState().values);Xe.useEffect(()=>a.subscribe(C=>C.values,C=>l(C)),[a]);let{fieldConditions:u,hasConditionalFields:c,getFieldCondition:d,isFieldVisible:f,isFieldDisabled:p,isFieldRequired:b,isFieldReadonly:g}=de({formConfig:e,formValues:m});Xe.useEffect(()=>{for(let[V,C]of Object.entries(u)){let M={visible:C.visible,disabled:C.disabled,required:C.required,readonly:C.readonly};a.getState()._setFieldConditions(V,M);}},[u,a]);let w=Xe.useMemo(()=>({hasConditionalFields:c,getFieldCondition:d,isFieldVisible:f,isFieldDisabled:p,isFieldRequired:b,isFieldReadonly:g}),[c,d,f,p,b,g]),{validateField:_,validateForm:S}=fe({formConfig:e,store:a,conditionsHelpers:w}),{submit:k}=le({store:a,onSubmit:i,validateForm:S}),D=Xe.useMemo(()=>({formConfig:e,conditionsHelpers:w,validateField:_,validateForm:S,submit:k}),[e,w,_,S,k]);return jsxRuntime.jsx(O.Provider,{value:a,children:jsxRuntime.jsx(Ce.Provider,{value:D,children:jsxRuntime.jsx("form",{onSubmit:k,className:n,noValidate:true,children:o})})})}function Ye({formConfig:o,defaultValues:e,onSubmit:t,onFieldChange:i,children:r}){let n=Xe.useMemo(()=>o instanceof x?o.build():o,[o]);return jsxRuntime.jsx(K,{formConfig:n,defaultValues:e,onSubmit:t,onFieldChange:i,children:r})}var Z=Xe__default.default.memo(function({fieldId:e,disabled:t=false,customProps:i={},className:r,forceVisible:n=false}){let{formConfig:a,validateField:s,conditionsHelpers:F}=y(),m=N(e),l=W(e),u=P(e),{setValue:c,setTouched:d}=L(e),f=a.allFields.find(R=>R.id===e);if(!f)throw new Error(`Field with ID "${e}" not found`);let p=a.config.getComponent(f.componentId);if(!p)throw new Error(`Component with ID "${f.componentId}" not found`);let b=l.validationState==="validating",g=Xe.useMemo(()=>({isVisible:n||u.visible,isFieldDisabled:t||u.disabled,isFieldRequired:u.required||F.isFieldRequired(e),isFieldReadonly:u.readonly}),[n,t,u,F,e]),w=Xe.useCallback(async R=>{c(R),(f.validation?.validateOnChange||l.touched)&&await s(e,R);},[e,c,s,f.validation?.validateOnChange,l.touched]),_=Xe.useCallback(async()=>{l.touched||d(),f.validation?.validateOnBlur!==false&&await s(e);},[e,l.touched,d,s,f.validation?.validateOnBlur]),S=Xe.useMemo(()=>({...p.defaultProps??{},...f.props,...i,disabled:g.isFieldDisabled,required:g.isFieldRequired,readOnly:g.isFieldReadonly}),[p.defaultProps,f.props,i,g.isFieldDisabled,g.isFieldRequired,g.isFieldReadonly]),k=Xe.useMemo(()=>({id:e,props:S,value:m,onChange:w,onBlur:_,disabled:g.isFieldDisabled,error:l.errors,isValidating:b,touched:l.touched}),[e,S,m,w,_,g.isFieldDisabled,l.errors,b,l.touched]);if(!g.isVisible)return null;let D=p.renderer(k),V=a.renderConfig?.fieldRenderer,C=p.useFieldRenderer!==false,M=V&&C?V({children:D,id:e,...S,error:l.errors,isValidating:b,touched:l.touched}):D;return jsxRuntime.jsx("div",{className:r,"data-field-id":e,"data-field-type":p.type,"data-field-visible":g.isVisible,"data-field-disabled":g.isFieldDisabled,"data-field-required":g.isFieldRequired,"data-field-readonly":g.isFieldReadonly,children:M})});var be=Xe__default.default.memo(function({row:e,className:t,...i}){let{formConfig:r,conditionsHelpers:n}=y(),a=Xe.useMemo(()=>e.fields.filter(m=>n.isFieldVisible(m.id)),[e.fields,n]),s=Xe.useMemo(()=>a.map(m=>jsxRuntime.jsx(Z,{fieldId:m.id},m.id)),[a]),F=Xe.useMemo(()=>({row:e,children:s,className:t}),[e,s,t]);return a.length===0?null:jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormRow",renderer:r.renderConfig?.rowRenderer,props:F,...i,children:s})}),Re=be;var it=Xe__default.default.memo(function({className:e,...t}){let{formConfig:i}=y(),r=Xe.useMemo(()=>i.rows.map(a=>jsxRuntime.jsx(Re,{row:a},a.id)),[i.rows]),n=Xe.useMemo(()=>({formConfig:i,children:r,className:e}),[i,r,e]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormBody",renderer:i.renderConfig?.bodyRenderer,props:n,...t,children:r})});var dt=Xe__default.default.memo(function({className:e,isSubmitting:t,...i}){let{formConfig:r,submit:n}=y(),{isSubmitting:a}=H(),s=Xe.useMemo(()=>({isSubmitting:t??a,onSubmit:n,className:e}),[t,a,n,e]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormSubmitButton",renderer:r.renderConfig?.submitButtonRenderer,props:s,...i})});exports.Form=Ye;exports.FormBody=it;exports.FormBuilder=x;exports.FormField=Z;exports.FormProvider=K;exports.FormRow=be;exports.FormStoreContext=O;exports.FormSubmitButton=dt;exports.createFormStore=$;exports.form=x;exports.useConditionEvaluation=Ft;exports.useConditionEvaluator=xt;exports.useFieldActions=L;exports.useFieldConditions=P;exports.useFieldConditionsLazy=Vt;exports.useFieldConditionsWithRefresh=Pt;exports.useFieldErrors=Me;exports.useFieldState=W;exports.useFieldTouched=Be;exports.useFieldValidationState=Te;exports.useFieldValue=N;exports.useFormActions=Ie;exports.useFormConditions=de;exports.useFormConfigContext=y;exports.useFormDirty=Ue;exports.useFormMonitoring=je;exports.useFormStore=v;exports.useFormStoreApi=B;exports.useFormSubmissionWithStore=le;exports.useFormSubmitState=H;exports.useFormSubmitting=qe;exports.useFormValid=Oe;exports.useFormValidationWithStore=fe;exports.useFormValues=Ae;exports.useMultipleConditionEvaluation=oe;
'use strict';var Ot=require('react'),core=require('@rilaykit/core'),zustand=require('zustand'),middleware=require('zustand/middleware'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Ot__default=/*#__PURE__*/_interopDefault(Ot);var j=class{constructor(e){this.innerForm=new T(e,"__repeatable_template__");}add(...e){return this.innerForm.add(...e),this}addSeparateRows(e){return this.innerForm.addSeparateRows(e),this}min(e){return this._min=e,this}max(e){return this._max=e,this}defaultValue(e){return this._defaultValue=e,this}validation(e){return this._validation=e,this}_build(e){let t=this.innerForm.getRows(),i=this.innerForm.getFields();if(t.length===0)throw new Error(`Repeatable "${e}" must have at least one field`);for(let o of i)if(o.id.includes("[")||o.id.includes("]"))throw new Error(`Repeatable template field ID "${o.id}" cannot contain "[" or "]" (reserved for composite keys)`);if(this._min!==void 0&&this._max!==void 0&&this._min>this._max)throw new Error(`Repeatable "${e}": min (${this._min}) cannot be greater than max (${this._max})`);return {id:e,rows:t.map(o=>({...o,kind:"fields"})),allFields:i,min:this._min,max:this._max,defaultValue:this._defaultValue,validation:this._validation}}_hasRepeatables(){return this.innerForm.getRows().some(e=>"kind"in e&&e.kind==="repeatable")}};var T=class r{constructor(e,t){this.rows=[];this.idGenerator=new core.IdGenerator;this.config=e,this.formId=t||`form-${Math.random().toString(36).substring(2,15)}`;}static create(e,t){return new r(e,t)}createFormField(e){let t=this.config.getComponent(e.type);if(!t)throw new Error(`No component found with type "${e.type}"`);let i;return (t.validation||e.validation)&&(i={validateOnChange:e.validation?.validateOnChange??t.validation?.validateOnChange,validateOnBlur:e.validation?.validateOnBlur??t.validation?.validateOnBlur,debounceMs:e.validation?.debounceMs??t.validation?.debounceMs,validate:(()=>{let o=t.validation?.validate,s=e.validation?.validate;if(!o)return s;if(!s)return o;let a=Array.isArray(o)?o:[o],n=Array.isArray(s)?s:[s];return [...a,...n]})()}),{id:e.id||this.idGenerator.next("field"),componentId:t.id,props:{...t.defaultProps,...e.props},validation:i,conditions:e.conditions}}createRow(e){if(e.length===0)throw new Error("At least one field is required");if(e.length>3)throw new Error("Maximum 3 fields per row");let t=e.map(i=>this.createFormField(i));return {kind:"fields",id:this.idGenerator.next("row"),fields:t,maxColumns:e.length}}add(...e){let t,i=false;if(e.length===1&&Array.isArray(e[0])?(t=e[0],i=true):t=e,t.length===0)throw new Error("At least one field is required");if(i&&t.length>3)throw new Error("Maximum 3 fields per row");if(t.length===1){let o=this.createRow(t);return this.rows.push(o),this}if(t.length<=3){let o=this.createRow(t);return this.rows.push(o),this}for(let o of t){let s=this.createRow([o]);this.rows.push(s);}return this}addSeparateRows(e){for(let t of e)this.add(t);return this}addRepeatable(e,t){if(e.includes("[")||e.includes("]"))throw new Error(`Repeatable ID "${e}" cannot contain "[" or "]" (reserved for composite keys)`);let i=new j(this.config),o=t(i);if(o._hasRepeatables())throw new Error(`Nested repeatables are not supported (in repeatable "${e}")`);let s=o._build(e),a={kind:"repeatable",id:this.idGenerator.next("repeatable"),repeatable:s};return this.rows.push(a),this}setId(e){return this.formId=e,this}updateField(e,t){let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);return Object.assign(i,{...t,props:{...i.props,...t.props}}),this}findField(e){for(let t of this.rows)if(t.kind==="fields"){let i=t.fields.find(o=>o.id===e);if(i)return i}else {let i=t.repeatable.allFields.find(o=>o.id===e);if(i)return i}return null}removeField(e){return this.rows=this.rows.map(t=>t.kind==="repeatable"?t:{...t,fields:t.fields.filter(i=>i.id!==e)}).filter(t=>t.kind==="repeatable"||t.fields.length>0),this}getField(e){return this.findField(e)||void 0}getFields(){return this.rows.filter(e=>e.kind==="fields").flatMap(e=>e.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.idGenerator.reset(),this}setValidation(e){return this.formValidation=e,this}addFieldValidation(e,t){console.warn("addFieldValidation is deprecated. Use updateField with validation.validate property instead.");let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);let o={...i.validation,...t};return this.updateField(e,{validation:o})}addFieldConditions(e,t){let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);let o={...i.conditions,...t};return this.updateField(e,{conditions:o})}clone(e){let t=new r(this.config,e||`${this.formId}-clone`);return t.rows=core.deepClone(this.rows),t}validate(){let e=[],t=this.getFields(),i=this.rows.filter(n=>n.kind==="repeatable"),o=i.flatMap(n=>n.repeatable.allFields),s=[...t.map(n=>n.id),...o.map(n=>n.id)];try{core.ensureUnique(s,"field");}catch(n){e.push(n instanceof Error?n.message:String(n));}let a=i.map(n=>n.repeatable.id);try{core.ensureUnique(a,"repeatable");}catch(n){e.push(n instanceof Error?n.message:String(n));}for(let n of t)this.config.hasComponent(n.componentId)||e.push(`Component "${n.componentId}" not found for field "${n.id}"`);for(let n of o)this.config.hasComponent(n.componentId)||e.push(`Component "${n.componentId}" not found for repeatable template field "${n.id}"`);for(let n of this.rows)n.kind==="fields"&&(n.fields.length>3&&e.push(`Row "${n.id}" has ${n.fields.length} fields, maximum is 3`),n.fields.length===0&&e.push(`Row "${n.id}" is empty`));for(let n of t)(n.id.includes("[")||n.id.includes("]"))&&e.push(`Field ID "${n.id}" cannot contain "[" or "]" (reserved for repeatable composite keys)`);for(let n of a)(n.includes("[")||n.includes("]"))&&e.push(`Repeatable ID "${n}" cannot contain "[" or "]" (reserved for composite keys)`);return e}build(){let e=this.validate();if(e.length>0)throw new Error(`Form validation failed: ${e.join(", ")}`);let t=this.rows.filter(o=>o.kind==="repeatable"),i=t.length>0?Object.fromEntries(t.map(o=>[o.repeatable.id,o.repeatable])):void 0;return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),repeatableFields:i,config:this.config,renderConfig:this.config.getFormRenderConfig(),validation:this.formValidation}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(e){return e.id&&(this.formId=e.id),e.rows&&(this.rows=e.rows.map(t=>t.kind?t:{...t,kind:"fields"})),this}getStats(){let e=this.getFields(),t=this.rows.filter(s=>s.kind==="fields"),i=this.rows.filter(s=>s.kind==="repeatable"),o=t.map(s=>s.fields.length);return {totalFields:e.length,totalRows:this.rows.length,averageFieldsPerRow:t.length>0?e.length/t.length:0,maxFieldsInRow:o.length>0?Math.max(...o):0,minFieldsInRow:o.length>0?Math.min(...o):0,totalRepeatables:i.length,totalRepeatableFields:i.reduce((s,a)=>s+a.repeatable.allFields.length,0)}}};function er(r,e={},t={}){return Ot.useMemo(()=>{if(!r)return {visible:t.visible??true,disabled:t.disabled??false,required:t.required??false,readonly:t.readonly??false};let i=o=>{try{return o&&typeof o=="object"&&"build"in o?core.evaluateCondition(o.build(),e):core.evaluateCondition(o,e)}catch(s){return console.warn("Error evaluating condition:",s),false}};return {visible:r.visible?i(r.visible):t.visible??true,disabled:r.disabled?i(r.disabled):t.disabled??false,required:r.required?i(r.required):t.required??false,readonly:r.readonly?i(r.readonly):t.readonly??false}},[r,e,t])}function Te(r,e={}){return Ot.useMemo(()=>{let t={};for(let[i,o]of Object.entries(r))if(t[i]={visible:true,disabled:false,required:false,readonly:false},o){let s=a=>{try{return a&&typeof a=="object"&&"build"in a?core.evaluateCondition(a.build(),e):core.evaluateCondition(a,e)}catch(n){return console.warn(`Error evaluating condition for field ${i}:`,n),false}};t[i]={visible:o.visible?s(o.visible):true,disabled:o.disabled?s(o.disabled):false,required:o.required?s(o.required):false,readonly:o.readonly?s(o.readonly):false};}return t},[r,e])}var it=/^([^[\]]+)\[([^\]]+)\]\.(.+)$/;function V(r,e,t){return `${r}[${e}].${t}`}function L(r){let e=it.exec(r);return e?{repeatableId:e[1],itemKey:e[2],fieldId:e[3]}:null}function de(r,e,t){let i={},o=new Set;for(let[s,a]of Object.entries(t)){if(!e[s])continue;let n=e[s],u=[];for(let p of a){let f={};for(let m of n.allFields){let l=V(s,p,m.id);l in r&&(f[m.id]=r[l],o.add(l));}u.push(f);}i[s]=u;}for(let[s,a]of Object.entries(r))!o.has(s)&&!L(s)&&(i[s]=a);return i}function re(r,e){let t={},i={},o={};for(let[s,a]of Object.entries(r))if(e[s]&&Array.isArray(a)){let n=[],u=0;for(let p of a){let f=`k${u}`;n.push(f);for(let[m,l]of Object.entries(p))t[V(s,f,m)]=l;u++;}i[s]=n,o[s]=u;}else t[s]=a;return {values:t,order:i,nextKeys:o}}function ue(r={}){return zustand.createStore()(middleware.subscribeWithSelector((e,t)=>({values:{...r},errors:{},validationStates:{},touched:{},isDirty:false,isSubmitting:false,isValid:true,_defaultValues:{...r},_fieldConditions:{},_repeatableConfigs:{},_repeatableOrder:{},_repeatableNextKey:{},_setValue:(i,o)=>{e(s=>({values:{...s.values,[i]:o},isDirty:true}));},_setTouched:i=>{e(o=>({touched:{...o.touched,[i]:true}}));},_setErrors:(i,o)=>{e(s=>{let a={...s.errors,[i]:o},n=o.length>0?"invalid":"valid";return {errors:a,validationStates:{...s.validationStates,[i]:n}}}),t()._updateIsValid();},_clearErrors:i=>{e(o=>{let s={...o.errors};return delete s[i],{errors:s,validationStates:{...o.validationStates,[i]:"idle"}}}),t()._updateIsValid();},_setValidationState:(i,o)=>{e(s=>({validationStates:{...s.validationStates,[i]:o}}));},_setSubmitting:i=>{e({isSubmitting:i});},_reset:i=>{let o=i??t()._defaultValues;e({values:{...o},errors:{},validationStates:{},touched:{},isDirty:false,isSubmitting:false,isValid:true,_repeatableOrder:{},_repeatableNextKey:{}});},_setFieldConditions:(i,o)=>{e(s=>({_fieldConditions:{...s._fieldConditions,[i]:o}}));},_updateIsValid:()=>{let i=t(),o=Object.values(i.errors).some(a=>a&&a.length>0),s=Object.values(i.validationStates).some(a=>a==="invalid");e({isValid:!o&&!s});},_setRepeatableConfig:(i,o)=>{e(s=>({_repeatableConfigs:{...s._repeatableConfigs,[i]:o}}));},_appendRepeatableItem:(i,o)=>{let s=t(),a=s._repeatableConfigs[i];if(!a)return null;let n=s._repeatableOrder[i]??[];if(a.max!==void 0&&n.length>=a.max)return null;let u=s._repeatableNextKey[i]??0,p=`k${u}`,f=o??a.defaultValue??{},m={...s.values};for(let l of a.allFields){let d=V(i,p,l.id);m[d]=f[l.id]??void 0;}return e({values:m,isDirty:true,_repeatableOrder:{...s._repeatableOrder,[i]:[...n,p]},_repeatableNextKey:{...s._repeatableNextKey,[i]:u+1}}),p},_removeRepeatableItem:(i,o)=>{let s=t(),a=s._repeatableConfigs[i];if(!a)return false;let n=s._repeatableOrder[i]??[];if(a.min!==void 0&&n.length<=a.min||!n.includes(o))return false;let u=n.filter(F=>F!==o),p={...s.values},f={...s.errors},m={...s.validationStates},l={...s.touched},d={...s._fieldConditions};for(let F of a.allFields){let g=V(i,o,F.id);delete p[g],delete f[g],delete m[g],delete l[g],delete d[g];}return e({values:p,errors:f,validationStates:m,touched:l,isDirty:true,_fieldConditions:d,_repeatableOrder:{...s._repeatableOrder,[i]:u}}),t()._updateIsValid(),true},_moveRepeatableItem:(i,o,s)=>{let a=t(),n=a._repeatableOrder[i];if(!n||o<0||o>=n.length||s<0||s>=n.length||o===s)return;let u=[...n],[p]=u.splice(o,1);u.splice(s,0,p),e({_repeatableOrder:{...a._repeatableOrder,[i]:u}});},_insertRepeatableItem:(i,o,s)=>{let a=t(),n=a._repeatableConfigs[i];if(!n)return null;let u=a._repeatableOrder[i]??[];if(n.max!==void 0&&u.length>=n.max)return null;let p=a._repeatableNextKey[i]??0,f=`k${p}`,m=s??n.defaultValue??{},l={...a.values};for(let g of n.allFields){let c=V(i,f,g.id);l[c]=m[g.id]??void 0;}let d=[...u],F=Math.max(0,Math.min(o,d.length));return d.splice(F,0,f),e({values:l,isDirty:true,_repeatableOrder:{...a._repeatableOrder,[i]:d},_repeatableNextKey:{...a._repeatableNextKey,[i]:p+1}}),f}})))}var oe=Ot.createContext(null);function S(){let r=Ot.useContext(oe);if(!r)throw new Error("useFormStore must be used within a FormProvider");return r}var De=[];function ce(r){let e=S();return zustand.useStore(e,t=>t.values[r])}function dt(r){let e=S();return zustand.useStore(e,t=>t.errors[r]??De)}function ut(r){let e=S();return zustand.useStore(e,t=>t.touched[r]??false)}function ct(r){let e=S();return zustand.useStore(e,t=>t.validationStates[r]??"idle")}var mt={visible:true,disabled:false,required:false,readonly:false};function $(r){let e=S();return zustand.useStore(e,t=>t._fieldConditions[r]??mt)}function me(r){let e=S(),t=zustand.useStore(e,n=>n.values[r]),i=zustand.useStore(e,n=>n.errors[r]??De),o=zustand.useStore(e,n=>n.validationStates[r]??"idle"),s=zustand.useStore(e,n=>n.touched[r]??false),a=zustand.useStore(e,n=>n._defaultValues[r]);return {value:t,errors:i,validationState:o,touched:s,dirty:t!==a}}function ft(){let r=S();return zustand.useStore(r,e=>e.isSubmitting)}function pt(){let r=S();return zustand.useStore(r,e=>e.isValid)}function Ft(){let r=S();return zustand.useStore(r,e=>e.isDirty)}function gt(){let r=S();return zustand.useStore(r,e=>e.values)}function fe(){let r=S(),e=zustand.useStore(r,o=>o.isSubmitting),t=zustand.useStore(r,o=>o.isValid),i=zustand.useStore(r,o=>o.isDirty);return {isSubmitting:e,isValid:t,isDirty:i}}var bt=[];function pe(r){let e=S();return zustand.useStore(e,t=>t._repeatableOrder[r]??bt)}function Fe(r){let e=S();return {setValue:t=>e.getState()._setValue(r,t),setTouched:()=>e.getState()._setTouched(r),setErrors:t=>e.getState()._setErrors(r,t),clearErrors:()=>e.getState()._clearErrors(r),setValidationState:t=>e.getState()._setValidationState(r,t)}}function Ct(){let r=S();return {setValue:(e,t)=>r.getState()._setValue(e,t),setTouched:e=>r.getState()._setTouched(e),setErrors:(e,t)=>r.getState()._setErrors(e,t),setSubmitting:e=>r.getState()._setSubmitting(e),reset:e=>r.getState()._reset(e),setFieldConditions:(e,t)=>r.getState()._setFieldConditions(e,t)}}function H(){return S()}var Ae={visible:true,disabled:false,required:false,readonly:false};function Ke(r){try{return JSON.stringify(r)}catch{return String(Date.now())}}function ie(r,e){if(r)try{return typeof r=="object"&&"build"in r?core.evaluateCondition(r.build(),e):core.evaluateCondition(r,e)}catch(t){console.warn("Error evaluating condition:",t);return}}function be(r,e){if(!r)return Ae;let t=ie(r.visible,e),i=ie(r.disabled,e),o=ie(r.required,e),s=ie(r.readonly,e);return {visible:t??true,disabled:i??false,required:o??false,readonly:s??false}}function fr(r,e={}){let{conditions:t,skip:i=false}=e,o=H(),s=$(r),a=Ot.useRef(null);if(i||!t)return s;let n=o.getState().values,u=Ke(n);if(a.current?.valuesHash===u)return a.current.result;let p=be(t,n);return a.current={result:p,valuesHash:u},p}function pr(){let r=H(),e=Ot.useRef(new Map),t=Ot.useRef("");return Ot.useMemo(()=>function(o,s){if(!s)return Ae;let a=r.getState().values,n=Ke(a);t.current!==n&&(e.current.clear(),t.current=n);let u=e.current.get(o);if(u)return u.result;let p=be(s,a);return e.current.set(o,{result:p,valuesHash:n}),p},[r])}function Fr(r,e){let t=H(),i=$(r),o=Ot.useMemo(()=>()=>{if(!e)return i;let s=t.getState().values;return be(e,s)},[t,e,i]);return {conditions:i,refresh:o}}function Y(r,e,t,i){let o={};return r.visible&&(o.visible=G(r.visible,e,t,i)),r.disabled&&(o.disabled=G(r.disabled,e,t,i)),r.required&&(o.required=G(r.required,e,t,i)),r.readonly&&(o.readonly=G(r.readonly,e,t,i)),o}function G(r,e,t,i){let o=r.field&&i.has(r.field)?`${e}[${t}].${r.field}`:r.field,s=r.conditions?.map(a=>G(a,e,t,i));return {...r,field:o,conditions:s}}function Ue({formConfig:r,formValues:e,repeatableOrder:t}){let i=Ot.useMemo(()=>{let m={};for(let l of r.allFields)l.conditions&&(m[l.id]=l.conditions);if(t&&r.repeatableFields)for(let[l,d]of Object.entries(r.repeatableFields)){let F=t[l]??[];if(F.length===0)continue;let g=new Set(d.allFields.map(c=>c.id));for(let c of F)for(let R of d.allFields){if(!R.conditions)continue;let b=V(l,c,R.id);m[b]=Y(R.conditions,l,c,g);}}return m},[r.allFields,r.repeatableFields,t]),o=Ot.useMemo(()=>Object.keys(i).length>0,[i]),s=Te(o?i:{},o?e:{}),a=Ot.useCallback(m=>s[m],[s]),n=Ot.useCallback(m=>{let l=s[m];return l?l.visible:true},[s]),u=Ot.useCallback(m=>{let l=s[m];return l?l.disabled:false},[s]),p=Ot.useCallback(m=>{let l=s[m];return l?l.required:false},[s]),f=Ot.useCallback(m=>{let l=s[m];return l?l.readonly:false},[s]);return Ot.useMemo(()=>({fieldConditions:s,hasConditionalFields:o,getFieldCondition:a,isFieldVisible:n,isFieldDisabled:u,isFieldRequired:p,isFieldReadonly:f}),[s,o,a,n,u,p,f])}function $e({store:r,onSubmit:e,validateForm:t}){let i=Ot.useRef(e);return i.current=e,{submit:Ot.useCallback(async s=>{s?.preventDefault();let a=r.getState();if(a.isSubmitting)return false;a._setSubmitting(true);try{if(!(await t()).isValid)return a._setSubmitting(!1),!1;let u=r.getState(),f=Object.keys(u._repeatableConfigs).length>0?de(u.values,u._repeatableConfigs,u._repeatableOrder):u.values;return i.current&&await i.current(f),a._setSubmitting(!1),!0}catch(n){return a._setSubmitting(false),console.error("Form submission error:",n),false}},[r,t])}}function ne(){return {isValid:true,errors:[]}}function Le({formConfig:r,store:e,conditionsHelpers:t}){let i=Ot.useRef(r),o=Ot.useRef(t);i.current=r,o.current=t;let s=Ot.useCallback(async(n,u)=>{let p=i.current.allFields.find(d=>d.id===n);if(!p){let d=L(n);if(d&&i.current.repeatableFields){let F=i.current.repeatableFields[d.repeatableId];if(F){let g=F.allFields.find(c=>c.id===d.fieldId);g&&(p={...g,id:n});}}}let f=e.getState();if(!p)return ne();if(!o.current.isFieldVisible(n))return f._setErrors(n,[]),f._setValidationState(n,"valid"),ne();if(!p.validation||!core.hasUnifiedValidation(p.validation)){let d=o.current.isFieldRequired(n),F=u!==void 0?u:f.values[n];if(d&&core.isEmptyValue(F)){let g={isValid:false,errors:[{message:"This field is required",code:"CONDITIONAL_REQUIRED"}]};return f._setErrors(n,g.errors),f._setValidationState(n,"invalid"),g}return f._setErrors(n,[]),f._setValidationState(n,"valid"),ne()}let m=u!==void 0?u:f.values[n],l=core.createValidationContext({fieldId:n,formId:i.current.id,allFormData:{...f.values,[n]:m}});f._setValidationState(n,"validating");try{let d=await core.validateWithUnifiedConfig(p.validation,m,l);if(o.current.isFieldRequired(n)&&core.isEmptyValue(m)&&!d.errors.some(c=>c.code==="REQUIRED"||c.message.toLowerCase().includes("required"))){let c={isValid:!1,errors:[{message:"This field is required",code:"CONDITIONAL_REQUIRED"},...d.errors]};return f._setErrors(n,c.errors),f._setValidationState(n,"invalid"),c}return f._setErrors(n,d.errors),f._setValidationState(n,d.isValid?"valid":"invalid"),d}catch(d){let F={isValid:false,errors:[{message:d instanceof Error?d.message:"Validation failed",code:"VALIDATION_ERROR"}]};return f._setErrors(n,F.errors),f._setValidationState(n,"invalid"),F}},[e]),a=Ot.useCallback(async()=>{let n=e.getState(),u=i.current.allFields.filter(c=>{if(!o.current.isFieldVisible(c.id))return false;let b=c.validation&&core.hasUnifiedValidation(c.validation),k=o.current.isFieldRequired(c.id);return b||k}),p=i.current.allFields.filter(c=>!o.current.isFieldVisible(c.id));for(let c of p)n._setErrors(c.id,[]),n._setValidationState(c.id,"valid");let f=await Promise.all(u.map(c=>s(c.id))),m=f.some(c=>!c.isValid),l=i.current.repeatableFields??{},d=[];for(let[c,R]of Object.entries(l)){let b=n._repeatableOrder[c]??[];for(let k of b)for(let O of R.allFields){let P=V(c,k,O.id);if(!o.current.isFieldVisible(P)){n._setErrors(P,[]),n._setValidationState(P,"valid");continue}let D=await s(P);d.push(D);}R.min!==void 0&&b.length<R.min&&d.push({isValid:false,errors:[{message:`At least ${R.min} item(s) required`,code:"REPEATABLE_MIN_COUNT",path:c}]});}let F=d.some(c=>!c.isValid);m=m||F;let g=ne();if(i.current.validation&&core.hasUnifiedValidation(i.current.validation)){let c=Object.keys(n.values).reduce((b,k)=>(o.current.isFieldVisible(k)&&(b[k]=n.values[k]),b),{}),R=core.createValidationContext({formId:i.current.id,allFormData:c});try{g=await core.validateFormWithUnifiedConfig(i.current.validation,c,R);}catch(b){g={isValid:false,errors:[{message:b instanceof Error?b.message:"Form validation failed",code:"FORM_VALIDATION_ERROR"}]};}}return {isValid:!m&&g.isValid,errors:[...f.flatMap(c=>c.errors),...d.flatMap(c=>c.errors),...g.errors]}},[e,s]);return {validateField:s,validateForm:a}}function ve(r){let e=S(),{formConfig:t}=E(),i=pe(r),o=t.repeatableFields?.[r],s=Ot.useMemo(()=>o?new Set(o.allFields.map(l=>l.id)):new Set,[o]),a=Ot.useMemo(()=>o?i.map((l,d)=>{let F=o.allFields.map(c=>{let R=V(r,l,c.id),b=c.conditions?Y(c.conditions,r,l,s):void 0;return {...c,id:R,conditions:b}}),g=o.rows.map(c=>({...c,fields:c.fields.map(R=>{let b=V(r,l,R.id),k=R.conditions?Y(R.conditions,r,l,s):void 0;return {...R,id:b,conditions:k}})}));return {key:l,index:d,rows:g,allFields:F}}):[],[r,i,o,s]),n=Ot.useMemo(()=>o?o.max===void 0?true:i.length<o.max:false,[o,i.length]),u=Ot.useMemo(()=>{if(!o)return false;let l=o.min??0;return i.length>l},[o,i.length]),p=Ot.useCallback(l=>{e.getState()._appendRepeatableItem(r,l);},[e,r]),f=Ot.useCallback(l=>{e.getState()._removeRepeatableItem(r,l);},[e,r]),m=Ot.useCallback((l,d)=>{e.getState()._moveRepeatableItem(r,l,d);},[e,r]);return {items:a,append:p,remove:f,move:m,canAdd:n,canRemove:u,count:i.length}}function xt({formConfig:r,enabled:e=true}){let t=core.getGlobalMonitor(),i=Ot.useRef(null),o=Ot.useRef(0),s=Ot.useRef(0);Ot.useEffect(()=>{t&&e&&(i.current=t.getProfiler());},[t,e]);let a=Ot.useCallback(l=>{if(!t||!e)return;o.current++;let d={formId:r.id,fieldCount:r.allFields.length,timestamp:Date.now(),duration:0,renderDuration:0,validationDuration:0,validationErrors:0,renderCount:l||o.current};t.track("component_render",`form_${r.id}`,{formId:r.id,fieldCount:r.allFields.length,renderCount:o.current},d,"low");},[t,e,r.id,r.allFields.length]),n=Ot.useCallback((l,d)=>{if(!t||!e)return;let F=i.current?.getMetrics(`form_validation_${r.id}`),g={formId:r.id,fieldCount:d||r.allFields.length,timestamp:Date.now(),duration:F?.duration||0,renderDuration:0,validationDuration:F?.duration||0,validationErrors:l,renderCount:o.current};t.track("form_validation",`form_${r.id}`,{formId:r.id,validationErrors:l,fieldCount:d||r.allFields.length},g,l>0?"medium":"low");},[t,e,r.id,r.allFields.length]),u=Ot.useCallback((l,d)=>{if(!t||!e)return;let F=i.current?.getMetrics(`form_submission_${r.id}`),g={formId:r.id,fieldCount:d||r.allFields.length,timestamp:Date.now(),duration:F?.duration||0,renderDuration:0,validationDuration:0,validationErrors:l?0:1,renderCount:o.current};t.track("form_submission",`form_${r.id}`,{formId:r.id,success:l,fieldCount:d||r.allFields.length,fieldChanges:s.current},g,l?"low":"high");},[t,e,r.id,r.allFields.length]),p=Ot.useCallback((l,d)=>{!t||!e||(s.current++,t.track("component_update",`field_${l}`,{formId:r.id,fieldId:l,componentType:d,changeCount:s.current},void 0,"low"));},[t,e,r.id]),f=Ot.useCallback(l=>{!i.current||!e||i.current.start(l,{formId:r.id,renderCount:o.current});},[e,r.id]),m=Ot.useCallback(l=>{if(!i.current||!e)return null;let d=i.current.end(l);return d?{...d,formId:r.id,fieldCount:r.allFields.length,renderDuration:d.duration,validationDuration:0,validationErrors:0}:null},[e,r.id,r.allFields.length]);return {trackFormRender:a,trackFormValidation:n,trackFormSubmission:u,trackFieldChange:p,startPerformanceTracking:f,endPerformanceTracking:m}}var Ye=Ot.createContext(null);function E(){let r=Ot.useContext(Ye);if(!r)throw new Error("useFormConfigContext must be used within a FormProvider");return r}function xe({children:r,formConfig:e,defaultValues:t={},onSubmit:i,onFieldChange:o,className:s}){let[a]=Ot.useState(()=>{let _=e.repeatableFields??{},C={...t},h={},y={};if(Object.keys(_).some(v=>Array.isArray(t[v]))){let v=re(t,_);C=v.values,h=v.order,y=v.nextKeys;}for(let[v,B]of Object.entries(_))if(!h[v]){let Z=B.min??0,K=[],U=y[v]??0;for(let N=0;N<Z;N++){let W=`k${U}`;K.push(W);for(let ee of B.allFields){let tt=V(v,W,ee.id);C[tt]=B.defaultValue?.[ee.id]??void 0;}U++;}h[v]=K,y[v]=U;}let M=ue(C),x=M.getState();for(let[v,B]of Object.entries(_))x._setRepeatableConfig(v,B);return M.setState({_repeatableOrder:h,_repeatableNextKey:y}),M}),n=Ot.useRef(e.id),u=Ot.useRef(o);u.current=o,Ot.useEffect(()=>u.current?a.subscribe(C=>C.values,(C,h)=>{for(let y of Object.keys(C))C[y]!==h[y]&&u.current?.(y,C[y],C);}):void 0,[a]),Ot.useEffect(()=>{if(n.current!==e.id){n.current=e.id;let _=e.repeatableFields??{},C={...t},h={},y={};if(Object.keys(_).some(x=>Array.isArray(t[x]))){let x=re(t,_);C=x.values,h=x.order,y=x.nextKeys;}for(let[x,v]of Object.entries(_))if(!h[x]){let B=v.min??0,Z=[],K=y[x]??0;for(let U=0;U<B;U++){let N=`k${K}`;Z.push(N);for(let W of v.allFields){let ee=V(x,N,W.id);C[ee]=v.defaultValue?.[W.id]??void 0;}K++;}h[x]=Z,y[x]=K;}a.getState()._reset(C);let M=a.getState();for(let[x,v]of Object.entries(_))M._setRepeatableConfig(x,v);a.setState({_repeatableOrder:h,_repeatableNextKey:y});}},[e.id,e.repeatableFields,a,t]);let[p,f]=Ot.useState(()=>a.getState().values);Ot.useEffect(()=>a.subscribe(C=>C.values,C=>f(C)),[a]);let[m,l]=Ot.useState(()=>a.getState()._repeatableOrder);Ot.useEffect(()=>a.subscribe(C=>C._repeatableOrder,C=>l(C)),[a]);let{fieldConditions:d,hasConditionalFields:F,getFieldCondition:g,isFieldVisible:c,isFieldDisabled:R,isFieldRequired:b,isFieldReadonly:k}=Ue({formConfig:e,formValues:p,repeatableOrder:m});Ot.useEffect(()=>{for(let[_,C]of Object.entries(d)){let h={visible:C.visible,disabled:C.disabled,required:C.required,readonly:C.readonly};a.getState()._setFieldConditions(_,h);}},[d,a]);let O=Ot.useMemo(()=>({hasConditionalFields:F,getFieldCondition:g,isFieldVisible:c,isFieldDisabled:R,isFieldRequired:b,isFieldReadonly:k}),[F,g,c,R,b,k]),{validateField:P,validateForm:D}=Le({formConfig:e,store:a,conditionsHelpers:O}),{submit:q}=$e({store:a,onSubmit:i,validateForm:D}),X=Ot.useMemo(()=>({formConfig:e,conditionsHelpers:O,validateField:P,validateForm:D,submit:q}),[e,O,P,D,q]);return jsxRuntime.jsx(oe.Provider,{value:a,children:jsxRuntime.jsx(Ye.Provider,{value:X,children:jsxRuntime.jsx("form",{onSubmit:q,className:s,noValidate:true,children:r})})})}function Et({formConfig:r,defaultValues:e,onSubmit:t,onFieldChange:i,className:o,children:s}){let a=Ot.useMemo(()=>r instanceof T?r.build():r,[r]);return jsxRuntime.jsx(xe,{formConfig:a,defaultValues:e,onSubmit:t,onFieldChange:i,className:o,children:s})}var Q=Ot__default.default.memo(function({fieldId:e,fieldConfig:t,disabled:i=false,customProps:o={},className:s,forceVisible:a=false}){let{formConfig:n,validateField:u,conditionsHelpers:p}=E(),f=ce(e),m=me(e),l=$(e),{setValue:d,setTouched:F}=Fe(e),g=Ot.useMemo(()=>{if(t)return t;let h=n.allFields.find(A=>A.id===e);if(h)return h;let y=L(e);if(y&&n.repeatableFields){let A=n.repeatableFields[y.repeatableId];if(A){let M=A.allFields.find(x=>x.id===y.fieldId);if(M)return {...M,id:e}}}},[t,n.allFields,n.repeatableFields,e]);if(!g)throw new Error(`Field with ID "${e}" not found`);let c=n.config.getComponent(g.componentId);if(!c)throw new Error(`Component with ID "${g.componentId}" not found`);let R=m.validationState==="validating",b=Ot.useMemo(()=>({isVisible:a||l.visible,isFieldDisabled:i||l.disabled,isFieldRequired:l.required||p.isFieldRequired(e),isFieldReadonly:l.readonly}),[a,i,l,p,e]),k=Ot.useCallback(async h=>{d(h),(g.validation?.validateOnChange||m.touched)&&await u(e,h);},[e,d,u,g.validation?.validateOnChange,m.touched]),O=Ot.useCallback(async()=>{m.touched||F(),g.validation?.validateOnBlur!==false&&await u(e);},[e,m.touched,F,u,g.validation?.validateOnBlur]),P=Ot.useMemo(()=>({...c.defaultProps??{},...g.props,...o,disabled:b.isFieldDisabled,required:b.isFieldRequired,readOnly:b.isFieldReadonly}),[c.defaultProps,g.props,o,b.isFieldDisabled,b.isFieldRequired,b.isFieldReadonly]),D=Ot.useMemo(()=>({id:e,props:P,value:f,onChange:k,onBlur:O,disabled:b.isFieldDisabled,error:m.errors,isValidating:R,touched:m.touched}),[e,P,f,k,O,b.isFieldDisabled,m.errors,R,m.touched]);if(!b.isVisible)return null;let q=c.renderer(D),X=n.renderConfig?.fieldRenderer,_=c.useFieldRenderer!==false,C=X&&_?X({children:q,id:e,...P,error:m.errors,isValidating:R,touched:m.touched}):q;return jsxRuntime.jsx("div",{className:s,"data-field-id":e,"data-field-type":c.type,"data-field-visible":b.isVisible,"data-field-disabled":b.isFieldDisabled,"data-field-required":b.isFieldRequired,"data-field-readonly":b.isFieldReadonly,children:C})});var Qe=Ot__default.default.memo(function({row:e,className:t,...i}){let{formConfig:o,conditionsHelpers:s}=E(),a=Ot.useMemo(()=>e.fields.filter(p=>s.isFieldVisible(p.id)),[e.fields,s]),n=Ot.useMemo(()=>a.map(p=>jsxRuntime.jsx(Q,{fieldId:p.id},p.id)),[a]),u=Ot.useMemo(()=>({row:e,children:n,className:t}),[e,n,t]);return a.length===0?null:jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormRow",renderer:o.renderConfig?.rowRenderer,props:u,...i,children:n})}),le=Qe;var ke=Ot__default.default.memo(function({item:e,index:t,total:i,canRemove:o,canMoveUp:s,canMoveDown:a,onRemove:n,onMoveUp:u,onMoveDown:p}){let{formConfig:f}=E(),m=Ot.useMemo(()=>new Map(e.allFields.map(F=>[F.id,F])),[e.allFields]),l=Ot.useMemo(()=>e.rows.map(F=>jsxRuntime.jsx(le,{row:F,children:F.fields.map(g=>jsxRuntime.jsx(Q,{fieldId:g.id,fieldConfig:m.get(g.id)},g.id))},F.id)),[e.rows,m]),d=f.renderConfig?.repeatableItemRenderer;return d?d({item:e,index:t,total:i,canRemove:o,canMoveUp:s,canMoveDown:a,onRemove:n,onMoveUp:u,onMoveDown:p,children:l}):jsxRuntime.jsx("div",{"data-repeatable-item":e.key,"data-repeatable-index":t,children:l})});var Ee=Ot__default.default.memo(function({repeatableId:e,repeatableConfig:t,className:i}){let{formConfig:o}=E(),{items:s,append:a,remove:n,move:u,canAdd:p,canRemove:f}=ve(e),m=Ot.useMemo(()=>s.map((d,F)=>jsxRuntime.jsx(ke,{item:d,index:F,total:s.length,canRemove:f,canMoveUp:F>0,canMoveDown:F<s.length-1,onRemove:()=>n(d.key),onMoveUp:()=>u(F,F-1),onMoveDown:()=>u(F,F+1)},d.key)),[s,f,n,u]),l=o.renderConfig?.repeatableRenderer;return l?l({repeatableId:e,items:s,canAdd:p,canRemove:f,onAdd:()=>a(),min:t.min,max:t.max,children:m}):jsxRuntime.jsxs("div",{className:i,"data-repeatable-id":e,children:[m,p&&jsxRuntime.jsx("button",{type:"button",onClick:()=>a(),"data-repeatable-add":e,children:"Add"})]})});var It=Ot__default.default.memo(function({className:e,...t}){let{formConfig:i}=E(),o=Ot.useMemo(()=>i.rows.map(a=>a.kind==="repeatable"?jsxRuntime.jsx(Ee,{repeatableId:a.repeatable.id,repeatableConfig:a.repeatable},a.id):jsxRuntime.jsx(le,{row:a},a.id)),[i.rows]),s=Ot.useMemo(()=>({formConfig:i,children:o,className:e}),[i,o,e]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormBody",renderer:i.renderConfig?.bodyRenderer,props:s,...t,children:o})});var Lt=Ot__default.default.memo(function({className:e,isSubmitting:t,...i}){let{formConfig:o,submit:s}=E(),{isSubmitting:a}=fe(),n=Ot.useMemo(()=>({isSubmitting:t??a,onSubmit:s,className:e}),[t,a,s,e]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormSubmitButton",renderer:o.renderConfig?.submitButtonRenderer,props:n,...i})});exports.Form=Et;exports.FormBody=It;exports.FormBuilder=T;exports.FormField=Q;exports.FormProvider=xe;exports.FormRow=Qe;exports.FormStoreContext=oe;exports.FormSubmitButton=Lt;exports.RepeatableBuilder=j;exports.RepeatableField=Ee;exports.RepeatableItem=ke;exports.createFormStore=ue;exports.flattenRepeatableValues=re;exports.form=T;exports.structureFormValues=de;exports.useConditionEvaluation=er;exports.useConditionEvaluator=pr;exports.useFieldActions=Fe;exports.useFieldConditions=$;exports.useFieldConditionsLazy=fr;exports.useFieldConditionsWithRefresh=Fr;exports.useFieldErrors=dt;exports.useFieldState=me;exports.useFieldTouched=ut;exports.useFieldValidationState=ct;exports.useFieldValue=ce;exports.useFormActions=Ct;exports.useFormConditions=Ue;exports.useFormConfigContext=E;exports.useFormDirty=Ft;exports.useFormMonitoring=xt;exports.useFormStore=S;exports.useFormStoreApi=H;exports.useFormSubmissionWithStore=$e;exports.useFormSubmitState=fe;exports.useFormSubmitting=ft;exports.useFormValid=pt;exports.useFormValidationWithStore=Le;exports.useFormValues=gt;exports.useMultipleConditionEvaluation=Te;exports.useRepeatableField=ve;exports.useRepeatableKeys=pe;

@@ -1,1 +0,1 @@

import Xe,{createContext,useMemo,useCallback,useContext,useRef,useEffect,useState}from'react';import {ComponentRendererWrapper,IdGenerator,deepClone,ensureUnique,hasUnifiedValidation,createValidationContext,validateWithUnifiedConfig,validateFormWithUnifiedConfig,getGlobalMonitor,evaluateCondition}from'@rilaykit/core';import {useStore,createStore}from'zustand';import {subscribeWithSelector}from'zustand/middleware';import {jsx}from'react/jsx-runtime';var x=class o{constructor(e,t){this.rows=[];this.idGenerator=new IdGenerator;this.config=e,this.formId=t||`form-${Math.random().toString(36).substring(2,15)}`;}static create(e,t){return new o(e,t)}createFormField(e){let t=this.config.getComponent(e.type);if(!t)throw new Error(`No component found with type "${e.type}"`);let i;return (t.validation||e.validation)&&(i={validateOnChange:e.validation?.validateOnChange??t.validation?.validateOnChange,validateOnBlur:e.validation?.validateOnBlur??t.validation?.validateOnBlur,debounceMs:e.validation?.debounceMs??t.validation?.debounceMs,validate:(()=>{let r=t.validation?.validate,n=e.validation?.validate;if(!r)return n;if(!n)return r;let a=Array.isArray(r)?r:[r],s=Array.isArray(n)?n:[n];return [...a,...s]})()}),{id:e.id||this.idGenerator.next("field"),componentId:t.id,props:{...t.defaultProps,...e.props},validation:i,conditions:e.conditions}}createRow(e){if(e.length===0)throw new Error("At least one field is required");if(e.length>3)throw new Error("Maximum 3 fields per row");let t=e.map(i=>this.createFormField(i));return {id:this.idGenerator.next("row"),fields:t,maxColumns:e.length}}add(...e){let t,i=false;if(e.length===1&&Array.isArray(e[0])?(t=e[0],i=true):t=e,t.length===0)throw new Error("At least one field is required");if(i&&t.length>3)throw new Error("Maximum 3 fields per row");if(t.length===1){let r=this.createRow(t);return this.rows.push(r),this}if(t.length<=3){let r=this.createRow(t);return this.rows.push(r),this}for(let r of t){let n=this.createRow([r]);this.rows.push(n);}return this}addSeparateRows(e){for(let t of e)this.add(t);return this}setId(e){return this.formId=e,this}updateField(e,t){let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);return Object.assign(i,{...t,props:{...i.props,...t.props}}),this}findField(e){for(let t of this.rows){let i=t.fields.find(r=>r.id===e);if(i)return i}return null}removeField(e){return this.rows=this.rows.map(t=>({...t,fields:t.fields.filter(i=>i.id!==e)})).filter(t=>t.fields.length>0),this}getField(e){return this.findField(e)||void 0}getFields(){return this.rows.flatMap(e=>e.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.idGenerator.reset(),this}setValidation(e){return this.formValidation=e,this}addFieldValidation(e,t){console.warn("addFieldValidation is deprecated. Use updateField with validation.validate property instead.");let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);let r={...i.validation,...t};return this.updateField(e,{validation:r})}addFieldConditions(e,t){let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);let r={...i.conditions,...t};return this.updateField(e,{conditions:r})}clone(e){let t=new o(this.config,e||`${this.formId}-clone`);return t.rows=deepClone(this.rows),t}validate(){let e=[],t=this.getFields(),i=t.map(r=>r.id);try{ensureUnique(i,"field");}catch(r){e.push(r instanceof Error?r.message:String(r));}for(let r of t)this.config.hasComponent(r.componentId)||e.push(`Component "${r.componentId}" not found for field "${r.id}"`);for(let r of this.rows)r.fields.length>3&&e.push(`Row "${r.id}" has ${r.fields.length} fields, maximum is 3`),r.fields.length===0&&e.push(`Row "${r.id}" is empty`);return e}build(){let e=this.validate();if(e.length>0)throw new Error(`Form validation failed: ${e.join(", ")}`);return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),config:this.config,renderConfig:this.config.getFormRenderConfig(),validation:this.formValidation}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(e){return e.id&&(this.formId=e.id),e.rows&&(this.rows=e.rows),this}getStats(){let e=this.getFields(),t=this.rows.map(i=>i.fields.length);return {totalFields:e.length,totalRows:this.rows.length,averageFieldsPerRow:this.rows.length>0?e.length/this.rows.length:0,maxFieldsInRow:t.length>0?Math.max(...t):0,minFieldsInRow:t.length>0?Math.min(...t):0}}};function Ft(o,e={},t={}){return useMemo(()=>{if(!o)return {visible:t.visible??true,disabled:t.disabled??false,required:t.required??false,readonly:t.readonly??false};let i=r=>{try{return r&&typeof r=="object"&&"build"in r?evaluateCondition(r.build(),e):evaluateCondition(r,e)}catch(n){return console.warn("Error evaluating condition:",n),false}};return {visible:o.visible?i(o.visible):t.visible??true,disabled:o.disabled?i(o.disabled):t.disabled??false,required:o.required?i(o.required):t.required??false,readonly:o.readonly?i(o.readonly):t.readonly??false}},[o,e,t])}function oe(o,e={}){return useMemo(()=>{let t={};for(let[i,r]of Object.entries(o))if(t[i]={visible:true,disabled:false,required:false,readonly:false},r){let n=a=>{try{return a&&typeof a=="object"&&"build"in a?evaluateCondition(a.build(),e):evaluateCondition(a,e)}catch(s){return console.warn(`Error evaluating condition for field ${i}:`,s),false}};t[i]={visible:r.visible?n(r.visible):true,disabled:r.disabled?n(r.disabled):false,required:r.required?n(r.required):false,readonly:r.readonly?n(r.readonly):false};}return t},[o,e])}function $(o={}){return createStore()(subscribeWithSelector((e,t)=>({values:{...o},errors:{},validationStates:{},touched:{},isDirty:false,isSubmitting:false,isValid:true,_defaultValues:{...o},_fieldConditions:{},_setValue:(i,r)=>{e(n=>({values:{...n.values,[i]:r},isDirty:true}));},_setTouched:i=>{e(r=>({touched:{...r.touched,[i]:true}}));},_setErrors:(i,r)=>{e(n=>{let a={...n.errors,[i]:r},s=r.length>0?"invalid":"valid";return {errors:a,validationStates:{...n.validationStates,[i]:s}}}),t()._updateIsValid();},_clearErrors:i=>{e(r=>{let n={...r.errors};return delete n[i],{errors:n,validationStates:{...r.validationStates,[i]:"idle"}}}),t()._updateIsValid();},_setValidationState:(i,r)=>{e(n=>({validationStates:{...n.validationStates,[i]:r}}));},_setSubmitting:i=>{e({isSubmitting:i});},_reset:i=>{let r=i??t()._defaultValues;e({values:{...r},errors:{},validationStates:{},touched:{},isDirty:false,isSubmitting:false,isValid:true});},_setFieldConditions:(i,r)=>{e(n=>({_fieldConditions:{...n._fieldConditions,[i]:r}}));},_updateIsValid:()=>{let i=t(),r=Object.values(i.errors).some(a=>a&&a.length>0),n=Object.values(i.validationStates).some(a=>a==="invalid");e({isValid:!r&&!n});}})))}var O=createContext(null);function v(){let o=useContext(O);if(!o)throw new Error("useFormStore must be used within a FormProvider");return o}var re=[];function N(o){let e=v();return useStore(e,t=>t.values[o])}function Me(o){let e=v();return useStore(e,t=>t.errors[o]??re)}function Be(o){let e=v();return useStore(e,t=>t.touched[o]??false)}function Te(o){let e=v();return useStore(e,t=>t.validationStates[o]??"idle")}var De={visible:true,disabled:false,required:false,readonly:false};function P(o){let e=v();return useStore(e,t=>t._fieldConditions[o]??De)}function W(o){let e=v(),t=useStore(e,s=>s.values[o]),i=useStore(e,s=>s.errors[o]??re),r=useStore(e,s=>s.validationStates[o]??"idle"),n=useStore(e,s=>s.touched[o]??false),a=useStore(e,s=>s._defaultValues[o]);return {value:t,errors:i,validationState:r,touched:n,dirty:t!==a}}function qe(){let o=v();return useStore(o,e=>e.isSubmitting)}function Oe(){let o=v();return useStore(o,e=>e.isValid)}function Ue(){let o=v();return useStore(o,e=>e.isDirty)}function Ae(){let o=v();return useStore(o,e=>e.values)}function H(){let o=v(),e=useStore(o,r=>r.isSubmitting),t=useStore(o,r=>r.isValid),i=useStore(o,r=>r.isDirty);return {isSubmitting:e,isValid:t,isDirty:i}}function L(o){let e=v();return {setValue:t=>e.getState()._setValue(o,t),setTouched:()=>e.getState()._setTouched(o),setErrors:t=>e.getState()._setErrors(o,t),clearErrors:()=>e.getState()._clearErrors(o),setValidationState:t=>e.getState()._setValidationState(o,t)}}function Ie(){let o=v();return {setValue:(e,t)=>o.getState()._setValue(e,t),setTouched:e=>o.getState()._setTouched(e),setErrors:(e,t)=>o.getState()._setErrors(e,t),setSubmitting:e=>o.getState()._setSubmitting(e),reset:e=>o.getState()._reset(e),setFieldConditions:(e,t)=>o.getState()._setFieldConditions(e,t)}}function B(){return v()}var se={visible:true,disabled:false,required:false,readonly:false};function ae(o){try{return JSON.stringify(o)}catch{return String(Date.now())}}function U(o,e){if(o)try{return typeof o=="object"&&"build"in o?evaluateCondition(o.build(),e):evaluateCondition(o,e)}catch(t){console.warn("Error evaluating condition:",t);return}}function j(o,e){if(!o)return se;let t=U(o.visible,e),i=U(o.disabled,e),r=U(o.required,e),n=U(o.readonly,e);return {visible:t??true,disabled:i??false,required:r??false,readonly:n??false}}function Vt(o,e={}){let{conditions:t,skip:i=false}=e,r=B(),n=P(o),a=useRef(null);if(i||!t)return n;let s=r.getState().values,F=ae(s);if(a.current?.valuesHash===F)return a.current.result;let m=j(t,s);return a.current={result:m,valuesHash:F},m}function xt(){let o=B(),e=useRef(new Map),t=useRef("");return useMemo(()=>function(r,n){if(!n)return se;let a=o.getState().values,s=ae(a);t.current!==s&&(e.current.clear(),t.current=s);let F=e.current.get(r);if(F)return F.result;let m=j(n,a);return e.current.set(r,{result:m,valuesHash:s}),m},[o])}function Pt(o,e){let t=B(),i=P(o),r=useMemo(()=>()=>{if(!e)return i;let n=t.getState().values;return j(e,n)},[t,e,i]);return {conditions:i,refresh:r}}function de({formConfig:o,formValues:e}){let t=useMemo(()=>{let l={};for(let u of o.allFields)u.conditions&&(l[u.id]=u.conditions);return l},[o.allFields]),i=useMemo(()=>Object.keys(t).length>0,[t]),r=oe(i?t:{},i?e:{}),n=useCallback(l=>r[l],[r]),a=useCallback(l=>{let u=r[l];return u?u.visible:true},[r]),s=useCallback(l=>{let u=r[l];return u?u.disabled:false},[r]),F=useCallback(l=>{let u=r[l];return u?u.required:false},[r]),m=useCallback(l=>{let u=r[l];return u?u.readonly:false},[r]);return useMemo(()=>({fieldConditions:r,hasConditionalFields:i,getFieldCondition:n,isFieldVisible:a,isFieldDisabled:s,isFieldRequired:F,isFieldReadonly:m}),[r,i,n,a,s,F,m])}function le({store:o,onSubmit:e,validateForm:t}){let i=useRef(e);return i.current=e,{submit:useCallback(async n=>{n?.preventDefault();let a=o.getState();if(a.isSubmitting)return false;a._setSubmitting(true);try{if(!(await t()).isValid)return a._setSubmitting(!1),!1;let F=o.getState().values;return i.current&&await i.current(F),a._setSubmitting(!1),!0}catch(s){return a._setSubmitting(false),console.error("Form submission error:",s),false}},[o,t])}}function A(){return {isValid:true,errors:[]}}function fe({formConfig:o,store:e,conditionsHelpers:t}){let i=useRef(o),r=useRef(t);i.current=o,r.current=t;let n=useCallback(async(s,F)=>{let m=i.current.allFields.find(d=>d.id===s),l=e.getState();if(!m)return A();if(!r.current.isFieldVisible(s))return l._setErrors(s,[]),l._setValidationState(s,"valid"),A();if(!m.validation||!hasUnifiedValidation(m.validation))return l._setErrors(s,[]),l._setValidationState(s,"valid"),A();let u=F!==void 0?F:l.values[s],c=createValidationContext({fieldId:s,formId:i.current.id,allFormData:{...l.values,[s]:u}});l._setValidationState(s,"validating");try{let d=await validateWithUnifiedConfig(m.validation,u,c),f=r.current.isFieldRequired(s),p=u==null||u==="";if(f&&p&&!d.errors.some(g=>g.code==="REQUIRED"||g.message.toLowerCase().includes("required"))){let g={isValid:!1,errors:[{message:"This field is required",code:"CONDITIONAL_REQUIRED"},...d.errors]};return l._setErrors(s,g.errors),l._setValidationState(s,"invalid"),g}return l._setErrors(s,d.errors),l._setValidationState(s,d.isValid?"valid":"invalid"),d}catch(d){let f={isValid:false,errors:[{message:d instanceof Error?d.message:"Validation failed",code:"VALIDATION_ERROR"}]};return l._setErrors(s,f.errors),l._setValidationState(s,"invalid"),f}},[e]),a=useCallback(async()=>{let s=e.getState(),F=i.current.allFields.filter(d=>{let f=r.current.isFieldVisible(d.id),p=d.validation&&hasUnifiedValidation(d.validation);return f&&p}),m=i.current.allFields.filter(d=>!r.current.isFieldVisible(d.id));for(let d of m)s._setErrors(d.id,[]),s._setValidationState(d.id,"valid");let l=await Promise.all(F.map(d=>n(d.id))),u=l.some(d=>!d.isValid),c=A();if(i.current.validation&&hasUnifiedValidation(i.current.validation)){let d=Object.keys(s.values).reduce((p,b)=>(r.current.isFieldVisible(b)&&(p[b]=s.values[b]),p),{}),f=createValidationContext({formId:i.current.id,allFormData:d});try{c=await validateFormWithUnifiedConfig(i.current.validation,d,f);}catch(p){c={isValid:false,errors:[{message:p instanceof Error?p.message:"Form validation failed",code:"FORM_VALIDATION_ERROR"}]};}}return {isValid:!u&&c.isValid,errors:[...l.flatMap(d=>d.errors),...c.errors]}},[e,n]);return {validateField:n,validateForm:a}}function je({formConfig:o,enabled:e=true}){let t=getGlobalMonitor(),i=useRef(null),r=useRef(0),n=useRef(0);useEffect(()=>{t&&e&&(i.current=t.getProfiler());},[t,e]);let a=useCallback(c=>{if(!t||!e)return;r.current++;let d={formId:o.id,fieldCount:o.allFields.length,timestamp:Date.now(),duration:0,renderDuration:0,validationDuration:0,validationErrors:0,renderCount:c||r.current};t.track("component_render",`form_${o.id}`,{formId:o.id,fieldCount:o.allFields.length,renderCount:r.current},d,"low");},[t,e,o.id,o.allFields.length]),s=useCallback((c,d)=>{if(!t||!e)return;let f=i.current?.getMetrics(`form_validation_${o.id}`),p={formId:o.id,fieldCount:d||o.allFields.length,timestamp:Date.now(),duration:f?.duration||0,renderDuration:0,validationDuration:f?.duration||0,validationErrors:c,renderCount:r.current};t.track("form_validation",`form_${o.id}`,{formId:o.id,validationErrors:c,fieldCount:d||o.allFields.length},p,c>0?"medium":"low");},[t,e,o.id,o.allFields.length]),F=useCallback((c,d)=>{if(!t||!e)return;let f=i.current?.getMetrics(`form_submission_${o.id}`),p={formId:o.id,fieldCount:d||o.allFields.length,timestamp:Date.now(),duration:f?.duration||0,renderDuration:0,validationDuration:0,validationErrors:c?0:1,renderCount:r.current};t.track("form_submission",`form_${o.id}`,{formId:o.id,success:c,fieldCount:d||o.allFields.length,fieldChanges:n.current},p,c?"low":"high");},[t,e,o.id,o.allFields.length]),m=useCallback((c,d)=>{!t||!e||(n.current++,t.track("component_update",`field_${c}`,{formId:o.id,fieldId:c,componentType:d,changeCount:n.current},void 0,"low"));},[t,e,o.id]),l=useCallback(c=>{!i.current||!e||i.current.start(c,{formId:o.id,renderCount:r.current});},[e,o.id]),u=useCallback(c=>{if(!i.current||!e)return null;let d=i.current.end(c);return d?{...d,formId:o.id,fieldCount:o.allFields.length,renderDuration:d.duration,validationDuration:0,validationErrors:0}:null},[e,o.id,o.allFields.length]);return {trackFormRender:a,trackFormValidation:s,trackFormSubmission:F,trackFieldChange:m,startPerformanceTracking:l,endPerformanceTracking:u}}var Ce=createContext(null);function y(){let o=useContext(Ce);if(!o)throw new Error("useFormConfigContext must be used within a FormProvider");return o}function K({children:o,formConfig:e,defaultValues:t={},onSubmit:i,onFieldChange:r,className:n}){let[a]=useState(()=>$(t)),s=useRef(e.id),F=useRef(r);F.current=r,useEffect(()=>F.current?a.subscribe(C=>C.values,(C,M)=>{for(let R of Object.keys(C))C[R]!==M[R]&&F.current?.(R,C[R],C);}):void 0,[a]),useEffect(()=>{s.current!==e.id&&(s.current=e.id,a.getState()._reset(t));},[e.id,a,t]);let[m,l]=useState(()=>a.getState().values);useEffect(()=>a.subscribe(C=>C.values,C=>l(C)),[a]);let{fieldConditions:u,hasConditionalFields:c,getFieldCondition:d,isFieldVisible:f,isFieldDisabled:p,isFieldRequired:b,isFieldReadonly:g}=de({formConfig:e,formValues:m});useEffect(()=>{for(let[V,C]of Object.entries(u)){let M={visible:C.visible,disabled:C.disabled,required:C.required,readonly:C.readonly};a.getState()._setFieldConditions(V,M);}},[u,a]);let w=useMemo(()=>({hasConditionalFields:c,getFieldCondition:d,isFieldVisible:f,isFieldDisabled:p,isFieldRequired:b,isFieldReadonly:g}),[c,d,f,p,b,g]),{validateField:_,validateForm:S}=fe({formConfig:e,store:a,conditionsHelpers:w}),{submit:k}=le({store:a,onSubmit:i,validateForm:S}),D=useMemo(()=>({formConfig:e,conditionsHelpers:w,validateField:_,validateForm:S,submit:k}),[e,w,_,S,k]);return jsx(O.Provider,{value:a,children:jsx(Ce.Provider,{value:D,children:jsx("form",{onSubmit:k,className:n,noValidate:true,children:o})})})}function Ye({formConfig:o,defaultValues:e,onSubmit:t,onFieldChange:i,children:r}){let n=useMemo(()=>o instanceof x?o.build():o,[o]);return jsx(K,{formConfig:n,defaultValues:e,onSubmit:t,onFieldChange:i,children:r})}var Z=Xe.memo(function({fieldId:e,disabled:t=false,customProps:i={},className:r,forceVisible:n=false}){let{formConfig:a,validateField:s,conditionsHelpers:F}=y(),m=N(e),l=W(e),u=P(e),{setValue:c,setTouched:d}=L(e),f=a.allFields.find(R=>R.id===e);if(!f)throw new Error(`Field with ID "${e}" not found`);let p=a.config.getComponent(f.componentId);if(!p)throw new Error(`Component with ID "${f.componentId}" not found`);let b=l.validationState==="validating",g=useMemo(()=>({isVisible:n||u.visible,isFieldDisabled:t||u.disabled,isFieldRequired:u.required||F.isFieldRequired(e),isFieldReadonly:u.readonly}),[n,t,u,F,e]),w=useCallback(async R=>{c(R),(f.validation?.validateOnChange||l.touched)&&await s(e,R);},[e,c,s,f.validation?.validateOnChange,l.touched]),_=useCallback(async()=>{l.touched||d(),f.validation?.validateOnBlur!==false&&await s(e);},[e,l.touched,d,s,f.validation?.validateOnBlur]),S=useMemo(()=>({...p.defaultProps??{},...f.props,...i,disabled:g.isFieldDisabled,required:g.isFieldRequired,readOnly:g.isFieldReadonly}),[p.defaultProps,f.props,i,g.isFieldDisabled,g.isFieldRequired,g.isFieldReadonly]),k=useMemo(()=>({id:e,props:S,value:m,onChange:w,onBlur:_,disabled:g.isFieldDisabled,error:l.errors,isValidating:b,touched:l.touched}),[e,S,m,w,_,g.isFieldDisabled,l.errors,b,l.touched]);if(!g.isVisible)return null;let D=p.renderer(k),V=a.renderConfig?.fieldRenderer,C=p.useFieldRenderer!==false,M=V&&C?V({children:D,id:e,...S,error:l.errors,isValidating:b,touched:l.touched}):D;return jsx("div",{className:r,"data-field-id":e,"data-field-type":p.type,"data-field-visible":g.isVisible,"data-field-disabled":g.isFieldDisabled,"data-field-required":g.isFieldRequired,"data-field-readonly":g.isFieldReadonly,children:M})});var be=Xe.memo(function({row:e,className:t,...i}){let{formConfig:r,conditionsHelpers:n}=y(),a=useMemo(()=>e.fields.filter(m=>n.isFieldVisible(m.id)),[e.fields,n]),s=useMemo(()=>a.map(m=>jsx(Z,{fieldId:m.id},m.id)),[a]),F=useMemo(()=>({row:e,children:s,className:t}),[e,s,t]);return a.length===0?null:jsx(ComponentRendererWrapper,{name:"FormRow",renderer:r.renderConfig?.rowRenderer,props:F,...i,children:s})}),Re=be;var it=Xe.memo(function({className:e,...t}){let{formConfig:i}=y(),r=useMemo(()=>i.rows.map(a=>jsx(Re,{row:a},a.id)),[i.rows]),n=useMemo(()=>({formConfig:i,children:r,className:e}),[i,r,e]);return jsx(ComponentRendererWrapper,{name:"FormBody",renderer:i.renderConfig?.bodyRenderer,props:n,...t,children:r})});var dt=Xe.memo(function({className:e,isSubmitting:t,...i}){let{formConfig:r,submit:n}=y(),{isSubmitting:a}=H(),s=useMemo(()=>({isSubmitting:t??a,onSubmit:n,className:e}),[t,a,n,e]);return jsx(ComponentRendererWrapper,{name:"FormSubmitButton",renderer:r.renderConfig?.submitButtonRenderer,props:s,...i})});export{Ye as Form,it as FormBody,x as FormBuilder,Z as FormField,K as FormProvider,be as FormRow,O as FormStoreContext,dt as FormSubmitButton,$ as createFormStore,x as form,Ft as useConditionEvaluation,xt as useConditionEvaluator,L as useFieldActions,P as useFieldConditions,Vt as useFieldConditionsLazy,Pt as useFieldConditionsWithRefresh,Me as useFieldErrors,W as useFieldState,Be as useFieldTouched,Te as useFieldValidationState,N as useFieldValue,Ie as useFormActions,de as useFormConditions,y as useFormConfigContext,Ue as useFormDirty,je as useFormMonitoring,v as useFormStore,B as useFormStoreApi,le as useFormSubmissionWithStore,H as useFormSubmitState,qe as useFormSubmitting,Oe as useFormValid,fe as useFormValidationWithStore,Ae as useFormValues,oe as useMultipleConditionEvaluation};
import Ot,{createContext,useMemo,useCallback,useContext,useRef,useEffect,useState}from'react';import {ComponentRendererWrapper,IdGenerator,deepClone,ensureUnique,hasUnifiedValidation,isEmptyValue,createValidationContext,validateWithUnifiedConfig,validateFormWithUnifiedConfig,getGlobalMonitor,evaluateCondition}from'@rilaykit/core';import {useStore,createStore}from'zustand';import {subscribeWithSelector}from'zustand/middleware';import {jsx,jsxs}from'react/jsx-runtime';var j=class{constructor(e){this.innerForm=new T(e,"__repeatable_template__");}add(...e){return this.innerForm.add(...e),this}addSeparateRows(e){return this.innerForm.addSeparateRows(e),this}min(e){return this._min=e,this}max(e){return this._max=e,this}defaultValue(e){return this._defaultValue=e,this}validation(e){return this._validation=e,this}_build(e){let t=this.innerForm.getRows(),i=this.innerForm.getFields();if(t.length===0)throw new Error(`Repeatable "${e}" must have at least one field`);for(let o of i)if(o.id.includes("[")||o.id.includes("]"))throw new Error(`Repeatable template field ID "${o.id}" cannot contain "[" or "]" (reserved for composite keys)`);if(this._min!==void 0&&this._max!==void 0&&this._min>this._max)throw new Error(`Repeatable "${e}": min (${this._min}) cannot be greater than max (${this._max})`);return {id:e,rows:t.map(o=>({...o,kind:"fields"})),allFields:i,min:this._min,max:this._max,defaultValue:this._defaultValue,validation:this._validation}}_hasRepeatables(){return this.innerForm.getRows().some(e=>"kind"in e&&e.kind==="repeatable")}};var T=class r{constructor(e,t){this.rows=[];this.idGenerator=new IdGenerator;this.config=e,this.formId=t||`form-${Math.random().toString(36).substring(2,15)}`;}static create(e,t){return new r(e,t)}createFormField(e){let t=this.config.getComponent(e.type);if(!t)throw new Error(`No component found with type "${e.type}"`);let i;return (t.validation||e.validation)&&(i={validateOnChange:e.validation?.validateOnChange??t.validation?.validateOnChange,validateOnBlur:e.validation?.validateOnBlur??t.validation?.validateOnBlur,debounceMs:e.validation?.debounceMs??t.validation?.debounceMs,validate:(()=>{let o=t.validation?.validate,s=e.validation?.validate;if(!o)return s;if(!s)return o;let a=Array.isArray(o)?o:[o],n=Array.isArray(s)?s:[s];return [...a,...n]})()}),{id:e.id||this.idGenerator.next("field"),componentId:t.id,props:{...t.defaultProps,...e.props},validation:i,conditions:e.conditions}}createRow(e){if(e.length===0)throw new Error("At least one field is required");if(e.length>3)throw new Error("Maximum 3 fields per row");let t=e.map(i=>this.createFormField(i));return {kind:"fields",id:this.idGenerator.next("row"),fields:t,maxColumns:e.length}}add(...e){let t,i=false;if(e.length===1&&Array.isArray(e[0])?(t=e[0],i=true):t=e,t.length===0)throw new Error("At least one field is required");if(i&&t.length>3)throw new Error("Maximum 3 fields per row");if(t.length===1){let o=this.createRow(t);return this.rows.push(o),this}if(t.length<=3){let o=this.createRow(t);return this.rows.push(o),this}for(let o of t){let s=this.createRow([o]);this.rows.push(s);}return this}addSeparateRows(e){for(let t of e)this.add(t);return this}addRepeatable(e,t){if(e.includes("[")||e.includes("]"))throw new Error(`Repeatable ID "${e}" cannot contain "[" or "]" (reserved for composite keys)`);let i=new j(this.config),o=t(i);if(o._hasRepeatables())throw new Error(`Nested repeatables are not supported (in repeatable "${e}")`);let s=o._build(e),a={kind:"repeatable",id:this.idGenerator.next("repeatable"),repeatable:s};return this.rows.push(a),this}setId(e){return this.formId=e,this}updateField(e,t){let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);return Object.assign(i,{...t,props:{...i.props,...t.props}}),this}findField(e){for(let t of this.rows)if(t.kind==="fields"){let i=t.fields.find(o=>o.id===e);if(i)return i}else {let i=t.repeatable.allFields.find(o=>o.id===e);if(i)return i}return null}removeField(e){return this.rows=this.rows.map(t=>t.kind==="repeatable"?t:{...t,fields:t.fields.filter(i=>i.id!==e)}).filter(t=>t.kind==="repeatable"||t.fields.length>0),this}getField(e){return this.findField(e)||void 0}getFields(){return this.rows.filter(e=>e.kind==="fields").flatMap(e=>e.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.idGenerator.reset(),this}setValidation(e){return this.formValidation=e,this}addFieldValidation(e,t){console.warn("addFieldValidation is deprecated. Use updateField with validation.validate property instead.");let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);let o={...i.validation,...t};return this.updateField(e,{validation:o})}addFieldConditions(e,t){let i=this.findField(e);if(!i)throw new Error(`Field with ID "${e}" not found`);let o={...i.conditions,...t};return this.updateField(e,{conditions:o})}clone(e){let t=new r(this.config,e||`${this.formId}-clone`);return t.rows=deepClone(this.rows),t}validate(){let e=[],t=this.getFields(),i=this.rows.filter(n=>n.kind==="repeatable"),o=i.flatMap(n=>n.repeatable.allFields),s=[...t.map(n=>n.id),...o.map(n=>n.id)];try{ensureUnique(s,"field");}catch(n){e.push(n instanceof Error?n.message:String(n));}let a=i.map(n=>n.repeatable.id);try{ensureUnique(a,"repeatable");}catch(n){e.push(n instanceof Error?n.message:String(n));}for(let n of t)this.config.hasComponent(n.componentId)||e.push(`Component "${n.componentId}" not found for field "${n.id}"`);for(let n of o)this.config.hasComponent(n.componentId)||e.push(`Component "${n.componentId}" not found for repeatable template field "${n.id}"`);for(let n of this.rows)n.kind==="fields"&&(n.fields.length>3&&e.push(`Row "${n.id}" has ${n.fields.length} fields, maximum is 3`),n.fields.length===0&&e.push(`Row "${n.id}" is empty`));for(let n of t)(n.id.includes("[")||n.id.includes("]"))&&e.push(`Field ID "${n.id}" cannot contain "[" or "]" (reserved for repeatable composite keys)`);for(let n of a)(n.includes("[")||n.includes("]"))&&e.push(`Repeatable ID "${n}" cannot contain "[" or "]" (reserved for composite keys)`);return e}build(){let e=this.validate();if(e.length>0)throw new Error(`Form validation failed: ${e.join(", ")}`);let t=this.rows.filter(o=>o.kind==="repeatable"),i=t.length>0?Object.fromEntries(t.map(o=>[o.repeatable.id,o.repeatable])):void 0;return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),repeatableFields:i,config:this.config,renderConfig:this.config.getFormRenderConfig(),validation:this.formValidation}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(e){return e.id&&(this.formId=e.id),e.rows&&(this.rows=e.rows.map(t=>t.kind?t:{...t,kind:"fields"})),this}getStats(){let e=this.getFields(),t=this.rows.filter(s=>s.kind==="fields"),i=this.rows.filter(s=>s.kind==="repeatable"),o=t.map(s=>s.fields.length);return {totalFields:e.length,totalRows:this.rows.length,averageFieldsPerRow:t.length>0?e.length/t.length:0,maxFieldsInRow:o.length>0?Math.max(...o):0,minFieldsInRow:o.length>0?Math.min(...o):0,totalRepeatables:i.length,totalRepeatableFields:i.reduce((s,a)=>s+a.repeatable.allFields.length,0)}}};function er(r,e={},t={}){return useMemo(()=>{if(!r)return {visible:t.visible??true,disabled:t.disabled??false,required:t.required??false,readonly:t.readonly??false};let i=o=>{try{return o&&typeof o=="object"&&"build"in o?evaluateCondition(o.build(),e):evaluateCondition(o,e)}catch(s){return console.warn("Error evaluating condition:",s),false}};return {visible:r.visible?i(r.visible):t.visible??true,disabled:r.disabled?i(r.disabled):t.disabled??false,required:r.required?i(r.required):t.required??false,readonly:r.readonly?i(r.readonly):t.readonly??false}},[r,e,t])}function Te(r,e={}){return useMemo(()=>{let t={};for(let[i,o]of Object.entries(r))if(t[i]={visible:true,disabled:false,required:false,readonly:false},o){let s=a=>{try{return a&&typeof a=="object"&&"build"in a?evaluateCondition(a.build(),e):evaluateCondition(a,e)}catch(n){return console.warn(`Error evaluating condition for field ${i}:`,n),false}};t[i]={visible:o.visible?s(o.visible):true,disabled:o.disabled?s(o.disabled):false,required:o.required?s(o.required):false,readonly:o.readonly?s(o.readonly):false};}return t},[r,e])}var it=/^([^[\]]+)\[([^\]]+)\]\.(.+)$/;function V(r,e,t){return `${r}[${e}].${t}`}function L(r){let e=it.exec(r);return e?{repeatableId:e[1],itemKey:e[2],fieldId:e[3]}:null}function de(r,e,t){let i={},o=new Set;for(let[s,a]of Object.entries(t)){if(!e[s])continue;let n=e[s],u=[];for(let p of a){let f={};for(let m of n.allFields){let l=V(s,p,m.id);l in r&&(f[m.id]=r[l],o.add(l));}u.push(f);}i[s]=u;}for(let[s,a]of Object.entries(r))!o.has(s)&&!L(s)&&(i[s]=a);return i}function re(r,e){let t={},i={},o={};for(let[s,a]of Object.entries(r))if(e[s]&&Array.isArray(a)){let n=[],u=0;for(let p of a){let f=`k${u}`;n.push(f);for(let[m,l]of Object.entries(p))t[V(s,f,m)]=l;u++;}i[s]=n,o[s]=u;}else t[s]=a;return {values:t,order:i,nextKeys:o}}function ue(r={}){return createStore()(subscribeWithSelector((e,t)=>({values:{...r},errors:{},validationStates:{},touched:{},isDirty:false,isSubmitting:false,isValid:true,_defaultValues:{...r},_fieldConditions:{},_repeatableConfigs:{},_repeatableOrder:{},_repeatableNextKey:{},_setValue:(i,o)=>{e(s=>({values:{...s.values,[i]:o},isDirty:true}));},_setTouched:i=>{e(o=>({touched:{...o.touched,[i]:true}}));},_setErrors:(i,o)=>{e(s=>{let a={...s.errors,[i]:o},n=o.length>0?"invalid":"valid";return {errors:a,validationStates:{...s.validationStates,[i]:n}}}),t()._updateIsValid();},_clearErrors:i=>{e(o=>{let s={...o.errors};return delete s[i],{errors:s,validationStates:{...o.validationStates,[i]:"idle"}}}),t()._updateIsValid();},_setValidationState:(i,o)=>{e(s=>({validationStates:{...s.validationStates,[i]:o}}));},_setSubmitting:i=>{e({isSubmitting:i});},_reset:i=>{let o=i??t()._defaultValues;e({values:{...o},errors:{},validationStates:{},touched:{},isDirty:false,isSubmitting:false,isValid:true,_repeatableOrder:{},_repeatableNextKey:{}});},_setFieldConditions:(i,o)=>{e(s=>({_fieldConditions:{...s._fieldConditions,[i]:o}}));},_updateIsValid:()=>{let i=t(),o=Object.values(i.errors).some(a=>a&&a.length>0),s=Object.values(i.validationStates).some(a=>a==="invalid");e({isValid:!o&&!s});},_setRepeatableConfig:(i,o)=>{e(s=>({_repeatableConfigs:{...s._repeatableConfigs,[i]:o}}));},_appendRepeatableItem:(i,o)=>{let s=t(),a=s._repeatableConfigs[i];if(!a)return null;let n=s._repeatableOrder[i]??[];if(a.max!==void 0&&n.length>=a.max)return null;let u=s._repeatableNextKey[i]??0,p=`k${u}`,f=o??a.defaultValue??{},m={...s.values};for(let l of a.allFields){let d=V(i,p,l.id);m[d]=f[l.id]??void 0;}return e({values:m,isDirty:true,_repeatableOrder:{...s._repeatableOrder,[i]:[...n,p]},_repeatableNextKey:{...s._repeatableNextKey,[i]:u+1}}),p},_removeRepeatableItem:(i,o)=>{let s=t(),a=s._repeatableConfigs[i];if(!a)return false;let n=s._repeatableOrder[i]??[];if(a.min!==void 0&&n.length<=a.min||!n.includes(o))return false;let u=n.filter(F=>F!==o),p={...s.values},f={...s.errors},m={...s.validationStates},l={...s.touched},d={...s._fieldConditions};for(let F of a.allFields){let g=V(i,o,F.id);delete p[g],delete f[g],delete m[g],delete l[g],delete d[g];}return e({values:p,errors:f,validationStates:m,touched:l,isDirty:true,_fieldConditions:d,_repeatableOrder:{...s._repeatableOrder,[i]:u}}),t()._updateIsValid(),true},_moveRepeatableItem:(i,o,s)=>{let a=t(),n=a._repeatableOrder[i];if(!n||o<0||o>=n.length||s<0||s>=n.length||o===s)return;let u=[...n],[p]=u.splice(o,1);u.splice(s,0,p),e({_repeatableOrder:{...a._repeatableOrder,[i]:u}});},_insertRepeatableItem:(i,o,s)=>{let a=t(),n=a._repeatableConfigs[i];if(!n)return null;let u=a._repeatableOrder[i]??[];if(n.max!==void 0&&u.length>=n.max)return null;let p=a._repeatableNextKey[i]??0,f=`k${p}`,m=s??n.defaultValue??{},l={...a.values};for(let g of n.allFields){let c=V(i,f,g.id);l[c]=m[g.id]??void 0;}let d=[...u],F=Math.max(0,Math.min(o,d.length));return d.splice(F,0,f),e({values:l,isDirty:true,_repeatableOrder:{...a._repeatableOrder,[i]:d},_repeatableNextKey:{...a._repeatableNextKey,[i]:p+1}}),f}})))}var oe=createContext(null);function S(){let r=useContext(oe);if(!r)throw new Error("useFormStore must be used within a FormProvider");return r}var De=[];function ce(r){let e=S();return useStore(e,t=>t.values[r])}function dt(r){let e=S();return useStore(e,t=>t.errors[r]??De)}function ut(r){let e=S();return useStore(e,t=>t.touched[r]??false)}function ct(r){let e=S();return useStore(e,t=>t.validationStates[r]??"idle")}var mt={visible:true,disabled:false,required:false,readonly:false};function $(r){let e=S();return useStore(e,t=>t._fieldConditions[r]??mt)}function me(r){let e=S(),t=useStore(e,n=>n.values[r]),i=useStore(e,n=>n.errors[r]??De),o=useStore(e,n=>n.validationStates[r]??"idle"),s=useStore(e,n=>n.touched[r]??false),a=useStore(e,n=>n._defaultValues[r]);return {value:t,errors:i,validationState:o,touched:s,dirty:t!==a}}function ft(){let r=S();return useStore(r,e=>e.isSubmitting)}function pt(){let r=S();return useStore(r,e=>e.isValid)}function Ft(){let r=S();return useStore(r,e=>e.isDirty)}function gt(){let r=S();return useStore(r,e=>e.values)}function fe(){let r=S(),e=useStore(r,o=>o.isSubmitting),t=useStore(r,o=>o.isValid),i=useStore(r,o=>o.isDirty);return {isSubmitting:e,isValid:t,isDirty:i}}var bt=[];function pe(r){let e=S();return useStore(e,t=>t._repeatableOrder[r]??bt)}function Fe(r){let e=S();return {setValue:t=>e.getState()._setValue(r,t),setTouched:()=>e.getState()._setTouched(r),setErrors:t=>e.getState()._setErrors(r,t),clearErrors:()=>e.getState()._clearErrors(r),setValidationState:t=>e.getState()._setValidationState(r,t)}}function Ct(){let r=S();return {setValue:(e,t)=>r.getState()._setValue(e,t),setTouched:e=>r.getState()._setTouched(e),setErrors:(e,t)=>r.getState()._setErrors(e,t),setSubmitting:e=>r.getState()._setSubmitting(e),reset:e=>r.getState()._reset(e),setFieldConditions:(e,t)=>r.getState()._setFieldConditions(e,t)}}function H(){return S()}var Ae={visible:true,disabled:false,required:false,readonly:false};function Ke(r){try{return JSON.stringify(r)}catch{return String(Date.now())}}function ie(r,e){if(r)try{return typeof r=="object"&&"build"in r?evaluateCondition(r.build(),e):evaluateCondition(r,e)}catch(t){console.warn("Error evaluating condition:",t);return}}function be(r,e){if(!r)return Ae;let t=ie(r.visible,e),i=ie(r.disabled,e),o=ie(r.required,e),s=ie(r.readonly,e);return {visible:t??true,disabled:i??false,required:o??false,readonly:s??false}}function fr(r,e={}){let{conditions:t,skip:i=false}=e,o=H(),s=$(r),a=useRef(null);if(i||!t)return s;let n=o.getState().values,u=Ke(n);if(a.current?.valuesHash===u)return a.current.result;let p=be(t,n);return a.current={result:p,valuesHash:u},p}function pr(){let r=H(),e=useRef(new Map),t=useRef("");return useMemo(()=>function(o,s){if(!s)return Ae;let a=r.getState().values,n=Ke(a);t.current!==n&&(e.current.clear(),t.current=n);let u=e.current.get(o);if(u)return u.result;let p=be(s,a);return e.current.set(o,{result:p,valuesHash:n}),p},[r])}function Fr(r,e){let t=H(),i=$(r),o=useMemo(()=>()=>{if(!e)return i;let s=t.getState().values;return be(e,s)},[t,e,i]);return {conditions:i,refresh:o}}function Y(r,e,t,i){let o={};return r.visible&&(o.visible=G(r.visible,e,t,i)),r.disabled&&(o.disabled=G(r.disabled,e,t,i)),r.required&&(o.required=G(r.required,e,t,i)),r.readonly&&(o.readonly=G(r.readonly,e,t,i)),o}function G(r,e,t,i){let o=r.field&&i.has(r.field)?`${e}[${t}].${r.field}`:r.field,s=r.conditions?.map(a=>G(a,e,t,i));return {...r,field:o,conditions:s}}function Ue({formConfig:r,formValues:e,repeatableOrder:t}){let i=useMemo(()=>{let m={};for(let l of r.allFields)l.conditions&&(m[l.id]=l.conditions);if(t&&r.repeatableFields)for(let[l,d]of Object.entries(r.repeatableFields)){let F=t[l]??[];if(F.length===0)continue;let g=new Set(d.allFields.map(c=>c.id));for(let c of F)for(let R of d.allFields){if(!R.conditions)continue;let b=V(l,c,R.id);m[b]=Y(R.conditions,l,c,g);}}return m},[r.allFields,r.repeatableFields,t]),o=useMemo(()=>Object.keys(i).length>0,[i]),s=Te(o?i:{},o?e:{}),a=useCallback(m=>s[m],[s]),n=useCallback(m=>{let l=s[m];return l?l.visible:true},[s]),u=useCallback(m=>{let l=s[m];return l?l.disabled:false},[s]),p=useCallback(m=>{let l=s[m];return l?l.required:false},[s]),f=useCallback(m=>{let l=s[m];return l?l.readonly:false},[s]);return useMemo(()=>({fieldConditions:s,hasConditionalFields:o,getFieldCondition:a,isFieldVisible:n,isFieldDisabled:u,isFieldRequired:p,isFieldReadonly:f}),[s,o,a,n,u,p,f])}function $e({store:r,onSubmit:e,validateForm:t}){let i=useRef(e);return i.current=e,{submit:useCallback(async s=>{s?.preventDefault();let a=r.getState();if(a.isSubmitting)return false;a._setSubmitting(true);try{if(!(await t()).isValid)return a._setSubmitting(!1),!1;let u=r.getState(),f=Object.keys(u._repeatableConfigs).length>0?de(u.values,u._repeatableConfigs,u._repeatableOrder):u.values;return i.current&&await i.current(f),a._setSubmitting(!1),!0}catch(n){return a._setSubmitting(false),console.error("Form submission error:",n),false}},[r,t])}}function ne(){return {isValid:true,errors:[]}}function Le({formConfig:r,store:e,conditionsHelpers:t}){let i=useRef(r),o=useRef(t);i.current=r,o.current=t;let s=useCallback(async(n,u)=>{let p=i.current.allFields.find(d=>d.id===n);if(!p){let d=L(n);if(d&&i.current.repeatableFields){let F=i.current.repeatableFields[d.repeatableId];if(F){let g=F.allFields.find(c=>c.id===d.fieldId);g&&(p={...g,id:n});}}}let f=e.getState();if(!p)return ne();if(!o.current.isFieldVisible(n))return f._setErrors(n,[]),f._setValidationState(n,"valid"),ne();if(!p.validation||!hasUnifiedValidation(p.validation)){let d=o.current.isFieldRequired(n),F=u!==void 0?u:f.values[n];if(d&&isEmptyValue(F)){let g={isValid:false,errors:[{message:"This field is required",code:"CONDITIONAL_REQUIRED"}]};return f._setErrors(n,g.errors),f._setValidationState(n,"invalid"),g}return f._setErrors(n,[]),f._setValidationState(n,"valid"),ne()}let m=u!==void 0?u:f.values[n],l=createValidationContext({fieldId:n,formId:i.current.id,allFormData:{...f.values,[n]:m}});f._setValidationState(n,"validating");try{let d=await validateWithUnifiedConfig(p.validation,m,l);if(o.current.isFieldRequired(n)&&isEmptyValue(m)&&!d.errors.some(c=>c.code==="REQUIRED"||c.message.toLowerCase().includes("required"))){let c={isValid:!1,errors:[{message:"This field is required",code:"CONDITIONAL_REQUIRED"},...d.errors]};return f._setErrors(n,c.errors),f._setValidationState(n,"invalid"),c}return f._setErrors(n,d.errors),f._setValidationState(n,d.isValid?"valid":"invalid"),d}catch(d){let F={isValid:false,errors:[{message:d instanceof Error?d.message:"Validation failed",code:"VALIDATION_ERROR"}]};return f._setErrors(n,F.errors),f._setValidationState(n,"invalid"),F}},[e]),a=useCallback(async()=>{let n=e.getState(),u=i.current.allFields.filter(c=>{if(!o.current.isFieldVisible(c.id))return false;let b=c.validation&&hasUnifiedValidation(c.validation),k=o.current.isFieldRequired(c.id);return b||k}),p=i.current.allFields.filter(c=>!o.current.isFieldVisible(c.id));for(let c of p)n._setErrors(c.id,[]),n._setValidationState(c.id,"valid");let f=await Promise.all(u.map(c=>s(c.id))),m=f.some(c=>!c.isValid),l=i.current.repeatableFields??{},d=[];for(let[c,R]of Object.entries(l)){let b=n._repeatableOrder[c]??[];for(let k of b)for(let O of R.allFields){let P=V(c,k,O.id);if(!o.current.isFieldVisible(P)){n._setErrors(P,[]),n._setValidationState(P,"valid");continue}let D=await s(P);d.push(D);}R.min!==void 0&&b.length<R.min&&d.push({isValid:false,errors:[{message:`At least ${R.min} item(s) required`,code:"REPEATABLE_MIN_COUNT",path:c}]});}let F=d.some(c=>!c.isValid);m=m||F;let g=ne();if(i.current.validation&&hasUnifiedValidation(i.current.validation)){let c=Object.keys(n.values).reduce((b,k)=>(o.current.isFieldVisible(k)&&(b[k]=n.values[k]),b),{}),R=createValidationContext({formId:i.current.id,allFormData:c});try{g=await validateFormWithUnifiedConfig(i.current.validation,c,R);}catch(b){g={isValid:false,errors:[{message:b instanceof Error?b.message:"Form validation failed",code:"FORM_VALIDATION_ERROR"}]};}}return {isValid:!m&&g.isValid,errors:[...f.flatMap(c=>c.errors),...d.flatMap(c=>c.errors),...g.errors]}},[e,s]);return {validateField:s,validateForm:a}}function ve(r){let e=S(),{formConfig:t}=E(),i=pe(r),o=t.repeatableFields?.[r],s=useMemo(()=>o?new Set(o.allFields.map(l=>l.id)):new Set,[o]),a=useMemo(()=>o?i.map((l,d)=>{let F=o.allFields.map(c=>{let R=V(r,l,c.id),b=c.conditions?Y(c.conditions,r,l,s):void 0;return {...c,id:R,conditions:b}}),g=o.rows.map(c=>({...c,fields:c.fields.map(R=>{let b=V(r,l,R.id),k=R.conditions?Y(R.conditions,r,l,s):void 0;return {...R,id:b,conditions:k}})}));return {key:l,index:d,rows:g,allFields:F}}):[],[r,i,o,s]),n=useMemo(()=>o?o.max===void 0?true:i.length<o.max:false,[o,i.length]),u=useMemo(()=>{if(!o)return false;let l=o.min??0;return i.length>l},[o,i.length]),p=useCallback(l=>{e.getState()._appendRepeatableItem(r,l);},[e,r]),f=useCallback(l=>{e.getState()._removeRepeatableItem(r,l);},[e,r]),m=useCallback((l,d)=>{e.getState()._moveRepeatableItem(r,l,d);},[e,r]);return {items:a,append:p,remove:f,move:m,canAdd:n,canRemove:u,count:i.length}}function xt({formConfig:r,enabled:e=true}){let t=getGlobalMonitor(),i=useRef(null),o=useRef(0),s=useRef(0);useEffect(()=>{t&&e&&(i.current=t.getProfiler());},[t,e]);let a=useCallback(l=>{if(!t||!e)return;o.current++;let d={formId:r.id,fieldCount:r.allFields.length,timestamp:Date.now(),duration:0,renderDuration:0,validationDuration:0,validationErrors:0,renderCount:l||o.current};t.track("component_render",`form_${r.id}`,{formId:r.id,fieldCount:r.allFields.length,renderCount:o.current},d,"low");},[t,e,r.id,r.allFields.length]),n=useCallback((l,d)=>{if(!t||!e)return;let F=i.current?.getMetrics(`form_validation_${r.id}`),g={formId:r.id,fieldCount:d||r.allFields.length,timestamp:Date.now(),duration:F?.duration||0,renderDuration:0,validationDuration:F?.duration||0,validationErrors:l,renderCount:o.current};t.track("form_validation",`form_${r.id}`,{formId:r.id,validationErrors:l,fieldCount:d||r.allFields.length},g,l>0?"medium":"low");},[t,e,r.id,r.allFields.length]),u=useCallback((l,d)=>{if(!t||!e)return;let F=i.current?.getMetrics(`form_submission_${r.id}`),g={formId:r.id,fieldCount:d||r.allFields.length,timestamp:Date.now(),duration:F?.duration||0,renderDuration:0,validationDuration:0,validationErrors:l?0:1,renderCount:o.current};t.track("form_submission",`form_${r.id}`,{formId:r.id,success:l,fieldCount:d||r.allFields.length,fieldChanges:s.current},g,l?"low":"high");},[t,e,r.id,r.allFields.length]),p=useCallback((l,d)=>{!t||!e||(s.current++,t.track("component_update",`field_${l}`,{formId:r.id,fieldId:l,componentType:d,changeCount:s.current},void 0,"low"));},[t,e,r.id]),f=useCallback(l=>{!i.current||!e||i.current.start(l,{formId:r.id,renderCount:o.current});},[e,r.id]),m=useCallback(l=>{if(!i.current||!e)return null;let d=i.current.end(l);return d?{...d,formId:r.id,fieldCount:r.allFields.length,renderDuration:d.duration,validationDuration:0,validationErrors:0}:null},[e,r.id,r.allFields.length]);return {trackFormRender:a,trackFormValidation:n,trackFormSubmission:u,trackFieldChange:p,startPerformanceTracking:f,endPerformanceTracking:m}}var Ye=createContext(null);function E(){let r=useContext(Ye);if(!r)throw new Error("useFormConfigContext must be used within a FormProvider");return r}function xe({children:r,formConfig:e,defaultValues:t={},onSubmit:i,onFieldChange:o,className:s}){let[a]=useState(()=>{let _=e.repeatableFields??{},C={...t},h={},y={};if(Object.keys(_).some(v=>Array.isArray(t[v]))){let v=re(t,_);C=v.values,h=v.order,y=v.nextKeys;}for(let[v,B]of Object.entries(_))if(!h[v]){let Z=B.min??0,K=[],U=y[v]??0;for(let N=0;N<Z;N++){let W=`k${U}`;K.push(W);for(let ee of B.allFields){let tt=V(v,W,ee.id);C[tt]=B.defaultValue?.[ee.id]??void 0;}U++;}h[v]=K,y[v]=U;}let M=ue(C),x=M.getState();for(let[v,B]of Object.entries(_))x._setRepeatableConfig(v,B);return M.setState({_repeatableOrder:h,_repeatableNextKey:y}),M}),n=useRef(e.id),u=useRef(o);u.current=o,useEffect(()=>u.current?a.subscribe(C=>C.values,(C,h)=>{for(let y of Object.keys(C))C[y]!==h[y]&&u.current?.(y,C[y],C);}):void 0,[a]),useEffect(()=>{if(n.current!==e.id){n.current=e.id;let _=e.repeatableFields??{},C={...t},h={},y={};if(Object.keys(_).some(x=>Array.isArray(t[x]))){let x=re(t,_);C=x.values,h=x.order,y=x.nextKeys;}for(let[x,v]of Object.entries(_))if(!h[x]){let B=v.min??0,Z=[],K=y[x]??0;for(let U=0;U<B;U++){let N=`k${K}`;Z.push(N);for(let W of v.allFields){let ee=V(x,N,W.id);C[ee]=v.defaultValue?.[W.id]??void 0;}K++;}h[x]=Z,y[x]=K;}a.getState()._reset(C);let M=a.getState();for(let[x,v]of Object.entries(_))M._setRepeatableConfig(x,v);a.setState({_repeatableOrder:h,_repeatableNextKey:y});}},[e.id,e.repeatableFields,a,t]);let[p,f]=useState(()=>a.getState().values);useEffect(()=>a.subscribe(C=>C.values,C=>f(C)),[a]);let[m,l]=useState(()=>a.getState()._repeatableOrder);useEffect(()=>a.subscribe(C=>C._repeatableOrder,C=>l(C)),[a]);let{fieldConditions:d,hasConditionalFields:F,getFieldCondition:g,isFieldVisible:c,isFieldDisabled:R,isFieldRequired:b,isFieldReadonly:k}=Ue({formConfig:e,formValues:p,repeatableOrder:m});useEffect(()=>{for(let[_,C]of Object.entries(d)){let h={visible:C.visible,disabled:C.disabled,required:C.required,readonly:C.readonly};a.getState()._setFieldConditions(_,h);}},[d,a]);let O=useMemo(()=>({hasConditionalFields:F,getFieldCondition:g,isFieldVisible:c,isFieldDisabled:R,isFieldRequired:b,isFieldReadonly:k}),[F,g,c,R,b,k]),{validateField:P,validateForm:D}=Le({formConfig:e,store:a,conditionsHelpers:O}),{submit:q}=$e({store:a,onSubmit:i,validateForm:D}),X=useMemo(()=>({formConfig:e,conditionsHelpers:O,validateField:P,validateForm:D,submit:q}),[e,O,P,D,q]);return jsx(oe.Provider,{value:a,children:jsx(Ye.Provider,{value:X,children:jsx("form",{onSubmit:q,className:s,noValidate:true,children:r})})})}function Et({formConfig:r,defaultValues:e,onSubmit:t,onFieldChange:i,className:o,children:s}){let a=useMemo(()=>r instanceof T?r.build():r,[r]);return jsx(xe,{formConfig:a,defaultValues:e,onSubmit:t,onFieldChange:i,className:o,children:s})}var Q=Ot.memo(function({fieldId:e,fieldConfig:t,disabled:i=false,customProps:o={},className:s,forceVisible:a=false}){let{formConfig:n,validateField:u,conditionsHelpers:p}=E(),f=ce(e),m=me(e),l=$(e),{setValue:d,setTouched:F}=Fe(e),g=useMemo(()=>{if(t)return t;let h=n.allFields.find(A=>A.id===e);if(h)return h;let y=L(e);if(y&&n.repeatableFields){let A=n.repeatableFields[y.repeatableId];if(A){let M=A.allFields.find(x=>x.id===y.fieldId);if(M)return {...M,id:e}}}},[t,n.allFields,n.repeatableFields,e]);if(!g)throw new Error(`Field with ID "${e}" not found`);let c=n.config.getComponent(g.componentId);if(!c)throw new Error(`Component with ID "${g.componentId}" not found`);let R=m.validationState==="validating",b=useMemo(()=>({isVisible:a||l.visible,isFieldDisabled:i||l.disabled,isFieldRequired:l.required||p.isFieldRequired(e),isFieldReadonly:l.readonly}),[a,i,l,p,e]),k=useCallback(async h=>{d(h),(g.validation?.validateOnChange||m.touched)&&await u(e,h);},[e,d,u,g.validation?.validateOnChange,m.touched]),O=useCallback(async()=>{m.touched||F(),g.validation?.validateOnBlur!==false&&await u(e);},[e,m.touched,F,u,g.validation?.validateOnBlur]),P=useMemo(()=>({...c.defaultProps??{},...g.props,...o,disabled:b.isFieldDisabled,required:b.isFieldRequired,readOnly:b.isFieldReadonly}),[c.defaultProps,g.props,o,b.isFieldDisabled,b.isFieldRequired,b.isFieldReadonly]),D=useMemo(()=>({id:e,props:P,value:f,onChange:k,onBlur:O,disabled:b.isFieldDisabled,error:m.errors,isValidating:R,touched:m.touched}),[e,P,f,k,O,b.isFieldDisabled,m.errors,R,m.touched]);if(!b.isVisible)return null;let q=c.renderer(D),X=n.renderConfig?.fieldRenderer,_=c.useFieldRenderer!==false,C=X&&_?X({children:q,id:e,...P,error:m.errors,isValidating:R,touched:m.touched}):q;return jsx("div",{className:s,"data-field-id":e,"data-field-type":c.type,"data-field-visible":b.isVisible,"data-field-disabled":b.isFieldDisabled,"data-field-required":b.isFieldRequired,"data-field-readonly":b.isFieldReadonly,children:C})});var Qe=Ot.memo(function({row:e,className:t,...i}){let{formConfig:o,conditionsHelpers:s}=E(),a=useMemo(()=>e.fields.filter(p=>s.isFieldVisible(p.id)),[e.fields,s]),n=useMemo(()=>a.map(p=>jsx(Q,{fieldId:p.id},p.id)),[a]),u=useMemo(()=>({row:e,children:n,className:t}),[e,n,t]);return a.length===0?null:jsx(ComponentRendererWrapper,{name:"FormRow",renderer:o.renderConfig?.rowRenderer,props:u,...i,children:n})}),le=Qe;var ke=Ot.memo(function({item:e,index:t,total:i,canRemove:o,canMoveUp:s,canMoveDown:a,onRemove:n,onMoveUp:u,onMoveDown:p}){let{formConfig:f}=E(),m=useMemo(()=>new Map(e.allFields.map(F=>[F.id,F])),[e.allFields]),l=useMemo(()=>e.rows.map(F=>jsx(le,{row:F,children:F.fields.map(g=>jsx(Q,{fieldId:g.id,fieldConfig:m.get(g.id)},g.id))},F.id)),[e.rows,m]),d=f.renderConfig?.repeatableItemRenderer;return d?d({item:e,index:t,total:i,canRemove:o,canMoveUp:s,canMoveDown:a,onRemove:n,onMoveUp:u,onMoveDown:p,children:l}):jsx("div",{"data-repeatable-item":e.key,"data-repeatable-index":t,children:l})});var Ee=Ot.memo(function({repeatableId:e,repeatableConfig:t,className:i}){let{formConfig:o}=E(),{items:s,append:a,remove:n,move:u,canAdd:p,canRemove:f}=ve(e),m=useMemo(()=>s.map((d,F)=>jsx(ke,{item:d,index:F,total:s.length,canRemove:f,canMoveUp:F>0,canMoveDown:F<s.length-1,onRemove:()=>n(d.key),onMoveUp:()=>u(F,F-1),onMoveDown:()=>u(F,F+1)},d.key)),[s,f,n,u]),l=o.renderConfig?.repeatableRenderer;return l?l({repeatableId:e,items:s,canAdd:p,canRemove:f,onAdd:()=>a(),min:t.min,max:t.max,children:m}):jsxs("div",{className:i,"data-repeatable-id":e,children:[m,p&&jsx("button",{type:"button",onClick:()=>a(),"data-repeatable-add":e,children:"Add"})]})});var It=Ot.memo(function({className:e,...t}){let{formConfig:i}=E(),o=useMemo(()=>i.rows.map(a=>a.kind==="repeatable"?jsx(Ee,{repeatableId:a.repeatable.id,repeatableConfig:a.repeatable},a.id):jsx(le,{row:a},a.id)),[i.rows]),s=useMemo(()=>({formConfig:i,children:o,className:e}),[i,o,e]);return jsx(ComponentRendererWrapper,{name:"FormBody",renderer:i.renderConfig?.bodyRenderer,props:s,...t,children:o})});var Lt=Ot.memo(function({className:e,isSubmitting:t,...i}){let{formConfig:o,submit:s}=E(),{isSubmitting:a}=fe(),n=useMemo(()=>({isSubmitting:t??a,onSubmit:s,className:e}),[t,a,s,e]);return jsx(ComponentRendererWrapper,{name:"FormSubmitButton",renderer:o.renderConfig?.submitButtonRenderer,props:n,...i})});export{Et as Form,It as FormBody,T as FormBuilder,Q as FormField,xe as FormProvider,Qe as FormRow,oe as FormStoreContext,Lt as FormSubmitButton,j as RepeatableBuilder,Ee as RepeatableField,ke as RepeatableItem,ue as createFormStore,re as flattenRepeatableValues,T as form,de as structureFormValues,er as useConditionEvaluation,pr as useConditionEvaluator,Fe as useFieldActions,$ as useFieldConditions,fr as useFieldConditionsLazy,Fr as useFieldConditionsWithRefresh,dt as useFieldErrors,me as useFieldState,ut as useFieldTouched,ct as useFieldValidationState,ce as useFieldValue,Ct as useFormActions,Ue as useFormConditions,E as useFormConfigContext,Ft as useFormDirty,xt as useFormMonitoring,S as useFormStore,H as useFormStoreApi,$e as useFormSubmissionWithStore,fe as useFormSubmitState,ft as useFormSubmitting,pt as useFormValid,Le as useFormValidationWithStore,gt as useFormValues,Te as useMultipleConditionEvaluation,ve as useRepeatableField,pe as useRepeatableKeys};
{
"name": "@rilaykit/forms",
"version": "0.1.1",
"version": "0.1.2",
"private": false,

@@ -19,2 +19,5 @@ "description": "Form building utilities and components for RilayKit",

],
"publishConfig": {
"provenance": true
},
"keywords": [

@@ -28,13 +31,13 @@ "react",

"license": "MIT",
"homepage": "https://rilay.io",
"homepage": "https://rilay.dev",
"repository": {
"type": "git",
"url": "https://github.com/andyoucreate/rilay.git"
"url": "https://github.com/andyoucreate/rilaykit.git"
},
"bugs": {
"url": "https://github.com/andyoucreate/rilay/issues"
"url": "https://github.com/andyoucreate/rilaykit/issues"
},
"dependencies": {
"zustand": "^5.0.5",
"@rilaykit/core": "0.1.1"
"@rilaykit/core": "0.1.2"
},

@@ -49,6 +52,6 @@ "peerDependencies": {

"@testing-library/user-event": "^14.6.1",
"@types/react": "^18.3.23",
"@types/react-dom": "^18.3.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"typescript": "^5.8.3",

@@ -55,0 +58,0 @@ "vitest": "^3.2.4"