> ## Documentation Index
> Fetch the complete documentation index at: https://tally.outhebox.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Solid

> Solid primitives that bind a Tally grid to a reactive scope and expose its state as signals.

`tally-solid` binds a `Grid` from `tally-core` to the owning reactive scope and exposes its stores as signals. It renders nothing. You write the markup, and the engine does the querying, view state, mutations and undo. The full rendered component exists only in [React](https://tally.outhebox.dev/docs/frameworks/react.md).

```sh theme={null}
npm install tally-solid tally-core solid-js
```

Solid 1.9 or newer.

## Usage

```tsx accounts.tsx theme={null}
import type { JSX } from 'solid-js'
import { createArraySource, createSchema, type RowData } from 'tally-core'
import { createGridState, createView, useGrid } from 'tally-solid'

const schema = createSchema({
  key: 'id',
  columns: [
    { id: 'account', label: 'Account' },
    { id: 'mrr', label: 'MRR', type: 'currency', aggregate: 'sum' },
  ],
})

export function Accounts(props: { rows: readonly RowData[] }): JSX.Element {
  const source = createArraySource(props.rows, schema)
  const grid = useGrid({ schema, source })
  const state = createGridState(grid)
  const view = createView(grid)
  return (
    <>
      <p>
        {state().status}, sorted by {view().sort[0]?.column ?? 'nothing'}
      </p>
      <button type="button" onClick={() => grid().view.toggleSort('mrr')}>
        Sort by MRR
      </button>
    </>
  )
}
```

`useGrid` accepts options or an accessor. It creates a `Grid`, loads it in an effect and disposes it when the owner is cleaned up. It recreates the grid when `schema` or `source` change identity, and when the format context changes. The current view carries over.

Subscriptions start in effects, so server rendering produces the initial state without touching the data source.

## API

| Primitive | Returns |
| - | - |
| `useGrid(options)` | An `Accessor<Grid>` bound to the owner. |
| `createGridState(grid)` | An accessor of status, totals, aggregates and page. |
| `createView(grid)` | An accessor of the current `View`. |
| `createRows(grid)` | An accessor of loaded rows and changed cells. |
| `createSelection(grid)` | An accessor of the active cell, ranges and selected rows. |
| `GridContext` | Context for `<GridContext.Provider value={grid}>`. |
| `useGridContext()` | The provided `Accessor<Grid>`. Throws without a provider. |

Every primitive that takes `grid` accepts a `Grid` or an accessor, and follows the grid when it is recreated. Derive narrower values with `createMemo`.

## Context

```tsx accounts.tsx theme={null}
import type { JSX } from 'solid-js'
import type { GridOptions } from 'tally-core'
import { GridContext, createGridState, useGrid, useGridContext } from 'tally-solid'

function Total(): JSX.Element {
  const state = createGridState(useGridContext())
  return <span>{state().total ?? 0}</span>
}

export function Accounts(props: { options: GridOptions }): JSX.Element {
  const grid = useGrid(() => props.options)
  return (
    <GridContext.Provider value={grid}>
      <Total />
    </GridContext.Provider>
  )
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.