Files
unionflow-mobile-apps/lib/shared/design_system/components/uf_header.dart
2026-03-31 09:14:47 +00:00

127 lines
3.6 KiB
Dart

import 'package:flutter/material.dart';
import '../unionflow_design_system.dart';
/// Header harmonisé UnionFlow
///
/// Composant header standardisé pour toutes les pages de l'application.
/// Garantit la cohérence visuelle et l'expérience utilisateur.
class UFHeader extends StatelessWidget {
final String title;
final String? subtitle;
final IconData icon;
final List<Widget>? actions;
final VoidCallback? onNotificationTap;
final VoidCallback? onSettingsTap;
final bool showActions;
const UFHeader({
super.key,
required this.title,
this.subtitle,
required this.icon,
this.actions,
this.onNotificationTap,
this.onSettingsTap,
this.showActions = true,
});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(SpacingTokens.lg),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [AppColors.primaryGreen, AppColors.brandGreenLight],
),
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
),
child: Row(
children: [
// Icône et contenu principal
Container(
padding: const EdgeInsets.all(SpacingTokens.sm),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(SpacingTokens.radiusSm),
),
child: Icon(
icon,
color: Colors.white,
size: 18,
),
),
const SizedBox(width: SpacingTokens.lg),
// Titre et sous-titre
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: AppTypography.headerSmall.copyWith(
color: Colors.white,
),
),
if (subtitle != null) ...[
const SizedBox(height: SpacingTokens.xs),
Text(
subtitle!,
style: AppTypography.subtitleSmall.copyWith(
color: Colors.white.withOpacity(0.8),
),
),
],
],
),
),
// Actions
if (showActions) _buildActions(),
],
),
);
}
Widget _buildActions() {
if (actions != null) {
return Row(children: actions!);
}
return Row(
children: [
if (onNotificationTap != null)
Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(SpacingTokens.radiusXs),
),
child: IconButton(
onPressed: onNotificationTap,
icon: const Icon(
Icons.notifications_outlined,
color: Colors.white,
),
),
),
if (onNotificationTap != null && onSettingsTap != null)
const SizedBox(width: SpacingTokens.sm),
if (onSettingsTap != null)
Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(SpacingTokens.radiusXs),
),
child: IconButton(
onPressed: onSettingsTap,
icon: const Icon(
Icons.settings_outlined,
color: Colors.white,
),
),
),
],
);
}
}