Skip to content

Contributes and contribute to #92

Description

@einari

Context

Studio's app template can hold a NavBar (or similar widget) whose content
is assembled from navigation entries declared deep inside modules and
features — a many-contributors-to-one-consumer shape the language doesn't
have a construct for yet. layout slots are the wrong tool: they express
one parent placing one block of content into one region, not many children
contributing into a collection.

Proposal

Generic mechanism: contribute to <Name>

A widget declares it accepts contributions under a name (no generic
"channel" noun needed — the contribution point is just named like any
other construct, e.g. Navigation):

layout AppShell
  template
    navbar contributes Navigation
    main

Anything anywhere in the module/feature tree can contribute to it, without
knowing or caring who's listening:

navigation-item
  contribute to Navigation
    navigate to InvoiceDetails by invoiceId   // implicit default property
    label NavLabel
    order 10

contribute to X opens a property bag shaped by whatever X declares it
needs. For Navigation, navigate to <Screen> [by <param>] is the
implicit default property (reusing the exact syntax on row-click already
uses) — a bare navigate to X with no block still works and targets the
nearest-enclosing contribution point. Other contribution points (e.g. a
future Notifications point) would declare a different required shape
entirely — the mechanism is generic, Navigation is just its first user.

Resolution rule

A contribution attaches to the nearest enclosing template that declares
a matching contribution point
, walking outward the same way bare name
references already resolve inside-out. A module with its own
contributes Navigation subnav stops features inside it from bubbling to
the app shell; without one, contributions keep walking out. This gives
unlimited nesting (app nav, module subnav, feature sub-subnav) for free,
with no new resolution algorithm.

An optional explicit override (navigation-item ... in <ContributionPoint>)
should exist for the rare case where nearest-enclosing isn't wanted —
mirrors explicit query qualification (Queue.All) being the override to
the bare-name default.

Route arguments

Arguments (e.g. an id flowing into a URL) are not string
interpolation. They reuse the existing typed navigate ... by <param>
binding, checked by the compiler the same way any other bare-name
reference is. How that becomes a URL/query-string/native deep link is a
rendering concern owned by the NavBar widget implementation, not the
model.

Open questions

  • Ambiguity handling when a bare contribution matches two equally-near
    contribution points — should mirror the existing "ambiguous query"
    warning (named candidates, not a silent pick).
  • Ordering/grouping properties (order, group) needed for anything
    beyond a flat nav list — worth scoping now vs. later.

Dependencies

Blocks

Part of the screen work — build order and full dependency map: Cratis/Scene#7

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    screenScreen/UI work: Screenplay UI constructs, Scene runtime, Stage rendering, Studio designers

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions