Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/Edge/NativeComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,17 @@ protected function wrapWithChrome(Element $content): Element
}
} elseif (! $hasCustomBottomNav && $layout !== null) {
$tabBar = $layout->tabBar($this);
// Per-screen opt-out ($hidesTabBar shortcut + tabBarOptions()
// builder), mirroring the NavBar handling above. On the
// custom-Column path hiding is identical to the layout
// returning null — dropping the bar also hands the bottom
// safe-area edge back to the wrapper in buildChromeColumn().
// The native-chrome path instead keeps the config and folds a
// `hide_tab_bar` prop onto the sentinel, so the TabView
// survives for tab switching.
if ($tabBar !== null && ! $usesNativeChrome && $this->shouldHideTabBar()) {
$tabBar = null;
}
if ($tabBar !== null) {
$currentUri = $this->nativeRouter?->currentUri();
if ($currentUri !== null) {
Expand Down
38 changes: 30 additions & 8 deletions src/Testing/TestableComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -951,14 +951,28 @@ public function assertHasTabBar(): static
return $this;
}

/**
* Assert the tab bar is hidden on this screen (`$hidesTabBar` /
* `tabBarOptions()->hidden()`), across both chrome paths: on the
* native-chrome path the sentinel carries `hide_tab_bar`; on the
* custom-Column path the bar is simply not rendered.
*/
public function assertTabBarHidden(): static
{
$tabs = $this->findElement($this->tree(), 'native_root_tabs');

Assert::assertNotNull($tabs, 'No native tab chrome rendered — nothing to be hidden.');
Assert::assertTrue(
(bool) ($tabs['props']['hide_tab_bar'] ?? false),
'Expected the tab bar to be hidden on this screen, but hide_tab_bar is not set.'
if ($tabs !== null) {
Assert::assertTrue(
(bool) ($tabs['props']['hide_tab_bar'] ?? false),
'Expected the tab bar to be hidden on this screen, but hide_tab_bar is not set.'
);

return $this;
}

Assert::assertNull(
$this->findElement($this->tree(), 'bottom_nav'),
'Expected the tab bar to be hidden on this screen, but a bottom_nav element was rendered.'
);

return $this;
Expand All @@ -968,10 +982,18 @@ public function assertTabBarVisible(): static
{
$tabs = $this->findElement($this->tree(), 'native_root_tabs');

Assert::assertNotNull($tabs, 'No native tab chrome rendered.');
Assert::assertFalse(
(bool) ($tabs['props']['hide_tab_bar'] ?? false),
'Expected the tab bar to be visible, but hide_tab_bar is set.'
if ($tabs !== null) {
Assert::assertFalse(
(bool) ($tabs['props']['hide_tab_bar'] ?? false),
'Expected the tab bar to be visible, but hide_tab_bar is set.'
);

return $this;
}

Assert::assertNotNull(
$this->findElement($this->tree(), 'bottom_nav'),
'Expected the tab bar to be visible, but no bottom_nav element was rendered.'
);

return $this;
Expand Down
20 changes: 20 additions & 0 deletions tests/Feature/TestingSuiteV2Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Tests\Fixtures\Edge\GateScreen;
use Tests\Fixtures\Edge\HiddenNavOptionsScreen;
use Tests\Fixtures\Edge\HiddenNavScreen;
use Tests\Fixtures\Edge\HiddenTabOptionsScreen;
use Tests\Fixtures\Edge\HiddenTabScreen;
use Tests\Fixtures\Edge\PingReceived;
use Tests\Fixtures\Edge\PlatformScreen;
Expand Down Expand Up @@ -249,6 +250,25 @@
->assertNavTitle('Chrome Demo');
});

it('hides the tab bar via the tabBarOptions builder', function () {
Native::test(HiddenTabOptionsScreen::class, layout: ChromeTabsLayout::class)
->assertTabBarHidden();
});

it('drops the tab bar entirely on the custom-Column chrome path', function () {
// Both spellings — the $hidesTabBar shortcut and the tabBarOptions()
// builder — must hide the bar here, exactly as they do on the native
// chrome path.
Native::test(HiddenTabScreen::class, layout: ChromeColumnLayout::class)
->assertTabBarHidden();

Native::test(HiddenTabOptionsScreen::class, layout: ChromeColumnLayout::class)
->assertTabBarHidden();

Native::test(ChromeScreen::class, layout: ChromeColumnLayout::class)
->assertTabBarVisible();
});

it('fails nav title assertions helpfully', function () {
Native::test(CounterScreen::class)->assertNavTitle('Nope');
})->throws(AssertionFailedError::class);
Expand Down
15 changes: 13 additions & 2 deletions tests/Fixtures/Edge/ChromeColumnLayout.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,28 @@
namespace Tests\Fixtures\Edge;

use Native\Mobile\Edge\Layouts\Builders\NavBar;
use Native\Mobile\Edge\Layouts\Builders\Tab;
use Native\Mobile\Edge\Layouts\Builders\TabBar;
use Native\Mobile\Edge\Layouts\NativeLayout;
use Native\Mobile\Edge\NativeComponent;

/**
* Custom-Column chrome path (usesNativeChrome() = false) — the bar
* renders as a `top_bar` element instead of a native sentinel.
* Custom-Column chrome path (usesNativeChrome() = false) — the bars
* render as `top_bar` / `bottom_nav` elements instead of a native
* sentinel.
*/
class ChromeColumnLayout extends NativeLayout
{
public function navBar(NativeComponent $screen): ?NavBar
{
return NavBar::make()->title($screen->navTitle());
}

public function tabBar(NativeComponent $screen): ?TabBar
{
return TabBar::make()
->add(Tab::link('Home', '/'))
->add(Tab::link('Detail', '/detail/1'))
->highlight('/');
}
}
22 changes: 22 additions & 0 deletions tests/Fixtures/Edge/HiddenTabOptionsScreen.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Tests\Fixtures\Edge;

use Native\Mobile\Edge\Layouts\Builders\TabBarOptions;

/**
* Hides the tab bar via the `tabBarOptions()` builder rather than the
* `$hidesTabBar` shortcut — the form reported in #250.
*/
class HiddenTabOptionsScreen extends ChromeScreen
{
public function navTitle(): string
{
return 'Pushed Detail';
}

public function tabBarOptions(): ?TabBarOptions
{
return TabBarOptions::make()->hidden();
}
}
Loading