flutter_multi_app_core 1.0.0 copy "flutter_multi_app_core: ^1.0.0" to clipboard
flutter_multi_app_core: ^1.0.0 copied to clipboard

A shared Flutter package providing configurable theme, reusable widgets, network client, storage, and utilities for multi-app projects.

app_core #

A shared Flutter package providing configurable theme, reusable widgets, network client, secure storage, and utilities — designed to be consumed by multiple apps from a single codebase.


Installation #

In your app's pubspec.yaml:

dependencies:
  app_core:
    path: ../app_core   # local path
    # or via git:
    # git:
    #   url: https://github.com/your-org/app_core.git

Then import everything with one line:

import 'package:app_core/app_core.dart';

Theme #

Basic setup #

MaterialApp(
  theme: AppTheme.light(),
  darkTheme: AppTheme.dark(),
);

Only primary and secondary are required. Everything else has sensible defaults.

final scheme = AppColorScheme(
  primary: Color(0xFFFF6D00),
  secondary: Color(0xFF00BFA5),
);

MaterialApp(
  theme: AppTheme.light(scheme),
  darkTheme: AppTheme.dark(scheme),
);

Full customisation #

final scheme = AppColorScheme(
  primary: Color(0xFF4A148C),
  onPrimary: Colors.white,
  secondary: Color(0xFF00C853),
  onSecondary: Colors.black,   // if secondary is light
  error: Color(0xFFB71C1C),
  warning: Color(0xFFF57F17),
  info: Color(0xFF0288D1),
  success: Color(0xFF2E7D32),  // defaults to secondary if omitted
);

Accessing extra theme tokens in widgets #

// success, warning, info, divider colors
final ext = context.appTheme;
Container(color: ext.success);
Divider(color: ext.divider);

Widgets #

Buttons #

AppButton(label: 'Submit', onPressed: _submit)
AppButton(label: 'Cancel', onPressed: _cancel, variant: AppButtonVariant.secondary)
AppButton(label: 'Delete', onPressed: _delete, variant: AppButtonVariant.text)
AppButton(label: 'Loading', onPressed: null, isLoading: true)
AppButton(label: 'Icon', onPressed: _go, icon: Icon(Icons.send), size: AppButtonSize.small)

AppIconButton(icon: Icon(Icons.edit), onPressed: _edit)
AppIconButton(icon: Icon(Icons.delete), onPressed: _delete, variant: AppIconButtonVariant.filled)

Fields #

// Standard text field
AppTextField(
  label: 'Email',
  prefixIcon: Icon(Icons.email),
  validator: Validators.compose([Validators.required, Validators.email]),
)

// Password field — visibility toggle built in
AppPasswordField(
  label: 'Password',
  validator: (v) => Validators.minLength(v, 8),
)

// Search field — clear button built in
AppSearchField(
  hint: 'Search products...',
  onChanged: (v) => bloc.add(SearchChanged(v)),
  onSearch: (v) => bloc.add(SearchSubmitted(v)),
)
AppDropdown<String>(
  label: 'Country',
  value: _selected,
  items: ['US', 'UK', 'AU'].map((e) => DropdownMenuItem(value: e, child: Text(e))).toList(),
  onChanged: (v) => setState(() => _selected = v),
)

Card #

AppCard(
  header: Text('Title', style: context.textTheme.titleMedium),
  footer: AppButton(label: 'Action', onPressed: _action),
  onTap: _onTap,
  child: Text('Card body content'),
)

Dialog #

AppDialog.show(
  context,
  title: 'Delete item?',
  content: Text('This cannot be undone.'),
  confirmLabel: 'Delete',
  isDestructive: true,
  onConfirm: _delete,
);

Bottom Sheet #

AppBottomSheet.show(
  context,
  title: 'Options',
  child: Column(children: [...]),
);

States #

AppStateWidget.empty(message: 'No results found')
AppStateWidget.error(onRetry: _reload)
AppStateWidget.noInternet(onRetry: _reload)

Loaders #

AppLoader()                        // circular
AppShimmer(child: YourWidget())    // shimmer effect

Network #

final client = ApiClient.create(
  baseUrl: 'https://api.example.com',
  tokenProvider: () => storage.read(AppConstants.keyAccessToken),
  tokenRefresher: () => authService.refresh(),
  enableLogging: kDebugMode,
);

// All calls return ApiResponse<T> — no try/catch needed
final response = await client.get(
  '/users/me',
  fromJson: (data) => User.fromJson(data),
);

response.when(
  success: (user) => print(user.name),
  failure: (e) => print(e.message),
);

Network connectivity #

final networkInfo = NetworkInfoImpl(Connectivity());
if (await networkInfo.isConnected) { ... }

Storage #

Wraps flutter_secure_storage — values are encrypted on device.

final storage = AppStorage();

await storage.write(AppConstants.keyAccessToken, token);
final token = await storage.read(AppConstants.keyAccessToken);
await storage.delete(AppConstants.keyAccessToken);
await storage.deleteAll();

Validators #

// Single
AppTextField(validator: Validators.required)
AppTextField(validator: Validators.email)

// Composed — first error wins
AppTextField(
  validator: Validators.compose([
    Validators.required,
    Validators.email,
  ]),
)

Extensions #

// String
'hello world'.titleCase   // 'Hello World'
'test@x.com'.isEmail      // true
'  '.isBlank              // true

// BuildContext
context.colors.primary
context.textTheme.bodyLarge
context.isDark
context.screenWidth
context.showSnackBar('Saved!', isError: false)

// Num spacing
16.verticalSpace       // SizedBox(height: 16)
8.horizontalSpace      // SizedBox(width: 8)
16.allPadding          // EdgeInsets.all(16)

Constants #

AppConstants.keyAccessToken    // 'access_token'
AppConstants.keyRefreshToken   // 'refresh_token'
AppConstants.defaultPageSize   // 20
AppConstants.animNormal        // Duration(milliseconds: 300)

What each app needs to do #

  1. Add app_core to pubspec.yaml
  2. Create an AppColorScheme with your brand primary and secondary
  3. Pass it to AppTheme.light(scheme) and AppTheme.dark(scheme)
  4. Create an ApiClient with your baseUrl and token callbacks
  5. That's it — all widgets, utils, and network are ready to use
0
likes
130
points
99
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A shared Flutter package providing configurable theme, reusable widgets, network client, storage, and utilities for multi-app projects.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

connectivity_plus, dio, flutter, flutter_secure_storage

More

Packages that depend on flutter_multi_app_core