Skip to content

feat(inspector): improve DOM debug layer for Chrome devtools#14

Merged
chiefcll merged 1 commit into
mainfrom
inspector-debug-improvements
May 18, 2026
Merged

feat(inspector): improve DOM debug layer for Chrome devtools#14
chiefcll merged 1 commit into
mainfrom
inspector-debug-improvements

Conversation

@chiefcll
Copy link
Copy Markdown
Contributor

Summary

Improvements to the Inspector / DOM debug layer that solid renders alongside the WebGL output (and uses fully in DOM-render mode) to make Chrome devtools more useful for debugging TV apps.

Changes

1. Parent-handling fix in domRenderer.ts

Mirrors the fix from lightning-js/renderer#795.

  • updateNodeParent now removes the div from its DOM parent when props.parent becomes null. Previously the orphaned div stayed attached to its former parent.
  • destroy() uses parentNode?.removeChild so it's safe if the node was unparented before destruction.

The other two commits in that upstream PR (proto-chain getter walk, type=constructor.name) don't apply — solid's DOMNode defines accessors directly on the class, and the wrapping ElementNode already carries richer naming via componentName.

2. States surfaced as a DOM attribute

elementNode.ts now writes node.states to div.dataset.states whenever they change (and on initial inspector attachment). Lets you see focus/active state in the Elements panel and write rules like:

[data-states~="$focus"] { outline: 2px solid magenta }

Both writes are gated by isDev, so production WebGL paths pay no cost.

3. componentName for <Dynamic>

The jsx-locator babel plugin handles componentName for static JSX, but it can't see runtime-resolved tags. Dynamic now sets el.componentName = component for the string-component case, so dynamic intrinsics show up in the inspector with the same field.

4. Alt+click-to-log (new core/clickInspector.ts)

A small debug overlay that lets you click any rendered node in Chrome and inspect its underlying ElementNode.

  • Gated by isDev (stripped in production) + Config.debug runtime flag + event.altKey modifier.
  • Uses position-based traversal modeled on useMouse's getChildrenByPosition — finds the deepest visible child at the click point, honoring absX/absY, dimensions, alpha, and zIndex. Unlike useMouse, it skips the onEnter/onMouseClick/focus filters since any node should be inspectable.
  • Logs a structured group (element, lng, div, states, position, parent, children) and pins the node to globalThis.$el so you can chain $el.parent, $el.setFocus(), etc. in the console.
  • Lives in its own file behind initClickInspector() — single side-effecting call from elementNode.ts.

To use: set Config.debug = true, then Alt+click any node. The logged div reference in the console is clickable to reveal in the Elements panel.

Test plan

  • npm run tsc clean
  • npm test — 120/120 passing
  • Manual: enable Config.debug in an app, Alt+click various nodes, confirm correct deepest-hit selection across overlapping/zIndex'd elements
  • Manual: trigger node.states.add('$focus') and verify data-states updates live in devtools
  • Manual: render a <Dynamic component="view" /> and verify componentName="view" appears

🤖 Generated with Claude Code

- Fix unparenting bug in DOM renderer: setting `parent = null` now removes
  the div from its previous parent (mirrors lightning-js/renderer#795), and
  `destroy()` is safe if the node was unparented first.
- Sync `node.states` to `div.dataset.states` so focus/active states are
  visible in devtools and styleable via attribute selectors.
- Set `componentName` for `<Dynamic component="..." />` so runtime-resolved
  intrinsics show up in the inspector with the same field the jsx-locator
  babel plugin uses.
- Add Alt+click-to-log inspector (gated by `isDev` + `Config.debug`) that
  walks the ElementNode tree by hit-position to find the deepest visible
  child, logs its key state, and pins it to `window.$el`. Lives in a new
  `core/clickInspector.ts` with a small `initClickInspector()` entry point.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@chiefcll chiefcll merged commit 2bcd9b7 into main May 18, 2026
1 check 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.

1 participant