Spreadsheet like react canvas datagrid optimized for performance built entirely typescript and react functional components with react hooks.
- recent changes
- features
- todo
- quickstart
- examples list
- tips
- how to contribute ( quickstart )
- local deploy
- how this project was built
- development notes
- v0.23.6
- fix custom render component visibiliy when column scrolls
- v0.23.5
- infinite rearrangement workaround ; repro start sample5 and size height of the window like the grid then add items until last in the grid will start infinite rearrange
- v0.23.4
- added margin when wrap custom rendere objects
- can't deselect cell ( a better negative selection should implement with a class that implements a contains operator that matches in order selection pattern, for example select all then deselect a cell )
- smooth scroll ( actually scroll by row and col and not partial by pixel )
- a complete refactoring with better state management ( collect all feature currently available and rewrite the code with better modularization and functional correspondance )
- canvas based high performance datagrid ( able to scroll with ease millions of rows maintaining immediate cell focus and editing features )
50000 rows x 200 cols example ( LIVE EXAMPLE : click EX1 button )
-
direct cell editing, just click on a cell then type, hit ENTER or arrows keys to move next ( native cell types )
- "text": type text to change cell ; CANC to clear cell ; CTRL+C / CTRL+V to copy/paste
- "boolean": toggle boolean with keyboard space when cell focused
- "date", "time", "datetime": smart date insertion ( typing 121030 results in 12/10/2030 ) browser locale supported
- "number": sci numbers ( typing 12e-3 results in 0.012 displayed ) browser locale support for decimal separators
-
cell or row selection mode
- selection mode multi
- frozen rows, cols
-
rows and cols numbering can be shown or hidden
-
if column numbering visible automatic sort can be customized through less-than-op ( helper )
-
column click behavior can be full column select, column toggle sort or none to disable sort/select behavior
-
column header can be customized ( helper )
-
canvas size can be specified through width, height ( fullwidth option available )
-
column width can be changed intractively using mouse
-
column width autoexpand
-
column custom initial sort ( note: prepareCellDataset, rowSetCellData, commitCellDataset must defined to make sort working ); also see example6 for tip about ensure initial sort on subsequent datasource applications
-
data getter/setter can follow a worksheet or a db record type ( example of nested field using getFieldData and setFieldData methods)
-
data filter global
-
optional dataset on external object with ds rows getter mapper useful in some circumstance when need to preserve rows array object ref
-
api and handlers available for control interactions ( example ) ; props can be accessed inversely through api; retrieve list of selected row idxs example
- each individual cell custom edit ( F2 ) control can be customized also in column helper ( example : through keyboard F2, arrows then enter ) ; cell editing/edited also in column helper
-
custom multi select with material-ui ( example )
-
custom date picker with material pickers ( example )
- custom color picker with custom render ( example ) ; note: wrapText will use custom component height to autoresize row height ; filter can work as text mode defining renderTransform
- cell background, font and color, readonly mode customization and text align also with helper
-
container height min and canvas styles
-
each individual cell type can be customized ( column helper )
-
clipboard copy to/from spreadsheet with ctrl-c and ctrl-v or api ( example api )
- support mobile touch scrolling rows, cols and scrollbars
- create react app
eventually install create-react-app
npm install -g create-react-app
create-react-app test --template typescript
cd test
yarn add react-ws-canvas
- edit
App.tsx
as follows
import React, { useState, useEffect } from 'react';
import { WSCanvas, useWindowSize, WSCanvasColumnClickBehavior } from 'react-ws-canvas';
const AppQuickStart: React.FC = () => {
const [rows, setRows] = useState<any[][]>([]);
const winSize = useWindowSize();
const ROWS = 500000;
const COLS = 20;
useEffect(() => {
const _rows = [];
for (let ri = 0; ri < ROWS; ++ri) {
const row = [];
for (let ci = 0; ci < COLS; ++ci) {
row.push("r:" + ri + " c:" + ci);
}
_rows.push(row);
}
setRows(_rows);
}, []);
return <WSCanvas
width={winSize.width} height={winSize.height}
rowsCount={rows.length} colsCount={COLS}
showColNumber={true} showRowNumber={true}
columnClickBehavior={WSCanvasColumnClickBehavior.ToggleSort}
rows={rows}
rowGetCellData={(row, colIdx) => row[colIdx]}
prepareCellDataset={() => rows.slice()}
commitCellDataset={(q) => setRows(q)}
rowSetCellData={(row, colIdx, value) => row[colIdx] = value}
/>;
}
export default AppQuickStart;
- run the app
yarn start
example | description |
---|---|
quickstart | 500000 x 20 grid with minimal props |
Sample1 | 50000 x 200 grid with frozen row/col, filter, custom column width |
Sample2 | 5000 x 6 grid db-record-like column mapping, initial sort, custom sort, api onMouseDown, global filter, cell changing/changed |
Sample3 | 5000 x 7 grid db-record-like, data interact del/change row, custom cell editor, rowHover |
Sample4 | add/insert/del/move/currentRealRowSel rows using api |
Sample5 | custom multi select with material-ui ; custom render chip with color picker |
Sample6 | resetView behavior to force sync ds ; resetSorting and resetFilters resetView arguments |
prevent direct editing on editor customized cells
customize onPreviewKeyDown event handler on datagrid and preventDefault for matching cell
onPreviewKeyDown={(states, e) => {
if (states.props.columns && api && api.isDirectEditingKey(e)) {
const fieldname = states.props.columns[states.state.focusedCell.col].field;
if (fieldname === "colname") {
//const row = states.props.rows[states.state.focusedCell.row];
e.preventDefault();
}
}
}}
- clone repo
git clone https://github.com/devel0/react-ws-canvas.git
- open vscode
cd react-ws-canvas
code .
- from vscode, open terminal ctrl+` and execute example application ( this allow you to set breakpoints directly on library source code from
lib
folder )
cd example
yarn install
yarn start
- start chrome session using F5
- from library
cd lib
yarn build && yalc publish
- from your project
npm uninstall react-ws-canvas --save && yalc add react-ws-canvas && npm install
yarn create react-app react-ws-canvas --template typescript
Because I need a library to publish and either a working example to test/debug the library project structured this way:
/package.json
( workspaces "example" and "lib" )/example
( example and library sources )/example/package.json
/example/.env
with BROWSER=none to avoid browser start when issueyarn start
because I use F5 from vscode to open debugging session/example/lib
( library source codes )
/lib
( library publishing related files )/lib/package.json
/lib/rollup.config.json
( specificallyinput: '../example/src/lib/index.tsx',
)/lib/tsconfig.json
( specifically"rootDirs": ["../example/src/lib"],
and"include": ["../example/src/lib"],
)/lib/prepatch-and-publish
( helper script to prepatch version and publish with README.md )
- key notes (old)
- cs.width and cs.height variables represents canvas size and used as starting point for calculations
- stateNfo, viewMap, overridenRowHeight are kept separate because stateNfo must light because frequently updated while viewMap and overridenRowHeight can be heavy struct for large grids
- view mapping have a size less-or-equal than rowsCount depending on filtering and the order of view may different depending on sorting
- some methods work with real cells ( the same as user configure through getCellData, setCellData ), some other methods works with view cells that is an internal representation convenient to deal on what-you-see-is-what-you-get
- real and view coords can be transformed between
- mkstates is an helper used primarly by handlers to ensure callback uses synced state
- TODO
- type 'select' for cell with combobox integrated
- date picker when F2 (or double click) on date type cell
- isOverCell should true on last row when showPartialRows
- deployment
- remove any
from "react-ws-canvas";
- remove any