Skip to content

Latest commit

 

History

History
325 lines (273 loc) · 11.7 KB

File metadata and controls

325 lines (273 loc) · 11.7 KB

@datasketch/monkeytab — API Reference

The complete props reference for the <MonkeyTable> React component.

Install

npm install @datasketch/monkeytab

React 18 or 19 is required as a peer dependency.

Quick Start

import { MonkeyTable } from '@datasketch/monkeytab';

function App() {
  return (
    <MonkeyTable
      columns={[
        { id: 'Name' },
        { id: 'Age', type: 'Number' },
        { id: 'Active', type: 'Boolean' },
      ]}
      rows={[
        { Name: 'Alice', Age: 30, Active: true },
        { Name: 'Bob', Age: 25, Active: false },
      ]}
      onChange={(rows) => console.log('Updated:', rows)}
      height="auto"
    />
  );
}

<MonkeyTable> Props

Data

Prop Type Default Description
columns MonkeyTableColumn[] required Column definitions (id, type, options)
rows Record<string, Value>[] required Row data — each row is a { columnId: value } mapping
onChange (rows) => void Fires after any mutation. Receives the full denormalized row array.
onRowsChange (rows: Row[]) => void Same trigger as onChange but receives full Row objects with ids/timestamps
onCellChange (rowId, fieldId, newValue, oldValue) => void Granular per-cell change callback. Fires synchronously on every cell edit. Use for PATCH-style API persistence.
onSelectionChange (ids: string[]) => void Fires on every checkbox toggle
selectedRowIds string[] Controlled selection — set externally
onRowClick (row) => void Fires when a row body is clicked (not checkboxes)
onUpload (file: File, fieldType: string) => Promise<string> File upload handler — return permanent URL. Without it, files become base64 data URLs.

Sorting

Prop Type Default Description
sortBy string | null Controlled sort field
sortDirection 'asc' | 'desc' | null Controlled sort direction
onSortChange (fieldId, direction) => void Fires when user changes sort. Use for server-side sorting.

Pagination

Prop Type Default Description
totalRows number Total row count from server. When set, enables pagination UI.
page number 1 Current page (1-based). Controlled.
pageSize number 500 Rows per page
onPageChange (page: number) => void Fires on page navigation
paginationMode 'simple' | 'load-more' 'simple' UI style
paginationLoading boolean false Shows loading state during fetch

Layout

Prop Type Default Description
height 'auto' | number | string '100%' 'auto' fits content, number = fixed pixels (ghost rows on), string = CSS
maxHeight number Max height in px. Caps 'auto' growth or fluid containers
rowHeight RowHeightOption 'medium' 'short' | 'medium' | 'tall' | 'extra-tall' | 'fit'
showRowNumbers boolean false Show row number column
compactMode boolean false Denser layout — smaller fonts, tighter padding
ghostGrid boolean | { rows?: number, columns?: number } Show faint placeholder cells to fill the viewport. Defaults to true when height is a number

Permissions

Prop Type Default Description
editable boolean true Master switch — enable cell editing, row/column CRUD
allowCreateField boolean true Allow adding new columns
allowDeleteField boolean true Allow deleting columns
allowCreateRecord boolean true Allow adding new rows
allowColumnReorder boolean true Enable drag-and-drop column reorder
allowMultiColumnDrag boolean true Enable selecting and dragging multiple columns
confirmBeforeDelete boolean true Show confirmation dialog before destructive actions

Toolbar

Prop Type Default Description
showToolbar boolean true Show the toolbar above the grid
showSearch boolean true Show the search input
showFilters boolean true Show the filter button
showRowHeightControl boolean true Show the row height dropdown
showRowNumbersControl boolean true Show the row numbers toggle
showAddRowButton boolean true Show the add-row button

Locale & Formatting

Prop Type Default Description
locale string 'en-US' BCP 47 locale tag (e.g. 'es-CO', 'ja-JP')
language string UI language override — defaults to locale primary subtag
dateDisplayFormat 'iso' | 'locale' | 'relative' 'iso' How dates are displayed
numberDecimalPlaces number 2 Default decimal places for numbers
numberThousandsSeparator boolean false Show thousands separator (1,000)
currencyCode string 'USD' ISO 4217 currency code
currencyDisplay 'symbol' | 'narrowSymbol' | 'code' | 'name' 'symbol' How to display currency
translations Partial<I18nStrings> Override any UI string

Registry Extensions

Prop Type Default Description
functions FunctionDef[] Custom computed functions — registered on mount
constraints FieldTypeConstraint[] Custom field constraints
renderers Record<string, Component> Override built-in cell renderers
editors Record<string, Component> Override built-in cell editors

See EXTENDING.md for usage details.


MonkeyTableColumn

interface MonkeyTableColumn {
  id: string;                              // column key (used in row data)
  label?: string;                          // display label — defaults to id
  type?: FieldType;                        // defaults to 'Text'
  options?: FieldOptions;                  // type-specific options
  icon?: ReactNode;                        // custom column header icon
  render?: CellRendererFn;                 // custom cell renderer for this column
  hidden?: boolean;                        // hide column but keep data accessible
  editable?: boolean;                      // per-column read-only override
  width?: number;                          // initial width in pixels (default: 180)
  minWidth?: number;                       // minimum width (default: 80)
  maxWidth?: number;                       // maximum width (default: 600)
  sortable?: boolean;                      // can this column be sorted (default: true)
  align?: 'left' | 'center' | 'right';     // cell text alignment
}

Field Types

Type Description Key Options
Text Plain text, multiline, markdown, or JSON multiline, richText, json, maxLength, placeholder
Number Numeric values with formatting precision, format (decimal/percentage/currency), min, max, currencySymbol, thousandsSeparator
Boolean Checkbox, toggle, yes/no, or icon displayAs (checkbox/toggle/yesno/icon), trueLabel, falseLabel, trueIcon, falseIcon, trueColor, falseColor
Date Date, datetime, or time format (date/datetime/time), dateFormat, use24Hour
SingleSelect Dropdown selection options: [{ value, label, color }]
MultiSelect Multiple selections options: [{ value, label, color }], maxSelections
Image Image thumbnails with URL links maxImages, maxFileSize, displaySize
Attachment Generic file attachments maxFiles, maxFileSize, allowedTypes
Email Email address with mailto link
URL Clickable URL with optional label
Phone Phone number with tel link
Color Color swatch + hex value format (hex/rgb/hsl)
Rating Star/heart/circle rating max, icon
Computed Derived from other fields functionName, inputFieldIds, params

Keyboard Shortcuts

Key Action
↑↓←→ Move active cell
Tab / Shift+Tab Move right/left
Shift+↑↓←→ Extend selection range
Enter Edit active cell (or add row when on last)
Shift+Enter Insert new row
Escape Cancel editing / clear selection
Cmd+C / Ctrl+C Copy cell or range as TSV
Cmd+V / Ctrl+V Paste TSV (multi-cell paste from clipboard)
Cmd+Z / Ctrl+Z Undo
Cmd+Shift+Z / Ctrl+Shift+Z Redo

Header Interactions

Action Result
Click column header Toggle sort (asc → desc → none)
Cmd/Ctrl + Click Select column for drag
Shift + Click Select header range, copy labels with Cmd+C
Right-click / ⋮ menu Open column context menu (rename, change type, hide, sort, delete)

Examples

Editable table with change tracking

<MonkeyTable
  columns={[
    { id: 'Task' },
    { id: 'Priority', type: 'SingleSelect', options: {
      options: [
        { value: 'high', label: 'High', color: '#fee2e2' },
        { value: 'medium', label: 'Medium', color: '#fef9c3' },
        { value: 'low', label: 'Low', color: '#dcfce7' },
      ]
    }},
    { id: 'Done', type: 'Boolean' },
  ]}
  rows={[
    { Task: 'Write docs', Priority: 'high', Done: false },
    { Task: 'Fix bug #42', Priority: 'medium', Done: true },
  ]}
  onChange={(rows) => console.log(rows)}
  height={300}
  showRowNumbers
/>

Read-only table with compact mode

<MonkeyTable
  columns={[
    { id: 'Metric' },
    { id: 'Q1', type: 'Number', options: { precision: 0, thousandsSeparator: true } },
    { id: 'Q2', type: 'Number', options: { precision: 0, thousandsSeparator: true } },
  ]}
  rows={[
    { Metric: 'Revenue', Q1: 120000, Q2: 145000 },
    { Metric: 'Expenses', Q1: 98000, Q2: 102000 },
  ]}
  editable={false}
  compactMode
  height={200}
  rowHeight="short"
/>

Per-column options

<MonkeyTable
  columns={[
    { id: 'Id', type: 'Number', editable: false, width: 80, sortable: false, align: 'center' },
    { id: 'Name', type: 'Text', width: 250, minWidth: 150, maxWidth: 400 },
    { id: 'Price', type: 'Number', align: 'right', width: 120 },
    { id: 'Notes', type: 'Text' },
  ]}
  rows={rows}
  editable
/>

Server-side pagination and sorting

const [page, setPage] = useState(1);
const [sortField, setSortField] = useState<string | null>(null);
const [sortDir, setSortDir] = useState<'asc' | 'desc' | null>(null);
const { data, total, isLoading } = useFetchRows({ page, sortField, sortDir });

<MonkeyTable
  columns={columns}
  rows={data}
  totalRows={total}
  page={page}
  pageSize={100}
  onPageChange={setPage}
  paginationMode="simple"
  paginationLoading={isLoading}
  sortBy={sortField}
  sortDirection={sortDir}
  onSortChange={(field, dir) => {
    setSortField(field);
    setSortDir(dir);
    setPage(1);  // reset to first page on sort change
  }}
/>

Spanish locale with custom translations

<MonkeyTable
  columns={columns}
  rows={rows}
  locale="es-CO"
  language="es"
  dateDisplayFormat="locale"
  currencyCode="COP"
  translations={{ 'toolbar.addRow': 'Nueva fila' }}
  onChange={handleChange}
/>

Custom file upload

<MonkeyTable
  columns={[
    { id: 'Name' },
    { id: 'Photo', type: 'Image' },
    { id: 'Resume', type: 'Attachment' },
  ]}
  rows={rows}
  onUpload={async (file, fieldType) => {
    const form = new FormData();
    form.append('file', file);
    const res = await fetch('/api/upload', { method: 'POST', body: form });
    const { url } = await res.json();
    return url;
  }}
/>