From c38d9bdc4f4da72bbd4338f48d1759b243ba4489 Mon Sep 17 00:00:00 2001 From: hypercross Date: Thu, 9 Jul 2026 12:43:45 +0800 Subject: [PATCH] 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 --- src/components/journal/SheetView.tsx | 21 +++++++++++++++++++-- src/components/journal/StatsView.tsx | 9 +++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/components/journal/SheetView.tsx b/src/components/journal/SheetView.tsx index c1e1b00..eb7f6b0 100644 --- a/src/components/journal/SheetView.tsx +++ b/src/components/journal/SheetView.tsx @@ -65,8 +65,25 @@ export const SheetView: Component<{ sheetId: string }> = (props) => { container.innerHTML = ""; 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); + // 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; const dispose = createRoot((disposer) => { @@ -93,9 +110,9 @@ export const SheetView: Component<{ sheetId: string }> = (props) => { ); return ( -
+
{sheet() ? ( -
+
) : ( fallback )} diff --git a/src/components/journal/StatsView.tsx b/src/components/journal/StatsView.tsx index 3b04166..1b2f4f5 100644 --- a/src/components/journal/StatsView.tsx +++ b/src/components/journal/StatsView.tsx @@ -10,6 +10,7 @@ */ import { Component, For, createMemo, createSignal, Show } from "solid-js"; +import { useSearchParams } from "@solidjs/router"; import { useJournalStream } from "../stores/journalStream"; import { useJournalCompletions } from "./completions"; import { fullKey, modifierLabel } from "./stat-helpers"; @@ -24,8 +25,12 @@ export const StatsView: Component = () => { const values = createMemo(() => stream.stats); const sheets = createMemo(() => comp.data.statSheets); - /** Currently selected sheet id, or null for table view. */ - const [selectedSheetId, setSelectedSheetId] = createSignal(null); + /** Currently selected sheet id, or null for table view. Persisted in URL. */ + 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); /** Build a lookup: fullKey -> StatDef */