Appearance
Save & Undo
Save and Push are separate operations with separate snapshots.
- Save persists the full config (all themes) to
figma.root.pluginData("systema_config")— file-level storage, shared across all users of the file. Does not touch Figma variables. - Push Vars is described in the previous section. It always saves the config as step 1, but the inverse isn't true — saving doesn't push.
- Undo/Redo operates on per-theme stacks. Each Save creates an undo checkpoint; Undo restores the previous saved state, Redo moves forward. Switching themes swaps stacks, so each theme's history is independent.
isDirty= current theme JSON ≠lastSavedJsons[themeId]. Disables Save when clean.isPushNeeded= current theme JSON ≠lastPushedJsons[themeId]. Disables Push Vars when clean. Re-evaluated on every theme switch (per-theme), so flipping between themes reflects each one's own push state.- Optimistic push snapshot — when Push Vars is clicked, the UI stores
pendingPushSnapshot = { themeId, themeJson }and sendsapply-paletteto the backend.lastPushedJsonsandisPushNeededare NOT updated at this moment. The backend'spush-complete { success }message decides: on success → promote the snapshot intolastPushedJsons; on cancel/abort → discard. This is why cancelling the replace-theme dialog leaves Push Vars active instead of looking like the push succeeded. - Plugin-load reconcile — on startup
handleLoadConfigposts the list of existing Figma collection names alongsideconfig-loaded. The UI checks for any Systema-shape collection name (meta,color,color/meta,color/...or legacy{prefix}/color/...). If none are present, everylastPushedJsonsentry is dropped andisPushNeededflips totrue. The backend also emits alast-pushedmessage read fromsystema_pushed; that narrows the reconcile to just the theme currently in the file. - Config is also auto-saved to pluginData at the start of every Push Vars.