@@ -544,6 +544,7 @@ export interface DataEditorProps extends Props, Pick<DataGridSearchProps, "image
544544 * @returns A valid GridCell to be rendered by the Grid.
545545 */
546546 readonly getCellContent : ( cell : Item ) => GridCell ;
547+
547548 /**
548549 * Determines if row selection requires a modifier key to enable multi-selection or not. In auto mode it adapts to
549550 * touch or mouse environments automatically, in multi-mode it always acts as if the multi key (Ctrl) is pressed.
@@ -552,6 +553,14 @@ export interface DataEditorProps extends Props, Pick<DataGridSearchProps, "image
552553 */
553554 readonly rowSelectionMode ?: "auto" | "multi" ;
554555
556+ /**
557+ * Determines if column selection requires a modifier key to enable multi-selection or not. In auto mode it adapts to
558+ * touch or mouse environments automatically, in multi-mode it always acts as if the multi key (Ctrl) is pressed.
559+ * @group Editing
560+ * @defaultValue `auto`
561+ */
562+ readonly columnSelectionMode ?: "auto" | "multi" ;
563+
555564 /**
556565 * Add table headers to copied data.
557566 * @group Editing
@@ -838,6 +847,7 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
838847 freezeColumns = 0 ,
839848 cellActivationBehavior = "second-click" ,
840849 rowSelectionMode = "auto" ,
850+ columnSelectionMode = "auto" ,
841851 onHeaderMenuClick,
842852 onHeaderIndicatorClick,
843853 getGroupDetails,
@@ -1320,7 +1330,7 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
13201330 //If the grid is empty, we will return text
13211331 const isFirst = col === rowMarkerOffset ;
13221332
1323- const maybeFirstColumnHint = isFirst ? trailingRowOptions ?. hint ?? "" : "" ;
1333+ const maybeFirstColumnHint = isFirst ? ( trailingRowOptions ?. hint ?? "" ) : "" ;
13241334 const c = mangledColsRef . current [ col ] ;
13251335
13261336 if ( c ?. trailingRowOptions ?. disabled === true ) {
@@ -1829,7 +1839,7 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
18291839 ( args : GridMouseEventArgs ) => {
18301840 const isMultiKey = browserIsOSX . value ? args . metaKey : args . ctrlKey ;
18311841 const isMultiRow = isMultiKey && rowSelect === "multi" ;
1832- const isMultiCol = isMultiKey && columnSelect === "multi" ;
1842+
18331843 const [ col , row ] = args . location ;
18341844 const selectedColumns = gridSelection . columns ;
18351845 const selectedRows = gridSelection . rows ;
@@ -2003,14 +2013,19 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
20032013 lastCol !== undefined &&
20042014 selectedColumns . hasIndex ( lastCol )
20052015 ) {
2016+ // Support for selecting a slice of columns:
20062017 const newSlice : Slice = [ Math . min ( lastCol , col ) , Math . max ( lastCol , col ) + 1 ] ;
20072018
2008- if ( isMultiCol ) {
2019+ if ( isMultiKey || args . isTouch || columnSelectionMode === "multi" ) {
20092020 setSelectedColumns ( undefined , newSlice , isMultiKey ) ;
20102021 } else {
20112022 setSelectedColumns ( CompactSelection . fromSingleSelection ( newSlice ) , undefined , isMultiKey ) ;
20122023 }
2013- } else if ( isMultiCol ) {
2024+ } else if (
2025+ columnSelect === "multi" &&
2026+ ( isMultiKey || args . isTouch || columnSelectionMode === "multi" )
2027+ ) {
2028+ // Support for selecting a single columns additively:
20142029 if ( selectedColumns . hasIndex ( col ) ) {
20152030 // If the column is already selected, deselect that column:
20162031 setSelectedColumns ( selectedColumns . remove ( col ) , undefined , isMultiKey ) ;
@@ -2020,6 +2035,7 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
20202035 lastSelectedColRef . current = col ;
20212036 } else if ( columnSelect !== "none" ) {
20222037 if ( selectedColumns . hasIndex ( col ) ) {
2038+ // If the column is already selected, deselect that column:
20232039 setSelectedColumns ( selectedColumns . remove ( col ) , undefined , isMultiKey ) ;
20242040 } else {
20252041 setSelectedColumns ( CompactSelection . fromSingleSelection ( col ) , undefined , isMultiKey ) ;
@@ -2053,6 +2069,7 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
20532069 onRowMoved ,
20542070 focus ,
20552071 rowSelectionMode ,
2072+ columnSelectionMode ,
20562073 getCellRenderer ,
20572074 themeForCell ,
20582075 setSelectedRows ,
@@ -2146,7 +2163,7 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
21462163
21472164 focus ( ) ;
21482165
2149- if ( isMultiKey ) {
2166+ if ( isMultiKey || args . isTouch || columnSelectionMode === "multi" ) {
21502167 if ( selectedColumns . hasAll ( [ start , end + 1 ] ) ) {
21512168 let newVal = selectedColumns ;
21522169 for ( let index = start ; index <= end ; index ++ ) {
@@ -2160,7 +2177,15 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
21602177 setSelectedColumns ( CompactSelection . fromSingleSelection ( [ start , end + 1 ] ) , undefined , isMultiKey ) ;
21612178 }
21622179 } ,
2163- [ columnSelect , focus , gridSelection . columns , mangledCols , rowMarkerOffset , setSelectedColumns ]
2180+ [
2181+ columnSelect ,
2182+ focus ,
2183+ gridSelection . columns ,
2184+ mangledCols ,
2185+ rowMarkerOffset ,
2186+ setSelectedColumns ,
2187+ columnSelectionMode ,
2188+ ]
21642189 ) ;
21652190
21662191 const isPrevented = React . useRef ( false ) ;
@@ -2392,9 +2417,10 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
23922417 }
23932418 }
23942419 if ( shouldActivate ) {
2395- const act = a . isDoubleClick === true
2396- ? "double-click"
2397- : ( c . activationBehaviorOverride ?? cellActivationBehavior ) ;
2420+ const act =
2421+ a . isDoubleClick === true
2422+ ? "double-click"
2423+ : ( c . activationBehaviorOverride ?? cellActivationBehavior ) ;
23982424 const activationEvent : CellActivatedEventArgs = {
23992425 inputType : "pointer" ,
24002426 pointerActivation : act ,
@@ -2709,7 +2735,6 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
27092735 args . buttons !== 0 &&
27102736 mouseState !== undefined &&
27112737 mouseDownData . current ?. location [ 0 ] === 0 &&
2712- args . location [ 0 ] === 0 &&
27132738 rowMarkerOffset === 1 &&
27142739 rowSelect === "multi" &&
27152740 mouseState . previousSelection &&
@@ -2720,7 +2745,8 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
27202745 const end = Math . max ( mouseDownData . current . location [ 1 ] , args . location [ 1 ] ) + 1 ;
27212746 setSelectedRows ( CompactSelection . fromSingleSelection ( [ start , end ] ) , undefined , false ) ;
27222747 }
2723- if (
2748+ // Only handle rect selection if not already processed by row selection:
2749+ else if (
27242750 args . buttons !== 0 &&
27252751 mouseState !== undefined &&
27262752 gridSelection . current !== undefined &&
@@ -3942,7 +3968,7 @@ const DataEditorImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEditorPr
39423968 ( col : number ) => {
39433969 return typeof verticalBorder === "boolean"
39443970 ? verticalBorder
3945- : verticalBorder ?.( col - rowMarkerOffset ) ?? true ;
3971+ : ( verticalBorder ?.( col - rowMarkerOffset ) ?? true ) ;
39463972 } ,
39473973 [ rowMarkerOffset , verticalBorder ]
39483974 ) ;
0 commit comments