Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to styles #875

Merged
merged 8 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
- Add Slovak localization
- Add `AutoSuggestBox.itemBuilder` callback builder, which builds the items inside the overlay ([#869](https://github.com/bdlukaa/fluent_ui/issues/869))
- Add `AutoSuggestBoxItem.semanticsLabel` ([#869](https://github.com/bdlukaa/fluent_ui/issues/869))
- Add `ButtonState.forStates`, a helper function to quickly resolve values for each button state ([#875](https://github.com/bdlukaa/fluent_ui/pull/875))
- Slider label color is solid ([#847](https://github.com/bdlukaa/fluent_ui/issues/847))
- **BREAKING** Removed `.disabledColor`, `uncheckedColor`, `.checkedColor` and `.borderInputColor` from `FluentThemeData`. Use the values from theme resources instead ([`1295b6`](https://github.com/bdlukaa/fluent_ui/pull/875/commits/a195b58f4440c3c0febc595ba6f0b730a950a0d5))
- **BREAKING** To match the native implementation, `ToggleSwitch.thumb` and `.thumbBuilder` have been renamed to `.knob` and `.knobBuilder`, respectively. `DefaultToggleSwitchThumb` was renamed to `DefaultToggleSwitchKnob` ([e15e89d](https://github.com/bdlukaa/fluent_ui/pull/875/commits/e15e89d4140635796c105cf79a51f9ebc54cdfe6))
- Added `CheckboxThemeData.foregroundColor`, `RadioButtonThemeData.foregroundColor` and `ToggleSwitchThemeData.foregroundColor`, which, by default, reacts if the inputs are disabled or not ([#861](https://github.com/bdlukaa/fluent_ui/issues/861))
- `ToggleSwitch` correctly behaves as disabled when `onChanged` is `null` ([`4b5afb5`](https://github.com/bdlukaa/fluent_ui/pull/875/commits/4b5afb50ece212889917ba89d407fe45151ceff6))

## 4.6.2

Expand Down
8 changes: 6 additions & 2 deletions example/lib/screens/inputs/toggle_switch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,12 @@ ToggleSwitch(
),
if (secondValue)
const Padding(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: ProgressRing(),
padding: EdgeInsetsDirectional.only(start: 24.0),
child: SizedBox(
height: 30.0,
width: 30.0,
child: ProgressRing(),
),
)
]),
codeSnippet: '''bool checked = false;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/controls/flyouts/content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ class FlyoutListTile extends StatelessWidget {
DefaultTextStyle.merge(
style: TextStyle(
fontSize: 12.0,
color: theme.borderInputColor,
color: theme.resources.controlStrokeColorDefault,
height: 0.7,
),
child: trailing!,
Expand Down
8 changes: 6 additions & 2 deletions lib/src/controls/form/combo_box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1222,7 +1222,9 @@ class ComboBoxState<T> extends State<ComboBox<T>> {

placeholderIndex = items.length;
items.add(DefaultTextStyle.merge(
style: textStyle!.copyWith(color: theme.disabledColor),
style: textStyle!.copyWith(
color: theme.resources.textFillColorDisabled,
),
child: IgnorePointer(
ignoringSemantics: false,
child: displayedHint,
Expand Down Expand Up @@ -1254,7 +1256,9 @@ class ComboBoxState<T> extends State<ComboBox<T>> {
return DefaultTextStyle.merge(
style: isEnabled
? textStyle!
: textStyle!.copyWith(color: theme.disabledColor),
: textStyle!.copyWith(
color: theme.resources.textFillColorDisabled,
),
child: Container(
padding: padding.resolve(Directionality.of(context)),
child: Row(
Expand Down
2 changes: 1 addition & 1 deletion lib/src/controls/form/selection_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ class _FluentTextSelectionToolbarButton extends StatelessWidget {
shortcut,
style: body.merge(TextStyle(
fontSize: 12.0,
color: theme.borderInputColor,
color: theme.resources.controlStrokeColorDefault,
height: 0.7,
)),
),
Expand Down
2 changes: 1 addition & 1 deletion lib/src/controls/inputs/buttons/hyperlink_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class HyperlinkButton extends BaseButton {
padding: ButtonState.all(kDefaultButtonPadding),
foregroundColor: ButtonState.resolveWith((states) {
if (states.isDisabled) {
return theme.disabledColor;
return theme.resources.controlFillColorDisabled;
} else if (states.isPressing) {
return theme.accentColor.tertiaryBrushFor(theme.brightness);
} else if (states.isHovering) {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/controls/inputs/buttons/outlined_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class OutlinedButton extends BaseButton {
foregroundColor: ButtonState.all(theme.inactiveColor),
backgroundColor: ButtonState.resolveWith((states) {
if (states.isDisabled) {
return theme.disabledColor.withOpacity(0.30);
return theme.resources.controlFillColorDisabled.withOpacity(0.30);
} else if (states.isPressing) {
return theme.inactiveColor.withOpacity(0.25);
} else if (states.isHovering) {
Expand Down
96 changes: 74 additions & 22 deletions lib/src/controls/inputs/checkbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@ import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';

/// A check box is used to select or deselect action items. It can
/// be used for a single item or for a list of multiple items that
/// a user can choose from. The control has three selection states:
/// unselected, selected, and indeterminate. Use the indeterminate
/// state when a collection of sub-choices have both unselected and
/// selected states.
/// A check box is used to select or deselect action items. It can be used for a
/// single item or for a list of multiple items that a user can choose from. The
/// control has three selection states: unselected, selected, and indeterminate.
/// Use the indeterminate state when a collection of sub-choices have both
/// unselected and selected states.
///
/// ![Checkbox Preview](https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/images/templates-checkbox-states-default.png)
/// ![Checkbox Preview](https://learn.microsoft.com/en-us/windows/apps/design/controls/images/templates-checkbox-states-default.png)
///
/// See also:
/// - [ToggleSwitch](https://pub.dev/packages/fluent_ui#toggle-switches)
/// - [RadioButton](https://pub.dev/packages/fluent_ui#radio-buttons)
/// - [ToggleButton]
///
/// * <https://learn.microsoft.com/en-us/windows/apps/design/controls/checkbox>
/// * [ToggleSwitch], which represents a physical switch that allows users to
/// turn things on or off
/// * [RadioButton], let users select one option from a collection of two or
/// more mutually exclusive, visible options
/// * [ToggleButton], a button that can be on or off.
class Checkbox extends StatelessWidget {
/// Creates a checkbox.
const Checkbox({
Expand Down Expand Up @@ -82,8 +85,10 @@ class Checkbox extends StatelessWidget {
@override
Widget build(BuildContext context) {
assert(debugCheckHasFluentTheme(context));

final style = CheckboxTheme.of(context).merge(this.style);
const size = 20.0;

return HoverButton(
autofocus: autofocus,
semanticLabel: semanticLabel,
Expand All @@ -93,10 +98,8 @@ class Checkbox extends StatelessWidget {
? null
: () => onChanged!(checked == null ? null : !checked!),
builder: (context, state) {
Widget child = AnimatedContainer(
Widget child = Container(
alignment: AlignmentDirectional.center,
duration: FluentTheme.of(context).fastAnimationDuration,
curve: FluentTheme.of(context).animationCurve,
padding: style.padding,
height: size,
width: size,
Expand Down Expand Up @@ -134,7 +137,15 @@ class Checkbox extends StatelessWidget {
child = Row(mainAxisSize: MainAxisSize.min, children: [
child,
const SizedBox(width: 8.0),
content!,
DefaultTextStyle.merge(
style: TextStyle(color: style.foregroundColor?.resolve(state)),
child: IconTheme.merge(
data: IconThemeData(
color: style.foregroundColor?.resolve(state),
),
child: content!,
),
),
]);
}
return Semantics(
Expand Down Expand Up @@ -229,18 +240,37 @@ class CheckboxTheme extends InheritedTheme {

@immutable
class CheckboxThemeData with Diagnosticable {
/// The decoration of the checkbox when it's checked
final ButtonState<Decoration?>? checkedDecoration;

/// The decoration of the checkbox when it's unchecked
final ButtonState<Decoration?>? uncheckedDecoration;

/// The decoration of the checkbox when it's in its third state
final ButtonState<Decoration?>? thirdstateDecoration;

/// The icon displayed in the checkbox when it's checked
final IconData? icon;

/// The color of the [icon] when the checkbox is checked
final ButtonState<Color?>? checkedIconColor;

/// The color of the [icon] when the checkbox is unchecked
final ButtonState<Color?>? uncheckedIconColor;

/// The color of the [icon] when the checkbox is in its third state
final ButtonState<Color?>? thirdstateIconColor;

/// The color of the content of the checkbox
final ButtonState<Color?>? foregroundColor;

/// The padding around the checkbox
final EdgeInsetsGeometry? padding;

/// The margin around the checkbox
final EdgeInsetsGeometry? margin;

/// Creates a [CheckboxThemeData]
const CheckboxThemeData({
this.checkedDecoration,
this.uncheckedDecoration,
Expand All @@ -251,14 +281,23 @@ class CheckboxThemeData with Diagnosticable {
this.checkedIconColor,
this.uncheckedIconColor,
this.thirdstateIconColor,
this.foregroundColor,
});

factory CheckboxThemeData.standard(FluentThemeData theme) {
final BorderRadiusGeometry radius = BorderRadius.circular(4.0);
final BorderRadiusGeometry radius = BorderRadius.circular(6.0);
return CheckboxThemeData(
foregroundColor: ButtonState.resolveWith((states) {
return states.isDisabled ? theme.resources.textFillColorDisabled : null;
}),
checkedDecoration: ButtonState.resolveWith(
(states) => BoxDecoration(
borderRadius: radius,
border: Border.all(
color: states.isDisabled
? theme.resources.controlStrongStrokeColorDisabled
: ButtonThemeData.checkedInputColor(theme, states),
),
color: ButtonThemeData.checkedInputColor(theme, states),
),
),
Expand All @@ -269,13 +308,24 @@ class CheckboxThemeData with Diagnosticable {
? theme.resources.controlStrongStrokeColorDisabled
: theme.resources.controlStrongStrokeColorDefault,
),
color: ButtonThemeData.uncheckedInputColor(theme, states),
color: ButtonState.forStates(
states,
disabled: theme.resources.controlAltFillColorDisabled,
pressed: theme.resources.controlAltFillColorQuarternary,
hovering: theme.resources.controlAltFillColorTertiary,
none: theme.resources.controlAltFillColorSecondary,
),
borderRadius: radius,
),
),
thirdstateDecoration: ButtonState.resolveWith(
(states) => BoxDecoration(
borderRadius: radius,
border: Border.all(
color: states.isDisabled
? theme.resources.controlStrongStrokeColorDisabled
: ButtonThemeData.checkedInputColor(theme, states),
),
color: ButtonThemeData.checkedInputColor(theme, states),
),
),
Expand All @@ -287,6 +337,7 @@ class CheckboxThemeData with Diagnosticable {
);
}

/// Linearly interpolate between two checkbox themes.
static CheckboxThemeData lerp(
CheckboxThemeData? a,
CheckboxThemeData? b,
Expand All @@ -308,9 +359,12 @@ class CheckboxThemeData with Diagnosticable {
a?.uncheckedDecoration, b?.uncheckedDecoration, t, Decoration.lerp),
thirdstateDecoration: ButtonState.lerp(
a?.thirdstateDecoration, b?.thirdstateDecoration, t, Decoration.lerp),
foregroundColor: ButtonState.lerp(
a?.foregroundColor, b?.foregroundColor, t, Color.lerp),
);
}

/// Merge this checkbox theme data with another
CheckboxThemeData merge(CheckboxThemeData? style) {
return CheckboxThemeData(
margin: style?.margin ?? margin,
Expand All @@ -322,6 +376,7 @@ class CheckboxThemeData with Diagnosticable {
checkedDecoration: style?.checkedDecoration ?? checkedDecoration,
uncheckedDecoration: style?.uncheckedDecoration ?? uncheckedDecoration,
thirdstateDecoration: style?.thirdstateDecoration ?? thirdstateDecoration,
foregroundColor: style?.foregroundColor ?? foregroundColor,
);
}

Expand Down Expand Up @@ -365,18 +420,15 @@ class CheckboxThemeData with Diagnosticable {
..add(
DiagnosticsProperty<EdgeInsetsGeometry?>('padding', padding),
)
..add(DiagnosticsProperty<EdgeInsetsGeometry?>('margin', margin));
..add(DiagnosticsProperty<EdgeInsetsGeometry?>('margin', margin))
..add(DiagnosticsProperty('foregroundColor', foregroundColor));
}
}

/// Copy if [Icon], with specified font weight
/// See https://github.com/bdlukaa/fluent_ui/issues/471
class _Icon extends StatelessWidget {
const _Icon(
this.icon, {
this.size,
this.color,
});
const _Icon(this.icon, {this.size, this.color});

final IconData? icon;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/controls/inputs/chip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class ChipThemeData with Diagnosticable {
textStyle: ButtonState.resolveWith((states) {
return TextStyle(
color: states.isDisabled
? theme.disabledColor
? theme.resources.textFillColorDisabled
: normalColor(states).basedOnLuminance(),
);
}),
Expand Down
Loading