You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -58,15 +59,16 @@ Cell legend: **✅** = documented out-of-the-box · **❌** = not supported / no
58
59
-**A declarative `<Column>` API** (the PrimeVue-shaped surface) *and* a `:columns` config-array escape hatch, resolved by an id-keyed last-write-wins union — plus custom cell/header rendering via a single parent `#cell` / `#colHeader` scoped slot dispatched by `columnId` (a render-prop on React/Solid and a property on Lit, the one documented divergence).
59
60
-**Zero-config styling that re-skins to any design system.** Every rendered value is a `--rozie-data-table-*` CSS custom property with a built-in fallback, plus ready-made token bridges for shadcn/ui, Material 3, and Bootstrap 5 — no required CSS import.
60
61
-**Opt-in WAI-ARIA grid mode, identical on all six targets.** Set `interactionMode="grid"` for the full [APG grid pattern](https://www.w3.org/WAI/ARIA/apg/patterns/grid/) — `role="grid"`, a roving single tab-stop, and 2-D arrow-key cell navigation that survives a re-sort / filter / page change / column hide-reorder-pin (the active cell is tracked as a `{ rowIndex, colIndex }` pair over the visible model, never a stored DOM node). It is drivable and observable via the `focusCell` / `getActiveCell` / `clearActiveCell` handle verbs and the `activecell-change` event, and the behavioral contract is locked by a cross-framework VR matrix. The default `interactionMode="table"` stays a plain accessible table, byte-for-byte unchanged.
62
+
-**Opt-in vertical row windowing, on all six targets.** Set `virtual` (with an optional `maxHeight` / `--rozie-data-table-max-height` and `estimateRowHeight`) to render only the visible slice of a large dataset inside a bounded scroll container — windowing the full filtered + sorted (pre-pagination) model, with `aria-rowcount` / `aria-rowindex` mapping the full model, variable-height rows measured (no cumulative drift), and sticky-header + pinned-column geometry preserved. Built on the framework-agnostic `@tanstack/virtual-core` wired by hand — **no per-framework virtual adapter** — and **tested to 100,000 rows** on all six targets by a DOM/behavioral VR matrix (`tests/visual-regression/specs/data-table-virtual.spec.ts`). The default `virtual="false"` is byte-identical to a non-virtual table.
61
63
62
64
## What Rozie defers {#what-rozie-defers}
63
65
64
66
This page concedes where the incumbents are genuinely ahead — that's what keeps the comparison credible, and it doubles as Rozie's own roadmap.
65
67
66
68
-**AG Grid's enterprise depth.**[AG Grid](https://www.ag-grid.com/) ships row grouping, tree data, pivoting, range selection, master/detail, integrated charting, and a deep server-side row model. `@rozie-ui/data-table` covers the common surface (sort / filter / paginate / select / column management) and a `manual` server-side hook, not the enterprise feature set.
67
-
-**Row/cell virtualization.**Large datasets render every row today — there is no built-in windowing. Virtualization is a planned phase (the published support boundary is a row-count ceiling until it lands); for now, paginate or pre-window large data yourself.
69
+
-**Horizontal (column) virtualization + dynamic auto-measure.**Vertical **row** windowing ships and is GA on all six targets — set `virtual` and large datasets render only the visible slice (**tested to 100,000 rows**). What remains deferred is the orthogonal pieces: **horizontal/column virtualization** (a very wide column set still renders every column), and **dynamic auto-measurement beyond `measureElement`** — variable row heights are measured via `measureElement`, but there is no content-driven auto-sizing pass past it. Use `estimateRowHeight` to seed the row estimate for now.
68
70
-**TanStack's expansion / grouping / faceting helpers.** The shared `table-core` exposes more row-model features (expanding, grouping, faceted filters) than `@rozie-ui/data-table` surfaces in its current prop set. They are reachable via the imperative handle / future additive props.
69
-
-**`@rozie-ui/data-table` is `0.1.0`.** The surface (15 props / 9 two-way slices / 9 events / 15-verb handle / declarative `<Column>` + `columnId`-dispatched cell/header slots / 2 selection slots) is stable and gate-verified across all six targets, but it is younger and less battle-tested than the established libraries.
71
+
-**`@rozie-ui/data-table` is `0.1.0`.** The surface (18 props / 9 two-way slices / 9 events / 15-verb handle / declarative `<Column>` + `columnId`-dispatched cell/header slots / 2 selection slots) is stable and gate-verified across all six targets, but it is younger and less battle-tested than the established libraries.
@@ -73,6 +82,24 @@ This is the **real `@rozie-ui/data-table-vue` package** running on this page (Vi
73
82
74
83
Each `v-model:<slice>` is a two-way bind — the readout updates the instant you change the state, and a consumer write flows back in. The four slices bound here (`sorting`, `globalFilter`, `rowSelection`, `pagination`) are four of the [nine independent state slices](/components/data-table#models-the-nine-two-way-slices); bind a slice only when you want to own it. The header buttons drive the imperative handle (`toggleAllRows`, `clearSelection`, `clearSorting`) grabbed through Vue's `ref`. A single `#cell` slot on `<DataTable>`, dispatched by `columnId`, renders the **Status** badge; every other column falls through to the plain accessor value (the fast path). See the [full API](/components/data-table) for every prop, slice, event, slot, and handle verb, plus the `<Column>` API, theming, and accessibility reference.
75
84
85
+
## Row windowing (virtualization)
86
+
87
+
The same real `@rozie-ui/data-table-vue` package, now over **50,000 rows** with `virtual` + `maxHeight="400px"`. Only the visible slice renders inside the bounded scroll container — scroll the table below and watch the row count stay tiny while the scrollbar spans the full 50,000-row height. Row windowing is GA on all six targets and [**tested to 100,000 rows**](/components/data-table-comparison#feature-matrix) by a DOM/behavioral VR matrix; the default `virtual="false"` is byte-identical to a non-virtual table.
Set `virtual` to opt in; bound `maxHeight` (or the `--rozie-data-table-max-height` CSS custom property — the prop wins, the token is the fallback) sizes the scroll container, and `estimateRowHeight` seeds the row estimate before `measureElement` refines actual heights. Windowing runs over the full filtered + sorted (pre-pagination) model and suppresses the client pagination chrome. See the [comparison page](/components/data-table-comparison#what-rozie-defers) for the published support boundary (and the orthogonal pieces — column virtualization + dynamic auto-measure — that remain deferred).
102
+
76
103
## One source, six outputs
77
104
78
105
You author the component **once** as a `.rozie` file (the parent `DataTable.rozie` plus the declarative `Column.rozie` child):
Beyond props and events, `DataTable` exposes imperative methods (declared once in the `.rozie` source via `$expose`). Grab a handle through your framework's native ref mechanism and call them directly:
0 commit comments