Current state
Components 4 no longer exposes the TableRenderer, TableRendererProps, bindQuery, or bindObservableQuery experiment from closed PR #108. DataTableForQuery and DataTableForObservableQuery currently compose Arc React's paging hooks directly with the Cratis-owned semantic table and paginator.
That is the correct v4 foundation: Arc owns generated query/transport behavior; Components owns React visual policy. There is not yet enough evidence to add a renderer abstraction.
Consumer need to prove
A consumer that uses an application-owned advanced table still needs a renderer-neutral way to connect Arc query state to that table without depending on Components' table markup, filtering semantics, paginator, or visual contracts.
Before extracting anything, prove the contract in at least two real consumers or two materially different renderers. The proof must identify which state is genuinely transport/query behavior rather than table-library policy:
- current page, page size, total items, and total pages;
- loading, error, and refresh behavior;
- observable-query updates;
- query arguments for complete-result sorting and filtering;
- selection identity and retention across page changes;
- cancellation/race behavior when query state changes;
- ownership of URL or application state.
Direction
If the consumer proof establishes a stable seam, implement it in @cratis/arc.react, next to the existing query hooks. Prefer a headless hook or state contract over a renderer callback abstraction. It must not render a paginator, table, empty state, or container chrome and must not expose Components, PrimeReact, React Aria, TanStack, or another renderer's types.
@cratis/components may then compose that state with DataTableCore and TablePaginator while preserving the existing batteries-included APIs. A Vue or Svelte client should build framework-native state over the same generated transport contract rather than consume React state.
Acceptance criteria
- At least two materially different consumer/renderer implementations document the required state and callback contract.
- The extracted API lives in Arc React and contains no visual or renderer-specific policy.
- Complete-result sorting/filtering is expressed through explicit query arguments and applied server-side before paging; loaded-page filtering remains a Components concern.
- Existing
DataTableForQuery and DataTableForObservableQuery APIs remain source compatible unless a separately documented major change is approved.
- Specs cover snapshot and observable queries, paging races, loading/error state, and argument changes.
- Components documentation clearly separates server-result behavior from loaded-page table behavior.
Do not reintroduce the closed PR #108 abstraction merely to satisfy this issue. The proof is the work; extraction follows only if the proof supports it.
Current state
Components 4 no longer exposes the
TableRenderer,TableRendererProps,bindQuery, orbindObservableQueryexperiment from closed PR #108.DataTableForQueryandDataTableForObservableQuerycurrently compose Arc React's paging hooks directly with the Cratis-owned semantic table and paginator.That is the correct v4 foundation: Arc owns generated query/transport behavior; Components owns React visual policy. There is not yet enough evidence to add a renderer abstraction.
Consumer need to prove
A consumer that uses an application-owned advanced table still needs a renderer-neutral way to connect Arc query state to that table without depending on Components' table markup, filtering semantics, paginator, or visual contracts.
Before extracting anything, prove the contract in at least two real consumers or two materially different renderers. The proof must identify which state is genuinely transport/query behavior rather than table-library policy:
Direction
If the consumer proof establishes a stable seam, implement it in
@cratis/arc.react, next to the existing query hooks. Prefer a headless hook or state contract over a renderer callback abstraction. It must not render a paginator, table, empty state, or container chrome and must not expose Components, PrimeReact, React Aria, TanStack, or another renderer's types.@cratis/componentsmay then compose that state withDataTableCoreandTablePaginatorwhile preserving the existing batteries-included APIs. A Vue or Svelte client should build framework-native state over the same generated transport contract rather than consume React state.Acceptance criteria
DataTableForQueryandDataTableForObservableQueryAPIs remain source compatible unless a separately documented major change is approved.Do not reintroduce the closed PR #108 abstraction merely to satisfy this issue. The proof is the work; extraction follows only if the proof supports it.