From 66a35d9472c1f8a3f45958e63d4ffefb802d417a Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 1 May 2026 22:59:24 +0000 Subject: [PATCH] fix(ui): Use 4-column grid for theme picker 8 themes no longer fit in a single row. Changed from flex row to a 4x2 grid layout so all themes are visible. Co-Authored-By: Claude Opus 4.5 --- src/components/ThemePicker.jsx | 334 ++++++++++++++++----------------- 1 file changed, 167 insertions(+), 167 deletions(-) diff --git a/src/components/ThemePicker.jsx b/src/components/ThemePicker.jsx index b9f7792..9e0e35e 100644 --- a/src/components/ThemePicker.jsx +++ b/src/components/ThemePicker.jsx @@ -1,167 +1,167 @@ -import { useState, useRef, useEffect } from 'react' -import { Palette } from 'lucide-react' -import { themeList } from '../themes/registry' -import { useStore } from '../store' - -/** - * ThemeSwatch - Renders a circular swatch with 3 color segments - */ -function ThemeSwatch({ colors, size = 28, active = false }) { - // Split circle into 3 segments using conic gradient - const gradient = `conic-gradient( - ${colors[0]} 0deg 120deg, - ${colors[1]} 120deg 240deg, - ${colors[2]} 240deg 360deg - )` - - return ( -
- ) -} - -/** - * ThemePicker - Popover component for selecting themes - */ -export default function ThemePicker() { - const [isOpen, setIsOpen] = useState(false) - const theme = useStore((s) => s.theme) - const setThemeOverride = useStore((s) => s.setThemeOverride) - const triggerRef = useRef(null) - const popoverRef = useRef(null) - - const themes = themeList() - const currentTheme = themes.find(t => t.id === theme) || themes[0] - - // Handle click outside to close - useEffect(() => { - if (!isOpen) return - - function handleClickOutside(e) { - if ( - popoverRef.current && - !popoverRef.current.contains(e.target) && - triggerRef.current && - !triggerRef.current.contains(e.target) - ) { - setIsOpen(false) - } - } - - function handleEscape(e) { - if (e.key === 'Escape') { - setIsOpen(false) - } - } - - document.addEventListener('mousedown', handleClickOutside) - document.addEventListener('keydown', handleEscape) - return () => { - document.removeEventListener('mousedown', handleClickOutside) - document.removeEventListener('keydown', handleEscape) - } - }, [isOpen]) - - const handleThemeSelect = (themeId) => { - setThemeOverride(themeId) - setIsOpen(false) - } - - return ( -
- {/* Trigger button */} - - - {/* Popover */} - {isOpen && ( -
-
- {themes.map((t) => ( - - ))} -
-
- )} -
- ) -} +import { useState, useRef, useEffect } from 'react' +import { Palette } from 'lucide-react' +import { themeList } from '../themes/registry' +import { useStore } from '../store' + +/** + * ThemeSwatch - Renders a circular swatch with 3 color segments + */ +function ThemeSwatch({ colors, size = 28, active = false }) { + // Split circle into 3 segments using conic gradient + const gradient = `conic-gradient( + ${colors[0]} 0deg 120deg, + ${colors[1]} 120deg 240deg, + ${colors[2]} 240deg 360deg + )` + + return ( +
+ ) +} + +/** + * ThemePicker - Popover component for selecting themes + */ +export default function ThemePicker() { + const [isOpen, setIsOpen] = useState(false) + const theme = useStore((s) => s.theme) + const setThemeOverride = useStore((s) => s.setThemeOverride) + const triggerRef = useRef(null) + const popoverRef = useRef(null) + + const themes = themeList() + const currentTheme = themes.find(t => t.id === theme) || themes[0] + + // Handle click outside to close + useEffect(() => { + if (!isOpen) return + + function handleClickOutside(e) { + if ( + popoverRef.current && + !popoverRef.current.contains(e.target) && + triggerRef.current && + !triggerRef.current.contains(e.target) + ) { + setIsOpen(false) + } + } + + function handleEscape(e) { + if (e.key === 'Escape') { + setIsOpen(false) + } + } + + document.addEventListener('mousedown', handleClickOutside) + document.addEventListener('keydown', handleEscape) + return () => { + document.removeEventListener('mousedown', handleClickOutside) + document.removeEventListener('keydown', handleEscape) + } + }, [isOpen]) + + const handleThemeSelect = (themeId) => { + setThemeOverride(themeId) + setIsOpen(false) + } + + return ( +
+ {/* Trigger button */} + + + {/* Popover */} + {isOpen && ( +
+
+ {themes.map((t) => ( + + ))} +
+
+ )} +
+ ) +}