The stacked mount reads as one document in view mode — title, body and the thread share a single scroll

Preview, stacked (over/under): title, the rendered body and the comment
thread now stack in one continuous document with one scroll, instead of
the fixed ≈3:2 split with each pane keeping its own. Edit mode keeps the
split unchanged (an editor needs a stable scroll of its own), and the
beside mount is untouched.

CardBodySurface gains a `scrolls` flag: false switches off the hosted
NSScrollView's scroller and elasticity and reports the NSTextView's own
height for the proposed width via `sizeThatFits`, the layout-manager
height-fit trick CommentBodyView already uses one level up. CardCommentsPane
gains an `embeddedProxy`: supplied, it renders the same header, find bar,
rows and composer without wrapping them in a second ScrollView, driving
scrollTo off the outer document's proxy instead of its own. CardWindowView
composes the two behind a new pure predicate, CommentsMount.showsContinuousDocument(mode:),
tested in CardCommentsLayoutTests.

The continuous↔split swap within stacked mount is a genuine remount of the
body pane (two independent scrolls can't become one shared scroll by
reconfiguration) — the same accepted cost the raw-source outlet already
takes elsewhere in this window. No new animation on that swap, matching
this file's existing precedent (the raw-source swap and the beside↔stacked
mount switch are both instant cuts today). Decisions recorded on the card's
thread, flagged for owner review where they're user-visible.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
2026-08-09 12:30:41 -04:00
parent 7a4d27f62d
commit 6bf3308915
5 changed files with 256 additions and 87 deletions
+14
View File
@@ -57,6 +57,20 @@ public enum CommentsMount: Sendable, Equatable {
/// Stacked, the comments pane takes the width the body already had, so a narrow display keeps the
/// minimum it has always had. That is the whole reason the option exists.
public var widensWindow: Bool { self == .beside }
/// **Whether Preview shows the stacked mount's continuous, single-scroll arrangement** title,
/// body and the comment thread stacked directly atop each other in one document, rather than the
/// fixed 3:2 split with each pane keeping its own scroll.
///
/// Pure and mode-driven, so "continuous is Preview-only; Edit keeps the split; beside is
/// untouched" is a fact a test can hold rather than something read off a running window
/// (`CardWindowView.contentPanes` is the one caller). Edit needs its own stable scroll a text
/// editor's caret, selection and undo session cannot share a document scroll with the thread
/// beneath it and stay usable and the beside mount never had a split to begin with, so neither
/// case answers `true` regardless of `mode`.
public func showsContinuousDocument(mode: CardBodyMode) -> Bool {
self == .stacked && mode == .preview
}
}
// MARK: - Which way the thread runs