diff options
Diffstat (limited to 'src/components/Settings/SettingsPanel.tsx')
| -rw-r--r-- | src/components/Settings/SettingsPanel.tsx | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/components/Settings/SettingsPanel.tsx b/src/components/Settings/SettingsPanel.tsx new file mode 100644 index 0000000..e4a4b6b --- /dev/null +++ b/src/components/Settings/SettingsPanel.tsx @@ -0,0 +1,106 @@ +import { useSettingsStore } from '@/stores/useSettingsStore' +import { useThemeStore } from '@/stores/useThemeStore' +import Toggle from '@/components/UI/Toggle' +import Slider from '@/components/UI/Slider' +import Input from '@/components/UI/Input' + +function Section({ label, children }: { label: string; children: React.ReactNode }) { + return ( + <div className="mb-6"> + <div className="px-3 py-1.5 text-ui-xs font-medium tracking-[0.08em] uppercase text-text-muted"> + {label} + </div> + <div className="flex flex-col">{children}</div> + </div> + ) +} + +function Row({ label, children }: { label: string; children: React.ReactNode }) { + return ( + <div className="flex items-center justify-between px-3 py-2 min-h-[34px] gap-4"> + <span className="text-ui-sm text-text-secondary shrink-0">{label}</span> + <div className="w-[140px] shrink-0">{children}</div> + </div> + ) +} + +export default function SettingsPanel() { + const settings = useSettingsStore() + const toggleTheme = useThemeStore((s) => s.toggleTheme) + const theme = useThemeStore((s) => s.theme) + + return ( + <div className="flex-1 overflow-y-auto overflow-x-hidden"> + <Section label="Interface"> + <Row label="Theme"> + <button + onClick={toggleTheme} + className="flex items-center justify-between w-full h-7 px-2.5 rounded-md text-ui-sm text-text-primary bg-editor-surface border transition-all duration-150 hover:brightness-110" + style={{ borderColor: 'var(--color-panel-border)' }} + > + <span>{theme === 'dark' ? 'Dark' : 'Light'}</span> + <span className="text-text-muted text-ui-xs"> + {theme === 'dark' ? '🌙' : '☀️'} + </span> + </button> + </Row> + <Row label="Font Size"> + <div className="flex items-center gap-2"> + <Slider + value={settings.fontSize} + min={10} + max={24} + step={1} + onChange={(v) => settings.set('fontSize', v)} + /> + <span className="text-ui-xs text-text-muted w-5 text-right tabular-nums">{settings.fontSize}</span> + </div> + </Row> + <Row label="Tab Size"> + <div className="flex items-center gap-2"> + <Slider + value={settings.tabSize} + min={1} + max={8} + step={1} + onChange={(v) => settings.set('tabSize', v)} + /> + <span className="text-ui-xs text-text-muted w-5 text-right tabular-nums">{settings.tabSize}</span> + </div> + </Row> + </Section> + + <Section label="Editor"> + <Row label="Word Wrap"> + <Toggle + checked={settings.wordWrap} + onChange={(v) => settings.set('wordWrap', v)} + /> + </Row> + <Row label="Line Numbers"> + <Toggle + checked={settings.lineNumbers} + onChange={(v) => settings.set('lineNumbers', v)} + /> + </Row> + <Row label="Ruler"> + <Toggle + checked={settings.ruler} + onChange={(v) => settings.set('ruler', v)} + /> + </Row> + <Row label="Ruler Column"> + <Input + type="number" + value={settings.rulerColumn} + min={40} + max={200} + onChange={(v) => settings.set('rulerColumn', parseInt(v) || 80)} + /> + </Row> + </Section> + + <div className="h-2" /> + </div> + ) +} |