division 0.8.7+2

  • Readme
  • Changelog
  • Example
  • Installing
  • 96

Division #

Simple to use yet powerfull style widgets with syntax inspired by CSS.

The true power of this package is a combination of its features. Flutter widgets are designed to combine both the styling widgets and the structural widgets together when building apps. This package tries to decouple style from structure. This results in much more readable code. Another strong point of this package is the ease of animations.

⚠️ If you encounter an issue or have any feedback which you think could improve Division, please open an issue here

Built with Division #

App designer, CodeCode

Getting Started #

This is the two main widgets included in Division

Parent(
  child: Widget,
  style: ParentStyle, 
  gesture: Gestures,
);
Txt(
  String,
  style: TxtStyle,
  gesture: Gestures,
);

Basic example #

Import

import 'package:division/division.dart';

Code

bool pressed = false;

final buttonStyle = (pressed) => TxtStyle()
  ..alignment.center()
  ..background.color(pressed ? Colors.orange : Colors.white)
  ..textColor(pressed ? Colors.white : Colors.orange)
  ..borderRadius(all: 5)
  ..border(all: 3, color: Colors.orange)
  ..padding(vertical: 10, horizontal: 15)
  ..ripple(true)
  ..animate(150, Curves.easeOut);

Gestures buttonGestures() =>
    Gestures()..isTap((isPressed) => setState(() => pressed = isPressed));

@override
Widget build(BuildContext context) {
  return Txt(
    'Styled button!',
    style: buttonStyle(pressed),
    gesture: buttonGestures(),
  );
}

Result

Documentation #

All current and future Division widgets share a common style base.

Core style methods #

Animate
  ..animate([int duration, Curve curve = Curves.linear])

A powerful style method. Whenever a style property changes, the widget will animate between the two states (given the style property is compatibel with animations). duration in ms

Alignment
..alignment.[alignment] // alignment.topCenter()

The widget alignment

Content alignment
  ..alignmentContent.[alignment] // alignment.topCenter()

Alignment of the child.

Padding
  ..padding({double all, 
        double horizontal, 
        double vertical, 
        double top, 
        double bottom, 
        double left, 
        double right})

All properties work together. padding(all: 10, top: 30) is equivilent to padding(top: 30, bottom: 10, left: 10, right: 10)

Margin
  ..margin({double all,
        double horizontal,
        double vertical,
        double top,
        double bottom,
        double left,
        double right})

All properties work together. margin(all: 10, top: 30) is equivilent to margin(top: 30, bottom: 10, left: 10, right: 10)

Background color
  ..background.color(Color)
  ..background.hex(xxxxxx)
  ..background.rgba(int, int, int, [double])

color format options: hex('#xxxxxx'), rgba(int, int, int, double) or [Color].

Background image
  ..background.image(
        {String url, 
        String path, 
        ColorFilter colorFilter, 
        ImageProvider<dynamic> imageProveder,
        BoxFit fit, 
        AlignmentGeometry alignment = Alignment.center, 
        ImageRepeat repeat = ImageRepeat.noRepeat})

Eighter the [url] or the [path] has to be specified. [url] is for network images and [path] is for local images.

Background blur
  ..background.blur(double blur)

Blurs the background. Can be used for example to achieve a "frosted glass" effect:

  StyleClass()
    ..background.blur(10)
    ..background.rgba(255,255,255,0.15)

Does not work together with rotate().

Background blend mode
  ..background.blendMode(BlendMode blendMode)

Algorithms for blending background

Linear gradient
  ..linearGradient({AlignmentGeometry begin = Alignment.left,
        AlignmentGeometry end = Alignment.right,
        @required List<Color> colors,
        TileMode tileMode = TileMode.clamp,
        List<double> stops})
Radial gradient
  ..radialGradient(
      {AlignmentGeometry center = Alignment.center,
      @required double radius,
      @required List<Color> colors,
      TileMode tileMode = TileMode.clamp,
      List<double> stops})
Sweep gradient
  ..sweepGradient(
      {AlignmentGeometry center = Alignment.center,
      double startAngle = 0.0,
      @required double endAngle,
      @required List<Color> colors,
      TileMode tileMode = TileMode.clamp,
      List<double> stops})

In the style widget constructor, specify what angle calculation format you want to use.

Opacity
  ..opacity(double opacity)

Opacity applied on the whole widget.

Value must not be negative.

Border
  ..border(
        {double all,
        double left,
        double right,
        double top,
        double bottom,
        Color color = const Color(0xFF000000),
        BorderStyle style = BorderStyle.solid})

Choose between all, left, right, top and bottom. all works together with the other properties. color format options: hex('#xxxxxx'), rgb(int, int, int), rgba(int, int, int, double) or [Color].

Border radius
  ..borderRadius(
        {double all,
        double topLeft,
        double topRight,
        double bottomLeft,
        double bottomRight})

It is valid to use all together with single sided properties. Single sided properties will trump over the all property.

See also [circle] for creating circular widgets.

Circle
  ..circle([bool enable = true])

Makes the widget circular

Box shadow
  ..boxShadow(
        {Color color = const Color(0x33000000),
        double blur = 0.0,
        Offset offset = Offset.zero,
        double spread = 0.0})

See [elevation] for a different way of defining a box shadow.

Elevation
  ..elevation(
        double elevation,
        {double angle = 0.0,
        Color color = const Color(0x33000000),
        double opacity = 1.0})

Elevates the widget with a boxShadow. [opacity] is a relative constant

Scale
  ..scale(double ratio)

Scale the widget

Offset
  ..offset([double dx, double dy])

Offsets the widget

Rotate
  ..rotate(double angle)

Rotates the widget. By default one turn equals the value 1.0. To change to radians: StyleClass(useRadians: true).

Ripple
  ..ripple(bool enable, {dynamic splashColor, dynamic highlightColor})

Material ripple effect applied on tap.

Overflow
  ..overflow.visible({Axis direction = Axis.vertical})
  ..overflow.scrollable({Axis direction = Axis.vertical})
  ..overflow.hidden()

Change child overflow behaviour. Choose the overflow direction with the [direction] parameter.

Width, minWidth, maxWidth, Height, minHeight, maxHeight
  ..[type](double dimension)

Parent #

Parent(
  style: ParentStyle,
  gesture: Gestures,
  child: Widget
)

As the name suggests this widget is a simple styled widget which takes a child.

ParentStyle #

// format
ParentStyle()
  ..[style method]

// example
ParentStyle()
  ..width(100)
  ..padding(all: 10)
  ..elevation(5)
Add
  ..add(ParentStyle parentStyle, {bool override = false})

Combines style from two styled widgets.

Clone
  ..ParentStyle().clone()

This will clone the ParentStyle widget. This is usefull if you for example want to add more style to a widget without modifying the initial style.

Txt #

Txt(
  String,
  style: TxtStyle,
  gesture: Gestures,
)

As the name suggests this widget is a simple styled widget which takes a String as its child. This widget enables text styling with the TxtStyle widget. This also has the possibility to make the widget editable.

TxtStyle #

// format
TxtStyle()
  ..[style method]

// example
TxtStyle()
  ..width(100)
  ..padding(all: 10)
  ..textColor(Colors.blue)
  ..bold()
Editable
  ..editable(bool enable,
        {TextInputType keyboardType,
        String placeholder,
        bool obscureText = false,
        int maxLines,
        void Function(String) onChange,
        void Function(bool focus) onFocusChange,
        void Function(TextSelection, SelectionChangedCause) onSelectionChanged,
        void Function() onEditingComplete,
        FocusNode focusNode})

This makes the widget editable, just like a TextField, its just much easier to style

Text align
  ..textAlign.center()
Font weight
  ..fontWeight(FontWeight fontWeight)

A shorthand to make the text bold:

  ..bold([bool enable])
Italic
  ..italic([bool enable])
Font family
  ..fontFamily(String font, {List<String> fontFamilyFallback})
Text color
  ..textColor(Color textColor)
Max lines
  ..maxLines(int maxLines)
Letter spacing
  ..letterSpacing(double space)
Word spacing
  ..wordSpacing(double space)
Text decoration
  ..textDecoration(TextDecoration decoration)
Text shadow
  ..textShadow({Color color = const Color(0x33000000),
      double blur = 0.0,
      Offset offset = Offset.zero})
Text elevation
  ..textElevation(double elevation,
      {double angle = 0.0,
      Color color = const Color(0x33000000),
      double opacity = 1.0})
Add
  ..add(TxtStyle txtStyle, {bool override = false})

This adds together two TxtStyles. The override property specifies if already defined properties should be overrided.

Clone
  ..TxtStyle().clone()

This will clone the TxtStyle widget. This is usefull if you for example want to add more style to a widget without modifying the initial style.

Gestures #

isTap
  ..isTap((isTapped) => setState(() => pressed = isTapped))

Called whenever the tap state on the widget changes. This replaces the use of onTapDown, onTapUp and onTapCancel together.

Other
  ..onTap()
  ..onTapUp()
  ..onTapCancel()
  ..onDoubleTap()
  ..onTapDown()
  ..onLongPress()
  ..onLongPressStart()
  ..onLongPressEnd()
  ..onLongPressMoveUpdate()
  ..onLongPressUp()
  ..onVerticalDragStart()
  ..onVerticalDragEnd()
  ..onVerticalDragDown()
  ..onVerticalDragCancel()
  ..onVerticalDragUpdate()
  ..onHorizontalDragStart()
  ..onHorizontalDragEnd()
  ..onHorizontalDragCancel()
  ..onHorizontalDragUpdate()
  ..onHorizontalDragDown()
  ..onForcePressStart()
  ..onForcePressEnd()
  ..onForcePressPeak()
  ..onForcePressUpdate()
  ..onPanStart()
  ..onPanEnd()
  ..onPanCancel()
  ..onPanDown()
  ..onPanUpdate()
  ..onScaleStart()
  ..onScaleEnd()
  ..onScaleUpdate()

Examples and best practices #

Decoupling style from structure

final ParentStyle cardStyle = ParentStyle()
  ..height(175)
  ..padding(horizontal: 20.0, vertical: 10)
  ..alignment.center()
  ..background.hex('#3977FF')
  ..borderRadius(all: 20.0)
  ..elevation(10, color: hex('#3977FF'));

Widget build(BuildContext context) {
  return Parent(
    style: cardStyle,
    child: Widget,
  );
}

Variable dependent style

final Color color = Colors.blue;

final cardStyle = (color) => ParentStyle()
  ..height(175)
  ..padding(horizontal: 20.0, vertical: 10)
  ..alignment.center()
  ..background.color(color)
  ..borderRadius(all: 20.0)
  ..elevation(10, color: color);

Widget build(BuildContext context) {
  return Parent(
    style: cardStyle(color),
    child: Widget,
  );
}

Animated widgets

bool pressed = false;

final cardStyle = (pressed) => ParentStyle()
  ..height(175)
  ..padding(horizontal: 20.0, vertical: 10)
  ..alignment.center()
  ..borderRadius(all: 20.0)
  ..animate(200, Curves.easeOut)
  ..background.color(pressed ? Colors.white : Colors.black)
  ..elevation(pressed ? 10 : 20);

Widget build(BuildContext context) {
  return Parent(
    style: cardStyle(pressed),
    gesture: Gestures()
      ..isTap((isPressed) => setState(() => pressed = isPressed)),
    child: Widget,
  );
}

or

bool pressed = false;

final cardStyle = (pressed) => ParentStyle()
  ..height(175)
  ..padding(horizontal: 20.0, vertical: 10)
  ..alignment.center()
  ..borderRadius(all: 20.0)
  ..animate(200, Curves.easeOut)
  ..background.color(pressed ? Colors.white : Colors.black)
  ..elevation(pressed ? 10 : 20);

Gestures cardGesture() => Gestures()
  ..isTap((isPressed) => setState(() => pressed = isPressed));

Widget build(BuildContext context) {
  return Parent(
    style: cardStyle(pressed),
    gesture: cardGesture(),
    child: Widget,
  );
}

0.8.7 #

  • Added textShadow method to TxtStyle
  • Added textElevation method to TxtStyle
  • Added circle method to CoreStyle
  • Added background.blendMode method to CoreStyle
  • [Fix] Error when Parent child is [null]
  • [Fix] BoxShadow all property not working corectly

0.8.6 #

  • Renamed GestureClass widget to Gestures
  • [Fix] Txt placeholder not working without an animation
  • [Fix] onFocusChange triggering when focus doesnt change.
  • Changed boxShadow offset property type from List<double> to Offset
  • Changed enable parameter in editable to named
  • removed S and G class
  • Changed default textAlign value to start
  • minor performance improvements

0.8.5 #

  • [Fix] Text resetting to default value after editing when using Txt with editable enabled
  • Changed placeholder FontWeight to normal when using Txt with editable enabled
  • Improved performance when using Txt with editable enabled

0.8.4 #

  • Added animation support for fontSize, textColor, maxLines, letterSpacing and wordSpacing
  • Added textDirection method to TxtStyle

0.8.3+1 #

  • [fix] isTap not working correctly

0.8.3 #

  • Added isTap method to GestureClass
  • Other minor improvements

0.8.2 #

  • Added onEditingComplete parameter to the editable method in TxtStyle
  • Added textDecoration to TxtStyle
  • Added maxLines parameter to the editable method
  • [Fix] Ripple not working when BoxDecoration is null

0.8.1 #

  • Added placeholder parameter to the editable method in TxtStyle
  • Added clone method to be able to clone a StyleClass
  • Added textAlign method to TxtStyle
  • Other minor improvements

0.8.0+1 #

  • [Fix] Fixed bug with add method not working correctly

0.8.0 #

  • Renamed Division widget to Parent
  • Introduced Txt widget
  • [Beta] Introduced to posiblilty to make the Txt widget editable just like a TextField
  • [Breaking] Added new ways to calculate angles. Changed useRadians to AngleFormat
  • Minor tweaks and improvements

0.7.0 #

More strict typing is the theme of this update. #

  • Added alternative class names. StyleClass -> S and GestureClass -> G.
  • [Breaking] Changed backgroundColor syntax to background.color([Color]), background.hex() and background.rgba(int, int, int, [double]). Moved backgroundImage and backgroundBlur to background method.
  • [Breaking] Changed alignment syntax from alignment(dynamic [alignment]) to alignment.[alignment]
  • [Breaking] Changed overflow syntax from overflow([type]) to overflow.[type].
  • [Breaking] Changed linearGradient, radialGradient and sweepGradient alignment paramteres from [dynamic] to [AlignmentGeometry].
  • [Breaking] Changed ripple, elevation, boxShadow, border, sweepGradient, radialGradient, linearGradient color parameters from [dynamic] to [Color]. Use [Color], rgb(), rgba() or hex() for color.
  • [Fix] overflow.hidden() now clips with a borderRadius.
  • [Fix] Bug with Gestures not activating

0.6.4 #

  • Added opacity paramter to the elevation method. This parameter is a relative opacity constant.
  • Added the optional paramteres behaviour, excludeFromSemantics and dragStartBehaviour to GestureClass.
  • Added hex function.
  • [Fix] ripple now works together with all gestures.
  • [Breaking] As recomended in the dartlang documentation the single dotted chained methods is recalled. .overflow('scroll') -> ..overflow('scroll'). https://dart-lang.github.io/linter/lints/avoid_returning_this.html

0.6.3 #

  • Added support for singledotted chained methods for both the StyleClass and the GestureClass. ..overflow('scroll') -> .overflow('scroll').

0.6.2 #

  • Added overflow method to StyleClass.
  • [Breaking] angled property inside the elevation method is renamed to angle and is now given in a circular value. 0.0 equals down. [null] equals directly under the widget.

0.6.1 #

  • [Fix] ripple and opacity now works with add method.
  • Other minor improvements and fixes

0.6.0 #

  • Added ripple method to StyleClass.
  • Added opacity method to StyleClass.
  • Major rewrite of widget builder. Improved performance.

0.5.0 #

  • Added backgroundBlur method to the StyleClass.
  • Added backgroundImage method to StyleClass.
  • border now supports the use of all and left, right, top and bottom simultaneous.'border(all: 10, left: 20)'.
  • borderRadius now supports the use of all and topLeft, topRight, bottomLeft and bottomRight simultaneous. 'borderRadius(all: 10, bottomLeft: 30)'.
  • padding and margin now supports the use of all parameters simultaneous. padding(all: 10, bottom: 50).
  • Added rgb() and rgba() functions. May replace [int, int, int] and [int, int, int, double] formats in color parameters.
  • [Breaking] ripple method removed until a better solution is implemented.

0.4.0 #

  • [Breaking] Removed hex and rgba properties and combines them with the color property and changes it to dynamic. color property now supports HEX ('#xxxxxx'), RGBA ([int, int, int, double]), RGB ([int, int, int]) and [Color] format.
  • Changed alignment properties to dynamic. The alignment property now supports a variety of different formats.
  • The widget tree is now dynamicly constructed. Unused widgets is no longer being added to the widget tree. Improved performance.
  • Added linearGradient(), radialGradient(), sweepGradient() and border() methods to the StyleClass.
  • Added optional parameter override to add(), so you can choose to override already defined style or not when combining classes.
  • Added animation support for scale(), rotate(), offset and align(). All styling properties now support animation.
  • [Breaking] Added the ability to change between using radians or values between 0 to 1 in the StyleClass. Change by: StyleClass(useRadians: true)..[style]. Breaking because your values may be written in radians but now is interpreted as not.
  • [Breaking] Removed elevation bgColor parameter.
  • [Breaking] backgroundColor changed from named parameter to unnamed.
  • [beta] Added ripple() method to the StyleClass. Known issues: Doesnt cover the whole area when border and borderRadius is in use. Problems with gestures.
  • [beta] Added some custom presets. import 'package:division/presets.dart'.

0.3.0 #

  • [Breaking] Major rewrite. Changed the List<StyleItem> format to a custom StyleClass. Changed the List<GestureItem> format to a custom GestureClass.
  • [Breaking] Improved elevation() style property
  • Added animate(), rotate(), scale() and offset() properties to the StyleClass
  • Enhanced preformance
  • Other minor tweaks

0.2.0 #

  • Added all gesture properties found in the GestureDetector widget
  • Added elevation style property containing boxShadow presets.
  • Fixed bug with S.align() and S.alignChild() style properties. They now work with topLeft, topRight, bottomLeft and bottomRight!
  • General code improvements and optimizing

0.1.0 #

  • Initial release/ idea
  • Implementet the basic features for the style property and the gesture property for the Division widget

example/readme.md

Example showcase #

Design, codeCodeCode

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  division: ^0.8.7+2

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:division/division.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
92
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
96
Learn more about scoring.

We analyzed this package on Mar 30, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6
  • Flutter: 1.12.13+hotfix.8

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test