Fruitful Docs
GuidesRender

Compact and reader surfaces

Author the A2UI surface templates that Fruitful renders from its trusted catalog.

A surface is a JSON template in A2UI v0.9.1. The package ships two: compact for the Activity row and expanded for the reader. Components come from a trusted catalog that Fruitful implements; the package never ships client code.

A surface file

plugin/presentation/compact.surface.json:

{
  "protocolVersion": "v0.9.1",
  "catalogId": "https://fruitful.app/a2ui/catalogs/basic/v1/catalog.json",
  "components": [
    { "id": "root", "component": "Column", "children": ["title", "metadata"] },
    { "id": "title", "component": "Text", "text": { "path": "/record/title" }, "variant": "h5" },
    { "id": "metadata", "component": "Row", "children": ["site", "points", "pointsLabel"] },
    { "id": "site", "component": "Text", "text": { "path": "/record/site" }, "variant": "caption" },
    { "id": "points", "component": "Text", "text": { "path": "/record/points" }, "variant": "caption" },
    { "id": "pointsLabel", "component": "Text", "text": "points", "variant": "caption" }
  ]
}
  • Components are flat: an id, a component name from the catalog, and its props. Containers list children by id. There is exactly one root.
  • A prop is either a literal or a { "path": "/…" } JSON Pointer into the View. /record/title reads the root record's title through the View.
  • Both surfaces carry catalogId, and they must agree.

The two surfaces

  • compact is the Activity row. Headline, one line of metadata, nothing that needs interaction.
  • expanded is the reader. The full record, related records from the View, and whatever gives the item its context on the original site.

The Activity shell adds the provenance affordance, actions, and selection chrome around them. Do not restate those inside the surface.

What Fruitful owns

Fruitful owns the catalog implementations: React components, styling, accessibility, responsive behavior, and interaction semantics. Packages choose from the catalog and bind data. A surface that names an unknown component, an unknown catalog, or a pointer that does not resolve fails validation, and in the product fails closed as Presentation unavailable.

Check it

yarn fruitful plugin validate feed-packages/<name> --json
yarn fruitful plugin preview feed-packages/<name> --json

Validation's presentation check compares each review case's rendered surfaces to the committed presentation examples under review/presentation/. The preview opens the exact surfaces in the Desktop app through the same Activity components the Inbox uses; see Preview in the product.

Reference: surfaces.

On this page