phone-desktop-mode: a Menu with folded sections below 1024 px
The owner, 2026-10-16: "Вариант 1. Но меню выглядит длинной простынёй. Там
бы сделать сворачивание разделов." As the mockup of e0e30e2: the bar's
navbar-menu loses is-active, so Bulma hides it below 1024 px, and the new
touchnav partial (layout.html) takes its place in the brand - Menu, a
<details> whose panel holds Overview, each group as a fold (the current
one open, its page aria-current), and the user's group last with Account,
Help and Sign out (the same POST form as the bar's). The same Show* flags
as the bar decide what is there. panel.css takes the mockup's rules (the
touch navigation, a 1rem gutter for the page and the sibling strip below
1024 px). No script.
The cause, measured, is written in the roadmap row: every width under
1024 px had the always-open menu; "desktop site" (~980 px) added Bulma's
side-by-side columns from 769 px; Bulma's container has no side margin
below 1024 px.
Tests: the Menu marks the current group and page and the bar's menu has
no is-active (TestMenuHighlightsTheCurrentGroupEntryAndSibling), it offers
nothing the bar does not to a domain administrator (TestTouchMenuFollowsTheBar),
the shell's Sign out is counted twice on the password page;
TestPanelCSSIsTheMockupStylesheet. go vet + go test (26 packages) and make
e2e on the test server for this tree. CHANGELOG [Unreleased]; roadmap row
done.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -496,9 +496,18 @@ func TestMenuHighlightsTheCurrentGroupEntryAndSibling(t *testing.T) {
|
||||
if n := strings.Count(out, "sp-current"); n != 1 {
|
||||
t.Errorf("%d current groups, want 1", n)
|
||||
}
|
||||
if n := strings.Count(out, "aria-current"); n != 1 {
|
||||
t.Errorf("%d current siblings, want 1", n)
|
||||
// The current page is marked twice: in the strip of siblings and in the
|
||||
// Menu of a narrow screen, whose current group is the one open.
|
||||
if n := strings.Count(out, "aria-current"); n != 2 {
|
||||
t.Errorf("%d current entries, want the sibling strip's and the Menu's", n)
|
||||
}
|
||||
mustContain(t, out,
|
||||
`<details class="sp-touchnav"><summary>Menu</summary>`,
|
||||
`<details class="sp-touchnav-group" open><summary>Outbound</summary>`,
|
||||
`<a href="/outbound/log" aria-current="page"><i class="ti ti-list-details"></i>Log</a>`,
|
||||
`<details class="sp-touchnav-group"><summary>Inbound</summary>`,
|
||||
`<div class="navbar-menu">`)
|
||||
mustNotContain(t, out, `navbar-menu is-active`)
|
||||
|
||||
// The user menu is a group of its own and has no sibling strip.
|
||||
out = renderShell(t, kitEngine(t), Meta{Title: "t", User: "admin", IsGlobal: true, Section: "user", Page: "account"})
|
||||
@@ -613,3 +622,18 @@ func TestPollAndOOBAttributes(t *testing.T) {
|
||||
got = partial(t, "page_head", Head{Title: "T", ID: "h", OOB: true})
|
||||
mustContain(t, got, `<div class="sp-head" id="h" hx-swap-oob="true">`)
|
||||
}
|
||||
|
||||
// The Menu of a narrow screen offers what the bar offers, no more: a domain
|
||||
// administrator has no Server group and no Overview there either.
|
||||
func TestTouchMenuFollowsTheBar(t *testing.T) {
|
||||
out := renderShell(t, kitEngine(t), Meta{Title: "t", User: "ops", Section: "outbound", Page: "domains"})
|
||||
for _, group := range []string{"Overview", "Server", "Queue", "DMARC reports"} {
|
||||
inBar := strings.Contains(out, `">`+group+`</a>`) || strings.Contains(out, `>`+group+`</a>`)
|
||||
inMenu := strings.Contains(out, `<summary>`+group+`</summary>`) || strings.Contains(out, `></i>`+group+`</a>`) || strings.Contains(out, `<a href="/overview">`+group)
|
||||
if inMenu && !inBar {
|
||||
t.Errorf("the Menu offers %s, which the bar does not", group)
|
||||
}
|
||||
}
|
||||
mustContain(t, out, `<summary><i class="ti ti-user-circle"></i>ops</summary>`, `<form method="post" action="/logout"><button type="submit"><i class="ti ti-logout"></i>Sign out</button></form>`)
|
||||
mustNotContain(t, out, `<summary>Server</summary>`)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user