1
|
|
|
import React, { ReactElement } from "react"; |
2
|
|
|
import { FormattedMessage } from "react-intl"; |
3
|
|
|
import { inputMessages } from "./Form/Messages"; |
4
|
|
|
|
5
|
|
|
export interface SelectOption { |
6
|
|
|
/** option value */ |
7
|
|
|
value: string | number; |
8
|
|
|
/** option label */ |
9
|
|
|
label: string; |
10
|
|
|
} |
11
|
|
|
|
12
|
|
|
export interface SelectProps { |
13
|
|
|
/** HTML id of the input element */ |
14
|
|
|
id: string; |
15
|
|
|
/** HTML name of the input element */ |
16
|
|
|
name: string; |
17
|
|
|
/** Holds text for label associated with input element */ |
18
|
|
|
label: string | ReactElement; |
19
|
|
|
/** Boolean indicating if input must have a value, or not */ |
20
|
|
|
required?: boolean; |
21
|
|
|
/** Boolean that sets the select input to invalid */ |
22
|
|
|
invalid?: boolean | null; |
23
|
|
|
/** Selected string contains the default value of the select box */ |
24
|
|
|
selected: string | number | null; |
25
|
|
|
/** Null selection string provides a null value with instructions to user (eg. Select a department...) */ |
26
|
|
|
nullSelection?: string; |
27
|
|
|
/** A list of options for select element following the SelectOption structure */ |
28
|
|
|
options: SelectOption[]; |
29
|
|
|
/** Error text that appers underneath if error occurs (eg. required, ) */ |
30
|
|
|
errorText?: string; |
31
|
|
|
/** The data-clone-grid-item value (refer to clone-framework docs for details) */ |
32
|
|
|
grid?: string; |
33
|
|
|
/** Disables the element */ |
34
|
|
|
disabled?: boolean; |
35
|
|
|
/** Event listener which fires when a change event occurs (varies on input type) */ |
36
|
|
|
onChange: (event: React.ChangeEvent<HTMLSelectElement>) => void; |
37
|
|
|
/** Event listener which fires when a input loses focus */ |
38
|
|
|
onBlur?: (event: React.ChangeEvent<HTMLSelectElement>) => void; |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
const Select: React.FunctionComponent<SelectProps> = ({ |
42
|
|
|
id, |
43
|
|
|
name, |
44
|
|
|
label, |
45
|
|
|
required, |
46
|
|
|
invalid, |
47
|
|
|
selected, |
48
|
|
|
nullSelection, |
49
|
|
|
options, |
50
|
|
|
onChange, |
51
|
|
|
onBlur, |
52
|
|
|
errorText, |
53
|
|
|
grid, |
54
|
|
|
disabled, |
55
|
|
|
children, |
56
|
|
|
}): React.ReactElement => ( |
57
|
|
|
<div |
58
|
|
|
data-c-input="select" |
59
|
|
|
data-c-grid-item={grid} |
60
|
|
|
data-c-required={required || null} |
61
|
|
|
data-c-invalid={invalid || null} |
62
|
|
|
> |
63
|
|
|
<label htmlFor={id}>{label}</label> |
64
|
|
|
<span> |
65
|
|
|
<FormattedMessage {...inputMessages.required} /> |
66
|
|
|
</span> |
67
|
|
|
<div> |
68
|
|
|
<i className="fa fa-caret-down" /> |
69
|
|
|
<select |
70
|
|
|
id={id} |
71
|
|
|
name={name} |
72
|
|
|
value={selected !== null ? selected : ""} |
73
|
|
|
onChange={onChange} |
74
|
|
|
onBlur={onBlur} |
75
|
|
|
required={required} |
76
|
|
|
disabled={disabled} |
77
|
|
|
style={disabled ? { cursor: "not-allowed" } : {}} |
78
|
|
|
> |
79
|
|
|
{nullSelection && ( |
80
|
|
|
<option value="" disabled> |
81
|
|
|
{nullSelection} |
82
|
|
|
</option> |
83
|
|
|
)} |
84
|
|
|
{options && |
85
|
|
|
options.map( |
86
|
|
|
(option: SelectOption): React.ReactElement => ( |
87
|
|
|
<option key={option.value} value={option.value}> |
88
|
|
|
{option.label} |
89
|
|
|
</option> |
90
|
|
|
), |
91
|
|
|
)} |
92
|
|
|
{children} |
93
|
|
|
</select> |
94
|
|
|
</div> |
95
|
|
|
<span>{errorText || <FormattedMessage {...inputMessages.error} />}</span> |
96
|
|
|
</div> |
97
|
|
|
); |
98
|
|
|
|
99
|
|
|
export default Select; |
100
|
|
|
|