| import { LoaderCircle, Pause, Play, RefreshCw } from "lucide-react"; | |
| type SimulationControlsProps = { | |
| hasSnapshot: boolean; | |
| isAutoTicking: boolean; | |
| isWaitingForTick: boolean; | |
| isWorldCommandPending: boolean; | |
| onStep: () => void; | |
| onToggleAutoTick: () => void; | |
| }; | |
| export function SimulationControls({ | |
| hasSnapshot, | |
| isAutoTicking, | |
| isWaitingForTick, | |
| isWorldCommandPending, | |
| onStep, | |
| onToggleAutoTick, | |
| }: SimulationControlsProps) { | |
| const stepLabel = isWaitingForTick ? "Waiting for tick result" : "Advance one tick"; | |
| const autoLabel = isAutoTicking ? "Pause continuous ticks" : "Run continuous ticks"; | |
| return ( | |
| <div className="controls" aria-label="Simulation controls"> | |
| <button | |
| type="button" | |
| className={isWorldCommandPending ? "isLoading" : ""} | |
| aria-label={stepLabel} | |
| title={stepLabel} | |
| aria-busy={isWorldCommandPending} | |
| disabled={isWorldCommandPending} | |
| onClick={onStep} | |
| > | |
| {isWorldCommandPending ? ( | |
| <LoaderCircle className="spinIcon" size={20} /> | |
| ) : ( | |
| <RefreshCw size={18} /> | |
| )} | |
| </button> | |
| <button | |
| type="button" | |
| className={isAutoTicking ? "isActive" : ""} | |
| aria-label={autoLabel} | |
| title={autoLabel} | |
| aria-pressed={isAutoTicking} | |
| disabled={!hasSnapshot} | |
| onClick={onToggleAutoTick} | |
| > | |
| {isAutoTicking ? <Pause size={18} /> : <Play size={18} />} | |
| </button> | |
| </div> | |
| ); | |
| } | |