Skip to Content
Mix 2.0 is in development! You can access the Mix 1.0 docs here.
DocsGuidesDirectives

Directives

Directives transform values (text, numbers) when a style is resolved. Unlike modifiers (which wrap widgets), directives transform the underlying data values.

// The text "hello world" is transformed to "HELLO WORLD" at build time StyledText( 'hello world', style: TextStyler().uppercase(), )

Directives can be chained:

// Chain: multiply by 2, then add 5, then clamp between 0-30 final style = BoxStyler.create( width: Prop.value(10.0).multiply(2).add(5).clamp(0, 30), );

Text Directives

Transform strings in StyledText widgets:

Available Text Directives

MethodDescriptionExample InputResult
.uppercase()Converts all characters to uppercase”hello world""HELLO WORLD”
.lowercase()Converts all characters to lowercase”Hello World""hello world”
.capitalize()Capitalizes the first letter of each word”hello world""Hello World”
.titlecase()Transforms to title case format”hello world""Hello World”
.sentencecase()Capitalizes the first letter of the first word”hello world""Hello world”

Usage Examples

import 'package:flutter/material.dart'; import 'package:mix/mix.dart'; // Uppercase text StyledText( 'welcome back', style: TextStyler().uppercase().fontSize(18), ) // Title case for headings StyledText( 'user profile settings', style: TextStyler().titlecase().fontWeight(FontWeight.bold), ) // Sentence case for descriptions StyledText( 'click here to continue', style: TextStyler().sentencecase().color(Colors.grey), )

Number Directives

Transform numeric values (width, height, padding, font sizes):

Available Number Directives

MethodDescriptionExample
.multiply(factor)Multiplies by a factorProp.value(10).multiply(2) → 20
.add(addend)Adds a valueProp.value(10).add(5) → 15
.subtract(value)Subtracts a valueProp.value(10).subtract(3) → 7
.divide(divisor)Divides by a valueProp.value(10).divide(2) → 5
.clamp(min, max)Constrains between boundsProp.value(25).clamp(0, 20) → 20
.abs()Returns absolute valueProp.value(-10).abs() → 10
.round()Rounds to nearest integerProp.value(15.7).round() → 16
.floor()Rounds downProp.value(15.7).floor() → 15
.ceil()Rounds upProp.value(15.3).ceil() → 16
.scale(ratio)Alias for multiplyProp.value(10).scale(1.5) → 15

Usage Examples

import 'package:flutter/material.dart'; import 'package:mix/mix.dart'; // Proportional typography scaling final style = TextStyler.create( style: TextStyleMix( letterSpacing: Prop.value(0.0025).multiply(12.0), ), ); // Dynamic sizing with tokens final $baseSize = DoubleToken('base.size'); final boxStyle = BoxStyler.create( width: Prop.token($baseSize).multiply(2), height: Prop.token($baseSize).multiply(1.5), ); // Clamped responsive values final responsiveStyle = BoxStyler.create( padding: Prop.value(16.0).clamp(8, 32), ); // Chaining multiple directives final chainedStyle = BoxStyler.create( width: Prop.value(100.0).multiply(2).add(20).clamp(0, 300), );

Division always returns a double in Dart. The divisor cannot be zero.

Creating Custom Directives

Extend Directive<T> to create application-specific transformations.

Text Directive Example

import 'package:mix/mix.dart'; /// Directive that reverses a string final class ReverseStringDirective extends Directive<String> { const ReverseStringDirective(); @override String apply(String value) => value.split('').reversed.join(); @override String get key => 'reverse'; @override bool operator ==(Object other) => identical(this, other) || other is ReverseStringDirective; @override int get hashCode => key.hashCode; } // Usage with TextStyler extension ReverseTextDirective on TextStyler { TextStyler reverse() { return merge( TextStyler(textDirectives: [const ReverseStringDirective()]), ); } } // Apply the custom directive StyledText( 'hello', style: TextStyler().reverse(), // Displays "olleh" )

Number Directive Example

import 'package:mix/mix.dart'; /// Directive that negates a number final class NegateNumberDirective extends NumberDirective { const NegateNumberDirective(); @override num apply(num value) => -value; @override String get key => 'number_negate'; @override bool operator ==(Object other) => identical(this, other) || other is NegateNumberDirective; @override int get hashCode => key.hashCode; } // Extension to make it easy to use extension NegateNumberPropExt<T extends num> on Prop<T> { Prop<num> negate() { return directives([const NegateNumberDirective()]); } }

Best Practices

  • Use text directives for consistent case formatting
  • Use number directives for proportional sizing with tokens
  • Use color directives for state variations (hover, disabled)
  • Keep directives simple—complex logic belongs elsewhere

Chaining order matters:

Prop.value(10).add(5).multiply(2) // (10 + 5) * 2 = 30 Prop.value(10).multiply(2).add(5) // (10 * 2) + 5 = 25