@graview/pages
The traditional face: a routed webapp derived from the same declaration that drives the scene.
pnpm add @graview/pagesWhat it is
The traditional face: a routed webapp derived from the same declaration that drives the spatial scene. From one defineApp — schema, mutations, invariants, permissions, op log — this package serves lists, records, forms, problems and history as ordinary linked pages: / the gallery, /:plural per kind, /:plural/:id per node, /places/:as per picture, /map the relations, /problems.
- One store, no second path. Pages read through the same
Storeand write through the same mutations with the same principal; withheld actions render disabled with their refusal.recordFactscomposes the derivations the scene already uses (labels, readable fields, violations touching, derived affordances) — the parity tests hold a record page and the spatial detail to identical facts. - The page registry mirrors the view registry.
(kind × page-type) → component, defaults overridable per cell; the shell, home and problems pages are themselves registrations (registry.surface(...)). - Forms are derived.
formFields(in@graview/core) walks a mutation's zod input into a control tree — scalars, dates, node pickers over real candidates, nested objects, discriminated unions as a type picker plus that arm's fields, arrays as repeatable rows — andDerivedFormrenders it. Nothing renderable is hand-written; anything unrenderable says so instead of hiding. - Two faces, one application. Record pages link to their spatial stop (
spatialHref(id)); the scene links to the pages; the ids are shared. Seeapps/todofor both faces mounted from one declaration (/scene,/pagesrouted). - Mobile is an acceptance criterion.
pnpm pagesruns the phone-width harness (390×844): no sideways scroll, named links, labelled controls, and a derived form that actually applies.
- It lands on a gallery. The home opens with the standing as its headline — "2 gardeners, 3 plots and 1 planting.", or "Nothing here yet." and which act begins it — then every picture the app has as a large live card, two across at a desk and one on a phone: the lens itself, drawn inert at a scale measured from the card, captioned with its name and how much it is over. Handed the scene's view registry (
viewsin the context), every titled lens is a page at/places/<as>and a card on the home; a kind with no titled lens is drawn anyway, as a contact sheet of its members, so a new app lands on a gallery on its first afternoon. The kinds follow as one row of counts, the relations as one line that opens/map, and Recently stays short at the foot. The shell is one row of navigation that scrolls sideways on a phone; a new address opens at its top. - It reads like the product's own site. A list opens with the plural and its description, a record with its title and its kind's
describe, controls receding below the content. Typography rides the brand's display and body faces at a real scale; the brand's mark, name and per-kind accents (hueFor, from@graview/core) carry through every page. Still derivation: nothing here is a per-app template, and an app overrides a cell the same way it overrides a view.
The host applies themeCss from @graview/primitives (or supplies its own --graview-* tokens); the default pages render entirely from those tokens.
What it exports (42)
Read off the package's own barrel, so this is what is there today.
beginningsForbeginningsFromcreatePageRegistryDefaultHomePageDefaultListPageDefaultMapPageDefaultPlacePageDefaultPlacesPageDefaultProblemsPageDefaultRecordPageDefaultSearchPageDefaultShellDerivedFormGalleryGalleryCardgalleryOfkindFactskindMapKindMapSectionkindOfSluglastChangeOfPageAskPageFindPageMainPagesAppPagesRoutespageStylesPageUndoPlaceCardplaceHrefplacePathPlacePicturepluralSlugrankedRepairsrecordFactsrecordPathRepairsSearchToCreatespatialHrefStartFreshLinkuseStoreTickWhyLine