Fix long names in the joystick mapping being cropped#2656
Fix long names in the joystick mapping being cropped#2656rafaellehmkuhl merged 1 commit intobluerobotics:masterfrom
Conversation
Automated PR Review (Claude)0. SummaryVerdict: MINOR SUGGESTIONS Minor items to consider: 1.1, 1.2, 4.1, 6.1 This PR fixes a longstanding issue where joystick button function names were being cropped when they exceeded the SVG viewport boundaries. The approach hides the original SVG 1. Correctness & Implementation Bugs1.1 (minor) — 1.2 (minor) — 2. AGENTS.md AdherenceNo findings. The PR does not add new dependencies, does not introduce new local-storage keys, does not add comments explaining "what" (the comments explain "why" — e.g., explaining the SVG-to-HTML coordinate conversion strategy), and the new JSDoc entries have proper 3. Security3.1 (nit) — No obfuscated or intentionally unreadable code. 3.2 — No suspicious base64/hex/encoded blobs. 3.3 — No hidden Unicode, zero-width characters, or homoglyph attacks. 3.4 — No unexpected network calls or exfiltration patterns. 3.5 — No changes to build scripts, CI workflows, Dockerfiles, or Electron main-process code. 3.6 — No 3.7 — No new dependencies added. 3.8 — No other suspicious patterns detected. No security findings. 4. Performance4.1 (minor) — resizeObserver = new ResizeObserver(() => {
requestAnimationFrame(() => {
computeOverlayPositions()
updateLabelsState()
})
})4.2 (nit) — 5. UI / UXNo findings. The approach is sound: rendering HTML overlays on top of hidden SVG text elements preserves visual position while allowing natural text wrapping. The 6. Code Quality & Style6.1 (nit) — The 6.2 (nit) — The 7. TestsNo findings. This is a UI/visual fix to an SVG overlay component. There are no existing unit tests for 8. DocumentationNo findings. This is a bug fix that doesn't change any public API or feature-parity between Lite and Standalone. No README or docs update needed. 9. Nitpicks / Optional9.1 (nit) — The 9.2 (nit) — In 9.3 (nit) — The fallback const DEFAULT_SVG_VIEWBOX_WIDTH = 1250Generated by Claude. This is advisory; a human reviewer must still approve. |
ES-Alexander
left a comment
There was a problem hiding this comment.
Nice! It makes me slightly uncomfortable to be kind of and kind of not using the SVG (😅), but it does the job and definitely improves things!
A couple of notes/questions, but nothing significant.
If I make the window narrow it seems the left side wrapping doesn't work properly:

but given the state we're coming from I don't consider that a blocker for this PR.
| * @returns {string} A CSS transform string. | ||
| */ | ||
| const labelTransform = (textAnchor: string): string => { | ||
| // SVG text y is the baseline; translate up ~70% of the line height so the visual |
There was a problem hiding this comment.
Is this literally talking about the letter "y"? If so it should be in quotes. Otherwise I think this comment is incomplete.
There was a problem hiding this comment.
Was incomplete. Fixed.
| const objectRect = objectEl.getBoundingClientRect() | ||
| const wrapperRect = wrapperRef.value.getBoundingClientRect() | ||
| const svgRoot = svg.documentElement as SVGSVGElement | ||
| const viewBoxWidth = svgRoot?.viewBox?.baseVal?.width || 1250 |
There was a problem hiding this comment.
Curious where the 1250 default comes from. Is there a variable somewhere, or is this a guess based on common screen sizes or something?
There was a problem hiding this comment.
It's the default size of our SVGs, but it's a fallback. Explained better in the code now.
Long button function names were being clipped at the SVG viewport edges because the labels lived inside the SVG as <text> elements. Hide the original SVG labels and render an HTML overlay div per button, anchored at the same screen position as the original text. The overlays live outside the SVG so they can extend beyond its bounds and wrap onto multiple lines when the function name is too long.
98b48a3 to
687b04f
Compare


Finally found an elegant solution to that.
Long button function names were being clipped at the SVG viewport edges because the labels lived inside the SVG as elements. Hide the original SVG labels and render an HTML overlay div per button, anchored at the same screen position as the original text. The overlays live outside the SVG so they can extend beyond its bounds and wrap onto multiple lines when the function name is too long.
Before:

After:

Fix #456