Skip to content

State Management & Hooks

osdlabel is built on SolidJS and uses a reactive state model. State is managed via context providers and accessed through custom hooks.

osdlabel uses three internal SolidJS stores:

StoreContents
AnnotationStateAll annotations organized by image ID
UIStateActive tool, active cell, grid dimensions, grid assignments, selected annotation
ContextStateAvailable contexts and the active context ID

All of these stores are provided to the component tree via the AnnotatorProvider.

The primary hook for accessing all annotation state and actions. Must be used within an AnnotatorProvider.

import { useAnnotator } from 'osdlabel/state';
function MyComponent() {
const { annotationState, uiState, actions } = useAnnotator();
// Read state
console.log('Active tool:', uiState.activeTool);
// Mutate state using actions
return (
<button onClick={() => actions.setActiveTool('rectangle')}>
Select Rectangle Tool
</button>
);
}

You must never modify the stores directly. All mutations must go through the provided actions object returned by useAnnotator().

The actions object provides methods for:

  • Annotations: addAnnotation, updateAnnotation, deleteAnnotation, loadAnnotations
  • UI: setActiveTool, setActiveCell, setSelectedAnnotation, assignImageToCell, setGridDimensions
  • Contexts: setContexts, setActiveContext, setDisplayedContexts

A convenience hook for checking tool availability based on the active context’s constraints.

import { useConstraints } from 'osdlabel/hooks';
function MyToolbar() {
const { isToolEnabled } = useConstraints();
return (
<div>
<button disabled={!isToolEnabled('rectangle')}>Rectangle</button>
<button disabled={!isToolEnabled('circle')}>Circle</button>
</div>
);
}

Sets up keyboard shortcut handling. This is called automatically by AnnotatorProvider, so you usually don’t need to call it directly unless you are building a completely custom provider setup.

import { useKeyboard } from 'osdlabel/hooks';