import { memo, useState, useEffect } from 'react'; import * as Dialog from '@radix-ui/react-dialog'; import * as Switch from '@radix-ui/react-switch'; import * as Slider from '@radix-ui/react-slider'; import { classNames } from '~/utils/classNames'; import { motion, AnimatePresence } from 'framer-motion'; interface AutoSaveSettingsProps { onSettingsChange?: (settings: AutoSaveConfig) => void; trigger?: React.ReactNode; } export interface AutoSaveConfig { enabled: boolean; interval: number; // in seconds minChanges: number; saveOnBlur: boolean; saveBeforeRun: boolean; showNotifications: boolean; } const DEFAULT_CONFIG: AutoSaveConfig = { enabled: false, interval: 30, minChanges: 1, saveOnBlur: true, saveBeforeRun: true, showNotifications: true, }; const PRESET_INTERVALS = [ { label: '10s', value: 10 }, { label: '30s', value: 30 }, { label: '1m', value: 60 }, { label: '2m', value: 120 }, { label: '5m', value: 300 }, ]; export const AutoSaveSettings = memo(({ onSettingsChange, trigger }: AutoSaveSettingsProps) => { const [isOpen, setIsOpen] = useState(false); const [config, setConfig] = useState(() => { // Load from localStorage if available if (typeof window !== 'undefined') { const saved = localStorage.getItem('bolt-autosave-config'); if (saved) { try { return JSON.parse(saved); } catch { // Invalid JSON, use defaults } } } return DEFAULT_CONFIG; }); // Save to localStorage whenever config changes useEffect(() => { if (typeof window !== 'undefined') { localStorage.setItem('bolt-autosave-config', JSON.stringify(config)); } onSettingsChange?.(config); }, [config, onSettingsChange]); const updateConfig = (key: K, value: AutoSaveConfig[K]) => { setConfig((prev) => ({ ...prev, [key]: value })); }; return ( {trigger || ( )} {isOpen && (
{/* Header */}
Auto-save Settings
{/* Content */}
{/* Enable/Disable Auto-save */}

Automatically save files at regular intervals

updateConfig('enabled', checked)} className={classNames( 'relative inline-flex h-6 w-11 items-center rounded-full transition-colors', config.enabled ? 'bg-accent-500' : 'bg-bolt-elements-background-depth-3', )} >
{/* Save Interval */}

How often to save changes

updateConfig('interval', value)} min={5} max={300} step={5} className="relative flex items-center select-none touch-none w-full h-5" > {/* Preset buttons */}
{PRESET_INTERVALS.map((preset) => ( ))}
{/* Minimum Changes */}

Minimum number of files to trigger auto-save

updateConfig('minChanges', value)} min={1} max={10} step={1} className="relative flex items-center select-none touch-none w-full h-5" >
{/* Additional Options */}

Save when switching to another tab

updateConfig('saveOnBlur', checked)} className={classNames( 'relative inline-flex h-6 w-11 items-center rounded-full transition-colors', config.saveOnBlur ? 'bg-accent-500' : 'bg-bolt-elements-background-depth-3', )} >

Save all files before running commands

updateConfig('saveBeforeRun', checked)} className={classNames( 'relative inline-flex h-6 w-11 items-center rounded-full transition-colors', config.saveBeforeRun ? 'bg-accent-500' : 'bg-bolt-elements-background-depth-3', )} >

Display toast notifications on save

updateConfig('showNotifications', checked)} className={classNames( 'relative inline-flex h-6 w-11 items-center rounded-full transition-colors', config.showNotifications ? 'bg-accent-500' : 'bg-bolt-elements-background-depth-3', )} >
{/* Footer */}
Done
)} ); }); AutoSaveSettings.displayName = 'AutoSaveSettings';