Skip to content

<ControlWidgets />

<ControlWidgets /> adds a Control widgets button and floating panel that lists the connected machine’s resources and lets you open interactive controls for them — the resource widgets from @viamrobotics/test-widgets used to exercise component and service APIs (jog a motor, move an arm, view a camera, and so on). Each widget you open becomes its own resizable panel.

Every resource that supports the generic DoCommand API also offers a DoCommand control — a JSON editor to send a raw command and inspect the response. For generic components and services, whose only API is DoCommand, it’s the sole control.

Which widgets are open, and where their panels sit, is remembered per machine part across reloads.

Mount <ControlWidgets /> inside <Visualizer />. It needs a connected machine to list resources:

<script lang="ts">
	import { Visualizer } from '@viamrobotics/motion-tools'
	import { ControlWidgets } from '@viamrobotics/motion-tools/plugins'
</script>

<div class="h-screen w-screen">
	<Visualizer>
		<ControlWidgets />
	</Visualizer>
</div>

Click the Control widgets button in the toolbar to open the panel, then toggle on a widget for any resource. Each opened widget appears as its own panel you can move and resize.

For advanced use — reflecting state in your own UI or opening widgets programmatically — the useControlWidgets hook exposes the plugin’s per-part store:

import { useControlWidgets } from '@viamrobotics/motion-tools/plugins'

const widgets = useControlWidgets()
MethodDescription
openFor(partID)The open widgets ({ resourceName, widgetId }) for a part.
isOpen(partID, resourceName, widgetId)Whether a specific widget is open.
setOpen(partID, resourceName, widgetId, on)Open or close a widget.
rectFor(partID, resourceName, widgetId)The saved panel geometry, if any.
saveRect(partID, resourceName, widgetId, rect)Persist a panel’s geometry.

The store is backed by local storage, so it works whether or not the panel is mounted.

  • External packages: @viamrobotics/test-widgets (supplies the widget registry) and @viamrobotics/svelte-sdk. Both are required peers of @viamrobotics/motion-tools, so they’re already installed alongside it. The plugin also uses @threlte/xr to detect an active immersive session.
  • Plugins: none required — though its registry panels hide themselves while an immersive <XR /> session is active (see Plugin dependencies).
  • Runtime: a live machine connection. Resources are resolved per part, so the plugin must be mounted within the visualizer’s scene, and the list stays empty until a machine is connected. Registry widget panels are automatically hidden while an immersive XR session is active.