Props
value / onChange
Used to control the data of the grid:
function App() => {
const [ data, setData ] = useState([/*...*/])
return (
<DataSheetGrid
value={data}
onChange={setData}
/>
)
}
value
Type:
T[]
Each element of the array is a row, elements could be anything like strings or objects.
onChange
Type:
(newValue: T[], operations: Operation[]) => void
The first argument is the new value with the updated rows. In most cases this is all you'll need. This makes it possible to directly use the state setter:
const [ data, setData ] = useState([/*...*/])
return (
<DataSheetGrid
value={data}
onChange={(value) => setData(value)}
/>
)
// This is equivalent to
return (
<DataSheetGrid
value={data}
onChange={setData}
/>
)
The second argument is an array of operations:
type Operation = {
type: 'UPDATE' | 'DELETE' | 'CREATE'
fromRowIndex: number
toRowIndex: number
}
In most cases only one operation is passed, but it can happen that multiple operations are batched and passed as second argument.
When type
is DELETE
, the row indices refer to the old value, not the one passed as first argument.
fromRowIndex
is always inclusive, and toRowIndex
is always exclusive. This means that:
- You can compute the number of impacted rows:
toRowIndex - fromRowIndex
- You can get the impacted rows:
value.slice(fromRowIndex, toRowIndex)
You can read this recipe to have an example.
Columns
columns
Type:
Column[]
An array of columns. More details
function App() => {
return (
<DataSheetGrid
columns={[ { title: 'A' }, { title: 'B' }, /*...*/ ]}
/>
)
}
gutterColumn
Type:
Column | false
Used to customize the gutter column to the left of the grid. Mostly used to customize the width or the component that renders the gutter.
To change the width of the gutter column you can simply specify the basis
key (More details):
function App() => {
return (
<DataSheetGrid gutterColumn={{ basis: 60 }} />
)
}
You can also disable the gutter completely by passing false
.
stickyRightColumn
Type:
Column
Default:null
Used to add a column to the right of the grid. The added column is sticky (always visible even when scrolling) and cannot be selected, it is only used to show options to the user: delete row, insert row...
<DataSheetGrid
stickyRightColumn={{
component: ({ deleteRow }) => (
<button onClick={deleteRow}>❌</button>
),
}}
/>
Size
<DataSheetGrid
height={500}
rowHeight={30}
headerRowHeight={50}
/>
height
Type:
number
Default:400
Maximum height of the grid in pixels. If the content is longer, the grid becomes scrollable.
rowHeight
Type:
number
Default:40
Height of a single row in pixels. All rows have the same height.
headerRowHeight
Type:
number
Default:rowHeight
Height of the header row in pixels. Passing the value 0
will completely hide the header row.
Options
<DataSheetGrid />
lockRows
Type:
boolean
Default:false
When true, prevents the user from adding or removing rows, even when using keyboard shortcuts or when pasting large data-set.
autoAddRow
Type:
boolean
Default:false
When true, a new row is added at the end of the grid when the user presses enter while editing a cell from the last row.
autoAddRow
is useless when lockRows
is true
.
disableContextMenu
Type:
boolean
Default:false
When true, no context menu is shown when right clicking. disableContextMenu
is automatically set to true
when
lockRows
is true
.
disableExpandSelection
Type:
boolean
Default:false
When true, the user will not be able to drag the corner of the selection to expand it.
Style
className
Type:
string
CSS class of the outer <div />
.
style
Type:
CSSProperties
Style of the outer <div />
.
rowClassName
Type:
string | ((opt: { rowData: T; rowIndex: number }) => string | undefined)
CSS class of a row, or a function that returns a CSS class for a given row.
cellClassName
Type:
string | ((opt: { rowData: unknown; rowIndex: number, columnId?: string }) => string | undefined)
CSS class of a cell, or a function that returns a CSS class for a given cell.
This is exactly the same as specifying it on the column, but rowData
is of type unknown
because we cannot know how the column wraps the value.
Row behavior
rowKey
Type:
string | (({ rowData: T; rowIndex: number }) => string)
Default:({ rowIndex }) => rowIndex
By default, rows use the row index as the key
, this is not ideal when inserting / deleting rows in the middle of the grid:
React will update all rows instead of adding / deleting a single one in the middle.
For better performance and to avoid tricky behaviors, it is recommended to use some unique id for each row.
You can specify a string
that should be a key of the row object <DataSheetGrid value={[{ id: 'foo' }, ...]} rowKey="id" />
.
For more complex cases (nested properties, compound primary keys, non object rows...) you may specify a function that take the row object and row index as parameters.
createRow
Type:
() => any
Default:() => ({})
A function that should return a new row object. This function is called once per row every time the user appends or inserts new rows. Most often used to add default values and / or random ids to new rows.
duplicateRow
Type:
({ rowData: T, rowIndex: number }) => any
Default:({ rowData }) => ({ ...rowData })
A function that should return a new row object from an existing row. This function is called once per row every time the user duplicates rows. Most often used to override values and / or change uniq ids when duplicating rows.
Customizable components
addRowsComponent
Type:
FC<AddRowsComponentProps> | false
Used to replace the content of the "Add row" button below the grid. Most often used for translations, custom inputs, icons...
Passing false
will hide the component.
See more details and examples.
contextMenuComponent
Type:
FC<ContextMenuComponentProps>
Used to customize the context menu when right-clicking.
See more details and examples.
Callbacks
Callbacks receive parameters of type Cell
. row
is the index of the row, col
the index of the column, and colId
is the id
of the column if specified.
onFocus
Type:
({ cell: { colId?: string, col: number, row: number } }) => void
Default:void
Called when a cell gains focus (ie. the user starts editing its content). This is not the same as active / highlighted.
To know if the grid itself is focused, you can rely on onActiveCellChange
.
onBlur
Type:
({ cell: { colId?: string, col: number, row: number } }) => void
Default:void
Called when a cell is blurred (ie. the user stops editing its content).
onActiveCellChange
Type:
({ cell: { colId?: string, col: number, row: number } | null }) => void
Default:void
Called when the active / highlighted cell changes. Called with null when the grid is blurred.
onSelectionChange
Type:
({ selection: { min: Cell, max: Cell } | null }) => void
Default:void
Called when the selection changes. Called with null when the grid is blurred.