Skip to main content

Design State Subscriptions

Use kittl.designStore.subscribe() to react to real-time changes in the design state — object properties, board configuration, group structures, 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.designStore.subscribe(
['objects.obj-id.width'],
(width) => {
console.log('width:', width);
}
);

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.designStore.subscribe(
[
'objects.obj-id.left',
'objects.obj-id.top',
'objects.obj-id.fill',
],
(left, top, fill) => {
console.log('position:', left, top);
console.log('fill:', fill);
}
);

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.designStore.subscribe(
['objects.obj-id.width'],
(width) => console.log(width)
);

// Later, when done:
unsub();

Valid Paths

Each path is a dot-separated string. The first segment must be one of the top-level design state keys:

KeyDescription
objectsAll design objects (shapes, text, images, etc.)
boardsArtboards and board-like containers
boardsIndicesBoard ordering indices
groupStructuresGroup/layer hierarchy
groupStructuresIndicesGroup ordering indices
configDesign-level configuration (title, DPI, etc.)

You can drill into nested properties using dot notation:

objects.obj-id.width
objects.obj-id.fill
config.title
boards.board-id.floating

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. This happens when an object is deleted, hasn't been created yet, or the path is deeper than the current state tree. Always account for undefined.

const unsub = await kittl.designStore.subscribe(
['objects.obj-id.width'],
(width) => {
if (width === undefined) {
console.log('Object does not exist (yet)');
return;
}
console.log('width:', width);
}
);

Example: Sync a UI Panel with Object Size

function watchObjectSize(objectId: string) {
return kittl.designStore.subscribe(
[`objects.${objectId}.width`, `objects.${objectId}.height`],
(width, height) => {
if (width === undefined || height === undefined) return;
updateSizePanel(width, height);
}
);
}

const unsub = await watchObjectSize('shape-123');

// Tear down when the panel closes
unsub();