website: fixes

This commit is contained in:
nym21
2026-04-08 13:11:03 +02:00
parent 3a7887348c
commit eb75274dbf
6 changed files with 236 additions and 219 deletions
+47 -43
View File
@@ -74,6 +74,11 @@
});
});
}
let storedLayout;
try { storedLayout = localStorage.getItem("split-view"); } catch (_) {}
const isSplit = storedLayout !== "false" && window.matchMedia("(min-width: 768px)").matches;
document.documentElement.dataset.layout = isSplit ? "split" : "full";
</script>
<script type="module" src="/scripts/entry.js"></script>
@@ -88,8 +93,6 @@
</head>
<body>
<main id="main">
<div id="resize-bar"></div>
<nav id="nav" hidden></nav>
<search id="search" hidden>
@@ -109,53 +112,54 @@
<ul id="search-results"></ul>
</search>
<footer>
<fieldset id="frame-selectors">
<label
id="aside-selector-label"
for="aside-selector"
title="View sidebar"
class="md:hidden"
>
<input
type="radio"
name="frame"
id="aside-selector"
value="aside"
/>
View
</label>
<label id="nav-selector-label" for="nav-selector" title="Nav">
<input type="radio" name="frame" id="nav-selector" value="nav" />
Browse
</label>
<label
id="search-selector-label"
for="search-selector"
title="Search"
>
<input
type="radio"
name="frame"
id="search-selector"
value="search"
/>
Search
</label>
<button id="share-button" title="Share">Share</button>
<button id="theme-button" title="Invert theme">Theme</button>
<button id="pin-button" title="Unpin sidebar">Unpin</button>
</fieldset>
</footer>
</main>
<div id="resize-bar"></div>
<aside id="aside">
<div id="explorer" hidden></div>
<div id="chart" hidden></div>
<div id="table" hidden></div>
</aside>
<footer>
<fieldset id="frame-selectors">
<label
id="aside-selector-label"
for="aside-selector"
title="View sidebar"
class="full-only"
>
<input
type="radio"
name="frame"
id="aside-selector"
value="aside"
/>
View
</label>
<label id="nav-selector-label" for="nav-selector" title="Nav">
<input type="radio" name="frame" id="nav-selector" value="nav" />
Browse
</label>
<label
id="search-selector-label"
for="search-selector"
title="Search"
>
<input
type="radio"
name="frame"
id="search-selector"
value="search"
/>
Search
</label>
<button id="share-button" title="Share">Share</button>
<button id="theme-button" title="Invert theme">Theme</button>
<button id="layout-button"></button>
</fieldset>
</footer>
<div id="share-div" hidden>
<div id="share-content-div">
<img id="share-img" src="" />
+64 -83
View File
@@ -8,48 +8,49 @@ import {
} from "./panes/chart.js";
import { init as initExplorer } from "./explorer/index.js";
import { init as initSearch } from "./panes/search.js";
import { idle } from "./utils/timing.js";
import { readStored, removeStored, writeToStorage } from "./utils/storage.js";
import {
asideElement,
asideLabelElement,
bodyElement,
chartElement,
explorerElement,
frameSelectorsElement,
mainElement,
navElement,
navLabelElement,
pinButtonElement,
searchElement,
layoutButtonElement,
style,
} from "./utils/elements.js";
import { idle } from "./utils/timing.js";
const DESKTOP_QUERY = window.matchMedia("(min-width: 768px)");
let sidebarPinned = readStored("sidebar-pinned") !== "false";
const SPLIT = "split";
function updateLayout() {
const layout = DESKTOP_QUERY.matches && sidebarPinned ? "desktop" : "mobile";
document.documentElement.dataset.layout = layout;
if (layout === "desktop") {
asideElement.parentElement !== bodyElement &&
bodyElement.append(asideElement);
} else {
asideElement.parentElement !== mainElement &&
mainElement.append(asideElement);
}
const pref = readStored("split-view") !== "false";
const wasSplit = isSplit();
document.documentElement.dataset.layout =
DESKTOP_QUERY.matches && pref ? "split" : "full";
if (isSplit() !== wasSplit) syncFrame();
}
function isSplit() {
return document.documentElement.dataset.layout === SPLIT;
}
function syncFrame() {
if (isSplit()) navLabelElement.click();
else asideLabelElement.click();
}
DESKTOP_QUERY.addEventListener("change", updateLayout);
updateLayout();
pinButtonElement.addEventListener("click", () => {
sidebarPinned = !sidebarPinned;
writeToStorage("sidebar-pinned", String(sidebarPinned));
pinButtonElement.textContent = sidebarPinned ? "Unpin" : "Pin";
pinButtonElement.title = sidebarPinned ? "Unpin sidebar" : "Pin sidebar";
layoutButtonElement.addEventListener("click", () => {
writeToStorage("split-view", String(!isSplit()));
updateLayout();
if (!sidebarPinned) asideLabelElement.click();
});
function initFrameSelectors() {
@@ -101,19 +102,7 @@ function initFrameSelectors() {
}
}
asideLabelElement.click();
new IntersectionObserver((entries) => {
for (let i = 0; i < entries.length; i++) {
if (
!entries[i].isIntersecting &&
entries[i].target === asideLabelElement &&
focusedFrame == asideElement
) {
navLabelElement.click();
}
}
}).observe(asideLabelElement);
syncFrame();
}
initFrameSelectors();
@@ -206,62 +195,54 @@ onFirstIntersection(navElement, () => {
});
});
onFirstIntersection(searchElement, () => {
initSearch(options);
});
function initResizeBar() {
const bar = getElementById("resize-bar");
const key = "bar-width";
const max = () => parseFloat(style.getPropertyValue("--max-main-width")) / 100 * window.innerWidth;
function initDesktopResizeBar() {
const resizeBar = getElementById("resize-bar");
let resize = false;
let startingWidth = 0;
let startingClientX = 0;
const saved = readStored(key);
if (saved) mainElement.style.width = `${saved}px`;
const barWidthLocalStorageKey = "bar-width";
/**
* @param {number | null} width
*/
function setBarWidth(width) {
try {
if (typeof width === "number") {
mainElement.style.width = `${width}px`;
writeToStorage(barWidthLocalStorageKey, String(width));
} else {
mainElement.style.width = style.getPropertyValue(
"--default-main-width",
);
removeStored(barWidthLocalStorageKey);
}
} catch (_) {}
}
/**
* @param {MouseEvent} event
*/
function mouseMoveEvent(event) {
if (resize) {
setBarWidth(startingWidth + (event.clientX - startingClientX));
/** @param {number | null} width */
function setWidth(width) {
if (width != null) {
const clamped = Math.min(width, max());
mainElement.style.width = `${clamped}px`;
writeToStorage(key, String(clamped));
} else {
mainElement.style.width = "";
removeStored(key);
}
}
resizeBar.addEventListener("mousedown", (event) => {
startingClientX = event.clientX;
startingWidth = mainElement.clientWidth;
resize = true;
window.document.documentElement.dataset.resize = "";
window.addEventListener("mousemove", mouseMoveEvent);
bar.addEventListener("pointerdown", (e) => {
e.preventDefault();
bar.setPointerCapture(e.pointerId);
const startX = e.clientX;
const startW = mainElement.clientWidth;
document.documentElement.dataset.resize = "";
/** @param {PointerEvent} e */
function onMove(e) {
setWidth(startW + (e.clientX - startX));
}
function onUp() {
delete document.documentElement.dataset.resize;
bar.removeEventListener("pointermove", onMove);
bar.removeEventListener("pointerup", onUp);
bar.removeEventListener("pointercancel", onUp);
}
bar.addEventListener("pointermove", onMove);
bar.addEventListener("pointerup", onUp);
bar.addEventListener("pointercancel", onUp);
});
resizeBar.addEventListener("dblclick", () => {
setBarWidth(null);
});
const setResizeFalse = () => {
resize = false;
delete window.document.documentElement.dataset.resize;
window.removeEventListener("mousemove", mouseMoveEvent);
};
window.addEventListener("mouseup", setResizeFalse);
window.addEventListener("mouseleave", setResizeFalse);
bar.addEventListener("dblclick", () => setWidth(null));
}
initDesktopResizeBar();
initResizeBar();
onFirstIntersection(searchElement, () => {
initSearch(options);
});
+1 -1
View File
@@ -20,4 +20,4 @@ export const searchInput = /** @type {HTMLInputElement} */ (
);
export const searchResultsElement = getElementById("search-results");
export const frameSelectorsElement = getElementById("frame-selectors");
export const pinButtonElement = getElementById("pin-button");
export const layoutButtonElement = getElementById("layout-button");
+28 -19
View File
@@ -48,35 +48,35 @@ a {
aside {
min-width: 0;
min-height: 0;
position: relative;
/*height: 100%;*/
/*width: 100%;*/
/*overflow-y: auto;*/
flex: 1;
grid-row: 1;
grid-column: 1;
z-index: 1;
overflow: hidden;
background: var(--background-color);
html[data-layout="mobile"] & {
padding-bottom: calc(var(--main-padding) + 0.5rem);
}
html[data-layout="desktop"] & {
html[data-layout="split"] & {
grid-column: 2;
grid-row: 1 / -1;
border-left: 1px;
order: 2;
}
body > &[hidden] {
display: block !important;
&[hidden] {
display: block !important;
}
}
}
body {
font-weight: var(--font-weight-base);
height: 100dvh;
display: flex;
flex-direction: column;
display: grid;
grid-template-rows: 1fr auto;
grid-template-columns: 1fr;
position: relative;
html[data-layout="desktop"] & {
flex-direction: row;
html[data-layout="split"] & {
grid-template-columns: minmax(min-content, auto) 1fr;
html[data-display="standalone"] & {
border-top: 1px;
@@ -267,14 +267,23 @@ summary {
}
}
html[data-layout="desktop"] .md\:hidden {
html[data-layout="split"] .full-only {
display: none !important;
}
#pin-button {
#layout-button {
@media (max-width: 767px) {
display: none;
}
&::after {
content: "Split";
}
html[data-layout="split"] &::after {
content: "Full";
}
}
[data-resize] {
+95 -72
View File
@@ -1,7 +1,9 @@
main {
order: 1;
grid-row: 1;
grid-column: 1;
position: relative;
display: flex;
min-height: 0;
&::before,
&::after {
@@ -34,16 +36,13 @@ main {
);
}
html[data-layout="mobile"] & {
flex: 1;
min-height: 0;
html[data-layout="full"] & {
width: 100% !important;
}
html[data-layout="desktop"] & {
min-width: 300px;
width: var(--default-main-width);
max-width: 65dvw;
html[data-layout="split"] & {
min-width: 100%;
max-width: var(--max-main-width);
}
> nav,
@@ -57,85 +56,109 @@ main {
flex-direction: column;
padding-bottom: var(--bottom-area);
}
}
> footer {
#resize-bar {
display: none;
grid-column: 1;
grid-row: 1 / -1;
justify-self: end;
width: 8px;
margin: 0 -4px;
z-index: 50;
position: relative;
cursor: col-resize;
touch-action: none;
&::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
text-transform: uppercase;
z-index: 100;
padding-bottom: var(--main-padding);
left: 50%;
width: 2px;
translate: -50% 0;
background: transparent;
transition: background 0.15s;
}
&::before,
&::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
width: var(--main-padding);
z-index: 1;
pointer-events: none;
}
&::before {
left: 0;
background-image: linear-gradient(
to left,
transparent,
var(--background-color)
);
}
&:hover {
background: var(--border-color);
&::after {
right: 0;
background-image: linear-gradient(
to right,
transparent,
var(--background-color)
);
}
> fieldset {
display: flex;
gap: 1.125rem;
overflow-x: auto;
scrollbar-width: thin;
min-width: 0;
margin: -0.5rem 0;
padding: 0.5rem var(--main-padding);
pointer-events: auto;
> label,
> button {
flex-shrink: 0;
}
> button {
color: var(--off-color);
}
background: var(--color);
}
}
> #resize-bar {
display: none;
html[data-resize] &::after {
background: var(--color);
}
html[data-layout="split"] & {
display: block;
}
}
footer {
grid-row: 2;
grid-column: 1 / -1;
position: relative;
z-index: 2;
min-width: 0;
overflow: hidden;
text-transform: uppercase;
padding-bottom: var(--main-padding);
html[data-layout="split"] & {
grid-column: 1;
}
&::before,
&::after {
content: "";
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 4px;
margin: 0 -2px;
z-index: 50;
width: var(--main-padding);
z-index: 1;
pointer-events: none;
}
html[data-resize] &,
&:hover {
border-right: 4px;
cursor: col-resize;
border-color: var(--off-color) !important;
&::before {
left: 0;
background-image: linear-gradient(
to left,
transparent,
var(--background-color)
);
}
&::after {
right: 0;
background-image: linear-gradient(
to right,
transparent,
var(--background-color)
);
}
> fieldset {
display: flex;
gap: 1.125rem;
overflow-x: auto;
scrollbar-width: thin;
min-width: 0;
margin: -0.5rem 0;
padding: 0.5rem var(--main-padding);
pointer-events: auto;
> label,
> button {
flex-shrink: 0;
}
html[data-layout="desktop"] & {
display: block;
> button {
color: var(--off-color);
}
}
}
+1 -1
View File
@@ -55,6 +55,6 @@
}*/
--negative-main-padding: calc(-1 * var(--main-padding));
--font-weight-base: 400;
--default-main-width: 25rem;
--max-main-width: 70dvw;
--bottom-area: 69vh;
}