feat: code-gen always includes dark mode + mobile-first
- Dark mode mandatory: ThemeProvider, useTheme hook, ThemeToggle component with light/dark/system support via Tailwind 'class' strategy - Mobile-first mandatory: 320px minimum, 44px tap targets, responsive grids, hamburger nav, full-width mobile forms - Every UI component must have dark: variants and responsive breakpoints Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4f45ae78cf
commit
2386496d9c
@ -12,9 +12,106 @@ Du bist ein Code-Generator für React + Node.js Webprojekte.
|
||||
- Props-Interface immer definieren
|
||||
- Error Boundaries für kritische Komponenten
|
||||
- Loading/Error States berücksichtigen
|
||||
- Responsive Design (Mobile-First)
|
||||
- **Mobile-First Responsive Design** (siehe unten)
|
||||
- **Dark Mode immer einbauen** (siehe unten)
|
||||
- Styling: Tailwind CSS oder CSS Modules
|
||||
|
||||
### Mobile-First Pflicht
|
||||
Jede Komponente wird zuerst für Mobile designt, dann für größere Screens erweitert:
|
||||
- Tailwind: Basis-Klassen = Mobile, `sm:`, `md:`, `lg:` für größere Screens
|
||||
- Touch-freundliche Elemente: min. 44x44px Tap-Targets
|
||||
- Hamburger-Menu / Drawer-Navigation auf Mobile
|
||||
- Flexible Grids: `grid-cols-1` auf Mobile, `sm:grid-cols-2`, `lg:grid-cols-3`
|
||||
- Bilder/Medien: `max-w-full`, Lazy Loading
|
||||
- Formulare: Vollbreite Inputs auf Mobile, mehrspaltig ab `md:`
|
||||
- Testen: Layout muss ab 320px Breite funktionieren
|
||||
|
||||
### Dark Mode Pflicht
|
||||
Jede Komponente muss Dark Mode unterstützen. Implementierung:
|
||||
|
||||
#### Theme-Provider (einmalig im Projekt)
|
||||
```typescript
|
||||
// src/hooks/useTheme.ts
|
||||
import { useState, useEffect, createContext, useContext } from 'react';
|
||||
|
||||
type Theme = 'light' | 'dark' | 'system';
|
||||
|
||||
const ThemeContext = createContext<{
|
||||
theme: Theme;
|
||||
resolvedTheme: 'light' | 'dark';
|
||||
setTheme: (theme: Theme) => void;
|
||||
}>({ theme: 'system', resolvedTheme: 'light', setTheme: () => {} });
|
||||
|
||||
export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
const [theme, setTheme] = useState<Theme>(() => {
|
||||
return (localStorage.getItem('theme') as Theme) || 'system';
|
||||
});
|
||||
|
||||
const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>('light');
|
||||
|
||||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
const systemDark = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
|
||||
const apply = () => {
|
||||
const isDark = theme === 'dark' || (theme === 'system' && systemDark.matches);
|
||||
root.classList.toggle('dark', isDark);
|
||||
setResolvedTheme(isDark ? 'dark' : 'light');
|
||||
};
|
||||
|
||||
apply();
|
||||
localStorage.setItem('theme', theme);
|
||||
systemDark.addEventListener('change', apply);
|
||||
return () => systemDark.removeEventListener('change', apply);
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme, resolvedTheme, setTheme }}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export const useTheme = () => useContext(ThemeContext);
|
||||
```
|
||||
|
||||
#### Theme-Toggle Komponente
|
||||
```typescript
|
||||
// src/components/ThemeToggle.tsx
|
||||
import { useTheme } from '../hooks/useTheme';
|
||||
|
||||
export function ThemeToggle() {
|
||||
const { theme, setTheme } = useTheme();
|
||||
const next = { light: 'dark', dark: 'system', system: 'light' } as const;
|
||||
return (
|
||||
<button
|
||||
onClick={() => setTheme(next[theme])}
|
||||
className="p-2 rounded-lg bg-gray-200 dark:bg-gray-700 min-w-[44px] min-h-[44px]"
|
||||
aria-label="Theme wechseln"
|
||||
>
|
||||
{theme === 'light' ? '☀️' : theme === 'dark' ? '🌙' : '💻'}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### Tailwind Dark Mode Config
|
||||
```javascript
|
||||
// tailwind.config.js
|
||||
module.exports = {
|
||||
darkMode: 'class',
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
#### Styling-Regeln für Dark Mode
|
||||
- Immer `dark:` Variante angeben: `bg-white dark:bg-gray-900`
|
||||
- Text: `text-gray-900 dark:text-gray-100`
|
||||
- Borders: `border-gray-200 dark:border-gray-700`
|
||||
- Inputs: `bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100`
|
||||
- Hover: `hover:bg-gray-100 dark:hover:bg-gray-800`
|
||||
- Keine hardcoded Farben ohne `dark:` Gegenstück
|
||||
|
||||
## BACKEND-REGELN (Node.js/Express)
|
||||
- Express mit TypeScript
|
||||
- Controller/Service/Repository Pattern
|
||||
@ -29,7 +126,7 @@ Frontend:
|
||||
```
|
||||
src/
|
||||
components/ # React-Komponenten
|
||||
hooks/ # Custom Hooks
|
||||
hooks/ # Custom Hooks (inkl. useTheme)
|
||||
services/ # API-Calls
|
||||
types/ # TypeScript Interfaces
|
||||
utils/ # Hilfsfunktionen
|
||||
@ -54,3 +151,4 @@ src/
|
||||
- DRY-Prinzip
|
||||
- SOLID-Prinzipien
|
||||
- Jede Komponente/Service in eigener Datei
|
||||
- **Jede UI-Komponente: Mobile-First + Dark Mode**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user