Detent web components
By Shane Logsdon

Data & tables

Dependency Trace

Implemented

Interactive SVG node relationship & dependency tracer

detent-dependency-trace

Port status
Catalog status
implemented
Origin
upstream
Phase
3
Wave
phase-3-data
Group
Data & tables

4.7 KB gzip for the class module

Variants

No node has been selected yet.

Radial auto-layout with explicit placement for the job-worker node (top right), and the same graph with a larger node-size. Hovering or focusing a node traces its branch: unrelated nodes and connections dim (in colour, not opacity, so they stay above 4.5:1), the active branch takes the accent colour and the status bar reports Selected: <id>. Clicking a node, or pressing Enter/Space on a focused node, emits detent-node-select; hovering emits detent-node-hover. Sample data is local; nothing is fetched.

Recorded states

  • hover recorded state; no setter

Usage

Import

import '/components/dependency-trace/define.js';

// or register it yourself
import { DetentDependencyTrace } from '/components/dependency-trace/dependency-trace.js';

Attributes

  • node-size

Properties

  • connections
  • nodes
  • onNodeHover
  • onNodeSelect

Slots

No slots are recorded for this component.

Events

  • detent-node-select — {}
  • detent-node-hover — {}

Example

Runnable example: site/examples/dependency-trace.ts. The snippet below is generated from the catalogued attributes.

<detent-dependency-trace
  node-size="36"
></detent-dependency-trace>

Property-only values

const element = document.querySelector('detent-dependency-trace');
if (element !== null) {
  // nodes: TraceNode[]
  element.nodes = [];
  // connections: TraceConnection[]
  element.connections = [];
  // onNodeSelect: (id: string) => void
  element.onNodeSelect = () => {};
  // onNodeHover: (id: string | null) => void
  element.onNodeHover = () => {};
}

Source

The pinned upstream source for this row:

  • src/components/ui/DependencyTrace.tsx sha256 55a8700ade00…

Native files

The native module and its artifacts:

  • src/components/dependency-trace/dependency-trace.ts
  • src/components/dependency-trace/styles.css
  • src/components/dependency-trace/define.ts
  • docs/components/dependency-trace.md
  • site/examples/dependency-trace.ts
  • tests/browser/dependency-trace.spec.ts
  • evidence/components/dependency-trace.md

API

Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.

Attributes

Attributes
AttributePropertyTypeDefaultNotes
node-sizenodeSizenumber36Kebab-case attribute; camelCase property.

Properties

Properties
PropertyTypeDefaultNotes
connectionsTraceConnection[]—Property-only: assign from script; not accepted as an attribute.
nodesTraceNode[]—Property-only: assign from script; not accepted as an attribute.
onNodeHover(id: string | null) => voidundefinedProperty-only: assign from script; not accepted as an attribute.
onNodeSelect(id: string) => voidundefinedProperty-only: assign from script; not accepted as an attribute.

Events

Events
EventUpstream propPayload typeNotes
detent-node-selectonNodeSelect(id: string) => voidComposed, bubbles; fires only for a user action.
detent-node-hoveronNodeHover(id: string | null) => voidComposed, bubbles; fires only for a user action.

Slots

No slots are recorded for this component.

CSS customisation

  • React callback props become typed composed CustomEvents; programmatic state assignment emits none.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • nodes / connections default to [] instead of being required props with no default; a native element renders before its data arrives.
  • onNodeSelect / onNodeHover callbacks become the composed events detent-node-select { id } and detent-node-hover { id | null }.
  • className is replaced by documented CSS parts and custom properties.
  • The Framer-Motion scale/opacity springSnappy animations become CSS transitions and a CSS pulse; no spring token is reimplemented.
  • lucide-react is not used; the graph draws its own SVG.
  • Dimming uses colour tokens instead of opacity: 0.25 so dimmed content keeps WCAG contrast (accessibility correction).
  • Every node is keyboard reachable (role="button", tabindex="0", Enter/Space), which upstream's <g onClick> did not offer.
  • An empty nodes array renders a labelled empty state instead of a bare canvas.
  • connection.label / connection.type are accepted as plain data but are not drawn (upstream only used them for grouping/tooltips); they remain part of the documented shape so a consumer's data survives a port.

What it does

An interactive SVG dependency graph: nodes are laid out radially unless they carry explicit coordinates, hovering a node traces its branch, unrelated nodes and connections dim, and clicking or pressing Enter/Space on a node selects it.

Upstream behaviour
  • Interactive bezier curve paths with animated glow pulses on hover
  • Automatic dimming of unrelated network branches and nodes
  • Configurable node placement or radial auto-layout geometry
  • Accessible region landmark with hover & click selection telemetry
Differences from upstream
  • React callback props become typed composed CustomEvents; programmatic state assignment emits none.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • nodes / connections default to [] instead of being required props with no default; a native element renders before its data arrives.
  • onNodeSelect / onNodeHover callbacks become the composed events detent-node-select { id } and detent-node-hover { id | null }.
  • className is replaced by documented CSS parts and custom properties.
  • The Framer-Motion scale/opacity springSnappy animations become CSS transitions and a CSS pulse; no spring token is reimplemented.
  • lucide-react is not used; the graph draws its own SVG.
  • Dimming uses colour tokens instead of opacity: 0.25 so dimmed content keeps WCAG contrast (accessibility correction).
  • Every node is keyboard reachable (role="button", tabindex="0", Enter/Space), which upstream's <g onClick> did not offer.
  • An empty nodes array renders a labelled empty state instead of a bare canvas.
  • connection.label / connection.type are accepted as plain data but are not drawn (upstream only used them for grouping/tooltips); they remain part of the documented shape so a consumer's data survives a port.
Previous: Density Lens Next: Depth Corridor

Docs

Components

Project