mirror of
https://github.com/Iconica-Development/flutter_input_library.git
synced 2025-05-19 09:23:43 +02:00
Compare commits
25 commits
Author | SHA1 | Date | |
---|---|---|---|
|
7d64f467bf | ||
|
de5d38ffc7 | ||
|
0da6ba35f2 | ||
|
5bee01e304 | ||
|
f2d1fb5262 | ||
|
815ca7b0b2 | ||
|
b6de3299e0 | ||
|
bc8b1d572b | ||
|
e505662e2f | ||
|
59c3568e0c | ||
|
9838220de7 | ||
|
04752e9a53 | ||
|
cdc06bbb79 | ||
|
d74c702fa7 | ||
|
fbc64dcc23 | ||
|
f30634508e | ||
|
f970719da2 | ||
|
e6ea668b80 | ||
|
6b952ae230 | ||
|
f09037b850 | ||
|
fddf100fb0 | ||
|
8e8fe01467 | ||
|
919f461125 | ||
|
f6ecacc69a | ||
|
e900f4ada5 |
40 changed files with 8267 additions and 209 deletions
14
.github/workflows/release.yml
vendored
Normal file
14
.github/workflows/release.yml
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
name: Iconica Standard Component Release Workflow
|
||||||
|
# Workflow Caller version: 1.0.0
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
call-global-iconica-workflow:
|
||||||
|
uses: Iconica-Development/.github/.github/workflows/component-release.yml@master
|
||||||
|
secrets: inherit
|
||||||
|
permissions: write-all
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -35,3 +35,7 @@ example/windows
|
||||||
example/web
|
example/web
|
||||||
example/android
|
example/android
|
||||||
example/ios
|
example/ios
|
||||||
|
|
||||||
|
# FVM Version Cache
|
||||||
|
.fvm/
|
||||||
|
.fvmrc
|
||||||
|
|
116
CHANGELOG.md
116
CHANGELOG.md
|
@ -1,71 +1,97 @@
|
||||||
## 0.0.1
|
## 3.7.0
|
||||||
|
|
||||||
* Initial release, retrieved inputs from flutter_form
|
* Added a 16 pixel padding between the `FlutterFormInputRadioPicker` items that is customizable with the `itemSpacing` parameter.
|
||||||
|
|
||||||
## 1.0.0
|
## 3.6.0
|
||||||
|
* Added style parameter to `FlutterFormInputMultiLine`
|
||||||
|
* Upgrade flutter_iconica_analysis to 7.0.0
|
||||||
|
* Changed the name of the `CarouselController` to `FlutterInputCarouselController`
|
||||||
|
|
||||||
* enforce 24h clock in the time picker because it can caused a bug on web
|
## 3.5.0
|
||||||
|
* Added `selectableTimePredicate` to the `DateTimeInputField` constructor
|
||||||
|
|
||||||
## 1.0.1
|
## 3.4.0
|
||||||
|
* Added `FlutterFormInputDropdown`
|
||||||
|
|
||||||
* add decoration option for datetime input fields
|
## 3.3.1
|
||||||
|
* Loosened the dependen on intl to be more compatible with several Flutter versions
|
||||||
|
|
||||||
## 1.0.3
|
## 3.3.0
|
||||||
|
* Added `FlutterFormInputRadioPicker`
|
||||||
|
* Changed the `FlutterFormInputNumberPicker` and added axis parameter.
|
||||||
|
* Changed the formating of the result value of the `showDateRangePicker`.
|
||||||
|
|
||||||
* add FocusNode option for input fields
|
## 3.2.1
|
||||||
|
* Added `PhoneNumber` model to save the `FlutterFormInputPhone` result.
|
||||||
|
* Added more customization for `FlutterFormInputPhone`.
|
||||||
|
|
||||||
## 1.0.4
|
## 3.2.0
|
||||||
* fix datetimepicker format and validator
|
* Added `FlutterFormInputPhone`
|
||||||
|
|
||||||
## 1.0.5
|
## 3.1.0
|
||||||
* add style to datetime
|
* `FlutterFormInputPassword` now has the controller parameter to set the `TextEditingController` of the `TextFormField`
|
||||||
|
|
||||||
## 1.0.6
|
## 3.0.0
|
||||||
* add initial timepicker parameter
|
* Updated the FlutterFormInputSwitch to FlutterFormInputBool. This now includes a parameter to either show a checkbox or switch
|
||||||
|
|
||||||
## 2.0.0
|
## 2.7.1
|
||||||
* remove 'riverpod' dependency
|
* Added Iconica CI and Iconica Linter
|
||||||
|
|
||||||
## 2.1.0
|
## 2.7.0
|
||||||
* make compatible with flutter 3.10
|
* Addition of 'decoration' parameter to 'FlutterFormInputPassword'
|
||||||
|
|
||||||
## 2.2.0
|
## 2.6.1
|
||||||
* Dateformat optional on input from the user, defaulting to 24 hour format
|
* Addition of 'obscureText' parameter to 'FlutterFormInputPlainText'
|
||||||
|
|
||||||
## 2.2.1
|
## 2.6.0
|
||||||
* Initial time optional on input from the user, defaulting to current time
|
* Addition of the `textCapitalization` parameter to `FlutterFormInputPlainText` and `FlutterFormInputMultiLine`.
|
||||||
|
|
||||||
## 2.3.0
|
## 2.5.2
|
||||||
* The ability to set the enabled parameter of TextFormFields
|
* Addition of `style` parameter to `FlutterFormInputPassword` widget.
|
||||||
|
|
||||||
## 2.4.0
|
|
||||||
* The ability to disable the onTap paramater of the DatePicker
|
|
||||||
* FlutterFormInputDateTime now also had the enabled parameter to provide to DateTimeInputField
|
|
||||||
|
|
||||||
## 2.5.0
|
|
||||||
* Addition of the ScrollPicker input field.
|
|
||||||
|
|
||||||
## 2.5.1
|
## 2.5.1
|
||||||
* Addition of `formatInputs` parameter to `FlutterFormInputPlainText` widget.
|
* Addition of `formatInputs` parameter to `FlutterFormInputPlainText` widget.
|
||||||
* Addition of `formatInputs` parameter to `FlutterFormInputPassword` widget.
|
* Addition of `formatInputs` parameter to `FlutterFormInputPassword` widget.
|
||||||
|
|
||||||
## 2.5.2
|
## 2.5.0
|
||||||
* Addition of `style` parameter to `FlutterFormInputPassword` widget.
|
* Addition of the ScrollPicker input field.
|
||||||
|
|
||||||
## 2.6.0
|
## 2.4.0
|
||||||
* Addition of the `textCapitalization` parameter to `FlutterFormInputPlainText` and `FlutterFormInputMultiLine`.
|
* The ability to disable the onTap paramater of the DatePicker
|
||||||
|
* FlutterFormInputDateTime now also had the enabled parameter to provide to DateTimeInputField
|
||||||
|
|
||||||
## 2.6.1
|
## 2.3.0
|
||||||
* Addition of 'obscureText' parameter to 'FlutterFormInputPlainText'
|
* The ability to set the enabled parameter of TextFormFields
|
||||||
|
|
||||||
## 2.7.0
|
## 2.2.1
|
||||||
* Addition of 'decoration' parameter to 'FlutterFormInputPassword'
|
* Initial time optional on input from the user, defaulting to current time
|
||||||
|
|
||||||
## 2.7.1
|
## 2.2.0
|
||||||
* Added Iconica CI and Iconica Linter
|
* Dateformat optional on input from the user, defaulting to 24 hour format
|
||||||
|
|
||||||
## 3.0.0
|
## 2.1.0
|
||||||
* Updated the FlutterFormInputSwitch to FlutterFormInputBool. This now includes a parameter to either show a checkbox or switch
|
* make compatible with flutter 3.10
|
||||||
|
|
||||||
## 3.1.0
|
## 2.0.0
|
||||||
* `FlutterFormInputPassword` now has the controller parameter to set the `TextEditingController` of the `TextFormField`
|
* remove 'riverpod' dependency
|
||||||
|
|
||||||
|
## 1.0.6
|
||||||
|
* add initial timepicker parameter
|
||||||
|
|
||||||
|
## 1.0.5
|
||||||
|
* add style to datetime
|
||||||
|
|
||||||
|
## 1.0.4
|
||||||
|
* fix datetimepicker format and validator
|
||||||
|
|
||||||
|
## 1.0.3
|
||||||
|
* add FocusNode option for input fields
|
||||||
|
|
||||||
|
## 1.0.1
|
||||||
|
* add decoration option for datetime input fields
|
||||||
|
|
||||||
|
## 1.0.0
|
||||||
|
* enforce 24h clock in the time picker because it can caused a bug on web
|
||||||
|
|
||||||
|
## 0.0.1
|
||||||
|
* Initial release, retrieved inputs from flutter_form
|
||||||
|
|
|
@ -53,6 +53,16 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
Container(height: 10),
|
||||||
|
const Text('FlutterFormInputPhone'),
|
||||||
|
SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
child: FlutterFormInputPhone(
|
||||||
|
onChanged: (v) {
|
||||||
|
debugPrint('Phone number: $v');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
Container(height: 10),
|
Container(height: 10),
|
||||||
const Text('FlutterFormInputBool'),
|
const Text('FlutterFormInputBool'),
|
||||||
FlutterFormInputBool(
|
FlutterFormInputBool(
|
||||||
|
|
|
@ -45,10 +45,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
|
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.5"
|
version: "1.0.8"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -68,15 +68,15 @@ packages:
|
||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "3.0.0"
|
version: "3.6.0"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
|
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.3"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -86,50 +86,74 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.1"
|
version: "0.19.0"
|
||||||
|
leak_tracker:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker
|
||||||
|
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "10.0.4"
|
||||||
|
leak_tracker_flutter_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_flutter_testing
|
||||||
|
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.3"
|
||||||
|
leak_tracker_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_testing
|
||||||
|
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
|
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.1.1"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.16"
|
version: "0.12.16+1"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.0"
|
version: "0.8.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0"
|
version: "1.12.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.3"
|
version: "1.9.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -179,10 +203,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.1"
|
version: "0.7.0"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -191,14 +215,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
web:
|
vm_service:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web
|
name: vm_service
|
||||||
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
|
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.0"
|
version: "14.2.1"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.2.0-194.0.dev <4.0.0"
|
dart: ">=3.3.0 <4.0.0"
|
||||||
flutter: ">=1.17.0"
|
flutter: ">=3.18.0-18.0.pre.54"
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
/// A library for creating input fields in Flutter.
|
/// A library for creating input fields in Flutter.
|
||||||
library flutter_input_library;
|
library flutter_input_library;
|
||||||
|
|
||||||
export 'src/inputs/inputs.dart';
|
export "src/inputs/inputs.dart";
|
||||||
export 'src/utils/utils.dart';
|
export "src/utils/utils.dart";
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
// ignore_for_file: avoid_positional_boolean_parameters
|
// ignore_for_file: avoid_positional_boolean_parameters
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
|
|
||||||
import 'package:flutter_input_library/src/inputs/bool/bool_field.dart';
|
import "package:flutter_input_library/src/inputs/bool/bool_field.dart";
|
||||||
|
|
||||||
class FlutterFormInputBool extends StatelessWidget {
|
class FlutterFormInputBool extends StatelessWidget {
|
||||||
const FlutterFormInputBool({
|
const FlutterFormInputBool({
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
// ignore_for_file: avoid_positional_boolean_parameters
|
// ignore_for_file: avoid_positional_boolean_parameters
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter_input_library/flutter_input_library.dart';
|
import "package:flutter_input_library/flutter_input_library.dart";
|
||||||
|
|
||||||
class BoolFormField extends FormField<bool> {
|
class BoolFormField extends FormField<bool> {
|
||||||
BoolFormField({
|
BoolFormField({
|
||||||
|
@ -85,7 +85,6 @@ class _BoolWidgetState extends State<BoolWidget> {
|
||||||
focusNode: widget.focusNode,
|
focusNode: widget.focusNode,
|
||||||
onChanged: onChanged,
|
onChanged: onChanged,
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
|
|
||||||
case BoolWidgetType.checkbox:
|
case BoolWidgetType.checkbox:
|
||||||
child = Checkbox(
|
child = Checkbox(
|
||||||
|
@ -97,7 +96,6 @@ class _BoolWidgetState extends State<BoolWidget> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
|
|
||||||
import 'package:flutter_input_library/src/inputs/carousel/carousel_form.dart';
|
import "package:flutter_input_library/src/inputs/carousel/carousel_form.dart";
|
||||||
|
|
||||||
class FlutterFormInputCarousel extends StatelessWidget {
|
class FlutterFormInputCarousel extends StatelessWidget {
|
||||||
const FlutterFormInputCarousel({
|
const FlutterFormInputCarousel({
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'dart:async';
|
import "dart:async";
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/carousel/carousel_options.dart';
|
import "package:flutter_input_library/src/inputs/carousel/carousel_options.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/carousel/carousel_state.dart';
|
import "package:flutter_input_library/src/inputs/carousel/carousel_state.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/carousel/carousel_utils.dart';
|
import "package:flutter_input_library/src/inputs/carousel/carousel_utils.dart";
|
||||||
|
|
||||||
abstract class CarouselController {
|
abstract class FlutterInputCarouselController {
|
||||||
factory CarouselController() => CarouselControllerImpl();
|
factory FlutterInputCarouselController() => CarouselControllerImpl();
|
||||||
bool get ready;
|
bool get ready;
|
||||||
|
|
||||||
Future<void> get onReady;
|
Future<void> get onReady;
|
||||||
|
@ -28,7 +28,7 @@ abstract class CarouselController {
|
||||||
void stopAutoPlay();
|
void stopAutoPlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
class CarouselControllerImpl implements CarouselController {
|
class CarouselControllerImpl implements FlutterInputCarouselController {
|
||||||
final Completer<void> _readyCompleter = Completer<void>();
|
final Completer<void> _readyCompleter = Completer<void>();
|
||||||
|
|
||||||
CarouselState? _state;
|
CarouselState? _state;
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/carousel/carousel_slider.dart';
|
import "package:flutter_input_library/src/inputs/carousel/carousel_slider.dart";
|
||||||
|
|
||||||
class CarouselFormField extends FormField<int> {
|
class CarouselFormField extends FormField<int> {
|
||||||
CarouselFormField({
|
CarouselFormField({
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
|
|
||||||
enum CarouselPageChangedReason { timed, manual, controller }
|
enum CarouselPageChangedReason { timed, manual, controller }
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,17 @@
|
||||||
///
|
///
|
||||||
library carousel_slider;
|
library carousel_slider;
|
||||||
|
|
||||||
import 'dart:async';
|
import "dart:async";
|
||||||
|
|
||||||
import 'package:flutter/gestures.dart';
|
import "package:flutter/gestures.dart";
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/carousel/carousel_controller.dart';
|
import "package:flutter_input_library/src/inputs/carousel/carousel_controller.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/carousel/carousel_options.dart';
|
import "package:flutter_input_library/src/inputs/carousel/carousel_options.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/carousel/carousel_state.dart';
|
import "package:flutter_input_library/src/inputs/carousel/carousel_state.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/carousel/carousel_utils.dart';
|
import "package:flutter_input_library/src/inputs/carousel/carousel_utils.dart";
|
||||||
|
|
||||||
export 'carousel_controller.dart';
|
export "carousel_controller.dart";
|
||||||
export 'carousel_options.dart';
|
export "carousel_options.dart";
|
||||||
|
|
||||||
typedef ExtendedIndexedWidgetBuilder = Widget Function(
|
typedef ExtendedIndexedWidgetBuilder = Widget Function(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
|
@ -26,25 +26,25 @@ class CarouselSlider extends StatefulWidget {
|
||||||
CarouselSlider({
|
CarouselSlider({
|
||||||
required this.items,
|
required this.items,
|
||||||
required this.options,
|
required this.options,
|
||||||
CarouselController? carouselController,
|
FlutterInputCarouselController? carouselController,
|
||||||
super.key,
|
super.key,
|
||||||
}) : itemBuilder = null,
|
}) : itemBuilder = null,
|
||||||
itemCount = items != null ? items.length : 0,
|
itemCount = items != null ? items.length : 0,
|
||||||
_carouselController = carouselController != null
|
_carouselController = carouselController != null
|
||||||
? carouselController as CarouselControllerImpl
|
? carouselController as CarouselControllerImpl
|
||||||
: CarouselController() as CarouselControllerImpl;
|
: FlutterInputCarouselController() as CarouselControllerImpl;
|
||||||
|
|
||||||
/// The on demand item builder constructor/
|
/// The on demand item builder constructor/
|
||||||
CarouselSlider.builder({
|
CarouselSlider.builder({
|
||||||
required this.itemCount,
|
required this.itemCount,
|
||||||
required this.itemBuilder,
|
required this.itemBuilder,
|
||||||
required this.options,
|
required this.options,
|
||||||
CarouselController? carouselController,
|
FlutterInputCarouselController? carouselController,
|
||||||
super.key,
|
super.key,
|
||||||
}) : items = null,
|
}) : items = null,
|
||||||
_carouselController = carouselController != null
|
_carouselController = carouselController != null
|
||||||
? carouselController as CarouselControllerImpl
|
? carouselController as CarouselControllerImpl
|
||||||
: CarouselController() as CarouselControllerImpl;
|
: FlutterInputCarouselController() as CarouselControllerImpl;
|
||||||
|
|
||||||
/// [CarouselOptions] to create a [CarouselState] with.
|
/// [CarouselOptions] to create a [CarouselState] with.
|
||||||
final CarouselOptions options;
|
final CarouselOptions options;
|
||||||
|
@ -81,6 +81,7 @@ class CarouselSliderState extends State<CarouselSlider>
|
||||||
/// [mode] is related to why the page is being changed.
|
/// [mode] is related to why the page is being changed.
|
||||||
CarouselPageChangedReason mode = CarouselPageChangedReason.controller;
|
CarouselPageChangedReason mode = CarouselPageChangedReason.controller;
|
||||||
|
|
||||||
|
// ignore: use_setters_to_change_properties
|
||||||
void changeMode(CarouselPageChangedReason mode) {
|
void changeMode(CarouselPageChangedReason mode) {
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/carousel/carousel_slider.dart';
|
import "package:flutter_input_library/src/inputs/carousel/carousel_slider.dart";
|
||||||
|
|
||||||
class CarouselState {
|
class CarouselState {
|
||||||
CarouselState(
|
CarouselState(
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/date_picker/date_picker_field.dart';
|
import "package:flutter_input_library/src/inputs/date_picker/date_picker_field.dart";
|
||||||
import 'package:intl/intl.dart';
|
import "package:intl/intl.dart";
|
||||||
|
|
||||||
enum FlutterFormDateTimeType {
|
enum FlutterFormDateTimeType {
|
||||||
date,
|
date,
|
||||||
|
@ -36,6 +36,7 @@ class FlutterFormInputDateTime extends StatelessWidget {
|
||||||
this.timePickerEntryMode = TimePickerEntryMode.dial,
|
this.timePickerEntryMode = TimePickerEntryMode.dial,
|
||||||
this.enabled = true,
|
this.enabled = true,
|
||||||
this.onTapEnabled = true,
|
this.onTapEnabled = true,
|
||||||
|
this.selectableTimePredicate,
|
||||||
});
|
});
|
||||||
final TextStyle? style;
|
final TextStyle? style;
|
||||||
final InputDecoration? decoration;
|
final InputDecoration? decoration;
|
||||||
|
@ -57,6 +58,7 @@ class FlutterFormInputDateTime extends StatelessWidget {
|
||||||
final TimePickerEntryMode timePickerEntryMode;
|
final TimePickerEntryMode timePickerEntryMode;
|
||||||
final bool enabled;
|
final bool enabled;
|
||||||
final bool onTapEnabled;
|
final bool onTapEnabled;
|
||||||
|
final bool Function(DateTime)? selectableTimePredicate;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => DateTimeInputField(
|
Widget build(BuildContext context) => DateTimeInputField(
|
||||||
|
@ -80,5 +82,6 @@ class FlutterFormInputDateTime extends StatelessWidget {
|
||||||
timePickerEntryMode: timePickerEntryMode,
|
timePickerEntryMode: timePickerEntryMode,
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
onTapEnabled: onTapEnabled,
|
onTapEnabled: onTapEnabled,
|
||||||
|
selectableDayPredicate: selectableTimePredicate,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'dart:async';
|
import "dart:async";
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/date_picker/date_picker.dart';
|
import "package:flutter_input_library/src/inputs/date_picker/date_picker.dart";
|
||||||
import 'package:intl/intl.dart';
|
import "package:intl/intl.dart";
|
||||||
|
|
||||||
class DateTimeInputField extends StatefulWidget {
|
class DateTimeInputField extends StatefulWidget {
|
||||||
const DateTimeInputField({
|
const DateTimeInputField({
|
||||||
|
@ -31,6 +31,7 @@ class DateTimeInputField extends StatefulWidget {
|
||||||
this.validator,
|
this.validator,
|
||||||
this.enabled = true,
|
this.enabled = true,
|
||||||
this.onTapEnabled = true,
|
this.onTapEnabled = true,
|
||||||
|
this.selectableDayPredicate,
|
||||||
});
|
});
|
||||||
final TextStyle? style;
|
final TextStyle? style;
|
||||||
final InputDecoration? decoration;
|
final InputDecoration? decoration;
|
||||||
|
@ -52,6 +53,7 @@ class DateTimeInputField extends StatefulWidget {
|
||||||
final TimePickerEntryMode timePickerEntryMode;
|
final TimePickerEntryMode timePickerEntryMode;
|
||||||
final bool enabled;
|
final bool enabled;
|
||||||
final bool onTapEnabled;
|
final bool onTapEnabled;
|
||||||
|
final bool Function(DateTime)? selectableDayPredicate;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<DateTimeInputField> createState() => _DateInputFieldState();
|
State<DateTimeInputField> createState() => _DateInputFieldState();
|
||||||
|
@ -63,7 +65,7 @@ class _DateInputFieldState extends State<DateTimeInputField> {
|
||||||
late final DateTime initialDate;
|
late final DateTime initialDate;
|
||||||
late final DateTimeRange initialDateRange;
|
late final DateTimeRange initialDateRange;
|
||||||
late final TimeOfDay? initialTime;
|
late final TimeOfDay? initialTime;
|
||||||
String currentValue = '';
|
String currentValue = "";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -95,31 +97,34 @@ class _DateInputFieldState extends State<DateTimeInputField> {
|
||||||
FlutterFormDateTimeType inputType, [
|
FlutterFormDateTimeType inputType, [
|
||||||
DateFormat? dateFormat,
|
DateFormat? dateFormat,
|
||||||
]) async {
|
]) async {
|
||||||
var userInput = '';
|
var userInput = "";
|
||||||
switch (inputType) {
|
switch (inputType) {
|
||||||
case FlutterFormDateTimeType.date:
|
case FlutterFormDateTimeType.date:
|
||||||
|
if (context.mounted) {
|
||||||
var unformatted = await showDatePicker(
|
var unformatted = await showDatePicker(
|
||||||
initialDate: initialDate,
|
initialDate: initialDate,
|
||||||
context: context,
|
context: context,
|
||||||
firstDate: firstDate,
|
firstDate: firstDate,
|
||||||
lastDate: lastDate,
|
lastDate: lastDate,
|
||||||
|
selectableDayPredicate: widget.selectableDayPredicate,
|
||||||
);
|
);
|
||||||
userInput = unformatted != null
|
userInput = unformatted != null
|
||||||
? widget.dateFormat.format(unformatted)
|
? widget.dateFormat.format(unformatted)
|
||||||
: userInput;
|
: userInput;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case FlutterFormDateTimeType.dateTime:
|
case FlutterFormDateTimeType.dateTime:
|
||||||
await getInputFromUser(FlutterFormDateTimeType.date)
|
await getInputFromUser(FlutterFormDateTimeType.date)
|
||||||
.then((value) async {
|
.then((value) async {
|
||||||
if (value != '') {
|
if (value != "") {
|
||||||
var secondInput =
|
var secondInput =
|
||||||
await getInputFromUser(FlutterFormDateTimeType.time);
|
await getInputFromUser(FlutterFormDateTimeType.time);
|
||||||
if (secondInput != '') {
|
if (secondInput != "") {
|
||||||
var date = widget.dateFormat.parse(value);
|
var date = widget.dateFormat.parse(value);
|
||||||
var time = dateFormat != null
|
var time = dateFormat != null
|
||||||
? dateFormat.parse('01 01 1970 $secondInput')
|
? dateFormat.parse("01 01 1970 $secondInput")
|
||||||
: DateFormat('dd MM yyyy HH:mm')
|
: DateFormat("dd MM yyyy HH:mm")
|
||||||
.parse('01 01 1970 $secondInput');
|
.parse("01 01 1970 $secondInput");
|
||||||
userInput = widget.dateFormat.format(
|
userInput = widget.dateFormat.format(
|
||||||
DateTime(
|
DateTime(
|
||||||
date.year,
|
date.year,
|
||||||
|
@ -132,7 +137,7 @@ class _DateInputFieldState extends State<DateTimeInputField> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
|
||||||
case FlutterFormDateTimeType.range:
|
case FlutterFormDateTimeType.range:
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
userInput = await showDateRangePicker(
|
userInput = await showDateRangePicker(
|
||||||
|
@ -142,13 +147,14 @@ class _DateInputFieldState extends State<DateTimeInputField> {
|
||||||
initialDateRange: initialDateRange,
|
initialDateRange: initialDateRange,
|
||||||
).then(
|
).then(
|
||||||
(value) => value != null
|
(value) => value != null
|
||||||
? '${widget.dateFormat.format(value.start)} -'
|
? "${widget.dateFormat.format(value.start)} - "
|
||||||
'${widget.dateFormat.format(value.end)}'
|
"${widget.dateFormat.format(value.end)}"
|
||||||
: '',
|
: "",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case FlutterFormDateTimeType.time:
|
case FlutterFormDateTimeType.time:
|
||||||
|
var locale = MaterialLocalizations.of(context);
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
userInput = await showTimePicker(
|
userInput = await showTimePicker(
|
||||||
initialEntryMode: widget.timePickerEntryMode,
|
initialEntryMode: widget.timePickerEntryMode,
|
||||||
|
@ -161,9 +167,8 @@ class _DateInputFieldState extends State<DateTimeInputField> {
|
||||||
initialTime: initialTimeOfDay,
|
initialTime: initialTimeOfDay,
|
||||||
).then(
|
).then(
|
||||||
(value) => value == null
|
(value) => value == null
|
||||||
? ''
|
? ""
|
||||||
: MaterialLocalizations.of(context)
|
: locale.formatTimeOfDay(value, alwaysUse24HourFormat: true),
|
||||||
.formatTimeOfDay(value, alwaysUse24HourFormat: true),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,12 +187,12 @@ class _DateInputFieldState extends State<DateTimeInputField> {
|
||||||
? () async {
|
? () async {
|
||||||
var userInput = await getInputFromUser(
|
var userInput = await getInputFromUser(
|
||||||
widget.inputType,
|
widget.inputType,
|
||||||
DateFormat('dd MM yyyy HH:mm'),
|
DateFormat("dd MM yyyy HH:mm"),
|
||||||
);
|
);
|
||||||
setState(() {
|
setState(() {
|
||||||
currentValue = userInput != '' ? userInput : currentValue;
|
currentValue = userInput != "" ? userInput : currentValue;
|
||||||
widget.onChanged
|
widget.onChanged
|
||||||
?.call(userInput != '' ? userInput : currentValue);
|
?.call(userInput != "" ? userInput : currentValue);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
|
@ -196,7 +201,7 @@ class _DateInputFieldState extends State<DateTimeInputField> {
|
||||||
InputDecoration(
|
InputDecoration(
|
||||||
suffixIcon: widget.showIcon ? Icon(widget.icon) : null,
|
suffixIcon: widget.showIcon ? Icon(widget.icon) : null,
|
||||||
focusColor: Theme.of(context).primaryColor,
|
focusColor: Theme.of(context).primaryColor,
|
||||||
label: widget.label ?? const Text('Date'),
|
label: widget.label ?? const Text("Date"),
|
||||||
),
|
),
|
||||||
enabled: widget.enabled,
|
enabled: widget.enabled,
|
||||||
);
|
);
|
||||||
|
|
99
lib/src/inputs/dropdown/dropdown.dart
Normal file
99
lib/src/inputs/dropdown/dropdown.dart
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
import "package:flutter/material.dart";
|
||||||
|
|
||||||
|
class FlutterFormInputDropdown extends StatelessWidget {
|
||||||
|
const FlutterFormInputDropdown({
|
||||||
|
this.alignment = AlignmentDirectional.centerStart,
|
||||||
|
this.autofocus = false,
|
||||||
|
this.isExpanded = false,
|
||||||
|
this.isDense = true,
|
||||||
|
this.iconSize = 24,
|
||||||
|
this.elevation = 8,
|
||||||
|
this.items,
|
||||||
|
this.selectedItemBuilder,
|
||||||
|
this.value,
|
||||||
|
this.hint,
|
||||||
|
this.disabledHint,
|
||||||
|
this.onChanged,
|
||||||
|
this.onTap,
|
||||||
|
this.style,
|
||||||
|
this.icon,
|
||||||
|
this.iconDisabledColor,
|
||||||
|
this.iconEnabledColor,
|
||||||
|
this.itemHeight,
|
||||||
|
this.focusColor,
|
||||||
|
this.focusNode,
|
||||||
|
this.dropdownColor,
|
||||||
|
this.decoration,
|
||||||
|
this.onSaved,
|
||||||
|
this.validator,
|
||||||
|
this.autovalidateMode,
|
||||||
|
this.menuMaxHeight,
|
||||||
|
this.enableFeedback,
|
||||||
|
this.borderRadius,
|
||||||
|
this.padding,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final List<DropdownMenuItem<Object?>>? items;
|
||||||
|
final List<Widget> Function(BuildContext)? selectedItemBuilder;
|
||||||
|
final Object? value;
|
||||||
|
final Widget? hint;
|
||||||
|
final Widget? disabledHint;
|
||||||
|
final void Function(Object?)? onChanged;
|
||||||
|
final void Function()? onTap;
|
||||||
|
final int elevation;
|
||||||
|
final TextStyle? style;
|
||||||
|
final Widget? icon;
|
||||||
|
final Color? iconDisabledColor;
|
||||||
|
final Color? iconEnabledColor;
|
||||||
|
final double iconSize;
|
||||||
|
final bool isDense;
|
||||||
|
final bool isExpanded;
|
||||||
|
final double? itemHeight;
|
||||||
|
final Color? focusColor;
|
||||||
|
final FocusNode? focusNode;
|
||||||
|
final bool autofocus;
|
||||||
|
final Color? dropdownColor;
|
||||||
|
final InputDecoration? decoration;
|
||||||
|
final void Function(Object?)? onSaved;
|
||||||
|
final String? Function(Object?)? validator;
|
||||||
|
final AutovalidateMode? autovalidateMode;
|
||||||
|
final double? menuMaxHeight;
|
||||||
|
final bool? enableFeedback;
|
||||||
|
final AlignmentGeometry alignment;
|
||||||
|
final BorderRadius? borderRadius;
|
||||||
|
final EdgeInsetsGeometry? padding;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => DropdownButtonFormField(
|
||||||
|
items: items,
|
||||||
|
selectedItemBuilder: selectedItemBuilder,
|
||||||
|
value: value,
|
||||||
|
hint: hint,
|
||||||
|
disabledHint: disabledHint,
|
||||||
|
onChanged: (value) => onChanged?.call(value),
|
||||||
|
onTap: () => onTap?.call(),
|
||||||
|
elevation: elevation,
|
||||||
|
style: style,
|
||||||
|
icon: icon,
|
||||||
|
iconDisabledColor: iconDisabledColor,
|
||||||
|
iconEnabledColor: iconEnabledColor,
|
||||||
|
iconSize: iconSize,
|
||||||
|
isDense: isDense,
|
||||||
|
isExpanded: isExpanded,
|
||||||
|
itemHeight: itemHeight,
|
||||||
|
focusColor: focusColor,
|
||||||
|
focusNode: focusNode,
|
||||||
|
autofocus: autofocus,
|
||||||
|
dropdownColor: dropdownColor,
|
||||||
|
decoration: decoration,
|
||||||
|
onSaved: (value) => onSaved?.call(value),
|
||||||
|
validator: (value) => validator?.call(value),
|
||||||
|
autovalidateMode: autovalidateMode,
|
||||||
|
menuMaxHeight: menuMaxHeight,
|
||||||
|
enableFeedback: enableFeedback,
|
||||||
|
alignment: alignment,
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
padding: padding,
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,8 +1,13 @@
|
||||||
export 'bool/bool.dart';
|
export "bool/bool.dart";
|
||||||
export 'carousel/carousel.dart';
|
export "carousel/carousel.dart";
|
||||||
export 'date_picker/date_picker.dart';
|
export "date_picker/date_picker.dart";
|
||||||
export 'number_picker/number_picker.dart';
|
export "dropdown/dropdown.dart";
|
||||||
export 'scroll_picker/scroll_picker.dart';
|
export "number_picker/number_picker.dart";
|
||||||
export 'slider/slider.dart';
|
export "phone/countries.dart";
|
||||||
export 'text/password.dart';
|
export "phone/phone.dart";
|
||||||
export 'text/plain_text.dart';
|
export "phone/phone_number_model.dart";
|
||||||
|
export "radio/radio_picker.dart";
|
||||||
|
export "scroll_picker/scroll_picker.dart";
|
||||||
|
export "slider/slider.dart";
|
||||||
|
export "text/password.dart";
|
||||||
|
export "text/plain_text.dart";
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'dart:math' as math;
|
import "dart:math" as math;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
|
|
||||||
import 'package:flutter_input_library/src/inputs/number_picker/number_picker_field.dart';
|
import "package:flutter_input_library/src/inputs/number_picker/number_picker_field.dart";
|
||||||
|
|
||||||
class DecimalNumberPicker extends StatelessWidget {
|
class DecimalNumberPicker extends StatelessWidget {
|
||||||
const DecimalNumberPicker({
|
const DecimalNumberPicker({
|
||||||
|
@ -28,8 +28,8 @@ class DecimalNumberPicker extends StatelessWidget {
|
||||||
this.integerZeroPad = false,
|
this.integerZeroPad = false,
|
||||||
this.integerDecoration,
|
this.integerDecoration,
|
||||||
this.decimalDecoration,
|
this.decimalDecoration,
|
||||||
}) : assert(minValue <= value, 'value must be greater than minValue'),
|
}) : assert(minValue <= value, "value must be greater than minValue"),
|
||||||
assert(value <= maxValue, 'value must be less than maxValue');
|
assert(value <= maxValue, "value must be less than maxValue");
|
||||||
final int minValue;
|
final int minValue;
|
||||||
final int maxValue;
|
final int maxValue;
|
||||||
final double value;
|
final double value;
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'dart:math' as math;
|
import "dart:math" as math;
|
||||||
|
|
||||||
import 'package:flutter/gestures.dart' show DragStartBehavior;
|
import "package:flutter/gestures.dart" show DragStartBehavior;
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter/rendering.dart';
|
import "package:flutter/rendering.dart";
|
||||||
import 'package:flutter/widgets.dart';
|
import "package:flutter/widgets.dart";
|
||||||
|
|
||||||
/// Infinite ListView
|
/// Infinite ListView
|
||||||
///
|
///
|
||||||
|
@ -274,18 +274,18 @@ class InfiniteListViewState extends State<InfiniteListView> {
|
||||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
super.debugFillProperties(properties);
|
super.debugFillProperties(properties);
|
||||||
properties
|
properties
|
||||||
.add(EnumProperty<Axis>('scrollDirection', widget.scrollDirection));
|
.add(EnumProperty<Axis>("scrollDirection", widget.scrollDirection));
|
||||||
properties.add(
|
properties.add(
|
||||||
FlagProperty(
|
FlagProperty(
|
||||||
'reverse',
|
"reverse",
|
||||||
value: widget.reverse,
|
value: widget.reverse,
|
||||||
ifTrue: 'reversed',
|
ifTrue: "reversed",
|
||||||
showName: true,
|
showName: true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
properties.add(
|
properties.add(
|
||||||
DiagnosticsProperty<ScrollController>(
|
DiagnosticsProperty<ScrollController>(
|
||||||
'controller',
|
"controller",
|
||||||
widget.controller,
|
widget.controller,
|
||||||
showName: false,
|
showName: false,
|
||||||
defaultValue: null,
|
defaultValue: null,
|
||||||
|
@ -293,7 +293,7 @@ class InfiniteListViewState extends State<InfiniteListView> {
|
||||||
);
|
);
|
||||||
properties.add(
|
properties.add(
|
||||||
DiagnosticsProperty<ScrollPhysics>(
|
DiagnosticsProperty<ScrollPhysics>(
|
||||||
'physics',
|
"physics",
|
||||||
widget.physics,
|
widget.physics,
|
||||||
showName: false,
|
showName: false,
|
||||||
defaultValue: null,
|
defaultValue: null,
|
||||||
|
@ -301,16 +301,16 @@ class InfiniteListViewState extends State<InfiniteListView> {
|
||||||
);
|
);
|
||||||
properties.add(
|
properties.add(
|
||||||
DiagnosticsProperty<EdgeInsetsGeometry>(
|
DiagnosticsProperty<EdgeInsetsGeometry>(
|
||||||
'padding',
|
"padding",
|
||||||
widget.padding,
|
widget.padding,
|
||||||
defaultValue: null,
|
defaultValue: null,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
properties.add(
|
properties.add(
|
||||||
DoubleProperty('itemExtent', widget.itemExtent, defaultValue: null),
|
DoubleProperty("itemExtent", widget.itemExtent, defaultValue: null),
|
||||||
);
|
);
|
||||||
properties.add(
|
properties.add(
|
||||||
DoubleProperty('cacheExtent', widget.cacheExtent, defaultValue: null),
|
DoubleProperty("cacheExtent", widget.cacheExtent, defaultValue: null),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
|
|
||||||
import 'package:flutter_input_library/src/inputs/number_picker/number_picker_field.dart';
|
import "package:flutter_input_library/src/inputs/number_picker/number_picker_field.dart";
|
||||||
|
|
||||||
class FlutterFormInputNumberPicker extends StatelessWidget {
|
class FlutterFormInputNumberPicker extends StatelessWidget {
|
||||||
const FlutterFormInputNumberPicker({
|
const FlutterFormInputNumberPicker({
|
||||||
|
@ -15,7 +15,8 @@ class FlutterFormInputNumberPicker extends StatelessWidget {
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
this.initialValue,
|
this.initialValue,
|
||||||
this.validator,
|
this.validator,
|
||||||
}) : assert(minValue < maxValue, 'minValue must be less than maxValue');
|
this.axis = Axis.vertical,
|
||||||
|
}) : assert(minValue < maxValue, "minValue must be less than maxValue");
|
||||||
|
|
||||||
final int minValue;
|
final int minValue;
|
||||||
final int maxValue;
|
final int maxValue;
|
||||||
|
@ -23,6 +24,7 @@ class FlutterFormInputNumberPicker extends StatelessWidget {
|
||||||
final String? Function(int?)? validator;
|
final String? Function(int?)? validator;
|
||||||
final int? initialValue;
|
final int? initialValue;
|
||||||
final Function(int?)? onChanged;
|
final Function(int?)? onChanged;
|
||||||
|
final Axis axis;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => NumberPickerFormField(
|
Widget build(BuildContext context) => NumberPickerFormField(
|
||||||
|
@ -32,6 +34,7 @@ class FlutterFormInputNumberPicker extends StatelessWidget {
|
||||||
validator: (value) => validator?.call(value),
|
validator: (value) => validator?.call(value),
|
||||||
onChanged: (value) => onChanged?.call(value),
|
onChanged: (value) => onChanged?.call(value),
|
||||||
initialValue: initialValue ?? 0,
|
initialValue: initialValue ?? 0,
|
||||||
|
axis: axis,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +47,7 @@ class NumberPickerFormField extends FormField<int> {
|
||||||
int super.initialValue = 0,
|
int super.initialValue = 0,
|
||||||
int minValue = 0,
|
int minValue = 0,
|
||||||
int maxValue = 100,
|
int maxValue = 100,
|
||||||
|
Axis axis = Axis.vertical,
|
||||||
}) : super(
|
}) : super(
|
||||||
builder: (FormFieldState<int> state) => NumberPicker(
|
builder: (FormFieldState<int> state) => NumberPicker(
|
||||||
minValue: minValue,
|
minValue: minValue,
|
||||||
|
@ -55,7 +59,9 @@ class NumberPickerFormField extends FormField<int> {
|
||||||
state.didChange(value);
|
state.didChange(value);
|
||||||
},
|
},
|
||||||
itemHeight: 35,
|
itemHeight: 35,
|
||||||
|
itemWidth: 35,
|
||||||
itemCount: 5,
|
itemCount: 5,
|
||||||
|
axis: axis,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'dart:async';
|
import "dart:async";
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter/services.dart';
|
import "package:flutter/services.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/number_picker/infinite_listview.dart';
|
import "package:flutter_input_library/src/inputs/number_picker/infinite_listview.dart";
|
||||||
|
|
||||||
typedef TextMapper = String Function(String numberText);
|
typedef TextMapper = String Function(String numberText);
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@ class NumberPicker extends StatefulWidget {
|
||||||
this.zeroPad = false,
|
this.zeroPad = false,
|
||||||
this.textMapper,
|
this.textMapper,
|
||||||
this.infiniteLoop = false,
|
this.infiniteLoop = false,
|
||||||
}) : assert(minValue <= value, 'value must be greater than minValue'),
|
}) : assert(minValue <= value, "value must be greater than minValue"),
|
||||||
assert(value <= maxValue, 'value must be less than maxValue');
|
assert(value <= maxValue, "value must be less than maxValue");
|
||||||
|
|
||||||
/// Min value user can pick
|
/// Min value user can pick
|
||||||
final int minValue;
|
final int minValue;
|
||||||
|
@ -182,8 +182,8 @@ class NumberPickerState extends State<NumberPicker> {
|
||||||
children: [
|
children: [
|
||||||
Center(
|
Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 300,
|
width: widget.itemWidth,
|
||||||
height: 45,
|
height: widget.itemHeight,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
color: const Color(0xFFD8D8D8).withOpacity(0.50),
|
color: const Color(0xFFD8D8D8).withOpacity(0.50),
|
||||||
|
@ -248,7 +248,7 @@ class NumberPickerState extends State<NumberPicker> {
|
||||||
|
|
||||||
String _getDisplayedValue(int value) {
|
String _getDisplayedValue(int value) {
|
||||||
var text = widget.zeroPad
|
var text = widget.zeroPad
|
||||||
? value.toString().padLeft(widget.maxValue.toString().length, '0')
|
? value.toString().padLeft(widget.maxValue.toString().length, "0")
|
||||||
: value.toString();
|
: value.toString();
|
||||||
if (widget.textMapper != null) {
|
if (widget.textMapper != null) {
|
||||||
return widget.textMapper!(text);
|
return widget.textMapper!(text);
|
||||||
|
|
7572
lib/src/inputs/phone/countries.dart
Normal file
7572
lib/src/inputs/phone/countries.dart
Normal file
File diff suppressed because it is too large
Load diff
146
lib/src/inputs/phone/phone.dart
Normal file
146
lib/src/inputs/phone/phone.dart
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Iconica
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
// ignore: depend_on_referenced_packages
|
||||||
|
import "package:collection/collection.dart";
|
||||||
|
import "package:flutter/material.dart";
|
||||||
|
import "package:flutter_input_library/flutter_input_library.dart";
|
||||||
|
|
||||||
|
class FlutterFormInputPhone extends StatefulWidget {
|
||||||
|
const FlutterFormInputPhone({
|
||||||
|
super.key,
|
||||||
|
this.label,
|
||||||
|
this.decoration,
|
||||||
|
this.initialValue,
|
||||||
|
this.onChanged,
|
||||||
|
this.onSaved,
|
||||||
|
this.validator,
|
||||||
|
this.onFieldSubmitted,
|
||||||
|
this.numberFieldStyle,
|
||||||
|
this.dialCodeSelectorStyle,
|
||||||
|
this.enabled = true,
|
||||||
|
this.priorityCountries = const ["NL", "BE", "LU"],
|
||||||
|
this.textAlignVertical = TextAlignVertical.top,
|
||||||
|
this.dialCodeSelectorPadding = const EdgeInsets.only(top: 6),
|
||||||
|
});
|
||||||
|
|
||||||
|
final InputDecoration? decoration;
|
||||||
|
final Widget? label;
|
||||||
|
final PhoneNumber? initialValue;
|
||||||
|
final Function(PhoneNumber?)? onSaved;
|
||||||
|
final String? Function(PhoneNumber?)? validator;
|
||||||
|
final Function(PhoneNumber?)? onChanged;
|
||||||
|
final Function(PhoneNumber?)? onFieldSubmitted;
|
||||||
|
final TextStyle? numberFieldStyle;
|
||||||
|
final TextStyle? dialCodeSelectorStyle;
|
||||||
|
final bool enabled;
|
||||||
|
final List<String>? priorityCountries;
|
||||||
|
final EdgeInsets dialCodeSelectorPadding;
|
||||||
|
final TextAlignVertical textAlignVertical;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FlutterFormInputPhone> createState() => _FlutterFormInputPhoneState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FlutterFormInputPhoneState extends State<FlutterFormInputPhone> {
|
||||||
|
final List<Country> _countryList = [];
|
||||||
|
late Country _selectedCountry;
|
||||||
|
|
||||||
|
String? validatorMessage;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
for (var country in countries) {
|
||||||
|
_countryList.add(country);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widget.priorityCountries != null) {
|
||||||
|
for (var countryCode in widget.priorityCountries!.reversed.toList()) {
|
||||||
|
_countryList.removeWhere(
|
||||||
|
(country) => country.code.toLowerCase() == countryCode.toLowerCase(),
|
||||||
|
);
|
||||||
|
|
||||||
|
var insertedCountry = countries.firstWhereOrNull(
|
||||||
|
(country) => country.code.toLowerCase() == countryCode.toLowerCase(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (insertedCountry != null) {
|
||||||
|
_countryList.insert(0, insertedCountry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectedCountry = _countryList.firstWhereOrNull(
|
||||||
|
(country) => widget.initialValue?.dialCode == country.dialCode,
|
||||||
|
) ??
|
||||||
|
_countryList.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var inputDecoration = widget.decoration ??
|
||||||
|
InputDecoration(
|
||||||
|
label: widget.label ?? const Text("Phone number"),
|
||||||
|
);
|
||||||
|
|
||||||
|
return FlutterFormInputPlainText(
|
||||||
|
label: widget.label,
|
||||||
|
style: widget.numberFieldStyle,
|
||||||
|
initialValue: widget.initialValue?.number,
|
||||||
|
onSaved: (value) => widget.onSaved?.call(
|
||||||
|
PhoneNumber(dialCode: _selectedCountry.dialCode, number: value),
|
||||||
|
),
|
||||||
|
validator: (value) => widget.validator?.call(
|
||||||
|
PhoneNumber(dialCode: _selectedCountry.dialCode, number: value),
|
||||||
|
),
|
||||||
|
onChanged: (value) => widget.onChanged?.call(
|
||||||
|
PhoneNumber(dialCode: _selectedCountry.dialCode, number: value),
|
||||||
|
),
|
||||||
|
onFieldSubmitted: (value) => widget.onFieldSubmitted?.call(
|
||||||
|
PhoneNumber(dialCode: _selectedCountry.dialCode, number: value),
|
||||||
|
),
|
||||||
|
decoration: inputDecoration.copyWith(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
prefixIcon: Padding(
|
||||||
|
padding: widget.dialCodeSelectorPadding,
|
||||||
|
child: DropdownButton(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
elevation: 0,
|
||||||
|
value: _selectedCountry,
|
||||||
|
style: widget.dialCodeSelectorStyle,
|
||||||
|
underline: const SizedBox.shrink(),
|
||||||
|
items: [
|
||||||
|
for (var country in _countryList) ...[
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: country,
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(country.flag),
|
||||||
|
const SizedBox(
|
||||||
|
width: 4,
|
||||||
|
),
|
||||||
|
Text("+${country.dialCode}"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
setState(() {
|
||||||
|
_selectedCountry = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.phone,
|
||||||
|
enabled: widget.enabled,
|
||||||
|
textAlignVertical: widget.textAlignVertical,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
9
lib/src/inputs/phone/phone_number_model.dart
Normal file
9
lib/src/inputs/phone/phone_number_model.dart
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
class PhoneNumber {
|
||||||
|
const PhoneNumber({
|
||||||
|
this.dialCode,
|
||||||
|
this.number,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String? dialCode;
|
||||||
|
final String? number;
|
||||||
|
}
|
77
lib/src/inputs/radio/radio_picker.dart
Normal file
77
lib/src/inputs/radio/radio_picker.dart
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Iconica
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
// ignore: depend_on_referenced_packages
|
||||||
|
import "package:collection/collection.dart";
|
||||||
|
import "package:flutter/material.dart";
|
||||||
|
import "package:flutter_input_library/src/inputs/radio/radio_picker_field.dart";
|
||||||
|
|
||||||
|
class FlutterFormInputRadioPicker extends StatelessWidget {
|
||||||
|
const FlutterFormInputRadioPicker({
|
||||||
|
required this.items,
|
||||||
|
super.key,
|
||||||
|
this.onSaved,
|
||||||
|
this.onChanged,
|
||||||
|
this.initialValue,
|
||||||
|
this.itemSpacing = 16.0,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Function(RadioItem?)? onSaved;
|
||||||
|
final String? initialValue;
|
||||||
|
final Function(RadioItem?)? onChanged;
|
||||||
|
final List<RadioItem> items;
|
||||||
|
final double itemSpacing;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => RadioPickerFormField(
|
||||||
|
onSaved: (value) => onSaved?.call(value),
|
||||||
|
onChanged: (value) => onChanged?.call(value),
|
||||||
|
initialValue: items.firstWhereOrNull((i) => i.value == initialValue),
|
||||||
|
itemSpacing: itemSpacing,
|
||||||
|
items: items,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class RadioPickerFormField extends FormField<RadioItem?> {
|
||||||
|
RadioPickerFormField({
|
||||||
|
required FormFieldSetter<RadioItem> super.onSaved,
|
||||||
|
required List<RadioItem> items,
|
||||||
|
required double itemSpacing,
|
||||||
|
void Function(RadioItem value)? onChanged,
|
||||||
|
super.initialValue,
|
||||||
|
super.key,
|
||||||
|
}) : super(
|
||||||
|
builder: (FormFieldState<RadioItem?> state) => RadioPicker(
|
||||||
|
onChanged: (value) {
|
||||||
|
onChanged?.call(value);
|
||||||
|
|
||||||
|
state.didChange(value);
|
||||||
|
},
|
||||||
|
items: items,
|
||||||
|
initialValue: initialValue,
|
||||||
|
itemSpacing: itemSpacing,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class RadioItem<T> {
|
||||||
|
/// Creates an item for a radio menu.
|
||||||
|
///
|
||||||
|
/// The [child] argument is required.
|
||||||
|
const RadioItem({
|
||||||
|
required this.child,
|
||||||
|
required this.value,
|
||||||
|
this.onTap,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Called when the dropdown menu item is tapped.
|
||||||
|
final VoidCallback? onTap;
|
||||||
|
|
||||||
|
/// The value to return if the user selects this menu item.
|
||||||
|
///
|
||||||
|
/// Eventually returned in a call to [DropdownButton.onChanged].
|
||||||
|
final T value;
|
||||||
|
|
||||||
|
final Widget child;
|
||||||
|
}
|
55
lib/src/inputs/radio/radio_picker_field.dart
Normal file
55
lib/src/inputs/radio/radio_picker_field.dart
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import "package:flutter/material.dart";
|
||||||
|
import "package:flutter_input_library/src/inputs/radio/radio_picker.dart";
|
||||||
|
|
||||||
|
class RadioPicker extends StatefulWidget {
|
||||||
|
const RadioPicker({
|
||||||
|
required this.onChanged,
|
||||||
|
required this.items,
|
||||||
|
this.itemSpacing = 16.0,
|
||||||
|
this.initialValue,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final RadioItem? initialValue;
|
||||||
|
final Function(RadioItem) onChanged;
|
||||||
|
final List<RadioItem> items;
|
||||||
|
|
||||||
|
/// The spacing between each item.
|
||||||
|
final double itemSpacing;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<RadioPicker> createState() => _RadioPickerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RadioPickerState extends State<RadioPicker> {
|
||||||
|
late RadioItem? value = widget.initialValue;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => Wrap(
|
||||||
|
children: [
|
||||||
|
for (var item in widget.items) ...[
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
item.child,
|
||||||
|
Radio<RadioItem>(
|
||||||
|
value: item,
|
||||||
|
groupValue: value,
|
||||||
|
onChanged: (v) {
|
||||||
|
if (v != null) {
|
||||||
|
setState(() {
|
||||||
|
value = v;
|
||||||
|
});
|
||||||
|
widget.onChanged(v);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (widget.items.last != item) ...[
|
||||||
|
SizedBox(width: widget.itemSpacing),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
export 'scroll_picker_decoration.dart';
|
export "scroll_picker_decoration.dart";
|
||||||
export 'scroll_picker_type_extensions.dart';
|
export "scroll_picker_type_extensions.dart";
|
||||||
export 'scroll_picker_widget.dart';
|
export "scroll_picker_widget.dart";
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
|
|
||||||
class ScrollPickerDecoration {
|
class ScrollPickerDecoration {
|
||||||
const ScrollPickerDecoration({
|
const ScrollPickerDecoration({
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/scroll_picker/scroll_picker_decoration.dart';
|
import "package:flutter_input_library/src/inputs/scroll_picker/scroll_picker_decoration.dart";
|
||||||
|
|
||||||
class ScrollPicker extends StatefulWidget {
|
class ScrollPicker extends StatefulWidget {
|
||||||
const ScrollPicker({
|
const ScrollPicker({
|
||||||
|
|
|
@ -35,7 +35,7 @@ class TypeUtils {
|
||||||
WeekDay end,
|
WeekDay end,
|
||||||
) {
|
) {
|
||||||
if (start.index > end.index) {
|
if (start.index > end.index) {
|
||||||
throw ArgumentError('Start month must be before or equal to end month.');
|
throw ArgumentError("Start month must be before or equal to end month.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = <DateTime>[];
|
var result = <DateTime>[];
|
||||||
|
@ -49,7 +49,7 @@ class TypeUtils {
|
||||||
/// Creates list of Datetime with the months from start to end.
|
/// Creates list of Datetime with the months from start to end.
|
||||||
List<DateTime> createMonthList(Month start, Month end, {int? year}) {
|
List<DateTime> createMonthList(Month start, Month end, {int? year}) {
|
||||||
if (start.index > end.index) {
|
if (start.index > end.index) {
|
||||||
throw ArgumentError('Start month must be before or equal to end month.');
|
throw ArgumentError("Start month must be before or equal to end month.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = <DateTime>[];
|
var result = <DateTime>[];
|
||||||
|
@ -65,7 +65,7 @@ class TypeUtils {
|
||||||
/// Creates a list of Datetime with the years from start to end.
|
/// Creates a list of Datetime with the years from start to end.
|
||||||
List<DateTime> createYearList(int start, int end) {
|
List<DateTime> createYearList(int start, int end) {
|
||||||
if (start > end) {
|
if (start > end) {
|
||||||
throw ArgumentError('Start year must be before or equal to year month.');
|
throw ArgumentError("Start year must be before or equal to year month.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = <DateTime>[];
|
var result = <DateTime>[];
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/scroll_picker/scroll_picker_decoration.dart';
|
import "package:flutter_input_library/src/inputs/scroll_picker/scroll_picker_decoration.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/scroll_picker/scroll_picker_field.dart';
|
import "package:flutter_input_library/src/inputs/scroll_picker/scroll_picker_field.dart";
|
||||||
|
|
||||||
class FlutterFormInputScrollPicker<T> extends StatelessWidget {
|
class FlutterFormInputScrollPicker<T> extends StatelessWidget {
|
||||||
const FlutterFormInputScrollPicker({
|
const FlutterFormInputScrollPicker({
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter_input_library/src/inputs/slider/slider_field.dart';
|
import "package:flutter_input_library/src/inputs/slider/slider_field.dart";
|
||||||
|
|
||||||
class FlutterFormInputSlider extends StatelessWidget {
|
class FlutterFormInputSlider extends StatelessWidget {
|
||||||
const FlutterFormInputSlider({
|
const FlutterFormInputSlider({
|
||||||
|
@ -15,7 +15,7 @@ class FlutterFormInputSlider extends StatelessWidget {
|
||||||
this.initialValue,
|
this.initialValue,
|
||||||
this.validator,
|
this.validator,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
}) : assert(minValue < maxValue, 'minValue must be less than maxValue');
|
}) : assert(minValue < maxValue, "minValue must be less than maxValue");
|
||||||
|
|
||||||
final int minValue;
|
final int minValue;
|
||||||
final int maxValue;
|
final int maxValue;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
|
|
||||||
/// Creates a slider with the given input parameters
|
/// Creates a slider with the given input parameters
|
||||||
class SliderFormField extends FormField<double> {
|
class SliderFormField extends FormField<double> {
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter/services.dart';
|
import "package:flutter/services.dart";
|
||||||
|
|
||||||
/// Generates a [TextFormField] for passwords. It requires a
|
/// Generates a [TextFormField] for passwords. It requires a
|
||||||
/// [FlutterFormInputController] as the [controller] parameter and an
|
/// [FlutterFormInputController] as the [controller] parameter and an
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import "package:flutter/material.dart";
|
||||||
import 'package:flutter/services.dart';
|
import "package:flutter/services.dart";
|
||||||
|
|
||||||
class FlutterFormInputPlainText extends StatelessWidget {
|
class FlutterFormInputPlainText extends StatelessWidget {
|
||||||
const FlutterFormInputPlainText({
|
const FlutterFormInputPlainText({
|
||||||
|
@ -53,7 +53,7 @@ class FlutterFormInputPlainText extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var inputDecoration = decoration ??
|
var inputDecoration = decoration ??
|
||||||
InputDecoration(
|
InputDecoration(
|
||||||
label: label ?? const Text('Plain text'),
|
label: label ?? const Text("Plain text"),
|
||||||
);
|
);
|
||||||
|
|
||||||
return TextFormField(
|
return TextFormField(
|
||||||
|
@ -96,6 +96,7 @@ class FlutterFormInputMultiLine extends StatelessWidget {
|
||||||
this.validator,
|
this.validator,
|
||||||
this.onFieldSubmitted,
|
this.onFieldSubmitted,
|
||||||
this.textCapitalization = TextCapitalization.sentences,
|
this.textCapitalization = TextCapitalization.sentences,
|
||||||
|
this.style,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Widget? label;
|
final Widget? label;
|
||||||
|
@ -113,12 +114,14 @@ class FlutterFormInputMultiLine extends StatelessWidget {
|
||||||
final Function(String?)? onChanged;
|
final Function(String?)? onChanged;
|
||||||
final Function(String?)? onFieldSubmitted;
|
final Function(String?)? onFieldSubmitted;
|
||||||
final TextCapitalization textCapitalization;
|
final TextCapitalization textCapitalization;
|
||||||
|
final TextStyle? style;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Column(
|
Widget build(BuildContext context) => Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: FlutterFormInputPlainText(
|
child: FlutterFormInputPlainText(
|
||||||
|
style: style,
|
||||||
label: label,
|
label: label,
|
||||||
textAlignVertical: TextAlignVertical.top,
|
textAlignVertical: TextAlignVertical.top,
|
||||||
expands: true,
|
expands: true,
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
export 'validators/validators.dart';
|
export "validators/validators.dart";
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
export 'email/email.dart';
|
export "email/email.dart";
|
||||||
|
|
13
pubspec.yaml
13
pubspec.yaml
|
@ -1,16 +1,19 @@
|
||||||
name: flutter_input_library
|
name: flutter_input_library
|
||||||
description: A new Flutter package project.
|
description: A new Flutter package project.
|
||||||
version: 3.1.0
|
version: 3.7.0
|
||||||
repository: https://github.com/Iconica-Development/flutter_input_library
|
repository: https://github.com/Iconica-Development/flutter_input_library
|
||||||
|
|
||||||
|
publish_to: https://forgejo.internal.iconica.nl/api/packages/internal/pub
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.18.2 <3.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=1.17.0"
|
flutter: ">=1.17.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
collection: ^1.18.0
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
intl: ^0.18.0
|
intl: ">=0.18.0 <1.0.0"
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -18,6 +21,4 @@ dev_dependencies:
|
||||||
flutter_iconica_analysis:
|
flutter_iconica_analysis:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_iconica_analysis
|
url: https://github.com/Iconica-Development/flutter_iconica_analysis
|
||||||
ref: 6.0.0
|
ref: 7.0.0
|
||||||
|
|
||||||
flutter:
|
|
||||||
|
|
Loading…
Reference in a new issue