dartwind 0.1.1 copy "dartwind: ^0.1.1" to clipboard
dartwind: ^0.1.1 copied to clipboard

Dartwind like a tailwind

Dartwind / DView #

Dartwind is a utility-first styling library for Flutter, inspired by Tailwind CSS. It provides a comprehensive set of builder-style APIs that allow you to construct complex widget trees through method chaining. At its core is the DView class, which wraps a list of child widgets and applies properties such as flex layouts, grid layouts, padding, margin, background colors, gradients, borders, shadows, responsive breakpoints, and much more. When you call .build(), DView synthesizes all of these settings into a single, fully styled Flutter Widget.


Table of Contents #

  1. Introduction
  2. Installation
  3. Quick Start
  4. Core Concept: DView Workflow
  5. Detailed API Reference
  6. Usage Examples
  7. Advanced Topics & Customization
  8. Performance Considerations
  9. FAQ
  10. License

1. Introduction #

In traditional Flutter development, styling a Container, Row, or Column often involves repeating boilerplate code for properties like padding, margin, color, border, and so on. Dartwind / DView streamlines this by providing a fluent, chainable API that mimics the convenience of Tailwind CSS but in Dart syntax.

Key Benefits:

  • Utility-First: Compose complex UI styles by chaining small, single-purpose methods.
  • Readability: A concise notation that spells out styling intentions in a natural, human-readable sequence.
  • Maintainability: By centralizing style logic within DView, the visual structure of your UI is easier to audit and refactor.
  • Responsive-Ready: Built-in support for breakpoint-based styling (e.g., .sm, .md, .lg variants).
  • Flexible Layouts: Full support for Flex-based (Row, Column, Wrap), Grid-based (GridView), and absolute positioning (Stack + Positioned) layouts.
  • Rich Visuals: Utilities for colors, gradients, borders, shadows, rounding, and more.

2. Installation #

Add the Dartwind dependency to your pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  dartwind: ^1.0.0

Then run:

flutter pub get

In any Dart file where you want to use DView and related utilities, import:

import 'package:dartwind/dartwind.dart';
import 'package:flutter/material.dart';

3. Quick Start #

Below is a minimal example that demonstrates how to create a horizontal flex container with three items, gap spacing, padding, and a background color—all with a single DView builder chain:

class QuickStartExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final items = [
      Container(color: Colors.red, width: 50, height: 50),
      Container(color: Colors.green, width: 50, height: 50),
      Container(color: Colors.blue, width: 50, height: 50),
    ];

    return Scaffold(
      appBar: AppBar(title: Text("Quick Start with DView")),
      body: Center(
        child: DView(items)
            .flexRow()              // Use a Row (Flex horizontal)
            .justifyCenter()        // Center items horizontally
            .itemsCenter()          // Center items vertically
            .gap(12)                // Add 12px gap between each child
            .p(16)                  // Add 16px padding on all sides
            .bg(Colors.grey.shade200)// Set background color
            .roundedLg()            // Large border radius (8px)
            .shadowMd()             // Medium shadow
            .build(),               // Build the final Widget
      ),
    );
  }
}

This code produces a container centered in the screen that holds three colored squares in a row, each spaced by 12 pixels, with 16 pixels of padding around them, a light gray background, slightly rounded corners, and a subtle drop-shadow.


4. Core Concept: DView Workflow #

  1. Initialization: You start by creating a DView object and passing it a List<Widget> that represents the children you want to display.

    final dv = DView([
      Text("Item 1"),
      Text("Item 2"),
      Icon(Icons.star),
    ]);
    
  2. Method Chaining: You call a sequence of methods on that DView object to configure layout, styling, spacing, etc. Each method modifies the internal state of DView and returns this, enabling a fluent, chainable syntax.

    dv.flexRow()
      .justifyBetween()
      .itemsCenter()
      .p(8)
      .bg(Colors.blue)
      .shadowSm()
      .roundedMd();
    
  3. Building: Finally, you call .build(), which takes all of the state accumulated by your chained calls and synthesizes it into a single Widget tree. This tree typically contains one or more Flutter layout widgets (Row, Column, Wrap, GridView, Container, Stack, etc.) configured with the properties you specified.

    Widget finalWidget = dv.build();
    
  4. Integration: The single Widget returned by build() can be inserted anywhere in your Flutter widget hierarchy—inside a Scaffold, a Column, a ListView, or any other parent.

Conceptually, DView works like a Virtual DOM builder for Flutter. Rather than writing nested and repetitive Container or BoxDecoration code, you assemble a set of style “instructions” via method calls. When build() is invoked, DView reads those instructions and constructs a real widget tree.


5. Detailed API Reference #

Below is an exhaustive reference of DView methods, organized by functionality. All methods return DView to allow chaining (unless otherwise noted).

5.1 Initialization #

DView(List<Widget> children)
  • children:
    • A List<Widget> representing the child widgets to wrap.
    • DView will manage the layout and styling around these children.

5.2 Sizing (DwSize<DView>) #

Control the width, height, and box constraints of the DView container.

Method Description
DView w(double w) Set a fixed width of w logical pixels.
DView h(double h) Set a fixed height of h logical pixels.
DView wFull() Equivalent to w(double.infinity). The container will expand to fill available width.
DView hFull() Equivalent to h(double.infinity). The container will expand to fill available height.
DView minW(double) Set BoxConstraints(minWidth: value, ...).
DView minH(double) Set BoxConstraints(minHeight: value, ...).
DView maxW(double) Set BoxConstraints(maxWidth: value, ...).
DView maxH(double) Set BoxConstraints(maxHeight: value, ...).

Usage Example:

DView(children)
  .w(200)
  .h(100)
  .minW(150)
  .minH(50)
  .maxW(250)
  .maxH(150)
  .build();
  • If any of minW, minH, maxW, or maxH are set, all sizing is controlled via a single BoxConstraints object.
  • Otherwise, simple width and height values are applied.

5.3 Padding & Margin (DwPadding<DView> / DwMargin<DView>) #

Padding (DwPadding)

Method Description
DView p(double all) Set equal padding on all four sides (left, right, top, bottom).
DView px(double val) Set horizontal padding (left, right).
DView py(double val) Set vertical padding (top, bottom).
DView pt(double val) Set top padding only.
DView pr(double val) Set right padding only.
DView pb(double val) Set bottom padding only.
DView pl(double val) Set left padding only.

Margin (DwMargin)

Method Description
DView m(double all) Set equal margin on all four sides.
DView mx(double val) Set horizontal margin.
DView my(double val) Set vertical margin.
DView mt(double val) Set top margin only.
DView mr(double val) Set right margin only.
DView mb(double val) Set bottom margin only.
DView ml(double val) Set left margin only.

Usage Example:

DView(children)
  .p(16)       // Padding: 16px all around
  .px(8)       // Overrides left/right padding to 8px
  .pt(12)      // Overrides top padding to 12px
  .m(24)       // Margin: 24px all around
  .ml(32)      // Overrides left margin to 32px
  .build();

Behavior:

  • Each call simply sets the respective internal variables (pLeft, pRight, pTop, pBottom or mLeft, mRight, mTop, mBottom).
  • At build time, EdgeInsets.only(...) is created accordingly.

5.4 Background, Colors & Gradients (DwBackgroundColor<DView> / DwGradientColor<DView>) #

Solid Background Color

Method Description
DView bg(Color c) Set a solid background color of c.

Gradient Background

DView supports building linear gradients using a combination of .from(...), .via(...), and .to(...) with directional helpers.

Method Description
DView from(Color c, { double? percentage }) Define the starting color of a gradient. Optional percentage is not currently used in DView logic.
DView via(Color c, { double? percentage }) Define an intermediate “via” color for three-stop gradients.
DView to(Color c, { double? percentage }) Define the ending color of a gradient.
DView bgGradientToB() Gradient direction from top to bottom.
DView bgGgradientToBl() Gradient direction from bottom-right to top-left (diagonal).
DView bgGradientToBR() Gradient direction from bottom-left to top-right (diagonal).
DView bgGradientToR() Gradient direction from left to right.
DView bgGradientToT() Gradient direction from bottom to top.
DView bgGradientToTr() Gradient direction from top-left to bottom-right.
DView bggradientToL() (Alias) gradient direction from top-left to bottom-right.
DView bggradientToTl() (Alias) gradient direction from top-left to bottom-right.

Usage Example:

DView(children)
  .from(Colors.red)
  .via(Colors.orange)
  .to(Colors.yellow)
  .bgGradientToBR()   // Diagonal from bottom-left to top-right
  .build();

Behavior:

  • If colorFrom is set (non-null), DView constructs a LinearGradient with begin = colorFromAlignment and end = colorToAlignment plus the stop colors [colorFrom, colorVia, colorTo] (or just [colorFrom, colorTo] if no .via() is called).
  • If no .from(...) is called but .bg(...) is called, DView uses a simple solid background instead (no gradient).

5.5 Borders & Rounded Corners (DwBorder<DView> / DwRounded<DView>) #

Borders

Method Description
DView border({ double width = 0, Color color }) Apply an equal border on all four sides with given width & color.
DView borderT({ double width = 0, Color color }) Apply a border only on the top side.
DView borderB({ double width = 0, Color color }) Apply a border only on the bottom side.
DView borderL({ double width = 0, Color color }) Apply a border only on the left side.
DView borderR({ double width = 0, Color color }) Apply a border only on the right side.

Usage Example:

DView(children)
  .border(width: 2, color: Colors.black)
  .borderT(width: 4, color: Colors.red)
  .build();
  • The code above sets a 2px black border on all sides, then overrides only the top border to be 4px red (since the last call to borderT(...) modifies the top side forcibly).

Rounded Corners

Method Description
DView rounded({ double borderRadius = 4 }) Apply equal border radius to all four corners (default = 4).
DView roundedFull() Fully round corners (borderRadius = 9999).
DView roundedSm() Small radius (2).
DView roundedMd() Medium radius (6).
DView roundedLg() Large radius (8).
DView roundedTL({ double? borderRadius = 4 }) Round top-left corner only.
DView roundedTR({ double? borderRadius = 4 }) Round top-right corner only.
DView roundedBL({ double? borderRadius = 4 }) Round bottom-left corner only.
DView roundedBR({ double? borderRadius = 4 }) Round bottom-right corner only.
DView roundedL({ double? borderRadius = 4 }) Round top-left & bottom-left (left side) corners.
DView roundedR({ double? borderRadius = 4 }) Round top-right & bottom-right (right side) corners.
DView roundedT({ double? borderRadius = 4 }) Round top-left & top-right (top side) corners.
DView roundedB({ double? borderRadius = 4 }) Round bottom-left & bottom-right (bottom side) corners.

Usage Example:

DView(children)
  .roundedMd()  // All four corners = 6px radius
  .roundedTR(borderRadius: 12)  // Override top-right to 12px
  .build();

5.6 Shadows (DwShadow<DView>) #

Method Description
DView shadowSm() Small box shadow: 0 1px 2px 0 rgba(0,0,0,0.05).
DView shadow() Default box shadow: combination of small offsets & blur.
DView shadowMd() Medium box shadow: 0 4px 6px -1px rgba(0,0,0,0.1) & 0 2px 4px -2px rgba(0,0,0,0.1).
DView shadowLg() Large box shadow: two-layered deeper shadows.
DView shadowXl() Extra-large: 0 20px 25px -5px rgba(0,0,0,0.1) & 0 8px 10px -6px rgba(0,0,0,0.1).
DView shadow2xl() Double extra-large: 0 25px 50px -12px rgba(0,0,0,0.25).
DView shadowInner() Inner shadow: inset 0 2px 4px 0 rgba(0,0,0,0.05).

Usage Example:

DView(children)
  .bg(Colors.white)
  .shadowMd()
  .roundedLg()
  .build();

5.7 Flex Layout (DwFlex<DView> / DwFlexUtilities<DView> / DwGap<DView>) #

Core Flex Methods

Method Description
DView flex() Same as flexRow(): Start a horizontal flex container (Row).
DView flexRow() Create a horizontal Row container.
DView flexCol() Create a vertical Column container.
DView flexRowReverse() Horizontal flex with reversed main-axis alignment (end).
DView flexColReverse() Vertical flex with reversed main-axis alignment (end).
DView itemsCenter() CrossAxisAlignment.center.
DView itemsStart() CrossAxisAlignment.start.
DView itemsEnd() CrossAxisAlignment.end.
DView itemsStretch() CrossAxisAlignment.stretch.
DView itemsBaseline() CrossAxisAlignment.baseline. Requires text baseline.
DView justifyStart() MainAxisAlignment.start.
DView justifyCenter() MainAxisAlignment.center.
DView justifyEnd() MainAxisAlignment.end.
DView justifyBetween() MainAxisAlignment.spaceBetween.
DView justifyAround() MainAxisAlignment.spaceAround.
DView justifyEvenly() MainAxisAlignment.spaceEvenly.
DView flexWrap() Switch to a Wrap container with default alignment WrapAlignment.start & cross WrapCrossAlignment.start.
DView flexWrapReverse() Wrap container with WrapAlignment.end & WrapCrossAlignment.end.
DView flexNowrap() Do not wrap; default to Row or Column (depending on flexDirection).

Note:

  • By default, if you do not call any flex-related method, DView still constructs a Flex container with direction = Axis.vertical (i.e., a Column).
  • To create a Wrap, call .flexWrap(); to revert to a normal Row/Column, call .flexNowrap().

Gap Between Flex Children (DwGap)

Method Description
DView gap(double size) Adds a SizedBox(width: size) between children if flexDirection == Axis.horizontal, or SizedBox(height: size) if vertical.
DView gapNumber(double number) Equivalent to .gap(number).
DView gapCustom(String property) Placeholder for string-based gap (not implemented).
DView setGapValue(String value) Parse numeric string, then .gap(parsedValue).
DView gapX(double value) Set gridGapX = value. Used in Wrap or GridView.
DView gapXNumber(double number) Same as .gapX(number).
DView gapXCustom(String property) Placeholder (not implemented).
DView setGapXValue(String value) Parse string to a double; set gapXValue.
DView gapY(double value) Set gridGapY = value. Used in Wrap or GridView.
DView gapYNumber(double number) Same as .gapY(number).
DView gapYCustom(String property) Placeholder (not implemented).
DView setGapYValue(String value) Parse string to a double; set gapYValue.

Usage Example:

DView(children)
  .flexRow()
  .gap(16)      // Horizontal: 16px gap between each child
  .build();

Flex-Basis, grow, shrink (DwFlexBasis / DwFlexUtilities)

Method Description
DView flex1() Equivalent to wrapping the container in Flexible(flex: 1, fit: FlexFit.tight). Use grow(...) / flexGrow(...) to adjust.
DView basis(int number) Set basisValue = number.toDouble(). At build, wraps in SizedBox(width: basisValue) if horizontal, or height if vertical.
DView basisFraction(double frac) Equivalent to basis(frac * 100).
DView basisFull() basisValue = double.infinity.
DView basisAuto() basisValue = null (ignored).
Preset Basis Sizes:
DView basis3xs() = 256
DView basis2xs() = 288
DView basisXs() = 320
DView basisSm() = 384
DView basisMd() = 448
DView basisLg() = 512
DView basisXl() = 576
DView basis2xl() = 672
DView basis3xl() = 768
DView basis4xl() = 896
DView basis5xl() = 1024
DView basis6xl() = 1152
DView basis7xl() = 1280
DView basisCustom(String prop) Placeholder for custom basis value parsing (not implemented).
DView setBasisValue(String value) Parse the string to a double.
Method Description
DView flexNumber(int num) Equivalent to flexGrow(num); sets _flexGrow = num.
DView flexFraction(double f) Equivalent to flexGrow((f * 100).round()).
DView flexAuto() flexGrow = 1; flexShrink = 1. (Both grow and shrink)
DView flexInitial() flexGrow = 0; flexShrink = 1.
DView flexNone() flexGrow = 0; flexShrink = 0. (Never grow or shrink)
DView flexGrow(int num) Set _flexGrow = num.
DView flexShrink(int num) Set _flexShrink = num.
DView flexValue(String value) Parse string to int, set _flexGrow.
DView flexCustom(String property) Placeholder for custom flex property (not implemented).
Method Description
DView grow() Equivalent to flexGrow(1).
DView growNumber(int number) Equivalent to flexGrow(number).
DView growValue(String val) Parse string to int, set _flexGrow.
DView growCustom(String property) Placeholder (not implemented).
DView shrink() Equivalent to flexShrink(1).
DView shrinkNumber(int number) Equivalent to flexShrink(number).
DView shrinkValue(String val) Parse string to int, set _flexShrink.
DView shrinkCustom(String property) Placeholder (not implemented).
Method Description
DView flexValue(String value) Parse string to int, sets _flexGrow.
DView flexCustom(String property) Placeholder (not implemented).
Method Description
DView orderNumber(int number) Sets _order = number.
DView orderNegative(int number) Sets _order = -number.
DView orderFirst() _order = -999999 (lowest possible).
DView orderLast() _order = 999999 (highest possible).
DView orderNone() _order = 0.
DView orderCustom(String property) Placeholder for custom CSS order property.
DView orderValue(String value) Parse string to int, set _order.

Usage Example:

DView(children)
  .flexRow()
  .flexGrow(2)          // This row’s children can grow 2x
  .shrink()             // Allow shrinking when needed
  .basisLg()            // Set flex-basis = 512px
  .build();

5.8 Grid Layout (DwGrid<DView> / DwGap<DView>) #

Core Grid Methods

Method Description
DView grid() Enable grid mode. The container will use GridView.extent(maxCrossAxisExtent: 200, ...) by default.
DView gridCols(int columns) (Currently not used directly) stores gridColCount.
DView gridColsNone() No explicit column count (fallback to default behavior).
DView gridColsSubgrid() Indicates subgrid behavior (not fully implemented).
DView setGridColsValue(String value) Parse string to set gridColValue (incomplete).
DView gridColsCustom(String property) Placeholder for custom column property.
DView gridRows(int rows) Set gridRowCount = rows.
DView gridRowsNone() No explicit row count (default).
DView gridRowsSubgrid() Subgrid for rows (not fully implemented).
DView setGridRowsValue(String value) Parse string to set gridRowsValue.
DView gridRowsCustom(String property) Placeholder for custom row property.
DView colSpanNumber(int number) Set colSpan = number.
DView colSpanFull() isColSpanFull = true.
DView colSpanCustom(String property) Placeholder for custom column-span.
DView colSpanValue(String val) Parse string to colSpan.
DView colStartNumber(int number) Set colStart = number.
DView colStartNegative(int number) Set colStart = -number.
DView colStartAuto() isColAuto = true (automatic placement).
DView colStartCustom(String property) Placeholder for custom column-start.
DView colStartValue(String value) Parse string to colStart.
DView colEndNumber(int number) Set colEnd = number.
DView colEndNegative(int number) Set colEnd = -number.
DView colEndAuto() isColAuto = true.
DView colEndCustom(String property) Placeholder for custom column-end.
DView colEndValue(String value) Parse string to colEnd.
DView colAuto() Reset all column spans/starts/ends to auto.
DView colNumber(int number) Set gridColValue = number.toString().
DView colNegative(int number) Set gridColValue = (-number).toString().
DView colCustom(String property) Placeholder for custom column property.
DView colValue(String value) Set gridColValue = value.
Method Description
DView rowSpanNumber(int number) Set rowSpan = number.
DView rowSpanFull() isRowSpanFull = true.
DView rowSpanCustom(String property) Placeholder for custom row-span.
DView rowSpanValue(String number) Parse string to rowSpan.
DView rowStartNumber(int number) Set rowStart = number.
DView rowStartNegative(int number) Set rowStart = -number.
DView rowStartAuto() isRowAuto = true.
DView rowStartCustom(String property) Placeholder for custom row-start.
DView rowStartValue(String number) Parse string to rowStart.
DView rowEndNumber(int number) Set rowEnd = number.
DView rowEndNegative(int number) Set rowEnd = -number.
DView rowEndAuto() isRowAuto = true.
DView rowEndCustom(String property) Placeholder for custom row-end.
DView rowEndValue(String number) Parse string to rowEnd.
DView rowAuto() Reset all row spans/starts/ends to auto.
DView rowNumber(int number) Set gridRowValue = number.toString().
DView rowNegative(int number) Set gridRowValue = (-number).toString().
DView rowCustom(String property) Placeholder for custom row property.
DView rowValue(String number) Set gridRowValue = number.
Method Description
DView gridFlowRow() Equivalent to CSS grid-auto-flow: row. Sets _isGridFlowRow = true.
DView gridFlowCol() Equivalent to CSS grid-auto-flow: column. Sets _isGridFlowCol = true.
DView gridFlowDense() Equivalent to CSS grid-auto-flow: dense. Sets _isGridFlowDense = true.
DView gridFlowRowDense() Equivalent to CSS grid-auto-flow: row dense.
DView gridFlowColDense() Equivalent to CSS grid-auto-flow: column dense.
Method Description
DView autoColsAuto() Equivalent to grid-auto-columns: auto.
DView autoColsMin() Equivalent to grid-auto-columns: min-content.
DView autoColsMax() Equivalent to grid-auto-columns: max-content.
DView autoColsFr() Equivalent to grid-auto-columns: repeat(auto-fit, minmax(min, 1fr)).
DView autoColsCustom(String property) Placeholder for custom.
DView setAutoColsValue(String value) Parse string, set autoColsValue.

Usage Example:

final gridItems = List<Widget>.generate(6, (i) {
  return Container(
    width: 80,
    height: 80,
    color: Colors.primaries[i % Colors.primaries.length],
  );
});

DView(gridItems)
  .grid()           // Enable grid mode (GridView.extent)
  .gapX(12)         // Horizontal spacing between grid items
  .gapY(12)         // Vertical spacing
  .build();

5.9 Text Alignment (DwTextAlign<DView>) #

Controls how a single Text child is aligned horizontally within its container.

Method Description
DView textCenter() textAlign = TextAlign.center
DView textLeft() textAlign = TextAlign.left
DView textRight() textAlign = TextAlign.right
DView textStart() textAlign = TextAlign.start
DView textEnd() textAlign = TextAlign.end
DView textJustify() textAlign = TextAlign.justify

Usage (effective only if child is a single Text widget):

DView([ Text("Hello World") ])
  .textCenter()
  .build();

5.10 Positioning & Centering (DwPosition<DView> / DwCenter<DView>) #

Relative & Absolute Positioning

Method Description
DView relative() Mark this container as relative. DView will use a parent Stack to position children.
DView absolute() Mark this container as absolute. It must appear inside a Stack.
DView top(double) Set positionTop = value.
DView left(double) Set positionLeft = value.
DView right(double) Set positionRight = value.
DView bottom(double) Set positionBottom = value.
  • Relative: Wraps both the container and any Positioned children in a Stack(children: [...]).
  • Absolute: Wraps the container itself in a Positioned(...). Should be used only when its parent is a Stack from .relative().

Center

Method Description
DView center() If both justifyCenter() and itemsCenter() have been called, sets alignment: Alignment.center on the Container.

5.11 Overflow Control (DwOverflow<DView>) #

Method Description
DView overflowXAuto() Enable horizontal scrolling by wrapping container in SingleChildScrollView(scrollDirection: Axis.horizontal).
DView overflowYAuto() Enable vertical scrolling by wrapping container in SingleChildScrollView(scrollDirection: Axis.vertical).

5.12 Responsive Breakpoints (DwResponsive<DView>) #

By mixing in DwResponsive<DView>, DView can respond to screen width breakpoints. Use variant prefixes (sm., md., lg., xl., 2xl.) before any utility method to apply it only at certain screen widths.

Breakpoint Definitions (Default)

Prefix Minimum Width (px) Typical Device Target
sm 640 Large phones / small tablets
md 768 Tablets
lg 1024 Small laptops
xl 1280 Large laptops/desktops
2xl 1536 Extra large monitors

Usage Example:

DView(children)
  .flexCol()            // Default: vertical layout
  .md.flexRow()         // When width >= 768px, switch to horizontal layout
  .gap(12)
  .p(16)
  .bg(Colors.grey.shade100)
  .roundedMd()
  .build();

6. Usage Examples #

Below are more in-depth examples demonstrating different combinations of utilities.

6.1 Building a Flex Row with Gap, Padding, and Background #

class FlexRowExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final squares = [
      Container(width: 50, height: 50, color: Colors.red),
      Container(width: 50, height: 50, color: Colors.green),
      Container(width: 50, height: 50, color: Colors.blue),
    ];

    return Scaffold(
      appBar: AppBar(title: Text("Flex Row Example")),
      body: Center(
        child: DView(squares)
          .flexRow()             // Horizontal flex container
          .justifyBetween()      // Space evenly between items
          .itemsCenter()         // Vertically center items
          .gap(16)               // 16px gap between each square
          .p(12)                 // 12px padding all around
          .bg(Colors.grey.shade200) // Light gray background
          .roundedLg()           // Rounded corners (8px radius)
          .shadow()              // Default drop shadow
          .border(width: 1, color: Colors.black12) // Light border
          .build(),
      ),
    );
  }
}

6.2 Creating a Complex Grid #

class ComplexGridExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Generate 6 colored boxes
    final gridItems = List<Widget>.generate(6, (i) {
      return DView([
        Container(
          color: Colors.primaries[i % Colors.primaries.length],
          width: double.infinity,
          height: double.infinity,
        ),
      ])
        .roundedSm()   // Small rounding (2px)
        .shadowSm()    // Small shadow behind each box
        .build();
    });

    return Scaffold(
      appBar: AppBar(title: Text("Complex Grid Example")),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: DView(gridItems)
          .grid()          // Enable grid mode (GridView.extent)
          .gapX(16)        // 16px horizontal spacing
          .gapY(16)        // 16px vertical spacing
          .rounded()       // Overall container rounded (4px)
          .bg(Colors.white)// White background behind grid
          .shadowMd()      // Medium shadow for parent container
          .build(),
      ),
    );
  }
}

6.3 Absolute & Relative Positioning #

class PositionExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Positioning Example")),
      body: Center(
        child: DView([
          // Yellow background box (parent container)
          DView([
            Container(
              width: 200,
              height: 200,
              color: Colors.yellowAccent,
            ),
            // Red square positioned top-left
            Positioned(
              top: 12,
              left: 12,
              child: Container(
                width: 50,
                height: 50,
                color: Colors.red,
              ),
            ),
            // Blue square positioned bottom-right
            Positioned(
              bottom: 12,
              right: 12,
              child: Container(
                width: 50,
                height: 50,
                color: Colors.blue,
              ),
            ),
          ])
            .relative()       // Use Stack container
            .border(width: 2, color: Colors.black)
            .w(200)
            .h(200)
            .build(),
        ]),
      ),
    );
  }
}

6.4 Combining Multiple Utilities #

class CombinedExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final iconText = [
      Icon(Icons.favorite, color: Colors.white),
      SizedBox(width: 8),
      Text("Like", style: TextStyle(color: Colors.white)),
    ];

    return Scaffold(
      backgroundColor: Colors.grey.shade100,
      body: Center(
        child: DView(iconText)
          .flexRow()
          .justifyCenter()
          .itemsCenter()
          .p(16)
          .py(12)
          .bg(Colors.pinkAccent)
          .roundedFull()
          .shadowLg()
          .build(),
      ),
    );
  }
}

6.5 Responsive Layout Example #

class ResponsiveExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final cards = [
      DView([Container(color: Colors.red, height: 100)])
        .roundedMd()
        .shadowSm()
        .build(),
      DView([Container(color: Colors.green, height: 100)])
        .roundedMd()
        .shadowSm()
        .build(),
      DView([Container(color: Colors.blue, height: 100)])
        .roundedMd()
        .shadowSm()
        .build(),
    ];

    return Scaffold(
      appBar: AppBar(title: Text("Responsive Example")),
      body: Center(
        child: DView(cards)
          .flexCol()               // Default: vertical stacking
          .md.flexRow()            // At width >= 768px, switch to horizontal
          .gap(16)
          .p(16)
          .bg(Colors.grey.shade200)
          .roundedLg()
          .shadow()
          .build(),
      ),
    );
  }
}

7. Advanced Topics & Customization #

7.1 Parsing Class Strings into Method Chains #

If you prefer to define your layout styling via CSS-like class strings (e.g., "flex-row gap-4 p-3 bg-red-500"), you can create a helper function that maps each class to the corresponding DView method:

DView dviewFromClasses(String classNames, List<Widget> children) {
  final dv = DView(children);
  final classes = classNames.trim().split(RegExp(r'\s+'));

  for (var cls in classes) {
    switch (cls) {
      case 'flex-row':
        dv.flexRow();
        break;
      case 'flex-col':
        dv.flexCol();
        break;
      case 'justify-center':
        dv.justifyCenter();
        break;
      case 'items-center':
        dv.itemsCenter();
        break;
      case 'gap-2':      // Suppose gap-2 corresponds to 8px
        dv.gap(8);
        break;
      case 'p-3':        // Suppose p-3 corresponds to 12px
        dv.p(12);
        break;
      case 'bg-red-500':
        dv.bg(Colors.red.shade500);
        break;
      case 'rounded-md':
        dv.roundedMd();
        break;
      case 'shadow-sm':
        dv.shadowSm();
        break;
      // Add more mappings for each supported class...
      default:
        // Unknown class: ignore or throw warning
        break;
    }
  }

  return dv;
}

Usage:

Widget widget = dviewFromClasses(
  "flex-row justify-center items-center gap-2 p-3 bg-red-500 rounded-md shadow-sm",
  [
    Text("Hello"),
    Icon(Icons.ac_unit),
  ],
).build();

This approach allows you to keep a familiar “class string” syntax and convert it into the DView method chain at runtime.


7.2 Extending Unimplemented Utilities #

Several methods act as placeholders for custom properties:

  • DView flexCustom(String property)
  • DView basisCustom(String property)
  • DView gridColsCustom(String property)
  • DView autoColsCustom(String property)
  • DView gapCustom(String property)
  • DView setGapXValue(String value) / DView setGapYValue(String value)
  • DView setGridColsValue(String value) / DView setGridRowsValue(String value)

To implement these, you can:

  1. Add internal parsing logic (e.g., parse a CSS-like string "1fr" to proper width/height or fraction).
  2. Map custom property names to actual Flutter properties.
  3. Extend the build() method to examine these new fields and inject the corresponding Widget or style.

For example, to support basisCustom("50%"), you could interpret "50%" relative to the parent width (e.g., MediaQuery.of(context).size.width * 0.5).


7.3 Nested DView Instances #

You can nest DView inside another DView to compose hierarchical styling:

Widget nestedExample = DView([
  DView([
    Text("Header", style: TextStyle(fontSize: 20, color: Colors.white)),
  ])
    .p(16)
    .bg(Colors.blue)
    .roundedTop()
    .build(),
  DView([
    Text("Content paragraph 1..."),
    Text("Content paragraph 2..."),
  ])
    .p(16)
    .build(),
  DView([
    Icon(Icons.thumb_up),
    Text("Footer action"),
  ])
    .flexRow()
    .justifyCenter()
    .gap(8)
    .p(16)
    .bg(Colors.grey.shade100)
    .roundedBottom()
    .build(),
])
  .border(width: 1, color: Colors.black12)
  .shadowSm()
  .build();
  • The outer DView wraps three nested DView blocks: Header, Content, Footer.
  • Each nested block can have its own styling; the outer DView adds a border and a small shadow.

7.4 Interoperability with Other Widgets #

While DView handles many common styling needs, you can combine it with any Flutter Widget:

Widget combinedWidgets = DView([
  IconButton(
    icon: Icon(Icons.menu),
    onPressed: () {},
  ),
  TextField(
    decoration: InputDecoration(hintText: "Search..."),
  ),
  ElevatedButton(
    onPressed: () {},
    child: Text("Submit"),
  ),
])
  .flexRow()
  .itemsCenter()
  .gap(12)
  .p(16)
  .bg(Colors.white)
  .shadowSm()
  .roundedMd()
  .build();
  • IconButton, TextField, and ElevatedButton are regular Flutter widgets.
  • DView wraps them seamlessly into a styled, flex-based toolbar.

8. Performance Considerations #

While DView provides a highly convenient and declarative styling API, there are a few performance considerations:

  1. Rebuild Overhead: Each call to .build() returns a Builder widget that executes the layout logic in its build function. If your DView tree is extremely large or rebuilt frequently (e.g., in a ListView.builder), consider using const constructors where possible or caching parts of the tree.
  2. Stateful vs. Stateless: DView itself is a StatelessWidget, but its build() logic does inspect many fields. If you need to animate properties (e.g., animate padding or color), you may need to wrap certain parts in AnimatedContainer or use an AnimationController.
  3. Heavy Widget Composition: When using features like Grid + nested DViews, or complex Positioned logic, the widget tree can grow deep. Profile using Flutter’s DevTools to identify expensive widgets and consider flattening nested structures or combining multiple simple utilities into one custom widget if needed.
  4. Responsive Logic: applyResponsive(context) reads MediaQuery.of(context) on every build. In very large trees with many responsive branches, consider using an inherited widget or context-level breakpoint provider that caches the current screen width to avoid repeated lookups.

9. FAQ #

Q: Where does DView apply the padding/margin – on the outer container or inner?

  • A: Padding is applied to the Container that wraps the child content (which may be a Flex, GridView, or single widget). Margin is handled by applying Container(margin: ...) on the outermost wrapper. Both are applied before background, border, and shadow.

Q: If I call both .bg(color) and .from(...).to(...), which one takes precedence?

  • A: If you set colorFrom (via .from(...)), DView constructs a LinearGradient with that color and ignores the solid bgColor. Conversely, if you only call .bg(...) with no gradient methods, a simple color is used.

Q: How do I use custom fonts or text styles inside DView?

  • A: DView does not override text styles. If you pass a Text widget with a TextStyle, it will be rendered with that style. If you call .textCenter(), DView will apply only textAlign = TextAlign.center; the original TextStyle remains intact.

Q: Can I animate DView properties?

  • A: Since DView builds a static widget tree, to animate properties like color or border radius, wrap the DView(...).build() call in an AnimatedContainer, AnimatedOpacity, or similar. Alternatively, extend DView to return an AnimatedDefaultTextStyle or TweenAnimationBuilder around specific properties.

Q: Does DView conflict with other styling packages?

  • A: DView can coexist with any other widget. It is simply a builder that produces a styled Container or layout. You can nest other styled widgets inside or outside a DView as needed.

10. License #

MIT License

Copyright (c) 2025 Your Name

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights 
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
copies of the Software, and to permit persons to whom the Software is 
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included 
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE SOFTWARE.

This README was generated to provide an exhaustive reference for the Dartwind / DView utility library in Flutter. Use it as a guide to quickly adopt and leverage the full power of the utility-first approach in your Flutter applications.

1
likes
120
points
115
downloads

Publisher

unverified uploader

Weekly Downloads

Dartwind like a tailwind

Homepage

Documentation

API reference

License

unknown (license)

Dependencies

float_column, flutter, logger, yaml

More

Packages that depend on dartwind