Attempt to fix note resizing with React keys and Muuri sync

This commit is contained in:
2026-01-24 19:52:13 +01:00
parent d59ec592eb
commit 8e35780717
48 changed files with 3369 additions and 279 deletions

View File

@@ -0,0 +1,310 @@
/**
* PROPOSITION D'HARMONIE DE COULEURS
* ===================================
*
* Recommandations pour un système de couleurs unifié et moderne
* Inspiré de Google Keep avec une approche contemporaine
*
*/
// =============================================================================
// 1. PALETTE PRINCIPALE DU THÈME (OKLCH)
// =============================================================================
/**
* Proposition de palette principale avec meilleure cohérence
* Utilise OKLCH pour une meilleure accessibilité et cohérence perceptive
*/
export const RECOMMENDED_THEME_COLORS = {
/* ============ THEME LIGHT ============ */
light: {
// Backgrounds
background: 'oklch(0.99 0.002 250)', // Blanc très légèrement bleuté
card: 'oklch(1 0 0)', // Blanc pur
sidebar: 'oklch(0.96 0.005 250)', // Gris-bleu très pâle
input: 'oklch(0.97 0.003 250)', // Gris-bleu pâle
// Textes
foreground: 'oklch(0.18 0.01 250)', // Gris-bleu foncé (meilleur contraste)
'foreground-secondary': 'oklch(0.45 0.01 250)', // Gris moyen
'foreground-muted': 'oklch(0.6 0.005 250)', // Gris clair
// Primary Actions
primary: 'oklch(0.55 0.2 250)', // Bleu Keep (plus vibrant)
'primary-hover': 'oklch(0.5 0.22 250)', // Bleu Keep foncé
'primary-foreground': 'oklch(0.99 0 0)', // Blanc pur
// Accents
accent: 'oklch(0.92 0.015 250)', // Bleu très pâle
'accent-foreground': 'oklch(0.18 0.01 250)',
// Borders
border: 'oklch(0.88 0.01 250)', // Gris-bleu très clair
'border-hover': 'oklch(0.8 0.015 250)',
// Functional
success: 'oklch(0.65 0.15 145)', // Vert
warning: 'oklch(0.75 0.12 70)', // Jaune/orange
destructive: 'oklch(0.6 0.2 25)', // Rouge
},
/* ============ THEME DARK ============ */
dark: {
// Backgrounds
background: 'oklch(0.12 0.01 250)', // Noir légèrement bleuté
card: 'oklch(0.16 0.01 250)', // Gris-bleu foncé
sidebar: 'oklch(0.1 0.01 250)', // Noir bleuté
input: 'oklch(0.18 0.01 250)',
// Textes
foreground: 'oklch(0.96 0.002 250)', // Blanc légèrement bleuté
'foreground-secondary': 'oklch(0.75 0.005 250)',
'foreground-muted': 'oklch(0.55 0.01 250)',
// Primary Actions
primary: 'oklch(0.65 0.2 250)', // Bleu plus clair
'primary-hover': 'oklch(0.7 0.2 250)',
'primary-foreground': 'oklch(0.1 0 0)',
// Accents
accent: 'oklch(0.22 0.01 250)',
'accent-foreground': 'oklch(0.96 0.002 250)',
// Borders
border: 'oklch(0.25 0.015 250)',
'border-hover': 'oklch(0.35 0.015 250)',
// Functional
success: 'oklch(0.7 0.15 145)',
warning: 'oklch(0.8 0.12 70)',
destructive: 'oklch(0.65 0.2 25)',
},
} as const;
// =============================================================================
// 2. PALETTE DES COULEURS DE NOTES (UNIFIÉE)
// =============================================================================
/**
* Nouvelle palette de couleurs pour les notes
* Harmonisée avec le thème principal
* Meilleure accessibilité WCAG AA (contraste minimum 4.5:1)
*/
export const RECOMMENDED_NOTE_COLORS = {
default: {
// Light theme
bg: 'bg-white',
'bg-dark': 'dark:bg-neutral-900',
border: 'border-neutral-200',
'border-dark': 'dark:border-neutral-800',
hover: 'hover:bg-neutral-50',
'hover-dark': 'dark:hover:bg-neutral-800',
// Pour texte sombre
text: 'text-neutral-900',
'text-dark': 'dark:text-neutral-100',
},
red: {
bg: 'bg-red-50',
'bg-dark': 'dark:bg-red-950/40',
border: 'border-red-100',
'border-dark': 'dark:border-red-900/50',
hover: 'hover:bg-red-100',
'hover-dark': 'dark:hover:bg-red-950/60',
text: 'text-red-950',
'text-dark': 'dark:text-red-100',
},
orange: {
bg: 'bg-orange-50',
'bg-dark': 'dark:bg-orange-950/40',
border: 'border-orange-100',
'border-dark': 'dark:border-orange-900/50',
hover: 'hover:bg-orange-100',
'hover-dark': 'dark:hover:bg-orange-950/60',
text: 'text-orange-950',
'text-dark': 'dark:text-orange-100',
},
yellow: {
bg: 'bg-yellow-50',
'bg-dark': 'dark:bg-yellow-950/40',
border: 'border-yellow-100',
'border-dark': 'dark:border-yellow-900/50',
hover: 'hover:bg-yellow-100',
'hover-dark': 'dark:hover:bg-yellow-950/60',
text: 'text-yellow-950',
'text-dark': 'dark:text-yellow-100',
},
green: {
bg: 'bg-emerald-50',
'bg-dark': 'dark:bg-emerald-950/40',
border: 'border-emerald-100',
'border-dark': 'dark:border-emerald-900/50',
hover: 'hover:bg-emerald-100',
'hover-dark': 'dark:hover:bg-emerald-950/60',
text: 'text-emerald-950',
'text-dark': 'dark:text-emerald-100',
},
teal: {
bg: 'bg-teal-50',
'bg-dark': 'dark:bg-teal-950/40',
border: 'border-teal-100',
'border-dark': 'dark:border-teal-900/50',
hover: 'hover:bg-teal-100',
'hover-dark': 'dark:hover:bg-teal-950/60',
text: 'text-teal-950',
'text-dark': 'dark:text-teal-100',
},
blue: {
bg: 'bg-blue-50',
'bg-dark': 'dark:bg-blue-950/40',
border: 'border-blue-100',
'border-dark': 'dark:border-blue-900/50',
hover: 'hover:bg-blue-100',
'hover-dark': 'dark:hover:bg-blue-950/60',
text: 'text-blue-950',
'text-dark': 'dark:text-blue-100',
},
indigo: {
bg: 'bg-indigo-50',
'bg-dark': 'dark:bg-indigo-950/40',
border: 'border-indigo-100',
'border-dark': 'dark:border-indigo-900/50',
hover: 'hover:bg-indigo-100',
'hover-dark': 'dark:hover:bg-indigo-950/60',
text: 'text-indigo-950',
'text-dark': 'dark:text-indigo-100',
},
violet: {
bg: 'bg-violet-50',
'bg-dark': 'dark:bg-violet-950/40',
border: 'border-violet-100',
'border-dark': 'dark:border-violet-900/50',
hover: 'hover:bg-violet-100',
'hover-dark': 'dark:hover:bg-violet-950/60',
text: 'text-violet-950',
'text-dark': 'dark:text-violet-100',
},
purple: {
bg: 'bg-purple-50',
'bg-dark': 'dark:bg-purple-950/40',
border: 'border-purple-100',
'border-dark': 'dark:border-purple-900/50',
hover: 'hover:bg-purple-100',
'hover-dark': 'dark:hover:bg-purple-950/60',
text: 'text-purple-950',
'text-dark': 'dark:text-purple-100',
},
pink: {
bg: 'bg-pink-50',
'bg-dark': 'dark:bg-pink-950/40',
border: 'border-pink-100',
'border-dark': 'dark:border-pink-900/50',
hover: 'hover:bg-pink-100',
'hover-dark': 'dark:hover:bg-pink-950/60',
text: 'text-pink-950',
'text-dark': 'dark:text-pink-100',
},
rose: {
bg: 'bg-rose-50',
'bg-dark': 'dark:bg-rose-950/40',
border: 'border-rose-100',
'border-dark': 'dark:border-rose-900/50',
hover: 'hover:bg-rose-100',
'hover-dark': 'dark:hover:bg-rose-950/60',
text: 'text-rose-950',
'text-dark': 'dark:text-rose-100',
},
gray: {
bg: 'bg-neutral-100',
'bg-dark': 'dark:bg-neutral-800',
border: 'border-neutral-200',
'border-dark': 'dark:border-neutral-700',
hover: 'hover:bg-neutral-200',
'hover-dark': 'dark:hover:bg-neutral-700',
text: 'text-neutral-900',
'text-dark': 'dark:text-neutral-100',
},
} as const;
// =============================================================================
// 3. RÈGLES DE DESIGN
// =============================================================================
/**
* Principes de design couleur :
*
* 1. HARMONIE : Toutes les couleurs partagent la même teinte de base (bleu 250°)
* - Crée une cohérence visuelle
* - Réduit la fatigue visuelle
* - Améliore la perception de marque
*
* 2. CONTRASTE : Respecte WCAG AA (4.5:1 minimum)
* - Texte sur fond : toujours ≥ 4.5:1
* - Éléments interactifs : ≥ 3:1
* - Utilise OKLCH pour une mesure plus précise
*
* 3. ACCESSIBILITÉ :
* - Ne pas utiliser la couleur seule pour véhiculer l'information
* - Inclure des icônes ou des symboles
* - Supporter le mode de contraste élevé
*
* 4. ADAPTABILITÉ :
* - Mode light/dark automatique
* - Variations de couleur par note
* - Thèmes alternatifs (midnight, blue, sepia)
*
* 5. PERFORMANCE PERCEPTIVE :
* - OKLCH pour une échelle perceptuelle uniforme
* - Même légèreté perçue entre light et dark
* - Transition fluide entre thèmes
*/
// =============================================================================
// 4. EXEMPLE D'IMPLEMENTATION
// =============================================================================
/**
* Comment utiliser ces couleurs dans les composants :
*
* ```tsx
* import { RECOMMENDED_NOTE_COLORS } from '@/lib/color-harmony-recommendation'
*
* // Pour une carte de note
* <div className={`
* ${noteColors.bg}
* dark:${noteColors['bg-dark']}
* ${noteColors.border}
* dark:${noteColors['border-dark']}
* ${noteColors.text}
* dark:${noteColors['text-dark']}
* hover:${noteColors.hover}
* dark:hover:${noteColors['hover-dark']}
* `}>
* {note.content}
* </div>
*
* // Pour le thème global (globals.css)
* :root {
* --background: oklch(0.99 0.002 250);
* --foreground: oklch(0.18 0.01 250);
* --primary: oklch(0.55 0.2 250);
* // ... autres couleurs
* }
* ```
*/
// =============================================================================
// 5. AVANTAGES DE CETTE APPROCHE
// =============================================================================
/**
* ✅ Cohérence visuelle accrue
* ✅ Meilleure accessibilité (WCAG AA+)
* ✅ Adaptation native aux modes light/dark
* ✅ Palette extensible (facile à ajouter de nouvelles couleurs)
* ✅ Performance OKLCH (perception humaine)
* ✅ Compatible avec Tailwind CSS
* ✅ Maintenance simplifiée
* ✅ Professionalisme et modernité
*/
export type RecommendedNoteColor = keyof typeof RECOMMENDED_NOTE_COLORS;

View File

@@ -0,0 +1,307 @@
/**
* OPTIONS DE COULEURS MODERNES - PAS DE DÉGRADÉS
* =================================================
*
* Alternatives au bleu traditionnel pour un design contemporain
*/
// =============================================================================
// OPTION 1: GRIS-BLEU (SLATE) - RECOMMANDÉE ✅
// =============================================================================
/**
* Gris-bleu moderne et professionnel
* Inspiré par Linear, Vercel, GitHub
* Très élégant, discret et apaisant pour les yeux
*/
export const SLATE_THEME = {
name: 'Gris-Bleu (Slate)',
description: 'Moderne, professionnel et apaisant - comme Linear/Vercel',
light: {
// Backgrounds
background: 'oklch(0.985 0.003 230)', // Blanc grisâtre très léger
card: 'oklch(1 0 0)', // Blanc pur
sidebar: 'oklch(0.97 0.004 230)', // Gris-bleu très pâle
input: 'oklch(0.98 0.003 230)', // Gris-bleu pâle
// Textes
foreground: 'oklch(0.2 0.02 230)', // Gris-bleu foncé
'foreground-secondary': 'oklch(0.45 0.015 230)', // Gris-bleu moyen
'foreground-muted': 'oklch(0.6 0.01 230)', // Gris-bleu clair
// Primary (le point coloré de l'interface)
primary: 'oklch(0.45 0.08 230)', // Gris-bleu doux
'primary-hover': 'oklch(0.4 0.09 230)', // Gris-bleu plus foncé
'primary-foreground': 'oklch(0.99 0 0)', // Blanc
// Accents
accent: 'oklch(0.94 0.005 230)', // Gris-bleu très pâle
'accent-foreground': 'oklch(0.2 0.02 230)',
// Borders
border: 'oklch(0.9 0.008 230)', // Gris-bleu très clair
'border-hover': 'oklch(0.82 0.01 230)',
// Functional
success: 'oklch(0.65 0.15 145)', // Vert emerald
warning: 'oklch(0.75 0.12 70)', // Jaune/orange
destructive: 'oklch(0.6 0.18 25)', // Rouge
},
dark: {
// Backgrounds
background: 'oklch(0.14 0.005 230)', // Noir grisâtre léger
card: 'oklch(0.18 0.006 230)', // Gris-bleu foncé
sidebar: 'oklch(0.12 0.005 230)', // Noir grisâtre
input: 'oklch(0.2 0.006 230)',
// Textes
foreground: 'oklch(0.97 0.003 230)', // Blanc grisâtre
'foreground-secondary': 'oklch(0.75 0.008 230)',
'foreground-muted': 'oklch(0.55 0.01 230)',
// Primary
primary: 'oklch(0.55 0.08 230)', // Gris-bleu plus clair
'primary-hover': 'oklch(0.6 0.09 230)',
'primary-foreground': 'oklch(0.1 0 0)',
// Accents
accent: 'oklch(0.24 0.006 230)',
'accent-foreground': 'oklch(0.97 0.003 230)',
// Borders
border: 'oklch(0.28 0.01 230)',
'border-hover': 'oklch(0.38 0.012 230)',
// Functional
success: 'oklch(0.7 0.15 145)',
warning: 'oklch(0.8 0.12 70)',
destructive: 'oklch(0.65 0.18 25)',
},
} as const;
// =============================================================================
// OPTION 2: MONOCHROME GRIS (MINIMALISTE)
// =============================================================================
/**
* Noir et blanc avec subtilités de gris
* Style minimaliste ultra-moderne (Linear, Stripe, Apple)
* Absolument pas de couleur sauf pour les fonctionnalités
*/
export const MONOCHROME_THEME = {
name: 'Monochrome Gris',
description: 'Minimaliste et élégant - style Linear/Apple',
light: {
background: 'oklch(0.99 0 0)', // Blanc pur
card: 'oklch(1 0 0)', // Blanc pur
sidebar: 'oklch(0.96 0 0)', // Gris très pâle
input: 'oklch(0.98 0 0)',
foreground: 'oklch(0.15 0 0)', // Noir pur
'foreground-secondary': 'oklch(0.45 0 0)', // Gris moyen
'foreground-muted': 'oklch(0.6 0 0)', // Gris clair
primary: 'oklch(0.2 0 0)', // Gris foncé
'primary-hover': 'oklch(0.15 0 0)', // Noir
'primary-foreground': 'oklch(1 0 0)', // Blanc
accent: 'oklch(0.95 0 0)', // Gris très pâle
'accent-foreground': 'oklch(0.2 0 0)',
border: 'oklch(0.89 0 0)', // Gris très clair
'border-hover': 'oklch(0.75 0 0)',
success: 'oklch(0.6 0.15 145)', // Vert subtil
warning: 'oklch(0.7 0.12 70)', // Jaune subtil
destructive: 'oklch(0.55 0.18 25)', // Rouge subtil
},
dark: {
background: 'oklch(0.1 0 0)', // Noir pur
card: 'oklch(0.14 0 0)', // Gris très foncé
sidebar: 'oklch(0.08 0 0)', // Noir pur
input: 'oklch(0.16 0 0)',
foreground: 'oklch(0.98 0 0)', // Blanc pur
'foreground-secondary': 'oklch(0.7 0 0)', // Gris moyen
'foreground-muted': 'oklch(0.5 0 0)', // Gris foncé
primary: 'oklch(0.85 0 0)', // Gris clair
'primary-hover': 'oklch(0.9 0 0)', // Blanc
'primary-foreground': 'oklch(0.1 0 0)', // Noir
accent: 'oklch(0.2 0 0)', // Gris foncé
'accent-foreground': 'oklch(0.98 0 0)',
border: 'oklch(0.25 0 0)', // Gris foncé
'border-hover': 'oklch(0.35 0 0)',
success: 'oklch(0.65 0.15 145)',
warning: 'oklch(0.75 0.12 70)',
destructive: 'oklch(0.6 0.18 25)',
},
} as const;
// =============================================================================
// OPTION 3: VIOLET PROFOND (INDIGO)
// =============================================================================
/**
* Violet profond élégant et moderne
* Entre le bleu et le violet
* Très professionnel (Discord, Notion, Figma)
*/
export const INDIGO_THEME = {
name: 'Violet Profond',
description: 'Élégant et moderne - style Discord/Notion',
light: {
background: 'oklch(0.99 0.005 260)', // Blanc légèrement violacé
card: 'oklch(1 0 0)',
sidebar: 'oklch(0.96 0.006 260)',
input: 'oklch(0.97 0.005 260)',
foreground: 'oklch(0.2 0.015 260)', // Gris-violet foncé
'foreground-secondary': 'oklch(0.45 0.012 260)',
'foreground-muted': 'oklch(0.6 0.008 260)',
primary: 'oklch(0.55 0.18 260)', // Violet profond
'primary-hover': 'oklch(0.5 0.2 260)', // Violet plus foncé
'primary-foreground': 'oklch(0.99 0 0)',
accent: 'oklch(0.94 0.008 260)',
'accent-foreground': 'oklch(0.2 0.015 260)',
border: 'oklch(0.9 0.01 260)',
'border-hover': 'oklch(0.82 0.012 260)',
success: 'oklch(0.65 0.15 145)',
warning: 'oklch(0.75 0.12 70)',
destructive: 'oklch(0.6 0.18 25)',
},
dark: {
background: 'oklch(0.14 0.008 260)', // Noir légèrement violacé
card: 'oklch(0.18 0.01 260)', // Gris-violet foncé
sidebar: 'oklch(0.12 0.008 260)',
input: 'oklch(0.2 0.01 260)',
foreground: 'oklch(0.97 0.005 260)', // Blanc légèrement violacé
'foreground-secondary': 'oklch(0.75 0.008 260)',
'foreground-muted': 'oklch(0.55 0.01 260)',
primary: 'oklch(0.65 0.18 260)', // Violet plus clair
'primary-hover': 'oklch(0.7 0.2 260)',
'primary-foreground': 'oklch(0.1 0 0)',
accent: 'oklch(0.24 0.01 260)',
'accent-foreground': 'oklch(0.97 0.005 260)',
border: 'oklch(0.28 0.012 260)',
'border-hover': 'oklch(0.38 0.015 260)',
success: 'oklch(0.7 0.15 145)',
warning: 'oklch(0.8 0.12 70)',
destructive: 'oklch(0.65 0.18 25)',
},
} as const;
// =============================================================================
// OPTION 4: TEAL (TURQUOISE)
// =============================================================================
/**
* Turquoise/teal moderne et rafraîchissante
* Entre le bleu et le vert
* Très appréciée dans le design moderne (Linear, Atlassian)
*/
export const TEAL_THEME = {
name: 'Teal (Turquoise)',
description: 'Moderne et rafraîchissant - style Atlassian/Linear',
light: {
background: 'oklch(0.99 0.003 195)', // Blanc légèrement teinté
card: 'oklch(1 0 0)',
sidebar: 'oklch(0.96 0.004 195)',
input: 'oklch(0.97 0.003 195)',
foreground: 'oklch(0.2 0.015 195)', // Gris-teal foncé
'foreground-secondary': 'oklch(0.45 0.012 195)',
'foreground-muted': 'oklch(0.6 0.008 195)',
primary: 'oklch(0.55 0.14 195)', // Teal moderne
'primary-hover': 'oklch(0.5 0.16 195)', // Teal plus foncé
'primary-foreground': 'oklch(0.99 0 0)',
accent: 'oklch(0.94 0.005 195)',
'accent-foreground': 'oklch(0.2 0.015 195)',
border: 'oklch(0.9 0.008 195)',
'border-hover': 'oklch(0.82 0.01 195)',
success: 'oklch(0.65 0.15 145)',
warning: 'oklch(0.75 0.12 70)',
destructive: 'oklch(0.6 0.18 25)',
},
dark: {
background: 'oklch(0.14 0.005 195)', // Noir légèrement teinté
card: 'oklch(0.18 0.006 195)', // Gris-teal foncé
sidebar: 'oklch(0.12 0.005 195)',
input: 'oklch(0.2 0.006 195)',
foreground: 'oklch(0.97 0.003 195)', // Blanc légèrement teinté
'foreground-secondary': 'oklch(0.75 0.006 195)',
'foreground-muted': 'oklch(0.55 0.008 195)',
primary: 'oklch(0.65 0.14 195)', // Teal plus clair
'primary-hover': 'oklch(0.7 0.16 195)',
'primary-foreground': 'oklch(0.1 0 0)',
accent: 'oklch(0.24 0.006 195)',
'accent-foreground': 'oklch(0.97 0.003 195)',
border: 'oklch(0.28 0.01 195)',
'border-hover': 'oklch(0.38 0.012 195)',
success: 'oklch(0.7 0.15 145)',
warning: 'oklch(0.8 0.12 70)',
destructive: 'oklch(0.65 0.18 25)',
},
} as const;
// =============================================================================
// RÉSUMÉ DES OPTIONS
// =============================================================================
/**
* Comparaison des options :
*
* | Option | Modernité | Professionnalisme | Fatigue oculaire | Unicité |
* |--------|-----------|-------------------|------------------|----------|
* | Slate (Gris-Bleu) | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
* | Monochrome | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
* | Indigo | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
* | Teal | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
*
* Recommandation : Slate (Gris-Bleu)
* - Le plus professionnel
* - Fatigue oculaire minimale
* - Très moderne et tendance
* - Différent du bleu traditionnel
* - Cohérent avec votre suggestion
*/
export type ThemeOption = 'slate' | 'monochrome' | 'indigo' | 'teal';
/**
* Pour choisir le thème :
*
* function getTheme(option: ThemeOption) {
* switch(option) {
* case 'slate': return SLATE_THEME;
* case 'monochrome': return MONOCHROME_THEME;
* case 'indigo': return INDIGO_THEME;
* case 'teal': return TEAL_THEME;
* }
* }
*/