Room list: drag and drop rooms into sections (#33366)

* chore: add dnd kit deps

* chore: patch dnd kit to fix ts error

* feat(sc): add drag-and-drop to room list item and wrapper

* feat(sc): make the room list header a droppable element

* feat(sc): add dnd to room list view

* feat(tags): can tag room as CHAT

* feat(vm): implement `changeRoomSection`

* feat(sc): disable dragging in flat list

* fix: disable keyboard navigation when dragging element

* test(sc): update snapshots

* test(sc): add dnd test

* test(e2e): add e2e tests for room drag and drop

* test(vm): add tests for changeRoomSection

* fix: remove focus visible when dropping with the mouse

* test(playwright): update existing screenshots

* chore(sc): move numbers out of main build

The Ew RecorderWorklet imports shared component bundle. However if the
bundle uses some deps using document/window which, the worklet will not
work.

The solution is to put the used functions into a separate bundle.

* doc(sc): add subpath import into README

* doc: typo barrel/bundle

* test: improve test expect

* refactor: add utils to section tag

* fix: incorrect check in tagRoom

* fix: add doc about dndkit tunning
This commit is contained in:
Florian Duros
2026-05-13 09:06:22 +00:00
committed by GitHub
parent 97da3be67a
commit 85aca65a81
50 changed files with 4845 additions and 3871 deletions
@@ -81,6 +81,13 @@ export interface VirtualizedListProps<Item, Context> extends Omit<
*/
onKeyDown?: (e: React.KeyboardEvent<HTMLDivElement>) => void;
/**
* When true, keyboard navigation (Arrow keys, Home, End, Page Up/Down) is disabled.
* All key events are forwarded directly to `onKeyDown` instead.
* Use this to prevent the list from scrolling while an item is being dragged via keyboard.
*/
disableKeyboardNavigation?: boolean;
/**
* Optional total count of items (for virtualization with partial data loading).
* If provided, this will be used instead of items.length for the total count.
@@ -164,6 +171,7 @@ export function useVirtualizedList<Item, Context>(
getItemKey,
context,
onKeyDown,
disableKeyboardNavigation,
totalCount,
rangeChanged,
mapScrollIndex,
@@ -260,6 +268,13 @@ export function useVirtualizedList<Item, Context>(
return;
}
// When keyboard navigation is disabled (e.g. during a keyboard drag),
// forward all events to the parent handler without handling navigation.
if (disableKeyboardNavigation) {
onKeyDown?.(e);
return;
}
if (e.code === Key.ARROW_UP && currentIndex !== undefined) {
scrollToItem(currentIndex - 1, false);
handled = true;
@@ -300,7 +315,16 @@ export function useVirtualizedList<Item, Context>(
onKeyDown?.(e);
}
},
[scrollToIndex, scrollToItem, tabIndexKey, keyToIndexMap, visibleRange, items, onKeyDown],
[
scrollToIndex,
scrollToItem,
tabIndexKey,
keyToIndexMap,
visibleRange,
items,
onKeyDown,
disableKeyboardNavigation,
],
);
/**