Code Monkey home page Code Monkey logo

styled_widget's Introduction

Simplifying your widget tree structure by defining widgets using methods.

License: MIT

Buy Me A Coffee


Thanks to the introduction of extension methods in Dart 2.7.0, styled_widget makes it possible to build widget tree`s more readable and efficient.

styled_widget is build as a tool to enhance your Flutter development experience and to seamlessly integrate with your codebase.

Showcase

Design, Code Design, Code Design, Code

Basic example

styled_widget has a bottom up approach to building widget`s. This means you start with the inner most element and layer widget`s on top. The following example is structured as follows: Icon -> blue circle -> light blue circle -> card -> background

Icon(OMIcons.home, color: Colors.white)
  .padding(all: 10)
  .decorated(color: Color(0xff7AC1E7), shape: BoxShape.circle)
  .padding(all: 15)
  .decorated(color: Color(0xffE8F2F7), shape: BoxShape.circle)
  .padding(all: 20)
  .card(
    elevation: 10,
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(20),
    ),
  )
  .alignment(Alignment.center)
  .backgroundColor(Color(0xffEBECF1));
Raw Flutter (click to show)
DecoratedBox(
  decoration: BoxDecoration(
    color: Color(0xffEBECF1),
  ),
  child: Align(
    alignment: Alignment.center,
    child: Card(
      elevation: 10,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(20),
      ),
      child: Padding(
        padding: EdgeInsets.all(20),
        child: DecoratedBox(
          decoration: BoxDecoration(
            color: Color(0xffE8F2F7),
            shape: BoxShape.circle,
          ),
          child: Padding(
            padding: EdgeInsets.all(15),
            child: DecoratedBox(
              decoration: BoxDecoration(
                color: Color(0xff7AC1E7),
                shape: BoxShape.circle,
              ),
              child: Padding(
                padding: EdgeInsets.all(10),
                child: Icon(
                  OMIcons.home,
                  color: Colors.white,
                ),
              ),
            ),
          ),
        ),
      ),
    ),
  ),
);

Docs

See the documentation at styled_widget/wiki for more information about using styled_widget!

Quicklinks

styled_widget's People

Contributors

ash0080 avatar chachako avatar chomosuke avatar devmuaz avatar fibbers avatar mit-mit avatar moraispgsi avatar mrsquaare avatar naveenadi avatar niboac avatar prn-ice avatar reinbentdal avatar vance-liu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

styled_widget's Issues

Possibility to create a base style as to not repeat

I saw its possible to use the Styled.widget(child) in the example, but this does not seem have the methods that are available for Text e.g. textColor().

            Text('NAME')
                .fontSize(16)
                .fontWeight(FontWeight.w600)
                .textColor(Colors.black),

            Text('AGE')
                .fontSize(16)
                .fontWeight(FontWeight.w600)
                .textColor(Colors.black),

Imagine we had something like above, it seems redundant to repeat ourselves. Is there a possibility to create a base style that can be applied to all Text widgets

e.g.

     final styledText= (Widget child) => StyledText.widget(child)
        .textColor(Colors.black)
        .fontSize(16)

     styledText(Text('NAME')),
     styledText(Text('AGE')),

or

Text('NAME')
  .applyStyles(?)

Text('AGE')
  .applyStyles(?)

Null-safety issue with animated translate

In 0.3.1 code like:
SomeWidget(...).translate(offset: ..., animate: true)
throws:

======== Exception caught by widgets library =======================================================
The following _CastError was thrown building _StyledAnimatedBuilder(dependencies: [_StyledInheritedAnimation]):
type 'Null' is not a subtype of type 'AlignmentGeometryTween' in type cast

The relevant error-causing widget was: 
  _StyledAnimatedBuilder file:///Users/ds/.pub-cache/hosted/pub.dartlang.org/styled_widget-0.3.1/lib/src/extensions/widget_extension.dart:861:13
When the exception was thrown, this was the stack: 
#0      _AnimatedTransformState.forEachTween (package:styled_widget/src/animated_widget.dart:263:9)
#1      ImplicitlyAnimatedWidgetState._constructTweens (package:flutter/src/widgets/implicit_animations.dart:427:5)
#2      ImplicitlyAnimatedWidgetState.initState (package:flutter/src/widgets/implicit_animations.dart:381:5)
#3      AnimatedWidgetBaseState.initState (package:flutter/src/widgets/implicit_animations.dart:553:11)
#4      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4632:57)
...

I think you should change
as AlignmentGeometryTween;
to
as AlignmentGeometryTween?;
at mentioned in stack trace line 263

How use " Japan style example" in own main.dart // there is issue about my codes

Hello! Mr.Rein ! I just wanted use simply " Japan style example " in my own project ( in main.dart ) but i am sure now it doesn't use " simply " as i though.

//// >>>>>   CODE START  <<<<<////

 import 'package:flutter/material.dart';
import 'package:styled_widget/styled_widget.dart';
import 'user_card.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(


        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'UYGULAMA ADI'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(

        title: Text(widget.title),
      ),
      body: Center(

        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            missionCard(
              cardColor: Colors.lightBlue,
              cardOwnder: "assets/userAvatar.png",
              cardMission1: "",
              cardMission2: "",
            ),
            SizedBox(height: 60),


            //// >>>>>   japan style example  START   <<<<< ////

            Styled.widget() // red circle
                .backgroundColor(Color(0xffFF6160))
                .constrained(width: 100, height: 100)
                .clipOval()
                .gestures(
              onTap: () => showBottomSheet(
                context: context,
                backgroundColor: Colors.transparent,
                builder: (BuildContext context) => BottomSheet(),
              ),
            ),

            //// >>>>>   japan style example  END  <<<<<////

          ],
        ),

      ),


      // This trailing comma makes auto-formatting nicer for build methods.
    );

  }
}

//// >>>>>   Japan style example CLASS START  <<<<<////

class BottomSheet extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.end,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        Text('サインアップ') // button
            .textColor(Colors.white)
            .fontSize(24)
            .padding(vertical: 15, horizontal: 30)
            .decorated(
          color: Color(0xff41508D),
          borderRadius: BorderRadius.circular(35),
        )
            .gestures(onTap: () => Navigator.pop(context)),
        Text('サインイン') // bottom description
            .fontSize(18)
            .textColor(Color(0xff455178))
            .padding(vertical: 30),
      ],
    )
        .constrained(
      height: 380,
      width: MediaQuery.of(context).size.width,
    )
        .padding(all: 10)
        .backgroundBlur(20)
        .clipRect();
  }
}

//// >>>>>   Japan style example CLASS END  <<<<<//// ```

//// >>>>>   CODE END  <<<<<////


And, i check `flutter doctor` and there is no issue. 

There is no warning in Android Studio with this code. When i click "run" , app uploaded well on my phone without any warning. There is red button on my phone screen ( as Japanese Flag ) . But problem has start when i click this red button. 

Here is " 4: RUN " warning screen  after i click red button where on my screen : 


//// >>>>>   WARNING SCREEN  <<<<<////

`
════════ Exception caught by gesture ═══════════════════════════════════════════════════════════════
The following assertion was thrown while handling a gesture:
No Scaffold widget found.

MyHomePage widgets require a Scaffold widget ancestor.
The specific widget that could not find a Scaffold ancestor was: MyHomePage
  state: _MyHomePageState#b2c07
The ancestors of this widget were: 
  : MaterialApp
    state: _MaterialAppState#39fad
  : MyApp
  ...

Typically, the Scaffold widget is introduced by the MaterialApp or WidgetsApp widget at the top of your application widget tree.

When the exception was thrown, this was the stack: 
#0      debugCheckHasScaffold.<anonymous closure> (package:flutter/src/material/debug.dart:112:7)
#1      debugCheckHasScaffold (package:flutter/src/material/debug.dart:123:4)
#2      showBottomSheet (package:flutter/src/material/bottom_sheet.dart:534:10)
#3      _MyHomePageState.build.<anonymous closure> (package:flatmate/main.dart:73:28)
#4      StyledWidget.gestures.<anonymous closure> (package:styled_widget/src/extensions/widget_extension.dart:949:35)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#f7306
  debugOwner: GestureDetector
  state: possible
  won arena
  finalPosition: Offset(186.7, 573.7)
  finalLocalPosition: Offset(56.7, 53.7)
  button: 1
  sent tap down
════════════════════════════════════════════════════════════════════════════════════════════════════
`

Do you have any idea how i can solve this problem ? I hope you would help me . 
But in any case , its good work. I am almost new here and i hope i can done some good project as like you . 
Thanks for all ! 

[StatelessWidget] and [StatefulWidget] integration

Thinking about the posibility to wrap each styled widget with eighter a stateless or stateful widget.

Styled.widget((Widget child) => child.alignment(Alignment.center))

Something like this possible?

Styled.widget((useState, state) => ...)

Add ignorePointer()

This might be a nice one to add, especially since you already support gesture()

Animations for all properties supporting animations

Widget

  • height
  • width
  • rotate
  • scale
  • transform
  • translate
  • boxShadow
  • borderRadius
  • clipOval (animate [width] and [height] instead)
  • backgroundBlur
  • backgroundSweepGradient
  • backgroundRadialGradient
  • backgroundLinearGradient

Complete [Widget] style methods

  • boxShadow
  • backgroundImage
  • backgroundBlur
  • backgroundBlendMode (?)
  • linearGradient
  • radialGradient
  • sweepGradient
  • overflow
  • scrollable
    ...

Awesome!

Dart Team needs to adopt this one. Just awesome concept!
IS it production ready though?

[Widget], [Text] and [Icon] animations

Text

  • FontSize
  • letterSpacing
  • wordSpacing
  • textShadow
  • textColor

Icon

  • iconSize
  • iconColor

We can now animate all current widgets such as .alignment() like this:

widget
  .alignment(Alignment.center, duration: Duration(milliseconds: 200));

When the alignment changes with a state update, the widget will animate between the two states implicitly.

This works well for all method which adds a new widget to the widget tree. But for methods spesific to [Text] and [Icon] this would`nt work. For example:

Icon(Icons.icon)
  .iconColor(Colors.blue, duration: Duration(milliseconds: 200))
  .iconSize(24, duration: Duration(milliseconds: 400))

You cant animate the color and the size with different duration since its the same widget.
Therefor there needs to be a different solution if we want animations for those widgets aswell. For example:

Icon()
  .animateIcon(duration: Duration(milliseconds: 200))

or if we want to animate all widgets with the same duration there could be a method which would apply to all widgets AFTER the method (if possible)

widget
  .animate(duration: Duration(milliseconds: 200))
  .alignment(Alignment.center) // will animate
  .width(100, duration: Duration(milliseconds: 100)) // override animation duration

or

Styled.animated<Text>(widget: Text('some text'))
  .textColor(Colors.blue)
  // widgets added here will ble implicitly animated

Decoupling styles

Hi,
One issue that seems to be present when we decouple the styles is that the hot reload no longer works when the styles are changed (at least it is my experience with division), is there anything that can be done about this?

Merge down widgets when possible

When for example you style like this:

Text('some text')
  .backgroundColor(Colors.blue)
  .borderRadius(all: 10)

they will output

DecoratedBox(
  decoration: BoxDecoration(borderRadius: BorderRadius.circular(10)),
  child: DecoratedBox(
    decoration: BoxDecoration(color: Colors.blue),
    child: Text('some text'),
  ),
);

The two [DecoratedBox] should be merged into one.
This will be the case for all widgets where the child is of the same type.

  • ConstrainedBox
  • DecoratedBox

Performance comparison

The simplicity and usage of this plugin are very effective and I have looked into both the packages, the division and styled_widget. But I am not sure which has more performance as there are method calling for each and every style. Calling methods for each single style may affect performance as compared to plain dart code. Kindly guide me in the right direction. Which way will be more performant/fast executing, the devision way, styled_widget way or plain dart code as provided by the framework itself for a large scale mobile app. If there would be an option to apply multiple styles in single method call then it would be great.

Stacks support

Is it possible to create Stacks and position them to a specific percentage of their parent width,heigh?

Thanks for your work with styled_widget, it is fantastic!

Add support for "EdgeInsetsDirectional" in the "padding" extension method!

Now, despise of the beauty of this package ❤️ ... however, the current padding() method does not support the directional edge insets like Flutter does!
Flutter has this:

@override
Widget build(BuildContext context) {
  return const Scaffold(
    body: Center(
      child: Padding(
        padding: EdgeInsetsDirectional.only(start: 10, end: 10),
        child: Text('View'),
      ),
    ),
  );
}

Nowadays, most of apps have localization that could require RTL including: Arabic, Persian, etc..

I hope you could soon fix it, or I could make a PR for change suggestion.

Margin not available?

I tried adding .margin(), but the error is

The method 'margin' is not defined for the class 'Widget'.

Are there any ways to use margin in this plugin?

Possible issue: animation and gesture inheritance to all children

styled_widget uses InheritedWidget to pass animations down to children. This means defined animations in one Widget is passed down to all later children of the widget.

styled_widget also uses InheritedWidget for gestures to make the ripple method possible with InkWell. If onTap isnt inherited from GestureDetector the method wont trigger. Therefore all later children with a ripple method will inherit the onTap method. This can maybe be fixed by implementing some logic in the InheritedWidget which only allows two children (GestureDetector and one InkWell) to access the method

Support for TextSpans

First of all: I was already using your division-library and now I'm using this. I like both very much! 👌

I was searching to achieve something like this:

Text.rich(
  TextSpan(
    children: <InlineSpan>[
      TextSpan(text: 'All data will be deleted and '),
      TextSpan(
        text: 'this cannot be undone!',
        style: TextStyle(
          color: Colors.red,
          fontWeight: FontWeight.bold,
        ),
      ),
    ],
  ),
),

but couldn't find anything similar in division or styled_widgets (I was looking for either Txt.rich or just Txt(children:..), for styled_widgets Text(..).rich/children(..)).

Am I missing something or is this a possible future feature? If so, do you already have some ideas about this or do you need some inspiration? :)

Someway to have Gestures w/ Mouse Cursor?

In the latest Flutter they have enabled a classic HandCursor for Desktop and Web with:

MouseRegion(mouseCursor: SystemMouseCursors.click)

Would be nice if this could be wrapped around the .gestures() call if any of the onTap fxns are overriden. Or just expose a variable for it?

Alternatively a .clickable(Function onTapUp, Function onTapDown) could be really cool? Which is just a MR + GT and some syntactic sugar because we never really care about TapUpDetails

Is there any widget like Parent() on division

Hi, first of all I really love your division library. I used Parent() a lot to create "wrap_content" layout on flutter. How can I build widget like Parent() using styled_widget? Thanks.

Is README incomplete?

I was thinking of using this in a new prject, but I realized that the README was incomplete:

  • Core Concepts
    • Widget Tree
    • Implicit Animations
  • More Examples

Is there an ETA for the documentation? Do you suggest I use Division instead?

TextTheme support

It would be nice to have an API where you could apply styles directly from the theme.

Example:

Text("Some text").body1()
Text("Some text").caption()

I achieve this in my own app by creating a StyledTheme widget with a static global key that wraps theme. Then wrap the application in StyledTheme as the child of MaterialApp.

class StyledTheme extends StatefulWidget {
  final Widget child;

  StyledTheme({Key key, this.child}) : super(key: key);

  @override
  _StyledThemeState createState() => _StyledThemeState();

  static ThemeData get theme {
    return Theme.of(_StyledThemeState.styledThemeKey.currentContext);
  }
}

class _StyledThemeState extends State<StyledTheme> {
  static GlobalKey<_StyledThemeState> styledThemeKey = GlobalKey<_StyledThemeState>();

  @override
  Widget build(BuildContext context) {
    return Theme(
      key: styledThemeKey,
      data: theme,
      child: widget.child,
    );
  }
}

I have not been able to find a better way to acheive this.

Improved debugging

  • [AnimatedBorderRadius] debug [topLeft], [topRight], [bottomLeft], [bottomRight]
  • [AnimatedTransform] degub [origin], [transformHitTest] ?
  • [AnimatedDecorationBox] debug [position] ?
    ...

Why border radius doesn't work?

Hello. I'm new to Flutter and trying to add border radius to a Container. Padding works as expected but border-radius doesn't. Can you explain why? How can I apply border radius to a Container?

Styled.widget(
            child: Container(
              child: Text(this.message.message).fontSize(18).textColor(this._getTextColor()),
            ))
            .padding(all: 10.0)
            .backgroundColor(this._getBackgroundColor())
            .borderRadius(all: 8.0)

adding .toWrap()

I would love to use Wrap for spacing. It would be great if there is .toWrap().

Animation for all widgets

The following methods need support for animation

  • aspectRatio
  • center
  • fittedBox
  • fractionallySizedBox
  • Card

Add support for stacked BoxShadows

Some drop-shadows designs require multiple shadows layered on top of eachother.

Currently each boxShadow will replace the one before it, would be nice if these stacked instead.

Add support for IgnorePointer

Since we're already supporting gestures, it would be nice to be able to say ignorePointer(), or even:
gestures(ignore: someCondition, onTapUp: someHandler) .

Create style object which could be shared betwen Widgets

Hello. I'm new to Flutter with Angular background. I can compare these techs and I see a big pain with Flutter:

  • it's hard to style widgets (vs css)
  • styling is mixed with business logic (vs angular templates)

These problems lead to another one - it's hard to create plugins with customizable UI.
In a best-case, I would like to have Angular in Flutter where logic / structure / styles are split. But it's too hard. Just to make the picture a little bit better I would suggest the following:

  • create Style data class which will contain styles data (padding / colors / etc)
  • add api to apply Style object to Widget. E.g. Styled.widget(child: myRow).style(myStyle)
  • if Style object is null or empty Styled.widget(child: myRow).style(myStyle) just returns myRow

Style class may have builder style api.

With Style object plugin consumers may provide custom styles for Widgets, Styles may be shared and etc....

Wiki Demo App Missing Argument

Scale method has named parameter and hasn't declared on what type of argument does pressed ? 0.95 : 1.0 would be.

Line 231
.scale(pressed ? 0.95 : 1.0, animate: true)

Make extension params nullable

Please, make extension params nullable, where underlying class params are nullable.
For example, now (in version 0.3.1) you cant write:

Text(message).textColor(isError ? Colors.red : null)

to change text color (from default) only for some condition.
All params of TextStyle class are nullable.

List conversion not working

Thanks for this awesome package.
I cant seem to use toColumn() or toRow() conversion methods in my list.
It always gives an error since i cant find toColumn() and toRow() extension methods in my list.

Thanks in advance for the assist.

TextStyle extensions?

We recently added some extensions directly to TextStyle, and they are really handy:

extension TextStyleHelpers on TextStyle {
  TextStyle get bold => copyWith(fontWeight: FontWeight.bold);
  TextStyle get italic => copyWith(fontStyle: FontStyle.italic);
  TextStyle letterSpace(double value) => copyWith(letterSpacing: value);
}

Now, instead of
TextStyles.body.copyWith(fontWeight: FontWeight.bold, fontStyle: FontStyle.italic, letterSpacing: 1.6)
Can use:
TextStyles.body.bold.italic.letterSpacing(1.6)

I know these are technically not widgests, but I can't think of a better place to house these than this repo :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.