-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathSelect.tsx
83 lines (75 loc) · 2.11 KB
/
Select.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import React, { useEffect, useState } from 'react';
import cx from 'classnames';
import FieldWrapper, { type FieldWrapperProps } from './inputs/FieldWrapper';
export type SelectProps<T> = Omit<
React.InputHTMLAttributes<HTMLSelectElement>,
'value' | 'onChange'
> &
Omit<FieldWrapperProps, 'children'> & {
options: Array<T>;
value: T;
getOptionLabel: (option: T) => string;
getOptionValue: (option: T) => string;
onChange: (option?: T) => void;
};
const PLACEHOLDER_VALUE = '__PLACEHOLDER__';
const Select = <T,>({
id,
label,
hint,
value,
options,
placeholder,
statusWithMessage,
required,
disabled,
readOnly,
small,
getOptionLabel,
getOptionValue,
onChange,
}: SelectProps<T>) => {
const [selectedOption, setSelectedOption] = useState<T | undefined>(value);
const handleOnChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
const newSelectedOption =
e.target.value === PLACEHOLDER_VALUE
? undefined
: options.find((option) => getOptionValue(option) === e.target.value);
setSelectedOption(newSelectedOption);
onChange(newSelectedOption);
};
useEffect(() => {
setSelectedOption(value);
}, [value]);
return (
<FieldWrapper
id={id}
label={label}
hint={hint}
statusWithMessage={statusWithMessage}
required={required}
disabled={disabled}
small={small}
>
<select
className={cx('custom-select', statusWithMessage?.status, {
'placeholder-selected': placeholder && !selectedOption,
small,
'read-only': readOnly,
})}
value={selectedOption ? getOptionValue(selectedOption) : undefined}
required={required}
disabled={disabled || readOnly}
onChange={handleOnChange}
>
{placeholder && <option value={PLACEHOLDER_VALUE}>{`– ${placeholder} –`}</option>}
{options.map((option) => (
<option key={getOptionValue(option)} value={getOptionValue(option)}>
{getOptionLabel(option)}
</option>
))}
</select>
</FieldWrapper>
);
};
export default Select;