Skip to content

Commit b837e0e

Browse files
feat: add ref to select (#934)
1 parent 286385b commit b837e0e

File tree

1 file changed

+88
-82
lines changed

1 file changed

+88
-82
lines changed

packages/react-kit/src/components/form/Select.tsx

Lines changed: 88 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { ReactNode } from "react";
1+
import React, { forwardRef, ReactNode } from "react";
22
import { useField } from "formik";
33
import ReactSelect, {
44
GroupBase,
@@ -191,90 +191,96 @@ export type DefaultSelectProps<IsMulti extends boolean = false> = SelectProps<
191191
IsMulti,
192192
GroupBase<SelectOption>
193193
>;
194-
export function Select<
195-
Option extends SelectOption = SelectOption,
196-
IsMulti extends boolean = false,
197-
Group extends GroupBase<Option> = GroupBase<Option>
198-
>({
199-
name,
200-
options,
201-
placeholder = "Choose...",
202-
isClearable = false,
203-
isSearchable = true,
204-
isDisabled = false,
205-
errorMessage,
206-
onChange,
207-
onBlur,
208-
theme,
209-
reactSelectTheme,
210-
isMulti,
211-
...props
212-
}: SelectProps<Option, IsMulti, Group>) {
213-
const [field, meta, helpers] =
214-
useField<IsMulti extends true ? MultiValue<Option> : SingleValue<Option>>(
215-
name
216-
);
194+
export const Select = forwardRef(
195+
<
196+
Option extends SelectOption = SelectOption,
197+
IsMulti extends boolean = false,
198+
Group extends GroupBase<Option> = GroupBase<Option>
199+
>(
200+
{
201+
name,
202+
options,
203+
placeholder = "Choose...",
204+
isClearable = false,
205+
isSearchable = true,
206+
isDisabled = false,
207+
errorMessage,
208+
onChange,
209+
onBlur,
210+
theme,
211+
reactSelectTheme,
212+
isMulti,
213+
...props
214+
}: SelectProps<Option, IsMulti, Group>,
215+
ref: Parameters<typeof ReactSelect<Option, IsMulti, Group>>[0]["ref"]
216+
) => {
217+
const [field, meta, helpers] =
218+
useField<IsMulti extends true ? MultiValue<Option> : SingleValue<Option>>(
219+
name
220+
);
217221

218-
const displayErrorMessage =
219-
meta.error && meta.touched && !errorMessage
220-
? meta.error
221-
: meta.error && meta.touched && errorMessage
222-
? errorMessage
223-
: "";
222+
const displayErrorMessage =
223+
meta.error && meta.touched && !errorMessage
224+
? meta.error
225+
: meta.error && meta.touched && errorMessage
226+
? errorMessage
227+
: "";
224228

225-
const displayError =
226-
typeof displayErrorMessage === "string" && displayErrorMessage !== "";
229+
const displayError =
230+
typeof displayErrorMessage === "string" && displayErrorMessage !== "";
227231

228-
const handleChange = (
229-
option: IsMulti extends true ? MultiValue<Option> : SingleValue<Option>,
230-
actionMeta: ActionMeta<Option>
231-
) => {
232-
if (isDisabled) {
233-
return;
234-
}
235-
if (!meta.touched) {
236-
helpers.setTouched(true);
237-
}
238-
helpers.setValue(option);
239-
onChange?.(option, actionMeta);
240-
};
232+
const handleChange = (
233+
option: IsMulti extends true ? MultiValue<Option> : SingleValue<Option>,
234+
actionMeta: ActionMeta<Option>
235+
) => {
236+
if (isDisabled) {
237+
return;
238+
}
239+
if (!meta.touched) {
240+
helpers.setTouched(true);
241+
}
242+
helpers.setValue(option);
243+
onChange?.(option, actionMeta);
244+
};
241245

242-
const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {
243-
if (!meta.touched) {
244-
helpers.setTouched(true);
245-
}
246-
field.onBlur(event);
247-
onBlur?.(event);
248-
};
246+
const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {
247+
if (!meta.touched) {
248+
helpers.setTouched(true);
249+
}
250+
field.onBlur(event);
251+
onBlur?.(event);
252+
};
249253

250-
const { selectClassName } = useFixSelectFont({
251-
selectClassName: "boson-select",
252-
hasError: displayError
253-
});
254+
const { selectClassName } = useFixSelectFont({
255+
selectClassName: "boson-select",
256+
hasError: displayError
257+
});
254258

255-
return (
256-
<>
257-
<ReactSelect<Option, IsMulti, Group>
258-
styles={customStyles<Option, IsMulti, Group>(
259-
displayErrorMessage,
260-
theme
261-
)}
262-
{...field}
263-
{...props}
264-
theme={reactSelectTheme}
265-
className={selectClassName}
266-
isMulti={isMulti}
267-
placeholder={placeholder}
268-
options={options}
269-
value={field.value}
270-
onChange={handleChange}
271-
onBlur={handleBlur}
272-
isSearchable={isSearchable}
273-
isClearable={isClearable}
274-
isDisabled={isDisabled}
275-
isOptionDisabled={(option) => !!option.disabled}
276-
/>
277-
<Error display={displayError} message={displayErrorMessage} />
278-
</>
279-
);
280-
}
259+
return (
260+
<>
261+
<ReactSelect<Option, IsMulti, Group>
262+
ref={ref}
263+
styles={customStyles<Option, IsMulti, Group>(
264+
displayErrorMessage,
265+
theme
266+
)}
267+
{...field}
268+
{...props}
269+
theme={reactSelectTheme}
270+
className={selectClassName}
271+
isMulti={isMulti}
272+
placeholder={placeholder}
273+
options={options}
274+
value={field.value}
275+
onChange={handleChange}
276+
onBlur={handleBlur}
277+
isSearchable={isSearchable}
278+
isClearable={isClearable}
279+
isDisabled={isDisabled}
280+
isOptionDisabled={(option) => !!option.disabled}
281+
/>
282+
<Error display={displayError} message={displayErrorMessage} />
283+
</>
284+
);
285+
}
286+
);

0 commit comments

Comments
 (0)