✶ Flutter Design System
Every token.
Every
brand.
Production grade Flutter components built from the token layer up. Your apps own the brand. The system stays out of the way.
✶ The problem
Components that know
nothing about brands.
Most Flutter codebases scatter Color(), TextStyle(), and magic numbers across every widget.
Dievas moves them all to the token layer.
class SaveButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Color(0xFF6366F1), // ← hardcoded
borderRadius: BorderRadius
.circular(8), // ← hardcoded
),
child: Text('Save',
style: TextStyle(
color: Color(0xFFFFFFFF), // ← hardcoded
fontSize: 14, // ← hardcoded
fontWeight: FontWeight.w600,// ← hardcoded
),
),
);
}
}
class SaveButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: context.colors.action
.actionPrimary,
borderRadius: BorderRadius
.circular(
context.border.radiusMd,
),
),
child: Text('Save',
style: context.typography.labelMd,
// color baked in ✓
// size baked in ✓
// weight baked in ✓
),
);
}
}
✶ Architecture
Three layers.
One rule.
Each layer has exactly one responsibility.
Tokens define.
Theme composes.
Components consume.
// primitive scale — raw ints
abstract final class DievasColourPrimitives {
static const int indigo500 = 0xFF6366F1;
static const int slate900 = 0xFF0F172A;
}
// semantic alias — no Flutter import
abstract final class DievasColourSemanticLight {
static const int actionPrimary =
DievasColourPrimitives.indigo500;
static const int textPrimary =
DievasColourPrimitives.slate900;
}
// Color wrapping happens once, here
import 'package:flutter/painting.dart';
import 'package:dievas_tokens/...';
class ActionColors extends Equatable {
static const Color actionPrimary = Color(
DievasColourSemanticLight.actionPrimary,
);
}
// 9 typed aspects — surgical rebuilds
enum DievasThemeAspect {
colors, typography, spacing,
sizing, border, elevation, ...
}
// extend with your brand tokens
class CadenceLightThemeData
extends DievasGlobalThemeData {
CadenceLightThemeData({super.components})
: super(colors: ..., border: ...);
}
// wire up — system is brand-agnostic
DievasScope(
lightTheme: CadenceLightThemeData(),
darkTheme: CadenceDarkThemeData(),
child: MaterialApp.router(...),
)
Token-first, always
Primitives → semantic aliases → Flutter Color. Nothing in a component file is ever a raw hex or a magic number.
InheritedModel precision
DievasTheme has 9 aspects. A widget reading colors never rebuilds when spacing changes. Surgical, not shotgun.
Multi-brand by design
Apps extend DievasGlobalThemeData with their own brand tokens. The design system never knows which brand is active.
Pure Dart token layer
dievas_tokens has zero Flutter imports. Safe for Jaspr, CLI, and server-side Dart targets. No platform lock-in.
✶ Component catalog
36 shipped.
4 not started.
Every component covers all sizes, states, and variants. All verified in the live gallery.
Four button styles covering the full interaction spectrum. Filled, outlined, ghost, and square icon variants all driven by DievasButtonThemeData, no hardcoded values.
The full input surface: text fields, text areas, checkboxes, switches, radio groups, auth codes, breadcrumbs, dot indicators, input groups, dropdowns, segmented controls, and search. Token driven states for focus, error, and disabled. Localized via DievasLocalizations.
Avatar, badges, tags, dividers, loaders, and progress variants cover the visual data layer. Each derives color, sizing, and border radius entirely from DievasComponentThemeData.
Alert dialogs, bottom sheets, modals, snackbars, banners, and tooltips provide contextual feedback. Each integrates with DievasOverlayThemeData for backdrop and animation.
Accordion, drawer, popover, menu items, and tab bars provide progressive disclosure and contextual navigation. All surfaces are token-driven and animated via DievasAnimationThemeData.
✶ proof of work
The gallery is the proof.
Every component. Every state. Every size.
Toggle themes, resize viewports — live.