Skip to content

Rafferty97/solid-tabular

Repository files navigation

solid-tabular

solid-tabular

npm version bundle size license pnpm

Spreadsheet-like table UI for SolidJS.

Demo: https://alexanderrafferty.com/projects/solid-tabular/

⚠️ This library is currently in early development, and breaking changes will definitely occur.

Features

  • 🚀 Virtualization: Efficiently renders large datasets using @tanstack/solid-virtual.
  • 🖱️ Selection: Excel-like cell and range selection.
  • ✏️ Editing: In-place cell editing.
  • 📏 Resizing: Draggable column resizing.
  • 📋 Clipboard: Copy and paste support.
  • ⌨️ Keyboard Navigation: Arrow keys, Tab, Enter, etc.
  • 🎨 Customizable: CSS variables for theming.

Installation

npm install solid-tabular
# or
pnpm add solid-tabular
# or
yarn add solid-tabular

Basic Usage

The example below shows how to display a static data table using the createTableState utility function.

import { Table, createTableState } from 'solid-tabular'
import 'solid-tabular/styles.css'

function App() {
  const tableProps = createTableState([
    { A: 1, B: 2, C: 3 },
    { A: 4, B: 5, C: 6 },
    { A: 7, B: 8, C: 9 },
  ])

  return (
    <div style={{ width: '100%', padding: '20px' }}>
      <Table {...tableProps} columnsResizeable />
    </div>
  )
}

export default App

This example controls the table data explicitly for more control.

import { createSignal } from 'solid-js'
import { Table, ActiveRange } from 'solid-tabular'
import 'solid-tabular/dist/index.css'

function App() {
  const [activeRange, setActiveRange] = createSignal<ActiveRange>()
  
  const columns = ['A', 'B', 'C']
  
  const [data, setData] = createSignal([
    ['A1', 'B1', 'C1'],
    ['A2', 'B2', 'C2'],
    ['A3', 'B3', 'C3'],
  ])

  return (
    <div style={{ width: '100%', padding: '20px' }}>
      <Table
        columns={columns}
        numRows={data().length}
        getCellValue={(row, col) => data()[row][columns.indexOf(col)]}
        activeRange={activeRange()}
        setActiveRange={setActiveRange}
      />
    </div>
  )
}

API

Table Component

The Table component is the main entry point, and has two generic type parameters Column and Value.

Prop Type Description
columns Column[] Array of column objects.
numRows number Total number of rows.
getCellValue (row: number, column: Column) => Value Function to get the value for a cell.
setCellValue (row: number, column: Column, value: Value) => void Function to update the value of a cell.
activeRange ActiveRange The current selection state.
setActiveRange (range: ActiveRange) => void Callback to update the selection state.
columnsResizeable boolean Enables column resizing.
columnsRenameable boolean Enables column renaming.
addColumnButton boolean Whether to render an "add column" button.
addRowButton boolean Whether to render an "add row" button.
cellHeight number Height of cells in pixels (default: 29).
getCellContent (column: Column) => Component<CellContentProps<Value>> Component used to render the content of cells for a particular column.
getColumnIcon (column: Column) => Component Gets the icon for a particular column.
getColumnSize (column: Column) => number Get column width.
setColumnSize (column: Column, width: number) => void Set column width.
resetColumnSize (column: Column) => void Reset column width.
getColumnName (column: Column) => string Get column name.
setColumnName (column: Column, name: string) => void Set column name.
onInsertColumns (index: number, count: number) => void Insert columns.
onInsertRows (index: number, count: number) => void Insert rows.
onViewportChanged (start: number, end: number) => void Called whenever the range of rows visible in the viewport changes.
onCellContextMenu (ev: MouseEvent, row: number, column: Column) => void Fired when a cell context menu is opened.
onCopy (min: CellIndex, max: CellIndex) => void Called when cells are copied.
onPaste (min: CellIndex, max: CellIndex) => void Called when cells are pasted.
onClear (min: CellIndex, max: CellIndex) => void Called when cells are cleared (delete key).
initialScrollPosition { left: number; top: number } Initial scroll position to restore.
onScrollPositionChange (scrollLeft: number, scrollTop: number) => void Called when the table scroll position changes.

Theming

You can customize the appearance using CSS variables:

.my-table {
  /* General */
  --solid-tabular-font: 0.875rem 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  --solid-tabular-bg-color: oklch(92.8% 0.006 264.531);
  --solid-tabular-text-color: black;

  /* Cells */
  --solid-tabular-cell-color: white;
  --solid-tabular-cell-hover-color: oklch(96.7% 0.003 264.542);
  --solid-tabular-border-color: oklch(87.2% 0.01 258.338);
  --solid-tabular-placeholder-color: oklch(70.7% 0.022 261.325);

  /* Headers */
  --solid-tabular-header-color: var(--solid-tabular-cell-color);
  --solid-tabular-rownum-color: inherit;
  --solid-tabular-font-size-row-num: 1em;

  /* Selection & Accents */
  --solid-tabular-accent-color: oklch(45.7% 0.24 277.023);
  --solid-tabular-shade-color: rgba(0, 0, 0, 0.12);
}

About

Spreadsheet-like table component

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors