Skip to content

Feat: Align layout primitives and terminal geometry semantics with SwiftUI#71

Open
phranck wants to merge 15 commits into
mainfrom
issue/20-layout-primitives
Open

Feat: Align layout primitives and terminal geometry semantics with SwiftUI#71
phranck wants to merge 15 commits into
mainfrom
issue/20-layout-primitives

Conversation

@phranck

@phranck phranck commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Closes #20.

Summary

  • Alignment: HorizontalAlignment/VerticalAlignment become SwiftUI's extensible structs with AlignmentID identities and a cell-based ViewDimensions context; every renderer alignment switch now resolves guide-based cell offsets, so custom guides work everywhere alignment is consumed
  • Quantization policy (TerminalGeometry, package-scoped): one documented, deterministic CGFloat→cell mapping — sizes/spacing round half away from zero, alignment offsets floor (preserving established centering), .infinity fills, NaN and negatives degrade to zero; identical results on macOS and Linux
  • Edge/EdgeInsets/Padding: Edge is the enum with nested Edge.Set; EdgeInsets carries CGFloat sides; padding(_ edges: Edge.Set = .all, _ length: CGFloat? = nil) matches SwiftUI with the one-cell terminal default
  • Stacks/Spacer: CGFloat? spacing/minLength everywhere (nil = established terminal defaults); lazy stacks accept pinnedViews: (visual effect lands with viewport-driven laziness, [P1-20] Implement true viewport-driven lazy collections #25); no public API exposes Int because the renderer uses cells
  • Frames: CGFloat constraints, .infinity maxima fill, and the fixed-frame default alignment matches SwiftUI's .center; the FrameDimension enum is gone
  • New views: GeometryReader (CGSize proxy, fills its space), ViewThatFits (ideal-probe measurement so adaptive children don't always "fit"), and the Layout protocol family with AnyLayout (ProposedViewSize, LayoutSubview proxies, cache, placement compositing) built on the two-pass child infrastructure
  • ZStack alignment, frame alignment, and nested proposal propagation pinned by golden tests; layout compile fixture extended across the new surface

Test plan

  • 1389 tests green on macOS (Swift 6.0.3) and Linux (Docker 6.0.3-noble), warning-fatal, via ./scripts/test-linux.sh
  • New suites: AlignmentGuideTests (incl. quantization policy), LayoutGoldenTests, AdaptiveLayoutViewTests, CustomLayoutTests
  • verify-compatibility-manifest.sh passes against the regenerated manifest

phranck added 15 commits July 22, 2026 14:52
- Reshape HorizontalAlignment and VerticalAlignment into SwiftUI's
  extensible structs with AlignmentID identities and a cell-based
  ViewDimensions context
- Add the TerminalGeometry quantization policy: sizes and spacing round
  half away from zero, alignment offsets floor (preserving established
  centering), infinity fills, NaN and negatives degrade deterministically
- Replace every alignment switch in the renderers with guide-based cell
  offsets, so custom guides work everywhere alignment is consumed
- Cover identity equality, built-in and custom guide offsets, clamping,
  and the quantization policy with tests
- Reshape Edge into the enum with a nested Edge.Set option set
- Move EdgeInsets to CGFloat sides; the renderer quantizes through
  TerminalGeometry with negative values degrading to zero
- Align padding with SwiftUI: padding(_:) with CGFloat, and
  padding(_ edges: Edge.Set = .all, _ length: CGFloat? = nil) where nil
  means the one-cell terminal default
- HStack, VStack, LazyVStack, LazyHStack, and Spacer take CGFloat?
  spacing/minLength like SwiftUI; nil selects the established terminal
  defaults and values quantize through TerminalGeometry
- Internal spacing storage stays in cells; the public Int properties
  become internal
- Lazy stacks accept SwiftUI's pinnedViews option set; pinning takes
  visual effect with viewport-driven laziness (#25)
…fault

- Replace the public FrameDimension enum with CGFloat? maxima where
  .infinity fills the available space (Int.max cell sentinel internally)
- frame(width:height:alignment:) and the flexible overload take CGFloat
  values quantized through TerminalGeometry; the fixed-frame default
  alignment matches SwiftUI's .center
- Pin ZStack corner alignments, the SwiftUI center default of fixed
  frames, explicit frame corner alignment, and nested proposal
  propagation through frames and padding
- GeometryReader reports the proposed cell size through a CGSize-based
  proxy and expands to fill its space with top-leading content
- ViewThatFits measures candidates against a generous ideal probe in
  the constrained axes (adaptive children would otherwise always fit),
  renders the first candidate whose ideal size fits, and falls back to
  the clipped last candidate
- Add the Axis and Axis.Set types backing the axis constraint
- Add SwiftUI's Layout contract (ProposedViewSize, LayoutSubview
  proxies, cache) as a terminal adaptation: measurement quantizes to
  cells and placements composite child buffers at floored offsets
- Layouts apply like container views through callAsFunction, and
  AnyLayout erases concrete layouts for structure-preserving switches
- Cover a custom diagonal layout and AnyLayout delegation with tests
- Cover CGFloat spacing, custom alignment guides, Edge.Set padding,
  CGFloat frames, pinned lazy stacks, ViewThatFits, GeometryReader, and
  the custom layout family
- DocC cannot resolve symbol links to the package-visible
  TerminalGeometry type
- Drop 51 overrides for removed symbols (closed alignment enums, the
  Edge option set, Int-based spacing, frame, and inset APIs)
- Add 148 overrides for the new surface: AlignmentID guides,
  ViewDimensions, Edge.Set, CGFloat geometry, PinnedScrollableViews,
  Axis, GeometryReader, ViewThatFits, and the Layout family
- Regenerate the manifest with TUIkitAPICheck against fresh 6.0.3
  macOS and Linux snapshots
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P1-15] Align layout primitives and terminal geometry semantics with SwiftUI

1 participant