Skip to content

feat(shot): lay out with a device's safe area with --safe-area - #50

Merged
koji-1009 merged 2 commits into
feat/pixel-ratiofrom
feat/safe-area
Nov 5, 2026
Merged

koji-1009 merged 2 commits into
feat/pixel-ratiofrom
feat/safe-area

Conversation

@koji-1009

Copy link
Copy Markdown
Owner

Stacked on #49.

flutter test lays the app out without a safe area: the view reports no padding (MediaQuery.paddingOf and viewPaddingOf are EdgeInsets.zero), as no phone does. A screen shot that way has its AppBar 59 points higher than on an iPhone, and a SafeArea or a bottom bar that pads itself by the padding sits flush with the edges, so the image an agent attached was not the screen it was implementing.

How it works

  • shutter shot --safe-area <top>,<bottom> (and semantics) lays every preview out with those insets in logical pixels; from Dart, shot(safeArea: SafeAreaInsets(top:, bottom:)). There is no default, as with --keyboard: insets differ by device.
  • The harness sets the test view's viewPadding and padding to the insets. With --keyboard, the keyboard absorbs the bottom inset from the padding but not from the view padding, as the engine documents for a device (FlutterView, "Insets and Padding").
  • The status bar, notch, and home indicator are not drawn: the insets show what the app paints there.
  • shoot rejects insets that are not ≥ 0 and finite with exit 64; the CLI rejects anything but two numbers.
  • The run records safe_area in manifest.json, shot prints it, and diff prints both runs' when they differ and returns it as ShotSetup.safeArea. It is not part of shot ids.

Tests

  • test/e2e/device_test.dart: a SafeArea inside a red box keeps out of --safe-area 10,5 (red bands at the top and bottom, none without the option); with --keyboard 20 the bottom band is gone while MediaQuery.viewPaddingOf still reads the insets; diff prints safe_area.

Docs

  • doc/manual.md gains a Safe area section; runs, output, and commands name the option. doc/agent.md, the README, and the CHANGELOG cover it.

🤖 Generated with Claude Code

shot --safe-area <top>,<bottom> (and semantics, and
shot(safeArea: SafeAreaInsets(...))) lays every preview out with those
safe area insets in logical pixels, which flutter test reports as none.
The view reports them as its padding and view padding, so an AppBar
grows by the top inset and a SafeArea keeps out of them as on the
device; with --keyboard, the keyboard absorbs the bottom inset from the
padding but not from the view padding. The status bar and home
indicator are not drawn. The run records safe_area, shot prints it, and
diff prints both runs' when they differ and returns it as
ShotSetup.safeArea; it is not part of shot ids.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@koji-1009

koji-1009 commented Nov 4, 2026 •

Copy link
Copy Markdown
Owner Author

example/'s SettingsPage preview (390x844), shown at its logical width: with --safe-area 59,34 the AppBar grows by the top inset, as on an iPhone. The status bar itself is not drawn.

without --safe-area 59,34
SettingsPage without a safe area SettingsPage with --safe-area 59,34

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@koji-1009
koji-1009 marked this pull request as ready for review November 4, 2026 23:44
@koji-1009
koji-1009 added this pull request to stack #54 November 5, 2026 00:34
@koji-1009
koji-1009 merged commit b695199 into main Nov 5, 2026
5 checks passed
@koji-1009
koji-1009 deleted the feat/safe-area branch November 5, 2026 00:55
@koji-1009 koji-1009 mentioned this pull request Nov 5, 2026
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.

2 participants