feat(viewer): compact top bar, unified status strip, single-master icon pipeline#255
Merged
Conversation
Top bar + layout: - Apply the dormant .nv-form-vscode density tokens to the VS Code webview so the bar is 36px instead of the 48px :root default; the brand mark keeps its size, only the space above/below it shrinks. - New shared StatusBar merges the image-metadata line (was under the bar) and the crosshair mm readout (was a separate footer) into one slim bottom strip across the vscode/pwa/desktop/streamlit hosts. - Size the canvas off a ResizeObserver on its container instead of only window.onresize, and use flex-1/min-h-0 (not h-full), so a menu-bar reflow no longer leaves a stale, oversized canvas with scrollbars on both axes. Icons: - One committed master, branding/niivue-icon.png, drives every app icon via scripts/generate-icons.mjs (pnpm generate:icons): transparent neon mark for the file-type and in-app viewer icons, opaque for marketplace/PWA. - Generated binaries are gitignored and rebuilt by each app's build; the one committed generated file, niivue-logo.ts, stamps the master's sha256 so CI catches drift without a non-reproducible byte-compare. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
🚀 PWA Preview DeploymentYour PWA preview has been deployed! Preview URL: https://niivue.github.io/niivue-vscode/pr-255/ This preview will be updated automatically when you push new commits to this PR. |
Contributor
Coverage ReportOverall line coverage: 42.9% (+0.1) vs
|
…sBar The global mm readout is owned by the first selected canvas. NiiVue's initial onLocationChange can fire before a Menu effect initializes selection to [0], which left the readout blank until the next crosshair move. Fall back to canvas 0 owning it when selection is empty so it populates immediately on load. Add a StatusBar unit test covering mm reactivity and metadata rendering. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…llbars The hidden width-measurement twin (.nv-bar-measure) is absolutely positioned and holds every menu item at natural width. On viewports narrower than the full menu it extended past the edge and inflated the document scroll area, producing page scrollbars (a horizontal one that cascades to vertical via the root w-screen). Cap its box to the bar and clip the overflow; the proxies keep flex-shrink:0 so their measured widths stay natural and the adaptive overflow collapse is unchanged. Verified in the PWA at a narrow viewport: document horizontal overflow drops from 410px to 0 with the More menu still collapsing correctly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
🧹 PWA Preview CleanupThe preview deployment for this PR has been removed. |
korbinian90
added a commit
that referenced
this pull request
Jun 20, 2026
Reconcile #255 (compact top bar, unified StatusBar, single-master icon pipeline) with the @niivue/niivue v1.0 core migration. Resolution: - Menu.tsx import conflict: #255 moved the image-metadata line out of the menu into the new shared StatusBar, dropping getMetadataString / getNumberOfPoints from Menu. The migration had separately changed the multi-echo check from the removed nv.volumes[0].getImageMetadata() method to the v1 utility getImageMetadata(vol). Resolved by keeping only the still-used getImageMetadata import. - StatusBar (new in #255) calls getMetadataString(nv) / getNumberOfPoints(nv); both keep the same nv signature post-migration, now reading matrix/voxel size off the NIfTI header and mesh size off positions (v1) rather than the removed 0.x accessors. StatusBar wiring in App.tsx is unchanged from main. - Container.tsx, Volume.tsx, the three app package.json, and pnpm-lock.yaml auto-merged cleanly. Verified (forced, uncached): turbo type-check 8/8, turbo build 8/8, @niivue/react 160 unit tests pass (incl. StatusBar 2/2). The streamlit python test fails only on a missing local pytest (env, pre-existing). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related improvements to the viewer chrome, plus the icon-pipeline modernization that motivated them. Addresses the VS Code feedback that the top bar took too much vertical space and the file-type / viewer icons were still on the old scheme.
Top bar and layout
.nv-form-vscodedensity tokens existed intokens.cssbut were never applied, so the webview was stuck on the airy 48px:rootvalue. This wires the class onto the webview root, dropping the bar to 36px. The 26px brand mark is unchanged; only the empty space above and below it shrinks.StatusBar(packages/niivue-react) merges the image-metadata line (matrix/voxel size, formerly under the bar) and the crosshairmmreadout (formerly a standalone footer) into one slim bottom strip. Used by the VS Code, PWA, desktop, and Streamlit hosts; each keeps its existinghideUIgating.window.onresizeonly, so a menu-bar reflow (overflow into "More", the status strip toggling) changed the available height with no resize event and left a stale, oversized canvas with scrollbars on both axes. It now observes its container with aResizeObserver, and the container isflex-1 min-h-0instead offlex-grow h-full.Icons (one committed master, generate the rest)
branding/niivue-icon.png, viascripts/generate-icons.mjs(pnpm generate:icons). The file-type icons (VS Code Explorer/tab, Jupyter) and the in-app viewer logo become a transparent neon mark (luminance-keyed, so the glow falls off cleanly); the marketplace and PWA icons stay opaque on the dark tile. Outputs are palette-quantized for size (the PWAlogo.pngdropped 265KB to 118KB).turbo builddoes not race). Tauri's multi-format.icns/.icoare produced by the Tauri CLI inbeforeBuildCommand.niivue-logo.ts(imported from@niivue/reactsource, so gitignoring it would breaktsc/vitest ordering). It is markedlinguist-generatedand stamps the master'ssha256; CI fails if the master changes withoutpnpm generate:icons. That is a content check, not a byte-compare of the palette PNG, which is not reproducible across platforms.Testing
@niivue/reacttype-check + lint clean; 142/142 unit tests pass.pnpm --filter niivue buildandpnpm --filter @niivue/pwa build: both regenerate their icons from the master and compile (the PWA also regenerates all favicons / apple-touch / maskable via pwa-assets).pnpm install --frozen-lockfileclean.Notes for the reviewer
tauri build, needs Rust) or Jupyter (needs JupyterLab + Python) bundle builds locally. Their icon wiring follows the standard hook points (beforeBuildCommand,build:assets); please confirm a desktop bundle and a jupyter build on a machine with those toolchains.devis intentionally left without icon regeneration (it would re-runtauri iconon every start); runpnpm generate:icons:taurionce after a fresh clone if the dev window wants its icon.🤖 Generated with Claude Code