simple sheet UI in vanilla JS. Features:
- fast, infinite scrolling.
- small - < 25KB when minimized
- vanilla - only optional depends on Papaparse for CSV parsing
- CSS-based layout - better user experience
- size of column/row auto fit content yet still customizable
- support frozen row/column for data, fixed row/column for custom content
- support tsv/csv pasting (depends on Papaparse)
install:
npm install @plotdb/sheet
include:
<script src="path-to/sheet/index.min.js"></script>
<link rel="stylesheet" type="text/css" href="path-to/sheet/index.min.css"/>
<div class="container"></div>
initialize:
var s = new sheet({
root: '.container',
data: mydata = [[... ], ... /* array of arrays */]
})
root
: container element or selector.fixed
: {row, col}. default {row: 0, col: 0}frozen
: {row, col}. default {row: 0, col: 0}idx
: {row, col}. default {row: true, col: true}size
: {row, col}. force cell size, in array by order.- default: {row: [], col: []}
- example:
{col: ["300px", "12em"]}
class
: {row, col}. additional cell class name, in array by order, as space separated string.- default: {row: [], col: []}
editing
: false to disable editing. default true.- (TBD) in the future we should be able to:
- set edit permission ( e.g., edit, comment )
- apply on range
- (TBD) in the future we should be able to:
scrollLock
: default true. prevent from horizontal scrolling of document.body if true.- this affects how user interact with sheet with scrolling gestures. check src comment for more information.
- see also
enableScrolling
enableScrolling
: default true. enable scrolling if true.- the difference between
scrollLock
andenableScrolling
is that:scrollLock
is for horizontal scrolling that may conflict with browser gesture.enableScrolling
is for mouse / trackpad scrolling behavior
- the difference between
data
: initial data, as array of arraysslider
: default false. show slider widgets if true.cellcfg(opt)
: custom cell definition function. return value based on the givenopt
, which contains:row
: row of the cell to querycol
: col of the cell to querytype
: a string indicating what should we return. it can be:class
: should return the CSS classes for the given cellreadonly
: return true if the given cell should be readonly.
set({row, col, data, range})
: set cell data todata
for cell(s) in rowrow
and colcol
.- update a range based on 2D array
data
whenrange
is true.
- update a range based on 2D array
goto({row, col})
: set grid view starting from coordinate {row, col}render()
: force to re-render visible cellsediting(v)
: set edit status to v, or return edit status if v is not provided.data(d)
: replace data completely withd
and re-render.- return current data if
d
is omitted. d
is in the same format with the constructordata
option
- return current data if
size({row, col})
: update grid size.select(opt)
: set / get selection range- if opt is omitted, return current selection status, which is:
- null, if no selection available.
- the selection object with fields as below:
col
: index of column. omitted for selecting everything on a row.colspan
: span of column. will be 1 if omittedrow
: index of row. omitted for selecting everything on a column.rowspan
: span of row. will be 1 if omitted
{}
= the whole table selected, based on the definition of the selection object.
- otherwise, set selection based on the
opt
selection range object described as above.
- if opt is omitted, return current selection status, which is:
slice()
: delete selected rows/columnsinsert()
: insert empty row/column at selected location.sort(opt)
: sort data based on selected column.opt
is an object with following fields as options:dir
: direction. eitherasc
ordesc
, by defaultasc
.
edited(opt)
: force sheet enter non-edit mode. option:cancel
: default false. if true, cancel current editing and remove content that are going to be inputted.
use sheet.on('event-name', callback)
to handle sheet related events, e.g.,
s = new sheet( ... );
s.on('change', function({row, col, data, range}) {
....
});
Following are a list of possible events:
change
: fired when some cells are updated. callback function with following options, in object:row
: base row of the updated cellcol
: base col of the updated celldata
: data used to update. If it's a 2D array andrange
is true, then cells are updated with values indata
correspondingly relative torow
andcol
as the original cellrange
: true if a range of cells are updated.
menu.on
: fired when acontextmenu
event is fired within sheet. Option is an object with following fields:evt
: corresponding event objectnode
: target node from which this event was fired.
menu.off
: fired when a context menu is expected to dismiss. Option is an object with following fields:evt
: corresponding event objectnode
: target node from which this event was fired.
You can add more than texts in the grid of the sheet, by having an object with following structure in data:
{
type: "data-type",
... /* members according to type */
}
Currently, only node
type is supported:
{ type: "dom", node: SomeElement }
On Chrome in Mac, scrolling left with trackpad with two finger gesture may also triggers swipe back action, which navigate the page back in browsing history. This happens in all websites needing similar actions, including Airtable and Google Spreadsheet.
This may be temporarily solved by setting overscroll-behavior
to contain
of the sheet container, however - if swipe back happens once anywhere outside the sheet container, it then always triggered even in sheet container.
If this happens, try setting overscroll-behavior
to contain
directly on body
to see if it may solve this issue.
Reference:
- https://bugs.chromium.org/p/chromium/issues/detail?id=889846
- https://bugs.chromium.org/p/chromium/issues/detail?id=862693
- https://bugs.chromium.org/p/chromium/issues/detail?id=906886
- https://community.airtable.com/t/3074
MIT