Aller au contenu principal

🎨 Design System Kazalendar - Documentation Complète

Vue d'ensemble

Ce design system fournit une base cohérente et réutilisable pour toute l'application Kazalendar. Il est composé de tokens, composants et patterns qui garantissent une expérience utilisateur uniforme et professionnelle.


📐 Architecture du Design System

core/
├── theme/
│ ├── spacing.dart # Système de spacing 4pt grid
│ ├── design_tokens.dart # Tokens sémantiques (couleurs, shadows)
│ ├── typography.dart # Hiérarchie typographique
│ └── app_theme.dart # Theme principal (existant)
├── widgets/
│ ├── badge.dart # Système de badges/pills
│ ├── app_card.dart # Cards uniformisées
│ ├── touchable.dart # Composants tactiles
│ ├── status_indicator.dart # Indicateurs de statut
│ └── shimmer_loading.dart # Loading states
└── services/
└── haptic_service.dart # Feedback haptique

🎯 1. Design Tokens

Fichier: design_tokens.dart

Couleurs Sémantiques

Succès (Vert)

DesignTokens.successLight  // #ECFDF5 - Fond
DesignTokens.successBase // #10B981 - Base
DesignTokens.successDark // #065F46 - Texte

Erreur (Rouge)

DesignTokens.errorLight  // #FEF2F2
DesignTokens.errorBase // #EF4444
DesignTokens.errorDark // #991B1B

Avertissement (Orange)

DesignTokens.warningLight  // #FEF3C7
DesignTokens.warningBase // #F59E0B
DesignTokens.warningDark // #92400E

Information (Bleu)

DesignTokens.infoLight  // #DCEEFB
DesignTokens.infoBase // #3B82F6
DesignTokens.infoDark // #1E40AF

Neutre (Gris)

DesignTokens.neutral100   // #F3F4F6 - Très clair
DesignTokens.neutral200 // #E5E7EB
DesignTokens.neutral300 // #D1D5DB
DesignTokens.neutral400 // #9CA3AF
DesignTokens.neutral500 // #6B7280 - Moyen
DesignTokens.neutral600 // #4B5563
DesignTokens.neutral700 // #374151 - Foncé
DesignTokens.neutral800 // #1F2937

Shadows & Elevation

DesignTokens.shadowXs   // Hover states
DesignTokens.shadowSm // Cards, buttons
DesignTokens.shadowMd // Floating elements
DesignTokens.shadowLg // Modals, drawers
DesignTokens.shadowXl // Popovers

Usage:

Container(
decoration: BoxDecoration(
boxShadow: DesignTokens.shadowSm,
borderRadius: BorderRadius.circular(12),
),
)

Icons & Tailles

DesignTokens.iconXs   // 16dp
DesignTokens.iconSm // 20dp
DesignTokens.iconMd // 24dp
DesignTokens.iconLg // 32dp
DesignTokens.iconXl // 48dp

Durées d'Animation

DesignTokens.durationInstant  // 100ms
DesignTokens.durationFast // 200ms
DesignTokens.durationNormal // 300ms
DesignTokens.durationSlow // 500ms

📏 2. Spacing (4pt Grid)

Fichier: spacing.dart

Scale de Spacing

AppSpacing.xs    //  4dp - Minimal
AppSpacing.sm // 8dp - Tight
AppSpacing.md // 12dp - Compact
AppSpacing.lg // 16dp - Default
AppSpacing.xl // 20dp - Comfortable
AppSpacing.xxl // 24dp - Generous
AppSpacing.xxxl // 32dp - Section

Spacing Sémantique

AppSpacing.componentPadding  // 16dp
AppSpacing.sectionSpacing // 24dp
AppSpacing.cardPadding // 16dp
AppSpacing.pageMargin // 16dp

Border Radius

AppSpacing.radiusXs   //  4dp
AppSpacing.radiusSm // 8dp
AppSpacing.radiusMd // 12dp
AppSpacing.radiusLg // 16dp
AppSpacing.radiusXl // 20dp
AppSpacing.radiusFull // 999dp (cercle)

Helpers de Spacing

Spacing vertical/horizontal:

VSpace.lg  // SizedBox(height: 16)
HSpace.md // SizedBox(width: 12)

Padding pré-configurés:

AppPadding.all      // EdgeInsets.all(16)
AppPadding.card // EdgeInsets.all(16)
AppPadding.page // EdgeInsets.all(16)
AppPadding.button // EdgeInsets.symmetric(h:16, v:12)

✏️ 3. Typographie

Fichier: typography.dart

Hiérarchie des Titres

AppTypography.display1  // 40px, Bold - Pages principales
AppTypography.display2 // 32px, Bold

AppTypography.h1 // 28px, Bold
AppTypography.h2 // 24px, Semibold
AppTypography.h3 // 20px, Semibold
AppTypography.h4 // 18px, Semibold
AppTypography.h5 // 16px, Semibold
AppTypography.h6 // 14px, Semibold

Texte Courant

AppTypography.bodyLarge   // 16px, Regular
AppTypography.bodyMedium // 14px, Regular
AppTypography.bodySmall // 12px, Regular

Labels & Captions

AppTypography.labelLarge   // 14px, Semibold
AppTypography.labelMedium // 12px, Semibold
AppTypography.labelSmall // 11px, Semibold

AppTypography.caption // 12px, Regular
AppTypography.overline // 10px, Semibold, UPPERCASE

Widgets de Texte

AppText.h1('Titre Principal')
AppText.bodyMedium('Description')
AppText.caption('Note')

Helpers de Couleur

AppTypography.primary(style, color)  // Couleur personnalisée
AppTypography.secondary(style) // Texte secondaire
AppTypography.success(style) // Texte de succès
AppTypography.error(style) // Texte d'erreur

🏷️ 4. Badges

Fichier: badge.dart

Badge Générique

Badge(
label: 'En attente',
variant: BadgeVariant.warning,
icon: Icons.schedule,
size: BadgeSize.md,
outlined: false,
)

Variantes:

  • BadgeVariant.success - Vert
  • BadgeVariant.error - Rouge
  • BadgeVariant.warning - Orange
  • BadgeVariant.info - Bleu
  • BadgeVariant.neutral - Gris
  • BadgeVariant.primary - Primaire

Tailles:

  • BadgeSize.sm - Petit (11px)
  • BadgeSize.md - Moyen (12px)
  • BadgeSize.lg - Grand (14px)

Constructeurs Named

Badge.success(label: 'Validé')
Badge.error(label: 'Refusé')
Badge.warning(label: 'En attente')
Badge.info(label: 'Information')

Badges Spécialisés

StatusBadge - Pour les statuts de commande:

StatusBadge(
status: CommandeStatus.accepted,
size: BadgeSize.md,
outlined: false,
)

SourceBadge - Pour identifier la source:

SourceBadge(
isAgentIA: true, // Affiche "Agent IA" ou "Manuel"
size: BadgeSize.md,
)

🃏 5. Cards

Fichier: app_card.dart

Card Basique

AppCard(
child: Text('Contenu'),
variant: CardVariant.elevated,
elevation: CardElevation.sm,
onTap: () => print('Tapped'),
)

Variantes:

  • CardVariant.elevated - Avec ombre
  • CardVariant.outlined - Avec bordure
  • CardVariant.filled - Avec fond coloré

Elevations:

  • CardElevation.none
  • CardElevation.sm
  • CardElevation.md
  • CardElevation.lg

Constructeurs Named

AppCard.elevated(child: ...)  // Card avec ombre
AppCard.outlined(child: ...) // Card avec bordure
AppCard.filled(child: ..., backgroundColor: Colors.blue.shade50)

Cards Spécialisées

InfoCard - Card d'information avec icône:

InfoCard(
title: 'Client',
subtitle: 'Jean Dupont',
icon: Icons.person,
iconColor: Colors.blue,
onTap: () => print('Tapped'),
trailing: Icon(Icons.chevron_right),
)

StatCard - Card statistique:

StatCard(
label: 'Commandes',
value: '24',
icon: Icons.shopping_cart,
color: Colors.blue,
onTap: () => print('Tapped'),
)

ListCard - Card compacte pour listes:

ListCard(
title: 'Gâteau d\'anniversaire',
subtitle: '15 janvier 2025',
leading: Icon(Icons.cake),
trailing: Badge.success(label: 'Payé'),
onTap: () => print('Tapped'),
)

👆 6. Composants Touchables

Fichier: touchable.dart

Touchable Générique

Garantit un touch target de 48x48dp minimum:

Touchable(
onTap: () => print('Tapped'),
enableHaptic: true,
child: Icon(Icons.star),
)

TouchableIcon

IconButton optimisé avec haptic feedback:

TouchableIcon(
icon: Icons.settings,
onTap: () => print('Settings'),
color: Colors.blue,
backgroundColor: Colors.blue.shade100,
tooltip: 'Paramètres',
size: 20,
)

TouchableButton

Button avec styles pré-configurés:

TouchableButton(
onPressed: () => print('Pressed'),
isPrimary: true, // Style primaire
isOutlined: false, // Outlined ou filled
isDestructive: false, // Style destructif (rouge)
isLoading: false, // Affiche un loader
child: Text('Confirmer'),
)

📊 7. Indicateurs de Statut

Fichier: status_indicator.dart

StatusIndicator

Affiche un message avec statut visuel:

StatusIndicator(
message: 'Commande validée avec succès',
type: StatusType.success,
icon: Icons.check_circle,
compact: false,
)

Types:

  • StatusType.success
  • StatusType.error
  • StatusType.warning
  • StatusType.info
  • StatusType.neutral

Constructeurs named:

StatusIndicator.success(message: '...')
StatusIndicator.error(message: '...')
StatusIndicator.warning(message: '...')
StatusIndicator.info(message: '...')

InlineStatusIndicator

Point coloré pour les listes:

InlineStatusIndicator(
type: StatusType.success,
size: 8.0,
)

ProgressIndicator

Barre de progression avec statut:

ProgressIndicator(
value: 0.75, // 0.0 à 1.0
label: 'Progression',
type: StatusType.info,
showPercentage: true,
)

StatusBanner

Bannière pour les messages importants:

StatusBanner(
message: 'Nouvelle mise à jour disponible',
type: StatusType.info,
onDismiss: () => print('Dismissed'),
action: TextButton(
onPressed: () => print('Action'),
child: Text('Mettre à jour'),
),
)

🎭 8. Patterns d'Usage

Pattern 1: Page avec Cards

Scaffold(
body: SingleChildScrollView(
padding: AppPadding.page,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppText.h2('Mes Commandes'),
VSpace.lg,
ListCard(
title: 'Commande #1',
subtitle: 'Client: Jean',
leading: InlineStatusIndicator(type: StatusType.success),
trailing: StatusBadge(status: CommandeStatus.completed),
onTap: () {},
),
],
),
),
)

Pattern 2: Formulaire avec Statut

Column(
children: [
StatusIndicator.info(
message: 'Remplissez tous les champs obligatoires',
compact: true,
),
VSpace.lg,
TextField(...),
VSpace.md,
TextField(...),
VSpace.xl,
TouchableButton(
onPressed: _submit,
isPrimary: true,
isLoading: _isSubmitting,
child: Text('Valider'),
),
],
)

Pattern 3: Stats Dashboard

GridView.count(
crossAxisCount: 2,
children: [
StatCard(
label: 'Commandes',
value: '42',
icon: Icons.shopping_cart,
color: DesignTokens.infoBase,
),
StatCard(
label: 'Revenu',
value: '1,250€',
icon: Icons.euro,
color: DesignTokens.successBase,
),
],
)

✅ Checklist d'Implémentation

Lors de la création d'une nouvelle fonctionnalité:

  • Utiliser AppSpacing pour tous les espacements
  • Utiliser AppTypography pour tous les textes
  • Utiliser Badge pour les statuts et tags
  • Utiliser AppCard pour regrouper le contenu
  • Utiliser Touchable* pour les éléments interactifs
  • Ajouter HapticService sur les actions importantes
  • Utiliser StatusIndicator pour les messages de retour
  • Utiliser DesignTokens pour les couleurs personnalisées
  • Garder une hiérarchie visuelle claire (h1 → h2 → body)
  • Respecter les touch targets de 48x48dp minimum

🎨 Avant / Après

Avant

// ❌ Inconsistant, difficile à maintenir
Container(
padding: EdgeInsets.all(15),
decoration: BoxDecoration(
color: Colors.blue[100],
borderRadius: BorderRadius.circular(10),
),
child: Text(
'Status',
style: TextStyle(
fontSize: 13,
color: Colors.blue[900],
fontWeight: FontWeight.w600,
),
),
)

Après

// ✅ Cohérent, maintenable, réutilisable
Badge.info(
label: 'Status',
size: BadgeSize.md,
)

📦 Composants Disponibles

ComposantFichierUsage
AppSpacingspacing.dartEspacements cohérents
VSpace / HSpacespacing.dartWidgets de spacing
AppPaddingspacing.dartPadding sémantiques
DesignTokensdesign_tokens.dartCouleurs, shadows
AppTypographytypography.dartStyles de texte
AppTexttypography.dartWidgets de texte
Badgebadge.dartBadges génériques
StatusBadgebadge.dartBadges de statut
SourceBadgebadge.dartBadge source (IA/Manuel)
AppCardapp_card.dartCards génériques
InfoCardapp_card.dartCard d'information
StatCardapp_card.dartCard statistique
ListCardapp_card.dartCard de liste
Touchabletouchable.dartZone touchable
TouchableIcontouchable.dartIcon button optimisé
TouchableButtontouchable.dartButton optimisé
StatusIndicatorstatus_indicator.dartIndicateur de statut
InlineStatusIndicatorstatus_indicator.dartPoint de statut
ProgressIndicatorstatus_indicator.dartBarre de progression
StatusBannerstatus_indicator.dartBannière d'état
HapticServicehaptic_service.dartFeedback haptique
ShimmerLoadingshimmer_loading.dartLoading shimmer

🚀 Prochaines Étapes

  1. Appliquer progressivement le design system aux pages existantes
  2. Former l'équipe aux nouveaux composants
  3. Créer des exemples dans un Storybook Flutter
  4. Documenter les cas d'usage spécifiques
  5. Itérer en fonction des retours

📝 Dernière mise à jour: Janvier 2025 👨‍💻 Auteurs: Claude Code (Expert UX/UI Design) 📖 Version: 2.0