Skip to content
NewService Map: 30 components for hosts, ports and routes
<ln-topology>Custom elementTopologyFree

Topology editor

Editable site topology graph: traffic pixels on each link follow its measured rate, and devices or links open an inspector when selected.

View as Markdown
<ln-topology>

Trydrag a device, hold Ctrl or ⌘ and scroll to zoom, then switch on Edit and add a device.

Playground

Change a prop and the component updates. Props marked live animate to the new value; the others rebuild the element.

Loading <ln-topology>
Props
labelremounts
heightremounts
<LnTopology label="Innsbruck HQ" height={560} />

Installation

pnpm dlx shadcn@latest add @lumesec/ln-topology
First timeRegister the @lumesec registry once, or install by URL+

Adds @lumesec to your components.json:

pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json

Or skip the setup and install by URL:

npx shadcn@latest add https://elements.lumesec.ai/r/ln-topology.json

Usage

import { LnTopology } from "@/components/lumesec/ln-topology";

export function Example() {
  return (
    <LnTopology label="Innsbruck HQ" height={560} />
  );
}

Behaviour

The whole site as a graph. Device cards and links are plain interface. The pixels on each link are its traffic, downstream on one side and upstream on the other, released at a rate that follows the measured throughput. Select a device or a link to inspect it. In edit mode, drag from a card’s handle onto another card to connect them.

API reference

Attributes

labelReact proplabelTypestringDefaultInnsbruck HQ

Title shown in the toolbar. Read once when the element connects; later changes are ignored.

heightReact propheightTypenumberDefault560

Stage height in pixels. Read once when the element connects. When it is not set, stages narrower than 640px size their height to fit the graph.

Events

Events bubble and cross the shadow boundary unless the description says otherwise.

selectReact proponSelectDetail{ device: string } | { link: [string, string] }

Fires when a device or a link is selected by pointer, keyboard or the inspector's connection list, and after a device or link is added. link holds the ids of both ends. Not fired when the selection is cleared.

restartReact proponRestartDetail{ device: string }

Fires when Restart is pressed in the inspector. The device shows Restarting for about 2.6 s.

changeReact proponChangeDetail{ added: string } | { removed: string } | { linked: [string, string] } | { unlinked: [string, string] }

Fires when the graph changes: a device is added or removed, or a link is drawn or removed. Removing a device drops its links without separate unlinked events.

moveReact proponMoveDetail{ device: string, x: number, y: number }

Fires when a pointer drag of a device card ends. x and y are rounded graph coordinates. Arrow-key moves do not fire it.

Methods

Call them on the element, for example through a React ref.

fit(anim?: boolean)

Scales and centres the view so every device fits. Animates unless anim is false or reduced motion is on. Same as the Fit to view button.

tidy()

Arranges the devices as a tree from the uplinks down, then fits the view. Same as the Tidy button.

addDevice(type: "switch" | "ap" | "server" | "camera" | "storage")

Adds a device near the centre of the view, selects it and fires change with added. The device shows Adopting for 2.4 s. Works with edit mode off.

Keyboard

KeysAction
Enter / SpaceOn a focused device card: select it and open the inspector.
ArrowLeft / ArrowRight / ArrowUp / ArrowDownOn a focused device card: move it 10 px, or 40 px with Shift.
Delete / BackspaceIn edit mode: remove the focused device (internet uplinks excepted), or the selected link when no card has focus.
+ / =Zoom in, when focus is in the stage but not on a device card.
-Zoom out, when focus is in the stage but not on a device card.
0Fit the graph to the view, when focus is in the stage but not on a device card.
EscapeIn the stage: clear the selection and close the Add device menu. In the menu: close it and return focus to Add device.
ArrowDown / ArrowUpIn the Add device menu: move to the next or previous item, wrapping around.

Accessibility

  • The stage is a focusable role="application" region whose aria-label describes the keyboard controls.
  • Each device card is a role="button" with tabindex="0" and an aria-label of name, status and IP address.
  • Edit, Traffic and Rates are toggle buttons with aria-pressed. Add device has aria-haspopup="menu" and opens a role="menu" of menuitem buttons; the first item receives focus.
  • The zoom buttons are labelled Zoom out, Zoom in and Fit to view.
  • Selections are announced in a polite live region ("Selected …"). The inspector is aria-live="polite" and its rates refresh every second.
  • Links are drawn on a canvas and can be selected with a pointer only. The canvas and the legend are aria-hidden.
  • Closing the inspector returns focus to the stage.
  • Reduced motion: traffic pixels are not drawn, fit, zoom and Tidy jump without animation, and the card and inspector entrance animations are switched off; centring on a device still eases.

Theming

The element reads your shadcn theme tokens through its shadow root, so light and dark follow your theme. The accent comes from --lumesec. See Theming.

This component reads --background, --border, --card, --destructive, --foreground, --input, --lumesec, --lumesec-info, --muted and --muted-foreground.

To restyle only LumeSec elements, set the matching --ui-* overrides: --ui-accent, --ui-border, --ui-border-strong, --ui-danger, --ui-faint, --ui-fg, --ui-fg2, --ui-info, --ui-mono, --ui-muted, --ui-page, --ui-surface and --ui-track.

Notes

  • Shows built-in demo data for one site: the shared device set from the network engine (ids such as gw, core, aiop1) plus a Frankfurt DC site and three client groups. No attribute selects other data; link rates are simulated and update every second while the element is on screen.
  • Edits (moved devices, new devices and links) exist only inside the element and are lost when it is recreated.
  • Ctrl or ⌘ with the mouse wheel zooms between 30% and 220%, two pointers pinch-zoom, and dragging the background pans.
  • The React wrapper's ref is typed as the element class, so its methods can be called once the element is connected.

Was this page helpful?