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
- Introduction
- Installation
- Quick Start
- Core Concept: DView Workflow
- Detailed API Reference
- 5.1 Initialization
- 5.2 Sizing (DwSize)
- 5.3 Padding & Margin (DwPadding / DwMargin)
- 5.4 Background, Colors & Gradients (DwBackgroundColor / DwGradientColor)
- 5.5 Borders & Rounded Corners (DwBorder / DwRounded)
- 5.6 Shadows (DwShadow)
- 5.7 Flex Layout (DwFlex / DwFlexUtilities / DwGap)
- 5.8 Grid Layout (DwGrid / DwGap)
- 5.9 Text Alignment (DwTextAlign)
- 5.10 Positioning & Centering (DwPosition / DwCenter)
- 5.11 Overflow Control (DwOverflow)
- 5.12 Responsive Breakpoints (DwResponsive)
- Usage Examples
- Advanced Topics & Customization
- Performance Considerations
- FAQ
- 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
-
Initialization: You start by creating a
DView
object and passing it aList<Widget>
that represents the children you want to display.final dv = DView([ Text("Item 1"), Text("Item 2"), Icon(Icons.star), ]);
-
Method Chaining: You call a sequence of methods on that
DView
object to configure layout, styling, spacing, etc. Each method modifies the internal state ofDView
and returnsthis
, enabling a fluent, chainable syntax.dv.flexRow() .justifyBetween() .itemsCenter() .p(8) .bg(Colors.blue) .shadowSm() .roundedMd();
-
Building: Finally, you call
.build()
, which takes all of the state accumulated by your chained calls and synthesizes it into a singleWidget
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();
-
Integration: The single
Widget
returned bybuild()
can be inserted anywhere in your Flutter widget hierarchy—inside aScaffold
, aColumn
, aListView
, 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.
- A
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
, ormaxH
are set, all sizing is controlled via a singleBoxConstraints
object. - Otherwise, simple
width
andheight
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
ormLeft
,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 aLinearGradient
withbegin = colorFromAlignment
andend = 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 withdirection = Axis.vertical
(i.e., aColumn
). - To create a
Wrap
, call.flexWrap()
; to revert to a normalRow
/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 aStack(children: [...])
. - Absolute: Wraps the container itself in a
Positioned(...)
. Should be used only when its parent is aStack
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:
- Add internal parsing logic (e.g., parse a CSS-like string
"1fr"
to proper width/height or fraction). - Map custom property names to actual Flutter properties.
- Extend the
build()
method to examine these new fields and inject the correspondingWidget
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 nestedDView
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
, andElevatedButton
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:
- Rebuild Overhead: Each call to
.build()
returns aBuilder
widget that executes the layout logic in itsbuild
function. If yourDView
tree is extremely large or rebuilt frequently (e.g., in aListView.builder
), consider usingconst
constructors where possible or caching parts of the tree. - Stateful vs. Stateless:
DView
itself is aStatelessWidget
, but itsbuild()
logic does inspect many fields. If you need to animate properties (e.g., animate padding or color), you may need to wrap certain parts inAnimatedContainer
or use anAnimationController
. - 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. - Responsive Logic:
applyResponsive(context)
readsMediaQuery.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 thechild
content (which may be aFlex
,GridView
, or single widget). Margin is handled by applyingContainer(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 aLinearGradient
with that color and ignores the solidbgColor
. Conversely, if you only call.bg(...)
with no gradient methods, a simplecolor
is used.
Q: How do I use custom fonts or text styles inside DView
?
- A:
DView
does not override text styles. If you pass aText
widget with aTextStyle
, it will be rendered with that style. If you call.textCenter()
,DView
will apply onlytextAlign = TextAlign.center
; the originalTextStyle
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 theDView(...).build()
call in anAnimatedContainer
,AnimatedOpacity
, or similar. Alternatively, extendDView
to return anAnimatedDefaultTextStyle
orTweenAnimationBuilder
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 styledContainer
or layout. You can nest other styled widgets inside or outside aDView
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.