Skip to content

Commit

Permalink
fix(autocomplete): controlled state logic (#2969)
Browse files Browse the repository at this point in the history
* fix(autocomplete): autocomplete controlled state (#2955)

* chore(autocomplete): add changeset

* Update packages/components/autocomplete/__tests__/autocomplete.test.tsx

---------

Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>
  • Loading branch information
chirokas and jrgarciadev authored Jun 15, 2024
1 parent 0e4213c commit 255c641
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/proud-moles-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nextui-org/autocomplete": patch
---

Fix autocomplete controlled state (#2955)
70 changes: 70 additions & 0 deletions packages/components/autocomplete/__tests__/autocomplete.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@ const itemsSectionData = [
},
];


const ControlledAutocomplete = <T = object>(props: AutocompleteProps<T>) => {
const [selectedKey, setSelectedKey] = React.useState<React.Key>("cat");

return (
<Autocomplete
{...props}
aria-label="Favorite Animal"
label="Favorite Animal"
selectedKey={selectedKey}
onSelectionChange={setSelectedKey}
/>
);
};

const AutocompleteExample = (props: Partial<AutocompleteProps> = {}) => (
<Autocomplete label="Favorite Animal" {...props}>
<AutocompleteItem key="penguin" value="penguin">
Expand All @@ -62,6 +77,7 @@ const AutocompleteExample = (props: Partial<AutocompleteProps> = {}) => (
</Autocomplete>
);


describe("Autocomplete", () => {
it("should render correctly", () => {
const wrapper = render(<AutocompleteExample />);
Expand Down Expand Up @@ -559,6 +575,60 @@ describe("Autocomplete", () => {
});
});
});

it("should work when key equals textValue", async () => {
const wrapper = render(
<Autocomplete
aria-label="Favorite Animal"
data-testid="when-key-equals-textValue"
defaultSelectedKey="cat"
items={itemsData}
label="Favorite Animal"
>
{(item) => <AutocompleteItem key={item.value}>{item.value}</AutocompleteItem>}
</Autocomplete>,
);

const autocomplete = wrapper.getByTestId("when-key-equals-textValue");

const user = userEvent.setup();

await user.click(autocomplete);

expect(autocomplete).toHaveValue("cat");
expect(autocomplete).toHaveAttribute("aria-expanded", "true");

let listboxItems = wrapper.getAllByRole("option");

await user.click(listboxItems[1]);

expect(autocomplete).toHaveValue("dog");
expect(autocomplete).toHaveAttribute("aria-expanded", "false");
});

it("should work when key equals textValue (controlled)", async () => {
const wrapper = render(
<ControlledAutocomplete data-testid="when-key-equals-textValue" items={itemsData}>
{(item) => <AutocompleteItem key={item.value}>{item.value}</AutocompleteItem>}
</ControlledAutocomplete>,
);

const autocomplete = wrapper.getByTestId("when-key-equals-textValue");

const user = userEvent.setup();

await user.click(autocomplete);

expect(autocomplete).toHaveValue("cat");
expect(autocomplete).toHaveAttribute("aria-expanded", "true");

let listboxItems = wrapper.getAllByRole("option");

await user.click(listboxItems[1]);

expect(autocomplete).toHaveValue("dog");
expect(autocomplete).toHaveAttribute("aria-expanded", "false");
});
});

describe("Autocomplete with React Hook Form", () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/components/autocomplete/src/use-autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ export function useAutocomplete<T extends object>(originalProps: UseAutocomplete
const key = inputRef.current.value;
const item = state.collection.getItem(key);

if (item) {
if (item && state.inputValue !== item.textValue) {
state.setSelectedKey(key);
state.setInputValue(item.textValue);
}
Expand Down

0 comments on commit 255c641

Please sign in to comment.