Flutter · colveor_ui
Theming
Every widget reads its look from four token sets. Override only what you need; everything else uses the defaults.
VoTheme
Extend VoTheme and override any of colors, sizes, typography and componentTheme. Use .light and .dark for MaterialApp.
class AppTheme extends VoTheme {
const AppTheme();
@override
VoColors get colors => const AppColors();
@override
VoTypography get typography => const AppTypography();
}
class AppColors extends VoColors {
const AppColors({super.brightness});
@override
AppColors copyWith({Brightness? brightness}) =>
AppColors(brightness: brightness ?? this.brightness);
@override
VoColorMode get primaryMode =>
const VoColorMode(light: Color(xFF4F46E5), dark: Color(xFF818CF8));
}
class AppTypography extends VoTypography {
const AppTypography({super.colors, super.sizes});
@override
String get bodyFontFamily => 'Inter';
@override
AppTypography copyWith({VoColors? colors, VoSizes? sizes}) =>
AppTypography(colors: colors, sizes: sizes);
}Implement copyWith
The theme passes resolved values into each part through copyWith, so every custom colors, typography and component theme class must implement it.
Colors
Each token is a VoColorMode(light:, dark:); override the …Mode getter and read the resolved color (e.g. colors.primary) in widgets.
| Name | Description |
|---|---|
Brand | primary, onPrimary, secondary, onSecondary. |
Surfaces | background, onBackground, surface, onSurface, surfaceVariant, outline, shadow. |
Text | textPrimary, textSecondary, textDisabled, textInverse. |
Status | success, warning, info, error — each with an on… pair. |
Sizes
VoSizes values scale with the screen via ScreenUtil. Override any getter in a subclass.
| Name | Description |
|---|---|
Spacing | xs 4, sm 8, md 16, lg 24, xl 32, xxl 48. |
Radius | radiusXs 4 → radiusXl 24, radiusFull. |
Icons | iconXs 16, iconSm 20, iconMd 24, iconLg 32, iconXl 40 (plus icon45, icon50, icon64). |
Controls | buttonSm / Md / Lg, buttonRadius, inputHeight, inputRadius, inputBorderWidth. |
Text | textXs 11 → text7xl 57. |
Other | card, avatar, app bar, elevation, checkbox, radio, switch, badge, tooltip, snackbar, overlay and screenWidth / screenHeight. |
Typography
VoTypography defines the Material text styles — display, headline, title, body and label in Large / Medium / Small — plus caption, captionMedium and captionSmall. Headings use headlineFontFamily (default "barlow") and body text uses bodyFontFamily (default "nunito").
Note
Fonts are not bundled. Add your font files to your app's pubspec and override the family getters.
Component themes
Extend VoComponentTheme and override its getters to style individual widgets, then return it from VoTheme.componentTheme:
| Name | Description |
|---|---|
toast | VoToastTheme — style, position, duration (3s), stacking, icons, animation. |
overlay | VoOverlayTheme — bottom sheet, dialog and modal decoration, barrier, handle. |
overlayTile | VoOverlayTileTheme — rows in overlay lists. |
phoneInput | VoPhoneInputTheme — flag size and shape, layout ratios, hints. |
pinInput | Cell size, borders and colors for VoPinInput. |
keyboard | VoKeyboardTheme — keypad sizing and colors. |
divider | VoDividerTheme — dash, spacing and color. |
feedback | VoFeedbackTheme — icon and text styles for VoFeedbackView. |
dashboard | VoDashboardTheme — app bar, dock, drawers and scaffold. |
arrowDownIcon / navigateBackIcon | Icons used by select fields and overlays. |
class AppComponentTheme extends VoComponentTheme {
const AppComponentTheme({super.colors, super.sizes, super.typography});
@override
AppComponentTheme copyWith({
VoColors? colors,
VoSizes? sizes,
VoTypography? typography,
}) => AppComponentTheme(colors: colors, sizes: sizes, typography: typography);
@override
VoToastTheme get toast =>
super.toast.copyWith(defaultPosition: VoToastPosition.top);
}Material themes
VoThemeData builds the Material sub-themes (app bar, buttons, inputs, cards, dialogs, bottom sheets, chips and more) from your tokens. Extend it and return your subclass from VoTheme.createThemeData to change them.
Reading the theme
import 'package:colveor_ui/extensions.dart';
Container(
padding: EdgeInsets.all(context.sizes.md),
color: context.colors.surface,
child: Text('Hello', style: context.typography.titleMedium),
);Also available: context.theme, context.colorScheme, context.componentTheme, context.vo.isDarkMode, and color.darken() / color.lighten().
Theme mode
The theme mode starts as ThemeMode.system and is saved with VoStorage, so it survives restarts.
// In a ConsumerWidget / ConsumerState
IconButton(
icon: const Icon(Icons.brightness_6_outlined),
onPressed: ref.toggleThemeMode,
);
ref.setThemeMode(ThemeMode.dark);