Flow Studio
Consuming in Components
Components subscribe to designerModeStore slices using the useDesignerModeStore hook with a selector. The isReadonly flag is the primary gate for disabling edit interactions; mode-specific rendering branches on currentMode.
Reading isReadonly
// The most common subscription — disabling edit interactions
function NodeConfigForm({ nodeId }: { nodeId: string }) {
const isReadonly = useDesignerModeStore(state => state.isReadonly);
return (
<form>
<input
name="label"
disabled={isReadonly}
// ...
/>
{!isReadonly &&
<button type="submit">Save</button>}
</form>
);
}
Conditional Rendering Per Mode
// Show different toolbar content depending on mode
function CanvasToolbar() {
const currentMode = useDesignerModeStore(state => state.currentMode);
return (
<div className="toolbar">
{currentMode === 'design' && <DesignToolbarActions />}
{currentMode === 'execution' && <ExecutionProgressBar />}
{currentMode === 'readonly' && <ReadonlyBadge />}
</div>
);
}
Reading Execution Mode State
import { shallow } from 'zustand/shallow';
// Subscribe to multiple fields efficiently
function ExecutionSummaryPanel() {
const { executionId, runProgress, currentMode } = useDesignerModeStore(
state => ({
executionId: state.executionId,
runProgress: state.runProgress,
currentMode: state.currentMode
}),
shallow
);
if (currentMode !== 'execution') return null;
return (
<div>
<p>Execution: {executionId}</p>
<p>{runProgress.completedNodes} / {runProgress.totalNodes} completed</p>
</div>
);
}
Calling Transition Actions
// Stable action references — no shallow needed
function RunButton({ processId }: { processId: string }) {
const enterExecutionMode = useDesignerModeStore(state => state.enterExecutionMode);
async function handleRun() {
const { executionId } = await processApiClient.startExecution(processId);
enterExecutionMode(executionId);
}
return <button onClick={handleRun}>Run</button>;
}
Prefer isReadonly over checking currentMode for disabling edits. If a new mode is added in the future that also disables editing, components checking
isReadonly will automatically handle it without code changes.