Skip to content

Commit 7cdfc87

Browse files
authored
feat: added v2 adapters for custom fields & updated exports from ui & added tests (#2913)
1 parent b34891c commit 7cdfc87

File tree

21 files changed

+646
-2
lines changed

21 files changed

+646
-2
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { getCountries } from '@/helpers/countries-data';
2+
import { useLanguageParam } from '@/hooks/useLanguageParam/useLanguageParam';
3+
import { IFormElement, ISelectFieldParams, SelectField, TDynamicFormField } from '@ballerine/ui';
4+
import { useMemo } from 'react';
5+
6+
export const COUNTRY_PICKER_FIELD_TYPE = 'countrypickerfield';
7+
8+
export const CountryPickerField: TDynamicFormField<ISelectFieldParams> = ({ element }) => {
9+
const { language } = useLanguageParam();
10+
11+
const elementDefinitionWithCountryList: IFormElement<
12+
typeof COUNTRY_PICKER_FIELD_TYPE,
13+
ISelectFieldParams
14+
> = useMemo(() => {
15+
return {
16+
...element,
17+
element: COUNTRY_PICKER_FIELD_TYPE,
18+
params: {
19+
...element.params,
20+
options: getCountries(language).map(country => ({
21+
value: country.const,
22+
label: country.title,
23+
})),
24+
},
25+
};
26+
}, [element, language]);
27+
28+
return <SelectField element={elementDefinitionWithCountryList} />;
29+
};
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { getCountries } from '@/helpers/countries-data';
2+
import { useLanguageParam } from '@/hooks/useLanguageParam/useLanguageParam';
3+
import { IFormElement, ISelectFieldParams } from '@ballerine/ui';
4+
import { render, screen } from '@testing-library/react';
5+
import { describe, expect, it, vi } from 'vitest';
6+
import { COUNTRY_PICKER_FIELD_TYPE, CountryPickerField } from './CountryPicker';
7+
8+
// Mock dependencies
9+
vi.mock('@/helpers/countries-data');
10+
vi.mock('@/hooks/useLanguageParam/useLanguageParam');
11+
vi.mock('@ballerine/ui', () => ({
12+
SelectField: ({ element }: { element: any }) => (
13+
<div data-testid="select-field">{JSON.stringify(element)}</div>
14+
),
15+
}));
16+
17+
describe('CountryPickerField', () => {
18+
const mockElement = {
19+
params: {},
20+
} as IFormElement<typeof COUNTRY_PICKER_FIELD_TYPE, ISelectFieldParams>;
21+
22+
const mockCountries = [
23+
{ const: 'US', title: 'United States' },
24+
{ const: 'GB', title: 'United Kingdom' },
25+
];
26+
27+
beforeEach(() => {
28+
vi.mocked(getCountries).mockReturnValue(mockCountries);
29+
vi.mocked(useLanguageParam).mockReturnValue({ language: 'en', setLanguage: vi.fn() });
30+
});
31+
32+
it('renders SelectField with transformed country options', () => {
33+
render(<CountryPickerField element={mockElement} />);
34+
35+
const selectField = screen.getByTestId('select-field');
36+
const elementProp = JSON.parse(selectField.textContent || '');
37+
38+
expect(elementProp).toEqual({
39+
element: COUNTRY_PICKER_FIELD_TYPE,
40+
params: {
41+
options: [
42+
{ value: 'US', label: 'United States' },
43+
{ value: 'GB', label: 'United Kingdom' },
44+
],
45+
},
46+
});
47+
});
48+
49+
it('uses language from useLanguageParam hook to get countries', () => {
50+
vi.mocked(useLanguageParam).mockReturnValue({ language: 'cn', setLanguage: vi.fn() });
51+
52+
render(<CountryPickerField element={mockElement} />);
53+
54+
expect(getCountries).toHaveBeenCalledWith('cn');
55+
});
56+
57+
it('preserves existing element params while adding options', () => {
58+
const elementWithParams = {
59+
...mockElement,
60+
params: {
61+
placeholder: 'Select a country',
62+
},
63+
} as IFormElement<typeof COUNTRY_PICKER_FIELD_TYPE, ISelectFieldParams>;
64+
65+
render(<CountryPickerField element={elementWithParams} />);
66+
67+
const selectField = screen.getByTestId('select-field');
68+
const elementProp = JSON.parse(selectField.textContent || '');
69+
70+
expect((elementProp as any).params).toEqual({
71+
placeholder: 'Select a country',
72+
options: [
73+
{ value: 'US', label: 'United States' },
74+
{ value: 'GB', label: 'United Kingdom' },
75+
],
76+
});
77+
});
78+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './CountryPicker';
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { IFormElement, ISelectFieldParams, SelectField, TDynamicFormField } from '@ballerine/ui';
2+
import { useMemo } from 'react';
3+
import { useTranslation } from 'react-i18next';
4+
5+
export const INDUSTRIES_PICKER_FIELD_TYPE = 'industriespickerfield';
6+
7+
export const IndustriesPickerField: TDynamicFormField<ISelectFieldParams> = ({ element }) => {
8+
const { t } = useTranslation();
9+
10+
const translatedIndustries = t('industries', { returnObjects: true }) as string[];
11+
12+
const elementDefinitionWithIndustriesList: IFormElement<
13+
typeof INDUSTRIES_PICKER_FIELD_TYPE,
14+
ISelectFieldParams
15+
> = useMemo(() => {
16+
return {
17+
...element,
18+
element: INDUSTRIES_PICKER_FIELD_TYPE,
19+
params: {
20+
...element.params,
21+
options: translatedIndustries.map(industry => ({
22+
value: industry,
23+
label: industry,
24+
})),
25+
},
26+
};
27+
}, [element, translatedIndustries]);
28+
29+
return <SelectField element={elementDefinitionWithIndustriesList} />;
30+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { IFormElement, ISelectFieldParams } from '@ballerine/ui';
2+
import { render, screen } from '@testing-library/react';
3+
import { describe, expect, it, vi } from 'vitest';
4+
import { INDUSTRIES_PICKER_FIELD_TYPE, IndustriesPickerField } from './IndustriesPicker';
5+
6+
// Mock dependencies
7+
vi.mock('react-i18next', () => ({
8+
useTranslation: () => ({
9+
t: vi.fn().mockReturnValue(['Industry1', 'Industry2']),
10+
}),
11+
}));
12+
13+
vi.mock('@ballerine/ui', () => ({
14+
SelectField: ({ element }: { element: any }) => (
15+
<div data-testid="select-field">{JSON.stringify(element)}</div>
16+
),
17+
}));
18+
19+
describe('IndustriesPickerField', () => {
20+
const mockElement = {
21+
params: {},
22+
} as IFormElement<typeof INDUSTRIES_PICKER_FIELD_TYPE, ISelectFieldParams>;
23+
24+
it('renders SelectField with transformed industry options', () => {
25+
render(<IndustriesPickerField element={mockElement} />);
26+
27+
const selectField = screen.getByTestId('select-field');
28+
const elementProp = JSON.parse(selectField.textContent || '');
29+
30+
expect(elementProp).toEqual({
31+
element: INDUSTRIES_PICKER_FIELD_TYPE,
32+
params: {
33+
options: [
34+
{ value: 'Industry1', label: 'Industry1' },
35+
{ value: 'Industry2', label: 'Industry2' },
36+
],
37+
},
38+
});
39+
});
40+
41+
it('preserves existing element params while adding options', () => {
42+
const elementWithParams = {
43+
...mockElement,
44+
params: {
45+
placeholder: 'Select an industry',
46+
},
47+
} as IFormElement<typeof INDUSTRIES_PICKER_FIELD_TYPE, ISelectFieldParams>;
48+
49+
render(<IndustriesPickerField element={elementWithParams} />);
50+
51+
const selectField = screen.getByTestId('select-field');
52+
const elementProp = JSON.parse(selectField.textContent || '');
53+
54+
expect((elementProp as any).params).toEqual({
55+
placeholder: 'Select an industry',
56+
options: [
57+
{ value: 'Industry1', label: 'Industry1' },
58+
{ value: 'Industry2', label: 'Industry2' },
59+
],
60+
});
61+
});
62+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './IndustriesPicker';
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { IFormElement, ISelectFieldParams, SelectField, TDynamicFormField } from '@ballerine/ui';
2+
import { useMemo } from 'react';
3+
import { useTranslation } from 'react-i18next';
4+
5+
export const LOCALE_PICKER_FIELD_TYPE = 'localePickerField';
6+
7+
export const LocalePickerField: TDynamicFormField<ISelectFieldParams> = ({ element }) => {
8+
const { t } = useTranslation();
9+
10+
const elementDefinitionWithLocaleList: IFormElement<
11+
typeof LOCALE_PICKER_FIELD_TYPE,
12+
ISelectFieldParams
13+
> = useMemo(() => {
14+
return {
15+
...element,
16+
element: LOCALE_PICKER_FIELD_TYPE,
17+
params: {
18+
...element.params,
19+
options: (
20+
t('languages', { returnObjects: true }) as Array<{
21+
const: string;
22+
title: string;
23+
}>
24+
).map(locale => ({
25+
value: locale.const,
26+
label: locale.title,
27+
})),
28+
},
29+
};
30+
}, [element, t]);
31+
32+
return <SelectField element={elementDefinitionWithLocaleList} />;
33+
};
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { IFormElement, ISelectFieldParams } from '@ballerine/ui';
2+
import { render, screen } from '@testing-library/react';
3+
import { describe, expect, it, vi } from 'vitest';
4+
import { LOCALE_PICKER_FIELD_TYPE, LocalePickerField } from './LocalePicker';
5+
6+
// Mock dependencies
7+
vi.mock('react-i18next', () => ({
8+
useTranslation: () => ({
9+
t: vi.fn().mockReturnValue([
10+
{ const: 'en', title: 'English' },
11+
{ const: 'es', title: 'Spanish' },
12+
]),
13+
}),
14+
}));
15+
16+
vi.mock('@ballerine/ui', () => ({
17+
SelectField: ({ element }: { element: any }) => (
18+
<div data-testid="select-field">{JSON.stringify(element)}</div>
19+
),
20+
}));
21+
22+
describe('LocalePickerField', () => {
23+
const mockElement = {
24+
params: {},
25+
} as IFormElement<typeof LOCALE_PICKER_FIELD_TYPE, ISelectFieldParams>;
26+
27+
it('renders SelectField with transformed locale options', () => {
28+
render(<LocalePickerField element={mockElement} />);
29+
30+
const selectField = screen.getByTestId('select-field');
31+
const elementProp = JSON.parse(selectField.textContent || '');
32+
33+
expect(elementProp).toEqual({
34+
element: LOCALE_PICKER_FIELD_TYPE,
35+
params: {
36+
options: [
37+
{ value: 'en', label: 'English' },
38+
{ value: 'es', label: 'Spanish' },
39+
],
40+
},
41+
});
42+
});
43+
44+
it('preserves existing element params while adding options', () => {
45+
const elementWithParams = {
46+
...mockElement,
47+
params: {
48+
placeholder: 'Select a language',
49+
},
50+
} as IFormElement<typeof LOCALE_PICKER_FIELD_TYPE, ISelectFieldParams>;
51+
52+
render(<LocalePickerField element={elementWithParams} />);
53+
54+
const selectField = screen.getByTestId('select-field');
55+
const elementProp = JSON.parse(selectField.textContent || '');
56+
57+
expect((elementProp as any).params).toEqual({
58+
placeholder: 'Select a language',
59+
options: [
60+
{ value: 'en', label: 'English' },
61+
{ value: 'es', label: 'Spanish' },
62+
],
63+
});
64+
});
65+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './LocalePicker';
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { MCC } from '@/components/organisms/UIRenderer/elements/JSONForm/components/MCCPicker/options';
2+
import { IFormElement, ISelectFieldParams, SelectField, TDynamicFormField } from '@ballerine/ui';
3+
import { useMemo } from 'react';
4+
5+
export const MCC_PICKER_FIELD_TYPE = 'mccpickerfield';
6+
7+
export const MCCPickerField: TDynamicFormField<ISelectFieldParams> = ({ element }) => {
8+
const elementWithMccOptions: IFormElement<typeof MCC_PICKER_FIELD_TYPE, ISelectFieldParams> =
9+
useMemo(() => {
10+
return {
11+
...element,
12+
element: MCC_PICKER_FIELD_TYPE,
13+
params: {
14+
...element.params,
15+
options: MCC.map(item => ({
16+
value: item.const,
17+
label: `${item.const} - ${item.title}`,
18+
})),
19+
},
20+
};
21+
}, [element]);
22+
23+
return <SelectField element={elementWithMccOptions} />;
24+
};

0 commit comments

Comments
 (0)