Skip to content

Commit babea18

Browse files
committed
feat: implemented fields extend & removed elementsMap
1 parent a550b96 commit babea18

File tree

7 files changed

+67
-25
lines changed

7 files changed

+67
-25
lines changed

packages/ui/src/components/organisms/Form/DynamicForm/DynamicForm.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ import { useFieldHelpers } from './hooks/internal/useFieldHelpers';
88
import { useTouched } from './hooks/internal/useTouched';
99
import { useValidationSchema } from './hooks/internal/useValidationSchema';
1010
import { useValues } from './hooks/internal/useValues';
11+
import { extendFieldsRepository, getFieldsRepository } from './repositories';
1112
import { IDynamicFormProps } from './types';
1213

1314
export const DynamicFormV2: FunctionComponent<IDynamicFormProps> = ({
1415
elements,
1516
values: initialValues,
1617
validationParams,
17-
elementsMap,
18+
fieldExtends,
1819
onChange,
1920
onFieldChange,
2021
onSubmit,
@@ -36,18 +37,18 @@ export const DynamicFormV2: FunctionComponent<IDynamicFormProps> = ({
3637
values: valuesApi.values,
3738
submit,
3839
fieldHelpers,
39-
elementsMap,
40+
elementsMap: fieldExtends ? extendFieldsRepository(fieldExtends) : getFieldsRepository(),
4041
callbacks: {
4142
onEvent,
4243
},
4344
}),
44-
[touchedApi.touched, valuesApi.values, submit, fieldHelpers, elementsMap, onEvent],
45+
[touchedApi.touched, valuesApi.values, submit, fieldHelpers, fieldExtends, onEvent],
4546
);
4647

4748
return (
4849
<DynamicFormContext.Provider value={context}>
4950
<ValidatorProvider schema={validationSchema} value={context.values} {...validationParams}>
50-
<Renderer elements={elements} schema={elementsMap as unknown as TRendererSchema} />
51+
<Renderer elements={elements} schema={context.elementsMap as unknown as TRendererSchema} />
5152
</ValidatorProvider>
5253
</DynamicFormContext.Provider>
5354
);

packages/ui/src/components/organisms/Form/DynamicForm/DynamicForm.unit.test.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { useFieldHelpers } from './hooks/internal/useFieldHelpers';
99
import { useTouched } from './hooks/internal/useTouched';
1010
import { useValidationSchema } from './hooks/internal/useValidationSchema';
1111
import { useValues } from './hooks/internal/useValues';
12-
import { ICommonFieldParams, IDynamicFormProps, IFormElement, TBaseFormElements } from './types';
12+
import { ICommonFieldParams, IDynamicFormProps, IFormElement } from './types';
1313

1414
// Mock dependencies
1515
vi.mock('../../Renderer');
@@ -75,20 +75,19 @@ describe('DynamicFormV2', () => {
7575
elements: [],
7676
values: {},
7777
validationParams: {},
78-
elementsMap: {},
7978
onChange: vi.fn(),
8079
onFieldChange: vi.fn(),
8180
onSubmit: vi.fn(),
8281
onEvent: vi.fn(),
83-
} as unknown as IDynamicFormProps<object, TBaseFormElements>;
82+
} as unknown as IDynamicFormProps;
8483

8584
it('should render without crashing', () => {
8685
render(<DynamicFormV2 {...mockProps} />);
8786
});
8887

8988
it('should pass elements to useValidationSchema', () => {
90-
const elements = [{ id: 'test', element: 'text' }] as unknown as Array<
91-
IFormElement<TBaseFormElements, ICommonFieldParams>
89+
const elements = [{ id: 'test', element: 'textfield' }] as unknown as Array<
90+
IFormElement<string, ICommonFieldParams>
9291
>;
9392
render(<DynamicFormV2 {...mockProps} elements={elements} />);
9493
expect(useValidationSchema).toHaveBeenCalledWith(elements);
@@ -127,6 +126,7 @@ describe('DynamicFormV2', () => {
127126
onSubmit: mockProps.onSubmit,
128127
});
129128
});
129+
130130
it('should pass context to DynamicFormContext.Provider', () => {
131131
const touchedMock = {
132132
touched: { field1: true },
@@ -162,7 +162,7 @@ describe('DynamicFormV2', () => {
162162
values: valuesMock.values,
163163
submit: submitMock.submit,
164164
fieldHelpers: fieldHelpersMock,
165-
elementsMap: mockProps.elementsMap,
165+
elementsMap: mockProps.fieldExtends ? expect.any(Object) : expect.any(Object),
166166
callbacks: {
167167
onEvent: mockProps.onEvent,
168168
},

packages/ui/src/components/organisms/Form/DynamicForm/hooks/internal/useTouched/useTouched.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { IFormElement } from '../../../types';
33
import { generateTouchedMapForAllElements } from './helpers/generate-touched-map-for-all-elements/generate-touched-map-for-all-elements';
44
import { ITouchedState } from './types';
55

6-
export const useTouched = (elements: IFormElement[], context: object) => {
6+
export const useTouched = (elements: Array<IFormElement<any, any>>, context: object) => {
77
const [touched, setTouchedState] = useState<ITouchedState>({});
88

99
const setFieldTouched = useCallback((fieldName: string, isTouched: boolean) => {

packages/ui/src/components/organisms/Form/DynamicForm/hooks/internal/useValidationSchema/useValidationSchema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useMemo } from 'react';
33
import { convertFormElementsToValidationSchema } from '../../../helpers/convert-form-emenents-to-validation-schema';
44
import { IFormElement } from '../../../types';
55

6-
export const useValidationSchema = (elements: IFormElement[]) => {
6+
export const useValidationSchema = (elements: Array<IFormElement<any, any>>) => {
77
const validationSchema = useMemo(() => {
88
return convertFormElementsToValidationSchema(elements);
99
}, [elements]);
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { AutocompleteField } from '../fields/AutocompleteField';
2+
import { CheckboxField } from '../fields/CheckboxField';
3+
import { CheckboxListField } from '../fields/CheckboxList';
4+
import { DateField } from '../fields/DateField';
5+
import { FieldList } from '../fields/FieldList';
6+
import { MultiselectField } from '../fields/MultiselectField';
7+
import { TextField } from '../fields/TextField';
8+
import { TDynamicFormField } from '../types';
9+
10+
export const baseFields = {
11+
autocompletefield: AutocompleteField,
12+
checkboxfield: CheckboxField,
13+
checkboxlistfield: CheckboxListField,
14+
datefield: DateField,
15+
multiselectfield: MultiselectField,
16+
textfield: TextField,
17+
fieldlist: FieldList,
18+
} as const;
19+
20+
export type TBaseFields = keyof typeof baseFields & string;
21+
22+
export let fieldsRepository = {
23+
...baseFields,
24+
};
25+
26+
export const getField = <T extends keyof typeof fieldsRepository>(fieldType: T) => {
27+
return fieldsRepository[fieldType];
28+
};
29+
30+
export const extendFieldsRepository = <TNewFields extends string, TParams = unknown>(
31+
fields: Record<TNewFields, TDynamicFormField<TNewFields | TBaseFields, TParams>>,
32+
) => {
33+
const updatedRepository = { ...fieldsRepository, ...fields };
34+
fieldsRepository = updatedRepository;
35+
36+
return updatedRepository;
37+
};
38+
39+
export const getFieldsRepository = <
40+
TElements extends string = TBaseFields,
41+
TParams = unknown,
42+
>() => {
43+
return fieldsRepository as Record<TElements, TDynamicFormField<TElements, TParams>>;
44+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './fields-repository';

packages/ui/src/components/organisms/Form/DynamicForm/types/index.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ import { IRule } from '../../hooks/useRuleEngine';
33
import { IValidationError, IValidationParams, TValidators } from '../../Validator';
44
import { IFormEventElement, TElementEvent } from '../hooks/internal/useEvents/types';
55

6-
export type TBaseFormElements = 'textinput' | 'fieldlist';
7-
86
export interface ICommonFieldParams {
97
label?: string;
108
placeholder?: string;
119
}
1210

13-
export interface IFormElement<TElements = TBaseFormElements, TParams = ICommonFieldParams> {
11+
export interface IFormElement<TElements = string, TParams = ICommonFieldParams> {
1412
id: string;
1513
valueDestination: string;
1614
element: TElements;
@@ -31,35 +29,33 @@ export interface IFormRef<TValues = object> {
3129
}
3230

3331
export type TDynamicFormElement<
34-
TElements extends string = TBaseFormElements,
32+
TElements extends string = string,
3533
TParams = unknown,
3634
> = FunctionComponent<{
3735
element: IFormElement<TElements, TParams>;
3836
}>;
3937

4038
export type TDynamicFormField<
41-
TElements extends string = TBaseFormElements,
39+
TElements extends string = string,
4240
TParams = ICommonFieldParams,
4341
> = FunctionComponent<{
4442
element: IFormElement<TElements, TParams>;
4543
children?: React.ReactNode | React.ReactNode[];
4644
}>;
4745

48-
export type TElementsMap<TElements extends string = TBaseFormElements> = Record<
49-
TElements,
50-
TDynamicFormElement
51-
>;
46+
export type TElementsMap = Record<string, TDynamicFormElement<any, any>>;
5247

53-
export interface IDynamicFormProps<TValues = object, TElements extends string = TBaseFormElements> {
48+
export interface IDynamicFormProps<TValues = object> {
5449
values: TValues;
55-
elements: Array<IFormElement<TElements>>;
56-
elementsMap: TElementsMap<TElements>;
50+
elements: Array<IFormElement<string, any>>;
51+
52+
fieldExtends?: Record<string, TDynamicFormField<string>>;
5753

5854
validationParams?: IValidationParams;
5955
onChange?: (newValues: TValues) => void;
6056
onFieldChange?: (fieldName: string, newValue: unknown, newValues: TValues) => void;
6157
onSubmit?: (values: TValues) => void;
62-
onEvent?: (eventName: TElementEvent, element: IFormEventElement<TElements>) => void;
58+
onEvent?: (eventName: TElementEvent, element: IFormEventElement<string, any>) => void;
6359

6460
ref?: React.RefObject<IFormRef<TValues>>;
6561
}

0 commit comments

Comments
 (0)