Something went wrong

Thank you for being patient! We're working hard on resolving the issue

Variants & Facades - Lona Docs Log in

Variants & Facades

SheetRow is the base class. Each row also has:

  • A rolesource, renderer, layout, or alias
  • A variant — concrete subclass under variants/ carrying per-type state and capabilities
  • Zero or more facades — typed accessors over the row's attributes / cells, obtained via row.as(FACADE_KEY)

Roles

type Role = "source" | "renderer" | "layout" | "alias";
  • source — owns cell data (e.g. ColumnText, ColumnNumber, Weather, Calendar). The renderer reads cell content from these.
  • renderer — projects a source row onto a particular surface (e.g. column.text, timeline[row].event, grid.task). One source row may have multiple renderer rows in the tree.
  • layout — structural (block, group, header, column, timeline[row], timeline[column], grid, canvas, sheet-footer, timeline-legend). Has children, no cell data.
  • alias — declarative template that hydrates into a tree of layout + renderer descendants (e.g. a weather alias expands into a column + logs subtree).

Variant subclasses

import {
  SourceRow, LayoutRow, RendererRow, AliasRow,
  // sources
  ColumnText, ColumnNumber, ColumnCheckmark, Weather, Calendar,
  Tasks, FormulaDataSource,
  // layouts
  BlockRow, GroupRow, HeaderRow, ColumnRow, GridRow,
  TimelineRowRow, TimelineColumnRow, CanvasRow,
  // renderers
  ColumnTextRenderer, ColumnCheckmarkRenderer, GridEventRenderer,
  TimelineColumnTaskRenderer, /* ... */
  // aliases
  WeatherAlias, CalendarAlias, TaskListAlias, /* ... */
} from "@tento-lona/sheets";

SheetRow.variant is a typed accessor that returns the concrete subclass:

const v = row.variant;
if (v instanceof Weather) {
  v.location;
  v.units;
} else if (v instanceof FormulaDataSource) {
  v.expression;
}

The variant pattern means UI code can pattern-match on row type without touching row.type strings.

Facades

A facade is a typed accessor for repeating attribute/cell shapes. Facades are registered via FacadeRegistry; access them via row.as(KEY):

import { EVENT_FACADE } from "@tento-lona/sheets";

const events = row.as(EVENT_FACADE);   // Optional<EventFacade>
events?.upsertEvent({ ... });
events?.removeEvent(eventId);

Built-in facades cover events, tasks, weather entries, slots, etc. Custom facades plug into the registry at app startup.

Capabilities

row.capabilities() returns a RowCapabilities bag the UI uses to gate operations:

const caps = row.capabilities();
if (caps.canReparent) { showDragHandle(); }
if (caps.canDuplicate) { showCloneButton(); }

Variants own their capabilities — e.g. parent-stored rows return canReparent: false because they're structurally pinned.

See also

  • Sheet & SheetRow — the base class
  • Per-Type Plugins — how renderers map variants to a render surface
  • __design_docs/lona-rows/rowkey/per-type-plugin-plan.md — design history