mirror of
https://github.com/Iconica-Development/flutter_login_widget.git
synced 2025-05-18 21:23:44 +02:00
doc: create documentation for files
This commit is contained in:
parent
3ee3cc9461
commit
1a11692b5b
6 changed files with 334 additions and 22 deletions
194
CONTRIBUTING.md
Normal file
194
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,194 @@
|
|||
# Contributing
|
||||
First off, thanks for taking the time to contribute! ❤️
|
||||
|
||||
All types of contributions are encouraged and valued.
|
||||
See the [Table of Contents](#table-of-contents) for different ways to help and details about how we handle them.
|
||||
Please make sure to read the relevant section before making your contribution.
|
||||
It will make it a lot easier for us maintainers and smooth out the experience for all involved.
|
||||
Iconica looks forward to your contributions. 🎉
|
||||
|
||||
## Table of contents
|
||||
- [Code of conduct](#code-of-conduct)
|
||||
- [I Have a Question](#i-have-a-question)
|
||||
- [I Want To Contribute](#i-want-to-contribute)
|
||||
- [Reporting Bugs](#reporting-bugs)
|
||||
- [Contributing code](#contributing-code)
|
||||
|
||||
## Code of conduct
|
||||
|
||||
### Legal notice
|
||||
When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.
|
||||
All accepted pull requests and other additions to this project will be considered intellectual property of Iconica.
|
||||
|
||||
All repositories should be kept clean of jokes, easter eggs and other unnecessary additions.
|
||||
|
||||
## I have a question
|
||||
|
||||
If you want to ask a question, we assume that you have read the available documentation found within the code.
|
||||
Before you ask a question, it is best to search for existing issues that might help you.
|
||||
In case you have found a suitable issue but still need clarification, you can ask your question
|
||||
It is also advisable to search the internet for answers first.
|
||||
|
||||
If you then still feel the need to ask a question and need clarification, we recommend the following:
|
||||
|
||||
- Open an issue.
|
||||
- Provide as much context as you can about what you're running into.
|
||||
|
||||
We will then take care of the issue as soon as possible.
|
||||
|
||||
## I want to contribute
|
||||
|
||||
### Reporting bugs
|
||||
|
||||
<!-- omit in toc -->
|
||||
**Before submitting a bug report**
|
||||
|
||||
A good bug report shouldn't leave others needing to chase you up for more information.
|
||||
Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report.
|
||||
Please complete the following steps in advance to help us fix any potential bug as fast as possible.
|
||||
|
||||
- Make sure that you are using the latest version.
|
||||
- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (If you are looking for support, you might want to check [this section](#i-have-a-question)).
|
||||
- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error.
|
||||
- Also make sure to search the internet (including Stack Overflow) to see if users outside of Iconica have discussed the issue.
|
||||
- Collect information about the bug:
|
||||
- Stack trace (Traceback)
|
||||
- OS, Platform and Version (Windows, Linux, macOS, x86, ARM)
|
||||
- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant.
|
||||
- Time and date of occurance
|
||||
- Describe the expected result and actual result
|
||||
- Can you reliably reproduce the issue? And can you also reproduce it with older versions? Describe all steps that lead to the bug.
|
||||
|
||||
Once it's filed:
|
||||
|
||||
- The project team will label the issue accordingly.
|
||||
- A team member will try to reproduce the issue with your provided steps.
|
||||
If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for additional information.
|
||||
- If the team is able to reproduce the issue, it will be moved into the backlog, as well as marked with a priority, and the issue will be left to be [implemented by someone](#contributing-code).
|
||||
|
||||
### Contributing code
|
||||
|
||||
When you start working on your contribution, make sure you are aware of the relevant documentation and the functionality of the component you are working on.
|
||||
|
||||
When writing code, follow the style guidelines set by Dart: [Effective Dart](https://Dart.dev/guides/language/effective-Dart). This contains most information you will need to write clean Dart code that is well documented.
|
||||
|
||||
**Documentation**
|
||||
|
||||
As Effective Dart indicates, documenting your public methods with Dart doc comments is recommended.
|
||||
Aside from Effective Dart, we require specific information in the documentation of a method:
|
||||
|
||||
At the very least, your documentation should first name what the code does, then followed below by requirements for calling the method, the result of the method.
|
||||
Any references to internal variables or other methods should be done through [var] to indicate a reference.
|
||||
|
||||
If the method or class is complex enough (determined by the reviewers) an example is required.
|
||||
If unsure, add an example in the docs using code blocks.
|
||||
|
||||
For classes and methods, document the individual parameters with their implications.
|
||||
|
||||
> Tip: Remember that the shortest documentation can be written by having good descriptive names in the first place.
|
||||
|
||||
An example:
|
||||
```Dart
|
||||
library iconica_utilities.bidirectional_sorter;
|
||||
|
||||
part 'sorter.Dart';
|
||||
part 'enum.Dart';
|
||||
|
||||
/// Generic sort method, allow sorting of list with primitives or complex types.
|
||||
/// Uses [SortDirection] to determine the direction, either Ascending or Descending,
|
||||
/// Gets called on [List] toSort of type [T] which cannot be shorter than 2.
|
||||
/// Optionally for complex types a [Comparable] [Function] can be given to compare complex types.
|
||||
/// ```
|
||||
/// List<TestObject> objects = [];
|
||||
/// for (int i = 0; i < 10; i++) {
|
||||
/// objects.add(TestObject(name: "name", id: i));
|
||||
/// }
|
||||
///
|
||||
/// sort<TestObject>(
|
||||
/// SortDirection.descending, objects, (object) => object.id);
|
||||
///
|
||||
/// ```
|
||||
/// In the above example a list of TestObjects is created, and then sorted in descending order.
|
||||
/// If the implementation of TestObject is as following:
|
||||
/// ```
|
||||
/// class TestObject {
|
||||
/// final String name;
|
||||
/// final int id;
|
||||
///
|
||||
/// TestObject({required this.name, required this.id});
|
||||
/// }
|
||||
/// ```
|
||||
/// And the list is logged to the console, the following will appear:
|
||||
/// ```
|
||||
/// [name9, name8, name7, name6, name5, name4, name3, name2, name1, name0]
|
||||
/// ```
|
||||
|
||||
void sort<T>(
|
||||
/// Determines the sorting direction, can be either Ascending or Descending
|
||||
SortDirection sortDirection,
|
||||
|
||||
/// Incoming list, which gets sorted
|
||||
List<T> toSort, [
|
||||
|
||||
/// Optional comparable, which is only necessary for complex types
|
||||
SortFieldGetter<T>? sortValueCallback,
|
||||
]) {
|
||||
if (toSort.length < 2) return;
|
||||
assert(
|
||||
toSort.whereType<Comparable>().isNotEmpty || sortValueCallback != null);
|
||||
BidirectionalSorter<T>(
|
||||
sortInstructions: <SortInstruction<T>>[
|
||||
SortInstruction(
|
||||
sortValueCallback ?? (t) => t as Comparable, sortDirection),
|
||||
],
|
||||
).sort(toSort);
|
||||
}
|
||||
|
||||
/// same functionality as [sort] but with the added functionality
|
||||
/// of sorting multiple values
|
||||
void sortMulti<T>(
|
||||
/// Incoming list, which gets sorted
|
||||
List<T> toSort,
|
||||
|
||||
/// list of comparables to sort multiple values at once,
|
||||
/// priority based on index
|
||||
List<SortInstruction<T>> sortValueCallbacks,
|
||||
) {
|
||||
if (toSort.length < 2) return;
|
||||
assert(sortValueCallbacks.isNotEmpty);
|
||||
BidirectionalSorter<T>(
|
||||
sortInstructions: sortValueCallbacks,
|
||||
).sort(toSort);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
**Tests**
|
||||
|
||||
For each public method that was created, excluding widgets, which contains any form of logic (e.g. Calculations, predicates or major side-effects) tests are required.
|
||||
|
||||
A set of tests is written for each method, covering at least each path within the method. For example:
|
||||
|
||||
```Dart
|
||||
void foo() {
|
||||
try {
|
||||
var bar = doSomething();
|
||||
if (bar) {
|
||||
doSomethingElse();
|
||||
} else {
|
||||
doSomethingCool();
|
||||
}
|
||||
} catch (_) {
|
||||
displayError();
|
||||
}
|
||||
}
|
||||
```
|
||||
The method above should result in 3 tests:
|
||||
|
||||
1. A test for the path leading to displayError by the cause of an exception
|
||||
2. A test for if bar is true, resulting in doSomethingElse()
|
||||
3. A test for if bar is false, resulting in the doSomethingCool() method being called.
|
||||
|
||||
This means that we require 100% coverage of each method you test.
|
|
@ -58,17 +58,17 @@ packages:
|
|||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
|
||||
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "2.0.3"
|
||||
flutter_login:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: ".."
|
||||
relative: true
|
||||
source: path
|
||||
version: "5.1.1"
|
||||
version: "5.1.4"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -79,54 +79,78 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.0"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
sha256: "5cfd6509652ff5e7fe149b6df4859e687fca9048437857cb2e65c8d780f396e3"
|
||||
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
||||
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.16"
|
||||
version: "0.12.16+1"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "0.8.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
version: "1.11.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.3"
|
||||
version: "1.9.0"
|
||||
pinput:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pinput
|
||||
sha256: "1773743c188cdd2f8d0398ea708ec72645bb41ac9311755c4f7bb03a4184bdcf"
|
||||
sha256: "543da5bfdefd9e06914a12100f8c9156f84cef3efc14bca507c49e966c5b813b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.31"
|
||||
version: "2.3.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -136,10 +160,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: smart_auth
|
||||
sha256: "8cfaec55b77d5930ed1666bb7ae70db5bade099bb1422401386853b400962113"
|
||||
sha256: a25229b38c02f733d0a4e98d941b42bed91a976cb589e934895e60ccfa674cf6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
version: "1.1.1"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -204,14 +228,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
web:
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
|
||||
name: vm_service
|
||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
version: "13.0.0"
|
||||
sdks:
|
||||
dart: ">=3.2.0-194.0.dev <4.0.0"
|
||||
dart: ">=3.2.0-0 <4.0.0"
|
||||
flutter: ">=3.7.0"
|
||||
|
|
|
@ -31,15 +31,31 @@ class LoginOptions {
|
|||
this.showObscurePassword = true,
|
||||
});
|
||||
|
||||
/// Builds the login button.
|
||||
final ButtonBuilder loginButtonBuilder;
|
||||
|
||||
/// Builds the registration button.
|
||||
final ButtonBuilder registrationButtonBuilder;
|
||||
|
||||
/// Builds the forgot password button.
|
||||
final ButtonBuilder forgotPasswordButtonBuilder;
|
||||
|
||||
/// Builds the request forgot password button.
|
||||
final ButtonBuilder requestForgotPasswordButtonBuilder;
|
||||
|
||||
/// Builds the email input container.
|
||||
final InputContainerBuilder emailInputContainerBuilder;
|
||||
|
||||
/// Builds the password input container.
|
||||
final InputContainerBuilder passwordInputContainerBuilder;
|
||||
|
||||
/// The image to display on the login screen.
|
||||
final Widget? image;
|
||||
|
||||
/// The title widget to display on the login screen.
|
||||
final Widget? title;
|
||||
|
||||
/// The subtitle widget to display on the login screen.
|
||||
final Widget? subtitle;
|
||||
|
||||
/// Option to modify the spacing between the title, subtitle, image, form,
|
||||
|
@ -49,16 +65,34 @@ class LoginOptions {
|
|||
/// Maximum width of the form. Defaults to 400.
|
||||
final double? maxFormWidth;
|
||||
|
||||
/// Decoration for the email input field.
|
||||
final InputDecoration emailDecoration;
|
||||
|
||||
/// Decoration for the password input field.
|
||||
final InputDecoration passwordDecoration;
|
||||
|
||||
/// The initial email value for the email input field.
|
||||
final String initialEmail;
|
||||
|
||||
/// The initial password value for the password input field.
|
||||
final String initialPassword;
|
||||
|
||||
/// The text style for the email input field.
|
||||
final TextStyle? emailTextStyle;
|
||||
|
||||
/// The text style for the password input field.
|
||||
final TextStyle? passwordTextStyle;
|
||||
|
||||
/// Translations for various texts on the login screen.
|
||||
final LoginTranslations translations;
|
||||
|
||||
/// The validation service used for validating email and password inputs.
|
||||
final ValidationService? validationService;
|
||||
|
||||
/// Determines whether the password field should be obscured.
|
||||
final bool showObscurePassword;
|
||||
|
||||
/// Get validations.
|
||||
ValidationService get validations =>
|
||||
validationService ?? LoginValidationService(this);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,13 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_login/flutter_login.dart';
|
||||
|
||||
class EmailPasswordLoginForm extends StatefulWidget {
|
||||
/// Constructs an [EmailPasswordLoginForm] widget.
|
||||
///
|
||||
/// [onLogin]: Callback function for user login.
|
||||
/// [onForgotPassword]: Callback function for when the user
|
||||
/// forgets their password.
|
||||
/// [onRegister]: Callback function for user registration.
|
||||
/// [options]: The options for configuring the login form.
|
||||
const EmailPasswordLoginForm({
|
||||
required this.onLogin,
|
||||
super.key,
|
||||
|
|
|
@ -4,6 +4,13 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_login/flutter_login.dart';
|
||||
|
||||
class ForgotPasswordForm extends StatefulWidget {
|
||||
/// Constructs a [ForgotPasswordForm] widget.
|
||||
///
|
||||
/// [options]: The options for configuring the forgot password form.
|
||||
/// [description]: Widget to display description.
|
||||
/// [onRequestForgotPassword]: Callback function for requesting
|
||||
/// password reset.
|
||||
/// [title]: Widget to display title.
|
||||
const ForgotPasswordForm({
|
||||
required this.options,
|
||||
required this.description,
|
||||
|
|
|
@ -2,6 +2,23 @@ import 'package:flutter/material.dart';
|
|||
import 'package:pinput/pinput.dart';
|
||||
|
||||
class MFAWidget extends StatefulWidget {
|
||||
/// Constructs an [MFAWidget].
|
||||
///
|
||||
/// [onCompleted]: Callback function triggered when the MFA code is completed.
|
||||
/// [onSubmitted]: Callback function triggered when the MFA code is submitted.
|
||||
/// [length]: The length of the MFA code.
|
||||
/// [defaultPinTheme]: The theme for the default state of the input pins.
|
||||
/// [focusedPinTheme]: The theme for the focused state of the input pins.
|
||||
/// [submittedPinTheme]: The theme for the submitted state of the input pins.
|
||||
/// [followingPinTheme]: The theme for the pins following the submitted pin.
|
||||
/// [disabledPinTheme]: The theme for disabled input pins.
|
||||
/// [errorPinTheme]: The theme for input pins in error state.
|
||||
/// [seperatorPositions]: Positions for separators between input pins.
|
||||
/// [errorText]: Text to display when there's an error.
|
||||
/// [validator]: Validator function to validate the input.
|
||||
/// [errorBuilder]: Builder function to customize the error display.
|
||||
/// [errorTextStyle]: Style for the error text.
|
||||
/// [submitButtonBuilder]: Builder function to customize the submit button.
|
||||
const MFAWidget({
|
||||
required this.onCompleted,
|
||||
this.onSubmitted,
|
||||
|
@ -26,20 +43,49 @@ class MFAWidget extends StatefulWidget {
|
|||
' not null',
|
||||
);
|
||||
|
||||
/// Callback function triggered when the MFA code is completed.
|
||||
final Function(String code) onCompleted;
|
||||
|
||||
/// Callback function triggered when the MFA code is submitted.
|
||||
final Function(String code)? onSubmitted;
|
||||
|
||||
/// The length of the MFA code.
|
||||
final int length;
|
||||
|
||||
/// The theme for the default state of the input pins.
|
||||
final PinTheme? defaultPinTheme;
|
||||
|
||||
/// The theme for the focused state of the input pins.
|
||||
final PinTheme? focusedPinTheme;
|
||||
|
||||
/// The theme for the submitted state of the input pins.
|
||||
final PinTheme? submittedPinTheme;
|
||||
|
||||
/// The theme for the pins following the submitted pin.
|
||||
final PinTheme? followingPinTheme;
|
||||
|
||||
/// The theme for disabled input pins.
|
||||
final PinTheme? disabledPinTheme;
|
||||
|
||||
/// The theme for input pins in error state.
|
||||
final PinTheme? errorPinTheme;
|
||||
|
||||
/// Positions for separators between input pins.
|
||||
final List<int>? seperatorPositions;
|
||||
|
||||
/// Text to display when there's an error.
|
||||
final String? errorText;
|
||||
|
||||
/// Validator function to validate the input.
|
||||
final String? Function(String?)? validator;
|
||||
|
||||
/// Builder function to customize the error display.
|
||||
final Widget Function(String?, String)? errorBuilder;
|
||||
|
||||
/// Style for the error text.
|
||||
final TextStyle? errorTextStyle;
|
||||
|
||||
/// Builder function to customize the submit button.
|
||||
final Widget Function(Function onTap)? submitButtonBuilder;
|
||||
|
||||
@override
|
||||
|
|
Loading…
Reference in a new issue