feat(journal): improve sheet rendering and URL persistence

- Update SheetView to use full-width SVG and auto-height for better
  scaling
- Center template nodes in SheetView to maintain text alignment
- Enable overflow-y-auto in SheetView to support long sheets
- Persist selected sheet ID in URL search parameters in StatsView
This commit is contained in:
hypercross 2026-07-09 12:43:45 +08:00
parent fe87b1f80c
commit c38d9bdc4f
2 changed files with 26 additions and 4 deletions

View File

@ -65,8 +65,25 @@ export const SheetView: Component<{ sheetId: string }> = (props) => {
container.innerHTML = ""; container.innerHTML = "";
const parsed = parseSheet(s.svg); const parsed = parseSheet(s.svg);
// Force full-width, auto-height
parsed.svgElement.setAttribute("width", "100%");
parsed.svgElement.removeAttribute("height");
parsed.svgElement.style.display = "block";
container.appendChild(parsed.svgElement); container.appendChild(parsed.svgElement);
// Center template nodes so text stays centered as values change length
for (const tpl of parsed.templates) {
const el = tpl.el;
try {
const bbox = el.getBBox();
const cx = bbox.x + bbox.width / 2;
el.setAttribute("text-anchor", "middle");
el.setAttribute("x", String(cx));
} catch {
// getBBox may fail if the node has no layout — skip silently
}
}
if (parsed.templates.length === 0) return; if (parsed.templates.length === 0) return;
const dispose = createRoot((disposer) => { const dispose = createRoot((disposer) => {
@ -93,9 +110,9 @@ export const SheetView: Component<{ sheetId: string }> = (props) => {
); );
return ( return (
<div class="w-full h-full flex items-center justify-center p-2"> <div class="w-full h-full overflow-y-auto p-2">
{sheet() ? ( {sheet() ? (
<div ref={containerRef} class="w-full h-full" /> <div ref={containerRef} class="w-full" />
) : ( ) : (
fallback fallback
)} )}

View File

@ -10,6 +10,7 @@
*/ */
import { Component, For, createMemo, createSignal, Show } from "solid-js"; import { Component, For, createMemo, createSignal, Show } from "solid-js";
import { useSearchParams } from "@solidjs/router";
import { useJournalStream } from "../stores/journalStream"; import { useJournalStream } from "../stores/journalStream";
import { useJournalCompletions } from "./completions"; import { useJournalCompletions } from "./completions";
import { fullKey, modifierLabel } from "./stat-helpers"; import { fullKey, modifierLabel } from "./stat-helpers";
@ -24,8 +25,12 @@ export const StatsView: Component = () => {
const values = createMemo(() => stream.stats); const values = createMemo(() => stream.stats);
const sheets = createMemo(() => comp.data.statSheets); const sheets = createMemo(() => comp.data.statSheets);
/** Currently selected sheet id, or null for table view. */ /** Currently selected sheet id, or null for table view. Persisted in URL. */
const [selectedSheetId, setSelectedSheetId] = createSignal<string | null>(null); const [searchParams, setSearchParams] = useSearchParams<{ sheet?: string }>();
const selectedSheetId = () => searchParams.sheet || null;
const setSelectedSheetId = (id: string | null) => {
setSearchParams({ sheet: id || undefined });
};
const [pickerOpen, setPickerOpen] = createSignal(false); const [pickerOpen, setPickerOpen] = createSignal(false);
/** Build a lookup: fullKey -> StatDef */ /** Build a lookup: fullKey -> StatDef */