From e7ea5a5197ab59cda0e566d22afcfd384116749a Mon Sep 17 00:00:00 2001 From: Matthias Ngeo Date: Tue, 20 Aug 2024 19:43:12 +0800 Subject: [PATCH 1/6] Fix tabs --- forui/CHANGELOG.md | 4 + .../bottom_navigation_bar.dart | 2 +- .../lib/src/widgets/tabs/tab_controller.dart | 50 ++++---- forui/lib/src/widgets/tabs/tabs.dart | 117 +++++++++++------- forui/lib/src/widgets/tabs/tabs_style.dart | 20 +-- 5 files changed, 114 insertions(+), 79 deletions(-) diff --git a/forui/CHANGELOG.md b/forui/CHANGELOG.md index a9e82f83d..26641fae5 100644 --- a/forui/CHANGELOG.md +++ b/forui/CHANGELOG.md @@ -44,6 +44,8 @@ * **Breaking:** Remove `FTextField.error` - use `FTextField.forceErrorText` instead. +* Change `FTabController` to implement `ChangeNotifier` instead of `Listenable`. + ### Fixes * Fix `FResizable` not rendering properly in an expanded widget when its crossAxisExtent is null. @@ -54,6 +56,8 @@ * Fix `FCheckboxStyle.inherit(...)` icon color inheriting from the wrong color. +* Fix `FTabs` not handling indexes properly. + ## 0.4.0 diff --git a/forui/lib/src/widgets/bottom_navigation_bar/bottom_navigation_bar.dart b/forui/lib/src/widgets/bottom_navigation_bar/bottom_navigation_bar.dart index feac004c8..4b6a8baec 100644 --- a/forui/lib/src/widgets/bottom_navigation_bar/bottom_navigation_bar.dart +++ b/forui/lib/src/widgets/bottom_navigation_bar/bottom_navigation_bar.dart @@ -84,7 +84,7 @@ class FBottomNavigationBar extends StatelessWidget { } } -/// AFBottomNavigationBar]'s data. +/// A FBottomNavigationBar]'s data. class FBottomNavigationBarData extends InheritedWidget { /// Returns the [FBottomNavigationBarItemStyle] and currently selected index of the [FBottomNavigationBar] in the /// given [context]. diff --git a/forui/lib/src/widgets/tabs/tab_controller.dart b/forui/lib/src/widgets/tabs/tab_controller.dart index 6ea0e1553..caa1bd716 100644 --- a/forui/lib/src/widgets/tabs/tab_controller.dart +++ b/forui/lib/src/widgets/tabs/tab_controller.dart @@ -1,7 +1,7 @@ part of 'tabs.dart'; -/// An object that controls selection in a [FTabs] -class FTabController implements Listenable { +/// A controller that controls selection in a [FTabs]. +final class FTabController implements ChangeNotifier { final TabController _controller; /// Creates a [FTabController]. @@ -11,34 +11,40 @@ class FTabController implements Listenable { int initialIndex = 0, Duration? animationDuration, }) : _controller = TabController( - initialIndex: initialIndex, - length: length, - animationDuration: animationDuration, - vsync: vsync, - ); + initialIndex: initialIndex, + length: length, + animationDuration: animationDuration, + vsync: vsync, + ); + + /// Animates to the given [index]. + void animateTo( + int index, { + Duration? duration, + Curve curve = Curves.ease, + }) => + _controller.animateTo(index, duration: duration, curve: curve); @override void addListener(VoidCallback listener) => _controller.addListener(listener); + @override + void notifyListeners() => _controller.notifyListeners(); + @override void removeListener(VoidCallback listener) => _controller.removeListener(listener); - /// Discards any resources used by the object. After this is called, the - /// object is not in a usable state and should be discarded (calls to - /// [addListener] will throw after the object is disposed). - /// - /// This method should only be called by the object's owner. - /// - /// This method does not notify listeners, and clears the listener list once - /// it is called. Consumers of this class must decide on whether to notify - /// listeners or not immediately before disposal. - void dispose() => _controller.dispose(); + /// The index of the selected tab. + int get index => _controller.index; + + set index(int value) => _controller.index = value; + + /// The number of tabs. + int get length => _controller.length; @override - bool operator ==(Object other) => - identical(this, other) || - other is FTabController && runtimeType == other.runtimeType && _controller == other._controller; + bool get hasListeners => _controller.hasListeners; @override - int get hashCode => _controller.hashCode; -} + void dispose() => _controller.dispose(); +} \ No newline at end of file diff --git a/forui/lib/src/widgets/tabs/tabs.dart b/forui/lib/src/widgets/tabs/tabs.dart index 8c3eab46d..57b319c7e 100644 --- a/forui/lib/src/widgets/tabs/tabs.dart +++ b/forui/lib/src/widgets/tabs/tabs.dart @@ -20,8 +20,8 @@ class FTabEntry { /// Creates a [FTabs]. const FTabEntry({ - required this.content, required this.label, + required this.content, }); @override @@ -37,32 +37,37 @@ class FTabEntry { /// /// See: /// * https://forui.dev/docs/tabs for working examples. -/// * [FTabsStyle] for customizing a switch's appearance. +/// * [FTabsStyle] for customizing tabs' appearance. class FTabs extends StatefulWidget { - /// The tab and it's corresponding view. - final List tabs; + /// The tab controller. + final FTabController? controller; + + /// The style. + final FTabsStyle? style; /// The initial tab that is selected. + /// + /// ## Contract + /// Throws [AssertionError] if: + /// * [initialIndex] is not within the range '0 <= initialIndex < tabs.length`. final int initialIndex; /// Whether this tab bar can be scrolled horizontally. /// - /// If [scrollable] is true, then each tab is as wide as needed for its label - /// and the entire [TabBar] is scrollable. Otherwise each tab gets an equal - /// share of the available space. + /// If [scrollable] is true, then each tab is as wide as needed for its label and the entire [TabBar] is scrollable. + /// Otherwise each tab gets an equal share of the available space. final bool scrollable; - /// The tab controller. - final FTabController? controller; - - /// The style. - final FTabsStyle? style; - /// A callback that returns the tab that was tapped. final ValueChanged? onPress; + /// The tab and it's corresponding view. + final List tabs; + /// Creates a [FTabs]. - const FTabs({ + /// + /// ## Throws + FTabs({ required this.tabs, this.initialIndex = 0, this.scrollable = false, @@ -70,18 +75,27 @@ class FTabs extends StatefulWidget { this.style, this.onPress, super.key, - }) : assert(0 < tabs.length, 'Must have at least 1 tab provided'); + }) : assert(tabs.isNotEmpty, 'Must have at least 1 tab provided.'), + assert(0 <= initialIndex && initialIndex < tabs.length, 'Initial index must be within the range of tabs.'), + assert( + controller == null || controller.index == initialIndex, + 'Controller index must match the initial index.', + ), + assert( + controller == null || controller.length == tabs.length, + 'Controller length must match the number of tabs.', + ); @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties - ..add(IterableProperty('tabs', tabs)) - ..add(IntProperty('initialIndex', initialIndex)) - ..add(DiagnosticsProperty('controller', controller)) + ..add(ObjectFlagProperty.has('controller', controller)) ..add(DiagnosticsProperty('style', style)) + ..add(IntProperty('initialIndex', initialIndex)) + ..add(FlagProperty('scrollable', value: scrollable, ifTrue: 'scrollable')) ..add(ObjectFlagProperty.has('onPress', onPress)) - ..add(FlagProperty('scrollable', value: scrollable, ifTrue: 'scrollable')); + ..add(IterableProperty('tabs', tabs)); } @override @@ -89,24 +103,38 @@ class FTabs extends StatefulWidget { } class _FTabsState extends State with SingleTickerProviderStateMixin { - late int _index; - late final FTabController _controller; + late FTabController _controller; @override void initState() { super.initState(); - _index = widget.initialIndex; - _controller = FTabController(length: widget.tabs.length, vsync: this); + _controller = _createController(); } + @override + void didUpdateWidget(covariant FTabs old) { + super.didUpdateWidget(old); + if (widget.controller != old.controller) { + _controller.dispose(); + _controller = _createController(); + } + } + + FTabController _createController() => + widget.controller ?? + FTabController( + initialIndex: widget.initialIndex, + length: widget.tabs.length, + vsync: this, + ); + @override Widget build(BuildContext context) { final theme = context.theme; final style = widget.style ?? context.theme.tabsStyle; - final tabs = widget.tabs; - final materialLocalizations = Localizations.of(context, MaterialLocalizations); + final localizations = Localizations.of(context, MaterialLocalizations); - final child = Material( + final tabs = Material( color: Colors.transparent, child: Column( children: [ @@ -114,13 +142,13 @@ class _FTabsState extends State with SingleTickerProviderStateMixin { decoration: style.decoration, child: TabBar( tabs: [ - for (final tab in tabs) + for (final tab in widget.tabs) Tab( height: style.height, child: tab.label, ), ], - controller: (widget.controller ?? _controller)._controller, + controller: _controller._controller, isScrollable: widget.scrollable, padding: style.padding, indicator: style.indicator, @@ -128,37 +156,34 @@ class _FTabsState extends State with SingleTickerProviderStateMixin { dividerColor: Colors.transparent, labelStyle: style.selectedLabel, unselectedLabelStyle: style.unselectedLabel, - onTap: (index) { - setState(() => _index = index); - widget.onPress?.call(_index); - }, + onTap: (index) => widget.onPress?.call(index), ), ), SizedBox(height: style.spacing), - // A workaround to ensure any widgets under Tabs do not revert to material text style - // TODO: abstract out logic DefaultTextStyle( style: theme.typography.base.copyWith( fontFamily: theme.typography.defaultFontFamily, color: theme.colorScheme.foreground, ), - child: tabs[_index].content, + child: widget.tabs[_controller.index].content, ), ], ), ); - return materialLocalizations == null - ? Localizations( - locale: Localizations.maybeLocaleOf(context) ?? const Locale('en', 'US'), - delegates: const [ - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate, - ], - child: child, - ) - : child; + if (localizations == null) { + return Localizations( + locale: Localizations.maybeLocaleOf(context) ?? const Locale('en', 'US'), + delegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + child: tabs, + ); + } + + return tabs; } @override diff --git a/forui/lib/src/widgets/tabs/tabs_style.dart b/forui/lib/src/widgets/tabs/tabs_style.dart index 7529d7a0f..7b2e28f8b 100644 --- a/forui/lib/src/widgets/tabs/tabs_style.dart +++ b/forui/lib/src/widgets/tabs/tabs_style.dart @@ -26,12 +26,12 @@ final class FTabsStyle with Diagnosticable { /// The padding. final EdgeInsets padding; - /// The [TextStyle] of the label - final TextStyle unselectedLabel; - - /// The [TextStyle] of the label + /// The [TextStyle] of the label. final TextStyle selectedLabel; + /// The [TextStyle] of the label. + final TextStyle unselectedLabel; + /// The indicator. final BoxDecoration indicator; @@ -48,8 +48,8 @@ final class FTabsStyle with Diagnosticable { FTabsStyle({ required this.decoration, required this.padding, - required this.unselectedLabel, required this.selectedLabel, + required this.unselectedLabel, required this.indicator, required this.indicatorSize, required this.height, @@ -64,15 +64,15 @@ final class FTabsStyle with Diagnosticable { color: colorScheme.muted, ), padding = const EdgeInsets.all(4), - unselectedLabel = typography.sm.copyWith( + selectedLabel = typography.sm.copyWith( fontWeight: FontWeight.w500, fontFamily: typography.defaultFontFamily, - color: colorScheme.mutedForeground, + color: colorScheme.foreground, ), - selectedLabel = typography.sm.copyWith( + unselectedLabel = typography.sm.copyWith( fontWeight: FontWeight.w500, fontFamily: typography.defaultFontFamily, - color: colorScheme.foreground, + color: colorScheme.mutedForeground, ), indicatorSize = FTabBarIndicatorSize.tab, indicator = BoxDecoration( @@ -111,8 +111,8 @@ final class FTabsStyle with Diagnosticable { properties ..add(DiagnosticsProperty('decoration', decoration)) ..add(DiagnosticsProperty('padding', padding)) - ..add(DiagnosticsProperty('unselectedLabel', unselectedLabel)) ..add(DiagnosticsProperty('selectedLabel', selectedLabel)) + ..add(DiagnosticsProperty('unselectedLabel', unselectedLabel)) ..add(EnumProperty('indicatorSize', indicatorSize)) ..add(DiagnosticsProperty('indicator', indicator)) ..add(DoubleProperty('height', height)) From fccd640e007eccfbd5855656db4ea474a2c121fa Mon Sep 17 00:00:00 2001 From: Matthias Ngeo Date: Tue, 20 Aug 2024 19:51:02 +0800 Subject: [PATCH 2/6] Refactor textfield --- .../lib/src/widgets/tabs/tab_controller.dart | 2 +- .../{text_form_field.dart => field.dart} | 13 ++++--- .../src/widgets/text_field/text_field.dart | 10 ++---- .../text_field/text_field_state_style.dart | 35 +++---------------- .../widgets/text_field/text_field_style.dart | 20 +++-------- forui/lib/widgets/text_field.dart | 2 ++ 6 files changed, 21 insertions(+), 61 deletions(-) rename forui/lib/src/widgets/text_field/{text_form_field.dart => field.dart} (97%) diff --git a/forui/lib/src/widgets/tabs/tab_controller.dart b/forui/lib/src/widgets/tabs/tab_controller.dart index caa1bd716..55e9a190a 100644 --- a/forui/lib/src/widgets/tabs/tab_controller.dart +++ b/forui/lib/src/widgets/tabs/tab_controller.dart @@ -47,4 +47,4 @@ final class FTabController implements ChangeNotifier { @override void dispose() => _controller.dispose(); -} \ No newline at end of file +} diff --git a/forui/lib/src/widgets/text_field/text_form_field.dart b/forui/lib/src/widgets/text_field/field.dart similarity index 97% rename from forui/lib/src/widgets/text_field/text_form_field.dart rename to forui/lib/src/widgets/text_field/field.dart index 8b934405a..138222741 100644 --- a/forui/lib/src/widgets/text_field/text_form_field.dart +++ b/forui/lib/src/widgets/text_field/field.dart @@ -1,6 +1,9 @@ -part of 'text_field.dart'; +import 'package:flutter/material.dart'; +import 'package:forui/forui.dart'; +import 'package:meta/meta.dart'; -class _Field extends FormField { +@internal +class Field extends FormField { static InputDecoration _decoration( _State state, FTextField parent, @@ -62,7 +65,7 @@ class _Field extends FormField { final FTextField parent; - _Field({ + Field({ required this.parent, required FTextFieldStyle style, super.key, @@ -204,7 +207,7 @@ class _State extends FormFieldState { } @override - void didUpdateWidget(_Field old) { + void didUpdateWidget(Field old) { super.didUpdateWidget(old); if (widget.parent.controller == old.parent.controller) { return; @@ -262,7 +265,7 @@ class _State extends FormFieldState { } @override - _Field get widget => super.widget as _Field; + Field get widget => super.widget as Field; TextEditingController get _effectiveController => widget.parent.controller ?? _controller!.value; } diff --git a/forui/lib/src/widgets/text_field/text_field.dart b/forui/lib/src/widgets/text_field/text_field.dart index 8829ea4fd..773300ad2 100644 --- a/forui/lib/src/widgets/text_field/text_field.dart +++ b/forui/lib/src/widgets/text_field/text_field.dart @@ -3,15 +3,9 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; - import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:meta/meta.dart'; - import 'package:forui/forui.dart'; - -part 'text_field_state_style.dart'; -part 'text_field_style.dart'; -part 'text_form_field.dart'; +import 'package:forui/src/widgets/text_field/field.dart'; /// A text field. /// @@ -738,7 +732,7 @@ final class FTextField extends StatelessWidget { primaryColor: style.cursorColor, ), ), - child: _Field( + child: Field( parent: this, style: style, key: key, diff --git a/forui/lib/src/widgets/text_field/text_field_state_style.dart b/forui/lib/src/widgets/text_field/text_field_state_style.dart index e55ebbcfd..87ad8c371 100644 --- a/forui/lib/src/widgets/text_field/text_field_state_style.dart +++ b/forui/lib/src/widgets/text_field/text_field_state_style.dart @@ -1,4 +1,7 @@ -part of 'text_field.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:forui/forui.dart'; +import 'package:meta/meta.dart'; /// A [FTextField] state's style. sealed class FTextFieldStateStyle with Diagnosticable { @@ -89,21 +92,6 @@ final class FTextFieldNormalStyle extends FTextFieldStateStyle { }) : super.inherit(formFieldStateStyle: formFieldNormaStyle); /// Returns a copy of this [FTextFieldStateStyle] with the given properties replaced. - /// - /// ```dart - /// final style = FTextFieldNormalStyle( - /// labelTextStyle: ..., - /// contentTextStyle: ..., - /// // Other arguments omitted for brevity - /// ); - /// - /// final copy = style.copyWith( - /// contentTextStyle: ..., - /// ); - /// - /// print(style.labelTextStyle == copy.labelTextStyle); // true - /// print(style.contentTextStyle == copy.contentTextStyle); // false - /// ``` @useResult FTextFieldNormalStyle copyWith({ TextStyle? labelTextStyle, @@ -180,21 +168,6 @@ final class FTextFieldErrorStyle extends FTextFieldStateStyle { super.inherit(formFieldStateStyle: formFieldErrorStyle); /// Returns a copy of this [FTextFieldStateStyle] with the given properties replaced. - /// - /// ```dart - /// final style = FTextFieldErrorStyle( - /// labelTextStyle: ..., - /// contentTextStyle: ..., - /// // Other arguments omitted for brevity - /// ); - /// - /// final copy = style.copyWith( - /// contentTextStyle: ..., - /// ); - /// - /// print(style.labelTextStyle == copy.labelTextStyle); // true - /// print(style.contentTextStyle == copy.contentTextStyle); // false - /// ``` @useResult FTextFieldErrorStyle copyWith({ TextStyle? errorTextStyle, diff --git a/forui/lib/src/widgets/text_field/text_field_style.dart b/forui/lib/src/widgets/text_field/text_field_style.dart index 2502aca63..d6d534152 100644 --- a/forui/lib/src/widgets/text_field/text_field_style.dart +++ b/forui/lib/src/widgets/text_field/text_field_style.dart @@ -1,4 +1,7 @@ -part of 'text_field.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:forui/forui.dart'; +import 'package:meta/meta.dart'; /// [FTextFieldStyle]'s style. final class FTextFieldStyle with Diagnosticable { @@ -85,21 +88,6 @@ final class FTextFieldStyle with Diagnosticable { ); /// Returns a copy of this [FTextFieldStyle] with the given properties replaced. - /// - /// ```dart - /// final style = FTextFieldStyle( - /// enabledStyle: ..., - /// disabledStyle: ..., - /// // Other arguments omitted for brevity - /// ); - /// - /// final copy = style.copyWith( - /// disabledStyle: ..., - /// ); - /// - /// print(style.enabledStyle == copy.enabledStyle); // true - /// print(style.disabledStyle == copy.disabledStyle); // false - /// ``` @useResult FTextFieldStyle copyWith({ Brightness? keyboardAppearance, diff --git a/forui/lib/widgets/text_field.dart b/forui/lib/widgets/text_field.dart index d2b398a68..55e35828b 100644 --- a/forui/lib/widgets/text_field.dart +++ b/forui/lib/widgets/text_field.dart @@ -6,3 +6,5 @@ library forui.widgets.text_field; export '../src/widgets/text_field/text_field.dart'; +export '../src/widgets/text_field/text_field_style.dart'; +export '../src/widgets/text_field/text_field_state_style.dart'; From 5a8bcec7e844bd31dd8852a6d669b433f33c94cc Mon Sep 17 00:00:00 2001 From: Matthias Ngeo Date: Tue, 20 Aug 2024 20:14:47 +0800 Subject: [PATCH 3/6] Refactor remaining widgets --- docs/pages/docs/divider.mdx | 6 +-- forui/CHANGELOG.md | 2 + forui/lib/src/widgets/checkbox.dart | 44 ++-------------- forui/lib/src/widgets/divider.dart | 23 +++++---- forui/lib/src/widgets/progress.dart | 51 +++++++------------ forui/lib/src/widgets/scaffold.dart | 19 ++++++- forui/lib/src/widgets/switch.dart | 37 +++++--------- .../test/src/widgets/divider_golden_test.dart | 10 ++-- samples/lib/widgets/divider.dart | 4 +- 9 files changed, 77 insertions(+), 119 deletions(-) diff --git a/docs/pages/docs/divider.mdx b/docs/pages/docs/divider.mdx index 57dd80cac..d60260c39 100644 --- a/docs/pages/docs/divider.mdx +++ b/docs/pages/docs/divider.mdx @@ -46,12 +46,12 @@ Visually or semantically separates content. 'Blog', style: typography.sm.copyWith(color: colorScheme.foreground), ), - const FDivider(vertical: true), + const FDivider(axis : Axis.vertical), Text( 'Docs', style: typography.sm.copyWith(color: colorScheme.foreground), ), - const FDivider(vertical: true), + const FDivider(axis : Axis.vertical), Text( 'Source', style: typography.sm.copyWith(color: colorScheme.foreground), @@ -71,5 +71,5 @@ Visually or semantically separates content. ### `FDivider(...)` ```dart -FDivider(vertical: true); +const FDivider(axis : Axis.vertical); ``` diff --git a/forui/CHANGELOG.md b/forui/CHANGELOG.md index 26641fae5..e476b138b 100644 --- a/forui/CHANGELOG.md +++ b/forui/CHANGELOG.md @@ -30,6 +30,8 @@ * **Breaking:** Rename `FButtonIconStyle.height` to `FButtonIconStyle.size`. +* **Breaking:** Change `FDivider.vertical` to `FDivider.axis`. + * Change `FResizable` to resize by `FResizable.resizePercentage` when using a keyboard. * **Breaking:** Change `FResiableDividerStyle.thickness` to `FResizableDividerStyle.width`. diff --git a/forui/lib/src/widgets/checkbox.dart b/forui/lib/src/widgets/checkbox.dart index fa7d190c9..21955aee1 100644 --- a/forui/lib/src/widgets/checkbox.dart +++ b/forui/lib/src/widgets/checkbox.dart @@ -66,10 +66,10 @@ class FCheckbox extends FFormField { @override Widget builder(BuildContext context, FormFieldState state) { final style = this.style ?? context.theme.checkboxStyle; - final stateStyle = switch ((enabled, state.hasError)) { - (true, false) => style.enabledStyle, - (false, false) => style.disabledStyle, - (_, true) => style.errorStyle, + final (labelState, stateStyle) = switch ((enabled, state.hasError)) { + (true, false) => (FLabelState.enabled, style.enabledStyle), + (false, false) => (FLabelState.disabled, style.disabledStyle), + (_, true) => (FLabelState.error, style.errorStyle), }; final value = state.value ?? initialValue; @@ -92,11 +92,7 @@ class FCheckbox extends FFormField { : null, child: FLabel( axis: Axis.horizontal, - state: switch ((enabled, state.hasError)) { - (true, false) => FLabelState.enabled, - (false, false) => FLabelState.disabled, - (_, true) => FLabelState.error, - }, + state: labelState, label: label, description: description, error: Text(state.errorText ?? ''), @@ -206,21 +202,6 @@ final class FCheckboxStyle with Diagnosticable { ); /// Returns a copy of this [FCheckboxStyle] with the given properties replaced. - /// - /// ```dart - /// final style = FCheckboxStyle( - /// animationDuration: const Duration(minutes: 1), - /// curve: Curves.linear, - /// // Other arguments omitted for brevity. - /// ); - /// - /// final copy = style.copyWith( - /// curve: Curves.bounceIn, - /// ); - /// - /// print(style.animationDuration); // const Duration(minutes: 1) - /// print(copy.curve); // Curves.bounceIn - /// ``` @useResult FCheckboxStyle copyWith({ Duration? animationDuration, @@ -296,21 +277,6 @@ final class FCheckboxStateStyle with Diagnosticable { }); /// Returns a copy of this [FCheckboxStateStyle] with the given properties replaced. - /// - /// ```dart - /// final style = FCheckBoxStateStyle( - /// iconColor: ..., - /// checkedBackgroundColor: ..., - /// // Other arguments omitted for brevity. - /// ); - /// - /// final copy = style.copyWith( - /// checkedBackgroundColor: ..., - /// ); - /// - /// print(style.iconColor == copy.iconColor); // true - /// print(style.checkedBackgroundColor == copy.checkedBackgroundColor); // false - /// ``` @useResult FCheckboxStateStyle copyWith({ Color? borderColor, diff --git a/forui/lib/src/widgets/divider.dart b/forui/lib/src/widgets/divider.dart index 2556b5ff1..b24697b0e 100644 --- a/forui/lib/src/widgets/divider.dart +++ b/forui/lib/src/widgets/divider.dart @@ -16,23 +16,24 @@ final class FDivider extends StatelessWidget { /// The divider's style. Defaults to the appropriate style in [FThemeData.dividerStyles]. final FDividerStyle? style; - /// True if this divider is vertical. Defaults to false (horizontal). - final bool vertical; + /// The axis. Defaults to horizontal. + final Axis axis; /// Creates a [FDivider]. - const FDivider({this.style, this.vertical = false, super.key}); + const FDivider({this.style, this.axis = Axis.horizontal, super.key}); @override Widget build(BuildContext context) { - final style = - this.style ?? (vertical ? context.theme.dividerStyles.vertical : context.theme.dividerStyles.horizontal); - final (height, width) = vertical ? (null, style.width) : (style.width, null); + final style = this.style ?? switch (axis) { + Axis.horizontal => context.theme.dividerStyles.horizontal, + Axis.vertical => context.theme.dividerStyles.vertical, + }; return Container( margin: style.padding, color: style.color, - height: height, - width: width, + height: axis == Axis.horizontal ? style.width : null, + width: axis == Axis.vertical ? style.width : null, ); } @@ -40,8 +41,8 @@ final class FDivider extends StatelessWidget { void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties - ..add(FlagProperty('vertical', value: vertical, defaultValue: false, ifTrue: 'vertical')) - ..add(DiagnosticsProperty('style', style)); + ..add(DiagnosticsProperty('style', style)) + ..add(EnumProperty('axis', axis)); } } @@ -110,7 +111,7 @@ final class FDividerStyle with Diagnosticable { /// The padding surrounding the separating line. Defaults to the appropriate padding in [defaultPadding]. final EdgeInsetsGeometry padding; - /// The width of the separating line. Defaults to 1. + /// The width (thickness) of the separating line. Defaults to 1. /// /// ## Contract /// Throws [AssertionError] if: diff --git a/forui/lib/src/widgets/progress.dart b/forui/lib/src/widgets/progress.dart index d9e43f4ae..b5fb82bf4 100644 --- a/forui/lib/src/widgets/progress.dart +++ b/forui/lib/src/widgets/progress.dart @@ -13,25 +13,24 @@ import 'package:forui/forui.dart'; /// * https://forui.dev/docs/progress for working examples. /// * [FProgressStyle] for customizing a progress's appearance. class FProgress extends StatelessWidget { + /// The style. Defaults to [FThemeData.progressStyle]. + final FProgressStyle? style; + /// If non-null, the value of this progress indicator. /// /// A value of 0.0 means no progress and 1.0 means that progress is complete. - /// The value will be clamped to be in the range 0.0-1.0. + /// The value will be clamped to be in the range, `[0.0, 1.0]`. /// /// ## Contract - /// Throws [AssertionError] if: - /// * [value] is NaN + /// Throws [AssertionError] if [value] is NaN final double value; - /// The style. Defaults to [FThemeData.progressStyle]. - final FProgressStyle? style; - /// Creates a [FProgress]. FProgress({ required this.value, this.style, super.key, - }) : assert(!value.isNaN, 'Cannot provide a NaN value'); + }) : assert(!value.isNaN, 'Cannot provide a NaN value.'); @override Widget build(BuildContext context) { @@ -68,8 +67,8 @@ class FProgress extends StatelessWidget { void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties - ..add(DoubleProperty('value', value)) - ..add(DiagnosticsProperty('style', style)); + ..add(DiagnosticsProperty('style', style)) + ..add(DoubleProperty('value', value)); } } @@ -113,30 +112,7 @@ final class FProgressStyle with Diagnosticable { animationDuration = const Duration(milliseconds: 500), curve = Curves.ease; - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('progressDecoration', progressDecoration)) - ..add(DiagnosticsProperty('backgroundDecoration', backgroundDecoration)) - ..add(DiagnosticsProperty('constraints', constraints)) - ..add(DiagnosticsProperty('animationDuration', animationDuration)) - ..add(DiagnosticsProperty('curve', curve)); - } - /// Returns a copy of this [FProgressStyle] with the given properties replaced. - /// - /// ```dart - /// final style = FProgressStyle( - /// backgroundDecoration: ..., - /// progressDecoration: ..., - /// ); - /// - /// final copy = style.copyWith(progressDecoration: ...); - /// - /// print(style.backgroundDecoration == copy.backgroundDecoration); // true - /// print(style.progressDecoration == copy.progressDecoration); // false - /// ``` @useResult FProgressStyle copyWith({ BoxDecoration? backgroundDecoration, @@ -153,6 +129,17 @@ final class FProgressStyle with Diagnosticable { curve: curve ?? this.curve, ); + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty('progressDecoration', progressDecoration)) + ..add(DiagnosticsProperty('backgroundDecoration', backgroundDecoration)) + ..add(DiagnosticsProperty('constraints', constraints)) + ..add(DiagnosticsProperty('animationDuration', animationDuration)) + ..add(DiagnosticsProperty('curve', curve)); + } + @override bool operator ==(Object other) => identical(this, other) || diff --git a/forui/lib/src/widgets/scaffold.dart b/forui/lib/src/widgets/scaffold.dart index 8f1e6d967..a46c577a7 100644 --- a/forui/lib/src/widgets/scaffold.dart +++ b/forui/lib/src/widgets/scaffold.dart @@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:forui/forui.dart'; +import 'package:meta/meta.dart'; /// A scaffold. /// @@ -62,8 +63,8 @@ class FScaffold extends StatelessWidget { void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties - ..add(FlagProperty('pad', value: contentPad, defaultValue: true, ifTrue: 'pad')) - ..add(DiagnosticsProperty('style', style)); + ..add(DiagnosticsProperty('style', style)) + ..add(FlagProperty('contentPad', value: contentPad, defaultValue: true, ifTrue: 'pad')); } } @@ -103,6 +104,20 @@ final class FScaffoldStyle with Diagnosticable { ), ); + /// Returns a copy of this style with the provided properties replaced. + @useResult + FScaffoldStyle copyWith({ + Color? backgroundColor, + EdgeInsets? contentPadding, + BoxDecoration? headerDecoration, + BoxDecoration? footerDecoration, + }) => FScaffoldStyle( + backgroundColor: backgroundColor ?? this.backgroundColor, + contentPadding: contentPadding ?? this.contentPadding, + headerDecoration: headerDecoration ?? this.headerDecoration, + footerDecoration: footerDecoration ?? this.footerDecoration, + ); + @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); diff --git a/forui/lib/src/widgets/switch.dart b/forui/lib/src/widgets/switch.dart index 8419e0802..6b9fb3895 100644 --- a/forui/lib/src/widgets/switch.dart +++ b/forui/lib/src/widgets/switch.dart @@ -162,9 +162,9 @@ class FSwitch extends StatelessWidget { ..add(StringProperty('semanticLabel', semanticLabel)) ..add(FlagProperty('autofocus', value: autofocus, defaultValue: false, ifTrue: 'autofocus')) ..add(EnumProperty('dragStartBehavior', dragStartBehavior, defaultValue: DragStartBehavior.start)) - ..add(DiagnosticsProperty('onChange', onChange)) + ..add(ObjectFlagProperty.has('onChange', onChange)) ..add(DiagnosticsProperty('focusNode', focusNode)) - ..add(DiagnosticsProperty('onFocusChange', onFocusChange)) + ..add(ObjectFlagProperty.has('onFocusChange', onFocusChange)) ..add(ObjectFlagProperty.has('onSave', onSave)) ..add(ObjectFlagProperty.has('validator', validator)) ..add(DiagnosticsProperty('initialValue', initialValue)) @@ -203,30 +203,7 @@ final class FSwitchStyle with Diagnosticable { thumbColor = colorScheme.background, focusColor = colorScheme.primary; - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(ColorProperty('checkedColor', checkedColor)) - ..add(ColorProperty('uncheckedColor', uncheckedColor)) - ..add(ColorProperty('thumbColor', thumbColor)) - ..add(ColorProperty('focusColor', focusColor)); - } - /// Returns a copy of this [FSwitchStyle] with the given properties replaced. - /// - /// ```dart - /// final style = FSwitchStyle( - /// checkedColor: Colors.black, - /// uncheckedColor: Colors.white, - /// // Other arguments omitted for brevity - /// ); - /// - /// final copy = style.copyWith(uncheckedColor: Colors.blue); - /// - /// print(copy.checkedColor); // black - /// print(copy.uncheckedColor); // blue - /// ``` @useResult FSwitchStyle copyWith({ Color? checkedColor, @@ -241,6 +218,16 @@ final class FSwitchStyle with Diagnosticable { focusColor: focusColor ?? this.focusColor, ); + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(ColorProperty('checkedColor', checkedColor)) + ..add(ColorProperty('uncheckedColor', uncheckedColor)) + ..add(ColorProperty('thumbColor', thumbColor)) + ..add(ColorProperty('focusColor', focusColor)); + } + @override bool operator ==(Object other) => identical(this, other) || diff --git a/forui/test/src/widgets/divider_golden_test.dart b/forui/test/src/widgets/divider_golden_test.dart index a2815eb13..c9da90867 100644 --- a/forui/test/src/widgets/divider_golden_test.dart +++ b/forui/test/src/widgets/divider_golden_test.dart @@ -11,8 +11,8 @@ import '../test_scaffold.dart'; void main() { group('FDivider', () { for (final (name, theme, _) in TestScaffold.themes) { - for (final (orientation, value) in [('horizontal', false), ('vertical', true)]) { - testWidgets('$name - $orientation', (tester) async { + for (final axis in Axis.values) { + testWidgets('$name - $axis', (tester) async { final children = [ Container( width: 100, @@ -22,7 +22,7 @@ void main() { border: Border.all(color: theme.colorScheme.secondary), ), ), - FDivider(vertical: value), + FDivider(axis: axis), Container( width: 100, height: 100, @@ -36,7 +36,7 @@ void main() { await tester.pumpWidget( TestScaffold( data: theme, - child: value + child: axis == Axis.horizontal ? Row( mainAxisAlignment: MainAxisAlignment.center, children: children, @@ -50,7 +50,7 @@ void main() { await expectLater( find.byType(TestScaffold), - matchesGoldenFile('divider/$name-$orientation.png'), + matchesGoldenFile('divider/$name-$axis.png'), ); }); } diff --git a/samples/lib/widgets/divider.dart b/samples/lib/widgets/divider.dart index bf0412868..7ef9a2244 100644 --- a/samples/lib/widgets/divider.dart +++ b/samples/lib/widgets/divider.dart @@ -46,12 +46,12 @@ class DividerPage extends SampleScaffold { 'Blog', style: typography.sm.copyWith(color: colorScheme.foreground), ), - const FDivider(vertical: true), + const FDivider(axis : Axis.vertical), Text( 'Docs', style: typography.sm.copyWith(color: colorScheme.foreground), ), - const FDivider(vertical: true), + const FDivider(axis : Axis.vertical), Text( 'Source', style: typography.sm.copyWith(color: colorScheme.foreground), From 5e774e594be82f7366e967e8b8517f1053afeb3d Mon Sep 17 00:00:00 2001 From: Pante Date: Tue, 20 Aug 2024 12:16:50 +0000 Subject: [PATCH 4/6] Commit from GitHub Actions (Forui Samples Presubmit) --- samples/lib/widgets/divider.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/lib/widgets/divider.dart b/samples/lib/widgets/divider.dart index 7ef9a2244..28b4a37ef 100644 --- a/samples/lib/widgets/divider.dart +++ b/samples/lib/widgets/divider.dart @@ -46,12 +46,12 @@ class DividerPage extends SampleScaffold { 'Blog', style: typography.sm.copyWith(color: colorScheme.foreground), ), - const FDivider(axis : Axis.vertical), + const FDivider(axis: Axis.vertical), Text( 'Docs', style: typography.sm.copyWith(color: colorScheme.foreground), ), - const FDivider(axis : Axis.vertical), + const FDivider(axis: Axis.vertical), Text( 'Source', style: typography.sm.copyWith(color: colorScheme.foreground), From 58a031728d297a9edbcf231696a1d03fff1abceb Mon Sep 17 00:00:00 2001 From: Matthias Ngeo Date: Tue, 20 Aug 2024 22:50:10 +0800 Subject: [PATCH 5/6] Fix failing tests --- forui/lib/src/widgets/divider.dart | 2 +- ...ntal.png => zinc-dark-Axis.horizontal.png} | Bin 24534 -> 24533 bytes ...rtical.png => zinc-dark-Axis.vertical.png} | Bin 23269 -> 23268 bytes ...tal.png => zinc-light-Axis.horizontal.png} | Bin 23746 -> 23747 bytes ...tical.png => zinc-light-Axis.vertical.png} | Bin 22810 -> 22813 bytes .../test/src/widgets/divider_golden_test.dart | 2 +- 6 files changed, 2 insertions(+), 2 deletions(-) rename forui/test/golden/divider/{zinc-dark-horizontal.png => zinc-dark-Axis.horizontal.png} (64%) rename forui/test/golden/divider/{zinc-dark-vertical.png => zinc-dark-Axis.vertical.png} (60%) rename forui/test/golden/divider/{zinc-light-horizontal.png => zinc-light-Axis.horizontal.png} (66%) rename forui/test/golden/divider/{zinc-light-vertical.png => zinc-light-Axis.vertical.png} (74%) diff --git a/forui/lib/src/widgets/divider.dart b/forui/lib/src/widgets/divider.dart index b24697b0e..92f80da6a 100644 --- a/forui/lib/src/widgets/divider.dart +++ b/forui/lib/src/widgets/divider.dart @@ -33,7 +33,7 @@ final class FDivider extends StatelessWidget { margin: style.padding, color: style.color, height: axis == Axis.horizontal ? style.width : null, - width: axis == Axis.vertical ? style.width : null, + width: axis == Axis.horizontal ? null : style.width, ); } diff --git a/forui/test/golden/divider/zinc-dark-horizontal.png b/forui/test/golden/divider/zinc-dark-Axis.horizontal.png similarity index 64% rename from forui/test/golden/divider/zinc-dark-horizontal.png rename to forui/test/golden/divider/zinc-dark-Axis.horizontal.png index 451c6b2ca849bef4a58fb1e65662abf8821a0940..b369b559be7c02ae2c79d39ad22a7d279990edfb 100644 GIT binary patch literal 24533 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 literal 24534 zcmeHPdsI`$)<38PY(=qFuoQx|t@NQ{D=&G7S}bxaSgSk)4OA^4Z;(d_5U8}J79qE? zDoTJ@^@4^%#K11AWj6MYBFxLYCa{toglocMWO6xzJQrUXx<}K!19@@;_ zXcpcHOsk&ctQot=_TG5OIO3JuQ?}oIx#qc#{JPO|7Jc{+akiJA8%(VFeoQkM2rv*p ze>xD1*LlG9jhii0&eEi+fCgz5o*q(GsDCSW?o2}ljUOH&RaMkWV`H5t_1-T^0=fE;v9Y^29By2rsV^_Dk0q}L)mUd&!NIBDl>%pc8q@T9_&41g0bSKT&B$7(2b;f*# zEH2R5**PU!f2+L{ZZP)|Vli0X`c)pMdS>69COmeR#yF*9xK-ul!{|abH*o-Ja-fm-)qLenoi_~+Jh#4)bC7bigVJQ1#rSR^|%#2k* zAteG#97(UcSzey`Gt%;;ckBkx1H_6g^Q&wj>6$G=Wdj4^;o-05Uv&8fNN8zknUbA7 z;I5oAnVnT?`$zp?Md2?(uz@EWqwdS9X$^Zg5y7A|x3okhZj)DoJ54fCA=zNuw(xB1 zc>X51f%*%y!TXh!m5$esl;~u#SeZ;#=dy9C7u;24dx|>qT=(vcP22`*%d0mb2Gjng zSSd~>_D)#lr}M)Z7Iv%p^Fh}mGwBRZH#Y!2@sJm&&JEd)un_#eB$5Xw>0)Iwixrb- zC1-1wb@zLfDU58~moOTwuOLFWG!7;N@py`Gy>9VyRVowimI8(v7&t)D5!~VN7`lB6 z>303(#Kdt1DKqm|=2yn@x*r3oh?$u&8i8Ot=riZTjfkiw01%qE>(}|=JN;I((ijq7 z25xUr@axLr%(u>Xm<j2vl=l1$ZRZ1=qQ(<+g~TBtKHA{;)LJ z-=hk<7B@Fq^))|SIP@m8SWflv_Lf=L!PDArg*ZG3y9KwtRt4m|u;dC>KVvfW1=uCx z4jOt-$2rD0Njqps*<;GsN$bspTH^&{zzWc<||gQxJrn1;D_Jty^qI!!~cstU(wEFc4rM z__I2=@-WoTXYTY{bx*Cm{%q+-gzi@v=!WUNoKTcI5Z*z#Y1o<|F8yyP!F}a9X}I-< zk;RnK9A$flkjK`)5ZO_^ZG$)3eISjQaa%Y$cxOl{eAto@ZRp;8-##bhG~wSc9qCXc zGRg&`KoC%at5U*OSq|sbmU1>d$kDhu#{}aU8g#^}eVqk7gPN+wwMul(WI5#soEyP4eAtTf#KSYlz-Ro{dSn)~Zs;UaE4&akq%X&uz zp)}#x1DDNHy&%@I@N_s+UBL#b5Q_tM`oXy&mWe@fKvbI>8}H06jE-{Pn8uBjVWJY6|7G}os}-RTF@RhCJaLUG9%2@mBjid7CgK&BZWqR`AP z6OnB_gG<-VySeS%dzWlmnUef$CfgUp4Nl|n-_l`;17An@BVLqD3;=C11RyeSIy6+A z)D(ICUAa2k!Ad0Y{FPZ;{ZZkLb+^1f9sl;7U6b!}^opjOgJJs*-oA}XZn)g{Iel{A z;_Wc?F|RARdw%|+*ZW_RbhErR_Gm+cvm;gDRszq^{5PoXt6n4XQb@})w*R~Y-bf@6 z?z9j60HES6G>R92aF`?}KsYwR93aOJ)QnG0*WMa~1tp`)BzdHgTBv-MtRKIpkCfK; zY3_oU0f?*x)17UOm?r;2tn}v$RFOELIufTOJjhqLG|1+MAD_{tfPhNM?ziBs5S%^< z;tbG*LSYHNu;sNgMwtQ-b68wlY;L+P4u9hzys(qVoWmH9VvK zYe2)nyDaNY?K-4p2&#&ez3gNdVl@va&L9q(h&FG_D~fE9-Px8YjgC-b(0F)Yk8*Z=l&U|* zki^XW7%PPhu}+tjS7hXQ|JJQrAPXXM+o&8IYykNAFQ>M6Y6Xr~1*wbLrRJ6_ z=6J$3IeS5)qK(WbWh4hHu~wU&hh%tcS28>xB}4;(LZl$IKHMq~U?D6*Y zgr{%49qb15yP;#+27H&w$_SU#{;ySx3; zl(5g&*!U#DN`9+}#kvDN%9hj3VO1Hj2XZ->2;WMEZ29Tan_!ecMq56}(^XY<$zZoP z(gBPF)(;zKn%f_pFbJ5v$u{OLM z)R<1JzBqJhi5)K!+DBg*lU-Em3y1{aaZ+U88y1P3CTBo_!rtwv7!Ej97k-Z z<`~{F5MUsHFc4rM_%9Ify|)9O$~F@IzW~59f-g)<|D`2VF_>nc|5eSHF!1y=B{&NQ zXux85c2RkD6+AJ^Xhb(*_o^N8YSh--gS?IYoEm?%uleQOm*dtZZgRSMmRUNN%}o7y zOKHM)Yi^p{eY;|4yfx6g=U(rVnD34CPu88Fc7uR`98lt%Q8eD|z8PhBk)+F36~{qZ zC=;d2l_>eb@rmp{Jjg*zB&_9rXkwBlRf?jT+TbuZ_hXc!;P@huNJHG`DH(h@CvRj% zt65lBAm)7xs^k=-hb!Gn057Y>(|KFY9;p;2CMQ2o9D>eT+t?J0Jrht5ik067n#0`1 z5QBH8*;02X-U;GfNJx4*$Nou(WD7Eaa>A0bt0m(E#RTTdjI zO$FOnTVK{@ws`0X@vuaM9VjjA0VL3bu3eZKR9ri<-R;yGmQzvZxy+^c#Eh1f7R|Hw zKwY^Hsye$w(sFDDo5Rs>{SqQX0cLK+kSuGKRMH0hbS$WtgJyBuFU=A?cJ1nJ7*!~= zK|3tqUM=$57lD3Q9#kroES1i#w}b;Y_ScbU4B-QCE>tl-o|LiABg@(E=zuC=D0Zla(jDw-kjPJ^a1L#l2NIBK$sx~oSamp*9KkQV7srd^W6P5f9}V7t{>^(k*PTM z^YK6_3fGEMcm}`OxJaSc#Muvu(9ubHrO?{eHr^AQr&SCMWiBl*szJ3S&x}Ql ziZB=Veua>uk0xHY;6YkcIZtl}ZKmjGv`9~DAJVyacw|jUh-_R$M8w%9mZaxhxt`zC z(?ifN7uN#y%4fg<;0~=;TNnUqiT)j;rFpRp4p$gT(oT^R&am-hkSa^e%5n^-5*79u z2}G@}t=9yjih07aaFHjGh-**nN_(&#G$&M}>7#B|`b_E$iw&VRnqsL`nwY`FQTX98 zPL#y721)C|u)ys_o!9*A&bpQrjwQQ>Gj#7$_{-BE3ACqMz$x%tob2<#zdD?~G{jC52PgFbU2K15L-0)ki*DpdiSExE?mbetPndvYrH@j!fsN+oM#GHue* z(i9p^s<;UB50TK74i_PFt@LfA0RHU%!vRJ#b%s7c)rge0{()C`A>cs1&iUhSN&axS zY#XxpkSbW`aLfh0FtxzD3v!ubXjxGOwuq4PCx|+*y#@YZ2XbLs?(-jZVwMPY5ReNq z(9eJ4i}@`psDLon0&^`4V8CoBWEcEEDTV<2-ov}tN8ynYN3x67b1qxSQ{ev zEG-cP0gtTueGPEme9pA6uhE5p>BO)>V1U2?0b#2FTMhqHCc`MHzfsw7W&aecQlCS9 KUNr~9F8&9sQJ|;* diff --git a/forui/test/golden/divider/zinc-dark-vertical.png b/forui/test/golden/divider/zinc-dark-Axis.vertical.png similarity index 60% rename from forui/test/golden/divider/zinc-dark-vertical.png rename to forui/test/golden/divider/zinc-dark-Axis.vertical.png index 694944d976301cd82ebc49944228313dd798d7ea..494e6ec7b75db6c29d8e4fbec7ba63672211bb73 100644 GIT binary patch delta 2910 zcmZ8jdr(t%7QTs4WJOR|&{Bwf;><1@Tb_mxYprFS3Tdl=pac{o$a^#d@_?I`+0vGU z=(4TF7~)7P8Vp232u(Bww$3S@L#(|DPl`{2dst zaxvw52znJd_Wt3Ml0|<$7LF+Q0eKcqg~y-J&9+_3J{cc&cT#+3viOu{Qf$?7(sPuQ zVWzTWFxPGwSEPmpNK-|txSHUsD9rgN3Ydww&j(khNwmh^D6MJa*lKR9WGH zgE`?sjYcC^Dn%pt)90cN{mbaa{;R?hf+o6mWPo$*%EhuX{S6yQbq}A^38V$5d!F9^ zriYg*N&@)uloUqWwz+R_UC52j7hd>$Fud{F@sNo6mvpm-4J$iG^=2!3+eNipvdQ7F+AM5R>x)tAvrM|*LhM`!kZ6x4SPZ_Y zI(K0AK=m$sF2QIW%YzN=EiEm%B*9>|WVVDfp`NrVcI-1heta__A;C1O(^#l+aovCb zAtpxDZcjU?>MO)nxNRy??14y+-|byxfBv*NklSr!0U7%G5@J=Jj{Whv0ox27M~t*A z(^FvQi>9*a;L@&DDgY$W#{(qwN|gr;p8BN92RA6n)r|-47PHyR+*tM5)$ysdJym3~ zn-7`h4Q7jSvFsDI%c&;gwzykI;=B4m`5`FF?G!jJSbYApC$Q!N<07Cek?1H?EKZ=) z>Es>XmUcI4Z&NzUM$E_a@d{6eKPp7g8(oOb9((upo8X6a7fRU`6&7uB7dedAn;RKp zt!>g>;9tMKMDR0o1F~D<(-|+NLiL4lw zjQldi=Zv)#oR*9*O4-H5znY0lK(h9~8{I$<19g@V>5I&hk-Ye{^mKcyuXqYHoIIw+ zt4agjz~$T@@xY0O&EBVO9(goAZl&M@swq@VnRR+v^CE{}bUmgr*a++qq;~|qXgO$$ zIrqv8=1|D0EN8i1UuhdoaoGPa=p-<+iK6J)D&A)qKmTK91D$Jh%YOr{>IoQ0m@yL( zuT!cNistqL7T;q+*_(Z$w6xT?SgdC++K4#1pIC%;4%rhph{KNx@>UF+?egIih(vdF z4uos)72kAg0P%X1_+_LDdd7-cYJELQToB3gnfZS0V{a}GlPeB*CM(XBNBrZp87<(AHZF{*-zIJnhe7m&a;gYh)uIyW<~Ny zj+BNyAnYjohq#!kxQ2JIb6-)cx{VwH9|%J32YIjjFYgT@n82c8vrw2TGeqq6x`y-A zUjqJoH1AT$Q$$I2=f=(1D`n>Zw>(t7{>`zmU@)0IrSaP|r(7PhTf zUCs10b!-0ShyZD~gR_Zg(sCXpbw6v7PDldz^eHGu0B;qbQI#xHF%d1OE-vMto zhG~fk&zygv{a=Er9y4uY@CAaRR&H%ALWkhDu)e)YW{sGcp+*S$U*Ugg1U%q)6rrjH zB@-4>SB(_Qyy(#DKH$WK;kbE3CyiU*dkd`3KyV~83PawUkaRQ)J~}q`4j9JscCGef zWyMCE)ZqM!`+5*)ABx)92=tq04G#~OT)g;vLXZiA-H|Cl2D3^~l#M*#49UoVLFO7b zcTcYZrZ)BR4w)Ag#M%)~`uODJStY|pwKJ9Ttm>a`j;S`95U!GYin)-9w^4=alhlV6 zWXOK?XiF6lNEL~d4RK(Cid zXyNh|7L`gZVH~`W)shy{wMqaxZYSE%{jZ@r&f93I22*yW!TX~`>6!g`;L5-zHQSlx zW)JT9M}9) z^{#j>cKx$4HJlETOHcj6!<}#P6sy2gUEhj~f>%pj0vXVDA+h?WPN#FN)wHrUXtpLJCl+cp~XKAD$dTF!n z;O)xFgy5i{fd>x`>oT$A9BJxcu2lH+;)}^)Gx!#u#>3Ub0`*GKqHsS%w^Uu|)gG{< z^O;_d{ytK42$!yy1(bgORU~3VC7FL_czD@>6^dELl88LC_t&4?AzlDCrtZgrfbul%v2(Y|n9C+0Nr_Sn&c K_gmh}`0T%x+=Q(F literal 23269 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 diff --git a/forui/test/golden/divider/zinc-light-horizontal.png b/forui/test/golden/divider/zinc-light-Axis.horizontal.png similarity index 66% rename from forui/test/golden/divider/zinc-light-horizontal.png rename to forui/test/golden/divider/zinc-light-Axis.horizontal.png index 3d89450956c14d4d56e929db090de269e083efb2..302a8f1bbeed8e6eb19571674bcd0edf50f2e4fb 100644 GIT binary patch delta 3551 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 literal 23746 zcmeHPdstJ)w%>pvC<49^m510`M9~1^5hxF}D53(2S|keSvAG_M;VCckAg#UVIj2Ic zLIee`p9PAT@X#bY4CEF|PK}x>ny3L1NiEfgiH0OV2%MR{q1t=@yWjcFZNKjQNA_f9 z?U|LyZ)UCET9f>BdvwIi=?kYL2r@Hrb9gL**zQM=X*M?2pr+~J$P{q1$c&BHfN<`* zJO^*4WNwJuWdkmn%_k=jWHAyMzJ6Ekg_lp(&qO>Ng+kRRHPQbE2anPn+bt4SuXYEI zV3%l2ZZTO#>iqWq@+REcd$OMS59ZX#vg3mK$s)4E%4xE^?h~QqWcj4sp2;F|+G56J zc`@Gk>;3-}_!_m&AP;9D+kEGD3U+fdxKn1BNAap8{W1Qc)=8fO+0P{0Wn z&O;}lfYWn4YB2!?Jh1S44J_0@Ze{g!rmvZPd2UvE?|AaTgm2t_ynZk)ZfZ~KkISkX zogCNs9bvv_f08h2Yx{QV+hF`7zaW5yjhXb= zD7emJ(G}u0exv44oz0MULfjVF!~0nYHQW^mvU0)uQ0(Gt)DcM9L}nk6e=N;f!RB6L zSKHw7_K+Dw14>N zH6ppRs%B7-W;v9@V;ARDY$Xpo)g_nR3b6NNLxqP5r$7oMtZq)MBPH^cN@IHSX33XG;p>rOE9C~a zTq#j37Js*FC)DP7x7q>RgL{fzKlHKdTcO-eAh1rz2Z`iodi}A!zkxQUW&@fG3Vx^$ z3cDHCJddvS5-zX(EC-%>YgBdE?G}JmNlS@cm>XzPKQM$J(fT5ki zROnQpK;8Hf{qZCqhm5*ez;KUtE_;Af!ID!IMu)XsNU+%d6!_NUreFz4VZ^!|{T}=L zJ8$bukLrlz=6$O?Io3ldt5{oW^yVQQBL;pK0bik}Frb^qZKTKt%o(LyWaUkZmGb8; zd_jMzx}{k9^0`ou)Y6o6?^-11g>7jq0BE4P|etq{HXz-Iwc?;oNMJbAjAs&fNthnD5y@ zgU$Sit)_OTg^kQmdK;5>efW2px<}lkMGX~5&^f(L;uam ze2LIp6J$LV8s2hH$yEF_(MW%g=KdjaVZc`yi>e@+g=x}UwD9n}{T4|PY)!-^Y<@Ol zH=m;SY^LrJ%ATUhL1jGpWq>}x<$)@L7T0ZlCtrvyBDDTDvB2J*yT;LnGr^6tl~o_c!;M^^)=+p0k?ey z`TZ1m^gdhRWm8Cv#^lgu3+lBBj0bfbO~`4TN>=2|a?&n6BF|p5eh+!gXO8g6vlwrC zV7}w0UXJmgW;5iy0c8^{2btUwsbNl>6)gvl#RM53S>ODMWa;UGQy$)xXGx_o`(|o; zdNk{~p|4^<7f3|f6L@n;DXWs}T2d;x*?otZnk!s`4@1jHMS0`juu=9YWG8lfF00*J z&y;XAmHX;skdszwTu(qLQDz_PC-^%+cl)KpJi36Pr7#aB)XDBYVNi2SaDuho7-8}{ z%yyV11>C=a1qdu{zV60ZN~?QFKnbz+*Mzp~3)P;2r}Vi`8@);K;d_L-(I$yq$M(+j zQRRF%T6@Fn(f z@HAAQV2Sj}0EjK*tah>+3Nbjt)@_)QJ71dQ1O9SePpGD&srbu(3F`wJ8@^r{K zX+vwyaf55%n{84{%gvu!YEMqPIfoI}dA9JfZzUW~?T8X(Lai~8sID|79!ves%bMoS zEs0fY`vYPRZU)PMDO>tZ48FN~5qJ>27UQvbJZtgW1wj-`tp9nbhN>Rzlbs-xyIh2L>T!)FJaw3Y&J~3!Nc#!?=JlQ2imCoU9n6<{(UNe ztp_gx{(aNE6_#yV*p&~0&JxKB3W$f<5d`SRD9179iEx?wF^{qWjV9j{TO{5NuqU~Q z{0a{)ux6R8fMDGv!>jxVXbV(>y<+{bmFkvxqPfEM-Q<-ZZk|`sQwY5#mo4b>a_Ni6 z<(2?jUZi+HObttE{Zv!UHT2uuA4~qPKuKn4f8q<0rZyhiYX@FD}x$S1e<$9P=2!v3?XD;G3KNf#}YtpAaAJ0#|{{8zrt^Am5Rr_ zk3sZ2nH@6909BH%^|jE6XnPNJ2eqWT{h9Hy0Yf5rrPz;^JbNorng#oyH_alKb!G&W z+wVjDopQ{#t5yqGMx(AHYKYyBBbKi_HLen-vopZ2+O2rFWTky>|FnCvTVA@8Z=EYIst;X9h z(GYl%FpUGqAWF?yQX~RAy zher{F#B}Yt^7y#$(}GJS$z>@TqiP2n#IP7uI-ARJPwz1QOkiH_)@)R_Fy1VML*#p6 ztzEd|Zz7*F`tfOaHoD+ zL4?R&sBTi6>BeNgk6Z>M>d%{AALj;TBZ(1gy@AHx4V4-7_q+t3PI+~?!1TyM`IjP# z5=(eS;ZYIlXFs|_f8YbWJ!O_%hiJz)SlyY4CY8+wz(j(uQG)-D)`CYtJo682zBMzIGQ*SKCNG296-@g`6fnTQ{S^?9#TtFdD z<4jTBGgtT*7H$N@f@uy&hWcl(j#3Te$$3_BmfD{gF$+bn&k!K*7+Zuft@A|nfYa69 zR+|~QwjjE_$#fi{gC259 zGh-J#JtcIT;9#BUO=zA$tfQ8Kr~{(J{%(!peD-L*QNF#6Oq7` zx^+7AYT&Uygo-d_@$G#lB`d>HB4(06oL5ry>ygQg?ZY;5qElvY19;U zG2qpnNmeh_w6WuY4Bs;USD-F7f@pga6*Zlo{ymM$?~o6sm62F$3yegfVQlpV$u%jGwDYzO4(c zO8&yP%2zOogq~(yd+IEDJv+(#@@noeV(0LYVlViCoUsYLRH$-Rw-lP_)YTj$SL`39 zqJ^F!#ZN(FG#_Cr#o?gB*Z`DOrqh{MB>#mm%nN5=AanKK%}#epejT6BS{;dsGco z4SRA4ssvhI_YOV9JAeCwWqevNsDM`-EpX+cmm|K2CZ_`5ThRP5IvwHomOBZH#keJ! zoC*Xt(7&)0+_k`6i-~oC+t9Z^_r?8l$o0_+x1n!;`HkDqNmSrA^z8ve+=k*dbYfln z_H3xKE_(p|W2gOJw(DK8=SQHLov7Xa59kUhioD diff --git a/forui/test/golden/divider/zinc-light-vertical.png b/forui/test/golden/divider/zinc-light-Axis.vertical.png similarity index 74% rename from forui/test/golden/divider/zinc-light-vertical.png rename to forui/test/golden/divider/zinc-light-Axis.vertical.png index 6de5a625159a7e9a04a9d5c2f28b56bd50bfde3b..bd20e37f4fb2444f3a121fd9a91cc16e93cdfaef 100644 GIT binary patch delta 2479 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 Date: Tue, 20 Aug 2024 14:51:43 +0000 Subject: [PATCH 6/6] Commit from GitHub Actions (Forui Presubmit) --- forui/lib/src/widgets/divider.dart | 9 +++++---- forui/lib/src/widgets/scaffold.dart | 16 +++++++++------- forui/lib/src/widgets/tabs/tab_controller.dart | 18 +++++++++--------- forui/lib/src/widgets/text_field/field.dart | 4 +++- .../lib/src/widgets/text_field/text_field.dart | 2 ++ .../text_field/text_field_state_style.dart | 4 +++- .../widgets/text_field/text_field_style.dart | 6 ++++-- 7 files changed, 35 insertions(+), 24 deletions(-) diff --git a/forui/lib/src/widgets/divider.dart b/forui/lib/src/widgets/divider.dart index 92f80da6a..6dfede880 100644 --- a/forui/lib/src/widgets/divider.dart +++ b/forui/lib/src/widgets/divider.dart @@ -24,10 +24,11 @@ final class FDivider extends StatelessWidget { @override Widget build(BuildContext context) { - final style = this.style ?? switch (axis) { - Axis.horizontal => context.theme.dividerStyles.horizontal, - Axis.vertical => context.theme.dividerStyles.vertical, - }; + final style = this.style ?? + switch (axis) { + Axis.horizontal => context.theme.dividerStyles.horizontal, + Axis.vertical => context.theme.dividerStyles.vertical, + }; return Container( margin: style.padding, diff --git a/forui/lib/src/widgets/scaffold.dart b/forui/lib/src/widgets/scaffold.dart index a46c577a7..44a34c85f 100644 --- a/forui/lib/src/widgets/scaffold.dart +++ b/forui/lib/src/widgets/scaffold.dart @@ -1,9 +1,10 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; -import 'package:forui/forui.dart'; import 'package:meta/meta.dart'; +import 'package:forui/forui.dart'; + /// A scaffold. /// /// A scaffold is a layout structure that contains a header, content, and footer. @@ -111,12 +112,13 @@ final class FScaffoldStyle with Diagnosticable { EdgeInsets? contentPadding, BoxDecoration? headerDecoration, BoxDecoration? footerDecoration, - }) => FScaffoldStyle( - backgroundColor: backgroundColor ?? this.backgroundColor, - contentPadding: contentPadding ?? this.contentPadding, - headerDecoration: headerDecoration ?? this.headerDecoration, - footerDecoration: footerDecoration ?? this.footerDecoration, - ); + }) => + FScaffoldStyle( + backgroundColor: backgroundColor ?? this.backgroundColor, + contentPadding: contentPadding ?? this.contentPadding, + headerDecoration: headerDecoration ?? this.headerDecoration, + footerDecoration: footerDecoration ?? this.footerDecoration, + ); @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { diff --git a/forui/lib/src/widgets/tabs/tab_controller.dart b/forui/lib/src/widgets/tabs/tab_controller.dart index 55e9a190a..724ea6794 100644 --- a/forui/lib/src/widgets/tabs/tab_controller.dart +++ b/forui/lib/src/widgets/tabs/tab_controller.dart @@ -11,18 +11,18 @@ final class FTabController implements ChangeNotifier { int initialIndex = 0, Duration? animationDuration, }) : _controller = TabController( - initialIndex: initialIndex, - length: length, - animationDuration: animationDuration, - vsync: vsync, - ); + initialIndex: initialIndex, + length: length, + animationDuration: animationDuration, + vsync: vsync, + ); /// Animates to the given [index]. void animateTo( - int index, { - Duration? duration, - Curve curve = Curves.ease, - }) => + int index, { + Duration? duration, + Curve curve = Curves.ease, + }) => _controller.animateTo(index, duration: duration, curve: curve); @override diff --git a/forui/lib/src/widgets/text_field/field.dart b/forui/lib/src/widgets/text_field/field.dart index 138222741..861ca5fbb 100644 --- a/forui/lib/src/widgets/text_field/field.dart +++ b/forui/lib/src/widgets/text_field/field.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:forui/forui.dart'; + import 'package:meta/meta.dart'; +import 'package:forui/forui.dart'; + @internal class Field extends FormField { static InputDecoration _decoration( diff --git a/forui/lib/src/widgets/text_field/text_field.dart b/forui/lib/src/widgets/text_field/text_field.dart index 773300ad2..34914e5d8 100644 --- a/forui/lib/src/widgets/text_field/text_field.dart +++ b/forui/lib/src/widgets/text_field/text_field.dart @@ -3,7 +3,9 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; + import 'package:flutter_localizations/flutter_localizations.dart'; + import 'package:forui/forui.dart'; import 'package:forui/src/widgets/text_field/field.dart'; diff --git a/forui/lib/src/widgets/text_field/text_field_state_style.dart b/forui/lib/src/widgets/text_field/text_field_state_style.dart index 87ad8c371..b8e7d5c1c 100644 --- a/forui/lib/src/widgets/text_field/text_field_state_style.dart +++ b/forui/lib/src/widgets/text_field/text_field_state_style.dart @@ -1,8 +1,10 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:forui/forui.dart'; + import 'package:meta/meta.dart'; +import 'package:forui/forui.dart'; + /// A [FTextField] state's style. sealed class FTextFieldStateStyle with Diagnosticable { /// The label's [TextStyle]. diff --git a/forui/lib/src/widgets/text_field/text_field_style.dart b/forui/lib/src/widgets/text_field/text_field_style.dart index d6d534152..531b3b020 100644 --- a/forui/lib/src/widgets/text_field/text_field_style.dart +++ b/forui/lib/src/widgets/text_field/text_field_style.dart @@ -1,8 +1,10 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/cupertino.dart'; -import 'package:forui/forui.dart'; +import 'package:flutter/foundation.dart'; + import 'package:meta/meta.dart'; +import 'package:forui/forui.dart'; + /// [FTextFieldStyle]'s style. final class FTextFieldStyle with Diagnosticable { /// The appearance of the keyboard. Defaults to [FColorScheme.brightness].