Cell Selection
To use multi-cell selection, you need to configure the
<DataSource />
component with selectionMode="multi-cell"
- see selectionMode
for details. For selecting rows, see the Row Selection page. Configuring the selection mode
<DataSource selectionMode="multi-cell" />
// can be "single-row", "multi-row", "multi-cell" or false
COPY
Click cells in the grid to add to the selection.
Use
Shift+Click
to select a range of cells and Cmd/Ctrl+Click
to add single cells to the selection.View Mode
Fork Forkimport { InfiniteTable, DataSource, InfiniteTablePropColumns, } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource = () => { return fetch('https://infinite-table.com/.netlify/functions/json-server' + '/developers1k') .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { id: { field: 'id', defaultWidth: 60 }, firstName: { field: 'firstName' }, preferredLanguage: { field: 'preferredLanguage' }, stack: { field: 'stack' }, country: { field: 'country' }, age: { field: 'age', type: 'number' }, salary: { field: 'salary', type: 'number' }, currency: { field: 'currency', type: 'number' }, }; export default function App() { return ( <DataSource<Developer> primaryKey="id" data={dataSource} selectionMode="multi-cell" > <InfiniteTable<Developer> columns={columns} columnDefaultWidth={100} /> </DataSource> ); }
Using default selection#
You can specify a default value for cell selection by using the
defaultCellSelection
prop. Using default selection
const defaultCellSelection = {
defaultSelection: false,
selectedCells: [
[3, "stack"], // rowId + colId
[5, "stack"], // rowId + colId
[0, "firstName"], // rowId + colId
]
}
<DataSource
selectionMode="multi-cell"
defaultCellSelection={defaultCellSelection}
COPY
Cell selection uses
[rowId, colId]
cell descriptors to identify cells to be marked as selected or deselected - read more in the Cell selection format.By default some cells are already selected in the grid below, by using the
defaultCellSelection
prop on the <DataSource />
component.View Mode
Fork Forkimport { InfiniteTable, DataSource, InfiniteTablePropColumns, DataSourcePropCellSelection_MultiCell, } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource = () => { return fetch('https://infinite-table.com/.netlify/functions/json-server' + '/developers1k') .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { id: { field: 'id', defaultWidth: 60 }, firstName: { field: 'firstName' }, preferredLanguage: { field: 'preferredLanguage' }, stack: { field: 'stack' }, country: { field: 'country' }, age: { field: 'age', type: 'number' }, salary: { field: 'salary', type: 'number' }, currency: { field: 'currency', type: 'number' }, }; export default function App() { const defaultCellSelection: DataSourcePropCellSelection_MultiCell = { defaultSelection: false, selectedCells: [ [3, 'stack'], // rowId + colId [4, 'stack'], [5, 'stack'], [0, 'firstName'], ], }; return ( <DataSource<Developer> primaryKey="id" data={dataSource} defaultCellSelection={defaultCellSelection} selectionMode="multi-cell" > <InfiniteTable<Developer> columns={columns} columnDefaultWidth={100} /> </DataSource> ); }
Whe you're using cell selection with or without any default value (via the
defaultCellSelection
), you're using an uncontrolled prop. This means that the selection state is managed by the <DataSource />
component and not by you. If you want to control the selection state yourself, you can use the controlled cellSelection
prop instead - see Using controlled selection for details.Cell selection format#
The
cellSelection
prop is an object with the following shape:defaultSelection
-boolean
- whether or not cells are selected by default.- either:
selectedCells
:[rowId, colId][]
- an array of cells that should be selected (this is combined withdefaultSelection: false
)
- or
deselectedCells
:[rowId, colId][]
- an array of cells that should be deselected (this is combined withdefaultSelection: true
)
When
defaultSelection
is true
, you will only need to specify the deselectedCells
prop.And when
defaultSelection
is false
, you will only need to specify the selectedCells
prop.In this way, you can either specify which cells should be selected or which cells should be deselected - and have a default that matches the most common case.
The
selectedCells
/deselectedCells
are arrays of [rowId, colId]
tuples. The rowId
is the id
of the row (the primary key), and the colId
is the id
of the column (the identifier of the column in the columns
prop).The following scenarios are all possible:
Just a few specified cells are selected
const defaultCellSelection = {
defaultSelection: false,
selectedCells: [
['id2', 'stack'],
['id2', 'stack'],
['id0', 'firstName'],
],
};
COPY
Everything is selected, except a few cells
const defaultCellSelection = {
defaultSelection: true,
deselectedCells: [
['row2', 'stack'],
['row3', 'stack'],
['row5', 'firstName'],
],
};
COPY
Using wildcards for selection#
It's also possible to use wildcards for selecting cells. This is useful if you want to select all cells in a column, or all cells in a row.
Selecting all cells in a column
const defaultCellSelection = {
defaultSelection: false,
selectedCells: [
['*', 'stack'],
['row2', 'firstName'],
],
};
COPY
Selecting all cells in a row
const defaultCellSelection = {
defaultSelection: false,
selectedCells: [
['row1', '*'],
['row2', 'firstName'],
],
};
COPY
Selecting everything except a column
const defaultCellSelection = {
defaultSelection: true,
deselectedCells: [['*', 'stack']],
};
COPY
Using controlled selection#
When using the controlled
cellSelection
you have to update the value of the property yourself, by listening to the onCellSelectionChange
event.This example shows how to use the
onCellSelectionChange
callback prop to listen to changes to the controlled cellSelection
prop on the <DataSource />
component.View Mode
Fork Forkimport { InfiniteTable, DataSource, InfiniteTablePropColumns, DataSourcePropCellSelection_MultiCell, } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource = () => { return fetch('https://infinite-table.com/.netlify/functions/json-server' + '/developers1k') .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { id: { field: 'id', defaultWidth: 60 }, firstName: { field: 'firstName' }, preferredLanguage: { field: 'preferredLanguage' }, stack: { field: 'stack' }, country: { field: 'country' }, age: { field: 'age', type: 'number' }, salary: { field: 'salary', type: 'number' }, currency: { field: 'currency', type: 'number' }, }; export default function App() { const [cellSelection, setCellSelection] = React.useState<DataSourcePropCellSelection_MultiCell>({ defaultSelection: false, selectedCells: [ [3, 'stack'], [0, 'firstName'], ], }); return ( <div style={{ display: 'flex', flex: 1, color: 'var(--infinite-cell-color)', flexFlow: 'column', background: 'var(--infinite-background)', }} > <div style={{ maxHeight: 200, overflow: 'auto', border: '2px solid magenta', }} > Current selection: <pre>{JSON.stringify(cellSelection, null, 2)}</pre> </div> <DataSource<Developer> primaryKey="id" data={dataSource} cellSelection={cellSelection} onCellSelectionChange={setCellSelection} selectionMode="multi-cell" > <InfiniteTable<Developer> columns={columns} columnDefaultWidth={100} /> </DataSource> </div>
Using the Cell Selection API#
The
<DataSource />
component also exposes a Cell Selection API, which you can use to select and deselect cells programmatically.View Mode
Fork Forkimport { InfiniteTable, DataSource, InfiniteTablePropColumns, DataSourcePropCellSelection_MultiCell, InfiniteTableApi, } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource = () => { return fetch('https://infinite-table.com/.netlify/functions/json-server' + '/developers1k') .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { id: { field: 'id', defaultWidth: 60 }, firstName: { field: 'firstName' }, preferredLanguage: { field: 'preferredLanguage' }, stack: { field: 'stack' }, country: { field: 'country' }, age: { field: 'age', type: 'number' }, salary: { field: 'salary', type: 'number' }, currency: { field: 'currency', type: 'number' }, }; export default function App() { const [cellSelection, setCellSelection] = React.useState<DataSourcePropCellSelection_MultiCell>({ defaultSelection: false, selectedCells: [ [3, 'stack'], [0, 'firstName'], ], }); const [api, setApi] = React.useState<InfiniteTableApi<Developer> | null>(); return ( <div style={{ display: 'flex', flex: 1, color: 'var(--infinite-cell-color)', flexFlow: 'column', background: 'var(--infinite-background)', }} > <button style={{ margin: 10, padding: 10, borderRadius: 5, border: '2px solid magenta', }} onClick={() => { api?.cellSelectionApi.selectColumn('firstName'); }} > Select "firstName" column </button> <div style={{ maxHeight: 200, overflow: 'auto', border: '2px solid magenta', }} > Current selection: <pre>{JSON.stringify(cellSelection, null, 2)}</pre> </div> <DataSource<Developer> primaryKey="id" data={dataSource} cellSelection={cellSelection} onCellSelectionChange={setCellSelection} selectionMode="multi-cell" > <InfiniteTable<Developer> columns={columns} columnDefaultWidth={100} onReady={({ api }) => { setApi(api); }} /> </DataSource> </div>