A complete Flutter UI kit with design tokens, semantic theme extensions, WCAG-compliant palette generation, and production-ready components.
- 6 core + 17 accent + 7 gray color palettes (12 shades each)
- 7 semantic ThemeExtension classes (TextColors, BackgroundColors, BorderColors, ForegroundColors, AlphaColors, UtilityColors, ComponentColors)
- Runtime palette generation from any color with WCAG AA auto-correction
- Typography scale: 11 sizes × 4 weights with Material TextTheme bridge
- Spacing system: 30 primitives + 17 semantic tokens + EdgeInsets/Gap helpers
- Border radius: 11 named sizes with pre-built BorderRadius constants
- Shadows, backdrop blurs, and gradient systems
- Automatic light/dark mode switching
- Button component system: 6 types × 4 sizes with icon variants
- Full Material ColorScheme bridge (30+ properties, 22 widget themes)
dependencies:
mihr_ui: ^0.1.0-dev.1import 'package:mihr_ui/mihr_ui.dart';
MaterialApp(
theme: MihrTheme.light(),
darkTheme: MihrTheme.dark(),
home: const MyApp(),
);Mihr UI exposes four independent customization layers — pick the narrowest one that solves your problem.
| # | Layer | Scope | API |
|---|---|---|---|
| 1 | Preset | App-wide defaults | MihrThemeConfig |
| 2 | Component theme | One component family | MihrThemeConfig.buttonTheme (and friends) |
| 3 | Per-instance | One widget | style / styleBuilder on the widget |
| 4 | Material escape-hatch | Raw ThemeData |
MihrThemeConfig.materialOverrides |
The canonical configuration object. Groups brand palette, typography, and every component theme into a single immutable value you can share across apps.
final cfg = MihrThemeConfig(
brand: ColorScaleGenerator.fromHex('#E63946'),
fontFamily: 'Roboto',
);
MaterialApp(
theme: MihrTheme.light(config: cfg),
darkTheme: MihrTheme.dark(config: cfg),
);Customize a whole component family (shape, shadows, per-variant style) via a theme extension. Example: flatten every button and override the primary fill.
MihrThemeConfig(
buttonTheme: MihrButtonThemeData(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)),
shadows: MihrButtonShadows.flat,
primaryStyle: const ButtonStyle(
backgroundColor: WidgetStatePropertyAll(Colors.indigo),
),
),
);Every Mihr component accepts a style (and often styleBuilder) prop that
wins over theme-level defaults.
MihrPrimaryButton(
onPressed: _save,
style: const ButtonStyle(
backgroundColor: WidgetStatePropertyAll(Colors.teal),
),
child: const Text('Save'),
);For Material properties Mihr does not model semantically (e.g.
scaffoldBackgroundColor, AppBarTheme.centerTitle, cardTheme), pass a
callback that receives the fully-built ThemeData with every Mihr default and
returns a modified copy. Use base.bgColors, base.textColors,
base.mihrTypography, and friends to read Mihr tokens ergonomically — no new
classes required.
MihrThemeConfig(
brand: AccentColors.indigo,
materialOverrides: (base) => base.copyWith(
scaffoldBackgroundColor: base.bgColors.secondary,
appBarTheme: base.appBarTheme.copyWith(
centerTitle: true,
backgroundColor: base.bgColors.brandSolid,
foregroundColor: base.textColors.white,
),
cardTheme: base.cardTheme.copyWith(color: base.bgColors.tertiary),
),
);From a widget, use the BuildContext extension:
context.textColors.primary
context.bgColors.brandSolidFrom a ThemeData (inside materialOverrides, tests, or non-widget code),
use the parallel ThemeData extension:
theme.textColors.primary
theme.bgColors.brandSolid| Extension | Getter | Tokens |
|---|---|---|
| TextColors | context.textColors |
23 |
| BackgroundColors | context.bgColors |
32 |
| BorderColors | context.borderColors |
10 |
| ForegroundColors | context.fgColors |
21 |
| AlphaColors | context.alphaColors |
20 |
| UtilityColors | context.utilityColors |
18 families |
| ComponentColors | context.componentColors |
29 |
Available button types:
- MihrPrimaryButton — solid brand fill, highest emphasis
- MihrSoftPrimaryButton — tinted brand fill, no border
- MihrSecondaryButton — outlined with gray border
- MihrTertiaryButton — ghost / transparent
- MihrLinkButton — inline text link (brand or gray)
- MihrDestructiveButton — error variants (primary, soft, secondary, tertiary, link)
All buttons support 4 sizes (sm, md, lg, xl) and icon variants.
Contributions are welcome! Please read our Contributing Guide before submitting a PR.
This project is licensed under the MIT License - see the LICENSE file for details.