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, acomponentname from the catalog, and its props. Containers listchildrenby id. There is exactly oneroot. - A prop is either a literal or a
{ "path": "/…" }JSON Pointer into the View./record/titlereads 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> --jsonValidation'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.