diff --git a/docs/.vuepress/vaahflutter.js b/docs/.vuepress/vaahflutter.js index 30451845..eb14d79b 100644 --- a/docs/.vuepress/vaahflutter.js +++ b/docs/.vuepress/vaahflutter.js @@ -87,6 +87,7 @@ sidebar = [ text: 'helpers', collapsible: true, children: [ + { text: 'alerts', link: '/vaahflutter/directory_structure/vaahextendflutter/helpers/alerts.md' }, { text: 'console', link: '/vaahflutter/directory_structure/vaahextendflutter/helpers/console.md' }, { text: 'constants', link: '/vaahflutter/directory_structure/vaahextendflutter/helpers/constants.md' }, { text: 'datetime', link: '/vaahflutter/directory_structure/vaahextendflutter/helpers/datetime.md' }, diff --git a/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/alerts.md b/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/alerts.md new file mode 100644 index 00000000..4e293fa8 --- /dev/null +++ b/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/alerts.md @@ -0,0 +1,225 @@ +# Alerts + +::: warning Dependencies + +- [fluttertoast](https://pub.dev/packages/fluttertoast) + +- depends on [app_theme](../apptheme.md) also. + +- [API](../services/api.md) lib depends on Alerts. + +::: + +[[toc]] + +Basically we have two types of alerts: 1. Toast and 2. Dialog + +Here Type of alert functions are nullable so you might want to check if they are null or not before using them. We made them nullable because developer can remove them in specific project so API will check if the dialogue or toast exist, if they don't it won't show anything. One usecase here is: developer wants to show error toasts only and not succuss toasts when using API, so dev will set this success toast to null. Now on success it will check if success toast is null or not if not null then only it shows it. + +## Toast + +For toast, we have 3 kind of toasts: `success`, `error`, and `info`. + +### Info toast + +```dart +Alerts.showInfoToast!(content: 'Your Content'); +``` + +### Success toast + +```dart +Alerts.showSuccessToast!(content: 'Your Content'); +``` + +### Error toast + +```dart +Alerts.showErrorToast!(content: 'Your Content'); +``` + +## Dialog + +For dialog also, we have 2 kind of dialogs: `success`, and `error`. + +### Success Dialog + +```dart +Alerts.showSuccessDialog!( + title: 'Title', + messages: ['Content'], + hint: 'Hint', + actions: [], +); +``` + +### Error Dialog + +```dart +Alerts.showErrorDialog!( + title: 'Title', + messages: ['Content'], + hint: 'Hint', + actions: [], +); +``` + +## Source Code + +```dart +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:get/get.dart'; + +import '../app_theme.dart'; +import 'constants.dart'; + +class Alerts { + static Future _toast({required String content}) async { + await Fluttertoast.showToast( + msg: content, + toastLength: Toast.LENGTH_SHORT, + gravity: ToastGravity.BOTTOM, + backgroundColor: AppTheme.colors['white'], + textColor: AppTheme.colors['black'], + fontSize: 16.0, + ); + } + + static _dialog({ + required String title, + List? messages, + String? hint, + Color? hintColor, + List? actions, + Color color = Colors.white, + }) { + return Get.dialog( + AlertDialog( + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(defaultPadding), + ), + ), + contentPadding: allPadding8, + title: Center(child: Text(title)), + content: SingleChildScrollView( + physics: const BouncingScrollPhysics(), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + if (messages != null && messages.isNotEmpty) ...[ + verticalMargin12, + Padding( + padding: horizontalPadding8, + child: Text( + messages.join('\n'), + textAlign: TextAlign.center, + ), + ), + ], + if ((messages != null && messages.isNotEmpty) || + (hint != null && hint.trim().isNotEmpty)) + verticalMargin8, + if (hint != null && hint.trim().isNotEmpty) ...[ + Padding( + padding: horizontalPadding8, + child: Text( + hint, + textAlign: TextAlign.center, + style: TextStyle(color: hintColor), + ), + ), + verticalMargin8, + ], + ], + ), + ), + actions: [ + if (actions == null || actions.isNotEmpty) + Center( + child: ElevatedButton( + style: ElevatedButton.styleFrom(backgroundColor: color), + child: Text( + 'Ok', + style: TextStyle( + color: color == AppTheme.colors['white'] + ? AppTheme.colors['black'] + : AppTheme.colors['white'], + ), + ), + onPressed: () { + Get.back(); + }, + ), + ) + else + ...actions, + ], + ), + barrierDismissible: false, + ); + } + + static Future Function({ + required String content, + })? showInfoToast = ({required String content}) async { + await _toast(content: content); + }; + + static Future Function({ + required String content, + })? showErrorToast = ({required String content}) async { + await _toast(content: 'Error: $content'); + }; + + static Future Function({ + required String content, + })? showSuccessToast = ({required String content}) async { + await _toast(content: content); + }; + + static Future Function({ + required String title, + List? messages, + String? hint, + List? actions, + })? showErrorDialog = ({ + required String title, + List? messages, + String? hint, + List? actions, + }) async { + await _dialog( + title: title, + messages: messages, + hint: hint, + hintColor: AppTheme.colors['danger'], + actions: actions, + color: AppTheme.colors['danger']!, + ); + }; + + static Future Function({ + required String title, + List? messages, + String? hint, + List? actions, + })? showSuccessDialog = ({ + required String title, + List? messages, + String? hint, + List? actions, + }) async { + await _dialog( + title: title, + messages: messages, + hint: hint, + hintColor: AppTheme.colors['success'], + actions: actions, + color: AppTheme.colors['success']!, + ); + }; +} +``` \ No newline at end of file diff --git a/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/datetime.md b/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/datetime.md index e69de29b..8fe92487 100644 --- a/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/datetime.md +++ b/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/datetime.md @@ -0,0 +1,544 @@ +# DateTime Helpers + +::: warning Dependencies +`dart:math` and [`package:intl/intl.dart`](https://pub.dev/packages/intl) +::: + +[[toc]] + +This file contains all the common Date and Time helpers which can be used in the app. + +## Extension On TimeOfDay + +Get TimeOfDay in HH:MM AM/PM format. DateTime extension contains toHMaa getter on the extension so it translates DateTime to HH:MM AM/PM. + +```dart +final TimeOfDay time = TimeOfDay.now(); +print(time.toHMaa); +``` + +```dart +String formatExt({String format = 'hh:mm a'}) => + DateFormat(format).format(DateTime(0, 0, 0, hour, minute)); +``` + +## Extension On DateTime + +### Timezone Related + +::: tip Note: +In database developer should save DateTime in UTC if possible. And Developer will have to be carefull when working with Timezone. +::: + +We have offset with respect to UTC time so we can change timezone with respect to UTC only. We will walk you through few use cases and how they should be handled. + +Example of valid Timezones: `Asia/Kolkata`, `ASIA/KOLKATA`, `asia/kolkata`, Also check list of available timezones [here](https://gist.github.com/we-prajapati-c001/e67c763b0fb1f81c914092eedcfe0bbe) + +#### Usecase: We receive UTC time from database and we want to change it for specific timezone. + +```dart +DateTime? date = DateTimeHelper.toTimezone('Asia/Kolkata', dateString); +``` + +#### Usecase: We have DateTime for specific timezone and we want to change it to UTC. + +let's assume we have two properties in our model, one `datekey` and other `timezonekey`. And for some reason when we use date we don't want to use it as UTC. + +```dart +DateTime? date = DateTimeHelper.fromTimezone(timezonekey, datekey); +``` + +#### Usecase: We have to change DateTime from one timezone (known priorly) to another timezone. + +Let's say I have my DateTime according to `ABC` timezone and I want to change it to `LMN` timezone then First I'll have to convert `ABC` to `UTC` and then we can convert that `UTC` to `LMN`. But why do we have to go back to UTC when we want to change from one timezone to another timezone? Because we have time offsets respected to UTC. + +let's assume we have two properties in our model, one `datekey` and other `timezonekey`. And `newtimezone` holds new timezone value. + +```dart +DateTime? date = DateTimeHelper.fromTimezone(timezonekey, datekey)?.toTimezone(newtimezone); +``` + +#### Usecase: We have to change DateTime from one timezone (not known priorly) to another timezone. + +for reference in below explaination: +| **Region** | **DateTime** | +| --- | --- | +| EST | 2023-01-01 00:00:00 am | +| IST | 2023-01-01 10:30:00 am | + +Now why can't we convert DateTime from one timezone (not known priorly) to another timezone. e.g. let's try to convert EST (unknown) DateTime to IST DateTime. Date property from database looks something like: `2023-01-01 00:00:00` now we parse it in flutter, flutter gives us DateTime object as local. If I live in India it will give me DateTime object with same properties of `2023-01-01 00:00:00` and not with properties of `2023-01-01 10:30:00`. Which is not correct. You can try everything/ available extension methods but you won't get correct results to show if you don't know the timezone. + +::: danger Note +When we change timezone the DateTime, it will be converted to UTC. In Flutter we don't have `setter` for `timeZoneName` property on DateTime, so we don't know from which timzeone DateTime has and if we don't know that we can't convert that time to UTC automatically in our extension, because for every timezone offsets are different, And as we have said We can change timezone with respect to UTC. That's why if you want to remeber timezone, you have to maintain a separate property. +::: + +#### DateTimeHelper + +##### fromTimezone method: This method from DateTimeHelper class returns UTC datetime. `timezone` and `datetime` parameters are mendatory to pass, you can pass daylight true if the `datetime` is calculated depending on daylight, you can pass custom `pattern` if you're saving datetime in custom format. + +```dart +static DateTime? fromTimezone( + String timezone, + String datetime, { + String pattern = 'yyyy-MM-dd hh:mm:ss', + bool daylight = false, +}) { + // Will return UTC DateTime + return DateFormat(pattern).parse(datetime, true).fromTimezone(timezone, daylight: daylight); +} + +// Call +DateTime? datetime = DateTimeHelper.fromTimezone( + 'utc', + '2023-01-01', + pattern: 'yyyy-MM-dd', +); +``` + +##### toTimezone method: this method will give desired timezone datetime from UTC. You can pass daylight true if you want the results depending on daylight, you can pass custom `pattern` if you're saving datetime in custom format. + +```dart +static DateTime? toTimezone( + String timezone, + String datetime, { + String pattern = 'yyyy-MM-dd hh:mm:ss', + bool daylight = false, +}) { + return DateFormat(pattern).parse(datetime, true).toTimezone(timezone, daylight: daylight); +} + +DateTime? datetime = DateTimeHelper.toTimezone( + 'Asia/Kolkata', + '2023-01-01 10:30:00.000Z', + pattern: 'yyyy-MM-dd hh:mm:ss.000Z', +); +``` + +### Other DateTime Extensions + +##### Get DateTime with zero milliseconds and microsecond + +```dart +final DateTime date = DateTime.now(); +print(date.resetMillisecond); +``` + +##### Get DateTime for n days before provided DateTime + +```dart +final DateTime date = DateTime.now(); +print(date.daysBefore(2)); +``` + +##### Get DateTime for n days after provided DateTime + +```dart +final DateTime date = DateTime.now(); +print(date.daysAfter(2)); +``` + +##### Get DateTime for the next day start + +```dart +final DateTime date = DateTime.now(); +print(date.nextDayStart); +``` + +returns `xxxx-xx-xx 00:00:00.000` + +##### Get Date only (time is set to zero) (if DateTime type is UTC then return UTC otherwise return local) + +```dart +final DateTime date = DateTime.now(); +print(date.onlyDate); +``` + +returns year, month, date + +##### Get Month only (time is set to zero and date is set to first) (if DateTime type is UTC then return UTC otherwise return local) + +```dart +final DateTime date = DateTime.now(); +print(date.onlyMonth); +``` + +returns `xxxx-xx-01 00:00:00.000` + +##### Get Time only + +```dart +final DateTime date = DateTime.now(); +print(date.onlytime(01, 15)); +``` + +can pass optional arguments hours and minutes, the first argument will be hour always. +returns (epoch date + time) `1970-01-01 xx:xx:00.000z` + +##### Get UTC Time First Day Since Epoch + +```dart +final DateTime date = DateTime.now(); +print(date.utcTimeFirstDaySinceEpoch); +``` + +returns (epoch date + time with milli and micro secs) `1970-01-01 xx:xx:xx.xxxz` + +##### Get UTC DateTime + +```dart +final DateTime date = DateTime.now(); +print(date.asUtc); +``` + +##### Get Local DateTime + +```dart +final DateTime date = DateTime.now(); +print(date.asLocal); +``` + +##### Get Client DateTime + +```dart +final DateTime date = DateTime.now(); +print(date.asClient); +``` + +##### Get MMM DD HH:MM AM/PM formatted string + +```dart +final DateTime date = DateTime.now(); +print(date.toDateTimeString); +``` + +##### Get EEEE Month DD HH:MM AM/PM formatted string + +```dart +final DateTime date = DateTime.now(); +print(date.toFullDateTimeString); +``` + +##### Get EEE Month DD formated string + +```dart +final DateTime date = DateTime.now(); +print(date.toFullDateString); +``` + +##### Get HH:MM AM/PM formatted string + +```dart +final DateTime date = DateTime.now(); +print(date.toHMaa); +``` + +##### Get HH:MM:SS AM/PM formatted string + +```dart +final DateTime date = DateTime.now(); +print(date.toHHMMSS); +``` + +##### Get Month(short) Date formated string + +```dart +final DateTime date = DateTime.now(); +print(date.toMMMMdd); +``` + +##### Get Year-Month(short)-Date formated string + +```dart +final DateTime date = DateTime.now(); +print(date.toYyyymmmdd); +``` + +##### Get Date of Birth (YYYY-MM-DD) formatted string + +```dart +final DateTime date = DateTime.now(); +print(date.toDateOfBirth); +``` + +##### Get Custom formatted string + +by default format will be : 'yyyy MMM dd, h:mm a' + +`mm` will be used for Minutes and `MM`, `MMM`, `MMMM` will be used for Month. + +```dart +DateTime date = DateTime.now(); +Console.danger(date.format(format: 'yyyy-MM-dd')); +``` + + +## Extension On String + +##### From String to DateTime + +```dart +final DateTime date = '2023-01-01 00:00:00'.toDateTime(); +``` + +you can pass a valid pattern in toDateTime function to convert the string from that format, default pattern is 'yyyy-mm-dd hh:mm:ss' + +##### Add zeros as a prefix to equalize the length + +```dart +const String number = '100'; +print(number.zeroPrefix(6)); +``` + +##### Parse string to int and double + +```dart +const String number = '100'; +final int? numInt = number.parseInt; +final double? numDouble = number.parseDouble; +``` + +## Extension on Duration + +##### Get formatted String + +```dart +const Duration dur = Duration(days:3, hours: 20, minutes: 10); +print(dur.format); +``` + +will give output HH:MM:SS + +##### Get HH:MM:SS formatted String + +```dart +const Duration dur = Duration(days:3, hours: 20, minutes: 10); +print(dur.toHms); +``` + +will give output HH:MM:SS (Two Digit Hours, Two Digit Minutes, Two Digit Seconds) + +##### Get MM:SS formatted String + +```dart +const Duration dur = Duration(days:3, hours: 20, minutes: 10); +print(dur.toMs); +``` + +will give output MM:SS (Two Digit Minutes, Two Digit Seconds) + +## Extension on int + +##### Get Local and UTC time from Milliseconds Since Epoch + +```dart +final int millisecondsSinceEpoch = DateTime.now().millisecondsSinceEpoch; +print(millisecondsSinceEpoch.localDateTime); +print(millisecondsSinceEpoch.utcDateTime); +``` + +##### Get DateTime from Milliseconds Since Epoch + +```dart +final int millisecondsSinceEpoch = DateTime.now().millisecondsSinceEpoch; +final DateTime date = millisecondsSinceEpoch.asDateTime(from: TimeZone.local); +``` + +The argument is optional. + +##### Get DateTime from Milliseconds Since Epoch + +```dart +final int millisecondsSinceEpoch = DateTime.now().millisecondsSinceEpoch; +final DateTime date = millisecondsSinceEpoch.asDateTime(from: TimeZone.local); +``` + +The `from` argument is optional. + +## Source code for datetime.dart + +```dart +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +enum TimeZone { utc, local } + +extension TimeOfDayExtension on TimeOfDay { + // HH:MM AM + String get toHMaa => DateFormat('hh:mm aaaa').format(DateTime(0, 0, 0, hour, minute)); +} + +// Extension for DateTime +extension DateTimeExtension on DateTime { + String toTime(BuildContext context) => TimeOfDay.fromDateTime(asLocal).format(context); + + // Return DateTime with zero millisecond and microsecond + DateTime get resetMillisecond => DateTime(year, month, day, hour, minute, second); + + DateTime daysBefore(int days) => subtract(Duration(days: days)); + + DateTime daysAfter(int days) => add(Duration(days: days)); + + DateTime get nextDayStart => onlyDate.daysAfter(1); + + DateTime get localTimeToday { + DateTime now = DateTime.now(); + return DateTime( + now.year, + now.month, + now.day, + hour, + minute, + second, + millisecond, + microsecond, + ); + } + + DateTime get onlyDate => isUtc ? DateTime.utc(year, month, day) : DateTime(year, month, day); + + DateTime get onlyMonth => isUtc ? DateTime.utc(year, month) : DateTime(year, month); + + DateTime onlyTime([int? hourArg, int? minuteArg]) => + DateTime.utc(1970, 1, 1, hourArg ?? hour, minuteArg ?? minute, 0, 0, 0); + + DateTime get utcTimeFirstDaySinceEpoch => + DateTime.utc(1970, 1, 1, hour, minute, second, millisecond, microsecond); + + // Convert local time as current utc + // DateTime.now() = 2021-01-25 18:49:03.049422 + // DateTime.asUtc() = 2021-01-25 18:49:03.049422 + // DateTime.toUtc() = 2021-01-25 11:49:03.056208Z + DateTime get asUtc => + isUtc ? this : DateTime.utc(year, month, day, hour, minute, second, millisecond, microsecond); + + DateTime get asLocal => + !isUtc ? this : DateTime(year, month, day, hour, minute, second, millisecond, microsecond); + + // Convert DateTime to String + // Month(short) DD HH:MM AM/PM + String get toDateTimeString => DateFormat('MMM dd h:mm a').format(this); + + // Day, Month DD HH:MM am/pm + String get toFullDateTimeString => DateFormat('EEEE, MMMM dd h:mm a').format(this); + + // Day, Month DD am/pm + String get toFullDateString => DateFormat('EEE, yyyy MMMM dd').format(this); + + // HH:MM am/pm + String get toHMaa => DateFormat('hh:mm aaaa').format(this); + + // HH:MM:SS am/pm + String get toHHMMSS => DateFormat('hh:mm:ss a').format(this); + + // Month DD + String get toMMMMdd => DateFormat('MMMM dd').format(this); + + // Month(short) DD + String get toMMMdd => DateFormat('MMM dd').format(this); + + // YYYY-MM-DD + String get toYyyymmmdd => DateFormat('yyyy-MMM-dd').format(this); + + // YYYY-MM-DD + String get toDateOfBirth => DateFormat('yyyy-MM-dd').format(this); + + // To query format: YYYY-MM-DD + String get toQueryFormat => DateFormat('yyyy-MM-dd').format(this); +} + +// Extension for DateTime from String +extension DateTimeStringExtendsion on String { + // Convert to DateTime by pattern + // https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html + DateTime toDateTime({String pattern = 'yyyy-MM-dd HH:mm:ss'}) { + return DateFormat(pattern).parse(this, true).toLocal(); + } + + String get safe => this; + + String zeroPrefix(int count) { + if (length >= count) { + return this; + } else { + String builder = ''; + for (int i = 0; i < count - length; i++) { + builder += '0'; + } + builder += this; + return builder; + } + } + + int? get parseInt => int.tryParse(this); + + double? get parseDouble => double.tryParse(this); +} + +// Extension for duration +extension DurationExtension on Duration { + Duration get safe => this; + + String get format => toString().split('.').first.padLeft(8, '0'); + + // Add zero padding + String _twoDigits(int n) { + if (n >= 10) { + return '$n'; + } + return '0${max(n, 0)}'; + } + + // hours:minutes:seconds + String get toHms { + final String twoDigitHours = _twoDigits(inHours.remainder(24)); + final String twoDigitMinutes = _twoDigits(inMinutes.remainder(60)); + final String twoDigitSeconds = _twoDigits(inSeconds.remainder(60)); + return '$twoDigitHours:$twoDigitMinutes:$twoDigitSeconds'; + } + + // minutes:seconds + String get toMs { + final String twoDigitMinutes = _twoDigits(inMinutes.remainder(60)); + final String twoDigitSeconds = _twoDigits(inSeconds.remainder(60)); + return '$twoDigitMinutes:$twoDigitSeconds'; + } +} + +// Extension for int +extension DateExtensions on int { + DateTime get localDateTime => DateTime.fromMillisecondsSinceEpoch(this, isUtc: false); + + DateTime get utcDateTime => DateTime.fromMillisecondsSinceEpoch(this, isUtc: true); + + DateTime asDateTime({TimeZone from = TimeZone.utc}) { + switch (from) { + case TimeZone.local: + return localDateTime; + case TimeZone.utc: + default: + return utcDateTime; + } + } + + DateTime asLocal({TimeZone from = TimeZone.utc}) => asDateTime(from: from).asLocal; + + String toTime(BuildContext context, {TimeZone from = TimeZone.utc}) => + asDateTime(from: from).toTime(context); + + int localTimeToday({TimeZone from = TimeZone.utc}) => + asDateTime(from: from).localTimeToday.millisecondsSinceEpoch; + + int onlyDate({TimeZone from = TimeZone.utc}) => + asDateTime(from: from).onlyDate.millisecondsSinceEpoch; + + int onlyTime({TimeZone from = TimeZone.utc}) => + asDateTime(from: from).utcTimeFirstDaySinceEpoch.millisecondsSinceEpoch; + + int utcTimeFirstDaySinceEpoch({TimeZone from = TimeZone.utc}) => + asDateTime(from: from).utcTimeFirstDaySinceEpoch.millisecondsSinceEpoch; + + Duration asDuration() => Duration(milliseconds: this); +} +``` diff --git a/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/input-formatters.md b/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/input-formatters.md index e69de29b..fe602208 100644 --- a/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/input-formatters.md +++ b/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/input-formatters.md @@ -0,0 +1,7 @@ +# Input Formatters + +::: tip TODO +We have not added any formatters yet, we will be adding them soon. +::: + +[[toc]] \ No newline at end of file diff --git a/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/responsive.md b/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/responsive.md index e69de29b..dd1d2cfc 100644 --- a/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/responsive.md +++ b/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/responsive.md @@ -0,0 +1,7 @@ +# Responsive + +::: danger TODO +I don't think this file and code can be of any use, I propose that we remove this. +::: + +[[toc]] \ No newline at end of file diff --git a/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/styles.md b/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/styles.md index e69de29b..aedaafb8 100644 --- a/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/styles.md +++ b/docs/vaahflutter/directory_structure/vaahextendflutter/helpers/styles.md @@ -0,0 +1,243 @@ +# Styles + +::: warning Dependencies +None +::: + +[[toc]] + +We have 9 different size fonts: +- `size0`: `10`, +- `size1`: `12`, +- `size2`: `14`, +- `size3`: `15`, +- `size4`: `16`, +- `size5`: `18`, +- `size6`: `21`, +- `size7`: `24`, +- and `size8`: `27`. + +And we have 4 different kind of weights for fonts: +- `light`, +- `regular`, +- `semiBold`, +- and `bold` + +### Access light fonts + +`light0`, `light1`, `light2`, `light3`, `light4`, `light5`, `light6`, `light7`, `light8` + +```dart +Text('Message', style: TextStyles.light0), +``` + +### Access regular fonts + +`regular0`, `regular1`, `regular2`, `regular3`, `regular4`, `regular5`, `regular6`, `regular7`, `regular8` + +```dart +Text('Message', style: TextStyles.regular0), +``` + +### Access semiBold fonts + +`semiBold0`, `semiBold1`, `semiBold2`, `semiBold3`, `semiBold4`, `semiBold5`, `semiBold6`, `semiBold7`, `semiBold8` + +```dart +Text('Message', style: TextStyles.semiBold0), +``` + +### Access bold fonts + +`bold0`, `bold1`, `bold2`, `bold3`, `bold4`, `bold5`, `bold6`, `bold7`, `bold8` + +```dart +Text('Message', style: TextStyles.bold0), +``` + +### Access boldUnderlined fonts + +`boldUnderlined0`, `boldUnderlined1`, `boldUnderlined2`, `boldUnderlined3`, `boldUnderlined4`, `boldUnderlined5`, `boldUnderlined6`, `boldUnderlined7`, `boldUnderlined8` + +```dart +Text('Message', style: TextStyles.boldUnderlined0), +``` + +### Source code: + +```dart +import 'package:flutter/material.dart'; + +import 'responsive.dart'; + +class TextStyles { + const TextStyles._(); + + // Light + static final light0 = _baseLight[TextSize.size0]; + static final light1 = _baseLight[TextSize.size1]; + static final light2 = _baseLight[TextSize.size2]; + static final light3 = _baseLight[TextSize.size3]; + static final light4 = _baseLight[TextSize.size4]; + static final light5 = _baseLight[TextSize.size5]; + static final light6 = _baseLight[TextSize.size6]; + static final light7 = _baseLight[TextSize.size7]; + static final light8 = _baseLight[TextSize.size8]; + + // Regular + static final regular0 = _baseRegular[TextSize.size0]; + static final regular1 = _baseRegular[TextSize.size1]; + static final regular2 = _baseRegular[TextSize.size2]; + static final regular3 = _baseRegular[TextSize.size3]; + static final regular4 = _baseRegular[TextSize.size4]; + static final regular5 = _baseRegular[TextSize.size5]; + static final regular6 = _baseRegular[TextSize.size6]; + static final regular7 = _baseRegular[TextSize.size7]; + static final regular8 = _baseRegular[TextSize.size8]; + + // Semi-bold + static final semiBold0 = _baseSemiBold[TextSize.size0]; + static final semiBold1 = _baseSemiBold[TextSize.size1]; + static final semiBold2 = _baseSemiBold[TextSize.size2]; + static final semiBold3 = _baseSemiBold[TextSize.size3]; + static final semiBold4 = _baseSemiBold[TextSize.size4]; + static final semiBold5 = _baseSemiBold[TextSize.size5]; + static final semiBold6 = _baseSemiBold[TextSize.size6]; + static final semiBold7 = _baseSemiBold[TextSize.size7]; + static final semiBold8 = _baseSemiBold[TextSize.size8]; + + // Bold + static final bold0 = _baseBold[TextSize.size0]; + static final bold1 = _baseBold[TextSize.size1]; + static final bold2 = _baseBold[TextSize.size2]; + static final bold3 = _baseBold[TextSize.size3]; + static final bold4 = _baseBold[TextSize.size4]; + static final bold5 = _baseBold[TextSize.size5]; + static final bold6 = _baseBold[TextSize.size6]; + static final bold7 = _baseBold[TextSize.size7]; + static final bold8 = _baseBold[TextSize.size8]; + + // Bold Underlined + static final boldUnderlined0 = _baseBoldUnder[TextSize.size0]; + static final boldUnderlined1 = _baseBoldUnder[TextSize.size1]; + static final boldUnderlined2 = _baseBoldUnder[TextSize.size2]; + static final boldUnderlined3 = _baseBoldUnder[TextSize.size3]; + static final boldUnderlined4 = _baseBoldUnder[TextSize.size4]; + static final boldUnderlined5 = _baseBoldUnder[TextSize.size5]; + static final boldUnderlined6 = _baseBoldUnder[TextSize.size6]; + static final boldUnderlined7 = _baseBoldUnder[TextSize.size7]; + static final boldUnderlined8 = _baseBoldUnder[TextSize.size8]; + + // -------------------------------------------------------------------------- + + static final _baseLight = { + TextSize.size0: _createBaseTextStyle(TextWeight.light, TextSize.size0), + TextSize.size1: _createBaseTextStyle(TextWeight.light, TextSize.size1), + TextSize.size2: _createBaseTextStyle(TextWeight.light, TextSize.size2), + TextSize.size3: _createBaseTextStyle(TextWeight.light, TextSize.size3), + TextSize.size4: _createBaseTextStyle(TextWeight.light, TextSize.size4), + TextSize.size5: _createBaseTextStyle(TextWeight.light, TextSize.size5), + TextSize.size6: _createBaseTextStyle(TextWeight.light, TextSize.size6), + TextSize.size7: _createBaseTextStyle(TextWeight.light, TextSize.size7), + TextSize.size8: _createBaseTextStyle(TextWeight.light, TextSize.size8), + }; + + static final _baseRegular = { + TextSize.size0: _createBaseTextStyle(TextWeight.regular, TextSize.size0), + TextSize.size1: _createBaseTextStyle(TextWeight.regular, TextSize.size1), + TextSize.size2: _createBaseTextStyle(TextWeight.regular, TextSize.size2), + TextSize.size3: _createBaseTextStyle(TextWeight.regular, TextSize.size3), + TextSize.size4: _createBaseTextStyle(TextWeight.regular, TextSize.size4), + TextSize.size5: _createBaseTextStyle(TextWeight.regular, TextSize.size5), + TextSize.size6: _createBaseTextStyle(TextWeight.regular, TextSize.size6), + TextSize.size7: _createBaseTextStyle(TextWeight.regular, TextSize.size7), + TextSize.size8: _createBaseTextStyle(TextWeight.regular, TextSize.size8), + }; + + static final _baseSemiBold = { + TextSize.size0: _createBaseTextStyle(TextWeight.semiBold, TextSize.size0), + TextSize.size1: _createBaseTextStyle(TextWeight.semiBold, TextSize.size1), + TextSize.size2: _createBaseTextStyle(TextWeight.semiBold, TextSize.size2), + TextSize.size3: _createBaseTextStyle(TextWeight.semiBold, TextSize.size3), + TextSize.size4: _createBaseTextStyle(TextWeight.semiBold, TextSize.size4), + TextSize.size5: _createBaseTextStyle(TextWeight.semiBold, TextSize.size5), + TextSize.size6: _createBaseTextStyle(TextWeight.semiBold, TextSize.size6), + TextSize.size7: _createBaseTextStyle(TextWeight.semiBold, TextSize.size7), + TextSize.size8: _createBaseTextStyle(TextWeight.semiBold, TextSize.size8), + }; + + static final _baseBold = { + TextSize.size0: _createBaseTextStyle(TextWeight.bold, TextSize.size0), + TextSize.size1: _createBaseTextStyle(TextWeight.bold, TextSize.size1), + TextSize.size2: _createBaseTextStyle(TextWeight.bold, TextSize.size2), + TextSize.size3: _createBaseTextStyle(TextWeight.bold, TextSize.size3), + TextSize.size4: _createBaseTextStyle(TextWeight.bold, TextSize.size4), + TextSize.size5: _createBaseTextStyle(TextWeight.bold, TextSize.size5), + TextSize.size6: _createBaseTextStyle(TextWeight.bold, TextSize.size6), + TextSize.size7: _createBaseTextStyle(TextWeight.bold, TextSize.size7), + TextSize.size8: _createBaseTextStyle(TextWeight.bold, TextSize.size8), + }; + + static final _baseBoldUnder = { + TextSize.size0: _createBaseTextStyle(TextWeight.bold, TextSize.size0, underline: true), + TextSize.size1: _createBaseTextStyle(TextWeight.bold, TextSize.size1, underline: true), + TextSize.size2: _createBaseTextStyle(TextWeight.bold, TextSize.size2, underline: true), + TextSize.size3: _createBaseTextStyle(TextWeight.bold, TextSize.size3, underline: true), + TextSize.size4: _createBaseTextStyle(TextWeight.bold, TextSize.size4, underline: true), + TextSize.size5: _createBaseTextStyle(TextWeight.bold, TextSize.size5, underline: true), + TextSize.size6: _createBaseTextStyle(TextWeight.bold, TextSize.size6, underline: true), + TextSize.size7: _createBaseTextStyle(TextWeight.bold, TextSize.size7, underline: true), + TextSize.size8: _createBaseTextStyle(TextWeight.bold, TextSize.size8, underline: true), + }; + + static TextStyle _createBaseTextStyle(TextWeight weight, TextSize size, + {Color? color, double? lineHeight, bool underline = false}) { + final fontSize = _fontSizes[size]!; + return TextStyle( + fontWeight: _fontWeights[weight]!, + fontSize: fontSize, + decoration: underline ? TextDecoration.underline : null, + height: (lineHeight ?? _lineHeights[size]!) / fontSize, + ); + } + + static const _fontWeights = { + TextWeight.light: FontWeight.w300, + TextWeight.regular: FontWeight.w400, + TextWeight.semiBold: FontWeight.w600, + TextWeight.bold: FontWeight.w700, + }; + + static final _fontSizes = { + TextSize.size0: 10.0.spExt, + TextSize.size1: 12.0.spExt, + TextSize.size2: 14.0.spExt, + TextSize.size3: 15.0.spExt, + TextSize.size4: 16.0.spExt, + TextSize.size5: 18.0.spExt, + TextSize.size6: 21.0.spExt, + TextSize.size7: 24.0.spExt, + TextSize.size8: 27.0.spExt, + }; + + static final _lineHeights = { + TextSize.size0: 14.0.spExt, + TextSize.size1: 16.0.spExt, + TextSize.size2: 19.0.spExt, + TextSize.size3: 20.0.spExt, + TextSize.size4: 21.0.spExt, + TextSize.size5: 24.0.spExt, + TextSize.size6: 27.0.spExt, + TextSize.size7: 30.0.spExt, + TextSize.size8: 33.0.spExt, + }; +} + +enum TextSize { size0, size1, size2, size3, size4, size5, size6, size7, size8 } + +enum TextWeight { light, regular, semiBold, bold } + +extension TextStyleWithColor on TextStyle? { + TextStyle withColor(Color color) => this!.copyWith(color: color); +} +``` \ No newline at end of file