Skip to content

Commit 2e2192e

Browse files
committed
feat: Implement range selection in list view and grid view ✨
1 parent 00b3413 commit 2e2192e

3 files changed

Lines changed: 54 additions & 3 deletions

File tree

react/Table/Readme.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,31 @@ const initialVariants = [{ grouped: false }]
103103

104104
const makeGroups = () => ({ groupLabels: ['C', 'D', 'Others'], groupCounts: [1,1,12] })
105105

106-
;
106+
/**
107+
* @param direction: ArrowUp / ArrowRight: -1, ArrowDown / ArrowLeft: 1
108+
* @param items: Array (optional)
109+
*/
110+
const handleShiftArrow = (direction, items = []) => {
111+
const allItems = items.length === 0 ? itemsListRef.current : items
112+
113+
let newFocusedIndex = focusedIndex
114+
115+
if (direction === -1) {
116+
newFocusedIndex = Math.max(0, focusedIndex - 1)
117+
} else if (direction === 1) {
118+
newFocusedIndex = Math.min(allItems.length - 1, focusedIndex + 1)
119+
}
120+
121+
setFocusedIndex(newFocusedIndex)
122+
setIsKeyboardNavigating(true)
123+
124+
const anchorIndex =
125+
lastSelectedIndex !== null ? lastSelectedIndex : focusedIndex
126+
if (lastSelectedIndex === null) {
127+
setLastSelectedIndex(focusedIndex)
128+
}
129+
selectExactRange(allItems, anchorIndex, newFocusedIndex)
130+
}
107131

108132
<Variants initialVariants={initialVariants} screenshotAllVariants>
109133
{variant => (
@@ -123,6 +147,7 @@ const makeGroups = () => ({ groupLabels: ['C', 'D', 'Others'], groupCounts: [1,1
123147
onLongPress: (row, column) => { console.info(`long press on cell. Row ${row['id']}, Column ${column['id']}`) },
124148
},
125149
}}
150+
handleShiftArrow={handleShiftArrow}
126151
/>
127152
</div>
128153
)}

react/Table/Virtualized/RowContent.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const RowContent = ({
3030
'aria-labelledby': `enhanced-table-checkbox-${index}`
3131
}}
3232
size="small"
33-
onChange={() => onSelectClick(row)}
33+
onClick={event => onSelectClick(event, row, index)}
3434
/>
3535
</TableCell>
3636
{columns.map(column => (

react/Table/Virtualized/index.jsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import PropTypes from 'prop-types'
2-
import React, { useState, forwardRef } from 'react'
2+
import React, { useEffect, useState, useRef, forwardRef } from 'react'
33
import { TableVirtuoso, GroupedTableVirtuoso } from 'react-virtuoso'
44

55
import FixedHeaderContent from './FixedHeaderContent'
@@ -23,6 +23,7 @@ const VirtualizedTable = forwardRef(
2323
componentsProps,
2424
context,
2525
components,
26+
handleShiftArrow,
2627
...props
2728
},
2829
ref
@@ -41,6 +42,31 @@ const VirtualizedTable = forwardRef(
4142
selectedItems
4243
}
4344

45+
const dataRef = useRef(data)
46+
47+
useEffect(() => {
48+
dataRef.current = data
49+
}, [data])
50+
51+
useEffect(() => {
52+
if (!ref?.current) return
53+
const table = ref.current
54+
55+
const handleKeyDown = event => {
56+
if (
57+
event.shiftKey &&
58+
(event.key === 'ArrowUp' || event.key === 'ArrowDown')
59+
) {
60+
event.preventDefault()
61+
const direction = event.key === 'ArrowUp' ? -1 : 1
62+
handleShiftArrow(direction, dataRef.current)
63+
}
64+
}
65+
66+
table.addEventListener('keydown', handleKeyDown)
67+
return () => table.removeEventListener('keydown', handleKeyDown)
68+
}, [handleShiftArrow, ref])
69+
4470
const handleSort = property => {
4571
const isAsc = orderBy === property && order === 'asc'
4672
setOrder(isAsc ? 'desc' : 'asc')

0 commit comments

Comments
 (0)