Skip to content

Commit 4d1a044

Browse files
committed
migrated Select component to .tsx
1 parent efab482 commit 4d1a044

File tree

8 files changed

+2869
-2961
lines changed

8 files changed

+2869
-2961
lines changed

components/Form/Select/Select.js renamed to components/Form/Select/Select.tsx

Lines changed: 86 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,64 +15,101 @@ import Label from 'components/Form/Label/Label';
1515
import ThemedReactSelect from './ThemedReactSelect';
1616
import styles from './Select.module.css';
1717

18-
Select.propTypes = {
19-
field: shape({
20-
name: string.isRequired,
21-
value: oneOfType([string, number, bool, arrayOf(string), arrayOf(number), arrayOf(bool)])
22-
.isRequired,
23-
}).isRequired,
24-
form: shape({
25-
// TODO: Resolve why multiselects can end up with touched: { key: array }
26-
// see ThemedReactSelect as well
27-
// touched: objectOf(bool).isRequired,
28-
touched: object.isRequired,
29-
errors: objectOf(string).isRequired,
30-
setFieldTouched: func.isRequired,
31-
setFieldValue: func.isRequired,
32-
}).isRequired,
33-
hasValidationStyling: bool,
34-
id: oneOfType([string, number]),
35-
isLabelHidden: bool,
36-
isMulti: bool,
37-
isSearchable: bool,
38-
label: string.isRequired,
39-
options: arrayOf(shape({ label: string.isRequired, value: string.isRequired }).isRequired)
40-
.isRequired,
18+
type FieldType = {
19+
name: string;
20+
value: string | string[] | number | number[] | boolean | boolean[];
4121
};
4222

43-
Select.defaultProps = {
44-
hasValidationStyling: true,
45-
id: undefined,
46-
isLabelHidden: false,
47-
isMulti: false,
48-
isSearchable: true,
23+
type TouchedType = Record<string, any>;
24+
25+
type ErrorsType = {
26+
[key: string]: string;
27+
};
28+
29+
type FormType = {
30+
touched: TouchedType;
31+
errors: ErrorsType;
32+
setFieldTouched: (name: string) => void;
33+
setFieldValue: (name: string, value: string | string[]) => void;
34+
};
35+
36+
type SelectOptionType = {
37+
label: string;
38+
value: string;
39+
};
40+
41+
type SelectOptionsType = SelectOptionType[];
42+
43+
export type SelectPropsType = {
44+
field: FieldType;
45+
form: FormType;
46+
options: SelectOptionsType;
47+
label: string;
48+
hasValidationStyling?: boolean;
49+
id?: string;
50+
isLabelHidden?: boolean;
51+
isMulti?: boolean;
52+
isSearchable?: boolean;
4953
};
5054

55+
// Select.propTypes = {
56+
// field: shape({
57+
// name: string.isRequired,
58+
// value: oneOfType([string, number, bool, arrayOf(string), arrayOf(number), arrayOf(bool)])
59+
// .isRequired,
60+
// }).isRequired,
61+
// form: shape({
62+
// // TODO: Resolve why multiselects can end up with touched: { key: array }
63+
// // see ThemedReactSelect as well
64+
// // touched: objectOf(bool).isRequired,
65+
// touched: object.isRequired,
66+
// errors: objectOf(string).isRequired,
67+
// setFieldTouched: func.isRequired,
68+
// setFieldValue: func.isRequired,
69+
// }).isRequired,
70+
// hasValidationStyling: bool,
71+
// id: oneOfType([string, number]),
72+
// isLabelHidden: bool,
73+
// isMulti: bool,
74+
// isSearchable: bool,
75+
// label: string.isRequired,
76+
// options: arrayOf(shape({ label: string.isRequired, value: string.isRequired }).isRequired)
77+
// .isRequired,
78+
// };
79+
80+
// Select.defaultProps = {
81+
// hasValidationStyling: true,
82+
// id: undefined,
83+
// isLabelHidden: false,
84+
// isMulti: false,
85+
// isSearchable: true,
86+
// };
87+
5188
export default function Select({
5289
field: { name, value: fieldValue },
5390
form: { errors, setFieldTouched, setFieldValue, touched },
54-
hasValidationStyling,
91+
hasValidationStyling = true,
5592
id,
56-
isLabelHidden,
57-
isMulti,
58-
isSearchable,
93+
isLabelHidden = false,
94+
isMulti = false,
95+
isSearchable = true,
5996
label,
6097
options,
6198
...props // disabled, placeholder, etc.
62-
}) {
99+
}: SelectPropsType) {
63100
/**
64101
* @description handle changing of non-multi select
65102
* @param {string} selected
66103
*/
67-
const onChangeSingle = selected => {
104+
const onChangeSingle = (selected: SelectOptionType) => {
68105
setFieldValue(name, selected === null ? '' : selected.value);
69106
};
70107

71108
/**
72109
* @description handle changing of multi select
73110
* @param {string[]} selectedArray
74111
*/
75-
const onChangeMulti = selectedArray => {
112+
const onChangeMulti = (selectedArray: SelectOptionsType) => {
76113
if (selectedArray) {
77114
setFieldValue(
78115
name,
@@ -96,7 +133,17 @@ export default function Select({
96133
* @returns {{ label: string; value: string; }[]}
97134
*/
98135
const getValueFromMulti = () => {
99-
return options.filter(option => fieldValue.includes(option.value));
136+
if (Array.isArray(fieldValue)) {
137+
return fieldValue
138+
.map(
139+
value =>
140+
options.find((option: SelectOptionType) => option.value === value) as SelectOptionType,
141+
)
142+
.filter(Boolean);
143+
} else {
144+
return [];
145+
}
146+
// return options.filter(option => fieldValue.includes(option.value));
100147
};
101148

102149
const handleBlur = () => {
@@ -126,13 +173,13 @@ export default function Select({
126173
isSearchable={isSearchable}
127174
name={name}
128175
onBlur={handleBlur}
129-
onChange={onChangeHandler}
176+
onChange={() => onChangeHandler}
130177
options={options}
131178
value={value || ''}
132179
/>
133180

134181
<ErrorMessage name={name}>
135-
{message => {
182+
{(message: string) => {
136183
return hasErrors ? (
137184
<Alert className={styles.errorMessage} type="error">
138185
{message}

components/Form/Select/ThemedReactSelect.js

Lines changed: 0 additions & 143 deletions
This file was deleted.

components/Form/Select/__tests__/Select.test.js renamed to components/Form/Select/__tests__/Select.test.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ describe('Select', () => {
3737

3838
it('should render with required props', () => {
3939
createSnapshotTest(
40-
<Formik>
40+
<Formik initialValues={{}} onSubmit={() => {}}>
4141
<Select {...requiredProps} />
4242
</Formik>,
4343
);
4444
});
4545

4646
it('should render with label, even if hidden', () => {
4747
const { queryAllByTestId } = render(
48-
<Formik>
48+
<Formik initialValues={{}} onSubmit={() => {}}>
4949
<Select {...requiredProps} isLabelHidden />
5050
</Formik>,
5151
);
@@ -59,7 +59,7 @@ describe('Select', () => {
5959
const validate = () => ({ [fieldName]: 'Required' });
6060

6161
const { container, findByText } = render(
62-
<Formik initialValues={{ [fieldName]: '' }} validate={validate}>
62+
<Formik initialValues={{ [fieldName]: '' }} validate={validate} onSubmit={() => {}}>
6363
<Form>
6464
<Field
6565
name={fieldName}
@@ -81,7 +81,7 @@ describe('Select', () => {
8181

8282
it('should fire formik-related callbacks when changing non-multi select', async () => {
8383
const { container } = render(
84-
<Formik>
84+
<Formik initialValues={{}} onSubmit={() => {}}>
8585
<Select {...requiredProps} />
8686
</Formik>,
8787
);
@@ -99,7 +99,7 @@ describe('Select', () => {
9999

100100
it('should fire formik-related callbacks when changing multi select', async () => {
101101
const { container } = render(
102-
<Formik>
102+
<Formik initialValues={{}} onSubmit={() => {}}>
103103
<Select {...requiredProps} field={{ name: 'test', value: [] }} isMulti />
104104
</Formik>,
105105
);
@@ -125,7 +125,7 @@ describe('Select', () => {
125125

126126
it('should be able to remove multiselect options', async () => {
127127
const { container } = render(
128-
<Formik>
128+
<Formik initialValues={{}} onSubmit={() => {}}>
129129
<Select {...requiredProps} field={{ name: 'test', value: [] }} isMulti />
130130
</Formik>,
131131
);

components/Form/Select/__tests__/ThemedReactSelect.test.js

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)