ionic-planb-logistic-app-fl.../lib/theme/spacing_system.dart
Jean-Philippe Brule 3f31a509e0 Implement premium UI/UX refinements for Apple-like polish
Add three major UI components with animations and dark mode support:

- PremiumRouteCard: Enhanced route cards with left accent bar, delivery count badge, animated hover effects (1.02x scale), and dynamic shadow elevation
- DarkModeMapComponent: Google Maps integration with dark theme styling, custom info panels, navigation buttons, and delivery status indicators
- DeliveryListItem: Animated list items with staggered entrance animations, status badges with icons, contact indicators, and hover states

Updates:
- RoutesPage: Now uses PremiumRouteCard with improved visual hierarchy
- DeliveriesPage: Integrated DarkModeMapComponent and DeliveryListItem with proper theme awareness
- Animation system: Leverages existing AppAnimations constants for 200ms fast interactions and easeOut curves

Design philosophy:
- Element separation through left accent bars (status-coded)
- Elevation and shadow for depth (0.1-0.3 opacity)
- Staggered animations for list items (50ms delays)
- Dark mode optimized for evening use (reduced brightness)
- Responsive hover states with tactile feedback

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-15 14:41:32 -05:00

297 lines
8.9 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
/// Svrnty Spacing System - 4px Grid
/// All spacing, sizing, and border radius values follow a strict 4px grid
class AppSpacing {
// Prevent instantiation
AppSpacing._();
// ============================================
// BASE SPACING SCALE (4px grid)
// ============================================
/// Extra small spacing (4px) - unit × 1
static const double xs = 4.0;
/// Small spacing (8px) - unit × 2
static const double sm = 8.0;
/// Medium spacing (16px) - unit × 4 - DEFAULT
static const double md = 16.0;
/// Large spacing (24px) - unit × 6
static const double lg = 24.0;
/// Extra large spacing (32px) - unit × 8
static const double xl = 32.0;
/// Double extra large (48px) - unit × 12
static const double xxl = 48.0;
/// Triple extra large (64px) - unit × 16
static const double xxxl = 64.0;
// ============================================
// COMPONENT-SPECIFIC SPACING
// ============================================
/// Padding inside cards
static const double cardPadding = md; // 16px
/// Horizontal button padding
static const double buttonPaddingX = lg; // 24px
/// Vertical button padding
static const double buttonPaddingY = 12.0; // sm × 1.5
/// Padding in input fields
static const double inputPadding = md; // 16px
/// Standard icon size
static const double iconSize = lg; // 24px
/// Large icon size
static const double iconSizeLarge = xl; // 32px
/// Dialog content padding
static const double dialogPadding = lg; // 24px
/// Standard app bar height
static const double appBarHeight = 56.0;
/// List item padding
static const double listItemPadding = md; // 16px
// ============================================
// PRE-BUILT EDGEINSETS - ALL SIDES
// ============================================
/// EdgeInsets.all(4px)
static const EdgeInsets paddingAllXs = EdgeInsets.all(xs);
/// EdgeInsets.all(8px)
static const EdgeInsets paddingAllSm = EdgeInsets.all(sm);
/// EdgeInsets.all(16px)
static const EdgeInsets paddingAllMd = EdgeInsets.all(md);
/// EdgeInsets.all(24px)
static const EdgeInsets paddingAllLg = EdgeInsets.all(lg);
/// EdgeInsets.all(32px)
static const EdgeInsets paddingAllXl = EdgeInsets.all(xl);
/// EdgeInsets.all(48px)
static const EdgeInsets paddingAllXxl = EdgeInsets.all(xxl);
// ============================================
// PRE-BUILT EDGEINSETS - HORIZONTAL
// ============================================
/// EdgeInsets.symmetric(horizontal: 4px)
static const EdgeInsets paddingHorizontalXs =
EdgeInsets.symmetric(horizontal: xs);
/// EdgeInsets.symmetric(horizontal: 8px)
static const EdgeInsets paddingHorizontalSm =
EdgeInsets.symmetric(horizontal: sm);
/// EdgeInsets.symmetric(horizontal: 16px)
static const EdgeInsets paddingHorizontalMd =
EdgeInsets.symmetric(horizontal: md);
/// EdgeInsets.symmetric(horizontal: 24px)
static const EdgeInsets paddingHorizontalLg =
EdgeInsets.symmetric(horizontal: lg);
/// EdgeInsets.symmetric(horizontal: 32px)
static const EdgeInsets paddingHorizontalXl =
EdgeInsets.symmetric(horizontal: xl);
// ============================================
// PRE-BUILT EDGEINSETS - VERTICAL
// ============================================
/// EdgeInsets.symmetric(vertical: 4px)
static const EdgeInsets paddingVerticalXs =
EdgeInsets.symmetric(vertical: xs);
/// EdgeInsets.symmetric(vertical: 8px)
static const EdgeInsets paddingVerticalSm =
EdgeInsets.symmetric(vertical: sm);
/// EdgeInsets.symmetric(vertical: 16px)
static const EdgeInsets paddingVerticalMd =
EdgeInsets.symmetric(vertical: md);
/// EdgeInsets.symmetric(vertical: 24px)
static const EdgeInsets paddingVerticalLg =
EdgeInsets.symmetric(vertical: lg);
/// EdgeInsets.symmetric(vertical: 32px)
static const EdgeInsets paddingVerticalXl =
EdgeInsets.symmetric(vertical: xl);
// ============================================
// PRE-BUILT EDGEINSETS - COMPONENT SPECIFIC
// ============================================
/// Card padding (16px all sides)
static const EdgeInsets paddingCard = paddingAllMd;
/// Button padding (horizontal: 24px, vertical: 12px)
static const EdgeInsets paddingButton =
EdgeInsets.symmetric(horizontal: lg, vertical: buttonPaddingY);
/// List item padding (horizontal: 16px, vertical: 8px)
static const EdgeInsets paddingListItem =
EdgeInsets.symmetric(horizontal: md, vertical: sm);
/// Dialog padding (24px all sides)
static const EdgeInsets paddingDialog = paddingAllLg;
// ============================================
// SPACER WIDGETS - UNIVERSAL (SQUARE)
// ============================================
/// SizedBox(width: 4, height: 4)
static const Widget spacerXs = SizedBox(width: xs, height: xs);
/// SizedBox(width: 8, height: 8)
static const Widget spacerSm = SizedBox(width: sm, height: sm);
/// SizedBox(width: 16, height: 16)
static const Widget spacerMd = SizedBox(width: md, height: md);
/// SizedBox(width: 24, height: 24)
static const Widget spacerLg = SizedBox(width: lg, height: lg);
/// SizedBox(width: 32, height: 32)
static const Widget spacerXl = SizedBox(width: xl, height: xl);
// ============================================
// SPACER WIDGETS - VERTICAL
// ============================================
/// SizedBox(height: 4)
static const Widget vSpacerXs = SizedBox(height: xs);
/// SizedBox(height: 8)
static const Widget vSpacerSm = SizedBox(height: sm);
/// SizedBox(height: 16)
static const Widget vSpacerMd = SizedBox(height: md);
/// SizedBox(height: 24)
static const Widget vSpacerLg = SizedBox(height: lg);
/// SizedBox(height: 32)
static const Widget vSpacerXl = SizedBox(height: xl);
/// SizedBox(height: 48)
static const Widget vSpacerXxl = SizedBox(height: xxl);
/// SizedBox(height: 64)
static const Widget vSpacerXxxl = SizedBox(height: xxxl);
// ============================================
// SPACER WIDGETS - HORIZONTAL
// ============================================
/// SizedBox(width: 4)
static const Widget hSpacerXs = SizedBox(width: xs);
/// SizedBox(width: 8)
static const Widget hSpacerSm = SizedBox(width: sm);
/// SizedBox(width: 16)
static const Widget hSpacerMd = SizedBox(width: md);
/// SizedBox(width: 24)
static const Widget hSpacerLg = SizedBox(width: lg);
/// SizedBox(width: 32)
static const Widget hSpacerXl = SizedBox(width: xl);
/// SizedBox(width: 48)
static const Widget hSpacerXxl = SizedBox(width: xxl);
/// SizedBox(width: 64)
static const Widget hSpacerXxxl = SizedBox(width: xxxl);
// ============================================
// GAPS FOR ROW/COLUMN SPACING
// ============================================
/// Gap for Row/Column (4px)
static const double gapXs = xs;
/// Gap for Row/Column (8px)
static const double gapSm = sm;
/// Gap for Row/Column (16px)
static const double gapMd = md;
/// Gap for Row/Column (24px)
static const double gapLg = lg;
/// Gap for Row/Column (32px)
static const double gapXl = xl;
// ============================================
// RESPONSIVE SCREEN MARGINS
// ============================================
/// Screen margin for mobile devices (< 600px)
static const double screenMarginMobile = md; // 16px
/// Screen margin for tablets (600-1024px)
static const double screenMarginTablet = lg; // 24px
/// Screen margin for desktop (> 1024px)
static const double screenMarginDesktop = xl; // 32px
/// Max content width constraint
static const double maxContentWidth = 1200.0;
/// Compact content width for forms/compact layouts
static const double compactContentWidth = 600.0;
// ============================================
// RESPONSIVE PADDING FOR SCREENS
// ============================================
/// Screen padding for mobile
static const EdgeInsets screenPaddingMobile =
EdgeInsets.symmetric(horizontal: screenMarginMobile);
/// Screen padding for tablet
static const EdgeInsets screenPaddingTablet =
EdgeInsets.symmetric(horizontal: screenMarginTablet);
/// Screen padding for desktop
static const EdgeInsets screenPaddingDesktop =
EdgeInsets.symmetric(horizontal: screenMarginDesktop);
// ============================================
// UTILITY METHODS
// ============================================
/// Get responsive screen margin based on screen width
static double getScreenMargin(double screenWidth) {
if (screenWidth < 600) {
return screenMarginMobile;
} else if (screenWidth < 1024) {
return screenMarginTablet;
} else {
return screenMarginDesktop;
}
}
/// Get responsive screen padding based on screen width
static EdgeInsets getScreenPadding(double screenWidth) {
final margin = getScreenMargin(screenWidth);
return EdgeInsets.symmetric(horizontal: margin);
}
}