Osy#betaRun it on Osyrin: osyrin.com

Reference / UI

Facts

Facts(label) { Fact(label, value: "…", hint: "…") { chips } }

Information about one thing as a key/value table: what each fact is on the left, its value on the right, one line per fact with a rule under it, and whatever belongs beside the value — a status chip, a mark, a small button — in the fact's block. On a phone the label sits over its value.

stable1 example compiled by CIuikitlayout

Summary#

Where a card would otherwise hold lines of "Label: value" prose, give each fact its own line. A state reads as a chip beside its value rather than as a word in a sentence:

enum ServerState { Running, Stopped }

class Server {
  public string Name;
  public string Engine;
  public int UsedGiB;
  public int SizeGiB;
  public ServerState State;
}

[Route("/server")] [AllowAnonymous]
component ServerPage() {
  Server server = new Server { Name = "db-1", Engine = "Postgres 16", UsedGiB = 63, SizeGiB = 200, State = ServerState.Running };
  render {
    Stack(gap: 3, p: 6) {
      Card(server.Name) {
        slot actions { Badge(server.State.Label, tone: server.State == ServerState.Running ? Tone.Success : Tone.Warning); }
        Facts(label: "About this server") {
          Fact("Engine", value: server.Engine);
          Fact("Storage", value: $"{server.UsedGiB} of {server.SizeGiB} GiB", hint: "As its provider stated it.");
          Fact("State") { Badge(server.State.Label, tone: Tone.Success); }
        }
      }
    }
  }
}

Signature#

Facts(string label) { Fact(…); … }
Fact(string label, string value = "", string hint = "") { /* beside the value: chips, a mark, a button */ }

Description#

How do the values line up?#

Every Fact is a grid of the same two tracks — the label's, about a third of the width, and the value's — so the values line up down the table as a header's columns line up over its rows. On a phone it is one column, the label over its value.

What goes in the block?#

What belongs beside the value: a Badge for its state, a provider's mark, a link, a small Button. The value and the block sit on one line and wrap together. Leave value empty when the block says it all (Fact("Enrollment") { Badge("Approved", tone: Tone.Success); }).

A figure the app does not have#

Say so in words — value: "not reported" — rather than leave the value empty: an empty value is a line that promises a figure and shows nothing.

How do I read it in a test?#

Each line is a named group, so a value is read through its label: Assert.Visible("Postgres 16", within: "Engine"). Facts(label) names the whole table the same way. It is required: it is the table's only accessible name.

See also#

Related

control — foreign UI controls (charts, grids, maps)

A `control` block declares the contract of a foreign UI widget — a chart, a data grid, a map — that a small JavaScript…

Osysharp.Ui (the UI kit)

The bundled UI kit — ready-made styled controls like `Button`, the shared design-system vocabularies (`Tone`, `Size`)…

SettingsArea — an app's settings: sections, explicit save and discard, undo, who changed what

The kit's settings vocabulary: `SettingsArea` lays out an app's settings — its sections in a grouped nav, the current…