Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
57 lines
1.9 KiB
JavaScript
57 lines
1.9 KiB
JavaScript
// Adaptive sizing from the CONTAINER, not the viewport.
|
|
//
|
|
// v4's media bin got this right and nothing else used it: a panel that is 280px
|
|
// wide should lay out like a 280px panel whether the window is 1200px or 3000px.
|
|
// The column ratios there were hand-tuned (92/44/29/21 cqw) and drifted from the
|
|
// gaps they were meant to account for; here they are derived.
|
|
|
|
export const AUTO = 0;
|
|
export const MAX_COLS = 4;
|
|
|
|
/**
|
|
* Cell width for `cols` columns inside a container, as a cqw percentage,
|
|
* accounting for the gaps between them. cols = 0 means "as many as fit".
|
|
*/
|
|
export function cellWidth(cols, gapPercent = 2.5) {
|
|
if (!Number.isInteger(cols) || cols < 1) return null; // auto
|
|
const gaps = (cols - 1) * gapPercent;
|
|
return Math.max(1, Number(((100 - gaps) / cols).toFixed(2)));
|
|
}
|
|
|
|
/** The CSS value for `--cell` at a given column count. */
|
|
export function cellExpression(cols) {
|
|
const pct = cellWidth(cols);
|
|
return pct === null
|
|
? "clamp(var(--cell-thumb), 46cqw, var(--cell-panel))"
|
|
: `${pct}cqw`;
|
|
}
|
|
|
|
export function normaliseCols(value) {
|
|
const n = Number(value);
|
|
if (!Number.isFinite(n)) return AUTO;
|
|
return Math.min(MAX_COLS, Math.max(AUTO, Math.trunc(n)));
|
|
}
|
|
|
|
/** Apply a column choice to a grid host. */
|
|
export function applyDensity(host, cols) {
|
|
const n = normaliseCols(cols);
|
|
host.dataset.cols = String(n);
|
|
host.style.setProperty("--cell", cellExpression(n === AUTO ? null : n));
|
|
return n;
|
|
}
|
|
|
|
// Per-viewer convenience, not state anything depends on: a browser that refuses
|
|
// storage should still get a working grid.
|
|
export function rememberCols(id, cols) {
|
|
try { localStorage.setItem(`cx.density.${id}`, String(normaliseCols(cols))); } catch { /* private mode */ }
|
|
}
|
|
|
|
export function recallCols(id, fallback = AUTO) {
|
|
try {
|
|
const raw = localStorage.getItem(`cx.density.${id}`);
|
|
return raw === null ? fallback : normaliseCols(raw);
|
|
} catch {
|
|
return fallback;
|
|
}
|
|
}
|