colveor 0.1.0
colveor: ^0.1.0 copied to clipboard
Flutter foundation for production apps: authentication, Dio networking with DPoP, push notifications and bootstrap, built on colveor_ui.
Colveor #
A Flutter foundation package for building production-ready mobile apps. Colveor provides authentication flows, networking, push notifications, and app bootstrap on top of colveor_ui — so you can focus on your product screens instead of rebuilding common infrastructure.
The UI toolkit (widgets, theming, routing) lives in colveor_ui, which apps that don't need the API or auth layer can use on its own. Colveor depends on it and re-exports it, so apps built on Colveor only import package:colveor/....
The example/ app shows how to wire everything together.
Features #
- Authentication — phone sign-in/sign-up, OTP verification, session storage, and token refresh
- Networking — Dio-based API client with interceptors, DPoP proofs, error handling, and secure token storage
- Notifications — Firebase Cloud Messaging setup, permission prompt, and device registration
- Bootstrap — Firebase and network initialization on top of the colveor_ui bootstrap
- From colveor_ui — UI toolkit, theming with light/dark mode, and
go_routerrouting with redirect callbacks - State management — Riverpod with generated providers
Project structure #
colveor/
├── lib/ # The package (imported by your app)
│ ├── colveor.dart # Main entry — bootstrap, ColveorApp, ColveorRef
│ ├── auth.dart # Auth module exports
│ ├── notifications.dart # Notifications module exports
│ ├── config.dart # VoConfig, Firebase config, interceptor hooks
│ ├── extensions.dart # colveor_ui extensions + auth/controller extensions
│ ├── theme.dart, routing.dart, # Re-exports of colveor_ui
│ │ utils.dart, widgets/*.dart
│ └── src/
│ ├── core/ # Foundation layer
│ │ ├── bootstrap/ # Firebase & network setup
│ │ ├── config/ # VoConfig (extends colveor_ui's VoConfig)
│ │ ├── errors/ # Exceptions & API error responses
│ │ ├── models/ # Pagination & file models
│ │ ├── network/ # API client, interceptors, DPoP, tokens
│ │ └── utils/ # JWT helper
│ ├── modules/ # Feature modules
│ │ ├── auth/ # Auth services, controllers, and UI
│ │ └── notifications/ # Push notification controller & services
│ └── ui/extensions/ # Auth & controller BuildContext extensions
│
└── example/ # Demo app using the package
└── lib/
├── main.dart # App entry point
├── config/ # App-specific config
├── theme/ # App-specific colors & typography
├── routes/ # App-specific routes
└── modules/ # App-specific screens
| Layer | Role |
|---|---|
colveor_ui |
Widgets, theme, routing, base widgets, formatters, country data |
lib/src/core/ |
API, auth and Firebase infrastructure |
lib/src/modules/ |
Big features like authentication and notifications |
example/ |
Your real app — config, theme, routes, and screens |
Getting started #
Prerequisites #
- Dart SDK
^3.12.2 - Firebase is only needed if you use push notifications
Installation #
Add colveor from pub.dev:
flutter pub add colveor
or add it to pubspec.yaml yourself:
dependencies:
colveor: ^0.1.0
colveor_ui (^0.1.0) comes in as a dependency, so you don't need to add it.
To work against a local checkout instead, use a path dependency:
dependencies:
colveor:
path: ../colveor_flutter
Run the example app #
cd example
flutter pub get
flutter run
Usage #
1. Bootstrap the app #
Call VoBootstrap.initialize() before runApp. It runs the colveor_ui bootstrap, then sets up Firebase (optional) and the network layer.
Country data for the phone input loads the first time VoPhoneInput or VoSelectCountryField is built. Pass preloadCountries: true to load it during bootstrap instead.
import 'package:colveor/colveor.dart';
import 'package:example/config/app_config.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await VoBootstrap.initialize(config: AppConfig());
runApp(
ColveorApp(
config: AppConfig(),
appRoutes: appRoutes,
builder: (context, colveor) => App(colveor: colveor),
),
);
}
2. Implement app config #
Extend VoConfig in your app to provide API URLs, routing, and feature flags. Colveor's VoConfig extends the colveor_ui one, so the same object configures both layers; pass it to ColveorApp and it is read through voConfigProvider.
import 'package:colveor/config.dart';
class AppConfig extends VoConfig {
@override
String get appName => 'My App';
@override
String get apiBaseUrl => 'https://api.example.com';
@override
String get apiVersion => 'api/v1';
@override
VoRoutingConfig get routing => VoRoutingConfig(
initialLocation: '/',
// Optional: re-run redirects when auth state changes.
onInit: (ref, notifier) =>
ref.listen(authControllerProvider, (_, _) => notifier.notify()),
// Optional: return a location to redirect, or null to continue.
redirect: (ref, context, state) => null,
);
}
3. Define your theme #
Every theme part has a default. Subclass VoColors, VoSizes, VoTypography, or VoComponentTheme only where you need to brand, and return them from your VoTheme.
import 'package:colveor/theme.dart';
class AppColors extends VoColors {
@override
VoColorMode get primaryMode => VoColorMode(
light: const Color(0xFF132B50),
dark: const Color(0xFF4DA3FF),
);
// ... override other color modes
}
class AppTheme extends VoTheme {
const AppTheme();
@override
VoColors get colors => const AppColors();
}
Wire the theme into MaterialApp.router:
class App extends StatelessWidget {
final ColveorRef colveor;
const App({super.key, required this.colveor});
@override
Widget build(BuildContext context) => MaterialApp.router(
title: AppConfig().appName,
theme: const AppTheme().light,
darkTheme: const AppTheme().dark,
themeMode: colveor.themeMode,
routerConfig: colveor.router,
);
}
4. Add routes #
Define route path constants and pass a route list to ColveorApp. The router is created automatically from your routes and VoRoutingConfig.
import 'package:colveor/colveor.dart';
List<RouteBase> appRoutes(_) => [
GoRoute(
path: '/',
builder: (context, state) => const SplashScreen(),
),
GoRoute(
path: '/login',
builder: (context, state) => const AuthScreen(),
),
];
5. Set up authentication #
Use VoAuthScreen with custom page builders for each step in the auth flow. The example app uses phone sign-in, OTP verification, and sign-up.
import 'package:colveor/auth.dart';
import 'package:colveor/colveor.dart';
class AuthScreen extends StatelessWidget {
const AuthScreen({super.key});
@override
Widget build(BuildContext context) => Scaffold(
body: VoAuthScreen(
initialPage: VoAuthPageKeys.phoneSignIn,
pages: VoAuthPages.phone(
phoneBuilder: (_) => const PhoneSignInPage(),
verifyOtpBuilder: (_) => const VerifyOtpPage(),
signUpBuilder: (_) => const PhoneSignUpPage(),
),
onAuthSuccess: (_, _) => context.vo.pushReplace('/home'),
),
);
}
Inside auth pages, access the auth context and Colveor widgets:
import 'package:colveor/auth.dart';
import 'package:colveor/widgets/buttons.dart';
import 'package:colveor/widgets/inputs.dart';
class PhoneSignInPage extends StatefulWidget {
const PhoneSignInPage({super.key});
@override
State<PhoneSignInPage> createState() => _PhoneSignInPageState();
}
class _PhoneSignInPageState extends VoState<PhoneSignInPage> {
final _phoneController = TextEditingController();
@override
Widget build(BuildContext context) {
final auth = VoAuthScope.of(context);
return VoPhoneInput(
controller: _phoneController,
options: const VoFieldOptions(label: 'Phone'),
);
// ...
}
}
6. Use UI widgets #
Import widgets from the public widgets/ barrel files (re-exported from colveor_ui):
import 'package:colveor/widgets/buttons.dart'; // VoButton, VoIconButton
import 'package:colveor/widgets/inputs.dart'; // VoTextField, VoPhoneInput, VoPinInput, ...
import 'package:colveor/widgets/layout.dart'; // VoScaffold, VoScrollableForm, VoTile, ...
import 'package:colveor/widgets/display.dart'; // VoText, VoAvatar, VoDivider, ...
import 'package:colveor/widgets/overlay.dart'; // Dialogs, bottom sheets, overlay lists
import 'package:colveor/widgets/feedback.dart'; // VoToast, feedback views, countdown actions
import 'package:colveor/widgets/page_flow.dart'; // Multi-step page flows
import 'package:colveor/widgets/dashboard.dart'; // VoDashboardShell, VoDashboardPane
7. Use the context helpers #
In any widget, context.vo gives you the theme, screen size, navigation, and toast helpers for that context:
class MyScreen extends StatelessWidget {
const MyScreen({super.key});
@override
Widget build(BuildContext context) => VoButton(
label: 'Go home',
onPressed: () => context.vo.pushReplace('/home'),
);
}
In a State, extend VoState (or VoConsumerState with Riverpod) to use the same helpers as members, e.g. pushReplace('/home').
8. Adjust screen scaling #
ColveorApp scales sizes against a 360×690 design by default. Pass designSize (and optionally minTextAdapt / splitScreenMode) to match your designs:
ColveorApp(
config: AppConfig(),
appRoutes: appRoutes,
designSize: const Size(390, 844),
builder: (context, colveor) => App(colveor: colveor),
)
Public API overview #
| Import | What you get |
|---|---|
package:colveor/colveor.dart |
ColveorApp, VoBootstrap, ColveorRef, VoConfig, VoState / VoConsumerState, everything in routing.dart |
package:colveor/auth.dart |
Auth controllers, services, VoAuthScreen, VoAuthContext |
package:colveor/notifications.dart |
Notification controller, permission prompt |
package:colveor/config.dart |
VoConfig, VoRoutingConfig, VoFirebaseConfig, VoInterceptorHooks, Environment |
package:colveor/extensions.dart |
colveor_ui extensions (context.vo, context.colorScheme, ...), plus context.currentUser, context.logout(), context.voConfig |
package:colveor/theme.dart |
VoTheme, VoColors, VoSizes, VoTypography (colveor_ui) |
package:colveor/routing.dart |
voRouterProvider, voNavigatorKey, go_router types (colveor_ui) |
package:colveor/utils.dart |
VoLogger, VoValidators, formatters (colveor_ui) |
package:colveor/widgets/*.dart |
UI components grouped by category (colveor_ui) |
Import from package:colveor/... only. Importing package:colveor_ui/... alongside it causes name clashes, because both define VoConfig and VoBootstrap.
Environment flavors #
Set the build flavor via --dart-define:
flutter run --dart-define=FLAVOR=production
Defaults to development when not set. Read the current environment with Environment.current.
Additional information #
- See the
example/app for a full working integration - Auth API endpoints are configured via
VoConfig.endpoints— override in yourAppConfigif your backend paths differ - Firebase and push notifications are optional — set
firebaseConfigin your config when needed
License #
MIT — see LICENSE.