Skip to content

#705 - add LV Battery voltage tile to eFuses page - #707

Merged
bracyw merged 12 commits into
developfrom
705-lv-battery-tile
Sep 6, 2026
Merged

bracyw merged 12 commits into
developfrom
705-lv-battery-tile

Conversation

@bracyw

@bracyw bracyw commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Changes

Adds a reusable read-only "Quick view" status bar to the eFuses page: a right-edge pop-out, sticky to the top-right, that auto-opens and collapses to an edge handle. On it sits an LV Battery chip showing live voltage from VCU/LV/voltage with a status dot driven purely by the firmware fault flag (VCU/Faults/Non-Critical/LV_LOW_VOLTAGE_FAULT), never a hardcoded voltage cutoff. This is the physical LV battery, distinct from the LV eFuse card at VCU/eFuses/LV/Voltage.

The bar projects chips via ng-content and lives at src/components/status-bar; the chip is page-local. Frontend-only — telemetry ingest is schemaless, so no scylla-server, Charybdis, or Siren change.

Notes

The pop-out animates with a clip-path wipe rather than a transform. An earlier translateX(100%) slide put the panel past the right edge during the animation; transformed boxes contribute scrollable overflow, and the post-toggle focus() then scrolled the document to reach the off-screen control. The whole page jumped sideways and eased back over the 200ms animation — 193px at 1440 wide, 268px at 900 where the eFuse grid already scrolls. Animating clip-path keeps the box at its final position, so there is nothing to overflow and nothing to scroll toward. Focus also moves with preventScroll, since moving focus into a passive status surface should never move the page; a spec covers that.

The voltage uses tabular figures. The panel is shrink-to-fit and right-anchored, so proportional digits re-flowed it on every telemetry update.

Icon sizes and dock radii are set per control through custom properties, so the shared box is declared once while the handle stays visually heavier than the in-panel chevron.

Accessibility and theming: the fault is announced by an aria-label on the status dot rather than colour alone, both controls carry visible focus rings, focus moves to the successor control on toggle, the animation respects prefers-reduced-motion, and colours come from shared theme tokens.

Test Cases

  • Open by default, top-right, with live voltage and a green dot; pins to the corner while the eFuse cards scroll beneath.
  • Collapse and re-open via the chevron and edge handle, with focus following to whichever control is now on screen.
  • Toggling does not move the page: scroll offset and document scroll width are unchanged across the whole animation, measured frame by frame at 1440 and 900 wide.
  • Panel width holds steady across a run of live voltage updates.
  • Chip stays on one line down to 680 wide.
  • Fault raised: dot turns red and its accessible label changes, independent of the voltage reading.
  • Unit specs cover chip formatting and placeholder, the fault label, and status bar toggle, projection, and focus behaviour. Build, lint, prettier, and ng test green.

Screenshots

Quick View Tab (not popped out)
image

Quick View Popped out
image

Quick View Popped Out during scroll
image

Page shift on open, before and after the clip-path fix

screenshot pending

Checklist

It can be helpful to check the Checks and Files changed tabs.
Please review the contributor guide and reach out to your Tech Lead if anything is unclear.
Please request reviewers and ping on slack only after you've gone through this whole checklist.

  • All commits are tagged with the ticket number
  • No linting errors / newline at end of file warnings
  • All code follows repository-configured prettier formatting
  • No merge conflicts
  • All checks passing
  • Screenshots of UI changes (see Screenshots section)
  • Remove any non-applicable sections of this template
  • Assign the PR to yourself
  • No package-lock.json changes (unless dependencies have changed)
  • Request reviewers & ping on Slack
  • PR is linked to the ticket (fill in the closes line below)

Closes #705.

@bracyw bracyw self-assigned this Jul 13, 2026
bracyw and others added 7 commits July 19, 2026 11:19
Group the duplicated declarations rather than repeating them per selector:

- .side-handle / .panel share the right-edge dock block (position, surface,
  border, radius); radii unified onto --border-radius-panel
- .side-handle / .panel-collapse share the icon-button block, hover overlay,
  and focus ring; drops the hardcoded #383838 in favour of the
  rgba(255, 255, 255, 0.08) overlay already used elsewhere in the repo
- one mat-icon sizing rule at 24px replaces two three-magic-number rules
- reduced-motion inverted to `reduce` / animation: none so the animation
  sits on .panel

Chip: drop the .top wrapper (inline spans baseline-align for free), share
the .unit / .subtitle typography, drop max-width: 25vw, which could not
clamp inline-flex content and instead wrapped "LV BATTERY" onto two lines
below ~700px viewport.

Token fix: var(--font-size-sm, 12px) rendered 14px, since the fallback only
applies when the token is undefined. Labels now use --font-size-xs (12px),
matching live-value-strip.

Declarations: status-bar 74 -> 54, lv-battery-chip 32 -> 24.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Utoutip62kYoA7GfTstVn
The slide-in keyframe starts the panel at translateX(100%), past the right
edge, and transformed boxes add scrollable overflow. focus() then ran on that
first frame and scrolled the document right to reach the off-screen control,
so the whole page jumped ~193px sideways and eased back over the 200ms
animation. Measured: scrollLeft 0 -> 193, scrollWidth 1440 -> 1633 (268px at a
900px viewport).

Focus with preventScroll, and clip the host's horizontal overflow so the
keyframe stops creating scroll area at all. clip rather than hidden, so no
scroll container is created and the sticky positioning still works.

Also give the chip's voltage tabular figures: the panel is shrink-to-fit and
right-anchored, so proportional digits re-flowed it on every telemetry update.
…form

The slide-in translated the panel past the right edge, which added scrollable
overflow and gave focus() somewhere to scroll to. That needed two guards to
contain. Animating clip-path instead keeps the box at its final position for
the whole animation, so neither the overflow nor the scroll target exists and
overflow-x: clip is no longer needed.

Measured: scrollLeft stays 0 and the page adds no scroll width at 1440px and
900px, with no guard other than preventScroll, which stays as a guard because
moving focus into a passive status surface should never move the page.

Also drop font-size fallbacks that never applied (--font-size-sm is 14px
globally, not the 12px written) and derive both hover backgrounds from theme
tokens with color-mix, as indicator-light already does.
Their CSS dedup was authored against the pre-fix tree, so it kept the
translateX keyframe that caused the page to shift on open. Resolution keeps
their structure and re-applies the fixes on top:

- shared dock / icon-button blocks, the reduced-motion inversion, and the
  --font-size-xs token fix: taken as-is
- max-width: 25vw removal kept; it wrapped LV BATTERY onto two lines below
  ~700px. Verified single-line at 680px
- keyframe restored to the clip-path wipe, so the panel never leaves its
  final position and the page cannot scroll to chase it
- font-variant-numeric: tabular-nums kept on the voltage
- restored values their dedup flattened without cause: 26px/22px icon sizes,
  12px/10px radii, flex: 0 0 auto on the chip icon and dot
Two rules that differed only in scale, folded into one each:

- the two mat-icon rules become one, sized by an --icon-size custom property
  set per control, so the shared box is written once and only the 26px/22px
  difference is stated
- .icon and .dot share the flex: 0 0 auto that stops either shrinking

Values are unchanged: computed collapse icon 22px, handle icon 26px, panel
radius 12px, handle radius 10px, chip subtitle single-line at 680px.

status-bar 58 -> 57 declarations (18 -> 16 blocks), chip 27 -> 26.
@bracyw
bracyw marked this pull request as ready for review September 6, 2026 21:36
@bracyw
bracyw merged commit cef1ae5 into develop Sep 6, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add LV Battery voltage tile to efuses page

3 participants