Context
Screenplay's contribute to <Name> construct (see Screenplay issue
"contribution points and navigation") needs a runtime implementation:
collecting contributions from across the module/feature tree into the
widget that declared the contribution point, using nearest-enclosing
resolution.
Proposal
- Implement the aggregation as a computed view, analogous to how a
projection produces a read model — the NavBar (or any widget declaring
contributes X) doesn't get wired to a fixed source, it renders
whatever is currently contributed from the tree beneath it.
- Implement nearest-enclosing resolution: walk outward from a
contribution's declaration site to the first enclosing template that
declares a matching contribution point, same algorithm as existing
inside-out name resolution, just inverted (push vs. pull).
- NavBar widget specifically: consumes
Navigation contributions and
owns how a contribution's navigate to <Screen> by <param> becomes a
concrete route — URL path, query string, or native deep link — as a
rendering concern, not a modeling one. Should be configurable per
renderer (Scene.React vs. a future native renderer) without changing
the contribution's declared shape.
- Support ordering (
order property on a contribution) affecting render
order in the consuming widget.
Open questions
- Ambiguous contribution resolution (two equally-near matching points) —
confirm this surfaces the same warning UX as ambiguous query names, and
decide whether Studio needs a design-time-only strict mode that
upgrades these to errors.
Dependencies
Depends on
Blocks
Transferred from Cratis/Stage — the runtime and NavBar widget concerns here belong with Scene's engine, next to the other resolution engines. Cratis/Stage#37 remains the Screenplay → Scene seam.
Part of the screen work — build order and full dependency map: #7
Implementation notes
Lands in Scene.Engine (TypeScript) — the aggregation is computed over the object model at runtime in the browser. The NavBar widget's route rendering lands in Scene.React, per the per-renderer configurability the proposal calls for.
The contribution shape itself (what a contribution point declares it needs) is part of the C# Scene.Model and its TypeScript mirror — see the dual-stack decision in #1.
Context
Screenplay's
contribute to <Name>construct (see Screenplay issue"contribution points and navigation") needs a runtime implementation:
collecting contributions from across the module/feature tree into the
widget that declared the contribution point, using nearest-enclosing
resolution.
Proposal
projection produces a read model — the NavBar (or any widget declaring
contributes X) doesn't get wired to a fixed source, it renderswhatever is currently contributed from the tree beneath it.
contribution's declaration site to the first enclosing template that
declares a matching contribution point, same algorithm as existing
inside-out name resolution, just inverted (push vs. pull).
Navigationcontributions andowns how a contribution's
navigate to <Screen> by <param>becomes aconcrete route — URL path, query string, or native deep link — as a
rendering concern, not a modeling one. Should be configurable per
renderer (
Scene.Reactvs. a future native renderer) without changingthe contribution's declared shape.
orderproperty on a contribution) affecting renderorder in the consuming widget.
Open questions
confirm this surfaces the same warning UX as ambiguous query names, and
decide whether Studio needs a design-time-only strict mode that
upgrades these to errors.
Dependencies
Depends on
contribute to/contributesconstruct this implementsBlocks
Part of the screen work — build order and full dependency map: #7
Implementation notes
Lands in
Scene.Engine(TypeScript) — the aggregation is computed over the object model at runtime in the browser. The NavBar widget's route rendering lands inScene.React, per the per-renderer configurability the proposal calls for.The contribution shape itself (what a contribution point declares it needs) is part of the C#
Scene.Modeland its TypeScript mirror — see the dual-stack decision in #1.