pub package

A package that contain many custom Widget and utility that help decrease your development time on creating custom Widget.

Important note

  • If you're just starting using this package, We would recommend you to use sura_flutter instead, but if you're using this package, you can still use it and there'll be no breaking change.
  • sura_flutter is a successor of jin_widget_helper. we make an improvement from this package and other flutter latest feature and support.


Add this to pubspec.yaml

  jin_widget_helper: ^2.0.2


ActionButtonA Simple RaisedButton with loading notifier
BadgeButtonA small icon button with badge (like notification badge)
CupertinoOptionActionSheetA Cupertino bottom sheet with option
ConditionalWidgetProvide a widget base on condition true or false
ConnectionCheckerA widget to check internet connection and provide onNoInternet callback
CustomBackButtonA custom back button with title (header)
FutureHandlerA FutureBuilder with less boilerplate code
JinAccordianA customizable ExpansionTile
JinExpandableA widget that can be toggle with top and bottom widget
JinConfirmationDialogA dialog with cancel and confirm action
JinLoadingButtonA Loading button without using ValueNotifier
JinLoadingDialogA Class for showing dialog
JinPlatformCheckerProvide a widget base on Android or iOS platform
JinSimpleDialogA simple alert dialog
MiniListTileAn easy customizable ListTile
PaginatedListViewA Listview.separated with pagination support
PaginatedGridViewA Gridview.builder with pagination support
SmallIconButtonA small alternative to Flutter's IconButton
SmallFlatButtonA small alternative to Flutter's FlatButton
SpaceXSizedBox with only width
SpaceYSizedBox with only height
StreamHandlerA Streambuilder with less boilerplate code
ValueObserverA ValueListenableBuilder with lest boilerplate code



class _HomePageState extends State<NewPage> with AfterBuildMixin {

  //this method will call after widget has been build
  void afterBuild(BuildContext context) {


  Widget build(BuildContext context) {
    return Container();


field and attribute

  • formKey: a key for form
  • loadingNotifier: a bool ValueNotifier
  • passwordObsecureNotifier: a bool ValueNotitifer for toggling password obsecure field
  • isFormValidated: a bool return by validate formKey


  • toggleLoading: toggle loadingNotifier
  • togglePasswordObsecure: toggle passwordObsecureNotifier
class _HomePageState extends State<NewPage> with FormMixin {
  Widget build(BuildContext context) {
    return Container();

Widget's Extension

padding, margin

Text("Hello Flutter").padding(EdgeInsets.all(16.0)) // defaulat value is EdgeInsets.all(8.0)
Text("Hello Flutter").margin(EdgeInsets.all(16.0)) // defaulat value is EdgeInsets.all(8.0)
///As a value
Text("Hello Flutter").marginValue(all: 12)
Text("Hello Flutter").paddingValue(horizontal: 12, vertical: 8)


Text("Hello Flutter").cssSpacing(margin: [10,10], padding:[16])
//css margin and padding rule

rotate (in degree)

Text("Hello Flutter").rotate(45)

flexible, expanded, clipOval, opacity

Text("Hello Flutter").flexible
Text("Hello Flutter").expanded
Text("Hello Flutter").clipOval
Text("Hello Flutter").opacity(0.5)

TextStyle Extention

Text("Hello Flutter", style: TextStyle().normal)
Text("Hello Flutter", style: TextStyle().medium)
Text("Hello Flutter", style: TextStyle().bold)
Text("Hello Flutter", style: TextStyle().applyColor(Colors.white))
Text("Hello Flutter", style: TextStyle().applFontSize(24))

Other Extension

BuildContext extension

  Size screenSize = context.screenSize;
  Color primaryColor = context.primaryColor;
  Color accentColor = context.accentColor;
  TextTheme textTheme = context.textTheme;

DateTime extension

DateTime.now().format("dd mmm yyyy")
DateTime.now().formatToLocalDate("dd mmm yyyy")

String extension

String name = "chunlee".capitalize() // => Chunlee

Utility Class


      indicator: DotTabIndicator(
        color: Colors.blue,
        dotAlignment: DotAlignment.Bottom,


Color green = ColorUtils.getColorFromCode("42f545")
Color newColor = ColorUtils.fromRGB(8, 182, 155)
MaterilColor newMaterialColor = ColorUtils.hexColorToMaterialColor(0xFF869CF4)


Future<Uint8List> imageByte = await JinUtils.getBytesFromAsset("image asset path", 200); //200 is imagewidth
String carUrlImage =  JinUtils.randomCategoryStringImage(dimension: 200, category: "car"); //get image url with given dimension and category
String randomUrlImage = JinUtils.randomStringImage(200); //get random image url with given dimension


validator: (value) => JinFormValidator.validateEmail(value),
// check JinValidator class for more field validator

PageNavigator support push, pushReplacement and pushAndRemove method

PageNavigator.push(context, DetailPage());
PageNavigator.pushReplacement(context, HomePage());
PageNavigator.pushAndRemove(context, RootPage());

JinNavigator also support push, pushReplacement, pushAndRemove without providing a context but you need to add JinNavigator.navigatorKey to MaterialApp

    navigatorKey: JinNavigator.navigatorKey,
    home: MyHomePage(),

JinNavigator also can show dialog without providing a context

var result = await JinNavigator.dialog(MyDialog());


RoundedRectangleBorder roundRectangle = JinWidget.roundRect(12);
BorderRadius radius = JinWidget.radius(12); //default value is 8