{"id":49470792,"url":"https://github.com/orneryd/uigrid","last_synced_at":"2026-05-06T06:04:05.541Z","repository":{"id":354258040,"uuid":"1222822756","full_name":"orneryd/uiGrid","owner":"orneryd","description":"Modernization of the original ui-grid for rust eGui, angular 21+, react 18+, and web components","archived":false,"fork":false,"pushed_at":"2026-05-02T18:30:17.000Z","size":2863,"stargazers_count":61,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-05-02T18:32:45.596Z","etag":null,"topics":["angular","custom-elements","data-grid","grid","rust","typescript","ui-grid","wasm","wasm-pack","webcomponents"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/orneryd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-27T18:37:23.000Z","updated_at":"2026-05-02T18:30:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"5d34494f-1298-41c5-8801-ec1a39430407","html_url":"https://github.com/orneryd/uiGrid","commit_stats":null,"previous_names":["orneryd/uigrid"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/orneryd/uiGrid","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orneryd%2FuiGrid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orneryd%2FuiGrid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orneryd%2FuiGrid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orneryd%2FuiGrid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/orneryd","download_url":"https://codeload.github.com/orneryd/uiGrid/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orneryd%2FuiGrid/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32581021,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","custom-elements","data-grid","grid","rust","typescript","ui-grid","wasm","wasm-pack","webcomponents"],"created_at":"2026-04-30T16:01:43.627Z","updated_at":"2026-05-06T06:04:05.521Z","avatar_url":"https://github.com/orneryd.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CI](https://github.com/orneryd/uiGrid/actions/workflows/ci.yml/badge.svg)](https://github.com/orneryd/uiGrid/actions/workflows/ci.yml)\n[![Coverage Status](https://coveralls.io/repos/github/orneryd/uiGrid/badge.svg?branch=main)](https://coveralls.io/github/orneryd/uiGrid?branch=main)\n[![npm](https://img.shields.io/npm/v/@ornery/ui-grid)](https://www.npmjs.com/package/@ornery/ui-grid)\n[![crates.io](https://img.shields.io/crates/v/ui-grid-egui)](https://crates.io/crates/ui-grid-egui)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE.md)\n\n#### [Discord Community](https://discord.gg/Baz4w8ZWN)\n\n# UI Grid — Remastered\n\n**The modern multi-platform data grid. Every feature free and open source. Built for Angular, Web-Components, React, native Rust/egui, and native C/LVGL.**\n\nA from-scratch rewrite of the original [AngularJS ui-grid](https://github.com/angular-ui/ui-grid) — by the original author. Same `gridOptions` / `columnDefs` / `onRegisterApi` api surface, modern Angular signals internals, and zero legacy baggage. \n\nJust like the original grid, it will **NEVER** be monetized. This is purely my contribution to the greater community. \n\nIt proves that the datagrid cabal wants you to think it's hard to write a data grid. Well, it's not, and nobody should be paying to group data.\n\n**[Live Demo \u0026 Docs](https://orneryd.github.io/uiGrid/)** | **[npm](https://www.npmjs.com/package/@ornery/ui-grid)** | **[crates.io](https://crates.io/crates/ui-grid-egui)**\n\n---\n\n## Why Remastered?\n\n- **Original authorship** — built by the same engineer who created AngularJS ui-grid, with a decade of hindsight on what worked and what didn't\n- **Familiar API** — if you used the original ui-grid, you already know this one: `gridOptions`, `columnDefs`, `onRegisterApi`, `gridApi.core.*`\n- **Modern internals** — pure Angular signals architecture, `ChangeDetectionStrategy.OnPush`, Shadow DOM encapsulation, CDK virtual scrolling, standalone components\n- **No legacy** — no `$scope`, no Bower, no Grunt, no jQuery, no module system from 2013\n\n---\n\n## Feature Comparison\n\nEverything below ships free and MIT-licensed. No enterprise tier, no license keys, no per-developer fees.\n\n| Feature                  | UI Grid  | ag-Grid Community | ag-Grid Enterprise |   Vaadin Grid   |  Kendo UI  |   Syncfusion    |\n| ------------------------ | :------: | :---------------: | :----------------: | :-------------: | :--------: | :-------------: |\n| Sorting                  | **Free** |       Free        |         —          |      Free       |    Paid    |   Community\\*   |\n| Filtering                | **Free** |       Free        |         —          |      Free       |    Paid    |   Community\\*   |\n| **Row Grouping**         | **Free** |         —         |    ~$999/dev/yr    |        —        |    Paid    |   Community\\*   |\n| **Tree Data**            | **Free** |         —         |    ~$999/dev/yr    |        —        |    Paid    |   Community\\*   |\n| **Master/Detail Rows**   | **Free** |         —         |    ~$999/dev/yr    |        —        |    Paid    |   Community\\*   |\n| **Inline Cell Editing**  | **Free** |       Free        |         —          | Pro ~$99/dev/mo |    Paid    |   Community\\*   |\n| CSV Export               | **Free** |       Free        |         —          |        —        |    Paid    |   Community\\*   |\n| Virtual Scrolling        | **Free** |       Free        |         —          |      Free       |    Paid    |   Community\\*   |\n| Pagination               | **Free** |       Free        |         —          |      Free       |    Paid    |   Community\\*   |\n| **Column Pinning**       | **Free** |         —         |    ~$999/dev/yr    |        —        |    Paid    |   Community\\*   |\n| Column Reordering        | **Free** |       Free        |         —          |      Free       |    Paid    |   Community\\*   |\n| **Save/Restore State**   | **Free** |         —         |    ~$999/dev/yr    |        —        |    Paid    |        —        |\n| **Infinite Scroll**      | **Free** |       Free        |         —          |        —        |    Paid    |   Community\\*   |\n| **Shadow DOM**           | **Free** |         —         |         —          |        —        |     —      |        —        |\n| **Web Component Build**  | **Free** |         —         |         —          |     Native      |     —      |        —        |\n| **Feature Tree-Shaking** | **Free** |         —         |         —          |        —        |     —      |        —        |\n| **SSR Support**          | **Free** |         —         |    ~$999/dev/yr    |        —        |     —      |        —        |\n| i18n                     | **Free** |         —         |    ~$999/dev/yr    |      Free       |    Paid    |   Community\\*   |\n| React Native             | **Yes**  |      Wrapper      |      Wrapper       |       No        |  Wrapper   |     Wrapper     |\n| Rust/egui Native         | **Yes**  |      No      |      No       |       No        |  No   |     No     |\n| C/LVGL Native            | **Yes**  |      No      |      No       |       No        |  No   |     No     |\n| Angular Native           | **Yes**  |      Wrapper      |      Wrapper       |       No        |  Wrapper   |     Wrapper     |\n| **License**              | **MIT**  |        MIT        |     Commercial     |  Apache/Comm.   | Commercial | Comm./Community |\n\n\u003e **Bold** = features where UI Grid gives you for free what competitors charge for.\n\u003e\n\u003e _Syncfusion Community license is free for companies with \u003c$1M annual revenue. Prices are approximate and subject to change._\n\n---\n\n## Quick Start\n\n```bash\nnpm install @ornery/ui-grid\n```\n\n### Angular Component\n\n```typescript\nimport { Component } from '@angular/core';\nimport { GridOptions, UiGridComponent } from '@ornery/ui-grid';\n\n@Component({\n  selector: 'app-my-grid',\n  imports: [UiGridComponent],\n  template: `\u003capp-ui-grid [options]=\"gridOptions\" /\u003e`,\n})\nexport class MyGridComponent {\n  gridOptions: GridOptions = {\n    id: 'my-grid',\n    data: [\n      { name: 'Alice', role: 'Engineer', salary: 120000 },\n      { name: 'Bob', role: 'Designer', salary: 95000 },\n    ],\n    columnDefs: [\n      { name: 'name' },\n      { name: 'role' },\n      { name: 'salary', type: 'number', align: 'end' },\n    ],\n    onRegisterApi: (api) =\u003e {\n      this.gridApi = api;\n    },\n  };\n}\n```\n\n### React\n\n```bash\nnpm install @ornery/ui-grid-react @ornery/ui-grid-core\n```\n\n```tsx\nimport { UiGrid } from '@ornery/ui-grid-react';\nimport type { GridOptions } from '@ornery/ui-grid-core';\n\nfunction MyGrid() {\n  const options: GridOptions = {\n    id: 'my-grid',\n    data: [\n      { name: 'Alice', role: 'Engineer', salary: 120000 },\n      { name: 'Bob', role: 'Designer', salary: 95000 },\n    ],\n    columnDefs: [\n      { name: 'name' },\n      { name: 'role' },\n      { name: 'salary', type: 'number', align: 'end' },\n    ],\n  };\n\n  return \u003cUiGrid options={options} /\u003e;\n}\n```\n\n### Web Components\n\nThe grid ships **two separate web component outputs** that share the same default tag name, `\u003cui-grid-element\u003e`.\n\n- **Angular Elements output**: `@ornery/ui-grid`, rendered through Angular via `@angular/elements`\n- **Vanilla output**: `@ornery/ui-grid-vanilla`, rendered by the framework-free DOM implementation\n\nPick one output per page. They expose the same common declarative surface, but they are different packages with different runtime requirements.\n\n#### Angular Elements Output (`@ornery/ui-grid`)\n\nBuilt with `@angular/elements`, this wraps the full Angular component as a custom element. It requires the Angular runtime and is produced by the `build:element` script. Use this when you already have Angular in your stack or want the full Angular rendering pipeline.\n\n```bash\nnpm run build:element\n```\n\nDeclarative HTML usage is available for the same common setup surface as the vanilla build:\n\n```html\n\u003cscript type=\"module\" src=\"ui-grid-element/main.js\"\u003e\u003c/script\u003e\n\n\u003cui-grid-element\n  grid-id=\"element-demo\"\n  title=\"Team Roster\"\n  enable-sorting\n  enable-filtering\n  viewport-height=\"420\"\n  column-defs='[\n    { \"name\": \"name\" },\n    { \"name\": \"role\" },\n    { \"name\": \"salary\", \"type\": \"number\", \"align\": \"end\" }\n  ]'\n  data='[\n    { \"name\": \"Alice\", \"role\": \"Engineer\", \"salary\": 120000 },\n    { \"name\": \"Bob\", \"role\": \"Designer\", \"salary\": 95000 }\n  ]'\u003e\n\u003c/ui-grid-element\u003e\n```\n\nSupported declarative inputs include boolean flags such as `enable-sorting` and `enable-filtering`, scalar attributes such as `grid-id`, `title`, and `viewport-height`, plus JSON attributes such as `column-defs` and `data`.\n\nDeclarative attributes are the lowest-friction setup path, but they are not the cheapest update path. Changing JSON attributes such as `data` or `column-defs` means reparsing the payload and re-running the custom element's configuration flow. That is fine for initial render, docs examples, SSR/CMS content, and occasional state changes, but it is not ideal for high-frequency feeds.\n\nFor callbacks, function-valued column definitions, or one-shot bulk assignment, use the `options` property:\n\n```html\n\u003cscript type=\"module\" src=\"ui-grid-element/main.js\"\u003e\u003c/script\u003e\n\n\u003cui-grid-element id=\"my-grid\"\u003e\u003c/ui-grid-element\u003e\n\n\u003cscript type=\"module\"\u003e\n  document.querySelector('#my-grid').options = {\n    id: 'element-demo',\n    data: [{ name: 'Alice', role: 'Engineer' }],\n    columnDefs: [{ name: 'name' }, { name: 'role' }],\n  };\n\u003c/script\u003e\n```\n\nYou can also register the element programmatically:\n\n```typescript\nimport { defineUiGridElement } from '@ornery/ui-grid';\n\nawait defineUiGridElement(); // registers \u003cui-grid-element\u003e\n```\n\nFor performance-sensitive updates on the Angular-backed custom element, prefer declarative attributes for first render and infrequent changes, then batch any imperative `options` updates so you do not replace large `data` payloads every frame. If you need very high-frequency streaming behavior, use the Angular component directly instead of the custom-element wrapper.\n\n#### Vanilla Output (`@ornery/ui-grid-vanilla`)\n\nA framework-free custom element built on `@ornery/ui-grid-core` with pure DOM rendering and Shadow DOM encapsulation. No Angular dependency. Use this in non-Angular apps, static sites, or anywhere you want a zero-framework grid.\n\n```bash\nnpm install @ornery/ui-grid-vanilla @ornery/ui-grid-core\n```\n\nDeclarative HTML usage is available out of the box for the same common setup surface:\n\n```html\n\u003cui-grid-element\n  grid-id=\"vanilla-demo\"\n  title=\"Team Roster\"\n  enable-sorting\n  enable-filtering\n  viewport-height=\"420\"\n  column-defs='[\n    { \"name\": \"name\" },\n    { \"name\": \"role\" },\n    { \"name\": \"salary\", \"type\": \"number\", \"align\": \"end\" }\n  ]'\n  data='[\n    { \"name\": \"Alice\", \"role\": \"Engineer\", \"salary\": 120000 },\n    { \"name\": \"Bob\", \"role\": \"Designer\", \"salary\": 95000 }\n  ]'\u003e\n\u003c/ui-grid-element\u003e\n\n\u003cscript type=\"module\"\u003e\n  import { defineStandaloneUiGridElement } from '@ornery/ui-grid-vanilla';\n\n  await defineStandaloneUiGridElement(); // registers \u003cui-grid-element\u003e\n\u003c/script\u003e\n```\n\nSupported declarative inputs include boolean flags such as `enable-sorting` and `enable-filtering`, scalar attributes such as `grid-id`, `title`, and `viewport-height`, plus JSON attributes such as `column-defs` and `data`.\n\nDeclarative attributes are best for initial mount and occasional reconfiguration. Updating a large `data` JSON attribute repeatedly is more expensive than imperative row updates because the element must parse the new attribute value, merge options again, and potentially rebuild more of the grid state.\n\nWhen you need callbacks, function-valued column definitions, or one-shot bulk assignment, use the `options` property or the `mountVanillaUiGrid` helper instead:\n\n```typescript\nimport { mountVanillaUiGrid } from '@ornery/ui-grid-vanilla';\n\nawait mountVanillaUiGrid(document.getElementById('app'), {\n  id: 'mounted-grid',\n  data: [{ name: 'Alice', role: 'Engineer' }],\n  columnDefs: [{ name: 'name' }, { name: 'role' }],\n});\n```\n\nFor live or high-frequency data, use the declarative surface only for the initial mount and then switch to imperative updates. In the vanilla element, `grid.setData(rows)` is the most efficient path for streaming row changes because it updates the pipeline and patches rendered cells in place instead of re-running the full declarative attribute sync path.\n\n### Native Rust / egui\n\n```toml\n[dependencies]\nui-grid-egui = \"0.1\"\nui-grid-core = \"0.1\"\n```\n\n```rust\nuse ui_grid_egui::{EguiColumnExt, EguiGrid, GridThemePreset};\nuse ui_grid_core::models::{GridColumnDef, GridOptions};\n\nlet mut grid = EguiGrid::new();\nlet theme = GridThemePreset::DefaultDark.build();\nlet mut column_ext: Vec\u003cEguiColumnExt\u003e = vec![];\n\n// Each frame, inside your egui UI:\ngrid.show(ui, \u0026mut options, \u0026columns, \u0026mut column_ext, \u0026theme);\n```\n\nTo run the interactive demo app locally:\n\n```bash\ngit clone https://github.com/orneryd/uiGrid.git\ncd uiGrid\ncargo run -p ui-grid-egui --example demo --release\n```\n\nSee [docs/rust-egui.md](./docs/rust-egui.md) for pinning, CSV export, save/restore state, and custom column extensions.\n\n### Native C / LVGL\n\nThe C adapter sits on top of the same Rust core and C ABI contract used by the other foreign bindings. The current demo uses LVGL with the SDL desktop backend.\n\nPrerequisites:\n\n- Rust 1.95+\n- CMake 3.20+\n- SDL2\n\n```bash\nbrew install sdl2\ncargo build -p ui-grid-c-abi\ncmake -S crates/ui-grid-lvgl -B target/ui-grid-lvgl\ncmake --build target/ui-grid-lvgl -j4\n./target/ui-grid-lvgl/ui-grid-lvgl-demo\n```\n\nThe LVGL demo currently exercises the native C grid shell with sorting, grouping, pinning, state save/restore, theme presets, live trading-row updates, and the shared projection/command contract.\n\n---\n\n## Features\n\n- **Sorting** — click column headers to cycle asc/desc/none, custom comparators, programmatic API\n- **Filtering** — per-column inputs with conditions: contains, exact, startsWith, endsWith, greaterThan, regex, custom predicates\n- **Row Grouping** — nested multi-column grouping with collapsible group headers\n- **Tree View** — hierarchical data with expand/collapse per node, arbitrary nesting depth\n- **Expandable Rows** — master/detail pattern with custom templates (Angular `ng-template`, React render prop, or vanilla `\u003ctemplate\u003e` slot)\n- **Cell Editing** — inline spreadsheet-style editing with full keyboard navigation (Tab, Enter, Escape)\n- **Pagination** — client-side or external pagination with configurable page sizes\n- **Infinite Scroll** — bi-directional infinite scrolling with loading state management\n- **Column Pinning** — freeze columns left or right with CSS `position: sticky`, programmatic API, save/restore state\n- **Column Moving** — drag-and-drop column reordering (Angular CDK, native HTML drag in React and vanilla)\n- **CSV Export** — download visible rows with formula-injection protection\n- **Virtual Scrolling** — CDK virtual scroll viewport, auto-enabled at 40+ rows\n- **Save/Restore State** — serialize and restore sort, filter, grouping, pagination, and expansion state\n- **Native Rust and C Grids** — shared Rust core with native Rust/egui and native C/LVGL adapters driven by the same projection and command contract\n- **Auto Resize** — ResizeObserver-driven viewport height recalculation\n- **Custom Cell Templates** — Angular `ng-template`, React `cellRenderer` render prop, vanilla `\u003ctemplate\u003e` slots, or `cellRenderer` function for fully custom cells\n- **Shadow DOM** — encapsulated styles with CSS custom property and `::part()` hooks\n- **Web Component** — ship as `\u003cui-grid-element\u003e` in two flavors: Angular-backed (`@ornery/ui-grid`) or framework-free vanilla (`@ornery/ui-grid-vanilla`)\n- **Feature-Flag Builds** — compile-time tree-shaking of unused features\n- **i18n** — override any UI string at runtime or bake in a locale at build time\n- **SSR Support** — server-side rendering with platform-safe guards\n\n---\n\n## Theming\n\nThe grid renders inside Shadow DOM. Customize it via the public `--ui-grid-*` CSS custom properties:\n\n```css\n.my-app {\n  --ui-grid-surface: #1e1b2e;\n  --ui-grid-accent: #8b5cf6;\n  --ui-grid-header-background: #2d2640;\n  --ui-grid-cell-color: #e2e0f0;\n  --ui-grid-border-color: rgba(139, 92, 246, 0.2);\n  --ui-grid-row-hover: #322e4a;\n}\n```\n\nLegacy `--app-ui-grid-*` aliases remain supported as a fallback for older app themes, but new consumer theming should target only `--ui-grid-*`.\n\nTarget structural elements with `::part()`:\n\n```css\napp-ui-grid::part(header) {\n  text-transform: uppercase;\n  letter-spacing: 0.05em;\n}\n```\n\nSee [docs/theming.md](./docs/theming.md) for the full CSS variable reference grouped by grid section, `::part()` hooks, and the demo app's 4-mode theme system.\n\n---\n\n## Custom Builds\n\nShip only the features you use:\n\n```bash\n# Only sorting and filtering — everything else is tree-shaken\nnode scripts/build-grid.mjs --features sorting,filtering\n\n# Bake in a locale at build time\nnode scripts/build-grid.mjs --features sorting,filtering,pagination --locale i18n/fr-FR.json\n\n# See all available flags\nnode scripts/build-grid.mjs --list\n```\n\nSee [docs/custom-builds.md](./docs/custom-builds.md) for the full feature flag table and build presets.\n\n---\n\n## Documentation\n\n| Guide                                        | Description                                            |\n| -------------------------------------------- | ------------------------------------------------------ |\n| [Getting Started](./docs/getting-started.md) | Install, minimal setup, run the demo                   |\n| [Features](./docs/features.md)               | Overview of all features with code examples            |\n| [Theming](./docs/theming.md)                 | CSS custom properties, `::part()` hooks, sample themes |\n| [API Reference](./docs/api-reference.md)     | GridOptions, GridColumnDef, UiGridApi                  |\n| [Cell Editing](./docs/cell-editing.md)       | Keyboard navigation, conditional editing, API          |\n| [Tree View](./docs/tree-view.md)             | Hierarchical data, options, API                        |\n| [Expandable Rows](./docs/expandable-rows.md) | Master/detail, template context, API                   |\n| [Custom Builds](./docs/custom-builds.md)     | Feature flags, build presets, locale baking            |\n| [Web Component](./docs/web-component.md)     | Angular-backed and vanilla web component outputs       |\n| [Internationalization](./docs/i18n.md)       | Runtime overrides, build-time locales                  |\n| [Accessibility](./docs/accessibility.md)     | ARIA roles, keyboard navigation, screen reader support |\n| [Rust / WASM](./docs/rust.md)                | Rust pipeline in Angular, React, and vanilla hosts     |\n| [Rust / egui](./docs/rust-egui.md)           | Native egui adapter with pinning, export, save/restore |\n| `README native C / LVGL section`             | Native C/LVGL build and demo run instructions          |\n\nInteractive versions of all documentation are also available in the [live demo](https://orneryd.github.io/uiGrid/).\n\n---\n\n## Development\n\n```bash\nnpm start          # Dev server at localhost:4200\nnpm test           # Run tests (Vitest)\nnpm run build      # Production build\nnpm run build:library   # Build the library (ng-packagr)\nnpm run build:element   # Build the web component\nnpm run build:rust:web  # Build the browser-native Rust/WASM artifact\nnpm run start:vanilla   # Run the Rust-backed browser demo at 127.0.0.1:4174\n```\n\n### Rust / egui\n\nRequires [Rust 1.95+](https://rustup.rs/).\n\n```bash\ncargo test --workspace                                    # Run all Rust tests\ncargo clippy --workspace --all-targets -- -D warnings     # Lint\ncargo run -p ui-grid-egui --example demo --release        # Run the native egui demo app\n```\n\n### C / LVGL\n\nRequires SDL2 plus the Rust/C ABI build.\n\n```bash\nbrew install sdl2\ncargo build -p ui-grid-c-abi\ncmake -S crates/ui-grid-lvgl -B target/ui-grid-lvgl\ncmake --build target/ui-grid-lvgl -j4\n./target/ui-grid-lvgl/ui-grid-lvgl-demo                  # Run the native C/LVGL demo app\n```\n\n---\n\n## Compatibility\n\n| Dependency  | Version |\n| ----------- | ------- |\n| Angular     | 21.2    |\n| Angular CDK | 21.2    |\n| TypeScript  | 5.9     |\n| RxJS        | 7.8     |\n| Node        | 22.20   |\n| npm         | 11.11   |\n| Rust        | 1.95+   |\n| egui        | 0.34    |\n\n---\n\n## Contributing\n\nContributions are welcome. Please open an issue first to discuss what you'd like to change.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/my-feature`)\n3. Run `npm test` to ensure all tests pass\n4. Submit a pull request\n\n---\n\n## License\n\n[MIT](./LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forneryd%2Fuigrid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Forneryd%2Fuigrid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forneryd%2Fuigrid/lists"}