plex 0.3.3 plex: ^0.3.3 copied to clipboard
PLEX is Flutter UI framework for enterprise apps with pre-built components and best practices for efficient development in addition with many built in widgets
PLEX #
`PLEX` is a UI framework for Flutter designed specifically for building enterprise applications. It provides a robust and customizable foundation for the entire application, including boilerplate code for main.dart file, routes, screens, and other essential components.
In addition to the basic application structure, PLEX
comes with pre-built components for common UI elements such as tableviews and forms. The tableviews can be easily customized to display data in various formats like lists and grids, while the forms can collect data from users using different
input
types like text fields, dropdowns, and checkboxes.
PLEX
also offers guidelines and best practices for building enterprise applications, including data management, architecture, testing, and more. These guidelines can help developers to build scalable, maintainable, and high-performance applications.
The PLEX
framework is an ideal choice for developers who want to build enterprise-level applications quickly and efficiently, without compromising on quality or customization. Its pre-built components and best practices can save developers a significant amount of time and effort, while also
ensuring
the resulting application meets the high standards of enterprise-level software.
Note:
PLEX
also provide a single click to move from Material 2
to Material 3
and Light Mode
to Dark Mode
.
Screenshots #
Material 3 #
Material 2 #
Application Screen Shots #
Features #
- Create boilerplate code for an Application
- Built in login screen
- Built in User session manager
- Free useful widgets
- Free useful utilities
- Built in screens and pages
- Builtin form builder from model class
Getting started #
Install the plex
in your application.
Usage #
Widgets #
PlexWidget
- Updatable widget and controlled by a controller. Replaces the use of BLoC or provider pattern
PlexDataTable
- View Data in a tabular form. Sort By Any Column, Search By Any Column, Export as Excel builtin functions
PlexInputWidget
- Simple Widget to create a
TextInputField
,DropdownField
,DatePickerField
andMultiSelectionFiel
- There are lots of features available for each field
- Simple Widget to create a
PlexFormWidget
- Extend any model class with
PlexForm
andoverride
methodgetFields()
and configure UI fields. All the form layout will be created automatically.
- Extend any model class with
PlexLoader
- Show loading anywhere in application by displaying widget
PlexLoader
- Show loading anywhere in application by displaying widget
PlexShimmer
- Show shimmer widget when data is loading by displaying widget
PlexShimmer
- Show shimmer widget when data is loading by displaying widget
PlexInputWidget
Usage
/// Input Types
/// PlexInputWidget.typeInput
/// PlexInputWidget.typeDropdown
/// PlexInputWidget.typeDate
/// PlexInputWidget.typeButton
PlexInputWidget(
title: "Username / Email",
type: PlexInputWidget.typeInput,
inputHint: "Enter Your Email or Username",
inputController: usernameController,
inputOnChange: (value) {},
inputOnSubmit: (value) {},
inputAction: TextInputAction.go,
inputKeyboardType: TextInputType.name,
isPassword: false,
dropdownItemOnSelect: (item) {},
dropdownItemAsString: (item) => item.toString(),
dropdownItems: const ["Data"],
dropdownAsyncItems: Future(() => ["Data"]),
dropdownSelectionController: PlexWidgetController(),
dropDownLeadingIcon: (item) => const Icon(Icons.add),
dropdownItemWidget: (item) => const Text("Data"),
dropdownOnSearch: (query, item) { return true; },
dropdownCustomOnTap: () {},
buttonClick: ,
buttonIcon: ,
buttonColor: ,
useMargin: ,
margin: ,
fieldColor: ,
editable: ,
helperText: ,
)
Persistent Storage
//Only initialize if you are not using PlexApp
//and using PlexDb separately
PlexDb.initialize();
PlexDb.instance.setString("Key", "Value");
PlexDb.instance.getString("Key");
PlexDb.instance.setBool("Key", true);
PlexDb.instance.getBool("Key");
Messaging #
BuildContext context;
context.showSnackBar("Your Message...");
Utils #
Dimension Utilities
Dim.mini //Dimension of 2
Dim.smallest //Dimension of 4
Dim.small //Dimension of 8
Dim.medium //Dimension of 16
Dim.large //Dimension of 32
Spacing Utilities
spaceMini() //Widget with height width 2
spaceSmallest() //Widget with height width 4
spaceSmall() //Widget with height width 8
spaceMedium() //Widget with height width 16
space(Any Double) //Widget with custom height anf width
Console Utilities
console("Your Message In Console", '(optional) enable print in release build')
Widget Utilities
createWidget((){
//Any Calculation or Custom Logic Here...
return Container();
})
Async Utilities
//This will delay your code for 500 millis then do the work
//Usefully when you want to execute a task after navigation or when UI is still building
delay(() {
//Your Logic Here
return 'Any Object';
})
runAsync(() {
//Your Logic Here will be Asynchronously run
return "Any Object"
})
List Utilities
//List.sort() doesn't return anything so we need a extra line to sort the list og type T
//You can use this method to sort and use in one single line
List<T> result = List<T>.sortAndReturn();
//Will return a Map<Key, List<T>> by grouping the list on some condition
Map<String, List<User>> usersByCities = List<User>.groupBy((user) {
return user.city;
});
String Utils
/// "2012-02-27"
/// "2012-02-27 13:27:00"
/// "2012-02-27 13:27:00.123456789z"
/// "2012-02-27 13:27:00,123456789z"
/// "20120227 13:27:00"
/// "20120227T132700"
/// "20120227"
/// "+20120227"
/// "2012-02-27T14Z"
/// "2012-02-27T14+00:00"
/// "-123450101 00:00:00 Z": in the year -12345.
/// "2002-02-27T14:00:00-0500"
/// "2002-02-27T19:00:00Z"
DateTime time = "2012-02-27 13:27:00".toDate();
DateTime Utilities
var dateInString = DateTime.now().toDDMMMHHmmss();
var dateInString = DateTime.now().toMMMDDYYYY();
//Convert DateTime to String in custom format
var dateInString = DateTime.now().toFormattedString("hh:mm:ss a");
// Will return the time difference in hours or minutes or in seconds
var timeDifference = "20120227 13:27:00".toDate().getDifferenceString();
Complete Example of Using PlexApp #
- You can also see example project to see the whole project usage in action.
import 'package:flutter/material.dart';
import 'package:plex/plex_networking/plex_networking.dart';
import 'package:plex/plex_package.dart';
import 'package:plex/plex_route.dart';
import 'package:plex/plex_screens/plex_dashboard_screen.dart';
import 'package:plex/plex_screens/plex_login_screen.dart';
import 'package:plex/plex_user.dart';
import 'package:plex/plex_widgets/plex_data_table.dart';
import 'package:plex_app/screens/home_screen.dart';
import 'package:plex_app/screens/second_screen.dart';
class Routes {
static const dashboardScreen = "/dashboard";
static const secondScreen = "/second";
}
class AppUser extends PlexUser {
late String email;
late String userName;
List<String>? rules;
AppUser.init({required this.email, required this.userName, this.rules});
@override
String? getPictureUrl() {
return "https://images.pexels.com/photos/631317/pexels-photo-631317.jpeg";
}
@override
String getLoggedInEmail() => email;
@override
List<String>? getLoggedInRules() => rules;
@override
String getLoggedInUsername() => userName;
@override
String getLoggedInFullName() => userName;
@override
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['userName'] = userName;
map['email'] = email;
map['rules'] = rules;
return map;
}
AppUser.fromJson(Map<String, dynamic> map) {
userName = map["userName"];
email = map["email"];
rules = map["rules"];
}
}
void main() async {
getTableData() => [
[
PlexDataCell.text("1"),
PlexDataCell.text("First"),
PlexDataCell.text("Person"),
PlexDataCell.text("EMP953312RT"),
PlexDataCell.text("Software Engineer"),
PlexDataCell.text("Grade"),
PlexDataCell.custom(
"First Company Pvt. Ltd",
const DataCell(
Text("First Company Pvt. Ltd", style: TextStyle(color: Colors.brown)),
),
),
],
[
PlexDataCell.text("2"),
PlexDataCell.text("Second"),
PlexDataCell.text("Person"),
PlexDataCell.text("EMP95313RT"),
PlexDataCell.text("Software Engineer"),
PlexDataCell.text("Scale"),
PlexDataCell.custom(
"Second Company Pvt. Ltd",
const DataCell(
Text("Second Company Pvt. Ltd", style: TextStyle(color: Colors.green)),
),
)
],
];
runApp(PlexApp(
themeFromColor: const Color(0xFF26A9E1),
// themeFromImage: const AssetImage("/path/to/image"),
appInfo: PlexAppInfo(
title: "Auto Backup",
appLogo: const Icon(Icons.account_balance),
appLogoDark: const Icon(Icons.account_balance, color: Colors.white),
initialRoute: Routes.dashboardScreen,
versionCode: 1,
versionName: "v1.0.0",
),
useAuthorization: true,
onInitializationComplete: () {
PlexNetworking.instance.allowBadCertificateForHTTPS();
},
loginConfig: PlexLoginConfig(
debugUsername: 'test',
debugPassword: 'password',
additionalWidgetsTop: (context) => const Text("Login Screen"),
additionalWidgetsBottom: (context) => const Text("Login Screen End"),
onLogin: (context, email, password) async {
return AppUser.init(userName: "Abdur Rahman", email: "ar@mail.com");
},
userFromJson: (userData) {
return AppUser.fromJson(userData);
},
),
dashboardConfig: PlexDashboardConfig(
disableExpandNavigationRail: false,
disableNavigationRail: false,
disableBottomNavigation: false,
showThemeSwitch: true,
showBrightnessSwitch: true,
showMaterialSwitch: true,
appbarActions: [
MenuItemButton(
leadingIcon: const Icon(Icons.abc_outlined),
child: const Text("ABC"),
onPressed: () {},
),
MenuItemButton(
leadingIcon: const Icon(Icons.account_tree_outlined),
child: const Text("Tree"),
onPressed: () {},
),
MenuItemButton(
leadingIcon: const Icon(Icons.account_balance_outlined),
child: const Text("Balance"),
onPressed: () {},
),
],
dashboardScreens: [
PlexRoute(
route: Routes.dashboardScreen,
category: "Tables",
title: "Data Table Widget Usage",
shortTitle: 'Data Table',
logo: const Icon(Icons.account_balance_outlined),
screen: (context) => PlexDataTable(
enableSearch: true,
enablePrint: true,
onRefresh: () {
getTableData();
},
headerTextStyle: const TextStyle(fontWeight: FontWeight.bold),
headerBackground: Colors.redAccent,
border: TableBorder.all(color: Colors.black12),
columns: [
PlexDataCell.text("Id"),
PlexDataCell.text("First Name"),
PlexDataCell.text("Last Name"),
PlexDataCell.text("Emp Code"),
PlexDataCell.text("Designation"),
PlexDataCell.text("Grade"),
PlexDataCell.text("Company"),
],
rows: List.empty(), //getTableData(),
),
),
PlexRoute(
route: "/paginated-table",
category: "Paginated Tables",
title: "Paginated Data Table",
shortTitle: 'Paginated Table',
logo: const Icon(Icons.account_balance_outlined),
screen: (context) => PlexDataTableWithPages(
columns: [
PlexDataCell.text("Id"),
PlexDataCell.text("First Name"),
PlexDataCell.text("Last Name"),
PlexDataCell.text("Emp Code"),
PlexDataCell.text("Designation"),
PlexDataCell.text("Grade"),
PlexDataCell.text("Company"),
],
rows: getTableData(),
),
),
PlexRoute(
route: "/update-widget",
title: "Updatable Widget Usage",
shortTitle: 'Updatable Widget',
logo: const Icon(Icons.browser_updated),
screen: (context) => const UpdatableScreen(),
),
PlexRoute(
route: "/form-usage",
title: "Form Widget Usage",
shortTitle: 'Form Widget',
logo: const Icon(Icons.format_align_center),
screen: (context) => const FormUsageScreen(),
),
],
),
));
}