Skip to content
Merged
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
3 changes: 3 additions & 0 deletions resources/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ const docsearchOptions = {
docsearch({
...docsearchOptions,
container: '#docsearch-desktop',
// The site menu is a popover, so it renders above the search modal. Tell it
// to close when a keyboard shortcut opens search while the menu is open.
onOpen: () => window.dispatchEvent(new CustomEvent('docsearch:open')),
})

// Mirror the desktop DocSearch button into the mobile container so that
Expand Down
6 changes: 5 additions & 1 deletion resources/views/components/navbar/mobile-menu.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
})
}
"
x-on:docsearch:open.window="showMobileMenu = false"
class="relative z-40"
>
<button
Expand Down Expand Up @@ -419,7 +420,10 @@ class="-mr-0.5 transition-all duration-200 ease-in-out will-change-transform lg:
>
<div
id="docsearch-desktop"
x-on:click="if (window.innerWidth < 640) window.scrollTo({ top: 0, behavior: 'instant' })"
x-on:click="
showMobileMenu = false
if (window.innerWidth < 640) window.scrollTo({ top: 0, behavior: 'instant' })
"
aria-label="Search documentation"
></div>
</div>
Expand Down
56 changes: 56 additions & 0 deletions tests/Feature/NavigationMobileMenuSearchTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Tests\Feature;

use DOMDocument;
use DOMElement;
use DOMXPath;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

/**
* The menu is a popover, so the browser draws it above everything else,
* including the DocSearch modal. It has to close whenever search opens,
* otherwise it sits on top of the search box.
*/
class NavigationMobileMenuSearchTest extends TestCase
{
use RefreshDatabase;

public function test_menu_closes_when_its_search_button_is_clicked(): void
{
$searchButtonContainer = $this->elementOnHomePage('//*[@id="docsearch-desktop"]');

$this->assertStringContainsString(
'showMobileMenu = false',
$searchButtonContainer->getAttribute('x-on:click'),
);
}

public function test_menu_closes_when_a_keyboard_shortcut_opens_search(): void
{
$menu = $this->elementOnHomePage('//*[@id="mobile-menu-popover"]/..');

$this->assertSame('showMobileMenu = false', $menu->getAttribute('x-on:docsearch:open.window'));

$this->assertMatchesRegularExpression(
"/onOpen: .*new CustomEvent\('docsearch:open'\)/",
file_get_contents(resource_path('js/app.js')),
'DocSearch should announce that it opened with the event the menu listens for.',
);
}

private function elementOnHomePage(string $xpath): DOMElement
{
$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML('<?xml encoding="utf-8" ?>'.$this->get('/')->assertOk()->getContent());
libxml_clear_errors();

$element = (new DOMXPath($dom))->query($xpath)->item(0);

$this->assertInstanceOf(DOMElement::class, $element, "Nothing on the home page matches {$xpath}.");

return $element;
}
}
Loading