Skip to main content

Columns

DSG is column based, meaning that all cells of a given column are of the same type and have the same widget. This is why it is more like Notion or Airtable, and less like Excel.

The columns array

Columns are simple objects, and the list of columns is a simple array of column objects:

const columns = [{}, {}]

If you are using typescript:

import { Column } from 'react-datasheet-grid'

const columns: Column[] = [{}, {}]
// You may specify the row type
type Row = { firstName: string, lastName: string }
const columns: Column<Row>[] = [{}, {}]

Built-in columns

To get you started, 6 simple columns are built-in:

  • textColumn
  • checkboxColumn
  • intColumn
  • floatColumn
  • dateColumn
  • percentColumn
textColumn
checkboxColumn
intColumn
floatColumn
dateColumn
percentColumn
1
2
3
4
5
rows

Each built-in column handles rows of a very specific data type:

import {
DataSheetGrid,
textColumn,
checkboxColumn,
} from 'react-datasheet-grid'

const ExampleStrings = () => {
const [ data, setData ] = useState(['foo', 'bar', 'baz'])

const columns = [textColumn]

return (
<DataSheetGrid
value={data}
onChange={setData}
columns={columns}
/>
)
}

const ExampleBooleans = () => {
const [ data, setData ] = useState([true, false, true])

const columns = [checkboxColumn]

return (
<DataSheetGrid
value={data}
onChange={setData}
columns={columns}
/>
)
}

Overriding column props

Because columns are simple objects, you can easily override any property by spreading it. See the exhaustive list of properties a column has.

const columns = [
{
...textColumn,
title: 'Name',
minWidth: 200
}
]

Using objects as rows

In a real world project we often use objects and would like each column to handle a specific key of that object. This is where keyColumn comes in:

import {
DataSheetGrid,
checkboxColumn,
textColumn,
keyColumn,
} from 'react-datasheet-grid'

const Example = () => {
const [ data, setData ] = useState([
{ active: true, firstName: 'Elon', lastName: 'Musk' },
{ active: false, firstName: 'Jeff', lastName: 'Bezos' },
])

const columns = [
keyColumn('active', checkboxColumn),
keyColumn('firstName', textColumn),
keyColumn('lastName', textColumn),
]

return (
<DataSheetGrid
value={data}
onChange={setData}
columns={columns}
/>
)
}

keyColumn wraps all properties of a column and allows you to write simpler columns that only need to handle a specific data type. It also has a very positive performance impact.

Because columns are still regular objects, you can override any props by spreading it:

const columns = [
{
...keyColumn('active', checkboxColumn),
title: 'Active'
},
{
...keyColumn('firstName', textColumn),
title: 'First name'
},
{
...keyColumn('lastName', textColumn),
title: 'Last name'
},
]

Typescript

keyColumn is a generic that takes the row type and the key as parameters:

const columns = [
{
...keyColumn<Row, 'active'>('active', checkboxColumn),
title: 'Active'
},
// ...
]

Unfortunately, due to the complexity of the type, you have to type the key twice (eg. 'active' is written twice).

Building custom columns

Built-in columns are there to get your project started, but often you end up building you own custom columns to fit your needs. Note that built-in columns and helpers have nothing special, they are built on top of this library and do not ofer any additional feature that would not be available otherwise.

Text-based columns

To create a text-based column that simply has some custom parsing and formatting functions you do not have to implement a custom component from scratch and can instead use createTextColumn:

import { createTextColumn } from 'react-datasheet-grid'

const columns = [ createTextColumn({ /* options */ }) ]
// When using Typescript you may specify the data type:
const columns = [ createTextColumn<number>({ /* options */ }) ]

placeholder

Type: string
Default: null

alignRight

Type: boolean
Default: false

continuousUpdates

Type: boolean
Default: true

When true, data is updated as the user types, otherwise it is only updated on blur. Setting it to false will improve performance.

deletedValue

Type: T
Default: null

Value to use when deleting the cell

parseUserInput

Type: (value: string) => T

Parse what the user types

formatBlurredInput

Type: (value: T) => string

Format the value of the input when it is blurred

formatInputOnFocus

Type: (value: T) => string

Format the value of the input when it gets focused

formatForCopy

Type: (value: T) => string

Format the value when copy

parsePastedValue

Type: (value: string) => T

Parse the pasted value

Using a custom component

If you need a more exotic column, you can write your own from scratch. A column consists of a custom component that renders the widget and a few props to control its behavior.

See an example of how to implement a select column, or read the exhaustive list of properties a column has.

const columns = [
{
component: MyWidget,
title: 'My column'
}
]