feat(listview): clear selection on empty-space click (#3223)

Clicks landing outside any row (below the last row, on padding) now
deselect all items; rows carry a data-fm-row marker so in-row clicks
stay unaffected.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
pull/3582/head
Tomas Dvorak 2 weeks ago
parent 05adc628c7
commit bda95dbe5f

@ -1,6 +1,8 @@
import { useContext, useMemo } from "react"; import { Box } from "@mui/material";
import { useCallback, useContext, useMemo } from "react";
import { Virtuoso } from "react-virtuoso"; import { Virtuoso } from "react-virtuoso";
import { useAppSelector } from "../../../../redux/hooks.ts"; import { useAppDispatch, useAppSelector } from "../../../../redux/hooks.ts";
import { setSelected } from "../../../../redux/fileManagerSlice.ts";
import DndWrappedFile from "../../Dnd/DndWrappedFile.tsx"; import DndWrappedFile from "../../Dnd/DndWrappedFile.tsx";
import { FmIndexContext } from "../../FmIndexContext.tsx"; import { FmIndexContext } from "../../FmIndexContext.tsx";
import { FmFile, loadingPlaceHolderNumb } from "../GridView/GridView.tsx"; import { FmFile, loadingPlaceHolderNumb } from "../GridView/GridView.tsx";
@ -14,6 +16,7 @@ export interface ListBodyProps {
const ListBody = ({ columns }: ListBodyProps) => { const ListBody = ({ columns }: ListBodyProps) => {
const fmIndex = useContext(FmIndexContext); const fmIndex = useContext(FmIndexContext);
const dispatch = useAppDispatch();
const files = useAppSelector((state) => state.fileManager[fmIndex].list?.files); const files = useAppSelector((state) => state.fileManager[fmIndex].list?.files);
const mixedType = useAppSelector((state) => state.fileManager[fmIndex].list?.mixed_type); const mixedType = useAppSelector((state) => state.fileManager[fmIndex].list?.mixed_type);
const pagination = useAppSelector((state) => state.fileManager[fmIndex].list?.pagination); const pagination = useAppSelector((state) => state.fileManager[fmIndex].list?.pagination);
@ -46,7 +49,19 @@ const ListBody = ({ columns }: ListBodyProps) => {
return list; return list;
}, [files, mixedType, pagination, search_params]); }, [files, mixedType, pagination, search_params]);
// Clicking empty space below/around rows clears the selection (#3223);
// row clicks are excluded via the data-fm-row marker.
const onBackgroundClick = useCallback(
(e: React.MouseEvent<HTMLElement>) => {
if (!(e.target as HTMLElement).closest("[data-fm-row]")) {
dispatch(setSelected({ index: fmIndex, value: [] }));
}
},
[dispatch, fmIndex],
);
return ( return (
<Box sx={{ height: "100%" }} onClick={onBackgroundClick}>
<Virtuoso <Virtuoso
style={{ style={{
height: "100%", height: "100%",
@ -65,6 +80,7 @@ const ListBody = ({ columns }: ListBodyProps) => {
/> />
)} )}
/> />
</Box>
); );
}; };

@ -91,6 +91,7 @@ const Row = memo((props: FileBlockProps) => {
return ( return (
<RowContainer <RowContainer
data-fm-row
transparent={isDragging || fileDisabled} transparent={isDragging || fileDisabled}
isDropOver={isDropOver && !isDragging} isDropOver={isDropOver && !isDragging}
ref={setRefFunc} ref={setRefFunc}

Loading…
Cancel
Save