UI Primitives
Beneath the high-level panels, @oh-just-another/react-ui exports small building blocks โ buttons, controls, and hooks โ for composing your own chrome around the editor.
Primitive componentsโ
These are the low-level UI atoms used to build the toolbar and panels, and they are exported for your own layouts:
import { IconButton, ButtonGroup, SegmentedControl, Slider } from "@oh-just-another/react-ui";
<ButtonGroup ariaLabel="Tools">
<IconButton label="Zoom in" onClick={() => {}}>
+
</IconButton>
</ButtonGroup>;
IconButton and ButtonGroup cover buttons and grouped rows; SegmentedControl and Slider are a segmented toggle and a range slider. Each exports its props type (IconButtonProps, SegmentedControlProps, etc.).
Hooksโ
Hooks let custom components read editor state. Imperative hooks (useDiagram) return the live Editor without re-rendering; reactive hooks re-render on the slice they observe:
import { useDiagram, useScene, useSelection, useMode, useHistory } from "@oh-just-another/react-ui";
function StatusBar() {
const { canUndo, canRedo, undo, redo } = useHistory();
const selection = useSelection();
return <span>{selection.size} selected</span>;
}
Other slices include useLayers() / useActiveLayerId(), useAnnotations() / useSelectedAnnotation() / useSelectedLink(), and useMobileLayout(). For a custom projection, useEditorSelector(select) re-renders only when the projected value changes.
Providers and utilitiesโ
Several primitives pair with a provider or imperative API: wrap a subtree in TooltipProvider for Tooltip, in ToastHost for useToast(), and in ContextMenuControllerProvider for useContextMenuController(). PortalContainerProvider / usePortalContainer control where floating UI portals render. Tunable sizing lives in layout constants such as PALETTE_WIDTH, PROPERTY_PANEL_WIDTH, and LAYER_PANEL_WIDTH.