diff --git a/docs/pages/docs/check-box.mdx b/docs/pages/docs/check-box.mdx deleted file mode 100644 index 95c280904..000000000 --- a/docs/pages/docs/check-box.mdx +++ /dev/null @@ -1,45 +0,0 @@ -import { Tabs } from 'nextra/components'; -import { Widget } from "../../components/widget"; - -# Check box -A control that allows the user to toggle between checked and not checked. It can also be used in a form. - -On touch devices, it is recommended to use a [switch](/docs/switch) instead in most cases. - - - - - - - ```dart - FCheckBox(); - ``` - - - -## Usage - -### `FCheckBox(...)` - -```dart -FCheckBox( - enabled: true, - initialValue: true, -); -``` - -## Examples - -### Disabled - - - - - - - ```dart - FCheckBox(); - ``` - - - diff --git a/docs/pages/docs/checkbox.mdx b/docs/pages/docs/checkbox.mdx new file mode 100644 index 000000000..e9f719bec --- /dev/null +++ b/docs/pages/docs/checkbox.mdx @@ -0,0 +1,107 @@ +import { Tabs } from 'nextra/components'; +import { Widget } from "../../components/widget"; + +# Checkbox +A control that allows the user to toggle between checked and not checked. It can also be used in a form. + +On touch devices, it is recommended to use a [switch](/docs/switch) instead in most cases. + + + + + + + ```dart + FCheckBox(); + ``` + + + +## Usage + +### `FCheckbox(...)` + +```dart +FCheckbox( + enabled: true, + initialValue: true, +); +``` + +## Examples + +### Disabled + + + + + + + ```dart + FCheckbox( + enabled: false, + ); + ``` + + + +### Form + + + + + + + ```dart + class LoginForm extends StatefulWidget { + const LoginForm({super.key}); + + @override + State createState() => _LoginFormState(); + } + + class _LoginFormState extends State { + final GlobalKey _formKey = GlobalKey(); + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) => Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + FTextField.email( + hint: 'janedoe@foruslabs.com', + help: const Text(''), + validator: (value) => (value?.contains('@') ?? false) ? null : 'Please enter a valid email.', + ), + const SizedBox(height: 4), + FTextField.password( + hint: '', + help: const Text(''), + validator: (value) => 8 <= (value?.length ?? 0) ? null : 'Password must be at least 8 characters long.', + ), + const SizedBox(height: 4), + Row( + children: [ + const FCheckbox(), + const SizedBox(width: 7), + Text('Remember password?', style: context.theme.typography.sm), + ], + ), + const SizedBox(height: 30), + FButton( + label: const Text('Login'), + onPress: () => _formKey.currentState!.validate(), + ), + ], + ), + ); + } + ``` + + \ No newline at end of file diff --git a/forui/lib/src/theme/theme_data.dart b/forui/lib/src/theme/theme_data.dart index e78d28136..c00815fb9 100644 --- a/forui/lib/src/theme/theme_data.dart +++ b/forui/lib/src/theme/theme_data.dart @@ -34,8 +34,8 @@ final class FThemeData with Diagnosticable { /// The card style. final FCardStyle cardStyle; - /// The check box style. - final FCheckBoxStyle checkBoxStyle; + /// The checkbox style. + final FCheckboxStyle checkBoxStyle; /// The dialog style. final FDialogStyle dialogStyle; @@ -100,7 +100,7 @@ final class FThemeData with Diagnosticable { badgeStyles: FBadgeStyles.inherit(colorScheme: colorScheme, typography: typography, style: style), buttonStyles: FButtonStyles.inherit(colorScheme: colorScheme, typography: typography, style: style), cardStyle: FCardStyle.inherit(colorScheme: colorScheme, typography: typography, style: style), - checkBoxStyle: FCheckBoxStyle.inherit(colorScheme: colorScheme), + checkBoxStyle: FCheckboxStyle.inherit(colorScheme: colorScheme), dialogStyle: FDialogStyle.inherit(colorScheme: colorScheme, typography: typography, style: style), headerStyle: FHeaderStyles.inherit(colorScheme: colorScheme, typography: typography, style: style), progressStyle: FProgressStyle.inherit(colorScheme: colorScheme, style: style), @@ -136,7 +136,7 @@ final class FThemeData with Diagnosticable { FBadgeStyles? badgeStyles, FButtonStyles? buttonStyles, FCardStyle? cardStyle, - FCheckBoxStyle? checkBoxStyle, + FCheckboxStyle? checkBoxStyle, FDialogStyle? dialogStyle, FHeaderStyles? headerStyle, FProgressStyle? progressStyle, diff --git a/forui/lib/src/widgets/checkbox.dart b/forui/lib/src/widgets/checkbox.dart index b73498adb..953c2815f 100644 --- a/forui/lib/src/widgets/checkbox.dart +++ b/forui/lib/src/widgets/checkbox.dart @@ -5,15 +5,15 @@ import 'package:flutter/widgets.dart'; import 'package:forui/forui.dart'; -/// A check box control that allows the user to toggle between checked and not checked. +/// A checkbox control that allows the user to toggle between checked and not checked. /// -/// On touch devices, it is recommended to use a [FSwitch] instead in most cases. A [FCheckBox] is internally a +/// On touch devices, it is recommended to use a [FSwitch] instead in most cases. A [FCheckbox] is internally a /// [FormField], therefore it can be used in a form. /// /// See: -/// * https://forui.dev/docs/check-box for working examples. -/// * [FCheckBoxStyle] for customizing a check box's appearance. -class FCheckBox extends StatelessWidget { +/// * https://forui.dev/docs/checkbox for working examples. +/// * [FCheckboxStyle] for customizing a checkbox's appearance. +class FCheckbox extends StatelessWidget { /// The semantic label of the dialog used by accessibility frameworks to announce screen transitions when the dialog /// is opened and closed. /// @@ -24,10 +24,10 @@ class FCheckBox extends StatelessWidget { /// Called when the user initiates a change to the FCheckBox's value: when they have checked or unchecked this box. final ValueChanged? onChange; - /// Whether this check box should focus itself if nothing else is already focused. Defaults to false. + /// Whether this checkbox should focus itself if nothing else is already focused. Defaults to false. final bool autofocus; - /// Defines the [FocusNode] for this check box. + /// Defines the [FocusNode] for this checkbox. final FocusNode? focusNode; /// Handler called when the focus changes. @@ -73,8 +73,8 @@ class FCheckBox extends StatelessWidget { /// * [RestorationManager], which explains how state restoration works in Flutter. final String? restorationId; - /// Creates a [FCheckBox]. - const FCheckBox({ + /// Creates a [FCheckbox]. + const FCheckbox({ this.semanticLabel, this.onChange, this.autofocus = false, @@ -174,53 +174,53 @@ class FCheckBox extends StatelessWidget { } } -/// A [FCheckBox]'s style. -final class FCheckBoxStyle with Diagnosticable { - /// The duration of the animation when the check box's switches between checked and unchecked. +/// A [FCheckbox]'s style. +final class FCheckboxStyle with Diagnosticable { + /// The duration of the animation when the checkbox's switches between checked and unchecked. /// /// Defaults to `const Duration(milliseconds: 100)`. final Duration animationDuration; - /// The curve of the animation when the check box's switches between checked and unchecked. + /// The curve of the animation when the checkbox's switches between checked and unchecked. /// /// Defaults to [Curves.linear]. final Curve curve; - /// The check box's style when it's enabled. - final FCheckBoxStateStyle enabledStyle; + /// The checkbox's style when it's enabled. + final FCheckboxStateStyle enabledStyle; - /// The check box's style when it's disabled. - final FCheckBoxStateStyle disabledStyle; + /// The checkbox's style when it's disabled. + final FCheckboxStateStyle disabledStyle; - /// Creates a [FCheckBoxStyle]. - FCheckBoxStyle({ + /// Creates a [FCheckboxStyle]. + FCheckboxStyle({ required this.enabledStyle, required this.disabledStyle, this.animationDuration = const Duration(milliseconds: 100), this.curve = Curves.linear, }); - /// Creates a [FCheckBoxStyle] that inherits its properties from the given [FColorScheme]. - FCheckBoxStyle.inherit({required FColorScheme colorScheme}) + /// Creates a [FCheckboxStyle] that inherits its properties from the given [FColorScheme]. + FCheckboxStyle.inherit({required FColorScheme colorScheme}) : animationDuration = const Duration(milliseconds: 100), curve = Curves.linear, - enabledStyle = FCheckBoxStateStyle( - borderColor: colorScheme.foreground, + enabledStyle = FCheckboxStateStyle( + borderColor: colorScheme.primary, iconColor: colorScheme.background, - checkedBackgroundColor: colorScheme.foreground, + checkedBackgroundColor: colorScheme.primary, uncheckedBackgroundColor: colorScheme.background, ), - disabledStyle = FCheckBoxStateStyle( - borderColor: colorScheme.foreground.withOpacity(0.5), + disabledStyle = FCheckboxStateStyle( + borderColor: colorScheme.primary.withOpacity(0.5), iconColor: colorScheme.background.withOpacity(0.5), - checkedBackgroundColor: colorScheme.foreground.withOpacity(0.5), + checkedBackgroundColor: colorScheme.primary.withOpacity(0.5), uncheckedBackgroundColor: colorScheme.background.withOpacity(0.5), ); - /// Returns a copy of this [FCheckBoxStyle] with the given properties replaced. + /// Returns a copy of this [FCheckboxStyle] with the given properties replaced. /// /// ```dart - /// final style = FCheckBoxStyle( + /// final style = FCheckboxStyle( /// animationDuration: const Duration(minutes: 1), /// curve: Curves.linear, /// // Other arguments omitted for brevity. @@ -233,13 +233,13 @@ final class FCheckBoxStyle with Diagnosticable { /// print(style.animationDuration); // const Duration(minutes: 1) /// print(copy.curve); // Curves.bounceIn /// ``` - FCheckBoxStyle copyWith({ + FCheckboxStyle copyWith({ Duration? animationDuration, Curve? curve, - FCheckBoxStateStyle? enabledStyle, - FCheckBoxStateStyle? disabledStyle, + FCheckboxStateStyle? enabledStyle, + FCheckboxStateStyle? disabledStyle, }) => - FCheckBoxStyle( + FCheckboxStyle( animationDuration: animationDuration ?? this.animationDuration, curve: curve ?? this.curve, enabledStyle: enabledStyle ?? this.enabledStyle, @@ -259,7 +259,7 @@ final class FCheckBoxStyle with Diagnosticable { @override bool operator ==(Object other) => identical(this, other) || - other is FCheckBoxStyle && + other is FCheckboxStyle && runtimeType == other.runtimeType && animationDuration == other.animationDuration && curve == other.curve && @@ -270,29 +270,29 @@ final class FCheckBoxStyle with Diagnosticable { int get hashCode => animationDuration.hashCode ^ curve.hashCode ^ enabledStyle.hashCode ^ disabledStyle.hashCode; } -/// A check box state's style. -final class FCheckBoxStateStyle with Diagnosticable { - /// The check box's border color. +/// A checkbox state's style. +final class FCheckboxStateStyle with Diagnosticable { + /// The checkbox's border color. final Color borderColor; - /// The checked check box's icon's color. + /// The checked checkbox's icon's color. final Color iconColor; - /// The checked check box's background color. + /// The checked checkbox's background color. final Color checkedBackgroundColor; - /// The unchecked check box's background color. + /// The unchecked checkbox's background color. final Color uncheckedBackgroundColor; - /// Creates a [FCheckBoxStateStyle]. - const FCheckBoxStateStyle({ + /// Creates a [FCheckboxStateStyle]. + const FCheckboxStateStyle({ required this.borderColor, required this.iconColor, required this.checkedBackgroundColor, required this.uncheckedBackgroundColor, }); - /// Returns a copy of this [FCheckBoxStateStyle] with the given properties replaced. + /// Returns a copy of this [FCheckboxStateStyle] with the given properties replaced. /// /// ```dart /// final style = FCheckBoxStateStyle( @@ -308,13 +308,13 @@ final class FCheckBoxStateStyle with Diagnosticable { /// print(style.iconColor == copy.iconColor); // true /// print(style.checkedBackgroundColor == copy.checkedBackgroundColor); // false /// ``` - FCheckBoxStateStyle copyWith({ + FCheckboxStateStyle copyWith({ Color? borderColor, Color? iconColor, Color? checkedBackgroundColor, Color? uncheckedBackgroundColor, }) => - FCheckBoxStateStyle( + FCheckboxStateStyle( borderColor: borderColor ?? this.borderColor, iconColor: iconColor ?? this.iconColor, checkedBackgroundColor: checkedBackgroundColor ?? this.checkedBackgroundColor, @@ -334,7 +334,7 @@ final class FCheckBoxStateStyle with Diagnosticable { @override bool operator ==(Object other) => identical(this, other) || - other is FCheckBoxStateStyle && + other is FCheckboxStateStyle && runtimeType == other.runtimeType && borderColor == other.borderColor && iconColor == other.iconColor && diff --git a/forui/test/golden/check-box/zinc-light-disabled-value.png b/forui/test/golden/check-box/zinc-light-disabled-value.png index 265ae3902..266d5ea38 100644 Binary files a/forui/test/golden/check-box/zinc-light-disabled-value.png and b/forui/test/golden/check-box/zinc-light-disabled-value.png differ diff --git a/forui/test/golden/check-box/zinc-light-enabled-no-value.png b/forui/test/golden/check-box/zinc-light-enabled-no-value.png index 35233f59a..5e477dcc5 100644 Binary files a/forui/test/golden/check-box/zinc-light-enabled-no-value.png and b/forui/test/golden/check-box/zinc-light-enabled-no-value.png differ diff --git a/forui/test/golden/check-box/zinc-light-enabled-value.png b/forui/test/golden/check-box/zinc-light-enabled-value.png index 97aa34e1d..82a23e217 100644 Binary files a/forui/test/golden/check-box/zinc-light-enabled-value.png and b/forui/test/golden/check-box/zinc-light-enabled-value.png differ diff --git a/forui/test/src/widgets/checkbox_golden_test.dart b/forui/test/src/widgets/checkbox_golden_test.dart index f0d747649..522fe0678 100644 --- a/forui/test/src/widgets/checkbox_golden_test.dart +++ b/forui/test/src/widgets/checkbox_golden_test.dart @@ -21,7 +21,7 @@ void main() { TestScaffold( data: theme, background: background, - child: FCheckBox( + child: FCheckbox( enabled: enabled, initialValue: initialValue, ), diff --git a/samples/lib/main.dart b/samples/lib/main.dart index 38855872c..8896f9170 100644 --- a/samples/lib/main.dart +++ b/samples/lib/main.dart @@ -56,8 +56,12 @@ class _AppRouter extends $_AppRouter { page: CardRoute.page, ), AutoRoute( - path: '/check-box/default', - page: CheckBoxRoute.page, + path: '/checkbox/default', + page: CheckboxRoute.page, + ), + AutoRoute( + path: '/checkbox/form', + page: FormCheckboxRoute.page, ), AutoRoute( path: '/dialog/default', diff --git a/samples/lib/widgets/check_box.dart b/samples/lib/widgets/check_box.dart deleted file mode 100644 index 7bd86c989..000000000 --- a/samples/lib/widgets/check_box.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:flutter/widgets.dart'; -import 'package:forui/forui.dart'; -import 'package:forui_samples/sample_scaffold.dart'; - -@RoutePage() -class CheckBoxPage extends SampleScaffold { - final bool enabled; - - CheckBoxPage({ - @queryParam super.theme, - @queryParam this.enabled = false, - }); - - @override - Widget child(BuildContext context) => Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 30), - child: FCheckBox( - enabled: enabled, - ), - ), - ], - ); -} diff --git a/samples/lib/widgets/checkbox.dart b/samples/lib/widgets/checkbox.dart new file mode 100644 index 000000000..9b2d626a7 --- /dev/null +++ b/samples/lib/widgets/checkbox.dart @@ -0,0 +1,93 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:flutter/widgets.dart'; +import 'package:forui/forui.dart'; +import 'package:forui_samples/sample_scaffold.dart'; + +@RoutePage() +class CheckboxPage extends SampleScaffold { + final bool enabled; + + CheckboxPage({ + @queryParam super.theme, + @queryParam this.enabled = false, + }); + + @override + Widget child(BuildContext context) => Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 30), + child: FCheckbox( + enabled: enabled, + ), + ), + ], + ); +} + +@RoutePage() +class FormCheckboxPage extends SampleScaffold { + + FormCheckboxPage({ + @queryParam super.theme, + }); + + @override + Widget child(BuildContext context) => const Padding( + padding: EdgeInsets.all(15.0), + child: LoginForm(), + ); + +} + +class LoginForm extends StatefulWidget { + const LoginForm({super.key}); + + @override + State createState() => _LoginFormState(); +} + +class _LoginFormState extends State { + final GlobalKey _formKey = GlobalKey(); + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) => Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + FTextField.email( + hint: 'janedoe@foruslabs.com', + help: const Text(''), + validator: (value) => (value?.contains('@') ?? false) ? null : 'Please enter a valid email.', + ), + const SizedBox(height: 4), + FTextField.password( + hint: '', + help: const Text(''), + validator: (value) => 8 <= (value?.length ?? 0) ? null : 'Password must be at least 8 characters long.', + ), + const SizedBox(height: 4), + Row( + children: [ + const FCheckbox(), + const SizedBox(width: 7), + Text('Remember password?', style: context.theme.typography.sm), + ], + ), + const SizedBox(height: 30), + FButton( + label: const Text('Login'), + onPress: () => _formKey.currentState!.validate(), + ), + ], + ), + ); +} +