-
Notifications
You must be signed in to change notification settings - Fork 128
Expand file tree
/
Copy pathPaymentDropDownField.res
More file actions
157 lines (153 loc) · 5.38 KB
/
Copy pathPaymentDropDownField.res
File metadata and controls
157 lines (153 loc) · 5.38 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
open RecoilAtoms
@react.component
let make = (
~value: RecoilAtomTypes.field,
~setValue: (RecoilAtomTypes.field => RecoilAtomTypes.field) => unit,
~fieldName,
~options,
~disabled=false,
~className="",
) => {
let {config} = Recoil.useRecoilValueFromAtom(configAtom)
let {themeObj, localeString} = Recoil.useRecoilValueFromAtom(configAtom)
let {readOnly} = Recoil.useRecoilValueFromAtom(optionAtom)
let loggerState = Recoil.useRecoilValueFromAtom(loggerAtom)
let dropdownRef = React.useRef(Nullable.null)
let (inputFocused, setInputFocused) = React.useState(_ => false)
let {parentURL, iframeId} = Recoil.useRecoilValueFromAtom(keys)
let isSpacedInnerLayout = config.appearance.innerLayout === Spaced
let elementType = PaymentTypeContext.usePaymentType()->CardThemeType.getPaymentModeToString
let getClassName = initialLabel => {
if value.value->String.length == 0 {
`${initialLabel}--empty`
} else {
switch value.isValid {
| Some(valid) => valid ? `${initialLabel}--valid` : `${initialLabel}--invalid`
| None => ""
}
}
}
React.useEffect(() => {
let initialValue = options->Array.get(0)->Option.getOr("")
if value.value === "" || options->Array.includes(value.value)->not {
setValue(_ => {
errorString: "",
isValid: Some(true),
value: initialValue,
})
}
None
}, [options])
let handleFocus = _ => {
setInputFocused(_ => true)
Utils.handleOnFocusPostMessage(~iframeId, ~elementType, ~targetOrigin=parentURL)
}
let focusClass = if inputFocused || value.value->String.length > 0 {
`mb-7 pb-1 pt-2 ${themeObj.fontSizeXs} transition-all ease-in duration-75`
} else {
"transition-all ease-in duration-75"
}
let floatinglabelClass = inputFocused ? "Label--floating" : "Label--resting"
let labelClass = getClassName("Label")
let inputClass = getClassName("Input")
let inputClassStyles = isSpacedInnerLayout ? "Input" : "Input-Compressed"
let handleChange = ev => {
let target = ev->ReactEvent.Form.target
let value = target["value"]
// Log the dropdown change using fieldName
if fieldName->String.length > 0 {
LoggerUtils.logInputChangeInfo(fieldName, loggerState)
}
setValue(_ => {
isValid: Some(true),
value,
errorString: "",
})
}
let disbaledBG = React.useMemo(() => {
themeObj.colorBackground
}, [themeObj])
let cursorClass = !disabled ? "cursor-pointer" : "cursor-not-allowed"
<RenderIf condition={options->Array.length > 0}>
<div className="flex flex-col w-full" style={color: themeObj.colorText}>
<RenderIf
condition={fieldName->String.length > 0 &&
config.appearance.labels == Above &&
isSpacedInnerLayout}>
<div
className={`Label ${labelClass} `}
style={
fontWeight: themeObj.fontWeightNormal,
fontSize: themeObj.fontSizeLg,
marginBottom: "5px",
opacity: "0.6",
}
ariaHidden=true>
{React.string(fieldName)}
</div>
</RenderIf>
<div className="relative">
<select
ref={dropdownRef->ReactDOM.Ref.domRef}
style={
background: disabled ? disbaledBG : themeObj.colorBackground,
opacity: disabled ? "35%" : "",
padding: "11px 22px 11px 11px",
width: "100%",
}
name=""
value=value.value
disabled={readOnly || disabled}
onFocus={handleFocus}
onChange=handleChange
className={`${inputClassStyles} ${inputClass} ${className} w-full appearance-none outline-none overflow-hidden whitespace-nowrap text-ellipsis ${cursorClass}`}
ariaLabel={`${fieldName} option tab`}>
{options
->Array.mapWithIndex((item: string, i) => {
<option key={Int.toString(i)} value=item> {React.string(item)} </option>
})
->React.array}
</select>
<RenderIf condition={config.appearance.labels == Floating}>
<div
className={`Label ${floatinglabelClass} ${labelClass} absolute bottom-0 ml-3 ${focusClass} pointer-events-none`}
style={
marginBottom: {
inputFocused || value.value->String.length > 0 ? "" : themeObj.spacingUnit
},
fontSize: {
inputFocused || value.value->String.length > 0 ? themeObj.fontSizeXs : ""
},
opacity: "0.6",
}
ariaHidden=true>
{React.string(fieldName)}
</div>
</RenderIf>
<div
className="self-center absolute"
style={
opacity: disabled ? "35%" : "",
color: themeObj.colorText,
left: localeString.localeDirection == "rtl" ? "1%" : "97%",
top: "42%",
marginLeft: localeString.localeDirection == "rtl" ? "1rem" : "-1rem",
}>
<Icon size=10 name={"arrow-down"} />
</div>
<RenderIf condition={value.errorString->String.length > 0}>
<div
className="Error pt-1"
style={
color: themeObj.colorDangerText,
fontSize: themeObj.fontSizeSm,
alignSelf: "start",
textAlign: "left",
}>
{React.string(value.errorString)}
</div>
</RenderIf>
</div>
</div>
</RenderIf>
}