From b451fa3779b483a59095e5e05b104700a5e4102b Mon Sep 17 00:00:00 2001 From: Levin Rickert Date: Thu, 27 Feb 2025 10:02:54 +0100 Subject: [PATCH 1/2] fix: Support range selection with grid/table checkboxes --- .../grid/src/useGridSelectionCheckbox.ts | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/@react-aria/grid/src/useGridSelectionCheckbox.ts b/packages/@react-aria/grid/src/useGridSelectionCheckbox.ts index 7326146fb57..02bc5c6416c 100644 --- a/packages/@react-aria/grid/src/useGridSelectionCheckbox.ts +++ b/packages/@react-aria/grid/src/useGridSelectionCheckbox.ts @@ -4,6 +4,7 @@ import {GridState} from '@react-stately/grid'; // @ts-ignore import intlMessages from '../intl/*.json'; import {Key} from '@react-types/shared'; +import {useEffect, useRef} from 'react'; import {useId} from '@react-aria/utils'; import {useLocalizedStringFormatter} from '@react-aria/i18n'; @@ -31,8 +32,30 @@ export function useGridSelectionCheckbox>(props: let isDisabled = !state.selectionManager.canSelectItem(key); let isSelected = state.selectionManager.isSelected(key); + let isShiftDown = useRef(false); + useEffect(() => { + let trackKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Shift') { + isShiftDown.current = true; + } + }; + let trackKeyUp = (e: KeyboardEvent) => { + if (e.key === 'Shift') { + isShiftDown.current = false; + } + }; + + document.addEventListener('keydown', trackKeyDown); + document.addEventListener('keyup', trackKeyUp); + + return () => { + document.removeEventListener('keydown', trackKeyDown); + document.removeEventListener('keyup', trackKeyUp); + }; + }); + // Checkbox should always toggle selection, regardless of selectionBehavior. - let onChange = () => manager.toggleSelection(key); + let onChange = () => isShiftDown.current ? manager.extendSelection(key) : manager.toggleSelection(key); const stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/grid'); From f842abe0ef353701fe16d2b7111797e59b387b45 Mon Sep 17 00:00:00 2001 From: Levin Rickert Date: Mon, 3 Mar 2025 08:12:23 +0100 Subject: [PATCH 2/2] cr --- .../@react-aria/grid/src/useGridSelectionCheckbox.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/@react-aria/grid/src/useGridSelectionCheckbox.ts b/packages/@react-aria/grid/src/useGridSelectionCheckbox.ts index 02bc5c6416c..7fc523f8759 100644 --- a/packages/@react-aria/grid/src/useGridSelectionCheckbox.ts +++ b/packages/@react-aria/grid/src/useGridSelectionCheckbox.ts @@ -45,14 +45,14 @@ export function useGridSelectionCheckbox>(props: } }; - document.addEventListener('keydown', trackKeyDown); - document.addEventListener('keyup', trackKeyUp); + document.addEventListener('keydown', trackKeyDown, true); + document.addEventListener('keyup', trackKeyUp, true); return () => { - document.removeEventListener('keydown', trackKeyDown); - document.removeEventListener('keyup', trackKeyUp); + document.removeEventListener('keydown', trackKeyDown, true); + document.removeEventListener('keyup', trackKeyUp, true); }; - }); + }, []); // Checkbox should always toggle selection, regardless of selectionBehavior. let onChange = () => isShiftDown.current ? manager.extendSelection(key) : manager.toggleSelection(key);