|
12 | 12 |
|
13 | 13 | import {act, pointerMap, render, within} from '@react-spectrum/test-utils-internal';
|
14 | 14 | import {AriaAutocompleteTests} from './AriaAutocomplete.test-util';
|
15 |
| -import {Autocomplete, Breadcrumb, Breadcrumbs, Button, Cell, Column, Dialog, DialogTrigger, GridList, GridListItem, Header, Input, Label, ListBox, ListBoxItem, ListBoxSection, Menu, MenuItem, MenuSection, Popover, Row, SearchField, Select, SelectValue, Separator, SubmenuTrigger, Tab, Table, TableBody, TableHeader, TabList, TabPanel, Tabs, Tag, TagGroup, TagList, Text, TextField, Tree, TreeItem, TreeItemContent} from '..'; |
16 |
| -import React, {ReactNode} from 'react'; |
| 15 | +import {Autocomplete, Breadcrumb, Breadcrumbs, Button, Cell, Collection, Column, Dialog, DialogTrigger, GridList, GridListItem, Header, Input, Label, ListBox, ListBoxItem, ListBoxLoadMoreItem, ListBoxSection, Menu, MenuItem, MenuSection, Popover, Row, SearchField, Select, SelectValue, Separator, SubmenuTrigger, Tab, Table, TableBody, TableHeader, TabList, TabPanel, Tabs, Tag, TagGroup, TagList, Text, TextField, Tree, TreeItem, TreeItemContent} from '..'; |
| 16 | +import React, {ReactNode, useEffect, useState} from 'react'; |
17 | 17 | import {useAsyncList} from 'react-stately';
|
18 | 18 | import {useFilter} from '@react-aria/i18n';
|
19 | 19 | import userEvent from '@testing-library/user-event';
|
@@ -957,6 +957,73 @@ describe('Autocomplete', () => {
|
957 | 957 | expect(within(sections[0]).getByText('Baz')).toBeTruthy();
|
958 | 958 | expect(within(sections[1]).getByText('Copy')).toBeTruthy();
|
959 | 959 | });
|
| 960 | + |
| 961 | + |
| 962 | + it('shouldnt prevent default on keyboard interactions if somehow the active descendant doesnt exist in the DOM', async () => { |
| 963 | + let defaultOptions = [ |
| 964 | + {value: 'one'}, |
| 965 | + {value: 'two'}, |
| 966 | + {value: 'three'}, |
| 967 | + {value: 'four'}, |
| 968 | + {value: 'five'} |
| 969 | + ]; |
| 970 | + function ControlledItemsFilter() { |
| 971 | + const [options, setOptions] = useState(defaultOptions); |
| 972 | + const [inputValue, onInputChange] = useState(''); |
| 973 | + |
| 974 | + useEffect(() => { |
| 975 | + setOptions( |
| 976 | + defaultOptions.filter(({value}) => value.includes(inputValue)) |
| 977 | + ); |
| 978 | + }, [inputValue]); |
| 979 | + |
| 980 | + return ( |
| 981 | + <Autocomplete inputValue={inputValue} onInputChange={onInputChange}> |
| 982 | + <SearchField aria-label="Search"> |
| 983 | + <Input aria-label="Search" placeholder="Search..." /> |
| 984 | + <Button>X</Button> |
| 985 | + </SearchField> |
| 986 | + <ListBox selectionMode="multiple"> |
| 987 | + <Collection items={options} dependencies={[inputValue]}> |
| 988 | + {(option) => ( |
| 989 | + <ListBoxItem id={option.value}>{option.value}</ListBoxItem> |
| 990 | + )} |
| 991 | + </Collection> |
| 992 | + <ListBoxLoadMoreItem onLoadMore={() => {}} isLoading={false}> |
| 993 | + <div>Loading...</div> |
| 994 | + </ListBoxLoadMoreItem> |
| 995 | + </ListBox> |
| 996 | + </Autocomplete> |
| 997 | + ); |
| 998 | + } |
| 999 | + let {getByRole} = render( |
| 1000 | + <ControlledItemsFilter /> |
| 1001 | + ); |
| 1002 | + |
| 1003 | + let input = getByRole('searchbox'); |
| 1004 | + await user.tab(); |
| 1005 | + expect(document.activeElement).toBe(input); |
| 1006 | + await user.keyboard('o'); |
| 1007 | + act(() => jest.runAllTimers()); |
| 1008 | + let listbox = getByRole('listbox'); |
| 1009 | + let options = within(listbox).getAllByRole('option'); |
| 1010 | + expect(options).toHaveLength(3); |
| 1011 | + expect(input).toHaveAttribute('aria-activedescendant', options[0].id); |
| 1012 | + |
| 1013 | + await user.keyboard('o'); |
| 1014 | + act(() => jest.runAllTimers()); |
| 1015 | + options = within(listbox).queryAllByRole('option'); |
| 1016 | + expect(options).toHaveLength(0); |
| 1017 | + // TODO: this is strange, still need to investigate. Ideally this would be removed |
| 1018 | + // but the collection in this configuration doesn't seem to update in time, so |
| 1019 | + // useSelectableCollection doesn't properly resend virtual focus to the input |
| 1020 | + expect(input).toHaveAttribute('aria-activedescendant'); |
| 1021 | + |
| 1022 | + await user.keyboard('{Backspace}'); |
| 1023 | + act(() => jest.runAllTimers()); |
| 1024 | + options = within(listbox).getAllByRole('option'); |
| 1025 | + expect(options).toHaveLength(3); |
| 1026 | + }); |
960 | 1027 | });
|
961 | 1028 |
|
962 | 1029 | AriaAutocompleteTests({
|
|
0 commit comments