Skip to content

Repository files navigation

active-grid

A canvas grid with a zooming camera, where every cell is drawn by your code.

  • Zooming camera — pan, wheel-zoom, fit() the whole grid, animated focus on a single cell
  • Layered cell drawers — a cell is an ordered stack of { data, drawer } layers, drawn bottom→top
  • Background layers — gradients, hover highlights, routed paths between cells
  • Sticky cells — pin a row, a column or a single cell to the viewport edge
  • Header / footer decor — strips above or below a cell that never reflow the layout
  • HTML focus overlay — real DOM (selectable text, links, forms) over the focused cell

Zero runtime dependencies. ESM only. TypeScript types included.

Install

npm i active-grid

Hello grid

import {ActiveGrid, type CellDrawer} from 'active-grid';

const label: CellDrawer<string> = {
    draw(text, {rect}, ctx) {
        ctx.fillStyle = '#1b2a35';
        ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
        ctx.fillStyle = '#e0fbfc';
        ctx.font = '14px sans-serif';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText(text, rect.x + rect.width / 2, rect.y + rect.height / 2);
    },
};

const grid = new ActiveGrid({rows: 4, cols: 6, cellWidth: 120, cellHeight: 60, gap: 4});

for (let row = 0; row < 4; row++) {
    for (let col = 0; col < 6; col++) {
        grid.setCell(row, col, {data: `${row},${col}`, drawer: label});
    }
}

grid.attach(document.getElementById('grid') as HTMLCanvasElement);

The canvas must have a parent element and a CSS size — the grid tracks it with a ResizeObserver and fits the whole grid on the first frame.

<div style="position: relative; width: 100%; height: 100vh">
    <canvas id="grid" style="width: 100%; height: 100%"></canvas>
</div>

Core concepts

Concept API
The grid new ActiveGrid(config: GridConfig), attach(canvas), detach()
Cell content setCell(row, col, ...layers) — each layer is a CellLayer<T> = { data, drawer }
Drawing CellDrawer<T> — draw, optional layoutWidth/layoutHeight, onHover, onClick
Cell state CellContext — rect, scale, pointer, hovered, selected, focused, sticky, decor
Backgrounds setBackground(...) with verticalGradient(from, to), cellHover(color), cellPath(config)
Sticky cells setSticky(row, col, { horizontal, vertical })
Decor setHeader(row, col, height, ...layers), setFooter(...)
Camera fit(), setScale(1..100), revealCell(row, col), focusCell(row, col), clearFocus()
Focus overlay setFocusLayout(layout: FocusLayout) — returns HTML for the focused cell, or null
Keyboard setKeyboard(controller), defaultKeyboardController, focusKeyboard, selectAndShow
Events onHoverChange, onSelectionChange, onFocusChange, onScaleChange

Omit cellWidth/cellHeight to size columns and rows from the widest/tallest layer that implements layoutWidth/layoutHeight.

Focus overlay

setFocusLayout returns HTML shown over the focused cell. The panel is created for you, next to the canvas, with the class ag-focus-overlay:

grid.setFocusLayout(({row, col}) => `<article><h3>Cell ${row},${col}</h3><p>Selectable text.</p></article>`);

The library ships no stylesheet — only layout styles are set inline. Style the panel yourself:

.ag-focus-overlay {
    padding: 12px 16px;
    border: 1px solid #2c4152;
    border-radius: 6px;
    background: #12202b;
    color: #e0fbfc;
}

Development

npm run dev         # demo at http://localhost:5173
npm test            # vitest
npm run build       # ESM bundle + .d.ts into dist/
npm run build:demo  # deployable demo into dist-demo/

The demo under demo/ is the reference for everything canvas-related: one sample per file, with drawers, keyboard controllers and focus layouts kept separate.

A justfile wraps the same commands (just dev, just test, just build) if you have just installed — it is optional.

ARCHITECTURE.md is the file map and how the pieces fit; CONTRIBUTING.md has the full command list, conventions, invariants and the release process.

License

MIT © Eugene Levenetc

About

UI component for rendering large tables

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages