feat: add iPad sidebar layout and iPad CI test matrix#15
Merged
Conversation
The post-onboarding shell now adapts to the horizontal size class instead of stretching the iPhone tab bar across the iPad canvas: a bottom TabView in compact width (iPhone, iPad multitasking) and a left NavigationSplitView sidebar in regular width (full-screen iPad), per Apple's HIG. The three sections (Home / Rules / Settings) and their views are reused verbatim in both layouts. - AppSection enum is the single source of truth for tab items and sidebar rows; MainLayout.resolve picks the chrome from horizontalSizeClass. - New MainView shell owns the enforcement lifecycle (lifted off MainTabView) so it runs regardless of layout; MainSidebarView is the regular-width view. - CI: test.yml now runs the suite on both iPhone 17 Pro and iPad Pro 13-inch (M4) via a fail-fast:false matrix with per-leg artifacts. Tests (TDD red -> green): new AppSection / MainLayout unit suites and an idiom-aware NavigationChromeUITests. Existing UI helpers made sidebar-aware (goTo*Tab / waitForMainUI); iPhone-presentation-specific flows adapted to iPad (nav BackButton instead of window-edge swipe, scroll the shorter form sheet, gate window-relative width to iPhone) or skipped on iPad with a documented reason. Suite is green on both devices (iPad 231 pass/1 skip, iPhone 232 pass). Docs: spec section 6 and AGENTS.md updated for the adaptive shell. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SZ9eNtWxt96J66dG3amUSU
Resolves additive doc conflicts by keeping both sides: the iPad sidebar identifiers/diagram (this branch) and main's Settings "About" GitHub/Website links (AGENTS.md identifier list, spec §6 navigation diagram). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SZ9eNtWxt96J66dG3amUSU
iPad Pro 13-inch (M4) is not installed on the macos-26 runner image (only M5 Pros plus Air / mini / A16), so build-for-testing failed with a "destination not found" error (exit 70) before any test ran. iPad Pro 11-inch (M5) is present on the runner and is the device the suite was validated on locally; full-screen iPad is regular width regardless of model, so the sidebar layout is exercised identically. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SZ9eNtWxt96J66dG3amUSU
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes OpenAppLock iPad-native and adds iPad to CI. The app already declared
TARGETED_DEVICE_FAMILY = "1,2", so it ran on iPad — but it just stretched theiPhone bottom tab bar across the canvas. Per Apple's HIG, a bottom tab bar is an
iPhone idiom; on the regular-width iPad the top-level sections belong in a left
sidebar.
The post-onboarding shell is now adaptive, driven by
horizontalSizeClass(not device idiom, so iPad multitasking/Slide Over stays correct):
TabView(MainTabView)NavigationSplitViewsidebar (MainSidebarView)HomeView/RulesListView/SettingsVieware reused verbatim in bothlayouts — only the navigation chrome differs.
Changes
AppSectionenum — single source of truth for tab items and sidebar rows.MainLayout.resolve(horizontalSizeClass:)— picks tabs vs sidebar (sidebar only for known regular width).MainViewshell — owns the enforcement lifecycle (lifted offMainTabView) so it runs regardless of layout; newMainSidebarViewfor the iPad sidebar.RootViewnow rendersMainView;MainTabViewis compact-only and sources its tabs fromAppSection.test.ymlruns the suite on iPhone 17 Pro and iPad Pro 13-inch (M4) via afail-fast: falsematrix with per-leg artifacts.AGENTS.mdupdated for the adaptive shell +sidebarItem-<section>identifiers + iPad UI-test gotchas.Test plan
AppSectionTests,MainLayoutTests(unit)NavigationChromeUITests(sidebar-on-iPad / tabs-on-iPhone)BackButtonvs window-edge swipe; scroll the shorter form sheet; window-relative width gated to iPhone)Notes
testEditorSupportsNativeSwipeBack) is skipped on iPad with a documented reason: its window-edge swipe gesture only maps onto a full-width sheet (iPhone); the equivalent back navigation is covered bytestLimitEditorsAreBlockOnly.project.pbxprojchanges.🤖 Generated with Claude Code
https://claude.ai/code/session_01SZ9eNtWxt96J66dG3amUSU