Skip to content

Fix paragraph/heading width hugging; add LLM Chat sample demo - #162

Merged
Jun Yan (junyan72) merged 3 commits into
mainfrom
alignment-inv
Aug 2, 2026
Merged

Fix paragraph/heading width hugging; add LLM Chat sample demo#162
Jun Yan (junyan72) merged 3 commits into
mainfrom
alignment-inv

Conversation

@junyan72

Copy link
Copy Markdown
Contributor

Summary

Fix the core rendering bug where paragraph and heading blocks always report the full offered width, and add an interactive sample demo that exercises the corrected hugging behavior.

  • Sources/MarkdownText/UI/BlockView.swift — remove the HStack { ParagraphView(...); Spacer() } wrapper from the .paragraph and .heading cases of SingleBlockView. The unqualified Spacer() always consumed whatever width its parent HStack was offered, so the block reported that inflated width upward — breaking any ancestor that hugs content to the text's natural width (e.g. a chat bubble capping itself at a fraction of the screen). ParagraphView already renders left-aligned and BlockView's outer VStack is .leading, so left alignment is unchanged. Callers wanting full-width fill can still apply .frame(maxWidth: .infinity, alignment: .leading) from the outside.
  • Tests/.../SnapshotTestFoundation/CanvasView.swift — align the snapshot harness VStack to .leading so references reflect the hugging layout.
  • 46 re-recorded iOS snapshot references reflecting the wider natural line-wrapping.
  • New "LLM Chat" sample demo (LLMChatView + @MainActor LLMChatViewModel + non-isolated LLMChatInteractor) — a typical chat interface with trailing user bubbles and leading bot bubbles, a text composer, and rotating mock responses (text, citations, images, code) rendered via DocumentView from progressively parsed RenderableDocuments to simulate streaming. Linked from a new "Featured" section in NavigationView.

Fixes #157

Validation

  • make lint — 0 violations in 139 files
  • iOS snapshot references re-recorded locally on iPhone 17 (iOS 26.4.1) and spot-checked
  • LLM Chat demo built and run in the iOS Simulator; verified role-aligned bubbles hug their content and stream correctly

Note: macOS snapshot references were not re-recorded locally (per the snapshot-tests skill, macOS variants must be produced by the Record macOS Snapshots workflow to avoid subpixel mismatches). They still need to be backfilled before CI's macOS snapshot job will pass.

OSS readiness

  • No secrets, internal URLs, private identifiers, or product-only service names were added.
  • Public docs, fixtures, or notices were updated if behavior or dependencies changed. (sample app + snapshot references updated)
  • Third-party dependency changes (adds, removes, version bumps) are intentional and reviewed. (no dependency changes)
  • Streaming/incomplete markdown behavior remains covered by fixtures or tests.

Remove the `HStack { ParagraphView(); Spacer() }` wrapper from the
.paragraph and .heading cases in SingleBlockView. The unqualified
Spacer() forced blocks to report the full offered width upward,
breaking ancestors that hug content to the text's natural width
(e.g. chat bubbles). ParagraphView already renders left-aligned and
the outer VStack is `.leading`, so alignment is unchanged.

Also align the snapshot CanvasView harness to `.leading` and
re-record the affected iOS references.

Add an interactive "LLM Chat" sample demo (LLMChatView +
LLMChatViewModel + non-isolated LLMChatInteractor) showcasing
role-aligned bubbles with progressively streamed rich Markdown.

Fixes #157

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Not ready to approve

The sample chat code introduces compile-time issues (missing imports / incorrect onChange closure signature) and a concurrency safety concern around concurrent sends sharing mutable state and a parser instance.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

This PR fixes a core SwiftUI layout bug where paragraph and heading blocks inflated their reported width (breaking width-hugging containers like chat bubbles), updates the snapshot canvas alignment to reflect the corrected hugging behavior, and adds a new “LLM Chat” sample screen to exercise streaming, rich Markdown rendering.

Changes:

  • Fix width reporting for .paragraph and .heading blocks by removing the HStack { …; Spacer() } wrapper in SingleBlockView.
  • Update the snapshot test canvas to use a leading-aligned VStack so reference images match the new hugging behavior.
  • Add a new “LLM Chat” featured demo (view + view model + interactor) to demonstrate streaming-style incremental Markdown updates.
File summaries
File Description
Tests/MarkdownTextTests/SnapshotTestFoundation/CanvasView.swift Aligns the snapshot harness container to .leading to match the corrected hugging layout.
Sources/MarkdownText/UI/BlockView.swift Removes the Spacer()-inflated layout wrapper for headings/paragraphs so blocks can report their natural width.
Examples/SwiftStreamingMarkdownSample/SwiftStreamingMarkdownSample/NavigationView.swift Adds a “Featured” section linking to the new LLM Chat demo.
Examples/SwiftStreamingMarkdownSample/SwiftStreamingMarkdownSample/LLMChatViewModel.swift Introduces main-actor chat transcript + draft state for the demo.
Examples/SwiftStreamingMarkdownSample/SwiftStreamingMarkdownSample/LLMChatView.swift Implements the chat UI and incremental scrolling behavior.
Examples/SwiftStreamingMarkdownSample/SwiftStreamingMarkdownSample/LLMChatInteractor.swift Provides mock streaming replies and shared Markdown parsing/render configuration.
Review details
  • Files reviewed: 6/52 changed files
  • Comments generated: 4
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Jun Yan and others added 2 commits August 2, 2026 15:46
Copy the 26 affected macOS-standard light/dark references (13 test
methods) recorded by the Record macOS Snapshots workflow, matching the
iOS references re-recorded after removing the paragraph/heading
Spacer wrapper.

Refs #157

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Constrain the conversation column and composer to a centered 640pt max
width on macOS so the chat doesn't stretch across a wide window; iOS
keeps full width.

Refs #157

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@junyan72
Jun Yan (junyan72) merged commit 5f7c04e into main Aug 2, 2026
6 checks passed
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.

[Bug]: paragraph/heading blocks always report full offered width, breaking width-hugging containers

2 participants