From ab5dd68a810e180aa774a9c7d021bc89a74cc7ac Mon Sep 17 00:00:00 2001 From: dev-hann Date: Thu, 20 May 2021 20:16:15 -0300 Subject: [PATCH 1/3] Rework the inputs api --- CHANGELOG.md | 6 + example/lib/main.dart | 15 +-- lib/src/controls/form/combo_box.dart | 20 ++-- .../controls/form/pickers/date_picker.dart | 2 +- lib/src/controls/form/pickers/pickers.dart | 10 +- lib/src/controls/inputs/button.dart | 36 +++--- lib/src/controls/inputs/checkbox.dart | 10 +- lib/src/controls/inputs/hover_button.dart | 106 ++++++------------ lib/src/controls/inputs/icon_button.dart | 2 +- lib/src/controls/inputs/toggle_switch.dart | 18 +-- .../navigation/navigation_view/view.dart | 2 +- lib/src/controls/utils/scrollbar.dart | 4 +- 12 files changed, 97 insertions(+), 134 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5475c61e8..48a83df6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ Date format: DD/MM/YYYY +## [next] - [10/06/2021] + +- Reworked the inputs api ([#36](https://github.com/bdlukaa/fluent_ui/issues/36)): + - A input can have multiple states. Now, if the widget is focused and pressed at the same time, it doesn't lose its focused border. + - Now, the focus is not requested twice when the button is pressed, only once. This fixes a bug introduced in a previous version that combo boxes items we're not being focused. + ## [2.0.0] - [20/05/2021] - New way to disable the acrylic blur effect. Just wrap the acrylic widget in a `NoAcrylicBlurEffect` to have it disabled. diff --git a/example/lib/main.dart b/example/lib/main.dart index c9b890e70..467edebe5 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -68,7 +68,6 @@ class MyApp extends StatelessWidget { debugShowCheckedModeBanner: false, initialRoute: '/', routes: {'/': (_) => MyHomePage()}, - navigatorObservers: [ClearFocusOnPush()], theme: ThemeData( accentColor: appTheme.color, brightness: appTheme.mode == ThemeMode.system @@ -88,16 +87,6 @@ class MyApp extends StatelessWidget { } } -// This is the current solution for this. See https://github.com/flutter/flutter/issues/48464 -class ClearFocusOnPush extends NavigatorObserver { - @override - void didPush(Route route, Route? previousRoute) { - super.didPush(route, previousRoute); - final focus = FocusManager.instance.primaryFocus; - focus?.unfocus(); - } -} - class MyHomePage extends StatefulWidget { const MyHomePage({Key? key}) : super(key: key); @@ -212,8 +201,8 @@ class WindowButtons extends StatelessWidget { iconNormal: theme.inactiveColor, iconMouseDown: theme.inactiveColor, iconMouseOver: theme.inactiveColor, - mouseOver: ButtonThemeData.buttonColor(theme, ButtonStates.hovering), - mouseDown: ButtonThemeData.buttonColor(theme, ButtonStates.pressing), + mouseOver: ButtonThemeData.buttonColor(theme, [ButtonStates.hovering]), + mouseDown: ButtonThemeData.buttonColor(theme, [ButtonStates.pressing]), ); final closeButtonColors = WindowButtonColors( mouseOver: Colors.red, diff --git a/lib/src/controls/form/combo_box.dart b/lib/src/controls/form/combo_box.dart index 1c324c473..e84702984 100644 --- a/lib/src/controls/form/combo_box.dart +++ b/lib/src/controls/form/combo_box.dart @@ -4,6 +4,7 @@ import 'dart:ui' show window; import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; +import 'package:flutter/material.dart' as m; import 'package:fluent_ui/fluent_ui.dart'; @@ -34,7 +35,7 @@ class _ComboboxMenuPainter extends CustomPainter { this.selectedIndex, required this.resize, required this.getSelectedItemOffset, - }) : _painter = BoxDecoration( + }) : _painter = BoxDecoration( // If you add an image here, you must provide a real // configuration in the paint() function and you must provide some sort // of onChanged callback here. @@ -180,17 +181,14 @@ class _ComboboxItemButtonState extends State<_ComboboxItemButton> { opacity: opacity, child: HoverButton( autofocus: widget.itemIndex == widget.route.selectedIndex, - builder: (context, state) => Container( + builder: (context, states) => Container( decoration: BoxDecoration( color: () { - if (state.isFocused) + if (states.isFocused) return FluentTheme.of(context).accentColor.resolveFrom(context); return ButtonThemeData.uncheckedInputColor( FluentTheme.of(context), - () { - if (state.isFocused) return ButtonStates.hovering; - return state; - }(), + states, ); }(), ), @@ -1389,13 +1387,13 @@ class _ComboboxState extends State> with WidgetsBindingObserver { focusNode: focusNode, autofocus: widget.autofocus, onPressed: _enabled ? _handleTap : null, - builder: (context, state) { + builder: (context, states) { return Container( decoration: kPickerDecorationBuilder(context, () { if (_showHighlight) - return ButtonStates.focused; - else if (state.isFocused) return ButtonStates.none; - return state; + return [ButtonStates.focused]; + else if (states.isFocused) return []; + return states; }()), child: result, ); diff --git a/lib/src/controls/form/pickers/date_picker.dart b/lib/src/controls/form/pickers/date_picker.dart index b1552414c..bb4cd97b0 100644 --- a/lib/src/controls/form/pickers/date_picker.dart +++ b/lib/src/controls/form/pickers/date_picker.dart @@ -192,7 +192,7 @@ class _DatePickerState extends State { initControllers(); }, builder: (context, state) { - if (state == ButtonStates.disabled) state = ButtonStates.none; + if (state.isDisabled) state = []; final divider = Divider( direction: Axis.vertical, style: DividerThemeData( diff --git a/lib/src/controls/form/pickers/pickers.dart b/lib/src/controls/form/pickers/pickers.dart index 249ba10b8..52a0c94e0 100644 --- a/lib/src/controls/form/pickers/pickers.dart +++ b/lib/src/controls/form/pickers/pickers.dart @@ -24,16 +24,16 @@ TextStyle? kPickerPopupTextStyle(BuildContext context) { return context.theme.typography.body?.copyWith(fontSize: 16); } -Decoration kPickerDecorationBuilder(BuildContext context, ButtonStates state) { +Decoration kPickerDecorationBuilder(BuildContext context, List states) { assert(debugCheckHasFluentTheme(context)); return BoxDecoration( borderRadius: BorderRadius.circular(4.0), border: Border.all( color: () { late Color color; - if (state == ButtonStates.hovering) { + if (states.isHovering) { color = context.theme.inactiveColor; - } else if (state == ButtonStates.disabled) { + } else if (states.isDisabled) { color = context.theme.disabledColor; } else { color = context.theme.inactiveColor.withOpacity(0.75); @@ -43,9 +43,9 @@ Decoration kPickerDecorationBuilder(BuildContext context, ButtonStates state) { width: 1.0, ), color: () { - if (state == ButtonStates.pressing) + if (states.isPressing) return context.theme.disabledColor.withOpacity(0.2); - else if (state == ButtonStates.focused) { + else if (states.isFocused) { return context.theme.disabledColor.withOpacity(0.2); } }(), diff --git a/lib/src/controls/inputs/button.dart b/lib/src/controls/inputs/button.dart index 0f7a9e107..14eac83f4 100644 --- a/lib/src/controls/inputs/button.dart +++ b/lib/src/controls/inputs/button.dart @@ -307,25 +307,25 @@ class ButtonThemeData with Diagnosticable { )); } - static Color buttonColor(ThemeData style, ButtonStates state) { + static Color buttonColor(ThemeData style, List states) { if (style.brightness == Brightness.light) { late Color color; - if (state.isDisabled) + if (states.isDisabled) color = style.disabledColor; - else if (state.isPressing) + else if (states.isPressing) color = Colors.grey[70]!; - else if (state.isHovering) + else if (states.isHovering) color = Colors.grey[40]!; else color = Colors.grey[50]!; return color; } else { late Color color; - if (state.isDisabled) + if (states.isDisabled) color = style.disabledColor; - else if (state.isPressing) + else if (states.isPressing) color = Color.fromARGB(255, 102, 102, 102); - else if (state.isHovering) + else if (states.isHovering) color = Colors.grey[150]!; else color = Color.fromARGB(255, 51, 51, 51); @@ -333,26 +333,26 @@ class ButtonThemeData with Diagnosticable { } } - static Color checkedInputColor(ThemeData style, ButtonStates state) { + static Color checkedInputColor(ThemeData style, List states) { Color color = style.accentColor; - if (state.isDisabled) + if (states.isDisabled) return style.disabledColor; - else if (state.isHovering) + else if (states.isHovering) return color.withOpacity(0.70); - else if (state.isPressing) return color.withOpacity(0.90); + else if (states.isPressing) return color.withOpacity(0.90); return color; } - static Color uncheckedInputColor(ThemeData style, ButtonStates state) { + static Color uncheckedInputColor(ThemeData style, List states) { if (style.brightness == Brightness.light) { - if (state.isDisabled) return style.disabledColor; - if (state.isPressing) return Colors.grey[70]!; - if (state.isHovering) return Colors.grey[40]!; + if (states.isDisabled) return style.disabledColor; + if (states.isPressing) return Colors.grey[70]!; + if (states.isHovering) return Colors.grey[40]!; return Colors.grey[40]!.withOpacity(0); } else { - if (state.isDisabled) return style.disabledColor; - if (state.isPressing) return Colors.grey[130]!; - if (state.isHovering) return Colors.grey[150]!; + if (states.isDisabled) return style.disabledColor; + if (states.isPressing) return Colors.grey[130]!; + if (states.isHovering) return Colors.grey[150]!; return Colors.grey[150]!.withOpacity(0); } } diff --git a/lib/src/controls/inputs/checkbox.dart b/lib/src/controls/inputs/checkbox.dart index 88a75543a..8d9cef98b 100644 --- a/lib/src/controls/inputs/checkbox.dart +++ b/lib/src/controls/inputs/checkbox.dart @@ -1,5 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; +import 'package:flutter/material.dart' as m; + import 'package:fluent_ui/fluent_ui.dart'; /// A check box is used to select or deselect action items. It can @@ -69,8 +71,12 @@ class Checkbox extends StatelessWidget { properties.add(DiagnosticsProperty('style', style)); properties.add(StringProperty('semanticLabel', semanticLabel)); properties.add(DiagnosticsProperty('focusNode', focusNode)); - properties.add(FlagProperty('autofocus', - value: autofocus, defaultValue: false, ifFalse: 'manual focus')); + properties.add(FlagProperty( + 'autofocus', + value: autofocus, + defaultValue: false, + ifFalse: 'manual focus', + )); } @override diff --git a/lib/src/controls/inputs/hover_button.dart b/lib/src/controls/inputs/hover_button.dart index b56527112..b658d5e5e 100644 --- a/lib/src/controls/inputs/hover_button.dart +++ b/lib/src/controls/inputs/hover_button.dart @@ -3,7 +3,9 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; typedef ButtonStateWidgetBuilder = Widget Function( - BuildContext, ButtonStates state); + BuildContext, + List state, +); /// Base widget for any widget that requires input. It /// provides a [builder] callback to build the child with @@ -25,10 +27,10 @@ class HoverButton extends StatefulWidget { /// Creates a hover button. const HoverButton({ Key? key, + required this.builder, this.cursor, this.onPressed, this.onLongPress, - this.builder, this.focusNode, this.margin, this.semanticLabel, @@ -40,13 +42,12 @@ class HoverButton extends StatefulWidget { this.onHorizontalDragStart, this.onHorizontalDragUpdate, this.onHorizontalDragEnd, - this.onShowFocusHighlight, this.onFocusChange, this.autofocus = false, }) : super(key: key); /// The cursor of this hover button. If null, [MouseCursor.defer] is used - final MouseCursor Function(ButtonStates)? cursor; + final MouseCursor Function(List)? cursor; final VoidCallback? onLongPress; final VoidCallback? onLongPressStart; final VoidCallback? onLongPressEnd; @@ -60,7 +61,7 @@ class HoverButton extends StatefulWidget { final GestureDragUpdateCallback? onHorizontalDragUpdate; final GestureDragEndCallback? onHorizontalDragEnd; - final ButtonStateWidgetBuilder? builder; + final ButtonStateWidgetBuilder builder; /// {@macro flutter.widgets.Focus.focusNode} final FocusNode? focusNode; @@ -85,11 +86,6 @@ class HoverButton extends StatefulWidget { /// {@macro flutter.widgets.Focus.autofocus} final bool autofocus; - /// A function that will be called when the focus highlight should be shown or - /// hidden. - /// - /// This method is not triggered at the unmount of the widget. - final ValueChanged? onShowFocusHighlight; final ValueChanged? onFocusChange; @override @@ -107,10 +103,10 @@ class _HoverButtonState extends State { node = widget.focusNode ?? _createFocusNode(); void _handleActionTap() async { if (!enabled) return; - update(() => _pressing = true); + setState(() => _pressing = true); widget.onPressed?.call(); await Future.delayed(Duration(milliseconds: 100)); - update(() => _pressing = false); + setState(() => _pressing = false); } _actionMap = >{ @@ -143,7 +139,6 @@ class _HoverButtonState extends State { bool _hovering = false; bool _pressing = false; - bool _focused = false; bool _shouldShowFocus = false; bool get enabled => @@ -155,25 +150,13 @@ class _HoverButtonState extends State { widget.onLongPressStart != null || widget.onLongPressEnd != null; - ButtonStates get state => !enabled - ? ButtonStates.disabled - : _pressing - ? ButtonStates.pressing - : _hovering - ? ButtonStates.hovering - : _focused && _shouldShowFocus - ? ButtonStates.focused - : ButtonStates.none; - - void update(void Function() f) { - if (!enabled) return; - if (!mounted) return f(); - setState(f); - if (_pressing) { - node.requestFocus(); - } else { - if (node.hasFocus) node.unfocus(); - } + List get states { + if (!enabled) return [ButtonStates.disabled]; + return [ + if (_pressing) ButtonStates.pressing, + if (_hovering) ButtonStates.hovering, + if (_shouldShowFocus) ButtonStates.focused, + ]; } @override @@ -182,51 +165,47 @@ class _HoverButtonState extends State { behavior: HitTestBehavior.opaque, onTap: widget.onPressed, onTapDown: (_) { - update(() => _pressing = true); + if (mounted) setState(() => _pressing = true); widget.onTapDown?.call(); }, onTapUp: (_) async { widget.onTapUp?.call(); if (!enabled) return; await Future.delayed(Duration(milliseconds: 100)); - update(() => _pressing = false); + if (mounted) setState(() => _pressing = false); }, onTapCancel: () { widget.onTapCancel?.call(); - update(() => _pressing = false); + if (mounted) setState(() => _pressing = false); }, onLongPress: widget.onLongPress, onLongPressStart: (_) { widget.onLongPressStart?.call(); - update(() => _pressing = true); + if (mounted) setState(() => _pressing = true); }, onLongPressEnd: (_) { widget.onLongPressEnd?.call(); - update(() => _pressing = false); + if (mounted) setState(() => _pressing = false); }, onHorizontalDragStart: widget.onHorizontalDragStart, onHorizontalDragUpdate: widget.onHorizontalDragUpdate, onHorizontalDragEnd: widget.onHorizontalDragEnd, - child: widget.builder?.call(context, state) ?? SizedBox(), + child: widget.builder(context, states), ); w = FocusableActionDetector( - mouseCursor: widget.cursor?.call(state) ?? - context.maybeTheme?.inputMouseCursor.call(state) ?? + mouseCursor: widget.cursor?.call(states) ?? + context.maybeTheme?.inputMouseCursor.call(states) ?? MouseCursor.defer, focusNode: node, autofocus: widget.autofocus, enabled: enabled, actions: _actionMap, - onFocusChange: (v) { - setState(() => _focused = v); - widget.onFocusChange?.call(v); - }, + onFocusChange: widget.onFocusChange, onShowFocusHighlight: (v) { - setState(() => _shouldShowFocus = v); - widget.onShowFocusHighlight?.call(v); + if (mounted) setState(() => _shouldShowFocus = v); }, onShowHoverHighlight: (v) { - update(() => _hovering = v); + if (mounted) setState(() => _hovering = v); }, child: w, ); @@ -236,7 +215,7 @@ class _HoverButtonState extends State { label: widget.semanticLabel, button: true, enabled: enabled, - focusable: true, + focusable: enabled, focused: node.hasFocus, child: w, ), @@ -247,29 +226,14 @@ class _HoverButtonState extends State { } } -@immutable -class ButtonStates with Diagnosticable { - final String id; - - const ButtonStates._(this.id); +enum ButtonStates { disabled, hovering, pressing, focused, none } - static const ButtonStates disabled = ButtonStates._('disabled'); - static const ButtonStates hovering = ButtonStates._('hovering'); - static const ButtonStates pressing = ButtonStates._('pressing'); - static const ButtonStates focused = ButtonStates._('focused'); - static const ButtonStates none = ButtonStates._('none'); +typedef ButtonState = T Function(List); - bool get isDisabled => this == disabled; - bool get isHovering => this == hovering; - bool get isPressing => this == pressing; - bool get isFocused => this == focused; - bool get isNone => this == none; - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties.add(StringProperty('state', id)); - } +extension ButtonStatesExtension on List { + bool get isFocused => contains(ButtonStates.focused); + bool get isDisabled => contains(ButtonStates.disabled); + bool get isPressing => contains(ButtonStates.pressing); + bool get isHovering => contains(ButtonStates.hovering); + bool get isNone => isEmpty; } - -typedef ButtonState = T Function(ButtonStates); diff --git a/lib/src/controls/inputs/icon_button.dart b/lib/src/controls/inputs/icon_button.dart index 7370940f6..ac0ad74b9 100644 --- a/lib/src/controls/inputs/icon_button.dart +++ b/lib/src/controls/inputs/icon_button.dart @@ -2,7 +2,7 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; -typedef IconThemeButtonStateBuilder = IconThemeData Function(ButtonStates); +typedef IconThemeButtonStateBuilder = IconThemeData Function(List); class IconButton extends StatelessWidget { const IconButton({ diff --git a/lib/src/controls/inputs/toggle_switch.dart b/lib/src/controls/inputs/toggle_switch.dart index 292121df8..9f406d396 100644 --- a/lib/src/controls/inputs/toggle_switch.dart +++ b/lib/src/controls/inputs/toggle_switch.dart @@ -137,7 +137,7 @@ class _ToggleSwitchState extends State { setState(() => _alignment = null); } }, - builder: (context, state) { + builder: (context, states) { Widget child = AnimatedContainer( alignment: _alignment ?? (widget.checked ? Alignment.centerRight : Alignment.centerLeft), @@ -147,19 +147,19 @@ class _ToggleSwitchState extends State { curve: style.animationCurve ?? Curves.linear, padding: style.padding, decoration: widget.checked - ? style.checkedDecoration?.call(state) - : style.uncheckedDecoration?.call(state), + ? style.checkedDecoration?.call(states) + : style.uncheckedDecoration?.call(states), child: widget.thumb ?? DefaultToggleSwitchThumb( checked: widget.checked, style: style, - state: state, + states: states, ), ); return Semantics( child: FocusBorder( child: child, - focused: state.isFocused, + focused: states.isFocused, ), checked: widget.checked, ); @@ -173,12 +173,12 @@ class DefaultToggleSwitchThumb extends StatelessWidget { Key? key, required this.checked, required this.style, - required this.state, + required this.states, }) : super(key: key); final bool checked; final ToggleSwitchThemeData? style; - final ButtonStates state; + final List states; @override Widget build(BuildContext context) { @@ -192,8 +192,8 @@ class DefaultToggleSwitchThumb extends StatelessWidget { maxWidth: 12, ), decoration: checked - ? style?.checkedThumbDecoration?.call(state) - : style?.uncheckedThumbDecoration?.call(state), + ? style?.checkedThumbDecoration?.call(states) + : style?.uncheckedThumbDecoration?.call(states), ); } } diff --git a/lib/src/controls/navigation/navigation_view/view.dart b/lib/src/controls/navigation/navigation_view/view.dart index 92bbc658e..6d036a53d 100644 --- a/lib/src/controls/navigation/navigation_view/view.dart +++ b/lib/src/controls/navigation/navigation_view/view.dart @@ -389,7 +389,7 @@ class NavigationAppBar with Diagnosticable { margin: EdgeInsets.zero, scaleFactor: 1.0, decoration: (state) { - if (state == ButtonStates.disabled) state = ButtonStates.none; + if (state.isDisabled) state = []; return BoxDecoration( color: ButtonThemeData.uncheckedInputColor(context.theme, state), diff --git a/lib/src/controls/utils/scrollbar.dart b/lib/src/controls/utils/scrollbar.dart index 57c79bbdf..317131a79 100644 --- a/lib/src/controls/utils/scrollbar.dart +++ b/lib/src/controls/utils/scrollbar.dart @@ -77,13 +77,13 @@ class _ScrollbarState extends RawScrollbarState { } Color _trackColor(ButtonStates state) { - if (state.isNone) return Colors.transparent; + if (state == ButtonStates.none) return Colors.transparent; return _scrollbarTheme.backgroundColor ?? Colors.transparent; } Color _thumbColor(ButtonStates state) { Color? color; - if (state.isPressing) color = _scrollbarTheme.scrollbarPressingColor; + if (state == ButtonStates.pressing) color = _scrollbarTheme.scrollbarPressingColor; color ??= _scrollbarTheme.scrollbarColor ?? Colors.transparent; return color; } From 77372b4ba9c7d35a4fe57c0a2c0d670358db8d24 Mon Sep 17 00:00:00 2001 From: dev-hann Date: Thu, 20 May 2021 22:19:22 -0300 Subject: [PATCH 2/3] Updated the input colors And moved hover_button to utils --- example/lib/screens/colors.dart | 2 +- example/lib/screens/inputs.dart | 30 ++++++----- example/lib/screens/settings.dart | 2 +- lib/fluent_ui.dart | 2 +- lib/src/controls/form/combo_box.dart | 4 +- lib/src/controls/inputs/button.dart | 52 ++++++++++--------- lib/src/controls/inputs/icon_button.dart | 34 +++++++----- lib/src/controls/inputs/toggle_button.dart | 12 ++--- lib/src/controls/surfaces/dialog.dart | 2 +- lib/src/controls/surfaces/tooltip.dart | 2 +- .../{inputs => utils}/hover_button.dart | 2 +- lib/src/styles/color.dart | 4 ++ lib/src/styles/theme.dart | 4 +- 13 files changed, 86 insertions(+), 66 deletions(-) rename lib/src/controls/{inputs => utils}/hover_button.dart (99%) diff --git a/example/lib/screens/colors.dart b/example/lib/screens/colors.dart index c59c2ff77..322f08d94 100644 --- a/example/lib/screens/colors.dart +++ b/example/lib/screens/colors.dart @@ -74,7 +74,7 @@ class ColorsPage extends StatelessWidget { children: List.generate(22, (index) { return buildColorBlock( 'Grey#${(index + 1) * 10}', - Colors.grey[(index + 1) * 10]!, + Colors.grey[(index + 1) * 10], ); }), ), diff --git a/example/lib/screens/inputs.dart b/example/lib/screens/inputs.dart index de989b96c..77bb08184 100644 --- a/example/lib/screens/inputs.dart +++ b/example/lib/screens/inputs.dart @@ -102,9 +102,7 @@ class _InputsPageState extends State { controller: controller, child: Button( child: Text('File'), - onPressed: () { - controller.open = true; - }, + onPressed: disabled ? null : () => controller.open = true, ), ), ), @@ -157,20 +155,28 @@ class _InputsPageState extends State { height: splitButtonHeight, child: SplitButtonBar(buttons: [ Button( - child: SizedBox( - height: splitButtonHeight, - child: Container( - color: context.theme.accentColor, - height: 24, - width: 24, - ), - ), + builder: (context, states) { + return SizedBox( + height: splitButtonHeight, + child: Container( + color: states.isDisabled + ? FluentTheme.of(context).accentColor.darker + : context.theme.accentColor, + height: 24, + width: 24, + ), + ); + }, onPressed: disabled ? null : () {}, ), Button( child: SizedBox( height: splitButtonHeight, - child: Icon(Icons.keyboard_arrow_down), + child: Icon( + Icons.keyboard_arrow_down, + color: + disabled ? FluentTheme.of(context).disabledColor : null, + ), ), onPressed: disabled ? null : () {}, style: ButtonThemeData(padding: EdgeInsets.all(6)), diff --git a/example/lib/screens/settings.dart b/example/lib/screens/settings.dart index 7dce25d23..79aebca0f 100644 --- a/example/lib/screens/settings.dart +++ b/example/lib/screens/settings.dart @@ -33,7 +33,7 @@ class Settings extends StatelessWidget { blurRadius: 10.0, ), ]; - final border = Border.all(color: Colors.grey[100]!, width: 0.5); + final border = Border.all(color: Colors.grey[100], width: 0.5); if (context.theme.brightness == Brightness.light) { return BoxDecoration( color: Colors.white, diff --git a/lib/fluent_ui.dart b/lib/fluent_ui.dart index 69b456708..a8d6b9800 100644 --- a/lib/fluent_ui.dart +++ b/lib/fluent_ui.dart @@ -27,7 +27,7 @@ export 'src/navigation/route.dart'; export 'src/layout/page.dart'; -export 'src/controls/inputs/hover_button.dart'; +export 'src/controls/utils/hover_button.dart'; export 'src/controls/inputs/button.dart'; export 'src/controls/inputs/checkbox.dart'; export 'src/controls/inputs/icon_button.dart'; diff --git a/lib/src/controls/form/combo_box.dart b/lib/src/controls/form/combo_box.dart index e84702984..ac6125c07 100644 --- a/lib/src/controls/form/combo_box.dart +++ b/lib/src/controls/form/combo_box.dart @@ -1245,7 +1245,7 @@ class _ComboboxState extends State> with WidgetsBindingObserver { switch (FluentTheme.of(context).brightness) { case Brightness.light: - return Colors.grey[190]!; + return Colors.grey[190]; case Brightness.dark: return Colors.white.withOpacity(0.7); } @@ -1254,7 +1254,7 @@ class _ComboboxState extends State> with WidgetsBindingObserver { switch (FluentTheme.of(context).brightness) { case Brightness.light: - return Colors.grey[150]!; + return Colors.grey[150]; case Brightness.dark: return Colors.white.withOpacity(0.10); } diff --git a/lib/src/controls/inputs/button.dart b/lib/src/controls/inputs/button.dart index 14eac83f4..dceef285b 100644 --- a/lib/src/controls/inputs/button.dart +++ b/lib/src/controls/inputs/button.dart @@ -3,7 +3,7 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; -import 'hover_button.dart'; +import '../utils/hover_button.dart'; enum _ButtonType { def, icon, toggle } @@ -202,7 +202,9 @@ class _ButtonState extends State