Rework app-shell layout
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
// Wires the header-right [ACTIONS] dropdown. The buttons inside keep calling
|
||||
// the existing page/actions.js handlers (newPage / movePage / deletePage) and
|
||||
// the ?edit link, so the N/E/M keyboard shortcuts continue to work whether or
|
||||
// not the menu is open. Toggling reuses the generic wireDropdown mechanism
|
||||
// (global-shortcuts.js), which also handles outside-click / Escape close.
|
||||
(function () {
|
||||
var trigger = document.querySelector('[data-action="page-actions"]');
|
||||
if (!trigger || typeof wireDropdown !== 'function') return;
|
||||
wireDropdown(trigger);
|
||||
var menu = trigger.parentElement.querySelector('.dropdown-menu');
|
||||
if (!menu) return;
|
||||
// Keep aria-expanded in sync with the menu's open state.
|
||||
trigger.addEventListener('click', function () {
|
||||
trigger.setAttribute('aria-expanded', menu.classList.contains('is-open') ? 'true' : 'false');
|
||||
});
|
||||
})();
|
||||
+19
-12
@@ -1,5 +1,23 @@
|
||||
{{define "headScripts"}}<script src="/_/page/actions.js"></script>{{end}}
|
||||
|
||||
{{define "headerActions"}}{{if .CanEdit}}
|
||||
<span class="dropdown">
|
||||
<button type="button" class="btn" data-action="page-actions" aria-haspopup="true" aria-expanded="false" title="Page actions">ACTIONS</button>
|
||||
<div class="dropdown-menu align-right">
|
||||
<button class="btn btn-block" onclick="newPage()" title="New page (N)">NEW PAGE</button>
|
||||
<a class="btn btn-block" href="?edit" title="Edit page (E)">EDIT PAGE</a>
|
||||
<button class="btn btn-block" data-companion-reveal hidden title="Reveal in file manager">REVEAL ON CLIENT</button>
|
||||
{{if not .IsRoot}}
|
||||
<button class="btn btn-block" onclick="movePage()" title="Move page (M)">MOVE PAGE</button>
|
||||
{{end}}
|
||||
{{if not .IsRoot}}
|
||||
<button class="btn btn-block danger" onclick="deletePage()" title="Delete page">DELETE PAGE</button>
|
||||
{{end}}
|
||||
</div>
|
||||
</span>
|
||||
<script src="/_/page/header-actions.js"></script>
|
||||
{{end}}{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
{{if .Content}}
|
||||
<div class="content">{{.Content}}</div>
|
||||
@@ -49,15 +67,4 @@
|
||||
<script src="/_/page/sidebar-fab.js"></script>
|
||||
{{end}}
|
||||
|
||||
{{define "sidebar"}}{{if .CanEdit}}<nav class="actions panel panel-sidebar">
|
||||
<div class="panel-header">ACTIONS</div>
|
||||
<button class="btn btn-block" onclick="newPage()" title="New page (N)">NEW PAGE</button>
|
||||
<a class="btn btn-block" href="?edit" title="Edit page (E)">EDIT PAGE</a>
|
||||
<button class="btn btn-block" data-companion-reveal hidden title="Reveal in file manager">REVEAL ON CLIENT</button>
|
||||
{{if not .IsRoot}}
|
||||
<button class="btn btn-block" onclick="movePage()" title="Move page (M)">MOVE PAGE</button>
|
||||
{{end}}
|
||||
{{if not .IsRoot}}
|
||||
<button class="btn btn-block danger" onclick="deletePage()" title="Delete page">DELETE PAGE</button>
|
||||
{{end}}
|
||||
</nav>{{end}}{{if .SidebarWidget}}{{.SidebarWidget}}{{end}}{{end}}
|
||||
{{define "sidebar"}}{{if .SidebarWidget}}{{.SidebarWidget}}{{end}}{{end}}
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
// Mobile: the right-rail FAB is stacked ABOVE the tree FAB and opens the right
|
||||
// rail (TOC + page widgets) in the full-viewport Overlay (overlay.js). It only
|
||||
// appears when the rail actually has content — runs after toc.js has had a
|
||||
// chance to populate the rail (script order in page/main.html), so an
|
||||
// otherwise-empty rail shows no FAB. Hidden on desktop by .fab CSS.
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
var aside = document.querySelector("aside.sidebar");
|
||||
if (!aside || !aside.children.length) return;
|
||||
|
||||
var fab = document.createElement("button");
|
||||
fab.type = "button";
|
||||
fab.className = "btn btn-fab fab";
|
||||
fab.title = "Menu";
|
||||
fab.setAttribute("aria-label", "Menu");
|
||||
fab.setAttribute("aria-expanded", "false");
|
||||
fab.className = "btn btn-fab fab fab-rail";
|
||||
fab.title = "Contents";
|
||||
fab.setAttribute("aria-label", "Contents");
|
||||
fab.textContent = "≡";
|
||||
fab.addEventListener("click", function () {
|
||||
var open = aside.classList.toggle("is-open");
|
||||
fab.setAttribute("aria-expanded", open ? "true" : "false");
|
||||
});
|
||||
aside.addEventListener("click", function (e) {
|
||||
if (e.target.tagName === "A") {
|
||||
aside.classList.remove("is-open");
|
||||
fab.setAttribute("aria-expanded", "false");
|
||||
}
|
||||
if (typeof openOverlay === "function") openOverlay(aside);
|
||||
});
|
||||
document.body.appendChild(fab);
|
||||
});
|
||||
|
||||
+2
-1
@@ -28,6 +28,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
});
|
||||
nav.appendChild(list);
|
||||
|
||||
// Stack the TOC on top of any server-rendered widget(s) already in the rail.
|
||||
var rail = document.querySelector("aside.sidebar");
|
||||
rail.appendChild(nav);
|
||||
rail.insertBefore(nav, rail.firstChild);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user