Skip to content

Add snapshot variants for light/dark, Dynamic Type, RTL and locale - #176

Open
BarredEwe wants to merge 2 commits into
mainfrom
feature/snapshot-variants
Open

Add snapshot variants for light/dark, Dynamic Type, RTL and locale#176
BarredEwe wants to merge 2 commits into
mainfrom
feature/snapshot-variants

Conversation

@BarredEwe

Copy link
Copy Markdown
Owner

Closes #99

One preview currently produces exactly one rendering. This adds appearance, Dynamic Type, layout direction and locale as snapshot variants.

test_configuration:
  snapshot_variants: [light, dark, accessibilityXXXL, rtl, locale_ru_RU]
#Preview {
    ProfileCard().snapshotVariants([.light, .dark])
}

Implementation

SnapshotVariant covers light, dark, sizeCategory(_:), rightToLeft and locale(_:), and applies each purely through the SwiftUI environment — no UITraitCollection — so the same code path works on iOS, tvOS and macOS.

In the template assertSnapshots now delegates to an assertVariants layer that sits between the device loop and assertSnapshot, so names compose as Name-iPhone 13 Pro-dark. assertSnapshot takes the already-hosted view and preferences, so the default path still renders exactly once and produces byte-identical output when no variants are configured.

.light deliberately has an empty suffix, so a [light, dark] configuration reuses existing reference images and only adds -dark — no one's snapshots are invalidated by upgrading. Other suffixes: -dark, -rtl, -accessibilityXXXL, -locale_ru_RU. An unknown variant name fails loudly, mirroring the existing behavior for unknown devices.

The per-preview modifier is backed by a preference key; when it is absent, the configured list applies.

Tests

Config decoding, makeArguments, and two generator tests (rendered variants array, empty default). On the runtime side, SnapshotVariantTests covers name parsing and suffixes, and three MacOSSnapshotTests cases use a VariantProbe view that encodes the environment as a bit mask in its own width — necessary because the host machine's own dark mode and locale otherwise leak into the assertion.

make test 59/0, make test-cli 22/0, make build clean.

Render every preview once per variant, driven by the new `snapshot_variants`
configuration key or by `.snapshotVariants(_:)` on a single preview. Variants
compose with `snapshot_devices` (`MyView-iPhone 14-dark`), and `light` keeps the
snapshot name unsuffixed so already recorded references stay valid.

Variants are applied through the SwiftUI environment instead of
`UITraitCollection`, so they work on iOS, tvOS and macOS alike. Without any
configuration and without the modifier nothing changes: one snapshot per
preview, rendered exactly as before.

Closes #99

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b031df10cd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

`ContentSizeCategory` is not `Sendable` in the Xcode 16.4 SDK, which broke the
`Sendable` conformance of `SnapshotVariant` and its lookup table. Carry the
Dynamic Type size as our own `SnapshotVariant.SizeCategory` instead and map it
to `ContentSizeCategory` only where it is applied to the environment.

The raw value doubles as the configuration name, so the `snapshot_variants`
names and `.snapshotVariants([...])` are unchanged.
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.

Support for Light and Dark Theme Snapshots

1 participant