# Getting Started

> Install @toolbox-web/grid and render your first grid in under a minute. Covers npm, CDN, ES modules, declarative HTML, and full framework integration for Vanilla JS, React, Vue, and Angular.

**Using a framework?** Jump directly to [Angular](/grid/angular/getting-started.md), [React](/grid/react/getting-started.md), or [Vue](/grid/vue/getting-started.md).

## Quick Start

1. **Install the package**

#### npm

     ```bash
     npm install @toolbox-web/grid
     ```

#### yarn

     ```bash
     yarn add @toolbox-web/grid
     ```

#### pnpm

     ```bash
     pnpm add @toolbox-web/grid
     ```

#### bun

     ```bash
     bun add @toolbox-web/grid
     ```

#### CDN

     For quick prototyping, use the UMD bundle directly:
     ```html
     <script src="https://unpkg.com/@toolbox-web/grid/umd/grid.umd.js"></script>
     ```

2. **Import and use**

   ```typescript
   import '@toolbox-web/grid';                       // registers <tbw-grid>
   import { queryGrid } from '@toolbox-web/grid';     // typed DOM helper
   ```

3. **Add the grid to your HTML**

   ```html
   <tbw-grid id="my-grid" style="height: 400px;"></tbw-grid>
   ```

:::caution[The grid needs a height]
Set a height via CSS or inline style (e.g., `height: 400px`). Without it, the grid collapses to zero height and nothing will render. Use `height: auto` if you don't want virtual scrolling.

**Tip:** A parent CSS Grid or Flexbox layout that stretches the grid (e.g., a flex child with `flex: 1` or a grid row sized with `1fr`) also counts as a height — you don't need to set one explicitly on `<tbw-grid>` itself.
:::

### Declarative Columns (No JavaScript)

Define columns directly in HTML — great for static layouts and quick prototyping:

```html
<tbw-grid style="height: 400px;">
  <tbw-grid-column field="id" header="ID" type="number" sortable></tbw-grid-column>
  <tbw-grid-column field="name" header="Name"></tbw-grid-column>
  <tbw-grid-column field="email" header="Email"></tbw-grid-column>
</tbw-grid>
```

Set `rows` from JavaScript or via the `rows` HTML attribute (JSON). See [Light DOM Columns](/grid/core.md#light-dom-columns) for the full attribute reference.

### Auto-Inferred Columns

Skip column configuration entirely — the grid creates columns from your data:

```typescript
import '@toolbox-web/grid';
import { queryGrid } from '@toolbox-web/grid';

const grid = queryGrid('#my-grid');
grid.rows = [
  { id: 1, name: 'Alice Johnson', email: 'alice@example.com', active: true },
  { id: 2, name: 'Bob Smith', email: 'bob@example.com', active: false },
];
// → Creates ID, Name, Email, and Active columns automatically
```

The grid detects types (`number`, `boolean`, `date`, `string`) from values and formats headers from field names (`firstName` → `First Name`). See [Column Inference](/grid/core.md#column-inference) for details.

## Framework Integration

The grid is a standard web component that works in any JavaScript environment — you can always use the Vanilla JS approach in any framework. For React, Vue, and Angular, we also provide dedicated adapter packages that enable custom component renderers and editors.

:::tip[Prefer a single `gridConfig` object]
Across every framework, the recommended pattern is to describe the grid with one `gridConfig` object — columns, `features`, and `plugins` together — and pass it as a single prop/input/attribute. Keep reactive data (`rows`) separate, since it changes independently of configuration.

A single config object is portable (the same `GridConfig` works in vanilla, React, Angular, and Vue), easy to share or snapshot in tests, and keeps multi-line feature config readable. Individual feature props (e.g. `selection="row"`) remain fully supported and are a fine shorthand for very small grids — but default to `gridConfig` for everything else, including any column that uses a custom renderer or editor.

For framework adapters (React/Vue/Angular), the default should be `gridConfig.features` rather than wiring many feature props/inputs/directives in templates. Keep those template-level bindings as shorthand for tiny examples.
:::

#### TypeScript

Add a grid element to your HTML, then configure it from JavaScript:

```html title="index.html"
<tbw-grid style="height: 400px;"></tbw-grid>
```

```typescript title="main.ts"
import '@toolbox-web/grid';
import { queryGrid } from '@toolbox-web/grid';

const grid = queryGrid('tbw-grid');

grid.columns = [
  { field: 'id', header: 'ID', type: 'number' },
  { field: 'name', header: 'Name' },
  { field: 'email', header: 'Email' },
];

grid.rows = [
  { id: 1, name: 'Alice Johnson', email: 'alice@example.com' },
  { id: 2, name: 'Bob Smith', email: 'bob@example.com' },
  { id: 3, name: 'Carol White', email: 'carol@example.com' },
];
```

That's a working grid. From here, add features as you need them — sorting, editing, selection, and more are each a one-line import:

```typescript title="main.ts (with features)"
import '@toolbox-web/grid';
import { queryGrid } from '@toolbox-web/grid';
import '@toolbox-web/grid/features/editing';
import '@toolbox-web/grid/features/selection';
import '@toolbox-web/grid/features/filtering';

const grid = queryGrid('tbw-grid');

grid.gridConfig = {
  columns: [
    { field: 'id', header: 'ID', type: 'number' },
    { field: 'name', header: 'Name', editable: true },
    { field: 'email', header: 'Email', editable: true },
  ],
  features: {
    editing: 'dblclick',
    selection: 'row',
    filtering: true,
  },
};

grid.rows = [
  { id: 1, name: 'Alice Johnson', email: 'alice@example.com' },
  { id: 2, name: 'Bob Smith', email: 'bob@example.com' },
  { id: 3, name: 'Carol White', email: 'carol@example.com' },
];

grid.on('cell-commit', (detail) => console.log('Edited:', detail));
```

See [Core Features](/grid/core.md) for renderers, formatters, and custom editors.

:::note[Prefer creating grids programmatically?]
Use `createGrid()` to create a `<tbw-grid>` element without writing HTML:
```typescript
import { createGrid } from '@toolbox-web/grid';
const grid = createGrid({ columns: [...], features: { ... } });
document.body.appendChild(grid);
```
:::

#### React

For React projects, use the `@toolbox-web/grid-react` adapter package for enhanced integration:

```bash
# Install both packages
npm install @toolbox-web/grid @toolbox-web/grid-react
```

```tsx title="EmployeeGrid.tsx"
import { DataGrid } from '@toolbox-web/grid-react';

const employees = [
  { id: 1, name: 'Alice Johnson', email: 'alice@example.com' },
  { id: 2, name: 'Bob Smith', email: 'bob@example.com' },
  { id: 3, name: 'Carol White', email: 'carol@example.com' },
];

function EmployeeGrid() {
  return (
    <DataGrid
      rows={employees}
      columns={[
        { field: 'id', header: 'ID', type: 'number' },
        { field: 'name', header: 'Name' },
        { field: 'email', header: 'Email' },
      ]}
      style={{ height: 400, display: 'block' }}
    />
  );
}
```

That's a working grid. From here, add features as you need them — each is a one-line import plus a prop:

```tsx title="EmployeeGrid.tsx (with features)"
import '@toolbox-web/grid-react/features/editing';
import '@toolbox-web/grid-react/features/selection';
import '@toolbox-web/grid-react/features/filtering';

import { DataGrid } from '@toolbox-web/grid-react';

const employees = [
  { id: 1, name: 'Alice Johnson', email: 'alice@example.com' },
  { id: 2, name: 'Bob Smith', email: 'bob@example.com' },
  { id: 3, name: 'Carol White', email: 'carol@example.com' },
];

function EmployeeGrid() {
  return (
    <DataGrid
      rows={employees}
      columns={[
        { field: 'id', header: 'ID', type: 'number' },
        { field: 'name', header: 'Name', editable: true },
        { field: 'email', header: 'Email', editable: true },
      ]}
      editing="dblclick"
      selection="row"
      filtering
      onCellCommit={(e) => console.log('Edited:', e.detail)}
      style={{ height: 400, display: 'block' }}
    />
  );
}
```

The adapter adds JSX renderers/editors, the `useGrid` hook, and declarative `GridColumn` components.

See the [React adapter docs](/grid/react/getting-started.md) for custom renderers, editors, and the complete API reference.

#### Vue

For Vue projects, use the `@toolbox-web/grid-vue` adapter package for enhanced integration:

```bash
# Install both packages
npm install @toolbox-web/grid @toolbox-web/grid-vue
```

```html title="EmployeeGrid.vue"
<script setup>
import { TbwGrid } from '@toolbox-web/grid-vue';

const employees = [
  { id: 1, name: 'Alice Johnson', email: 'alice@example.com' },
  { id: 2, name: 'Bob Smith', email: 'bob@example.com' },
  { id: 3, name: 'Carol White', email: 'carol@example.com' },
];
</script>

<template>
  <TbwGrid
    :rows="employees"
    :columns="[
      { field: 'id', header: 'ID', type: 'number' },
      { field: 'name', header: 'Name' },
      { field: 'email', header: 'Email' },
    ]"
    style="height: 400px; display: block;"
  />
</template>
```

That's a working grid. From here, add features as you need them — each is a one-line import plus a prop:

```html title="EmployeeGrid.vue (with features)"
<script setup>
import '@toolbox-web/grid-vue/features/editing';
import '@toolbox-web/grid-vue/features/selection';
import '@toolbox-web/grid-vue/features/filtering';

import { TbwGrid } from '@toolbox-web/grid-vue';

const employees = [
  { id: 1, name: 'Alice Johnson', email: 'alice@example.com' },
  { id: 2, name: 'Bob Smith', email: 'bob@example.com' },
  { id: 3, name: 'Carol White', email: 'carol@example.com' },
];
</script>

<template>
  <TbwGrid
    :rows="employees"
    :columns="[
      { field: 'id', header: 'ID', type: 'number' },
      { field: 'name', header: 'Name', editable: true },
      { field: 'email', header: 'Email', editable: true },
    ]"
    editing="dblclick"
    selection="row"
    filtering
    @cell-commit="(e) => console.log('Edited:', e.detail)"
    style="height: 400px; display: block;"
  />
</template>
```

The adapter adds slot-based renderers/editors (`#cell`, `#editor`), the `useGrid` composable, and declarative `TbwGridColumn` components.

See the [Vue adapter docs](/grid/vue/getting-started.md) for custom renderers, editors, and the complete API reference.

#### Angular

For Angular projects, use the `@toolbox-web/grid-angular` adapter package for enhanced integration:

```bash
# Install both packages
npm install @toolbox-web/grid @toolbox-web/grid-angular
```

```typescript title="grid.component.ts"
import '@toolbox-web/grid';
import { Component } from '@angular/core';
import { Grid } from '@toolbox-web/grid-angular';
import type { ColumnConfig } from '@toolbox-web/grid';

@Component({
  selector: 'app-employee-grid',
  imports: [Grid],
  template: `
    <tbw-grid
      [rows]="employees"
      [columns]="columns"
      style="height: 400px; display: block;">
    </tbw-grid>
  `,
})
export class EmployeeGridComponent {
  employees = [
    { id: 1, name: 'Alice Johnson', email: 'alice@example.com' },
    { id: 2, name: 'Bob Smith', email: 'bob@example.com' },
    { id: 3, name: 'Carol White', email: 'carol@example.com' },
  ];

  columns: ColumnConfig[] = [
    { field: 'id', header: 'ID', type: 'number' },
    { field: 'name', header: 'Name' },
    { field: 'email', header: 'Email' },
  ];
}
```

That's a working grid. From here, add features as you need them — each is a one-line import plus an input binding:

```typescript title="grid.component.ts (with features)"
import { GridEditingDirective } from '@toolbox-web/grid-angular/features/editing';
import { GridSelectionDirective } from '@toolbox-web/grid-angular/features/selection';
import { GridFilteringDirective } from '@toolbox-web/grid-angular/features/filtering';
import '@toolbox-web/grid';
import { Component } from '@angular/core';
import { Grid } from '@toolbox-web/grid-angular';
import type { ColumnConfig, CellCommitDetail } from '@toolbox-web/grid';

@Component({
  selector: 'app-employee-grid',
  imports: [Grid, GridEditingDirective, GridSelectionDirective, GridFilteringDirective],
  template: `
    <tbw-grid
      [rows]="employees"
      [columns]="columns"
      [editing]="'dblclick'"
      [selection]="'row'"
      [filtering]="true"
      (cellCommit)="onCellCommit($event)"
      style="height: 400px; display: block;">
    </tbw-grid>
  `,
})
export class EmployeeGridComponent {
  employees = [
    { id: 1, name: 'Alice Johnson', email: 'alice@example.com' },
    { id: 2, name: 'Bob Smith', email: 'bob@example.com' },
    { id: 3, name: 'Carol White', email: 'carol@example.com' },
  ];

  columns: ColumnConfig[] = [
    { field: 'id', header: 'ID', type: 'number' },
    { field: 'name', header: 'Name', editable: true },
    { field: 'email', header: 'Email', editable: true },
  ];

  // camelCase outputs deliver the unwrapped detail directly ($event is the
  // detail, not the native CustomEvent). Bind kebab-case (cell-commit) instead
  // if you need the CustomEvent for event.preventDefault().
  onCellCommit(detail: CellCommitDetail) {
    console.log('Edited:', detail);
  }
}
```

The adapter adds structural directives (`*tbwRenderer`, `*tbwEditor`), template-driven renderers/editors, and grid-level event outputs.

See the [Angular adapter docs](/grid/angular/getting-started.md) for custom renderers, editors, and the complete API reference.

## Plain JavaScript (No Build Step)

Don't use TypeScript or a bundler? The grid works with a single `<script>` tag using the UMD bundle.
Everything is available on the global `TbwGrid` object:

```html title="index.html"
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/@toolbox-web/grid/umd/grid.umd.js"></script>
</head>
<body>
  <tbw-grid id="my-grid" style="height: 400px;"></tbw-grid>
  <script>
    var grid = TbwGrid.queryGrid('#my-grid');

    grid.columns = [
      { field: 'id', header: 'ID', type: 'number' },
      { field: 'name', header: 'Name' },
      { field: 'email', header: 'Email' },
    ];

    grid.rows = [
      { id: 1, name: 'Alice Johnson', email: 'alice@example.com' },
      { id: 2, name: 'Bob Smith', email: 'bob@example.com' },
      { id: 3, name: 'Carol White', email: 'carol@example.com' },
    ];
  </script>
</body>
</html>
```

To add plugins, use the all-in-one bundle and configure via `gridConfig`:

```html title="index.html (with plugins)"
<script src="https://unpkg.com/@toolbox-web/grid/umd/grid.all.umd.js"></script>
<script>
  var grid = TbwGrid.queryGrid('#my-grid');

  grid.gridConfig = {
    columns: [
      { field: 'id', header: 'ID', type: 'number' },
      { field: 'name', header: 'Name', editable: true },
      { field: 'email', header: 'Email', editable: true },
    ],
    plugins: [
      new TbwGrid.EditingPlugin({ trigger: 'dblclick' }),
      new TbwGrid.SelectionPlugin({ mode: 'row' }),
      new TbwGrid.FilteringPlugin(),
    ],
  };

  grid.rows = [
    { id: 1, name: 'Alice Johnson', email: 'alice@example.com' },
    { id: 2, name: 'Bob Smith', email: 'bob@example.com' },
    { id: 3, name: 'Carol White', email: 'carol@example.com' },
  ];
</script>
```

:::tip
`grid.umd.js` includes core only (~168 kB raw, ~48 kB gzipped). `grid.all.umd.js` bundles core + all plugins (~514 kB raw, ~136 kB gzipped).
You can also load individual plugin UMD files (e.g. `selection.umd.js`) for finer control over bundle size.
:::

## TypeScript Support

The package ships with full type definitions. Use generics on `queryGrid` to get typed row data throughout your code:

```typescript
import '@toolbox-web/grid';
import { queryGrid } from '@toolbox-web/grid';
import type { ColumnConfig } from '@toolbox-web/grid';

interface Employee {
  id: number;
  name: string;
  email: string;
}

const grid = queryGrid<Employee>('tbw-grid');

// Column config is type-checked against Employee
const columns: ColumnConfig<Employee>[] = [
  { field: 'id', header: 'ID', type: 'number' },
  { field: 'name', header: 'Name' },
  // { field: 'typo' } ← TypeScript error!
];

// Event payloads are typed too
grid.on('cell-commit', ({ row, field, value }) => {
  console.log(row.name, field, value); // row is Employee
});
```

## Next Steps

Now that you have the grid set up, explore:

  - [Core Features](/grid/core.md): Sorting, editing, keyboard navigation, and interactive playground
  - [Selection Plugin](/grid/plugins/selection.md): Add row, cell, or range selection
  - [Theming](/grid/guides/theming.md): Customize colors, spacing, and typography
  - [API Reference](/grid/api-reference.md): Complete property, method, and event reference
