107 lines
2.5 KiB
Dart
107 lines
2.5 KiB
Dart
/// Small pure helpers for layout, formatting, and user-facing strings.
|
|
library;
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'constants.dart';
|
|
|
|
/// Horizontal padding that grows a little on wider screens.
|
|
double pagePadding(double width) {
|
|
if (width >= Breakpoints.medium) return 32;
|
|
if (width >= Breakpoints.compact) return 24;
|
|
return 16;
|
|
}
|
|
|
|
/// Formats [date] as `MMM d, y` without pulling in `intl`.
|
|
String formatDate(DateTime date) {
|
|
const months = [
|
|
'Jan',
|
|
'Feb',
|
|
'Mar',
|
|
'Apr',
|
|
'May',
|
|
'Jun',
|
|
'Jul',
|
|
'Aug',
|
|
'Sep',
|
|
'Oct',
|
|
'Nov',
|
|
'Dec',
|
|
];
|
|
return '${months[date.month - 1]} ${date.day}, ${date.year}';
|
|
}
|
|
|
|
/// Converts a stored theme key into a [ThemeMode].
|
|
ThemeMode themeModeFromName(String name) {
|
|
return switch (name) {
|
|
'light' => ThemeMode.light,
|
|
'dark' => ThemeMode.dark,
|
|
_ => ThemeMode.system,
|
|
};
|
|
}
|
|
|
|
/// Inverse of [themeModeFromName] for persistence.
|
|
String nameFromThemeMode(ThemeMode mode) {
|
|
return switch (mode) {
|
|
ThemeMode.light => 'light',
|
|
ThemeMode.dark => 'dark',
|
|
ThemeMode.system => 'system',
|
|
};
|
|
}
|
|
|
|
/// Title-cases a [ThemeMode] for settings labels.
|
|
String labelForThemeMode(ThemeMode mode) {
|
|
return switch (mode) {
|
|
ThemeMode.light => 'Light',
|
|
ThemeMode.dark => 'Dark',
|
|
ThemeMode.system => 'System',
|
|
};
|
|
}
|
|
|
|
/// Formats a money amount with currency code, e.g. `1 234,56 EUR`.
|
|
String formatMoney(double amount, String currency) {
|
|
final sign = amount < 0 ? '-' : '';
|
|
final abs = amount.abs();
|
|
final fixed = abs.toStringAsFixed(2);
|
|
final parts = fixed.split('.');
|
|
final whole = parts[0];
|
|
final fraction = parts.length > 1 ? parts[1] : '00';
|
|
|
|
final buffer = StringBuffer();
|
|
for (var i = 0; i < whole.length; i++) {
|
|
final fromEnd = whole.length - i;
|
|
buffer.write(whole[i]);
|
|
if (fromEnd > 1 && fromEnd % 3 == 1) {
|
|
buffer.write('\u00a0');
|
|
}
|
|
}
|
|
return '$sign${buffer.toString()},$fraction $currency';
|
|
}
|
|
|
|
/// Formats [date] as `MMMM y`, e.g. `September 2026`.
|
|
String formatMonthYear(DateTime date) {
|
|
const months = [
|
|
'January',
|
|
'February',
|
|
'March',
|
|
'April',
|
|
'May',
|
|
'June',
|
|
'July',
|
|
'August',
|
|
'September',
|
|
'October',
|
|
'November',
|
|
'December',
|
|
];
|
|
return '${months[date.month - 1]} ${date.year}';
|
|
}
|
|
|
|
/// Formats an ISO date string (`yyyy-MM-dd` or full ISO) for list rows.
|
|
String formatIsoDate(String raw) {
|
|
if (raw.isEmpty) return '';
|
|
final parsed = DateTime.tryParse(raw);
|
|
if (parsed == null) return raw;
|
|
return formatDate(parsed);
|
|
}
|