v1.0.1: Add comprehensive theme switcher and fix dark mode issues

- Add theme switcher widget with Auto/Light/Dark options in header
- Implement manual theme override system with localStorage persistence
- Add complete button theme overrides for all variants (primary, outline-*)
- Fix missing focus states and placeholder colors for light theme
- Add proper alert styling for both themes
- Fix expression input error state colors in dark theme
- Complete comprehensive theme coverage for all UI elements
- Theme switcher overrides CSS media queries when manually selected
- All buttons, inputs, and surfaces now properly adapt to theme changes
This commit is contained in:
2026-01-21 09:45:38 +01:00
parent fef9c9732e
commit 97d83923d9
4 changed files with 369 additions and 2 deletions

View File

@@ -5,6 +5,10 @@ import './App.css';
// JMESPath Testing Tool - Main Application Component
function App() {
const [jmespathExpression, setJmespathExpression] = useState('people[0].name');
const [theme, setTheme] = useState(() => {
// Load theme from localStorage or default to 'auto'
return localStorage.getItem('theme') || 'auto';
});
const [jsonData, setJsonData] = useState(`{
"people": [
{
@@ -24,6 +28,29 @@ function App() {
const [error, setError] = useState('');
const [jsonError, setJsonError] = useState('');
// Theme management
useEffect(() => {
// Apply theme to document
const applyTheme = (selectedTheme) => {
const root = document.documentElement;
root.className = ''; // Clear existing theme classes
if (selectedTheme === 'light') {
root.classList.add('theme-light');
} else if (selectedTheme === 'dark') {
root.classList.add('theme-dark');
}
// 'auto' uses CSS media queries (no class needed)
};
applyTheme(theme);
localStorage.setItem('theme', theme);
}, [theme]);
const handleThemeChange = (newTheme) => {
setTheme(newTheme);
};
const evaluateExpression = () => {
try {
// Clear previous errors
@@ -185,8 +212,37 @@ function App() {
<div className="header-section py-2">
<div className="container">
<div className="row">
<div className="col-12 text-center">
<div className="col-12 text-center position-relative">
<h2 className="mb-1">JMESPath Testing Tool</h2>
{/* Theme switcher */}
<div className="position-absolute top-0 end-0">
<div className="btn-group btn-group-sm" role="group" aria-label="Theme switcher">
<button
type="button"
className={`btn ${theme === 'auto' ? 'btn-primary' : 'btn-outline-secondary'}`}
onClick={() => handleThemeChange('auto')}
title="Auto (follow system)"
>
🌓 Auto
</button>
<button
type="button"
className={`btn ${theme === 'light' ? 'btn-primary' : 'btn-outline-secondary'}`}
onClick={() => handleThemeChange('light')}
title="Light theme"
>
Light
</button>
<button
type="button"
className={`btn ${theme === 'dark' ? 'btn-primary' : 'btn-outline-secondary'}`}
onClick={() => handleThemeChange('dark')}
title="Dark theme"
>
🌙 Dark
</button>
</div>
</div>
</div>
</div>
</div>