Context
Existing layout templates declare named slots but say nothing about how
content arranges within them, and nothing about responsiveness or
per-size/orientation variation. Need to support both CSS-flex/grid-style
responsive layout and pixel-precise freeform placement (dashboards,
canvases), plus express size/orientation variants (e.g. phone portrait vs.
landscape) without inventing a separate orientation primitive.
Proposal
Size classes: width × height, not "orientation"
Reuse the size-class vocabulary from ui profile but split it two ways
(UIKit-style): width compact|regular × height compact|regular. Phone
portrait/landscape, tablet, and desktop narrow/wide all fall out of this
matrix for free — no orientation keyword needed.
flow — one definition, reflow via overrides
layout MasterDetail
arrangement flow
template
row
column sidebar width 280
column main grow
when width compact
column
main
sidebar
Primitives (row, column, grid, grow, gap, span) are deliberately
neutral, not CSS-flavored — they map to CSS flex/grid on web and to
native stack/grid equivalents elsewhere, keeping this platform-agnostic
the same way Level 1/2 already is.
freeform — one variant per size-class combination
layout DashboardCanvas
arrangement freeform
variant width regular, height regular
place header at 0,0 size fill,64
place sidebar at 0,64 size 240,fill
place main at 240,64 size fill,fill
variant width compact, height regular // phone portrait
place header at 0,0 size fill,48
place main at 0,48 size fill,fill
sidebar hidden
variant width compact, height compact // phone landscape
place header hidden
place main at 0,0 size fill,fill
Critically: one screen, one data/action/form contract, N variants
purely for placement. Freeform needing "a screen per size" only applies
to layout, not to the binding contract — duplicating that would repeat the
exact mistake form was designed to avoid for command properties. A
ui profile targeting a size class with no matching variant should be a
compiler warning, not a silent fallback — consistent with existing
unresolved-name diagnostics.
Open questions
- Mixed arrangement per slot: can a single
layout use flow for
most slots and freeform for one that needs pixel control (e.g. a
chart region inside an otherwise-responsive dashboard)? Leaning toward
allowing arrangement mode at the slot level rather than forcing one
choice for the whole layout, since real dashboards usually need exactly
this mix.
Dependencies
Depends on
Blocks
Gates other work: the open question on mixed arrangement per slot must be settled before Cratis/Scene#4 fixes its engine API and before Cratis/StudioIssues#161 builds slot-level mode switching.
Part of the screen work — build order and full dependency map: Cratis/Scene#7
Implementation notes — verified current state
layout exists today but carries no arrangement information at all. The whole declaration is one line in Source/DotNET/Screenplay/Syntax/ModuleSyntax.cs:
public record LayoutSyntax(string Name, IEnumerable<string> Slots, SourceLocation Location) : SyntaxNode(Location);
Slots are bare strings — no nesting, no primitives, no variants. It is declared at module scope (ModuleSyntax.Layouts) and referenced from a screen through ScreenLayoutSyntax(string Name, IEnumerable<ScreenSlotSyntax> Slots, …) in ScreenSyntax.cs.
So this issue replaces IEnumerable<string> Slots with a real template tree (row/column/grid + grow/gap/span, or variant + place for freeform). Every existing consumer of LayoutSyntax.Slots — parser, walker, printer, and the ScreenLayoutSyntax slot-filling check — has to move with it. Keep a bare layout X with plain slot names parsing exactly as it does now; this must be a purely additive language change.
New diagnostics (missing variant for a targeted size class) start at SP0035 — the highest code allocated today is SP0034.
Context
Existing
layouttemplates declare named slots but say nothing about howcontent arranges within them, and nothing about responsiveness or
per-size/orientation variation. Need to support both CSS-flex/grid-style
responsive layout and pixel-precise freeform placement (dashboards,
canvases), plus express size/orientation variants (e.g. phone portrait vs.
landscape) without inventing a separate orientation primitive.
Proposal
Size classes: width × height, not "orientation"
Reuse the size-class vocabulary from
ui profilebut split it two ways(UIKit-style):
width compact|regular×height compact|regular. Phoneportrait/landscape, tablet, and desktop narrow/wide all fall out of this
matrix for free — no
orientationkeyword needed.flow— one definition, reflow via overridesPrimitives (
row,column,grid,grow,gap,span) are deliberatelyneutral, not CSS-flavored — they map to CSS flex/grid on web and to
native stack/grid equivalents elsewhere, keeping this platform-agnostic
the same way Level 1/2 already is.
freeform— one variant per size-class combinationCritically: one
screen, one data/action/form contract, Nvariantspurely for placement. Freeform needing "a screen per size" only applies
to layout, not to the binding contract — duplicating that would repeat the
exact mistake
formwas designed to avoid for command properties. Aui profiletargeting a size class with no matchingvariantshould be acompiler warning, not a silent fallback — consistent with existing
unresolved-name diagnostics.
Open questions
layoutuseflowformost slots and
freeformfor one that needs pixel control (e.g. achart region inside an otherwise-responsive dashboard)? Leaning toward
allowing arrangement mode at the slot level rather than forcing one
choice for the whole layout, since real dashboards usually need exactly
this mix.
Dependencies
Depends on
ui profile— platform/size targeting and component packages #94 — thecompact/regular/expandedsize-class vocabulary this splits into width × heightBlocks
flowandfreeformarrangement rendering Scene#4 — layout engine implementingflowandfreeformlayoutarrangements intoScene.ModelGates other work: the open question on mixed arrangement per slot must be settled before Cratis/Scene#4 fixes its engine API and before Cratis/StudioIssues#161 builds slot-level mode switching.
Part of the screen work — build order and full dependency map: Cratis/Scene#7
Implementation notes — verified current state
layoutexists today but carries no arrangement information at all. The whole declaration is one line inSource/DotNET/Screenplay/Syntax/ModuleSyntax.cs:Slots are bare strings — no nesting, no primitives, no variants. It is declared at module scope (
ModuleSyntax.Layouts) and referenced from a screen throughScreenLayoutSyntax(string Name, IEnumerable<ScreenSlotSyntax> Slots, …)inScreenSyntax.cs.So this issue replaces
IEnumerable<string> Slotswith a real template tree (row/column/grid+grow/gap/span, orvariant+placefor freeform). Every existing consumer ofLayoutSyntax.Slots— parser, walker, printer, and theScreenLayoutSyntaxslot-filling check — has to move with it. Keep a barelayout Xwith plain slot names parsing exactly as it does now; this must be a purely additive language change.New diagnostics (missing
variantfor a targeted size class) start at SP0035 — the highest code allocated today is SP0034.