Skip to content

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 sends apply-palette to the backend. lastPushedJsons and isPushNeeded are NOT updated at this moment. The backend's push-complete { success } message decides: on success → promote the snapshot into lastPushedJsons; 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 handleLoadConfig posts the list of existing Figma collection names alongside config-loaded. The UI checks for any Systema-shape collection name (meta, color, color/meta, color/... or legacy {prefix}/color/...). If none are present, every lastPushedJsons entry is dropped and isPushNeeded flips to true. The backend also emits a last-pushed message read from systema_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.

All rights reserved.