diff --git a/apps/web/__e2e__/keyboard-list-navigation.test.ts b/apps/web/__e2e__/keyboard-list-navigation.test.ts index 4fba44946..27388b5da 100644 --- a/apps/web/__e2e__/keyboard-list-navigation.test.ts +++ b/apps/web/__e2e__/keyboard-list-navigation.test.ts @@ -256,6 +256,23 @@ test("select notes using Shift+Click upwards", async ({ page }, info) => { expect(await notesList[0].isFocused()).toBeTruthy(); }); +test("using Shift+Click when no notes are selected should not crash the app", async ({ + page +}, info) => { + info.setTimeout(60 * 1000); + + const { notes } = await populateList(page, 5); + await page.reload(); + + const note = await notes.findNote({ title: "Test note 3" }); + + await page.keyboard.down("Shift"); + await note?.click(); + await page.keyboard.up("Shift"); + + expect(await notes.isEmpty()).toBeFalsy(); +}); + test("Ctrl+Click to select/unselect notes", async ({ page }, info) => { info.setTimeout(60 * 1000); const { notesList, notes } = await populateList(page, 10); diff --git a/apps/web/src/components/list-container/index.tsx b/apps/web/src/components/list-container/index.tsx index 5e63c3b76..75333d9aa 100644 --- a/apps/web/src/components/list-container/index.tsx +++ b/apps/web/src/components/list-container/index.tsx @@ -114,7 +114,7 @@ function ListContainer(props: ListContainerProps) { element.focus() ); }, - skip: (index) => items[index].type === "header", + skip: (index) => !items[index] || items[index].type === "header", open: (index) => { const item = items[index]; if (!item || !listRef.current) return; diff --git a/apps/web/src/components/list-item/index.js b/apps/web/src/components/list-item/index.js index eb592ad46..a93a4ae27 100644 --- a/apps/web/src/components/list-item/index.js +++ b/apps/web/src/components/list-item/index.js @@ -70,11 +70,11 @@ function ListItem(props) { const isMenuTarget = target && target === listItemRef.current; const isSelected = useSelectionStore((store) => { - const inInSelection = + const isInSelection = store.selectedItems.findIndex((item) => props.item.id === item.id) > -1; return isFocused - ? store.selectedItems.length > 1 && inInSelection - : inInSelection; + ? store.selectedItems.length > 1 && isInSelection + : isInSelection; }); return ( diff --git a/apps/web/src/hooks/use-keyboard-list-navigation.ts b/apps/web/src/hooks/use-keyboard-list-navigation.ts index fd61008ba..f18683eed 100644 --- a/apps/web/src/hooks/use-keyboard-list-navigation.ts +++ b/apps/web/src/hooks/use-keyboard-list-navigation.ts @@ -90,6 +90,7 @@ export function useKeyboardListNavigation( itemIndex > cursor.current ? itemIndex : cursor.current; const indices = []; for (let i = startIndex; i <= endIndex; ++i) { + if (skip && skip(i)) continue; indices.push(i); } bulkSelect(indices); @@ -99,7 +100,7 @@ export function useKeyboardListNavigation( select(itemIndex); } }, - [select, resetSelection, bulkSelect, focusItemAt] + [select, resetSelection, bulkSelect, skip, focusItemAt] ); const onKeyDown = useCallback(