mervey_ui_kit 0.7.5
mervey_ui_kit: ^0.7.5 copied to clipboard
Adaptive Material/Cupertino design system: theming tokens, semantic color palette and reusable widgets that pick the right backend per platform.
mervey_ui_kit #
Adaptive Material/Cupertino design system for Flutter apps. Bundles a semantic color palette, typography tokens, spacing/radius scales, and a set of cross-platform components that pick the right backend per platform.
The package is brand-agnostic. Host apps wire their colors and typography in
through AppTheme.light / AppTheme.dark overrides.
Requirements #
- Dart SDK >= 3.6.0
- Flutter >= 3.27.0
The Flutter floor is dictated by Color.withValues(alpha:), which replaced the
deprecated withOpacity in Flutter 3.27.
Installation #
dependencies:
mervey_ui_kit: ^0.7.2
Theme setup #
import 'package:flutter/material.dart';
import 'package:mervey_ui_kit/mervey_ui_kit.dart';
void main() {
runApp(
MaterialApp(
theme: AppTheme.light(), // neutral Material defaults
darkTheme: AppTheme.dark(),
builder: AppTheme.wrapWithCupertino, // optional, for iOS Cupertino
home: const _Demo(),
),
);
}
Branding #
Pass a custom palette:
final palette = AppColorPalette.light(
brandPrimary: const Color(0xFFF3E123),
onBrand: const Color(0xFF111111),
textPrimary: const Color(0xFF111111),
);
MaterialApp(
theme: AppTheme.light(palette: palette),
darkTheme: AppTheme.dark(palette: AppColorPalette.dark(brandPrimary: ...)),
);
All factory arguments are named and optional — overrides are surgical, the
rest stays Material-flavoured. The palette also expands to a Material 3
ColorScheme
with the surface-container ramp, outline / outlineVariant and
surfaceTint filled in, so M3 widgets stay aligned with the brand.
Configure the brand once: AppTheme.wrapWithCupertino inherits the palette
already installed by AppTheme.light / .dark, so the Cupertino side
(CupertinoButton, navigation, action text, …) picks up brandPrimary
without re-passing it. Adaptive components such as AppButton read the brand
straight off context.colors, so they stay branded on iOS even without the
builder.
Typography #
The kit ships with system-font defaults on every platform — no
third-party fonts are bundled, and there are no licensing strings attached.
For a branded look, bundle your fonts in your app's pubspec.yaml and pass
them through:
AppTheme.light(
typography: const AppTypographyTokens(
scale: AppTextScale.md,
accentFont: 'Inter', // null → system font
secondaryFont: 'Inter',
monospaceFont: 'JetBrains Mono',
),
);
Use AppTextScale.sm / .md / .lg for a compact / default / roomy text
rhythm without touching individual styles. The scale applies everywhere —
component text, the Material TextTheme the kit builds, and the Cupertino
text styles.
Components #
Every component is a StatelessWidget/StatefulWidget that reads tokens
from the active theme.
| Category | Widgets |
|---|---|
| Buttons | AppButton, AppGlassButton, AppCircleIconButton, AppIconActionButton, AppResendButton |
| Inputs | AppTextField, AppAmountField, AppSearchField, AppOtpField, showAppInputDialog |
| Cards & surfaces | AppCard, AppTappableCard, AppCoinActionCard, AppFieldShell + AppFieldLabel, AppFieldTile, AppInfoBanner |
| Sheets & dialogs | showAppModalSheet, AppSheetHeader, AppSheetDragHandle, AppDialog + showAppDialog |
| Navigation | AppScaffold, AppNavbar, AppBackBar, AppPillTabs |
| Lists & structure | AppDetailRow, AppSectionHeader, AppSectionCaption, AppOnboardingHeader |
| Indicators | AppPill, AppStatusPill, AppBadgedIcon, AppAvatar, AppAvatarInitials, AppSwitch, AppSkeletonBar |
| Feedback | showAppSnackBar / context.showSnack, showAppToast, showAppTopToast, showAppCopiedToast |
| States | AppLoadingState, AppErrorState, AppEmptyState |
Platform adaptivity #
Some components swap to a Cupertino backend on iOS for native feel; the rest are Material-only and render the same on every platform (Material widgets look natural on iOS too).
Adaptive (Material on Android, Cupertino on iOS): AppButton,
AppTextField, AppAmountField, AppDialog / showAppDialog,
AppNavbar, AppScaffold. Everything else renders the same Material look
everywhere.
AppSwitch is deliberately not adaptive — since 0.7.4 it renders one
custom toggle on every platform so the kit's on/off state looks identical
across Android and iOS.
AppSearchField is intentionally Material-only — for iOS-pure search flows
prefer Flutter's CupertinoSearchTextField.
Context extensions #
Pull tokens from any BuildContext:
final colors = context.colors; // AppColorPalette
final typography = context.typography; // AppTypographyTokens
final icons = context.icons; // AppIconTokens
Since 0.7.0 these getters are safe under themes that were not built by
AppTheme: they fall back to neutral defaults matching the ambient
brightness instead of throwing. Kit components degrade to an unbranded look
inside host screens with a custom theme, consumer tests, and dialogs under a
foreign navigator — they never crash the app.
Migrating to 0.7.0 #
Components without the App prefix were renamed for the library-wide naming
convention. The old names still compile as @Deprecated aliases and will be
removed in 1.0.0 — migrate with a find/replace:
| Deprecated | Replacement |
|---|---|
AvatarInitials |
AppAvatarInitials |
BadgedIcon |
AppBadgedIcon |
IconActionButton |
AppIconActionButton |
LoadingState / ErrorState / EmptyState |
AppLoadingState / AppErrorState / AppEmptyState |
showInputDialog |
showAppInputDialog |
See CHANGELOG for the rest of 0.7.0: theme-fallback safety, the disabled/loading button treatment, formatter cursor fixes, text-scale routing, and accessibility improvements.
Example app #
See example/ for a runnable showcase with a light/dark switch and a tour
of every component.
License #
MIT — see LICENSE.