Always show 'Jump to...' menu item, closes #2725

This commit is contained in:
Simon Willison 2026-05-20 13:23:05 -07:00
commit d3330695fa
5 changed files with 57 additions and 8 deletions

View file

@ -362,6 +362,32 @@ form.nav-menu-logout {
.nav-menu-inner a {
display: block;
}
.nav-menu-inner button.button-as-link {
display: block;
width: 100%;
text-align: left;
font: inherit;
}
.nav-menu-inner .keyboard-shortcut {
float: right;
box-sizing: border-box;
min-width: 1.4em;
margin-left: 0.75rem;
padding: 0 0.35em;
border: 1px solid rgba(255,255,244,0.6);
border-radius: 3px;
background: rgba(255,255,244,0.12);
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 0.85em;
line-height: 1.35;
text-align: center;
text-decoration: none;
}
@media (max-width: 640px) {
.nav-menu-inner .keyboard-shortcut {
display: none;
}
}
/* Table/database actions menu */
.page-action-menu {

View file

@ -199,6 +199,15 @@ class NavigationSearch extends HTMLElement {
}
});
document.addEventListener("click", (e) => {
const trigger = e.target.closest("[data-navigation-search-open]");
if (trigger) {
e.preventDefault();
trigger.closest("details")?.removeAttribute("open");
this.openMenu();
}
});
// Input event
input.addEventListener("input", (e) => {
this.handleSearch(e.target.value);
@ -390,7 +399,9 @@ class NavigationSearch extends HTMLElement {
const dialog = this.shadowRoot.querySelector("dialog");
const input = this.shadowRoot.querySelector(".search-input");
dialog.showModal();
if (!dialog.open) {
dialog.showModal();
}
input.value = "";
input.focus();

View file

@ -20,7 +20,7 @@
<body class="{% block body_class %}{% endblock %}">
<div class="not-footer">
<header class="hd"><nav>{% block nav %}{% block crumbs %}{{ crumbs.nav(request=request) }}{% endblock %}
{% set links = menu_links() %}{% if links or show_logout %}
{% set links = menu_links() %}
<details class="nav-menu details-menu">
<summary><svg aria-labelledby="nav-menu-svg-title" role="img"
fill="currentColor" stroke="currentColor" xmlns="http://www.w3.org/2000/svg"
@ -29,19 +29,18 @@
<path fill-rule="evenodd" d="M1 2.75A.75.75 0 011.75 2h12.5a.75.75 0 110 1.5H1.75A.75.75 0 011 2.75zm0 5A.75.75 0 011.75 7h12.5a.75.75 0 110 1.5H1.75A.75.75 0 011 7.75zM1.75 12a.75.75 0 100 1.5h12.5a.75.75 0 100-1.5H1.75z"></path>
</svg></summary>
<div class="nav-menu-inner">
{% if links %}
<ul>
<li><button type="button" class="button-as-link" data-navigation-search-open>Jump to... <kbd class="keyboard-shortcut" aria-hidden="true" title="Keyboard shortcut: press / to open Jump to">/</kbd></button></li>
{% for link in links %}
<li><a href="{{ link.href }}">{{ link.label }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% if show_logout %}
<form class="nav-menu-logout" action="{{ urls.logout() }}" method="post">
<button class="button-as-link">Log out</button>
</form>{% endif %}
</div>
</details>{% endif %}
</details>
{% if actor %}
<div class="actor">
<strong>{{ display_actor(actor) }}</strong>

View file

@ -12,6 +12,7 @@ Unreleased
- Dropped Janus as a dependency, previously used to manage the write queue. This should not have any impact on plugin developers or end-users. (:issue:`1752`)
- Fixed a bug where stale tables and other related resources were not removed from ``catalog_*`` tables when a database was removed. (:issue:`2723`)
- Fixed a Safari bug with the table search mechanism triggered by pressing ``/``. (:issue:`2724`)
- New "Jump to..." menu item, always visible, for triggering the previously undocumented ``/`` menu. (:issue:`2725`)
.. _v1_0_a29:

View file

@ -1008,10 +1008,22 @@ async def test_navigation_menu_links(
kwargs["actor"] = {"id": actor_id}
html = (await ds_client.get("/", **kwargs)).text
soup = Soup(html, "html.parser")
details = soup.find("nav").find("details")
details = soup.find("nav").find("details", {"class": "nav-menu"})
assert details is not None
search_button = details.find("button", {"data-navigation-search-open": True})
assert search_button is not None
assert search_button.text.strip() == "Jump to... /"
assert search_button.find("kbd", {"class": "keyboard-shortcut"}).text == "/"
assert search_button.find("kbd")["aria-hidden"] == "true"
assert (
search_button.find("kbd")["title"]
== "Keyboard shortcut: press / to open Jump to"
)
assert details.find("li").find("button") == search_button
if not actor_id:
# Should not show a menu
assert details is None
# The app menu is always visible, but anonymous users do not see logout
# or debug links.
assert details.find("form") is None
return
# They are logged in: should show a menu
assert details is not None