Drag To Select Table (#1064)

* - added drag to select on EntityTable

* - moved dragToSelect to own component

* - convert DragSelect to a generic component

* - fixed unused vars

* formatting

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
This commit is contained in:
brendanlaschke
2023-08-05 01:16:01 +02:00
committed by GitHub
parent b6e1853d9f
commit 5e6351e099
5 changed files with 92 additions and 4 deletions

View File

@ -1,12 +1,16 @@
import { useRef } from 'react';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { SelectedSortType, SortType } from '@/ui/filter-n-sort/types/interface';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { DragSelect } from '../../../../utils/DragSelect';
import { useLeaveTableFocus } from '../hooks/useLeaveTableFocus';
import { useMapKeyboardToSoftFocus } from '../hooks/useMapKeyboardToSoftFocus';
import { useSetRowSelectedState } from '../hooks/useSetRowSelectedState';
import { EntityUpdateMutationHookContext } from '../states/EntityUpdateMutationHookContext';
import { tableRowIdsState } from '../states/tableRowIdsState';
import { TableHeader } from '../table-header/components/TableHeader';
import { EntityTableBody } from './EntityTableBody';
@ -99,6 +103,16 @@ export function EntityTable<SortField>({
useUpdateEntityMutation,
}: OwnProps<SortField>) {
const tableBodyRef = useRef<HTMLDivElement>(null);
const entityTableBodyRef = useRef<HTMLTableSectionElement>(null);
const rowIds = useRecoilValue(tableRowIdsState);
const setRowSelectedState = useSetRowSelectedState();
function resetSelections() {
for (const rowId of rowIds) {
setRowSelectedState(rowId, false);
}
}
useMapKeyboardToSoftFocus();
@ -124,9 +138,14 @@ export function EntityTable<SortField>({
<StyledTableWrapper>
<StyledTable>
<EntityTableHeader />
<EntityTableBody />
<EntityTableBody tbodyRef={entityTableBodyRef} />
</StyledTable>
</StyledTableWrapper>
<DragSelect
dragSelectable={entityTableBodyRef}
onDragSelectionStart={resetSelections}
onDragSelectionChange={setRowSelectedState}
/>
</StyledTableContainer>
</StyledTableWithHeader>
</EntityUpdateMutationHookContext.Provider>

View File

@ -1,3 +1,4 @@
import { Ref } from 'react';
import { useRecoilValue } from 'recoil';
import { isNavbarSwitchingSizeState } from '@/ui/layout/states/isNavbarSwitchingSizeState';
@ -9,7 +10,11 @@ import { tableRowIdsState } from '../states/tableRowIdsState';
import { EntityTableRow } from './EntityTableRow';
export function EntityTableBody() {
type OwnProps = {
tbodyRef: Ref<HTMLTableSectionElement>;
};
export function EntityTableBody({ tbodyRef }: OwnProps) {
const rowIds = useRecoilValue(tableRowIdsState);
const isNavbarSwitchingSize = useRecoilValue(isNavbarSwitchingSizeState);
@ -23,7 +28,7 @@ export function EntityTableBody() {
}
return (
<tbody>
<tbody ref={tbodyRef}>
{rowIds.map((rowId, index) => (
<RowIdContext.Provider value={rowId} key={rowId}>
<RowIndexContext.Provider value={index}>

View File

@ -16,7 +16,11 @@ export function EntityTableRow({ rowId }: { rowId: string }) {
const viewFields = useRecoilValue(visibleViewFieldsState);
return (
<StyledRow data-testid={`row-id-${rowId}`} selected={false}>
<StyledRow
data-testid={`row-id-${rowId}`}
selected={false}
data-selectable-id={rowId}
>
<td>
<CheckboxCell />
</td>

View File

@ -0,0 +1,9 @@
import { useRecoilCallback } from 'recoil';
import { isRowSelectedFamilyState } from '../states/isRowSelectedFamilyState';
export function useSetRowSelectedState() {
return useRecoilCallback(({ set }) => (rowId: string, selected: boolean) => {
set(isRowSelectedFamilyState(rowId), selected);
});
}