From e0bbe038512a0ac34ba3807359e1ce7b00a5a396 Mon Sep 17 00:00:00 2001 From: Bot Date: Sun, 1 Mar 2026 02:03:04 +0100 Subject: [PATCH] feat(web): add button size toggle (S/M/L) in header Adds a size selector in the header bar that allows users to choose between Small, Medium, and Large sound buttons. Choice persists via localStorage. Responsive breakpoints also respect the setting. Co-Authored-By: Claude Opus 4.6 --- web/src/App.tsx | 26 +++++++++- web/src/styles.css | 117 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 1 deletion(-) diff --git a/web/src/App.tsx b/web/src/App.tsx index 59639cb..c11438c 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -25,6 +25,12 @@ const THEMES = [ ]; type Tab = 'all' | 'favorites' | 'recent'; +type BtnSize = 'S' | 'M' | 'L'; +const BTN_SIZES: { id: BtnSize; label: string }[] = [ + { id: 'S', label: 'S' }, + { id: 'M', label: 'M' }, + { id: 'L', label: 'L' }, +]; export default function App() { /* ── State ── */ @@ -44,6 +50,7 @@ export default function App() { const [volume, setVolume] = useState(1); const [favs, setFavs] = useState>({}); const [theme, setTheme] = useState(() => localStorage.getItem('jb-theme') || 'midnight'); + const [btnSize, setBtnSize] = useState(() => (localStorage.getItem('jb-btn-size') as BtnSize) || 'M'); const [isAdmin, setIsAdmin] = useState(false); const [showAdmin, setShowAdmin] = useState(false); @@ -91,6 +98,11 @@ export default function App() { localStorage.setItem('jb-theme', theme); }, [theme]); + /* ── Button Size ── */ + useEffect(() => { + localStorage.setItem('jb-btn-size', btnSize); + }, [btnSize]); + /* ── SSE ── */ useEffect(() => { const unsub = subscribeEvents((msg) => { @@ -230,7 +242,7 @@ export default function App() { /* ── Render ── */ return ( -
+
{/* ════════ Header ════════ */}
@@ -256,6 +268,18 @@ export default function App() { {total} Sounds
+
+ {BTN_SIZES.map(s => ( + + ))} +
+