Skip to main content
Version: 0.0.4

App State Subscriptions

Use kittl.appStore.subscribe() to react to real-time changes in the app state — selection changes, active tool switches, viewport updates, and more.

Subscribing to a Single Property​

Pass an array with one path and a callback that receives the current value.

const unsub = await kittl.appStore.subscribe(
['selectedObjectsIds'],
(ids) => {
console.log('selected:', ids);
}
);

Subscribing to Multiple Properties​

Pass multiple paths in the array. The callback receives one argument per path, in the same order.

const unsub = await kittl.appStore.subscribe(
[
'selectedObjectsIds',
'activeTool',
'viewport',
],
(ids, tool, viewport) => {
console.log('selection:', ids);
console.log('tool:', tool);
console.log('viewport:', viewport);
}
);

The callback fires whenever any of the subscribed values changes.

Unsubscribing​

subscribe() returns an unsubscribe function. Call it when you no longer need updates.

const unsub = await kittl.appStore.subscribe(
['selectedObjectsIds'],
(ids) => console.log(ids)
);

// Later, when done:
unsub();

Valid Paths​

Each path is a dot-separated string. Common top-level app state keys include the following. See AppState for the full state shape:

KeyDescription
selectedObjectsIdsIDs of top-level selected objects
selectedLayersIdsIDs of selected layers
selectedArtboardIdsIDs of selected artboards
selectedArtboardsObjectIdsObject IDs within selected artboards
allSelectedObjectsIdsAll selected IDs including nested groups
canvasModeCurrent canvas mode ("erase", "crop", "inpaint", etc.)
activeToolCurrently active tool ("move", "pen", "hand", etc.)
viewportViewport position and zoom state
highlightedObjectIdID of the currently hovered object

You can drill into nested properties using dot notation:

viewport.coords.tl.x
activeTool.type

Invalid paths — empty segments, unknown top-level keys — throw an error.

Handling undefined​

A callback argument is undefined when the path doesn't resolve to a value. Always account for undefined.

const unsub = await kittl.appStore.subscribe(
['activeTool'],
(tool) => {
if (tool === undefined) {
console.log('No active tool');
return;
}
console.log('tool:', tool);
}
);

Example: React to Selection Changes​

const unsub = await kittl.appStore.subscribe(
['selectedObjectsIds'],
async (ids) => {
if (!ids || ids.length === 0) {
hidePropertiesPanel();
return;
}

// Fetch details for the first selected object
const result = await kittl.design.object.getObject({ id: ids[0] });
if (result.isOk) {
showPropertiesPanel(result.result);
}
}
);

Example: Track Viewport and Tool Together​

const unsub = await kittl.appStore.subscribe(
['viewport', 'activeTool'],
(viewport, tool) => {
if (viewport) {
updateMinimap(viewport);
}
if (tool) {
updateToolbarHighlight(tool);
}
}
);