Skip to content

Commit e7203bd

Browse files
authored
feat(form): autocomplete input
1 parent 47d6206 commit e7203bd

File tree

2 files changed

+60
-10
lines changed

2 files changed

+60
-10
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React from "react";
2+
import { Meta, StoryFn } from "@storybook/react";
3+
import { useForm, FormProvider } from "react-hook-form";
4+
import FormAutocompleteInput, {
5+
AutocompleteInputProps,
6+
} from "./form-autocomplete";
7+
8+
interface Option {
9+
id: number;
10+
name: string;
11+
}
12+
13+
export default {
14+
title: "Components/Form/AutocompleteInput",
15+
component: FormAutocompleteInput,
16+
} as Meta;
17+
18+
const Template: StoryFn<AutocompleteInputProps<Option> & { name: string }> = (
19+
args
20+
) => {
21+
const methods = useForm({
22+
defaultValues: {
23+
sampleAutocomplete: [],
24+
},
25+
});
26+
27+
return (
28+
<FormProvider {...methods}>
29+
<form>
30+
<FormAutocompleteInput {...args} />
31+
</form>
32+
</FormProvider>
33+
);
34+
};
35+
36+
export const Default = Template.bind({});
37+
Default.args = {
38+
label: "Autocomplete",
39+
name: "sampleAutocomplete",
40+
options: [
41+
{ id: 1, name: "Option 1" },
42+
{ id: 2, name: "Option 2" },
43+
{ id: 3, name: "Option 3" },
44+
{ id: 4, name: "Option 4" },
45+
{ id: 5, name: "Option 5" },
46+
],
47+
renderOption: (option: Option) => option.name,
48+
testId: "sampleAutocomplete",
49+
value: { id: 2, name: "Option 2" },
50+
getOptionLabel: (option) => option.name,
51+
};

src/components/form/autocomplete/form-autocomplete.tsx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,31 @@ import Autocomplete from "@mui/material/Autocomplete";
1212
import TextField from "@mui/material/TextField";
1313
import FormHelperText from "@mui/material/FormHelperText";
1414

15-
type AutocompleteInputProps<T> = {
15+
export type AutocompleteInputProps<T> = {
1616
label: string;
17-
type?: string;
1817
autoFocus?: boolean;
1918
disabled?: boolean;
2019
readOnly?: boolean;
2120
error?: string;
2221
testId?: string;
2322
size?: "small" | "medium";
24-
keyValue: keyof T;
2523
value: T | null;
2624
options: T[];
2725
renderOption: (option: T) => React.ReactNode;
26+
getOptionLabel: (option: T) => string;
2827
};
2928

3029
function AutocompleteInputRaw<T>(
3130
props: AutocompleteInputProps<T> & {
3231
name: string;
33-
value: T[] | undefined | null;
32+
value: T | undefined | null;
3433
onChange: (value: T) => void;
3534
onBlur: () => void;
3635
},
3736
ref?: ForwardedRef<HTMLDivElement | null>
3837
) {
3938
return (
40-
<FormControl error={!!props.error} disabled={props.disabled}>
39+
<FormControl error={!!props.error} disabled={props.disabled} fullWidth>
4140
<Autocomplete
4241
ref={ref}
4342
id={`autocomplete-${props.name}`}
@@ -50,7 +49,7 @@ function AutocompleteInputRaw<T>(
5049
}}
5150
onBlur={props.onBlur}
5251
data-testid={props.testId}
53-
getOptionLabel={(option) => option?.[props.keyValue]?.toString() ?? ""}
52+
getOptionLabel={props.getOptionLabel}
5453
renderOption={(htmlProps, option) => (
5554
<li {...htmlProps}>{props.renderOption(option)}</li>
5655
)}
@@ -70,8 +69,8 @@ function AutocompleteInputRaw<T>(
7069
const AutocompleteInput = forwardRef(AutocompleteInputRaw) as never as <T>(
7170
props: AutocompleteInputProps<T> & {
7271
name: string;
73-
value: T[] | undefined | null;
74-
onChange: (value: T[]) => void;
72+
value: T | undefined | null;
73+
onChange: (value: T) => void;
7574
onBlur: () => void;
7675
} & { ref?: ForwardedRef<HTMLDivElement | null> }
7776
) => ReturnType<typeof AutocompleteInputRaw>;
@@ -93,15 +92,15 @@ function FormAutocompleteInput<
9392
{...field}
9493
label={props.label}
9594
autoFocus={props.autoFocus}
96-
type={props.type}
9795
error={fieldState.error?.message}
9896
disabled={props.disabled}
9997
readOnly={props.readOnly}
10098
testId={props.testId}
10199
options={props.options}
102100
renderOption={props.renderOption}
103-
keyValue={props.keyValue}
101+
getOptionLabel={props.getOptionLabel}
104102
size={props.size}
103+
value={props.value}
105104
/>
106105
)}
107106
/>

0 commit comments

Comments
 (0)