dacs 0.4.0 copy "dacs: ^0.4.0" to clipboard
dacs: ^0.4.0 copied to clipboard

Tailwind-like utility classes for Flutter. Apply text styles, padding, margins, colors, and borders via concise string expressions.

DACS #

pub.dev license

DACS brings Tailwind-inspired utility classes to Flutter. Write concise string expressions to define text styles, padding, colors, borders, shadows, transforms, gradients, and more.

Text('Hello, World!', style: 'text-2xl font-medium text-sky-500'.dText)

Features #

  • Zero-config — just install and use
  • Tailwind v3 color palette — 22 colors × 11 shades
  • Spacing scale — 0 to 384px in Tailwind increments
  • Text utilities — size, weight, color, letter spacing, line height, decoration
  • Background & border — colors, border width, border radius with directional variants
  • Sizing, shadows & opacity — width, height, box shadows, opacity
  • Position — inset-, top-, right-, bottom-, left-*
  • Transform — scale, rotate, translate, skew
  • Gradient — linear gradients from Tailwind color tokens
  • Theme colors from ColorSchemetext-primary, bg-surface, border-error
  • Arbitrary valuestext-[#ff0000], p-[20], w-[50%], rounded-[12]
  • Material widget extensions — style any Material widget: .dButton(context), .dCheckbox(context), .dCard(context), etc.
  • WidgetState variantshover:, focus:, disabled:, pressed:, selected:, error:, dragged:, scrolledUnder:
  • Chained compound variants — combine any prefixes: dark:hover:, dark:md:focus:, light:lg:disabled:
  • Dark/Light mode & responsive variantsdark:, light:, sm:, md:, lg:, xl:, 2xl:

Documentation #

Installation #

dependencies:
  dacs: ^0.4.0

Usage #

Configuration and compilation #

DACS works without configuration, but you can enable diagnostics for unknown utilities and tune the parser cache:

Dacs.configure(
  strictMode: false,
  cacheSize: 500,
  onUnknownUtility: (utility) {
    debugPrint('Unknown DACS utility: $utility');
  },
);

final sheet = DacsCompiler.compile('text-sm dark:md:hover:bg-red-500');

Compilation is context-free: DacsCompiler.compile only parses the string into a DacsStyleSheet. Runtime values such as BuildContext, theme colors, brightness, breakpoints, and widget states are applied later by methods such as .dTextOf(context), .dBoxOf(context), and .dButton(context).

Text styles #

Text('Heading', style: 'text-3xl font-bold text-gray-900'.dText)
Text('Body', style: 'text-base leading-relaxed text-gray-600'.dText)

Padding & Margin #

Container(
  padding: 'px-4 py-2'.dPads,
  margin: 'mt-4'.dPads,
  child: Text('Content', style: 'text-base'.dText),
)

Box decoration #

Container(
  decoration: 'bg-blue-500 rounded-lg shadow-md'.dBox,
  child: Text('Button', style: 'text-white font-medium'.dText),
)

Gradients #

Container(
  decoration: 'bg-gradient-to-r from-sky-400 to-blue-600'.dBox,
  child: Text('Gradient', style: 'text-white text-xl'.dText),
)

Shadows #

Container(decoration: 'bg-white rounded-xl shadow-lg'.dBox)
// Or just the shadow list:
final shadows = 'shadow-lg'.dShadow;

Sizing #

final (width, height) = 'w-64 h-48'.dSize;

Position (for Stack) #

final (top, right, bottom, left) = 'inset-0'.dPosition;

Transform #

Transform(
  transform: 'scale-125 rotate-45'.dTransform,
  child: Text('Styled'),
)

Dark / Light mode variants #

// Resolves automatically from MediaQuery:
Text(
  'Responsive text',
  style: 'text-gray-900 dark:text-white'.dTextOf(context),
)

Container(
  decoration: 'bg-white dark:bg-gray-900'.dBoxOf(context),
  child: Text(
    'Content',
    style: 'text-base text-gray-600 dark:text-gray-300'.dTextOf(context),
  ),
)

Responsive variants #

// Applies breakpoints based on screen width from MediaQuery:
Text(
  'Responsive heading',
  style: 'text-base sm:text-lg md:text-xl lg:text-2xl'.dTextOf(context),
)

Container(
  padding: 'p-4 md:p-8 lg:p-12'.dPadsOf(context),
  decoration: 'bg-white dark:bg-gray-900 rounded-lg'.dBoxOf(context),
  child: Text(
    'Content',
    style: 'text-sm md:text-base'.dTextOf(context),
  ),
)

Theme colors #

Use any ColorScheme key as a color — no need to import or reference the theme directly:

Text('Primary', style: 'text-primary font-bold'.dTextOf(context))
Container(decoration: 'bg-surface rounded-lg border-outline'.dBoxOf(context))
CheckboxTheme(
  data: 'checked:bg-primary unchecked:bg-surface'.dCheckbox(context),
  child: Checkbox(value: true, onChanged: (_) {}),
)

Supported keys: primary, onPrimary, primaryContainer, onPrimaryContainer, secondary, onSecondary, secondaryContainer, onSecondaryContainer, tertiary, onTertiary, tertiaryContainer, onTertiaryContainer, error, onError, errorContainer, onErrorContainer, surface, onSurface, surfaceVariant, onSurfaceVariant, outline, outlineVariant, inverseSurface, onInverseSurface, inversePrimary, shadow, scrim

Arbitrary values #

Use square brackets for one-off values:

'text-[#ff0000]'         // exact color
'bg-[rgb(255,0,0)]'      // rgb syntax
'p-[20]'                  // 20px padding
'w-[50%]'                 // 50% width
'rounded-[12]'            // 12px border radius
'opacity-[0.75]'          // 75% opacity
'scale-[200]'             // 2x scale

Material widget extensions #

Style Material widgets via context-aware methods. WidgetState variant support (hover:, focus:, disabled:, etc.) varies by adapter — see the table below.

ElevatedButton(
  style: 'bg-primary text-white rounded-lg'.dButton(context),
  onPressed: () {},
  child: const Text('Submit'),
)

CheckboxTheme(
  data: 'bg-primary hover:bg-primaryContainer'.dCheckbox(context),
  child: Checkbox(value: true, onChanged: (_) {}),
)

CardTheme(
  data: 'bg-surface rounded-xl shadow-md'.dCard(context),
  child: Card(child: Text('Content', style: 'text-base'.dText)),
)

All 27 Material widgets are supported: dButton, dCheckbox, dSwitch, dRadio, dChip, dAppBar, dCard, dListTile, dTabBar, dBottomNav, dInput, dProgress, dTooltip, dDivider, dScrollbar, dSnackBar, dDialog, dBottomSheet, dExpansionTile, dNavBar, dFab, dDataTable, dSearchBar, dMenu, dSlider, dIcon, dShape.

For the detailed per-widget property matrix, see the widget support matrix.

TextField inputs #

TextField.style and TextField.decoration are different Flutter APIs. Use .dTextOf(context) for the typed text and .dInputOf(context) for the input chrome: label, hint, helper, error, prefix/suffix, fill, density, padding, and borders.

const classes = 'text-onSurface label-[Email] hint-[you@example.com] '
    'helper-[Use your work email] filled dense bg-surface '
    'border-outline focus:border-primary error:border-error '
    'focus:error:border-primaryContainer rounded-lg p-4';

TextField(
  style: classes.dTextOf(context),
  decoration: classes.dInputOf(context),
)

WidgetState variants #

For Material widgets, use interactive state variants:

ElevatedButton(
  style: 'bg-primary hover:bg-primaryContainer disabled:bg-surface 
          rounded-lg hover:rounded-xl'.dButton(context),
  onPressed: () {},
  child: const Text('Submit'),
)

State order: base → disabled → pressed → hover → focus → selected → error → dragged → scrolledUnder. Shape variants (hover:rounded-xl, pressed:rounded-sm) resolve dynamically via _stateProp.

Chained compound variants #

Combine any variant prefixes with ::

// Applies only in dark mode AND when hovered
Text(
  'Styled text',
  style: 'text-white dark:hover:text-primary'.dTextOf(context),
)

// Triple compound: dark mode, medium breakpoint, hover
Container(
  decoration: 'bg-primary dark:md:hover:bg-error'.dBoxOf(context),
)

Parsed style access #

final sheet = 'text-lg font-bold text-red-600 dark:text-white'.dStyle;
final base = sheet.base;

print(base.fontSize);   // 18
print(base.fontWeight); // FontWeight.w700
print(base.color);      // Color(0xFFDC2626)

final resolved = sheet.resolveFor(context); // DacsResolvedStyle

Extension methods #

Simple getters (no context) #

These parse classes and convert immediately. Useful when you don't need variant resolution.

Getter Returns
.dText TextStyle
.dPads EdgeInsets
.dBox BoxDecoration
.dStyle DacsStyleSheet
.dBase DacsStyle
.dShadow List<BoxShadow>
.dSize (double?, double?)
.dFixedSize Size?
.dLayout DacsLayoutStyle
.dPosition (double?, double?, double?, double?)
.dTransform Matrix4
.dGradient LinearGradient?
.dBorder BoxBorder?
.dBorderSide BorderSide?
.dRadius BorderRadiusGeometry?
.dConstraints BoxConstraints?
.dAlignment AlignmentGeometry?
.dShapeBorder ShapeBorder?

Context-aware methods (resolve variants) #

These accept a BuildContext to resolve dark/light mode, responsive breakpoints, and theme colors from MediaQuery / Theme.

Method Returns
.dTextOf(context) TextStyle
.dPadsOf(context) EdgeInsets
.dMarginOf(context) EdgeInsets
.dBoxOf(context) BoxDecoration
.dStyleOf(context) DacsResolvedStyle
.dShadowOf(context) List<BoxShadow>
.dSizeOf(context) (double?, double?)
.dFixedSizeOf(context) Size?
.dLayoutOf(context) DacsLayoutStyle
.dPositionOf(context) (double?, double?, double?, double?)
.dTransformOf(context) Matrix4
.dGradientOf(context) LinearGradient?
.dBorderOf(context) BoxBorder?
.dBorderSideOf(context) BorderSide?
.dRadiusOf(context) BorderRadiusGeometry?
.dConstraintsOf(context) BoxConstraints?
.dAlignmentOf(context) AlignmentGeometry?
.dShapeBorderOf(context) ShapeBorder?

Material widget extensions #

These accept a BuildContext and return Material theme data with variant resolution. WidgetState support is marked per method. For property-level support, see the widget support matrix.

Method Returns WidgetState
.dButton(context) ButtonStyle full
.dCheckbox(context) CheckboxThemeData partial
.dSwitch(context) SwitchThemeData partial
.dRadio(context) RadioThemeData partial
.dChip(context) ChipThemeData only color
.dScrollbar(context) ScrollbarThemeData partial
.dNavBar(context) NavigationBarThemeData only label
.dDataTable(context) DataTableThemeData partial
.dSearchBar(context) SearchBarThemeData partial
.dMenu(context) MenuStyle partial
.dSlider(context) SliderThemeData partial
.dAppBar(context) AppBarTheme
.dCard(context) CardTheme
.dListTile(context) ListTileThemeData
.dTabBar(context) TabBarTheme
.dBottomNav(context) BottomNavigationBarThemeData
.dInput(context) / .dInputOf(context) InputDecoration focus, disabled, error, focus:error border mappings
.dProgress(context) ProgressIndicatorThemeData
.dTooltip(context) TooltipThemeData
.dDivider(context) DividerThemeData
.dSnackBar(context) SnackBarThemeData
.dDialog(context) DialogTheme
.dBottomSheet(context) BottomSheetThemeData
.dExpansionTile(context) ExpansionTileThemeData
.dFab(context) FloatingActionButtonThemeData
.dIcon(context) IconThemeData
.dShape(context) ShapeDecoration

Supported classes #

Typography #

Class Flutter property
text-xstext-9xl fontSize (12 … 128)
font-thinfont-black fontWeight (100 … 900)
leading-3leading-10 height (line height)
leading-noneleading-loose height (relative)
tracking-tightertracking-widest letterSpacing
italic / not-italic fontStyle
underline / line-through / no-underline textDecoration
decoration-solid / double / dotted / dashed / wavy textDecorationStyle
decoration-{1..} textDecorationThickness
decoration-{color}-{shade} textDecorationColor

Colors (text, background, border, decoration) #

Format: {prefix}-{color}-{shade}

'text-sky-500'         // text color
'bg-blue-200'          // background color
'border-red-600'       // border color
'decoration-green-500' // text decoration color

Supported colors: slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose

Shades: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950

Also: text-black, text-white, text-transparent

Spacing #

Class Output
p-4 EdgeInsets.all(16)
px-4 EdgeInsets.symmetric(horizontal: 16)
py-2 EdgeInsets.symmetric(vertical: 8)
pt-4, pr-4, pb-4, pl-4 Directional padding
m-*, mx-*, my-*, mt-*, mr-*, mb-*, ml-* Same for margin

Spacing keys: 0, px, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96

Border #

Class Output
rounded-none BorderRadius.circular(0)
rounded-sm BorderRadius.circular(2)
rounded BorderRadius.circular(4)
rounded-md / rounded-lg / rounded-xl / rounded-2xl / rounded-3xl 6 / 8 / 12 / 16 / 24
rounded-full BorderRadius.circular(9999)
rounded-t-lg, rounded-b-sm, rounded-l-md, rounded-r-xl Directional
rounded-tl-lg, rounded-tr-lg, rounded-bl-lg, rounded-br-lg Corner-specific
border Border.all(width: 1)
border-2border-8 Border.all(width: size)

Sizing & opacity #

'w-64'       // width: 256
'h-32'       // height: 128
'w-full'     // width: double.infinity
'opacity-50' // opacity: 0.5

Shadows #

Class BoxShadows
shadow-sm 1 shadow (subtle)
shadow 2 shadows (default)
shadow-md / shadow-lg / shadow-xl / shadow-2xl Increasing blur/spread
shadow-inner Inset shadow
shadow-none Empty list

Position #

Class Properties
inset-0 top=0, right=0, bottom=0, left=0
inset-x-4 left=16, right=16
inset-y-2 top=8, bottom=8
top-4, right-4, bottom-4, left-4 Individual inset

Transform #

Class Property
scale-125 scaleX=1.25, scaleY=1.25
scale-x-150 scaleX=1.5
scale-y-75 scaleY=0.75
rotate-45 rotateDegrees=45
translate-x-4 translateX=16
translate-y-2 translateY=8
skew-x-12 skewX=12
skew-y-6 skewY=6

Gradient #

'bg-gradient-to-r from-red-500 to-blue-600'
'bg-gradient-to-tl from-amber-400 via-orange-500 to-red-600'

Directions: to-r, to-l, to-t, to-b, to-tr, to-tl, to-br, to-bl

Variants #

Prefix any class with a variant to scope it:

Variant Trigger
dark: Applies when MediaQuery.platformBrightness == Brightness.dark
light: Applies when MediaQuery.platformBrightness == Brightness.light
sm: Applies at min-width: 640px
md: Applies at min-width: 768px
lg: Applies at min-width: 1024px
xl: Applies at min-width: 1280px
2xl: Applies at min-width: 1536px
hover: WidgetState.hovered
focus: WidgetState.focused
active: / pressed: WidgetState.pressed
disabled: WidgetState.disabled
selected: WidgetState.selected
error: WidgetState.error
dragged: WidgetState.dragged
scrolledUnder: WidgetState.scrolledUnder

Resolution order (Material contexts): base → disabled → pressed → hover → focus → selected → error → dragged → scrolledUnder.

Chained compound variants: combine multiple prefix types with :.

'dark:hover:text-white'      // dark mode + hover
'light:md:bg-primary'        // light mode + md breakpoint
'dark:lg:focus:border-error' // dark + lg + focus

Compound variants match only when ALL conditions are met. WidgetState conditions re-map to simple keys for Material widget resolution.

Additional information #

1
likes
0
points
233
downloads

Documentation

Documentation

Publisher

unverified uploader

Weekly Downloads

Tailwind-like utility classes for Flutter. Apply text styles, padding, margins, colors, and borders via concise string expressions.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, vector_math

More

Packages that depend on dacs