;
+}
+
+// Utility type for users to create typed field component props without AnyObject
+export type TypedFieldProps = StrictBaseFieldProps & P;
+
+// Generic field type that infers component-specific props from any ComponentMapper
+export type Field<
+ T extends ComponentMapper = ComponentMapper,
+ C extends keyof T = keyof T,
+ FormValues = Record,
+ FieldValue = FormValues[keyof FormValues]
+> = StrictBaseFieldProps & {
+ component: C;
+} & ComponentPropsMap[C];
+
+// For backward compatibility - preserve the original interface
+interface LegacyField, FieldValue = FormValues[keyof FormValues]> extends AnyObject {
+ name: string;
+ component: string;
+ validate?: Validator[];
+ condition?: ConditionDefinition | ConditionDefinition[];
+ initializeOnMount?: boolean;
+ dataType?: DataType;
+ initialValue?: FieldValue;
+ clearedValue?: FieldValue;
+ clearOnUnmount?: boolean;
+ actions?: FieldActions;
+ resolveProps?: ResolvePropsFunction;
+}
+
+// Export the backward-compatible version as default for existing code
+export default LegacyField;
diff --git a/packages/react-form-renderer/src/common-types/form-template-render-props.d.ts b/packages/react-form-renderer/src/common-types/form-template-render-props.d.ts
deleted file mode 100644
index 196f7cb25..000000000
--- a/packages/react-form-renderer/src/common-types/form-template-render-props.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { ElementType } from "react";
-import Schema from "./schema";
-import { AnyObject } from "../common-types/any-object";
-
-export interface FormTemplateRenderProps extends AnyObject {
- formFields: ElementType[];
- schema: Schema;
-}
-
-export default FormTemplateRenderProps;
diff --git a/packages/react-form-renderer/src/common-types/form-template-render-props.ts b/packages/react-form-renderer/src/common-types/form-template-render-props.ts
new file mode 100644
index 000000000..db7432ff9
--- /dev/null
+++ b/packages/react-form-renderer/src/common-types/form-template-render-props.ts
@@ -0,0 +1,10 @@
+import { ReactNode } from 'react';
+import Schema from './schema';
+import { AnyObject } from './any-object';
+
+export interface FormTemplateRenderProps extends AnyObject {
+ formFields: ReactNode[];
+ schema: Schema;
+}
+
+export default FormTemplateRenderProps;
diff --git a/packages/react-form-renderer/src/common-types/index.d.ts b/packages/react-form-renderer/src/common-types/index.ts
similarity index 95%
rename from packages/react-form-renderer/src/common-types/index.d.ts
rename to packages/react-form-renderer/src/common-types/index.ts
index 1919da237..f2bebe13a 100644
--- a/packages/react-form-renderer/src/common-types/index.d.ts
+++ b/packages/react-form-renderer/src/common-types/index.ts
@@ -8,4 +8,5 @@ export * from './form-template-render-props';
export { default as SchemaValidatorMapper } from './schema-validator-mapper';
export * from './schema-validator-mapper';
export { default as Schema } from './schema';
+export * from './schema';
export { FieldInputProps as Input } from 'react-final-form';
diff --git a/packages/react-form-renderer/src/common-types/no-index.d.ts b/packages/react-form-renderer/src/common-types/no-index.ts
similarity index 100%
rename from packages/react-form-renderer/src/common-types/no-index.d.ts
rename to packages/react-form-renderer/src/common-types/no-index.ts
diff --git a/packages/react-form-renderer/src/common-types/schema-validator-mapper.d.ts b/packages/react-form-renderer/src/common-types/schema-validator-mapper.ts
similarity index 100%
rename from packages/react-form-renderer/src/common-types/schema-validator-mapper.d.ts
rename to packages/react-form-renderer/src/common-types/schema-validator-mapper.ts
diff --git a/packages/react-form-renderer/src/common-types/schema.d.ts b/packages/react-form-renderer/src/common-types/schema.d.ts
deleted file mode 100644
index 881d9e82c..000000000
--- a/packages/react-form-renderer/src/common-types/schema.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { ReactNode } from "react";
-import Field from "./field";
-
-interface Schema {
- title?: ReactNode;
- description?: ReactNode;
- fields: Field[];
-}
-
-export default Schema;
diff --git a/packages/react-form-renderer/src/common-types/schema.ts b/packages/react-form-renderer/src/common-types/schema.ts
new file mode 100644
index 000000000..fd6414e5a
--- /dev/null
+++ b/packages/react-form-renderer/src/common-types/schema.ts
@@ -0,0 +1,28 @@
+import { ReactNode } from 'react';
+import LegacyField, { Field } from './field';
+import ComponentMapper from './component-mapper';
+
+// Helper type to create a union of all possible Field types for a ComponentMapper
+type FieldUnion = {
+ [K in keyof T]: Field;
+}[keyof T];
+
+// Generic schema type that infers all component props from ComponentMapper
+export interface Schema {
+ title?: ReactNode;
+ description?: ReactNode;
+ fields: FieldUnion[];
+}
+
+// Backward-compatible legacy schema type
+export interface LegacySchema {
+ title?: ReactNode;
+ description?: ReactNode;
+ fields: LegacyField[];
+}
+
+// Export the generic Schema as default for new TypeScript usage
+export default Schema;
+
+// Export LegacySchema for explicit legacy usage
+export { LegacySchema as LegacySchemaType };
diff --git a/packages/react-form-renderer/src/common/helpers.d.ts b/packages/react-form-renderer/src/common/helpers.d.ts
deleted file mode 100644
index aceed4118..000000000
--- a/packages/react-form-renderer/src/common/helpers.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { ValidatorFunction, MessageTypes } from "../validators";
-import { ReactNode } from "react";
-
-// tslint:disable-next-line: ban-types
-export function memoize(func: Function): ValidatorFunction;
-
-export interface MessageObject {
- msg?: ReactNode;
- defaultMessage: ReactNode;
- values: object;
-}
-
-export function prepareMsg(msg: ReactNode, type: MessageTypes, values: object): MessageObject;
diff --git a/packages/react-form-renderer/src/common/helpers.js b/packages/react-form-renderer/src/common/helpers.js
deleted file mode 100644
index a4d4b49bc..000000000
--- a/packages/react-form-renderer/src/common/helpers.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/* eslint-disable no-unused-vars */
-import { isValidElement } from 'react';
-import Validators from '../validators';
-
-const HAS_PROP = {}.hasOwnProperty;
-export const TO_STRING = {}.toString;
-
-const isObject = (obj) => typeof obj === 'object' && TO_STRING.call(obj) === '[object Object]' && obj !== null;
-
-const stringify = (args) => {
- let arr = [];
- let value;
- let options = args;
- if (typeof options === 'number') {
- options = options.toString();
- }
-
- for (let k in options) {
- if (HAS_PROP.call(options, k)) {
- value = options[k];
- arr.push(k, isValidElement(value) ? stringify(value.props) : isObject(value) ? stringify(value) : value.toString());
- }
- }
-
- return JSON.stringify(arr);
-};
-
-export const memoize = (func) => {
- if (!func.cache) {
- func.cache = {};
- }
-
- return (value, allValues, ...options) => {
- const key = stringify(value, allValues);
- return HAS_PROP.call(func.cache, key) ? func.cache[key] : (func.cache[key] = func(value, allValues, ...options));
- };
-};
-
-const defaultMessage = (type, values) => {
- let msg = Validators.messages[type];
- return typeof msg === 'string' ? { defaultMessage: msg, values } : Object.assign({}, msg, { values });
-};
-
-export const prepareMsg = (msg, type, values) => {
- if (msg == null) {
- return defaultMessage(type, values);
- }
-
- if (HAS_PROP.call(msg, 'props') && isValidElement(msg)) {
- msg = msg.props;
- }
-
- if (msg[type] != null) {
- msg = msg[type];
- }
-
- if (isObject(msg)) {
- if (HAS_PROP.call(msg, 'id') || HAS_PROP.call(msg, 'defaultMessage')) {
- return Object.assign({}, msg, { values });
- }
-
- return defaultMessage(type, values);
- }
-
- return { id: msg, defaultMessage: msg, values };
-};
-
-export const assign = Object.assign;
-
-export const prepare =
- (func) =>
- (value, allValues, ...args) =>
- func(value, allValues, ...args);
-
-export const isNumber = (num) => !isNaN(num) && (num !== 0 || ('' + num).trim() !== '');
-
-export function selectNum(var1, var2) {
- return isNumber(var1) ? +var1 : arguments.length > 1 && isNumber(var2) ? +var2 : null;
-}
-
-export const trunc = (num) => (Math.trunc ? Math.trunc(num) : num < 0 ? Math.ceil(num) : Math.floor(num));
diff --git a/packages/react-form-renderer/src/common/helpers.ts b/packages/react-form-renderer/src/common/helpers.ts
new file mode 100644
index 000000000..86ad4297d
--- /dev/null
+++ b/packages/react-form-renderer/src/common/helpers.ts
@@ -0,0 +1,93 @@
+/* eslint-disable no-unused-vars */
+import { isValidElement, ReactNode, ReactElement } from 'react';
+import Validators from '../validators';
+import { ValidatorFunction } from '../validators';
+
+const HAS_PROP = {}.hasOwnProperty;
+export const TO_STRING = {}.toString;
+
+const isObject = (obj: any): obj is object => typeof obj === 'object' && TO_STRING.call(obj) === '[object Object]' && obj !== null;
+
+const stringify = (args: any): string => {
+ let arr: any[] = [];
+ let value: any;
+ let options = args;
+ if (typeof options === 'number') {
+ options = options.toString();
+ }
+
+ for (let k in options) {
+ if (HAS_PROP.call(options, k)) {
+ value = options[k];
+ arr.push(
+ k,
+ isValidElement(value) ? stringify(value.props) : isObject(value) ? stringify(value) : value != null ? value.toString() : 'undefined'
+ );
+ }
+ }
+
+ return JSON.stringify(arr);
+};
+
+export const memoize = (func: Function): ValidatorFunction => {
+ if (!(func as any).cache) {
+ (func as any).cache = {};
+ }
+
+ return (value: any, allValues?: object, ...options: any[]) => {
+ const key = stringify(value);
+ return HAS_PROP.call((func as any).cache, key) ? (func as any).cache[key] : ((func as any).cache[key] = func(value, allValues, ...options));
+ };
+};
+
+interface MessageObject {
+ id?: string;
+ defaultMessage: ReactNode | ((arg: any) => ReactNode);
+ values: object;
+}
+
+const defaultMessage = (type: keyof typeof Validators.messages, values: object): MessageObject => {
+ let msg = Validators.messages[type];
+ return typeof msg === 'string' ? { defaultMessage: msg, values } : (Object.assign({}, msg, { values }) as MessageObject);
+};
+
+export const prepareMsg = (msg: ReactNode | ((arg: any) => ReactNode), type: keyof typeof Validators.messages, values: object): MessageObject => {
+ if (msg == null) {
+ return defaultMessage(type, values);
+ }
+
+ let processedMsg: any = msg;
+
+ if (HAS_PROP.call(processedMsg, 'props') && isValidElement(processedMsg)) {
+ processedMsg = (processedMsg as ReactElement).props;
+ }
+
+ if ((processedMsg as any)[type] != null) {
+ processedMsg = (processedMsg as any)[type];
+ }
+
+ if (isObject(processedMsg)) {
+ if (HAS_PROP.call(processedMsg, 'id') || HAS_PROP.call(processedMsg, 'defaultMessage')) {
+ return Object.assign({}, processedMsg, { values }) as MessageObject;
+ }
+
+ return defaultMessage(type, values);
+ }
+
+ return { id: processedMsg as string, defaultMessage: processedMsg as ReactNode, values };
+};
+
+export const assign = Object.assign;
+
+export const prepare =
+ (func: Function) =>
+ (value: any, allValues?: object, ...args: any[]) =>
+ func(value, allValues, ...args);
+
+export const isNumber = (num: any): boolean => !isNaN(num) && (num !== 0 || ('' + num).trim() !== '');
+
+export function selectNum(var1: any, var2?: any): number | null {
+ return isNumber(var1) ? +var1 : arguments.length > 1 && isNumber(var2) ? +var2 : null;
+}
+
+export const trunc = (num: number): number => (Math.trunc ? Math.trunc(num) : num < 0 ? Math.ceil(num) : Math.floor(num));
diff --git a/packages/react-form-renderer/src/common/index.js b/packages/react-form-renderer/src/common/index.js
deleted file mode 100644
index c5f595cf9..000000000
--- a/packages/react-form-renderer/src/common/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export * from './helpers';
diff --git a/packages/react-form-renderer/src/common/index.d.ts b/packages/react-form-renderer/src/common/index.ts
similarity index 100%
rename from packages/react-form-renderer/src/common/index.d.ts
rename to packages/react-form-renderer/src/common/index.ts
diff --git a/packages/react-form-renderer/src/component-types/component-types.d.ts b/packages/react-form-renderer/src/component-types/component-types.d.ts
deleted file mode 100644
index a243e8304..000000000
--- a/packages/react-form-renderer/src/component-types/component-types.d.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-export type ComponentType = 'text-field'|'field-array'|'checkbox'|'sub-form'|'radio'|'tabs'|'tab-item'|'date-picker'|'time-picker'|'wizard'|'switch'|'textarea'|'select'|'plain-text'|'button'|'input-addon-group'|'input-addon-button-group'|'dual-list-select'|'slider';
-
-interface IcomponentTypes {
- TEXT_FIELD: 'text-field';
- FIELD_ARRAY: 'field-array';
- CHECKBOX: 'checkbox';
- SUB_FORM: 'sub-form';
- RADIO: 'radio';
- TABS: 'tabs';
- TAB_ITEM: 'tab-item';
- DATE_PICKER: 'date-picker';
- TIME_PICKER: 'time-picker';
- WIZARD: 'wizard';
- SWITCH: 'switch';
- TEXTAREA: 'textarea';
- SELECT: 'select';
- PLAIN_TEXT: 'plain-text';
- BUTTON: 'button';
- INPUT_ADDON_GROUP: 'input-addon-group';
- INPUT_ADDON_BUTTON_GROUP: 'input-addon-button-group';
- DUAL_LIST_SELECT: 'dual-list-select';
- SLIDER: 'slider';
-}
-
-declare const componentTypes: IcomponentTypes;
-
-export default componentTypes;
diff --git a/packages/react-form-renderer/src/component-types/component-types.js b/packages/react-form-renderer/src/component-types/component-types.ts
similarity index 85%
rename from packages/react-form-renderer/src/component-types/component-types.js
rename to packages/react-form-renderer/src/component-types/component-types.ts
index 8af0cee4d..0fc57d1bd 100644
--- a/packages/react-form-renderer/src/component-types/component-types.js
+++ b/packages/react-form-renderer/src/component-types/component-types.ts
@@ -18,6 +18,8 @@ const componentTypes = {
INPUT_ADDON_BUTTON_GROUP: 'input-addon-button-group',
DUAL_LIST_SELECT: 'dual-list-select',
SLIDER: 'slider',
-};
+} as const;
+
+export type ComponentType = (typeof componentTypes)[keyof typeof componentTypes];
export default componentTypes;
diff --git a/packages/react-form-renderer/src/component-types/index.d.ts b/packages/react-form-renderer/src/component-types/index.d.ts
deleted file mode 100644
index d136fbe77..000000000
--- a/packages/react-form-renderer/src/component-types/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from './component-types';
-export * from './component-types';
diff --git a/packages/react-form-renderer/src/component-types/index.js b/packages/react-form-renderer/src/component-types/index.js
deleted file mode 100644
index edfa5cc51..000000000
--- a/packages/react-form-renderer/src/component-types/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './component-types';
diff --git a/packages/react-form-renderer/src/component-types/index.ts b/packages/react-form-renderer/src/component-types/index.ts
new file mode 100644
index 000000000..fece723dd
--- /dev/null
+++ b/packages/react-form-renderer/src/component-types/index.ts
@@ -0,0 +1 @@
+export { default, ComponentType } from './component-types';
diff --git a/packages/react-form-renderer/src/compose-validators/compose-validators.d.ts b/packages/react-form-renderer/src/compose-validators/compose-validators.d.ts
deleted file mode 100644
index 9e1f1214c..000000000
--- a/packages/react-form-renderer/src/compose-validators/compose-validators.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { ValidatorFunction } from '../validators';
-
-export default function(validators: ValidatorFunction[]): ValidatorFunction;
diff --git a/packages/react-form-renderer/src/compose-validators/compose-validators.js b/packages/react-form-renderer/src/compose-validators/compose-validators.js
deleted file mode 100644
index eb21c5207..000000000
--- a/packages/react-form-renderer/src/compose-validators/compose-validators.js
+++ /dev/null
@@ -1,26 +0,0 @@
-const composeValidators =
- (validators = []) =>
- (value, allValues, meta) => {
- const [initialValidator, ...sequenceValidators] = validators;
- const resolveValidator = (error, validator) => {
- if (error) {
- return error;
- }
-
- if (typeof validator !== 'function') {
- return undefined;
- }
-
- return validator(value, allValues, meta);
- };
-
- const result = resolveValidator(undefined, initialValidator);
-
- if (result?.then) {
- return result.then(() => sequenceValidators.reduce(resolveValidator, undefined)).catch((error) => error);
- }
-
- return sequenceValidators.reduce(resolveValidator, result);
- };
-
-export default composeValidators;
diff --git a/packages/react-form-renderer/src/compose-validators/compose-validators.ts b/packages/react-form-renderer/src/compose-validators/compose-validators.ts
new file mode 100644
index 000000000..50ed7e42b
--- /dev/null
+++ b/packages/react-form-renderer/src/compose-validators/compose-validators.ts
@@ -0,0 +1,32 @@
+import { ValidatorFunction } from '../validators';
+
+function composeValidators<
+ TValue = any,
+ TFormValues extends Record = Record,
+ TMeta extends Record = Record
+>(validators: ValidatorFunction[] = []): ValidatorFunction {
+ return (value: TValue, allValues?: TFormValues, meta?: TMeta) => {
+ const [initialValidator, ...sequenceValidators] = validators;
+ const resolveValidator = (error: any, validator: ValidatorFunction) => {
+ if (error) {
+ return error;
+ }
+
+ if (typeof validator !== 'function') {
+ return undefined;
+ }
+
+ return validator(value, allValues, meta);
+ };
+
+ const result = resolveValidator(undefined, initialValidator);
+
+ if (result?.then) {
+ return result.then(() => sequenceValidators.reduce(resolveValidator, undefined)).catch((error: any) => error);
+ }
+
+ return sequenceValidators.reduce(resolveValidator, result);
+ };
+}
+
+export default composeValidators;
diff --git a/packages/react-form-renderer/src/compose-validators/index.d.ts b/packages/react-form-renderer/src/compose-validators/index.d.ts
deleted file mode 100644
index 03a788023..000000000
--- a/packages/react-form-renderer/src/compose-validators/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from './compose-validators';
-export * from './compose-validators'
\ No newline at end of file
diff --git a/packages/react-form-renderer/src/compose-validators/index.js b/packages/react-form-renderer/src/compose-validators/index.ts
similarity index 100%
rename from packages/react-form-renderer/src/compose-validators/index.js
rename to packages/react-form-renderer/src/compose-validators/index.ts
diff --git a/packages/react-form-renderer/src/condition/condition.d.ts b/packages/react-form-renderer/src/condition/condition.d.ts
deleted file mode 100644
index 735a9f742..000000000
--- a/packages/react-form-renderer/src/condition/condition.d.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import Field from "../common-types/field";
-import type { FormState, FormApi } from "final-form";
-
-export interface ActionResolution {
- visible?: boolean;
- set?: object | ((formState:FormState>, getFieldState:FormApi["getFieldState"]) => object) ; // TO DO specify this
-}
-
-export type InnerWhenFunction = (currentField: string) => string;
-export type WhenFunction = (currentField: string) => string | string[] | InnerWhenFunction[];
-
-export interface ConditionProp {
- when?: string | string[] | WhenFunction | InnerWhenFunction[];
- is?: any;
- isNotEmpty?: boolean;
- isEmpty?: boolean;
- pattern?: string | RegExp;
- notMatch?: any;
- then?: ActionResolution;
- else?: ActionResolution;
- or?: ConditionProp | ConditionProp[];
- and?: ConditionProp | ConditionProp[];
- not?: ConditionProp | ConditionProp[];
-}
-
-export interface ConditionDefinition extends ConditionProp {
- mappedAttributes?: {
- is?: string;
- when?: string;
- set?: string;
- },
- or?: ConditionProp | ConditionProp[];
- and?: ConditionProp | ConditionProp[];
- not?: ConditionProp | ConditionProp[];
- sequence?: ConditionProp[];
-}
-
-export interface ConditionProps {
- values: object;
- children: React.ReactChildren;
- condition?: ConditionDefinition | ConditionDefinition[];
- field: Field;
-}
-
-declare const Condition: React.ComponentType;
-
-export default Condition;
diff --git a/packages/react-form-renderer/src/condition/condition.js b/packages/react-form-renderer/src/condition/condition.js
deleted file mode 100644
index ed1a23a04..000000000
--- a/packages/react-form-renderer/src/condition/condition.js
+++ /dev/null
@@ -1,107 +0,0 @@
-import { useCallback, useContext, useEffect, useMemo, useReducer } from 'react';
-import isEqual from 'lodash/isEqual';
-
-import useFormApi from '../use-form-api';
-import parseCondition from '../parse-condition';
-import RendererContext from '../renderer-context/renderer-context';
-
-const setterValueCheck = (setterValue) => {
- if (setterValue === null || Array.isArray(setterValue)) {
- console.error('Received invalid setterValue. Expected object, received: ', setterValue);
-
- return false;
- }
-
- return typeof setterValue === 'object';
-};
-
-export const reducer = (state, { type, sets }) => {
- switch (type) {
- case 'formResetted':
- return {
- ...state,
- initial: true,
- };
- case 'rememberSets':
- return {
- ...state,
- initial: false,
- sets,
- };
- default:
- return state;
- }
-};
-
-const Condition = ({ condition, children, field }) => {
- const formOptions = useFormApi();
- const formState = formOptions.getState();
- const { conditionMapper } = useContext(RendererContext);
- const [state, dispatch] = useReducer(reducer, {
- sets: [],
- initial: true,
- });
-
- // It is required to get the context state values from in order to get the latest state.
- // Using the trigger values can cause issues with the radio field as each input is registered separately to state and does not yield the actual field value.
- const conditionResult = useMemo(
- () => parseCondition(condition, formState.values, field, conditionMapper),
- [formState.values, condition, field, conditionMapper]
- );
-
- const setters = conditionResult.set ? [conditionResult.set] : conditionResult.sets;
-
- useEffect(() => {
- if (!formState.dirty) {
- dispatch({ type: 'formResetted' });
- }
- }, [formState.dirty]);
-
- const setValue = useCallback((setter) => {
- Object.entries(setter).forEach(([name, value]) => {
- formOptions.change(name, value);
- });
- }, []);
-
- useEffect(() => {
- if (setters && setters.length > 0 && (state.initial || !isEqual(setters, state.sets))) {
- setters.forEach((setter, index) => {
- if (setter && (state.initial || !isEqual(setter, state.sets[index]))) {
- setTimeout(() => {
- /**
- * We have to get the meta in the timetout to wait for state initialization
- */
- const meta = formOptions.getFieldState(field.name);
- const isFormModified = Object.values(formOptions.getState().modified).some(Boolean);
- /**
- * Apply setter only
- * - field has no initial value
- * - form is modified
- * - when meta is false = field was unmounted before timeout, we finish the condition
- */
- if (!meta || isFormModified || typeof meta.initial === 'undefined') {
- formOptions.batch(() => {
- if (typeof setter !== 'function') {
- setValue(setter);
- } else {
- const setterValue = setter(formOptions.getState(), formOptions.getFieldState);
-
- if (setterValueCheck(setterValue)) {
- setValue(setterValue);
- } else {
- console.error('Received invalid setterValue. Expected object, received: ', setterValue);
- }
- }
- });
- }
- });
- }
- });
- dispatch({ type: 'rememberSets', sets: setters });
- }
- }, [setters, state.initial]);
-
- return conditionResult.visible ? children : null;
-};
-
-export default Condition;
diff --git a/packages/react-form-renderer/src/condition/condition.tsx b/packages/react-form-renderer/src/condition/condition.tsx
new file mode 100644
index 000000000..ee3473f56
--- /dev/null
+++ b/packages/react-form-renderer/src/condition/condition.tsx
@@ -0,0 +1,171 @@
+import React, { useCallback, useContext, useEffect, useMemo, useReducer, ReactNode } from 'react';
+import { FormState, FormApi } from 'final-form';
+import isEqual from 'lodash/isEqual';
+
+import useFormApi from '../use-form-api';
+import parseCondition from '../parse-condition';
+import RendererContext from '../renderer-context/renderer-context';
+import Field from '../common-types/field';
+
+export interface ActionResolution {
+ visible?: boolean;
+ set?: object | ((formState: FormState>, getFieldState: FormApi['getFieldState']) => object);
+}
+
+export type InnerWhenFunction = (currentField: string) => string;
+export type WhenFunction = (currentField: string) => string | string[] | InnerWhenFunction[];
+
+export interface ConditionProp {
+ when?: string | string[] | WhenFunction | InnerWhenFunction[];
+ is?: any;
+ isNotEmpty?: boolean;
+ isEmpty?: boolean;
+ pattern?: string | RegExp;
+ flags?: string;
+ notMatch?: any;
+ greaterThan?: number;
+ greaterThanOrEqualTo?: number;
+ lessThan?: number;
+ lessThanOrEqualTo?: number;
+ then?: ActionResolution;
+ else?: ActionResolution;
+ or?: ConditionProp | ConditionProp[];
+ and?: ConditionProp | ConditionProp[];
+ not?: ConditionProp | ConditionProp[];
+}
+
+export interface ConditionDefinition extends ConditionProp {
+ mappedAttributes?: {
+ is?: string[];
+ when?: string[];
+ set?: string[];
+ };
+ or?: ConditionProp | ConditionProp[];
+ and?: ConditionProp | ConditionProp[];
+ not?: ConditionProp | ConditionProp[];
+ sequence?: ConditionProp[];
+}
+
+interface ConditionState {
+ sets: object[];
+ initial: boolean;
+}
+
+interface ConditionAction {
+ type: 'formResetted' | 'rememberSets';
+ sets?: object[];
+}
+
+export interface ConditionProps {
+ // eslint-disable-next-line react/no-unused-prop-types
+ values?: object;
+ children: ReactNode;
+ condition?: ConditionDefinition | ConditionDefinition[];
+ field: Field;
+}
+
+const setterValueCheck = (setterValue: any): setterValue is object => {
+ if (setterValue === null || Array.isArray(setterValue)) {
+ console.error('Received invalid setterValue. Expected object, received: ', setterValue);
+ return false;
+ }
+
+ return typeof setterValue === 'object';
+};
+
+export const reducer = (state: ConditionState, { type, sets }: ConditionAction): ConditionState => {
+ switch (type) {
+ case 'formResetted':
+ return {
+ ...state,
+ initial: true,
+ };
+ case 'rememberSets':
+ return {
+ ...state,
+ initial: false,
+ sets: sets || [],
+ };
+ default:
+ return state;
+ }
+};
+
+const Condition: React.FC = ({ condition, children, field }) => {
+ const formOptions = useFormApi();
+ const formState = formOptions.getState();
+ const { conditionMapper } = useContext(RendererContext);
+ const [state, dispatch] = useReducer(reducer, {
+ sets: [],
+ initial: true,
+ });
+
+ // It is required to get the context state values from in order to get the latest state.
+ // Using the trigger values can cause issues with the radio field as each input is registered separately to state and does not yield the actual field value.
+ const conditionResult = useMemo(
+ () => (condition ? parseCondition(condition, formState.values, field, conditionMapper) : { visible: true, result: true }),
+ [formState.values, condition, field, conditionMapper]
+ );
+
+ const hasSetProperty = (result: any): result is { set: object } => 'set' in result;
+ const hasSetsProperty = (result: any): result is { sets: object[] } => 'sets' in result;
+
+ const setters = hasSetProperty(conditionResult) ? [conditionResult.set] : hasSetsProperty(conditionResult) ? conditionResult.sets : [];
+
+ useEffect(() => {
+ if (!formState.dirty) {
+ dispatch({ type: 'formResetted' });
+ }
+ }, [formState.dirty]);
+
+ const setValue = useCallback(
+ (setter: object) => {
+ Object.entries(setter).forEach(([name, value]) => {
+ formOptions.change(name, value);
+ });
+ },
+ [formOptions]
+ );
+
+ useEffect(() => {
+ if (setters && setters.length > 0 && (state.initial || !isEqual(setters, state.sets))) {
+ setters.forEach((setter, index) => {
+ if (setter && (state.initial || !isEqual(setter, state.sets[index]))) {
+ setTimeout(() => {
+ /**
+ * We have to get the meta in the timeout to wait for state initialization
+ */
+ const meta = formOptions.getFieldState(field.name);
+ const isFormModified = Object.values(formOptions.getState().modified || {}).some(Boolean);
+ /**
+ * Apply setter only
+ * - field has no initial value
+ * - form is modified
+ * - when meta is false = field was unmounted before timeout, we finish the condition
+ */
+ if (!meta || isFormModified || typeof meta.initial === 'undefined') {
+ formOptions.batch(() => {
+ if (typeof setter !== 'function') {
+ setValue(setter);
+ } else {
+ const setterValue = setter(formOptions.getState(), formOptions.getFieldState);
+
+ if (setterValueCheck(setterValue)) {
+ setValue(setterValue);
+ } else {
+ console.error('Received invalid setterValue. Expected object, received: ', setterValue);
+ }
+ }
+ });
+ }
+ }, 0);
+ }
+ });
+ dispatch({ type: 'rememberSets', sets: setters });
+ }
+ }, [setters, state.initial, state.sets, setValue, formOptions, field.name]);
+
+ return conditionResult.visible ? children : null;
+};
+
+export default Condition;
diff --git a/packages/react-form-renderer/src/condition/index.js b/packages/react-form-renderer/src/condition/index.js
deleted file mode 100644
index c75bf1b61..000000000
--- a/packages/react-form-renderer/src/condition/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from './condition';
-export * from './condition';
diff --git a/packages/react-form-renderer/src/condition/index.d.ts b/packages/react-form-renderer/src/condition/index.ts
similarity index 100%
rename from packages/react-form-renderer/src/condition/index.d.ts
rename to packages/react-form-renderer/src/condition/index.ts
diff --git a/packages/react-form-renderer/src/data-types/data-types.d.ts b/packages/react-form-renderer/src/data-types/data-types.d.ts
deleted file mode 100644
index 8b048e83e..000000000
--- a/packages/react-form-renderer/src/data-types/data-types.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export type DataType = 'integer'|'float'|'number'|'boolean'|'string';
-
-interface IdataTypes {
- INTEGER: 'integer';
- FLOAT: 'float';
- NUMBER: 'number';
- BOOLEAN: 'boolean';
- STRING: 'string';
-}
-
-declare const dataTypes: IdataTypes;
-
-export default dataTypes;
diff --git a/packages/react-form-renderer/src/data-types/data-types.js b/packages/react-form-renderer/src/data-types/data-types.js
deleted file mode 100644
index ded6ab31a..000000000
--- a/packages/react-form-renderer/src/data-types/data-types.js
+++ /dev/null
@@ -1,9 +0,0 @@
-const dataTypes = {
- INTEGER: 'integer',
- FLOAT: 'float',
- NUMBER: 'number',
- BOOLEAN: 'boolean',
- STRING: 'string',
-};
-
-export default dataTypes;
diff --git a/packages/react-form-renderer/src/data-types/data-types.ts b/packages/react-form-renderer/src/data-types/data-types.ts
new file mode 100644
index 000000000..193a92200
--- /dev/null
+++ b/packages/react-form-renderer/src/data-types/data-types.ts
@@ -0,0 +1,19 @@
+export type DataType = 'integer' | 'float' | 'number' | 'boolean' | 'string';
+
+interface IdataTypes {
+ INTEGER: 'integer';
+ FLOAT: 'float';
+ NUMBER: 'number';
+ BOOLEAN: 'boolean';
+ STRING: 'string';
+}
+
+const dataTypes: IdataTypes = {
+ INTEGER: 'integer',
+ FLOAT: 'float',
+ NUMBER: 'number',
+ BOOLEAN: 'boolean',
+ STRING: 'string',
+} as const;
+
+export default dataTypes;
diff --git a/packages/react-form-renderer/src/data-types/index.d.ts b/packages/react-form-renderer/src/data-types/index.d.ts
deleted file mode 100644
index 510ab5aec..000000000
--- a/packages/react-form-renderer/src/data-types/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from './data-types';
-export * from './data-types';
diff --git a/packages/react-form-renderer/src/data-types/index.js b/packages/react-form-renderer/src/data-types/index.js
deleted file mode 100644
index 3cc1133f9..000000000
--- a/packages/react-form-renderer/src/data-types/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './data-types';
diff --git a/packages/react-form-renderer/src/data-types/index.ts b/packages/react-form-renderer/src/data-types/index.ts
new file mode 100644
index 000000000..51d5066ec
--- /dev/null
+++ b/packages/react-form-renderer/src/data-types/index.ts
@@ -0,0 +1 @@
+export { default, DataType } from './data-types';
diff --git a/packages/react-form-renderer/src/default-schema-validator/default-schema-validator.d.ts b/packages/react-form-renderer/src/default-schema-validator/default-schema-validator.d.ts
deleted file mode 100644
index 599e33c1f..000000000
--- a/packages/react-form-renderer/src/default-schema-validator/default-schema-validator.d.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import Schema from '../common-types/schema';
-import ComponentMapper from '../common-types/component-mapper';
-import SchemaValidatorMapper from '../common-types/schema-validator-mapper';
-
-export default function(
- schema: Schema,
- componentMapper: ComponentMapper,
- validatorTypes: string[],
- actionTypes: string[],
- schemaValidatorMapper: SchemaValidatorMapper
-): void;
diff --git a/packages/react-form-renderer/src/default-schema-validator/default-schema-validator.js b/packages/react-form-renderer/src/default-schema-validator/default-schema-validator.ts
similarity index 78%
rename from packages/react-form-renderer/src/default-schema-validator/default-schema-validator.js
rename to packages/react-form-renderer/src/default-schema-validator/default-schema-validator.ts
index 011cc9065..ad0c59ba7 100644
--- a/packages/react-form-renderer/src/default-schema-validator/default-schema-validator.js
+++ b/packages/react-form-renderer/src/default-schema-validator/default-schema-validator.ts
@@ -1,12 +1,31 @@
/* eslint-disable no-prototype-builtins */
import DefaultSchemaError from '../schema-errors';
-//import isValidComponent from './isValidComponent';
import componentTypes from '../component-types';
import dataTypes from '../data-types';
+import Schema from '../common-types/schema';
+import ComponentMapper from '../common-types/component-mapper';
+import SchemaValidatorMapper from '../common-types/schema-validator-mapper';
+import Field from '../common-types/field';
const componentBlackList = [componentTypes.FIELD_ARRAY, 'tab-item'];
-const checkFieldsArray = (obj, objectKey) => {
+interface ObjectWithFields {
+ fields?: any;
+}
+
+interface ConditionalAction {
+ visible?: any;
+ set?: any;
+}
+
+// Using ConditionDefinition from the condition module
+
+interface ValidatorDefinition {
+ type?: string;
+ [key: string]: any;
+}
+
+const checkFieldsArray = (obj: ObjectWithFields, objectKey: string): void => {
if (!obj.hasOwnProperty('fields')) {
throw new DefaultSchemaError(`Component of type ${objectKey} must contain "fields" property of type array, received undefined!`);
}
@@ -16,7 +35,7 @@ const checkFieldsArray = (obj, objectKey) => {
}
};
-const checkConditionalAction = (type, action, fieldName) => {
+const checkConditionalAction = (type: string, action: ConditionalAction, fieldName: string): void => {
if (action.hasOwnProperty('visible') && typeof action.visible !== 'boolean') {
throw new DefaultSchemaError(`
Error occured in field definition with "name" property: "${fieldName}".
@@ -34,7 +53,7 @@ const checkConditionalAction = (type, action, fieldName) => {
const requiredOneOf = ['is', 'isEmpty', 'isNotEmpty', 'pattern', 'greaterThan', 'greaterThanOrEqualTo', 'lessThan', 'lessThanOrEqualTo'];
-const checkMappedAttributes = (condition) => {
+const checkMappedAttributes = (condition: any): boolean => {
const hasStaticAttribute = requiredOneOf.some((key) => condition.hasOwnProperty(key));
if (hasStaticAttribute) {
return true;
@@ -46,11 +65,13 @@ const checkMappedAttributes = (condition) => {
!Array.isArray(condition.mappedAttributes) &&
condition.mappedAttributes !== null
) {
- return requiredOneOf.some((key) => condition.mappedAttributes.hasOwnProperty(key));
+ return requiredOneOf.some((key) => condition.mappedAttributes!.hasOwnProperty(key));
}
+
+ return false;
};
-const checkCondition = (condition, fieldName, isRoot) => {
+const checkCondition = (condition: any, fieldName: string, isRoot?: boolean | string): void => {
/**
* validate array condition
*/
@@ -94,11 +115,11 @@ const checkCondition = (condition, fieldName, isRoot) => {
}
if (condition.hasOwnProperty('then')) {
- checkConditionalAction('then', condition.then, fieldName);
+ checkConditionalAction('then', condition.then!, fieldName);
}
if (condition.hasOwnProperty('else')) {
- checkConditionalAction('else', condition.else, fieldName);
+ checkConditionalAction('else', condition.else!, fieldName);
}
if (typeof condition !== 'object') {
@@ -148,23 +169,28 @@ const checkCondition = (condition, fieldName, isRoot) => {
if (condition.hasOwnProperty('pattern') && !(condition.pattern instanceof RegExp) && typeof condition.pattern !== 'string') {
throw new DefaultSchemaError(`
Error occured in field definition with name: "${fieldName}".
- Field condition must have "pattern" of instance "RegExp" or "string"! Instance received: [${condition.pattern.constructor.name}].
+ Field condition must have "pattern" of instance "RegExp" or "string"! Instance received: [${(condition.pattern as any).constructor.name}].
`);
}
} else {
['and', 'or', 'not'].forEach((key) => {
if (condition.hasOwnProperty(key)) {
- checkCondition(condition[key], fieldName);
+ checkCondition((condition as any)[key], fieldName);
}
});
if (condition.hasOwnProperty('sequence')) {
- condition.sequence.forEach((item) => checkCondition(item, fieldName, 'root'));
+ condition.sequence!.forEach((item: any) => checkCondition(item, fieldName, 'root'));
}
}
};
-const checkValidators = (validate, fieldName, validatorTypes, validatorMapper = {}) => {
+const checkValidators = (
+ validate: ValidatorDefinition[] | Function[],
+ fieldName: string,
+ validatorTypes: string[],
+ validatorMapper: Record = {}
+): void => {
if (validate === undefined) {
return;
}
@@ -185,29 +211,30 @@ const checkValidators = (validate, fieldName, validatorTypes, validatorMapper =
}
if (typeof validator !== 'function') {
- if (!validator.hasOwnProperty('type')) {
+ const validatorObj = validator as ValidatorDefinition;
+ if (!validatorObj.hasOwnProperty('type')) {
throw new DefaultSchemaError(`
Error occured in field definition with name: "${fieldName}".
- Field validator at index: ${index} does not have "type" property! Properties received: [${Object.keys(validator)}].
+ Field validator at index: ${index} does not have "type" property! Properties received: [${Object.keys(validatorObj)}].
`);
}
- if (!validatorTypes.includes(validator.type)) {
+ if (!validatorTypes.includes(validatorObj.type!)) {
throw new DefaultSchemaError(`
Error occured in field definition with name: "${fieldName}".
Field validator at index: ${index} does not have correct "type" property!
- Received "${validator.type}", expected one of: [${validatorTypes}].
+ Received "${validatorObj.type}", expected one of: [${validatorTypes}].
`);
}
- if (validatorMapper.hasOwnProperty(validator.type)) {
- validatorMapper[validator.type](validator, fieldName);
+ if (validatorMapper.hasOwnProperty(validatorObj.type!)) {
+ validatorMapper[validatorObj.type!](validatorObj, fieldName);
}
}
});
};
-const checkDataType = (type, fieldName) => {
+const checkDataType = (type: string, fieldName: string): void => {
if (typeof type !== 'string') {
throw new DefaultSchemaError(`
Error occured in field definition with name: "${fieldName}".
@@ -215,7 +242,7 @@ const checkDataType = (type, fieldName) => {
`);
}
- if (!Object.values(dataTypes).includes(type)) {
+ if (!Object.values(dataTypes).includes(type as any)) {
throw new DefaultSchemaError(`
Error occured in field definition with name: "${fieldName}".
Unknow dataType ${type}. Must be one these values: ${Object.values(dataTypes)}
@@ -223,7 +250,7 @@ const checkDataType = (type, fieldName) => {
}
};
-const checkActions = (actions, name, actionTypes, actionsValidator = {}) => {
+const checkActions = (actions: Record, name: string, actionTypes: string[], actionsValidator: Record = {}): void => {
Object.keys(actions).forEach((prop) => {
if (!Array.isArray(actions[prop])) {
throw new DefaultSchemaError(`
@@ -255,13 +282,20 @@ const checkActions = (actions, name, actionTypes, actionsValidator = {}) => {
});
};
-const iterateOverFields = (fields, componentMapper, validatorTypes, actionTypes, schemaValidatorMapper, parent = {}) => {
+const iterateOverFields = (
+ fields: (Field | Field[])[],
+ componentMapper: ComponentMapper,
+ validatorTypes: string[],
+ actionTypes: string[],
+ schemaValidatorMapper: SchemaValidatorMapper,
+ parent: Partial = {}
+): void => {
fields.forEach((field) => {
if (Array.isArray(field)) {
return iterateOverFields(field, componentMapper, validatorTypes, actionTypes, schemaValidatorMapper);
}
- if (![componentTypes.WIZARD, componentTypes.TABS].includes(parent.component)) {
+ if (![componentTypes.WIZARD, componentTypes.TABS].includes(parent.component as any)) {
if (parent.component !== componentTypes.WIZARD && !field.hasOwnProperty('component')) {
throw new DefaultSchemaError(`Each fields item must have "component" property!`);
}
@@ -287,23 +321,23 @@ const iterateOverFields = (fields, componentMapper, validatorTypes, actionTypes,
}
if (field.hasOwnProperty('condition')) {
- checkCondition(field.condition, field.name, 'root');
+ checkCondition(field.condition!, field.name, 'root');
}
if (field.hasOwnProperty('validate')) {
- checkValidators(field.validate, field.name, validatorTypes, schemaValidatorMapper.validators);
+ checkValidators(field.validate!, field.name, validatorTypes, schemaValidatorMapper.validators);
}
if (field.hasOwnProperty('dataType')) {
- checkDataType(field.dataType, field.name);
+ checkDataType(field.dataType!, field.name);
}
if (field.hasOwnProperty('fields')) {
- iterateOverFields(field.fields, componentMapper, validatorTypes, actionTypes, schemaValidatorMapper, field);
+ iterateOverFields((field as any).fields, componentMapper, validatorTypes, actionTypes, schemaValidatorMapper, field);
}
if (field.hasOwnProperty('actions')) {
- checkActions(field.actions, field.name, actionTypes, schemaValidatorMapper.actions);
+ checkActions((field as any).actions, field.name, actionTypes, schemaValidatorMapper.actions);
}
if (schemaValidatorMapper.components && schemaValidatorMapper.components.hasOwnProperty(field.component)) {
@@ -312,7 +346,13 @@ const iterateOverFields = (fields, componentMapper, validatorTypes, actionTypes,
});
};
-const defaultSchemaValidator = (schema, componentMapper, validatorTypes = [], actionTypes = [], schemaValidatorMapper = {}) => {
+const defaultSchemaValidator = (
+ schema: Schema,
+ componentMapper: ComponentMapper,
+ validatorTypes: string[] = [],
+ actionTypes: string[] = [],
+ schemaValidatorMapper: SchemaValidatorMapper = {}
+): void => {
if (Array.isArray(schema) || typeof schema !== 'object') {
throw new DefaultSchemaError(`Form Schema must be an object, received ${Array.isArray(schema) ? 'array' : typeof schema}!`);
}
diff --git a/packages/react-form-renderer/src/default-schema-validator/index.js b/packages/react-form-renderer/src/default-schema-validator/index.js
deleted file mode 100644
index 17ba66dcb..000000000
--- a/packages/react-form-renderer/src/default-schema-validator/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './default-schema-validator';
diff --git a/packages/react-form-renderer/src/default-schema-validator/index.d.ts b/packages/react-form-renderer/src/default-schema-validator/index.ts
similarity index 100%
rename from packages/react-form-renderer/src/default-schema-validator/index.d.ts
rename to packages/react-form-renderer/src/default-schema-validator/index.ts
diff --git a/packages/react-form-renderer/src/field-array/field-array.d.ts b/packages/react-form-renderer/src/field-array/field-array.d.ts
deleted file mode 100644
index ce2609b29..000000000
--- a/packages/react-form-renderer/src/field-array/field-array.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { FieldArrayProps } from 'react-final-form-arrays';
-import Field from '../common-types/field';
-
-export interface FieldArrayField extends Omit {
- name?: string;
-}
-
-declare const FieldArray: React.ComponentType>;
-
-export default FieldArray;
diff --git a/packages/react-form-renderer/src/field-array/field-array.js b/packages/react-form-renderer/src/field-array/field-array.ts
similarity index 100%
rename from packages/react-form-renderer/src/field-array/field-array.js
rename to packages/react-form-renderer/src/field-array/field-array.ts
diff --git a/packages/react-form-renderer/src/field-array/index.d.ts b/packages/react-form-renderer/src/field-array/index.d.ts
deleted file mode 100644
index 2dbda3dc9..000000000
--- a/packages/react-form-renderer/src/field-array/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from './field-array';
-export * from './field-array';
diff --git a/packages/react-form-renderer/src/field-array/index.js b/packages/react-form-renderer/src/field-array/index.ts
similarity index 100%
rename from packages/react-form-renderer/src/field-array/index.js
rename to packages/react-form-renderer/src/field-array/index.ts
diff --git a/packages/react-form-renderer/src/field-provider/field-provider.d.ts b/packages/react-form-renderer/src/field-provider/field-provider.d.ts
deleted file mode 100644
index e26369218..000000000
--- a/packages/react-form-renderer/src/field-provider/field-provider.d.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { ComponentType, ReactNode } from 'react';
-
-export interface FieldProviderProps {
- Component?: ComponentType;
- render?: (props: T) => ReactNode;
- skipRegistration?: boolean;
-}
-
-declare const FieldProvider: React.ComponentType>;
-
-export default FieldProvider;
diff --git a/packages/react-form-renderer/src/field-provider/field-provider.js b/packages/react-form-renderer/src/field-provider/field-provider.js
deleted file mode 100644
index 50f09b6af..000000000
--- a/packages/react-form-renderer/src/field-provider/field-provider.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-
-import useFieldApi from '../use-field-api';
-
-const FieldProvider = ({ Component, render, ...props }) => {
- const fieldProviderProps = useFieldApi(props);
- if (Component) {
- return ;
- }
-
- if (render) {
- return render({ ...fieldProviderProps });
- }
-
- throw new Error('Field provider is missing either Component or render prop.');
-};
-
-export default FieldProvider;
diff --git a/packages/react-form-renderer/src/field-provider/field-provider.tsx b/packages/react-form-renderer/src/field-provider/field-provider.tsx
new file mode 100644
index 000000000..7759c7ced
--- /dev/null
+++ b/packages/react-form-renderer/src/field-provider/field-provider.tsx
@@ -0,0 +1,23 @@
+import React, { ComponentType } from 'react';
+import useFieldApi, { UseFieldApiConfig } from '../use-field-api';
+
+interface FieldProviderProps extends UseFieldApiConfig {
+ Component?: ComponentType;
+ render?: (props: any) => React.ReactNode;
+}
+
+const FieldProvider: React.FC = ({ Component, render, ...props }) => {
+ const fieldProviderProps = useFieldApi(props);
+
+ if (Component) {
+ return ;
+ }
+
+ if (render) {
+ return render({ ...fieldProviderProps });
+ }
+
+ throw new Error('Field provider is missing either Component or render prop.');
+};
+
+export default FieldProvider;
diff --git a/packages/react-form-renderer/src/field-provider/index.d.ts b/packages/react-form-renderer/src/field-provider/index.d.ts
deleted file mode 100644
index 69ca0c813..000000000
--- a/packages/react-form-renderer/src/field-provider/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from './field-provider';
-export * from './field-provider';
diff --git a/packages/react-form-renderer/src/field-provider/index.js b/packages/react-form-renderer/src/field-provider/index.ts
similarity index 100%
rename from packages/react-form-renderer/src/field-provider/index.js
rename to packages/react-form-renderer/src/field-provider/index.ts
diff --git a/packages/react-form-renderer/src/form-error/form-error.d.ts b/packages/react-form-renderer/src/form-error/form-error.d.ts
deleted file mode 100644
index d59b5d470..000000000
--- a/packages/react-form-renderer/src/form-error/form-error.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export const FormError: 'FINAL_FORM/form-error'
-
-export default FormError;
diff --git a/packages/react-form-renderer/src/form-error/form-error.js b/packages/react-form-renderer/src/form-error/form-error.ts
similarity index 100%
rename from packages/react-form-renderer/src/form-error/form-error.js
rename to packages/react-form-renderer/src/form-error/form-error.ts
diff --git a/packages/react-form-renderer/src/form-error/index.js b/packages/react-form-renderer/src/form-error/index.js
deleted file mode 100644
index a35c3a755..000000000
--- a/packages/react-form-renderer/src/form-error/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './form-error';
diff --git a/packages/react-form-renderer/src/form-error/index.d.ts b/packages/react-form-renderer/src/form-error/index.ts
similarity index 100%
rename from packages/react-form-renderer/src/form-error/index.d.ts
rename to packages/react-form-renderer/src/form-error/index.ts
diff --git a/packages/react-form-renderer/src/form-renderer/action-mapper.d.ts b/packages/react-form-renderer/src/form-renderer/action-mapper.ts
similarity index 52%
rename from packages/react-form-renderer/src/form-renderer/action-mapper.d.ts
rename to packages/react-form-renderer/src/form-renderer/action-mapper.ts
index b14385c0e..f7926de96 100644
--- a/packages/react-form-renderer/src/form-renderer/action-mapper.d.ts
+++ b/packages/react-form-renderer/src/form-renderer/action-mapper.ts
@@ -1,3 +1,7 @@
export interface ActionMapper {
[key: string]: (...args: any[]) => any;
}
+
+const actionMapper: ActionMapper = {};
+
+export default actionMapper;
diff --git a/packages/react-form-renderer/src/form-renderer/condition-mapper.d.ts b/packages/react-form-renderer/src/form-renderer/condition-mapper.ts
similarity index 51%
rename from packages/react-form-renderer/src/form-renderer/condition-mapper.d.ts
rename to packages/react-form-renderer/src/form-renderer/condition-mapper.ts
index 304df3b0e..b8dd28627 100644
--- a/packages/react-form-renderer/src/form-renderer/condition-mapper.d.ts
+++ b/packages/react-form-renderer/src/form-renderer/condition-mapper.ts
@@ -1,5 +1,9 @@
-import { ConditionDefinition } from "../condition";
+import { ConditionDefinition } from '../condition';
export interface ConditionMapper {
[key: string]: (...args: any[]) => (value: any, conditionConfig: ConditionDefinition) => boolean;
}
+
+const conditionMapper: ConditionMapper = {};
+
+export default conditionMapper;
diff --git a/packages/react-form-renderer/src/form-renderer/form-renderer.d.ts b/packages/react-form-renderer/src/form-renderer/form-renderer.d.ts
deleted file mode 100644
index 27c73375c..000000000
--- a/packages/react-form-renderer/src/form-renderer/form-renderer.d.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { ComponentType, ReactElement, FunctionComponent, ReactNode } from 'react';
-import { FormProps } from 'react-final-form';
-import Schema from '../common-types/schema';
-import ComponentMapper from '../common-types/component-mapper';
-import { ValidatorMapper } from '../validator-mapper';
-import { ActionMapper } from './action-mapper';
-import SchemaValidatorMapper from '../common-types/schema-validator-mapper';
-import { FormTemplateRenderProps } from '../common-types/form-template-render-props';
-import { NoIndex } from '../common-types/no-index';
-import { ConditionMapper } from './condition-mapper';
-
-export interface FormRendererProps<
- FormValues = Record,
- InitialFormValues = Partial,
- FormTemplateProps extends FormTemplateRenderProps = FormTemplateRenderProps
-> extends Omit