feat: implement theme system and UI updates

- Added theme context and provider for light/dark mode support.
- Integrated theme toggle button in the Header component.
- Updated UI components to utilize CSS variables for consistent theming.
- Enhanced Kanban components and forms with new theme styles for better visual coherence.
- Adjusted global styles to define color variables for both themes, improving maintainability.
This commit is contained in:
Julien Froidefond
2025-09-15 11:49:54 +02:00
parent dce11e0569
commit 07cd3bde3b
23 changed files with 298 additions and 160 deletions

View File

@@ -108,7 +108,7 @@ export function TagInput({
return (
<div className={`relative ${className}`}>
{/* Container des tags et input */}
<div className="min-h-[42px] p-2 border border-slate-600 rounded-lg bg-slate-800 focus-within:border-cyan-400 focus-within:ring-1 focus-within:ring-cyan-400/20 transition-colors">
<div className="min-h-[42px] p-2 border border-[var(--border)] rounded-lg bg-[var(--input)] focus-within:border-[var(--primary)] focus-within:ring-1 focus-within:ring-[var(--primary)]/20 transition-colors">
<div className="flex flex-wrap gap-1 items-center">
{/* Tags existants */}
{tags.map((tag, index) => (
@@ -121,7 +121,7 @@ export function TagInput({
<button
type="button"
onClick={() => removeTag(tag)}
className="text-slate-400 hover:text-slate-200 ml-1"
className="text-[var(--muted-foreground)] hover:text-[var(--foreground)] ml-1"
aria-label={`Supprimer le tag ${tag}`}
>
×
@@ -140,7 +140,7 @@ export function TagInput({
onBlur={handleBlur}
onFocus={handleFocus}
placeholder={tags.length === 0 ? placeholder : ""}
className="flex-1 min-w-[120px] bg-transparent border-none outline-none text-slate-100 placeholder-slate-400 text-sm"
className="flex-1 min-w-[120px] bg-transparent border-none outline-none text-[var(--foreground)] placeholder-[var(--muted-foreground)] text-sm"
/>
)}
</div>
@@ -150,10 +150,10 @@ export function TagInput({
{showSuggestions && (suggestions.length > 0 || loading) && (
<div
ref={suggestionsRef}
className="absolute top-full left-0 right-0 mt-1 bg-slate-800 border border-slate-600 rounded-lg shadow-lg z-50 max-h-64 overflow-y-auto"
className="absolute top-full left-0 right-0 mt-1 bg-[var(--card)] border border-[var(--border)] rounded-lg shadow-lg z-50 max-h-64 overflow-y-auto"
>
{loading ? (
<div className="p-3 text-center text-slate-400 text-sm">
<div className="p-3 text-center text-[var(--muted-foreground)] text-sm">
Recherche...
</div>
) : (
@@ -165,8 +165,8 @@ export function TagInput({
onClick={() => handleSuggestionClick(tag)}
className={`flex items-center gap-2 px-2 py-1.5 text-xs rounded-md transition-colors ${
index === selectedIndex
? 'bg-slate-700 text-cyan-300 ring-1 ring-cyan-400'
: 'text-slate-200 hover:bg-slate-700'
? 'bg-[var(--card-hover)] text-[var(--primary)] ring-1 ring-[var(--primary)]'
: 'text-[var(--foreground)] hover:bg-[var(--card-hover)]'
} ${tags.includes(tag.name) ? 'opacity-50 cursor-not-allowed' : ''}`}
disabled={tags.includes(tag.name)}
title={tags.includes(tag.name) ? 'Déjà ajouté' : `Ajouter ${tag.name}`}
@@ -177,7 +177,7 @@ export function TagInput({
/>
<span className="truncate">{tag.name}</span>
{tags.includes(tag.name) && (
<span className="text-slate-400 ml-auto"></span>
<span className="text-[var(--muted-foreground)] ml-auto"></span>
)}
</button>
))}
@@ -188,7 +188,7 @@ export function TagInput({
{/* Indicateur de limite */}
{tags.length >= maxTags && (
<div className="text-xs text-slate-400 mt-1">
<div className="text-xs text-[var(--muted-foreground)] mt-1">
Limite de {maxTags} tags atteinte
</div>
)}