PluginContext
Plugin components and callbacks receive the base Context plus the plugin-specific properties documented below.
PluginContext is received by:
- InitComponent - as props
- API methods - as the first argument
- Panel render components - as props
- Control render components - as props
- Button callbacks (
onClick,enableWhen,hiddenWhen,excludeWhen,pressedWhen) - as an argument (onClickreceives event first, context second)
Base Context Properties
See Context for the following properties available to all contexts:
appConfig- Application configurationappState- Current application stateiconRegistry- Icon registrymapProvider- Map provider instancemapState- Current map stateservices- Core services
Plugin-Specific Properties
pluginConfig
- Type:
Object
Plugin-specific configuration. Contains all properties from the PluginDescriptor except id and load.
When using the factory function pattern, any options passed to the factory become available here:
// When registering:createScaleBarPlugin({ units: 'imperial' })
// Within the plugin:const { units } = context.pluginConfigSee Creating a Plugin Descriptor for the full pattern.
pluginState
- Type:
Object
Plugin-specific state managed by the plugin's reducer, plus utilities for updating state.
{ // State values from your reducer's initialState isActive: false,
// Dispatch function for updating plugin state dispatch: ({ type, payload }) => { /* ... */ }}// Access stateconst { isActive } = context.pluginState
// Update statecontext.pluginState.dispatch({ type: 'setActive', payload: true })setExclusiveControl
- Type:
(value: boolean | string | null) => void
Available to plugin components (InitComponent, panel and control render components) as a prop.
Tells the app that your plugin has taken control of the interface, e.g. while a search form is expanded. You don't pass your plugin's id: it's added for you.
setExclusiveControl(true)addsim-o-app--exclusive-control-{pluginId}to the app root.setExclusiveControl('some-name')addsim-o-app--exclusive-control-{pluginId}--some-nameinstead. The name is used as-is, so pass something class-safe.setExclusiveControl(false)(ornull/undefined) releases your claim.
Only one class is ever present, for the most recent claim. Claims stack: if another plugin claims control while yours holds it, its class replaces yours, and when it releases, your class comes back. Releasing only removes your own claim, so it never affects another plugin's. Each plugin holds one claim at a time, so claiming with a new name replaces your previous one rather than stacking on it. Release in your effect's cleanup too, so a claim isn't left behind if your component unmounts.
Your plugin's own CSS decides what to hide in response, so it can pick what suits its focus behaviour. For example, it could use opacity: 0 to keep hidden buttons in the tab order, or display: none to free up their space.
// Claim while expanded; release when collapsed or unmounteduseLayoutEffect(() => { setExclusiveControl(isExpanded) return () => setExclusiveControl(false)}, [isExpanded]).im-o-app--exclusive-control-my-plugin { .im-o-app__right .im-c-button-wrapper { display: none; }}