Canvas table grid to render large set of tabular data. Uses virtualization similar to react-window
and React-Konva for primitives such as Rect, Text, Shape etc
- React powered declarative library
- 💯 Virtualized: Only visible cells are rendered
- 💡 Performant: Canvas implementation - 55-60fps (re-render) and 40-60fps (scroll)
- 📜 Supports scrolling using native scrollbars
- 💻 Supports both Fixed and Variable sized grids
- 🔥 Freeze rows and columns
- 🔳 Merge rows and columns
- ✋ Resizable headers
- 🌳 Create Tree tables
- 🎹 Keyboard accessible
- 📃 Pagination sync/async
- 🛠️ Fully typed API written in TypeScript
- 🌈 Full Theming and Context Support
- ⚓ Fill handle support
- 🐾 Customizable undo/redo support
- 📱 Mobile/Touch device support
- 💪 Highly customizable using react-konva
Born out of frustration, having to deal with complicated imperative canvas libraries, I wanted to create something easy to understand and declarative in nature. This Grid primitive is built on top of React Konva making it easy to customize and extend. Take a look at the storybook to learn more.
npm install @rowsncolumns/grid --save
yarn add @rowsncolumns/grid
Konva grid will work in any browser that supports react, konva and canvas element.
Konva Grid is a pure renderer, that will work with many third-party table plugins
https://github.com/rowsncolumns/grid/tree/master/examples/react-table
Uses react-table to create grouped headings and rows, and display on Konva Grid
https://github.com/rowsncolumns/grid/tree/master/examples/excel-worksheet
https://github.com/rowsncolumns/grid/tree/master/examples/zustand
More examples coming soon.
import { Grid, Cell } from '@rowsncolumns/grid'
import { Group, Text, Rect } from 'react-konva'
const App = () => {
const data = {
[[1, 2]]: 'Hello world'
}
return (
<Grid
rowCount={100}
columnCount={100}
width={800}
height={800}
rowHeight={(rowIndex) => 20}
columnWidth={(columnIndex) => 100}
itemRenderer={(props) => (
<Cell
{...props}
value={
data[[props.rowIndex, props.columnIndex]]
}
/>
)}
/>
)
}
This is the list of props that are meant to be used to customise the konva-grid
behavior.
Name | Required | Type | Description | Default |
---|---|---|---|---|
width | true | number | Width of the grid container | 800 |
height | true | number | Height of the grid container | 800 |
columnCount | true | number | No of columns in the grid | 200 |
rowCount | true | number | No of rows in the grid | 200 |
rowHeight | true | function | Function that returns height of the row based on rowIndex | (rowIndex) => 20 |
columnWidth | true | function | Function that returns width of the column based on columnIndex | (columnIndex) => 100 |
itemRenderer | true | Function | React component to render the cell | null |
selectionRenderer | true | Function | React component to render selected cell | null |
scrollbarSize | false | number | Size of the scrollbar | 17 |
showScrollbar | false | boolean | Always show scrollbar | true |
selectionBackgroundColor | false | string | Background color of selected cells | rgba(66, 133, 244, 0.3) |
selectionBorderColor | false | string | Border color of bounding box of selected cells | rgba(66, 133, 244, 1) |
selectionStrokeWidth | false | number | Border width of selection | 1 |
activeCellStrokeWidth | false | number | Border width of activeCell | 2 |
activeCell | false | { rowIndex, columnIndex } | Recently active cell that user has clicked | null |
selections | false | Array | Array of selected cell areas | [] |
mergedCells | false | Array | Array of merged cell areas | [] |
cellAreas | false | Array | Increase the range of certain cells | [] |
snap | false | boolean | Snaps to the next row or column as you scroll | false |
frozenRows | false | number | No of frozen rows | 0 |
frozenColumns | false | number | No of frozen columns | 0 |
showFrozenShadow | false | boolean | Show shadow in frozen columns/rows | true |
shadowSettings | false | object | Customize shadow of frozen columns/rows | true |
onBeforeRenderRow | false | Function | Called right before a row is rendered, useful for react-table |
null |
stageProps | false | Object | Konva stage props | null |
children | false | Function | Inject React Konva shapes using children | null |
wrapper | false | Function | Inject custom context using a wrapper | (children) => children |
showFillHandle | false | boolean | Show fill handle at bottom right corner | true |
onFillHandleMouseDown | false | Function | Callback fired user selects fill handle | null |
fillSelection | false | SelectionProp | Area of selected fill | null |
overscanCount | false | number | Number of items outside the visible viewport should be renderer at all times | 1 |
Scrolls the grid to a specified x,y
position relative to the container
Imperatively trigger re-render of the grid after specified rowIndex
or columnIndex
Get the current scroll position of the grid.
const gridRef = useRef()
const { scrollLeft, scrollTop } = gridRef.current.getScrollPosition()
Check if a cell at a coordinate is a merged cell
Returns a selection IArea
for a particular cell. Useful to get selection area of a merged cell
Returns exact rowIndex
and columnIndex
from a x
and y
cordinate. Useful if you want to get cell coords based on mouse position
Returns offset position { x, y, width, height }
of a cell
Access Konva stage
instance
const gridRef = useRef()
<Grid
ref={gridRef}
>
const stage = gridRef.current.stage
React Konva uses react-reconciler
to create a custom React renderer. Which means Top Level Context is not available inside the canvas. We provide a simple wrapper
prop to pass Context to the Grid
const ThemeContext = React.createContext({})
const theme = { color: 'yellow' }
<Grid
wrapper={(children) => {
return (
<ThemeContext.Provider value={theme}>
{children}
</ThemContext.Provider>
)
}}
/>
This will let you use ThemeContext in any of the React Konva components. To access theme inside Cell
, you could do
const Cell = ({ x, y, width, height }) => {
const theme = useContext(ThemeContext)
return (
<Rect
fill={theme.color}
x={x}
y={y}
width={width}
height={height}
>
)
}
Examples can be found in stories
directory. To run storybook, enter the following commands
yarn
yarn run storybook
Feel free to fork and submit pull requests
git clone https://github.com/rowsncolumns/grid.git
cd grid
yarn
// Run storybook
yarn storybook