ReviewOS

also looking at this

craft-native/craft

test(ios): cover solid navigation bar title modes

#361
Closed glennmichael123 wants to merge codex/issue-360-solid-navigation-bar into main
3 files +22 -1
docs/guides/native-stx.mdmodified+11-0
Changes to docs/guides/native-stx.md
@@ -697,6 +697,17 @@ app, the iOS shell's gesture also covers the WebView. Pass
697697gesture of its own; native screens can still opt out independently with
698698`tabSwipeEnabled`.
699699
700On iOS, a native screen can opt into an opaque navigation bar that uses its
701screen background, including the light/dark variant from `craft.config.json`:
702
703```js
704craft.navigation.setOptions({ navigationBarSolid: true })
705```
706
707This applies to both standard and large-title bars, and remains in place while
708the screen is pushed, popped, or revealed by a tab swipe. The default remains
709UIKit's translucent material; pass `navigationBarSolid: false` to restore it.
710
700711A screen's content stays inside the safe area. To colour the strips under the
701712status bar and the home indicator too, such as a black full-screen timer with
702713the bar hidden, set `craft.navigation.setOptions({ hidden: true,
packages/ios/fixtures/native-screen/NativeLayoutUnitTests.swiftmodified+10-1
Changes to packages/ios/fixtures/native-screen/NativeLayoutUnitTests.swift
@@ -595,7 +595,9 @@ final class NativeLayoutUnitTests: XCTestCase {
595595 navigation.loadViewIfNeeded()
596596 controller.loadViewIfNeeded()
597597
598 controller.evaluateScript("craft.navigation.setOptions({ backgroundColor: '#123456', navigationBarSolid: true })")
598 controller.evaluateScript("craft.navigation.setOptions({ title: 'Solid', largeTitle: true, backgroundColor: '#123456', navigationBarSolid: true })")
599 XCTAssertEqual(controller.navigationItem.largeTitleDisplayMode, .always)
600 XCTAssertTrue(navigation.navigationBar.prefersLargeTitles)
599601 let solid = try XCTUnwrap(controller.navigationItem.standardAppearance)
600602 XCTAssertNil(solid.backgroundEffect)
601603 // UIKit may normalize clear to nil; both mean no shadow.
@@ -606,6 +608,13 @@ final class NativeLayoutUnitTests: XCTestCase {
606608 XCTAssertNotNil(controller.navigationItem.compactAppearance)
607609 XCTAssertNotNil(controller.navigationItem.compactScrollEdgeAppearance)
608610
611 // The same fill remains attached when a screen opts out of the large
612 // title layout; UIKit must not fall back to its translucent scroll-edge
613 // material just because the title collapsed.
614 controller.evaluateScript("craft.navigation.setOptions({ largeTitle: false })")
615 XCTAssertEqual(controller.navigationItem.largeTitleDisplayMode, .never)
616 XCTAssertNotNil(controller.navigationItem.scrollEdgeAppearance)
617
609618 controller.evaluateScript("craft.navigation.setOptions({ navigationBarSolid: false })")
610619 XCTAssertNil(controller.navigationItem.standardAppearance)
611620 XCTAssertNil(controller.navigationItem.scrollEdgeAppearance)
packages/ios/src/index.test.tsmodified+1-0
Changes to packages/ios/src/index.test.ts
@@ -1568,6 +1568,7 @@ describe('Craft iOS builder', () => {
15681568 expect(screen).toContain('appearance.backgroundColor = screenBackgroundColor ?? config.resolvedBackgroundColor')
15691569 expect(screen).toContain('appearance.shadowColor = .clear')
15701570 expect(screen).toContain('navigationItem.compactScrollEdgeAppearance = appearance')
1571 expect(screen).toContain('navigationItem.standardAppearance = nil')
15711572 expect(readFileSync(join(import.meta.dir, '..', 'fixtures/native-screen/NativeLayoutUnitTests.swift'), 'utf8')).toContain('try assertColor(light, red: 1, green: 1, blue: 1)')
15721573 // A screen that starts with its scroll view runs edge to edge, so what
15731574 // scrolls up goes under the bar, not over its back button; the bottom