Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

streaksheet

Package Overview
Dependencies
Maintainers
4
Versions
142
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

streaksheet

(Under development)

  • 0.7.7
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
6
increased by20%
Maintainers
4
Weekly downloads
 
Created
Source

StreakSheet

(Under development)

Usage

Important: StreakSheet requires the browser to support AbortController, so if you need to support browsers that predate it (https://caniuse.com/#feat=abortcontroller), you must first load a global polyfill.

Example

To run the example:

yarn example-watch

Then open http://localhost:1234 in your browser. The page automatically refreshes after making a change.

Styling

You can provide custom styles for most components via the styles prop. Each value of this object in an optional function. The first argument is the default styles and the second is an object of state values specific to that component. The return value is a CSSProperties object.

(base: CSSProperties, state: {}) => CSSProperties;

You can choose to extend the default styles or replace them completely. You almost always want to do the former.

styles={{
  columnReorderOverlay: base => ({
    ...base,
    backgroundColor: 'red',
  })
}}

Be careful when overriding styles completely. Many components apply rules like position: absolute that will break the component if removed.

The Styles type indicates exactly what state values each style callback sends. Some components are unaffected by state, in which case the second argument is omitted completely.

styles={{
  columnResizeHandle: (base, { isDragging }) => ({
    ...base,
    backgroundColor: isDragging ? 'red' : 'blue',
  })
}}

This API is inspired by React Select

Selection Styles

For each selection type there are actually two styles to apply: one for the foreground, another for the background. Typically you want to apply a backgroundColor rules to the background style and borders to the foreground. This prevents elements like images from getting discolored by a partially transparent background overlaying it.

styles={{
  selectionBackground: base => ({
    ...base,
    backgroundColor: 'red',
  })
  selectionForeground: base => ({
    ...base,
    borderTop: '1px dashed blue',
  })
}}

Overriding Borders

When applying custom border styles, it's common to want different styles for different edges. To make overriding default styles easier, internally we use borderBottom, borderLeft, borderRight, and borderTop shorthand, even when all four rules have the same value.

styles={{
  columnHeaderCellContainer: (base, { columnIndex }) => ({
    ...base,
    // Make border between cells 1px while keeping border on leftmost cell.
    borderLeft: columnIndex === 0 ? '1px solid black' : 'none',
  })
}}

Style Keys

  • cell
  • columnHeaderCellContainer
  • columnHeadersContainer
  • columnReorderIndicator
  • columnReorderOverlay
  • columnResizeHandle
  • columnResizeIndicator
  • copiedRegionBackground
  • copiedRegionForeground
  • grid
  • highlightedRowBackground
  • highlightedRowForeground
  • primarySelectedCellBackground
  • primarySelectedCellForeground
  • sectionHeaderCellContainer
  • sectionHeadersContainer
  • selectionBackground
  • selectionForeground

Keys vs. Indexes

StreakSheet internally often uses row and column indexes to refer to a cell. For example, the selection logic uses indexes and has no knowledge of sections.

The client never deals with indexes. Instead, section, row, and column keys uniquely identify each cell. In callbacks like onPaste and imperative methods like getSelectedCells, cells are represented by objects:

{
  sectionKey: string;
  rowKey: string;
  columnKey: string;
}

Internally, a cellIndexesToKeys function converts raw grid indexes to cell keys.

Selections

There are multiple ways a cell can appear selected.

It may be sufficient to override the default styles for the various selections, but you can also get the current selection using the imperative getSelectedCells method.

const selectedCells = sheetRef.current.getSelectedCells();

Primary Selected Cell

The first cell of each selection region is the "primary" selected cell. It acts as the anchor when expanding the selection region using the keyboard. When you click on the grid and there's a single cell selected, this is the primary one.

You can change the primary selected cell by clicking on any cell or using the arrow keys.

Selection Region

Clicking and dragging or using shift + arrow keys allows you to select multiple cells.

It's possible to have multiple selection regions by holding command while dragging.

Highlighted Row

All the cells in the same row as the primary selected cell appear highlighted. This isn't a selection per se, more a visual decoration.

Copied Region

When some cells are selected and you hit command-c to copy them, the copied region is indicated until the user pastes or copies a different region.

Copying Cells

StreakSheet supports the ability to copy and paste regions of cells. Clients listen for a paste event by supplying an onPaste to the useSheetData hook.

Upon being notified of a paste, it's up to the client to update the data accordingly. StreakSheet takes care of mapping the source cells to target cells.

onPaste: pasteTargets => {
  // pasteTargets is an array of objects with source and target keys.
  //
  // [
  //   {
  //     source: { sectionKey: 'a', 'rowKey: 'b', columnKey: 'c' },
  //     target: { sectionKey: 'd', 'rowKey: 'e', columnKey: 'f' },
  //   },
  //   ...
  // ]
};

The onPaste callback has a second argument didCut which indicates if the user used command-x rather than command-c to copy the selection. Again, it's up to the client to update the source cells (or not, depending on the desired behaviour).

When the paste region is larger than the copy region (i.e. the user copies a range, selects a larger range, then pastes), the copied values are "looped". That is, a 2x2 region pasted to a 3x3 region will result in this:

┏━━━━━┳━━━━━┓ ┏━━━━━┳━━━━━┳━━━━━┓
┃  A  ┃  B  ┃ ┃  A  ┃  B  ┃  A  ┃
┣━━━━━╋━━━━━┫ ┣━━━━━╋━━━━━╋━━━━━┫
┃  C  ┃  D  ┃ ┃  C  ┃  D  ┃  C  ┃
┗━━━━━┻━━━━━┛ ┣━━━━━╋━━━━━╋━━━━━┫
              ┃  A  ┃  B  ┃  A  ┃
              ┗━━━━━┻━━━━━┻━━━━━┛

The resulting pasteTargets will have nine entries. Assuming the copy region starts at [row 0, column 0] and the selection region at [row 10, column 10], the list will be:

[
  { source: {..., rowKey: '0', columnKey: '0'}, target: {..., rowKey: '10', columnKey: '10'} },
  { source: {..., rowKey: '0', columnKey: '1'}, target: {..., rowKey: '10', columnKey: '11'} },
  { source: {..., rowKey: '0', columnKey: '0'}, target: {..., rowKey: '10', columnKey: '12'} },
  { source: {..., rowKey: '1', columnKey: '0'}, target: {..., rowKey: '11', columnKey: '10'} },
  { source: {..., rowKey: '1', columnKey: '1'}, target: {..., rowKey: '11', columnKey: '11'} },
  { source: {..., rowKey: '1', columnKey: '0'}, target: {..., rowKey: '11', columnKey: '12'} },
  { source: {..., rowKey: '0', columnKey: '0'}, target: {..., rowKey: '12', columnKey: '10'} },
  { source: {..., rowKey: '0', columnKey: '1'}, target: {..., rowKey: '12', columnKey: '11'} },
  { source: {..., rowKey: '0', columnKey: '0'}, target: {..., rowKey: '12', columnKey: '12'} },
]

FAQs

Package last updated on 15 Sep 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc