Skip to content

Commit

Permalink
Complete implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
kawaijoe committed Aug 16, 2024
1 parent f83d351 commit 5dd0b57
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 175 deletions.
2 changes: 2 additions & 0 deletions forui/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

* Fix `FTextField` error message replacing the description text.

* Fix `FCheckboxStyle.inherit` icon color inheriting from the wrong color.


## 0.5.0

Expand Down
2 changes: 1 addition & 1 deletion forui/example/ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import UIKit
import Flutter

@UIApplicationMain
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
Expand Down
2 changes: 1 addition & 1 deletion forui/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Application extends StatefulWidget {
}

class _ApplicationState extends State<Application> {
int index = 1;
int index = 0;

@override
Widget build(BuildContext context) => MaterialApp(
Expand Down
30 changes: 28 additions & 2 deletions forui/example/lib/sandbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,37 @@ class _SandboxState extends State<Sandbox> {
@override
Widget build(BuildContext context) => ListView(
padding: EdgeInsets.zero,
children: [
children: const [
FCheckbox(
label: Text('Remember me'),
description: Text('Remember me on this device.'),
initialValue: true,
// forceErrorText: 'Please check the box to continue.',
// initialValue: true,
enabled: false,
),
SizedBox(height: 20),
FLabel(
axis: Axis.vertical,
label: Text('Email'),
description: Text('Enter your email address.'),
error: Text('Please enter a valid email address.'),
state: FLabelState.error,
child: DecoratedBox(
decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.grey),
child: SizedBox(width: 200, height: 30),
),
),
SizedBox(height: 20),
FLabel(
axis: Axis.horizontal,
label: Text('Email'),
description: Text('Enter your email address.'),
error: Text('Please enter a valid email address.'),
state: FLabelState.error,
child: DecoratedBox(
decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.grey),
child: SizedBox(width: 16, height: 16),
),
),
],
);
Expand Down
24 changes: 12 additions & 12 deletions forui/example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -338,18 +338,18 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev"
source: hosted
version: "10.0.4"
version: "10.0.5"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev"
source: hosted
version: "3.0.3"
version: "3.0.5"
leak_tracker_testing:
dependency: transitive
description:
Expand Down Expand Up @@ -378,18 +378,18 @@ packages:
dependency: transitive
description:
name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.8.0"
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted
version: "1.12.0"
version: "1.15.0"
mime:
dependency: transitive
description:
Expand Down Expand Up @@ -631,10 +631,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
version: "0.7.2"
timing:
dependency: transitive
description:
Expand Down Expand Up @@ -687,10 +687,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
url: "https://pub.dev"
source: hosted
version: "14.2.1"
version: "14.2.4"
watcher:
dependency: transitive
description:
Expand Down
93 changes: 93 additions & 0 deletions forui/lib/src/foundation/stateless_form_field.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

/// A stateless single form field.
///
/// This widget is meant to be extended by other form field widgets.
abstract class FStatelessFormField<T> extends StatelessWidget {
/// An optional method to call with the final value when the form is saved via [FormState.save].
final FormFieldSetter<T>? onSave;

/// An optional property that forces the [FormFieldState] into an error state by directly setting the
/// [FormFieldState.errorText] property without running the validator function.
///
/// When the [forceErrorText] property is provided, the [FormFieldState.errorText] will be set to the provided value,
/// causing the form field to be considered invalid and to display the error message specified.
///
/// When [validator] is provided, [forceErrorText] will override any error that it returns. [validator] will not be
/// called unless [forceErrorText] is null.
final String? forceErrorText;

/// An optional method that validates an input. Returns an error string to display if the input is invalid, or null
/// otherwise.
///
/// The returned value is exposed by the [FormFieldState.errorText] property.
final FormFieldValidator<T>? validator;

/// An optional value to initialize the form field to, or null otherwise.
final T initialValue;

/// Whether the form is able to receive user input.
///
/// Defaults to true. If [autovalidateMode] is not [AutovalidateMode.disabled], the checkbox will be auto validated.
/// Likewise, if this field is false, the widget will not be validated regardless of [autovalidateMode].
final bool enabled;

/// Used to enable/disable this checkbox auto validation and update its error text.
///
/// Defaults to [AutovalidateMode.disabled].
///
/// If [AutovalidateMode.onUserInteraction], this checkbox will only auto-validate after its content changes. If
/// [AutovalidateMode.always], it will auto-validate even without user interaction. If [AutovalidateMode.disabled],
/// auto-validation will be disabled.
final AutovalidateMode autovalidateMode;

/// Restoration ID to save and restore the state of the form field.
///
/// Setting the restoration ID to a non-null value results in whether or not the form field validation persists.
///
/// The state of this widget is persisted in a [RestorationBucket] claimed from the surrounding [RestorationScope]
/// using the provided restoration ID.
///
/// See also:
/// * [RestorationManager], which explains how state restoration works in Flutter.
final String? restorationId;

const FStatelessFormField({
required this.initialValue,
this.onSave,
this.forceErrorText,
this.validator,
this.enabled = true,
this.autovalidateMode = AutovalidateMode.disabled,
this.restorationId,
super.key,
});

@override
Widget build(BuildContext context) => FormField<T>(
onSaved: onSave,
forceErrorText: forceErrorText,
validator: validator,
initialValue: initialValue,
enabled: enabled,
autovalidateMode: autovalidateMode,
restorationId: restorationId,
builder: (state) => builder(context, state),
);

Widget builder(BuildContext context, FormFieldState<T> state);

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(ObjectFlagProperty.has('onSave', onSave))
..add(StringProperty('forceErrorText', forceErrorText))
..add(ObjectFlagProperty.has('validator', validator))
..add(DiagnosticsProperty('initialValue', initialValue))
..add(DiagnosticsProperty('enabled', enabled))
..add(EnumProperty('autovalidateMode', autovalidateMode))
..add(StringProperty('restorationId', restorationId));
}
}
4 changes: 2 additions & 2 deletions forui/lib/src/theme/form_field_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ final class FFormFieldStyle with Diagnosticable {
),
disabledStyle = FFormFieldNormalStyle.inherit(
labelColor: colorScheme.primary.withOpacity(0.7),
descriptionColor: colorScheme.border.withOpacity(0.7),
descriptionColor: colorScheme.mutedForeground.withOpacity(0.7),
typography: typography,
),
errorStyle = FFormFieldErrorStyle.inherit(
labelColor: colorScheme.primary,
labelColor: colorScheme.error,
descriptionColor: colorScheme.mutedForeground,
errorColor: colorScheme.error,
typography: typography,
Expand Down
1 change: 0 additions & 1 deletion forui/lib/src/theme/theme_data.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:forui/widgets/label.dart';

import 'package:meta/meta.dart';

Expand Down
Loading

0 comments on commit 5dd0b57

Please sign in to comment.