Compare commits

...

9 Commits

23 changed files with 603 additions and 129 deletions

View File

@@ -0,0 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"app_settings","path":"/Users/yaso_meth/.pub-cache/hosted/pub.dev/app_settings-7.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_darwin","path":"/Users/yaso_meth/.pub-cache/hosted/pub.dev/local_auth_darwin-1.6.0/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"app_settings","path":"/Users/yaso_meth/.pub-cache/hosted/pub.dev/app_settings-7.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_plugin_android_lifecycle","path":"/Users/yaso_meth/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.31/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_android","path":"/Users/yaso_meth/.pub-cache/hosted/pub.dev/local_auth_android-1.0.52/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"],"dev_dependency":false}],"macos":[{"name":"app_settings","path":"/Users/yaso_meth/.pub-cache/hosted/pub.dev/app_settings-7.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"local_auth_darwin","path":"/Users/yaso_meth/.pub-cache/hosted/pub.dev/local_auth_darwin-1.6.0/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[],"windows":[{"name":"local_auth_windows","path":"/Users/yaso_meth/.pub-cache/hosted/pub.dev/local_auth_windows-1.0.11/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[]},"dependencyGraph":[{"name":"app_settings","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"local_auth","dependencies":["local_auth_android","local_auth_darwin","local_auth_windows"]},{"name":"local_auth_android","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"local_auth_darwin","dependencies":[]},{"name":"local_auth_windows","dependencies":[]}],"date_created":"2026-03-20 09:42:38.514309","version":"3.32.2","swift_package_manager_enabled":{"ios":false,"macos":false}}

1
.gitignore vendored
View File

@@ -1 +1,2 @@
.DS_Store
.dart_tool

View File

@@ -1,3 +1,23 @@
# Changelog
All notable changes to this project will be documented in this file.
## 0.0.2
### Initial Release
Usability and Bug Fixes
* Add support for all platforms.
* Remove ThemeDate dependancy on mih_package_toolkit widgets.
* Add Color paramaters to `MihDateField`, `MihTimeField`, `MihPackage`, `MihPackageAction`, `MihPackageToolBody`, `MihPackageTools`.
* Add Auth Check paramater to `MihPackageTile`.
## 0.0.1
* TODO: Describe initial release.
### Initial Release
A comprehensive UI toolkit and utility library specifically designed for creating MIH Packages. This version includes a curated set of widgets, forms, and design utilities.
* **Form Elements**: Includes `MihButton`, `MihForm`, `MihTextFormField`, `MihDateField`, `MihTimeField`, and `MihDropdownField`, `MihSearchBar`, for streamlined data entry.
* **Navigation & Layout**: Complex structural components like `MihPackage`, `MihPackageTitle`, `MihPackageAction`, `MihPackageTools`, `MihPackageToolBody`, `MihPackageWindow`, `MihSingleChildScroll`, and `MihFloatingMenu`, .
* **Feedback & Progress**: Pre-styled `MihSnackBar` and `MihLoadingCircle` for user interaction.
* **Design Tokens**: Built-in access to `MihColors` and `MihIcons` to ensure brand compliance.
* **Specialized Controls**: Widgets like `MihNumericStepper`, `MihRadioOptions`, and `MihToggle`.

135
README.md
View File

@@ -1,34 +1,23 @@
<!--
This README describes the package. If you publish this package to pub.dev,
this README's contents appear on the landing page for your package.
For information about how to write a good package README, see the guide for
[writing package pages](https://dart.dev/tools/pub/writing-package-pages).
For general information about developing packages, see the Dart guide for
[creating packages](https://dart.dev/guides/libraries/create-packages)
and the Flutter guide for
[developing packages and plugins](https://flutter.dev/to/develop-packages).
-->
# mih_package_toolkit
A comprehensive UI toolkit and utility library specifically designed to help developers build **MIH Packages** for the MIH app ecosystem.
A comprehensive UI toolkit and utility library specifically designed to help developers build **MIH Packages** for the MIH Project ecosystem.
This toolkit provides a curated set of widgets, forms, and design utilitiesranging from custom buttons and input fields to complex layout components like floating menus and package windows.
---
This toolkit provides a curated set of widgets, forms, and design utilities-ranging from custom buttons and input fields to complex layout components like floating menus and package windows.
## Features
This toolkit provides everything you need to maintain visual and functional consistency within the MIH ecosystem:
* **Form Elements**: Includes `MihForm`, `MihTextField`, `MihDateField`, and `MihDropdownField` for streamlined data entry.
* **Navigation & Layout**: Complex structural components like `MihFloatingMenu`, `MihPackageWindow`, and `MihPackageToolBody`.
* **Form Elements**: Includes `MihButton`, `MihForm`, `MihTextFormField`, `MihDateField`, `MihTimeField`, and `MihDropdownField`, `MihSearchBar`, for streamlined data entry.
* **Navigation & Layout**: Complex structural components like `MihPackage`, `MihPackageTitle`, `MihPackageAction`, `MihPackageTools`, `MihPackageToolBody`, `MihPackageWindow`, `MihSingleChildScroll`, and `MihFloatingMenu`, .
* **Feedback & Progress**: Pre-styled `MihSnackBar` and `MihLoadingCircle` for user interaction.
* **Design Tokens**: Built-in access to `MihColors` and `MihIcons` to ensure brand compliance.
* **Specialized Controls**: Widgets like `MihNumericStepper`, `MihRadioOptions`, and `MihToggle`.
## Demo
<img src='assets/mih_package_toolkit_demo.gif' height='300' alt='MIH Package Demo'>
## Getting started
To use this library, Add the package to your `pubspec.yaml`:
@@ -49,19 +38,36 @@ import 'package:mih_package_toolkit/mih_package_toolkit.dart';
import 'package:flutter/material.dart';
import 'package:mih_package_toolkit/mih_package_toolkit.dart';
class ExamplePackage extends StatefulWidget {
const ExamplePackage({super.key});
@override
State<ExamplePackage> createState() => _ExamplePackageState();
void main() {
runApp(const MyApp());
}
class _ExamplePackageState extends State<ExamplePackage> {
int selectedbodyIndex = 0; // Important for state management of the body
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(title: 'Flutter Demo', home: const ExampleMihPackage());
}
}
class ExampleMihPackage extends StatefulWidget {
const ExampleMihPackage({super.key});
@override
State<ExampleMihPackage> createState() => _ExampleMihPackageState();
}
class _ExampleMihPackageState extends State<ExampleMihPackage> {
@override
Widget build(BuildContext context) {
return MihPackage(
backgroundColor: MihColors.primary(),
packageActionButton: actionButton(),
packageTools: tools(),
packageToolBodies: toolBodies(),
@@ -75,8 +81,11 @@ class _ExamplePackageState extends State<ExamplePackage> {
);
}
int selectedbodyIndex = 0; // Important for state management of the body
Widget actionButton() {
return MihPackageAction(
iconColor: MihColors.secondary(),
icon: Icon(Icons.arrow_back),
iconSize: 35,
onTap: () {
@@ -91,35 +100,89 @@ class _ExamplePackageState extends State<ExamplePackage> {
}
MihPackageTools tools() {
Map<Widget, void Function()?> temp = {};
temp[const Icon(Icons.calculate)] = () {
Map<Widget, void Function()?> toolList = {};
toolList[const Icon(Icons.calculate)] = () {
setState(() {
selectedbodyIndex = 0;
});
};
temp[const Icon(Icons.money)] = () {
toolList[const Icon(Icons.money)] = () {
setState(() {
selectedbodyIndex = 1;
});
};
return MihPackageTools(tools: temp, selectedIndex: selectedbodyIndex);
return MihPackageTools(
tools: toolList,
toolColor: MihColors.secondary(),
onSelectedIconColor: MihColors.primary(),
selectedIndex: selectedbodyIndex,
);
}
List<Widget> toolBodies() {
return [
MihPackageToolBody(
backgroundColor: MihColors.primary(),
bodyItem: Center(child: Text("Tool Body One")),
bodyItem: Center(
child: Text(
"Tool Body One",
style: TextStyle(
color: MihColors.secondary(),
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
),
MihPackageToolBody(
backgroundColor: MihColors.secondary(),
bodyItem: Center(child: Text("Tool Body Two")),
bodyItem: Center(
child: Text(
"Tool Body Two",
style: TextStyle(
color: MihColors.primary(),
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
),
];
}
}
```
---
## Android Setup & Troubleshooting
This package relies on **`local_auth`** and **`app_settings`**. Due to recent updates in these plugins, your Android project must meet specific SDK and NDK version requirements.
### 1. Official Plugin Documentation
If you encounter platform-specific issues (such as biometric permission errors), please refer to the official setup guides:
* [**local_auth (Android Integration)**](https://pub.dev/packages/local_auth#android-integration) — *Note: Requires `FlutterFragmentActivity` in your MainActivity.*
* [**app_settings (Documentation)**](https://pub.dev/packages/app_settings) — *Note: Required for opening system settings natively.*
### 2. Required Build Configuration
Update your `android/app/build.gradle.kts` (or `build.gradle`) to match the versions required by these plugins:
```kotlin
android {
// Required by the latest app_settings
compileSdk = 36
// Required by local_auth & app_settings native dependencies
ndkVersion = "27.0.12077973"
defaultConfig {
// local_auth requires a minimum of SDK 21
minSdk = 21
...
}
}
```
## Additional information
For more details about MIH Package Toolkit, including usage instructions and updates, please visit the [MIH Gitea repository](https://git.mzansi-innovation-hub.co.za/yaso_meth/mih_package_toolkit).
@@ -127,10 +190,12 @@ For more details about MIH Package Toolkit, including usage instructions and upd
### Contributing
Contributions are welcome! If you'd like to improve the package, please fork the repository, make your changes, and submit a pull request. For major changes, please open an issue first to discuss what you would like to change.
### Reporting Issues
If you encounter any bugs or have feature requests, please file an issue on the [MIH Gitea Issues page](https://git.mzansi-innovation-hub.co.za/yaso_meth/mih_package_toolkit/issues). Provide as much detail as possible to help us address the problem promptly.
### Reporting Issues/ Feature Requests
If you encounter any bugs or have feature requests, please log an issue on the [MIH Gitea Issues page](https://git.mzansi-innovation-hub.co.za/yaso_meth/mih_package_toolkit/issues). Provide as much detail as possible to help us address the problem promptly.
### Support and Response
We strive to respond to issues and pull requests in a timely manner. While this package is maintained voluntarily, we appreciate your patience and community involvement.
Thank you for using the MIH Package Toolkit!
If you would like to support the MIH development team directly, please feel free to contribute to the [MIH Project via DonaHub](https://donahub.co.za/campaigns/mih-project)
Thank you for using the MIH Package Toolkit!

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 MiB

29
example/ios/Podfile.lock Normal file
View File

@@ -0,0 +1,29 @@
PODS:
- app_settings (6.1.2):
- Flutter
- Flutter (1.0.0)
- local_auth_darwin (0.0.1):
- Flutter
- FlutterMacOS
DEPENDENCIES:
- app_settings (from `.symlinks/plugins/app_settings/ios`)
- Flutter (from `Flutter`)
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
EXTERNAL SOURCES:
app_settings:
:path: ".symlinks/plugins/app_settings/ios"
Flutter:
:path: Flutter
local_auth_darwin:
:path: ".symlinks/plugins/local_auth_darwin/darwin"
SPEC CHECKSUMS:
app_settings: 0341ec6daa4f0c50f5a421bf0ad7c36084db6e90
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
local_auth_darwin: d2e8c53ef0c4f43c646462e3415432c4dab3ae19
PODFILE CHECKSUM: 4305caec6b40dde0ae97be1573c53de1882a07e5
COCOAPODS: 1.16.2

View File

@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
13BE4213B36414F809A1160E /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B1C8417864665030A30B848B /* Pods_RunnerTests.framework */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
@@ -14,6 +15,7 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
BF9AD1C63D619E72946F42B5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1415EE22816931B4FC61241E /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -40,6 +42,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1415EE22816931B4FC61241E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
@@ -55,19 +58,44 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
986ED1F7945284CCBE47FD26 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
B1C8417864665030A30B848B /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B5A2FDFC90BC2E9FD77D3B67 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
BB242910E4BFE4FB21633CC5 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
C101B68593BFC91F1222DC62 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
DC7D27D9F017D871D9244B21 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
E51D8B28C213FB29301A14E5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
2D589B540E864F3AA91D01EC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
13BE4213B36414F809A1160E /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
BF9AD1C63D619E72946F42B5 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
2C1E99200F034F54F697E756 /* Frameworks */ = {
isa = PBXGroup;
children = (
1415EE22816931B4FC61241E /* Pods_Runner.framework */,
B1C8417864665030A30B848B /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
@@ -76,6 +104,20 @@
path = RunnerTests;
sourceTree = "<group>";
};
6342F71C04597DF5134EDDB6 /* Pods */ = {
isa = PBXGroup;
children = (
E51D8B28C213FB29301A14E5 /* Pods-Runner.debug.xcconfig */,
986ED1F7945284CCBE47FD26 /* Pods-Runner.release.xcconfig */,
B5A2FDFC90BC2E9FD77D3B67 /* Pods-Runner.profile.xcconfig */,
BB242910E4BFE4FB21633CC5 /* Pods-RunnerTests.debug.xcconfig */,
DC7D27D9F017D871D9244B21 /* Pods-RunnerTests.release.xcconfig */,
C101B68593BFC91F1222DC62 /* Pods-RunnerTests.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
@@ -94,6 +136,8 @@
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
6342F71C04597DF5134EDDB6 /* Pods */,
2C1E99200F034F54F697E756 /* Frameworks */,
);
sourceTree = "<group>";
};
@@ -128,8 +172,10 @@
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
D61BC6E88D716DC7D4EBB22A /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
2D589B540E864F3AA91D01EC /* Frameworks */,
);
buildRules = (
);
@@ -145,12 +191,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
EFF926552F4370E1F2A802AB /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
2061BC29C1101ABE580CD7CA /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -222,6 +270,23 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
2061BC29C1101ABE580CD7CA /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
@@ -253,6 +318,50 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
D61BC6E88D716DC7D4EBB22A /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
EFF926552F4370E1F2A802AB /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -379,6 +488,7 @@
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = BB242910E4BFE4FB21633CC5 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -396,6 +506,7 @@
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = DC7D27D9F017D871D9244B21 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -411,6 +522,7 @@
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = C101B68593BFC91F1222DC62 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;

View File

@@ -4,4 +4,7 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,4 +1,3 @@
import 'package:example/package_structure/example_package.dart';
import 'package:flutter/material.dart';
import 'package:mih_package_toolkit/mih_package_toolkit.dart';
@@ -16,47 +15,101 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
scaffoldBackgroundColor: MihColors.primary(),
colorScheme: ColorScheme(
brightness: Brightness.dark,
primary: MihColors.secondary(),
onPrimary: MihColors.primary(),
secondary: MihColors.primary(),
onSecondary: MihColors.secondary(),
error: MihColors.red(),
onError: MihColors.primary(),
surface: MihColors.primary(),
onSurface: MihColors.secondary(),
),
),
home: const HomePage(),
);
return MaterialApp(title: 'Flutter Demo', home: const ExampleMihPackage());
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
class ExampleMihPackage extends StatefulWidget {
const ExampleMihPackage({super.key});
@override
State<ExampleMihPackage> createState() => _ExampleMihPackageState();
}
class _ExampleMihPackageState extends State<ExampleMihPackage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: MihPackageTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const ExamplePackage()),
);
},
packageName: "Example Package",
packageIcon: Icon(MihIcons.mihLogo, color: MihColors.secondary()),
iconSize: 150,
textColor: MihColors.secondary(),
),
),
return MihPackage(
backgroundColor: MihColors.primary(),
packageActionButton: actionButton(),
packageTools: tools(),
packageToolBodies: toolBodies(),
packageToolTitles: appToolTitles(),
selectedBodyIndex: selectedbodyIndex,
onIndexChange: (newIndex) {
setState(() {
selectedbodyIndex = newIndex;
});
},
);
}
int selectedbodyIndex = 0; // Important for state management of the body
Widget actionButton() {
return MihPackageAction(
iconColor: MihColors.secondary(),
icon: Icon(Icons.arrow_back),
iconSize: 35,
onTap: () {
Navigator.pop(context);
},
);
}
List<String> appToolTitles() {
List<String> toolTitles = ["Tool 1", "Tool 2"];
return toolTitles;
}
MihPackageTools tools() {
Map<Widget, void Function()?> toolList = {};
toolList[const Icon(Icons.calculate)] = () {
setState(() {
selectedbodyIndex = 0;
});
};
toolList[const Icon(Icons.money)] = () {
setState(() {
selectedbodyIndex = 1;
});
};
return MihPackageTools(
tools: toolList,
toolColor: MihColors.secondary(),
onSelectedIconColor: MihColors.primary(),
selectedIndex: selectedbodyIndex,
);
}
List<Widget> toolBodies() {
return [
MihPackageToolBody(
backgroundColor: MihColors.primary(),
bodyItem: Center(
child: Text(
"Tool Body One",
style: TextStyle(
color: MihColors.secondary(),
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
),
MihPackageToolBody(
backgroundColor: MihColors.secondary(),
bodyItem: Center(
child: Text(
"Tool Body Two",
style: TextStyle(
color: MihColors.primary(),
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
),
];
}
}

View File

@@ -13,7 +13,7 @@ class ExamplePackage extends StatefulWidget {
class _ExamplePackageState extends State<ExamplePackage> {
int selectedbodyIndex = 0; // Important for state management of the body
late final ToolBodyOne _toolBodyOne;
late final Widget _toolBodyTwo;
late final ToolBodyTwo _toolBodyTwo;
@override
void initState() {
@@ -25,6 +25,8 @@ class _ExamplePackageState extends State<ExamplePackage> {
@override
Widget build(BuildContext context) {
return MihPackage(
backgroundColor: MihColors.primary(),
titleColor: MihColors.secondary(),
packageActionButton: actionButton(),
packageTools: tools(),
packageToolBodies: toolBodies(),
@@ -40,6 +42,7 @@ class _ExamplePackageState extends State<ExamplePackage> {
Widget actionButton() {
return MihPackageAction(
iconColor: MihColors.secondary(),
icon: Icon(Icons.arrow_back),
iconSize: 35,
onTap: () {
@@ -65,7 +68,12 @@ class _ExamplePackageState extends State<ExamplePackage> {
selectedbodyIndex = 1;
});
};
return MihPackageTools(tools: temp, selectedIndex: selectedbodyIndex);
return MihPackageTools(
toolColor: MihColors.green(),
onSelectedIconColor: MihColors.primary(),
tools: temp,
selectedIndex: selectedbodyIndex,
);
}
List<Widget> toolBodies() {

View File

@@ -14,6 +14,7 @@ class _ToolBodyOneState extends State<ToolBodyOne> {
return MihPackageToolBody(
backgroundColor: MihColors.primary(),
bodyItem: MihSingleChildScroll(
scrollbarOn: true,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [

View File

@@ -24,6 +24,7 @@ class _ToolBodyTwoState extends State<ToolBodyTwo> {
return MihPackageToolBody(
backgroundColor: MihColors.primary(),
bodyItem: MihSingleChildScroll(
scrollbarOn: true,
child: MihForm(
formKey: _formKey,
formFields: [

View File

@@ -209,7 +209,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.0.1"
version: "0.0.2"
path:
dependency: transitive
description:

View File

@@ -13,6 +13,12 @@ import 'package:mih_package_toolkit/src/mih_colors.dart';
/// * Theme-aware styling that syncs with [MihColors].
/// * Custom elevation and border radius.
class MihDateField extends StatefulWidget {
/// The primary color of the date picker
final Color? primaryColor;
/// The secondary color of the date picker
final Color? secondayColor;
/// The controller that handles the text being edited.
///
/// The date will be stored in `YYYY-MM-DD` format.
@@ -50,6 +56,8 @@ class MihDateField extends StatefulWidget {
required this.controller,
required this.labelText,
required this.required,
this.primaryColor,
this.secondayColor,
this.width,
this.height,
this.borderRadius,
@@ -79,6 +87,36 @@ class _MihDateFieldState extends State<MihDateField> {
: DateTime.now(),
firstDate: DateTime(1900),
lastDate: DateTime(2200),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ColorScheme.fromSeed(
seedColor: widget.primaryColor ?? MihColors.primary(),
primary: widget.secondayColor ??
MihColors.secondary(), // Header & Selected Day
onPrimary: widget.primaryColor ??
MihColors.primary(), // Text on top of primary
surface:
widget.secondayColor ?? MihColors.secondary(), // Background
onSurface:
widget.secondayColor ?? MihColors.secondary(), // Text/Dates
),
datePickerTheme: DatePickerThemeData(
backgroundColor: widget.primaryColor ?? MihColors.primary(),
headerBackgroundColor:
widget.secondayColor ?? MihColors.secondary(),
headerForegroundColor: widget.primaryColor ?? MihColors.primary(),
),
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: widget.secondayColor ??
MihColors.secondary(), // Action buttons (OK/Cancel)
),
),
),
child: child!,
);
},
);
if (picked != null) {
widget.controller.text = picked.toString().split(" ")[0];

View File

@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:mih_package_toolkit/src/mih_colors.dart';
import 'package:mih_package_toolkit/src/mih_package_tools.dart';
/// The core container for MIH application modules.
@@ -29,20 +30,26 @@ import 'package:mih_package_toolkit/src/mih_package_tools.dart';
/// )
/// ```
class MihPackage extends StatefulWidget {
/// The background color of the package
final Color? backgroundColor;
/// The title color of the package
final Color? titleColor;
/// The floating action button or primary action trigger for this package.
final Widget packageActionButton;
/// The titles displayed in the header for each corresponding page.
final List<String> packageToolTitles;
/// The toolbar widget containing icons that correspond to the [packageToolBodies] pages.
final MihPackageTools packageTools;
/// The list of main content widgets for each "page" of the package.
final List<Widget> packageToolBodies;
/// The titles displayed in the header for each corresponding page.
final List<String> packageToolTitles;
/// An optional drawer for secondary actions.
final Drawer? actionDrawer;
/// An optional drawer for actions.
final Widget? actionDrawer;
/// The initial page index to display.
final int selectedBodyIndex;
@@ -51,6 +58,8 @@ class MihPackage extends StatefulWidget {
final Function(int) onIndexChange;
const MihPackage({
super.key,
this.backgroundColor,
this.titleColor,
required this.packageActionButton,
required this.packageTools,
required this.packageToolBodies,
@@ -155,6 +164,7 @@ class _MihPackageState extends State<MihPackage>
return GestureDetector(
onTap: unfocusAll,
child: Scaffold(
backgroundColor: widget.backgroundColor ?? MihColors.primary(),
drawer: widget.actionDrawer,
body: SafeArea(
bottom: false,
@@ -181,7 +191,8 @@ class _MihPackageState extends State<MihPackage>
child: FittedBox(
child: Text(
widget.packageToolTitles[_currentIndex],
style: const TextStyle(
style: TextStyle(
color: widget.titleColor ?? MihColors.secondary(),
fontSize: 23,
fontWeight: FontWeight.w600,
),

View File

@@ -23,6 +23,9 @@ class MihPackageAction extends StatefulWidget {
/// If null, the button will be disabled and appear greyed out.
final void Function()? onTap;
/// The Color of the Icon
final Color iconColor;
/// The size of the icon inside the button.
final double iconSize;
@@ -32,6 +35,7 @@ class MihPackageAction extends StatefulWidget {
super.key,
required this.icon,
required this.iconSize,
required this.iconColor,
required this.onTap,
});
@@ -57,6 +61,7 @@ class _MihPackageActionState extends State<MihPackageAction> {
padding: const EdgeInsets.all(0),
onPressed: widget.onTap,
icon: widget.icon,
color: widget.iconColor,
);
}
}

View File

@@ -1,4 +1,6 @@
import 'dart:io' show Platform;
import 'package:app_settings/app_settings.dart';
import 'package:flutter/foundation.dart';
import 'package:local_auth/local_auth.dart';
import 'package:mih_package_toolkit/src/mih_button.dart';
import 'package:mih_package_toolkit/src/mih_colors.dart';
@@ -29,7 +31,9 @@ import 'package:mih_package_toolkit/src/mih_single_child_scroll.dart';
class MihPackageTile extends StatefulWidget {
/// The name of the package displayed below the icon.
final String packageName;
// final String? ytVideoID;
/// The icon of the package displayed above the name.
final Widget packageIcon;
/// The callback triggered when the tile is tapped.
@@ -40,7 +44,9 @@ class MihPackageTile extends StatefulWidget {
/// The color of the [packageName] text.
final Color textColor;
// final bool? authenticateUser;
/// Does the package require local auth check before opennings.
final bool? authenticateUser;
const MihPackageTile({
super.key,
required this.onTap,
@@ -49,7 +55,7 @@ class MihPackageTile extends StatefulWidget {
required this.packageIcon,
required this.iconSize,
required this.textColor,
// this.authenticateUser,
this.authenticateUser,
});
@override
@@ -95,7 +101,6 @@ class _MihPackageTileState extends State<MihPackageTile> {
} else {
authErrorPopUp();
}
// print("Authenticated: $didBioAuth");
} catch (error) {
authErrorPopUp();
}
@@ -212,17 +217,17 @@ class _MihPackageTileState extends State<MihPackageTile> {
}
Future<void> authenticateUser() async {
// if (widget.authenticateUser != null &&
// widget.authenticateUser! &&
// !kIsWeb &&
// !Platform.isLinux) {
// if (await isUserAuthenticated()) {
// widget.onTap();
// }
// } else {
// widget.onTap();
// }
widget.onTap();
if (widget.authenticateUser != null &&
widget.authenticateUser! &&
!kIsWeb &&
!Platform.isLinux) {
if (await isUserAuthenticated()) {
widget.onTap();
}
} else {
widget.onTap();
}
// widget.onTap();
}
@override

View File

@@ -95,8 +95,7 @@ class _MihPackageToolBodyState extends State<MihPackageToolBody> {
color: widget.backgroundColor,
borderRadius: BorderRadius.circular(25.0),
border: Border.all(
color:
widget.borderColor ??
color: widget.borderColor ??
MihColors.secondary(darkMode: widget.darkMode),
width: 3.0,
),
@@ -105,7 +104,7 @@ class _MihPackageToolBodyState extends State<MihPackageToolBody> {
_innerBodyPadding = 0.0;
return BoxDecoration(
color: widget.backgroundColor,
borderRadius: BorderRadius.circular(25.0),
borderRadius: BorderRadius.circular(0),
border: Border.all(color: widget.backgroundColor, width: 3.0),
);
}

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:mih_package_toolkit/src/mih_colors.dart';
/// A horizontal toolbar used for navigation within a [MihPackage].
///
@@ -33,6 +34,12 @@ import 'package:flutter/material.dart';
/// ```
// ignore: must_be_immutable
class MihPackageTools extends StatefulWidget {
/// The selected button fill color and unselected icon color
final Color? toolColor;
/// The selected button fill color and unselected icon color
final Color? onSelectedIconColor;
/// A map where the key is the Icon widget and the value is the
/// callback function triggered on tap.
final Map<Widget, void Function()?> tools;
@@ -43,6 +50,8 @@ class MihPackageTools extends StatefulWidget {
int selectedIndex;
MihPackageTools({
super.key,
this.toolColor,
this.onSelectedIconColor,
required this.tools,
required this.selectedIndex,
});
@@ -63,13 +72,24 @@ class _MihPackageToolsState extends State<MihPackageTools> {
temp.add(
Visibility(
visible: widget.selectedIndex != index,
child: IconButton(onPressed: onTap, icon: icon),
child: IconButton(
color: widget.toolColor ?? MihColors.secondary(),
onPressed: onTap,
icon: icon,
),
),
);
temp.add(
Visibility(
visible: widget.selectedIndex == index,
child: IconButton.filled(onPressed: onTap, icon: icon),
child: IconButton.filled(
color: widget.onSelectedIconColor ?? MihColors.primary(),
onPressed: onTap,
icon: icon,
style: IconButton.styleFrom(
backgroundColor: widget.toolColor ?? MihColors.secondary(),
),
),
),
);
index += 1;

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:mih_package_toolkit/src/mih_colors.dart';
/// A standardized scrollable container for the MIH Toolkit.
///
@@ -34,10 +35,18 @@ class MihSingleChildScroll extends StatefulWidget {
/// Defaults to `false` if null. When enabled, it applies a
/// [ScrollConfiguration] to the child subtree.
final bool? scrollbarOn;
/// the color of scroll thumb when enabled wth [scrollbarOn]
final Color? scrollThumbColor;
/// The thinkness of scroll thumb when enabled with [scrollbarOn]
final double? scrollThumbThinkness;
const MihSingleChildScroll({
super.key,
required this.child,
this.scrollbarOn,
this.scrollThumbColor,
this.scrollThumbThinkness,
});
@override
@@ -50,11 +59,22 @@ class _MihSingleChildScrollState extends State<MihSingleChildScroll> {
return SafeArea(
bottom: false,
minimum: EdgeInsets.only(bottom: 5),
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(
context,
).copyWith(scrollbars: widget.scrollbarOn ?? false),
child: SingleChildScrollView(child: widget.child),
child: Theme(
data: Theme.of(context).copyWith(
scrollbarTheme: ScrollbarThemeData(
thumbColor: WidgetStateProperty.all(widget.scrollThumbColor ??
MihColors.secondary()), // scrollbar color
thickness:
WidgetStateProperty.all(widget.scrollThumbThinkness ?? 10.0),
radius: Radius.circular(10),
),
),
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(
context,
).copyWith(scrollbars: widget.scrollbarOn ?? false),
child: SingleChildScrollView(child: widget.child),
),
),
);
}

View File

@@ -28,6 +28,12 @@ import 'package:mih_package_toolkit/src/mih_colors.dart';
/// )
/// ```
class MihTimeField extends StatefulWidget {
/// The primary color of the date picker
final Color? primaryColor;
/// The secondary color of the date picker
final Color? secondayColor;
/// The controller that stores and displays the selected time string (HH:mm).
final TextEditingController controller;
@@ -60,6 +66,8 @@ class MihTimeField extends StatefulWidget {
required this.controller,
required this.labelText,
required this.required,
this.primaryColor,
this.secondayColor,
this.width,
this.height,
this.borderRadius,
@@ -84,10 +92,95 @@ class _MihTimeFieldState extends State<MihTimeField> {
minute: int.tryParse(widget.controller.text.split(":")[1]) ?? 0,
)
: TimeOfDay.now(),
initialEntryMode: TimePickerEntryMode.dial,
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
child: child as Widget,
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ColorScheme.fromSeed(
seedColor: widget.primaryColor ??
MihColors.primary(darkMode: widget.darkMode),
primary: widget.secondayColor ??
MihColors.secondary(darkMode: widget.darkMode),
onPrimary: widget.primaryColor ??
MihColors.primary(darkMode: widget.darkMode),
surface: widget.secondayColor ??
MihColors.secondary(darkMode: widget.darkMode),
onSurface: widget.primaryColor ??
MihColors.primary(darkMode: widget.darkMode),
),
timePickerTheme: TimePickerThemeData(
helpTextStyle: TextStyle(
color: widget.secondayColor ??
MihColors.secondary(darkMode: widget.darkMode),
fontSize: 12,
letterSpacing: 0.8,
fontWeight: FontWeight.w500,
),
// The main dialog background
backgroundColor: widget.primaryColor ??
MihColors.primary(darkMode: widget.darkMode),
// The background of the clock dial
dialBackgroundColor: widget.primaryColor ??
MihColors.primary(darkMode: widget.darkMode),
dialTextColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return widget.primaryColor ??
MihColors.primary(
darkMode: widget
.darkMode); // number at selected position (inside the dot)
}
return widget.secondayColor ??
MihColors.secondary(
darkMode: widget.darkMode); // all other numbers
}),
// The color of the clock hand
dialHandColor: widget.secondayColor ??
MihColors.secondary(darkMode: widget.darkMode),
// The background color of the hour/minute input boxes
hourMinuteColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return widget.secondayColor ??
MihColors.secondary(
darkMode: widget
.darkMode); // lighter when selected (image 2 hour box)
}
return widget.primaryColor ??
MihColors.primary(
darkMode: widget
.darkMode); // lighter when selected (image 2 hour box)
}),
// The text color inside the hour/minute input boxes
hourMinuteTextColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return widget.primaryColor ??
MihColors.primary(
darkMode: widget
.darkMode); // lighter when selected (image 2 hour box)
}
return widget.secondayColor ??
MihColors.secondary(darkMode: widget.darkMode);
}),
// The color of the keyboard/clock toggle icon
entryModeIconColor: widget.secondayColor ??
MihColors.secondary(darkMode: widget.darkMode),
// Styles for AM/PM toggle (if not using 24h format)
dayPeriodColor: widget.secondayColor ??
MihColors.secondary(darkMode: widget.darkMode),
dayPeriodTextColor: widget.primaryColor ??
MihColors.primary(darkMode: widget.darkMode),
),
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: widget.secondayColor ??
MihColors.secondary(darkMode: widget.darkMode),
),
),
),
// Wrap your MediaQuery inside the child of the Theme
child: MediaQuery(
data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
child: child!,
),
);
},
);

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="jdk" jdkName="Android API 29 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart Packages" level="project" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
</component>
</module>

View File

@@ -1,10 +1,18 @@
name: mih_package_toolkit
description: "A comprehensive UI toolkit and utility library for building consistent MIH Packages within the MIH app ecosystem."
version: 0.0.1
description: "A comprehensive UI toolkit and utility library for building consistent MIH Packages within the MIH Project ecosystem."
version: 0.0.2
homepage: https://git.mzansi-innovation-hub.co.za/yaso_meth/mih_package_toolkit
repository: https://git.mzansi-innovation-hub.co.za/yaso_meth/mih_package_toolkit
issue_tracker: https://git.mzansi-innovation-hub.co.za/yaso_meth/mih_package_toolkit/issues
platforms:
android:
ios:
web:
linux:
macos:
windows:
environment:
sdk: ^3.0.0
flutter: ">=3.0.0"
@@ -26,4 +34,3 @@ flutter:
- family: MihIcons
fonts:
- asset: lib/src/fonts/Mih_Icons.ttf