# Feature: Data Table Runtime

## Intent

Problem: Data Table behavior is too complex to implement safely as ad hoc helpers, and the CSS package intentionally owns only visual styling.
Users or stakeholders: application teams, QA, keyboard users, screen reader users, and future framework package maintainers.
Desired outcome: adopt TanStack Table Core as the standard headless data grid engine for `@seventh-ui/vanillajs`, while rendering Seventh UI markup and classes owned by `@seventh-ui/css`.
Non-goals: build a proprietary data grid engine, copy CSS package files, use a visual grid library as the public component, implement spreadsheet/pivot features, or define server API contracts.

## Decision

`@seventh-ui/vanillajs` must use `@tanstack/table-core` as the default Data Table engine.

TanStack Table Core is selected because it is headless: it owns row models, column models, sorting, filtering, pagination, selection, expansion, and controlled state, but does not own DOM markup or CSS. This preserves the Seventh UI boundary where `@seventh-ui/css` owns `.sui-*` styles and this package owns behavior.

The Vanilla runtime must not expose Tabulator, AG Grid, Grid.js, DataTables.net, or another visual data grid as the default Data Table implementation. Those libraries may be evaluated later for optional adapters, but they must not replace the default TanStack-backed renderer without a new spec decision.

## Scope

In scope: TanStack Table Core dependency, Data Table initialization, semantic table rendering, column definitions, sorting, filtering/search, pagination, row selection, row expansion hooks, controlled state, lifecycle cleanup, runtime events, and playground/docs examples.
Out of scope: server transport, persistence, saved views, column drag-and-drop, column resizing, virtualization, editable cells, tree grids, pivoting, Excel import/export, and enterprise-only behavior.

Virtualization may be added later with `@tanstack/virtual-core` when large row/column support is specified. It must stay optional and must not be required for the first Data Table runtime.

## Responsibilities

CSS package responsibilities:

- Own Data Table classes, tokens, sizes, dark theme variables, responsive styling, and visual states.
- Provide visual classes such as `.sui-data-table-shell`, `.sui-data-table-wrapper`, `.sui-data-table`, `.sui-data-table__header-cell`, `.sui-data-table__row`, `.sui-data-table__cell`, `.sui-data-table__toolbar`, and `.sui-data-table__footer`.
- Remain behavior-agnostic and framework-agnostic.

Vanilla runtime responsibilities:

- Own the Data Table public JavaScript API and browser behavior.
- Use TanStack Table Core for table state and row model computation.
- Render semantic table markup using CSS-owned `.sui-*` classes.
- Synchronize `aria-sort`, `aria-selected`, `hidden`, disabled state, and `data-sui-state` where applicable.
- Dispatch cancellable and non-cancellable `sui:data-table:*` events.
- Clean up listeners, generated DOM, timers, and references on destroy.

TanStack Table Core responsibilities:

- Provide the internal table model.
- Compute row models for core rows, sorting, filtering, pagination, selection, and expansion.
- Remain an implementation detail unless an advanced API explicitly exposes the table instance.

## Public API

The runtime must support programmatic initialization:

```js
import { createDataTableController } from "@seventh-ui/vanillajs";

const table = createDataTableController(element, {
  columns,
  data,
  getRowId
});
```

The runtime must also support automatic initialization through `init(root)` for documented markup hooks.

The browser bundle must expose the component through the existing `SeventhUI` namespace without creating additional globals.

## Markup Hooks

- Root: `[data-sui-data-table]` or `[data-sui-component="data-table"]`.
- Table: `.sui-data-table` or `[data-sui-data-table-table]`.
- Column key: `[data-sui-column-key]`.
- Sortable column: `[data-sui-sortable]`.
- Search input: `[data-sui-data-table-search]`.
- Page size control: `[data-sui-data-table-page-size]`.
- Previous page trigger: `[data-sui-data-table-prev]`.
- Next page trigger: `[data-sui-data-table-next]`.
- Page status: `[data-sui-data-table-page-status]`.
- Row selection control: `[data-sui-data-table-row-select]`.
- Bulk selection control: `[data-sui-data-table-select-all]`.
- Row expansion trigger: `[data-sui-data-table-row-toggle]`.

The implementation may generate these hooks when rendering from JavaScript options. When enhancing existing semantic markup, it must only bind to documented hooks and must preserve consumer content.

## Behavior

1. Initialization creates a TanStack table instance using the provided data, columns, and enabled row models.
2. When only static semantic table markup is provided, the runtime may infer simple columns and rows from the DOM, but complex Data Tables should use explicit JavaScript options.
3. Sorting toggles between ascending, descending, and unsorted states unless disabled by configuration.
4. Sorting state updates `aria-sort`, header button state, `data-sui-state`, and rendered row order.
5. Search/filter input updates the controlled filter state and re-renders visible rows.
6. Pagination updates the visible row model, page status, page size control, and previous/next disabled state.
7. Row selection updates TanStack selection state, row `aria-selected`, row visual state, and bulk selection state.
8. Row expansion toggles detail row visibility when expansion content is provided.
9. Refreshing data preserves controlled state when row IDs remain stable.
10. Destroying the controller removes runtime listeners and generated nodes without removing consumer-owned markup.

## Events

Events use the `sui:data-table:*` namespace.

- `sui:data-table:before-sort`: cancellable before sorting changes.
- `sui:data-table:sort`: after sorting changes.
- `sui:data-table:before-filter`: cancellable before filtering/search changes.
- `sui:data-table:filter`: after filtering/search changes.
- `sui:data-table:before-page`: cancellable before pagination changes.
- `sui:data-table:page`: after pagination changes.
- `sui:data-table:before-select`: cancellable before row selection changes.
- `sui:data-table:select`: after row selection changes.
- `sui:data-table:before-expand`: cancellable before row expansion changes.
- `sui:data-table:expand`: after row expansion changes.
- `sui:data-table:render`: after the runtime updates rendered table content.

Event detail must include the Data Table controller, relevant state slice, and user/action source when available.

## Accessibility

Use native `<table>`, `<thead>`, `<tbody>`, `<tr>`, `<th>`, and `<td>` markup by default.

Interactive header controls must be real buttons or equivalent native controls. Sorting must expose `aria-sort` on the sorted column header. Row selection must expose native checkbox state when checkboxes are used and `aria-selected` on selected rows when row selection is enabled.

Keyboard support must include:

- Tab order through toolbar controls, sortable headers, selection controls, row actions, and pagination controls.
- Enter/Space activation for sort, selection, expansion, and pagination controls.
- Escape must not clear table state unless a future spec defines an active overlay/filter panel.

The runtime must not replace semantic table markup with ARIA grid roles unless a future interaction mode requires grid-style cell navigation.

## Data and Contracts

Inputs: `@seventh-ui/css` Data Table classes, documented `data-sui-*` hooks, TanStack-compatible column definitions, row data, and runtime options.
Outputs: Data Table controller, rendered table DOM, synchronized ARIA/native state, and `sui:data-table:*` events.
Dependencies: `@seventh-ui/css` for styling and `@tanstack/table-core` for the headless table engine.
Persistence changes: none.

## Quality Attributes

Encapsulation: TanStack must be used behind the Seventh UI runtime API and must not create globals.
Compatibility: the browser bundle must continue to protect legacy consumers from global namespace conflicts by using only `SeventhUI`.
Maintainability: Data Table behavior should be implemented as a controller with small rendering/state helpers.
Performance: the first implementation should handle common table sizes without virtualization and leave large-data virtualization for a separate spec.
Accessibility: native table semantics must be preserved by default.

## Acceptance Examples

Scenario: TanStack-backed rendering
Given a Data Table root is initialized with data and columns
When the runtime renders the table
Then the DOM uses Seventh UI Data Table classes and TanStack provides the internal row model.

Scenario: sorting
Given a sortable column header
When the user activates the sort control
Then the rows reorder, `aria-sort` updates, and `sui:data-table:sort` is dispatched.

Scenario: pagination
Given pagination is enabled
When the user activates next page
Then the visible rows update, page controls synchronize disabled state, and `sui:data-table:page` is dispatched.

Scenario: CSS-only fallback
Given a semantic table uses `.sui-data-table` without runtime hooks
When the runtime initializes
Then the table remains visually styled and is not modified.
