One core. Three interfaces.
The Angular, React and Vue grids do not each re-implement filtering, sorting, dates, parsing and export. They share one framework-agnostic package, and only the UI layer is written per framework.
What lives where
| Layer | Holds | Does not hold |
|---|---|---|
UIgrid-angular grid-react grid-vue |
The component, the headless hook / signals / composables, rendering, focus and keyboard handling, virtual scroll, theming, the server data hook. | Any rule about what a value means: how it is compared, filtered, formatted, parsed or exported. |
Core@inandu-solutions/grid-core |
Column filters, sorting, date and number formatting, aggregates, tree flattening, paste and draft parsing, CSV / Excel markup / PDF helpers, translated messages in 5 languages. | Frameworks, components and the DOM (the single exception is downloadBlob). |
ServerInandu.Grid.Extensions (.NET) |
Turning the grid's query string into an IQueryable: filters, sorts, paging, keyset cursors, deny-by-default field allow-list. |
Any client code. It only agrees with the clients on the wire format. |
What this buys you
- A fix is made once. A date bug, a CSV injection or a filter edge case is fixed in the core and reaches the three grids in the same release. There are no copies to drift.
- Parity is a property, not a promise. The three grids give the same result for the same input because they run the same code, which is tested in several time zones.
- Behaviour is stated in tests. The core has its own suite, with the date rules run under
TZ=America/Bogotaas well as UTC. - Swap the UI, keep the rules. A new framework port is a UI layer on top of the same package, not a rewrite of the data logic.
The contract with the server
The query the grids send and what the .NET extensions accept are checked against one shared fixture, server-queries.json. The same cases run on the TypeScript side (the clients) and on the .NET side (the server), so a change to the wire format fails a test on whichever side did not follow.
Use the core on its own
npm install @inandu-solutions/grid-core
import { formatCellValue, matchesColumnFilter, escapeCsvValue } from '@inandu-solutions/grid-core';
formatCellValue('2024-01-05', 'date', 'YYYY-MM-DD', 'en-US'); // "2024-01-05", in every time zone
escapeCsvValue('=HYPERLINK("http://example.com","x")'); // opens as text, not as a formula
grid-core on GitHub · npm · grid-angular · grid-react · grid-vue · Inandu.Grid.Extensions