Token-based design system with themes, JSON import/export, and validation
dart pub add philiprehberger_design_tokensToken-based design system with themes, JSON import/export, and validation. Zero dependencies. Pure Dart.
Add to your pubspec.yaml:
dependencies:
philiprehberger_design_tokens: ^0.1.0
Then run:
dart pub get
import 'package:philiprehberger_design_tokens/design_tokens.dart';
final theme = Theme(
name: 'light',
colors: {
'primary': ColorToken.fromHex('#3366FF'),
'background': ColorToken.fromHex('#FFFFFF'),
},
spacings: {
'sm': SpacingToken(value: 8.0),
'md': SpacingToken(value: 16.0),
},
typographies: {
'body': TypographyToken(fontSize: 16.0, fontWeight: FontWeight.regular),
},
);
final color = theme.color('primary');
print(color!.toHex()); // #3366ff
final manager = ThemeManager();
manager.register(lightTheme);
manager.register(darkTheme);
manager.onChange((theme) => print('Now using: ${theme.name}'));
manager.switchTo('dark');
// Colors with hex parsing
final color = ColorToken.fromHex('#FF6633');
final rgba = ColorToken(red: 1.0, green: 0.4, blue: 0.2);
// Spacing
const spacing = SpacingToken(value: 16.0);
// Typography with font weight enum
const heading = TypographyToken(
fontSize: 32.0,
fontWeight: FontWeight.bold,
lineHeight: 1.2,
letterSpacing: -0.5,
);
// Shadows
final shadow = ShadowToken(
color: ColorToken.fromHex('#000000'),
radius: 8.0,
xOffset: 0.0,
yOffset: 4.0,
opacity: 0.15,
);
// Borders
final border = BorderToken(
width: 1.0,
color: ColorToken.fromHex('#E0E0E0'),
style: BorderStyle.dashed,
);
// Merge: other theme's tokens override matching keys
final merged = baseTheme.merging(overrideTheme);
// Extend: add tokens while keeping the original name
final extended = baseTheme.extending(
colors: {'accent': ColorToken.fromHex('#FF6633')},
);
final exporter = TokenExporter();
// Export to JSON map
final json = exporter.exportJson(theme);
// Import from JSON map
final restored = exporter.importJson(json);
// Serialize to bytes
final bytes = exporter.serialize(theme);
final fromBytes = exporter.deserialize(bytes);
final validator = TokenValidator();
final issues = validator.validate(
theme,
requiredColors: ['primary', 'background', 'error'],
requiredSpacing: ['sm', 'md', 'lg'],
requiredTypography: ['body', 'heading'],
);
for (final issue in issues) {
print('${issue.severity.name}: ${issue.message}');
}
| Class | Description |
|---|---|
ColorToken | RGBA color with hex parsing (fromHex, toHex) |
SpacingToken | Numeric spacing value |
TypographyToken | Font size, weight, line height, letter spacing |
ShadowToken | Shadow with color, radius, offsets, opacity |
BorderToken | Border with width, color, and style |
| Method | Description |
|---|---|
color(key) | Look up a color token |
spacing(key) | Look up a spacing token |
typography(key) | Look up a typography token |
shadow(key) | Look up a shadow token |
border(key) | Look up a border token |
merging(other) | Merge another theme (other overrides) |
extending(...) | Extend with additional tokens |
| Method | Description |
|---|---|
register(theme) | Register a theme |
switchTo(name) | Switch active theme |
activeTheme | Current active theme |
availableThemes | List of registered theme names |
onChange(callback) | Listen for theme changes |
| Method | Description |
|---|---|
exportJson(theme) | Export theme to JSON map |
importJson(json) | Import theme from JSON map |
serialize(theme) | Export to UTF-8 bytes |
deserialize(bytes) | Import from UTF-8 bytes |
| Method | Description |
|---|---|
validate(theme, ...) | Validate against required token names |
dart pub get
dart analyze --fatal-infos
dart test
If you find this project useful: