Skip to content

Dynamic renderer

@samabaasi/renderer turns a validated app.json into live UIKit screens — the runtime interpreter. A page is data; the renderer instantiates the matching components by component type and binds them to OData.

Render a page

tsx
import { parseAppDefinition } from '@samabaasi/core';
import { DynamicRenderer } from '@samabaasi/renderer';

const app = parseAppDefinition(json);

<DynamicRenderer app={app} path={location.pathname} />;

DynamicRenderer is self‑contained: it wires the app's OData connection (ODataProvider) and theme, then renders the page whose path matches (or the first page). Data‑bound sections call OData hooks, so the provider is required — it's set up for you.

How sections resolve

DynamicRenderer → DynamicPage → DynamicSection(section)

            ┌──────────────────────┼─────────────────────────┐
            ▼                      ▼                          ▼
   built-in adapter        registered Custom          unknown → visible
   (DataTable, CrudPage,   component (props spread)    fallback (never executes)
    Chart, Stat, layout…)
  • Built‑in adapters map each schema section to a real UIKit component, resolving its data source from the section's entitySet + query (via useODataDataSource), and translating declarative format columns into renderers.
  • Layout sections (Stack/Grid/Card/Panel) recurse into children.
  • Custom sections render a component you registered by name.

Registering your own components

ts
import { registerComponent } from '@samabaasi/renderer';

registerComponent('PriceTicker', PriceTicker);   // now usable from a Custom section
jsonc
{ "id": "ticker", "component": "PriceTicker", "props": { "symbol": "ACME" } }

Only registered components ever render; a Custom section naming an unknown component shows a visible fallback — it never executes arbitrary code.

Why this is fast for AI (and to read)

  • Parsing + validating app.json is O(n) — already optimal; reads aren't the bottleneck.
  • Every section/page has an id, so edits can be JSON Patches (O(changes) tokens), not full regeneration — see the AI page.
  • Discriminated unions on component/type make both the model's generation and the renderer's dispatch predictable.

The companion static mode (the library's uikit build) emits a fully static app from the same app.json for CDN/air‑gapped hosting — the dynamic renderer here is the runtime counterpart.

Released under the MIT License.