Skip to content

Commit 7430eee

Browse files
fix: Update Tree drag and drop focus (adobe#9751)
* fix: Update Tree drag and drop focus * Remove unnecessary content node check * Use collection iterator and filter to only item nodes --------- Co-authored-by: Devon Govett <devongovett@gmail.com>
1 parent 92aef13 commit 7430eee

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

packages/@react-aria/dnd/src/useDroppableCollection.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,9 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
251251
state.selectionManager.isSelectionEqual(prevSelectedKeys)
252252
) {
253253
let newKeys = new Set<Key>();
254-
for (let key of state.collection.getKeys()) {
255-
if (!prevCollection.getItem(key)) {
256-
newKeys.add(key);
254+
for (let item of state.collection) {
255+
if (item.type === 'item' && !prevCollection.getItem(item.key)) {
256+
newKeys.add(item.key);
257257
}
258258
}
259259

packages/react-aria-components/test/Tree.test.tsx

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ import {useTreeData} from 'react-stately';
2424

2525
let {
2626
EmptyTreeStaticStory: EmptyLoadingTree,
27-
LoadingStoryDepOnTopStory: LoadingMoreTree
27+
LoadingStoryDepOnTopStory: LoadingMoreTree,
28+
TreeWithDragAndDrop
2829
} = composeStories(stories);
2930

3031
let onSelectionChange = jest.fn();
@@ -1924,6 +1925,60 @@ describe('Tree', () => {
19241925
expect(onRootDrop).toHaveBeenCalledTimes(1);
19251926
});
19261927

1928+
it('should automatically focus the newly added dropped item', async () => {
1929+
const {getAllByRole} = render(<TreeWithDragAndDrop />);
1930+
1931+
const trees = getAllByRole('treegrid');
1932+
const firstTreeRows = within(trees[0]).getAllByRole('row');
1933+
const dataTransfer = new DataTransfer();
1934+
1935+
fireEvent(firstTreeRows[1], new DragEvent('dragstart', {dataTransfer, clientX: 5, clientY: 5}));
1936+
act(() => jest.runAllTimers());
1937+
1938+
fireEvent(trees[1], new DragEvent('dragenter', {dataTransfer, clientX: 50, clientY: 50}));
1939+
fireEvent(trees[1], new DragEvent('dragover', {dataTransfer, clientX: 50, clientY: 50}));
1940+
expect(trees[1]).toHaveAttribute('data-drop-target', 'true');
1941+
1942+
// ¯\_(ツ)_/¯
1943+
await act(async () => fireEvent(trees[1], new DragEvent('drop', {dataTransfer, clientX: 50, clientY: 50})));
1944+
act(() => jest.runAllTimers());
1945+
1946+
let secondTreeRows = within(trees[1]).getAllByRole('row');
1947+
1948+
expect(secondTreeRows).toHaveLength(1);
1949+
// The newly added row in the second tree should be the active element
1950+
expect(secondTreeRows[0]).toBe(document.activeElement);
1951+
1952+
await user.click(document.body);
1953+
act(() => jest.runAllTimers());
1954+
1955+
await user.tab();
1956+
await user.keyboard('{ArrowRight}'); // expand the projects item
1957+
await user.keyboard('{ArrowRight}');
1958+
await user.keyboard('{Enter}');
1959+
act(() => jest.runAllTimers());
1960+
1961+
await user.tab();
1962+
act(() => jest.runAllTimers());
1963+
1964+
secondTreeRows = within(trees[1]).getAllByRole('row');
1965+
expect(secondTreeRows).toHaveLength(4);
1966+
expect(within(secondTreeRows[3]).getAllByRole('button')[0]).toHaveAttribute('aria-label', 'Insert after Reports');
1967+
expect(document.activeElement).toBe(within(secondTreeRows[3]).getAllByRole('button')[0]);
1968+
expect(secondTreeRows[3]).toHaveAttribute('data-drop-target', 'true');
1969+
1970+
await user.keyboard('{ArrowUp}');
1971+
expect(within(secondTreeRows[2]).getAllByRole('button')[0]).toHaveAttribute('aria-label', 'Drop on Reports');
1972+
expect(document.activeElement).toBe(within(secondTreeRows[2]).getAllByRole('button')[0]);
1973+
1974+
await user.keyboard('{Enter}');
1975+
act(() => jest.runAllTimers());
1976+
1977+
secondTreeRows = within(trees[1]).getAllByRole('row');
1978+
expect(secondTreeRows).toHaveLength(1);
1979+
expect(secondTreeRows[0]).toBe(document.activeElement);
1980+
});
1981+
19271982
it('should support disabled drag and drop', async () => {
19281983
let {getByRole, queryAllByRole} = render(
19291984
<DraggableTree isDisabled />

0 commit comments

Comments
 (0)