Skip to content

Commit

Permalink
feat!: unify ChipTheme and YaruChoiceChipBar and make them work with …
Browse files Browse the repository at this point in the history
…high contrast (#955)
  • Loading branch information
Feichtmeier authored Nov 5, 2024
1 parent eb653cb commit 0365af5
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 76 deletions.
2 changes: 1 addition & 1 deletion example/lib/pages/choice_chip_bar_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class _ChoiceChipBarPageState extends State<ChoiceChipBarPage> {
showCheckMarks: false,
shrinkWrap: true,
clearOnSelect: false,
yaruChoiceChipBarStyle: YaruChoiceChipBarStyle.stack,
style: YaruChoiceChipBarStyle.stack,
labels: _labels.map(Text.new).toList(),
isSelected: _isSelected,
onSelected: (index) => setState(() {
Expand Down
38 changes: 35 additions & 3 deletions lib/src/themes/common_themes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -663,8 +663,35 @@ ChipThemeData _createChipTheme({
required Color selectedColor,
required ColorScheme colorScheme,
}) {
final isHC = colorScheme.isHighContrast == true;
final selectedBackgroundColor =
isHC ? colorScheme.inverseSurface : selectedColor;
final selectedForeGroundColor =
isHC ? colorScheme.onInverseSurface : colorScheme.onSurface;

return ChipThemeData(
selectedColor: selectedColor.withOpacity(.4),
selectedColor: selectedBackgroundColor.withOpacity(isHC ? 1 : 0.4),
labelStyle: TextStyle(
color: colorScheme.onSurface,
),
checkmarkColor: selectedForeGroundColor,
secondaryLabelStyle: TextStyle(
color: selectedForeGroundColor,
fontWeight: isHC ? FontWeight.bold : FontWeight.normal,
),
side: WidgetStateBorderSide.resolveWith(
(s) => BorderSide(
color: s.contains(WidgetState.selected)
? selectedBackgroundColor.withOpacity(isHC ? 1 : 0.1)
: (isHC ? colorScheme.outlineVariant : colorScheme.outline)
.withOpacity(
s.contains(WidgetState.disabled) ? (isHC ? 0.3 : 0.7) : 1,
),
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100),
),
);
}

Expand Down Expand Up @@ -854,10 +881,13 @@ ThemeData createYaruLightTheme({
tertiaryContainer: tertiaryContainer,
onTertiaryContainer: contrastColor(tertiaryContainer),
onSurfaceVariant: YaruColors.coolGrey,
outline: const Color.fromARGB(255, 221, 221, 221),
outline: primaryColor == Colors.white
? Colors.black
: const Color.fromARGB(255, 221, 221, 221),
outlineVariant: Colors.black,
scrim: Colors.black,
);

return createYaruTheme(
colorScheme: colorScheme,
dividerColor: colorScheme.isHighContrast ? null : kDividerColorLight,
Expand Down Expand Up @@ -908,7 +938,9 @@ ThemeData createYaruDarkTheme({
tertiaryContainer: tertiaryContainer,
onTertiaryContainer: YaruColors.porcelain,
onSurfaceVariant: YaruColors.warmGrey,
outline: const Color.fromARGB(255, 68, 68, 68),
outline: primaryColor == Colors.black
? Colors.white
: const Color.fromARGB(255, 68, 68, 68),
outlineVariant: Colors.white,
scrim: Colors.black,
);
Expand Down
97 changes: 25 additions & 72 deletions lib/src/widgets/yaru_choice_chip_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ class YaruChoiceChipBar extends StatefulWidget {
required this.labels,
this.onSelected,
required this.isSelected,
this.yaruChoiceChipBarStyle = YaruChoiceChipBarStyle.row,
this.style = YaruChoiceChipBarStyle.row,
this.spacing = 10.0,
this.animationDuration = const Duration(milliseconds: 300),
this.navigationStep = 100.0,
this.animationCurve = Curves.bounceIn,
this.radius = kYaruTitleBarItemHeight,
this.chipHeight = kYaruTitleBarItemHeight,
this.wrapScrollDirection = Axis.horizontal,
this.wrapAlignment = WrapAlignment.start,
Expand All @@ -31,9 +30,6 @@ class YaruChoiceChipBar extends StatefulWidget {
this.shrinkWrap = true,
this.showCheckMarks = true,
this.selectedFirst = true,
this.borderColor,
this.chipBackgroundColor,
this.selectedChipBackgroundColor,
this.navigationButtonElevation,
}) : assert(labels.length == isSelected.length);

Expand All @@ -54,7 +50,7 @@ class YaruChoiceChipBar extends StatefulWidget {
/// Determines weither the [ChoiceChip]s should be put into a [ListView]
/// or a [Wrap] or a [ListView] but with the scrolling controls
/// put into a [Stack] on top of the [ListView].
final YaruChoiceChipBarStyle yaruChoiceChipBarStyle;
final YaruChoiceChipBarStyle style;

/// Sets how long the navigation jumps and fade in and out of
/// the scrolling controls are animated.
Expand All @@ -66,21 +62,6 @@ class YaruChoiceChipBar extends StatefulWidget {
/// Sets the easing [Curve] of the animations.
final Curve animationCurve;

/// Sets how round the [ChoiceChips] and scrolling control buttons are.
final double radius;

/// The optional [Color] of the [BorderSide] of the [ChoiceChips]
/// Defaults to `Theme.of(context).chipTheme.shape?.side.color ?? Theme.of(context).colorScheme.outline`
final Color? borderColor;

/// The optional [Color] of the [ShapeBorder] of the [ChoiceChips]
/// Defaults to `Theme.of(context).chipTheme.backgroundColor`
final Color? chipBackgroundColor;

/// The optional [Color] of the [ShapeBorder] of the [ChoiceChips] if selected.
/// Defaults to `Theme.of(context).chipTheme.selectedColor`
final Color? selectedChipBackgroundColor;

/// The optional elevation of the navigation buttons. Defaults to 0.
final double? navigationButtonElevation;

Expand Down Expand Up @@ -180,38 +161,21 @@ class _YaruChoiceChipBarState extends State<YaruChoiceChipBar> {

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);

Widget themedChip(int index) {
return ChipTheme(
data: theme.chipTheme.copyWith(
backgroundColor: widget.chipBackgroundColor,
selectedColor: widget.selectedChipBackgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(widget.radius),
side: BorderSide(
color: widget.borderColor ??
theme.chipTheme.shape?.side.color ??
theme.colorScheme.outline,
width: 1,
),
),
),
child: ChoiceChip(
showCheckmark: widget.showCheckMarks,
label: widget.labels[index],
selected: widget.isSelected[index],
onSelected: widget.onSelected == null
? null
: (v) {
widget.onSelected!(index);
if (widget.clearOnSelect) {
_controller.jumpTo(
_controller.position.minScrollExtent - widget.chipHeight,
);
}
},
),
return ChoiceChip(
showCheckmark: widget.showCheckMarks,
label: widget.labels[index],
selected: widget.isSelected[index],
onSelected: widget.onSelected == null
? null
: (v) {
widget.onSelected!(index);
if (widget.clearOnSelect) {
_controller.jumpTo(
_controller.position.minScrollExtent - widget.chipHeight,
);
}
},
);
}

Expand Down Expand Up @@ -245,9 +209,6 @@ class _YaruChoiceChipBarState extends State<YaruChoiceChipBar> {

final goPreviousButton = _NavigationButton(
elevation: widget.navigationButtonElevation,
borderColor: widget.borderColor,
chipBackgroundColor: widget.chipBackgroundColor,
radius: widget.radius,
chipHeight: widget.chipHeight,
icon: widget.goPreviousIcon ?? const Icon(YaruIcons.go_previous),
onTap: _enableGoPreviousButton
Expand All @@ -261,10 +222,7 @@ class _YaruChoiceChipBarState extends State<YaruChoiceChipBar> {

final goNextButton = _NavigationButton(
elevation: widget.navigationButtonElevation,
borderColor: widget.borderColor,
chipBackgroundColor: widget.chipBackgroundColor,
chipHeight: widget.chipHeight,
radius: widget.radius,
icon: widget.goNextIcon ?? const Icon(YaruIcons.go_next),
onTap: _enableGoNextButton
? () => _controller.animateTo(
Expand All @@ -275,7 +233,7 @@ class _YaruChoiceChipBarState extends State<YaruChoiceChipBar> {
: null,
);

if (widget.yaruChoiceChipBarStyle == YaruChoiceChipBarStyle.wrap) {
if (widget.style == YaruChoiceChipBarStyle.wrap) {
return Wrap(
alignment: widget.wrapAlignment,
clipBehavior: widget.wrapClipBehavior,
Expand All @@ -288,7 +246,7 @@ class _YaruChoiceChipBarState extends State<YaruChoiceChipBar> {
direction: widget.wrapScrollDirection,
children: children,
);
} else if (widget.yaruChoiceChipBarStyle == YaruChoiceChipBarStyle.stack) {
} else if (widget.style == YaruChoiceChipBarStyle.stack) {
return SizedBox(
height: widget.chipHeight,
child: Stack(
Expand Down Expand Up @@ -351,38 +309,33 @@ class _NavigationButton extends StatelessWidget {
const _NavigationButton({
this.onTap,
required this.icon,
required this.radius,
required this.chipHeight,
this.borderColor,
this.chipBackgroundColor,
this.elevation,
});

final Function()? onTap;
final Widget icon;
final double radius;
final double chipHeight;
final Color? borderColor;
final Color? chipBackgroundColor;
final double? elevation;

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final roundedRectangleBorder = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(radius),
borderRadius: BorderRadius.circular(chipHeight / 2),
side: BorderSide(
color: borderColor ?? theme.colorScheme.outline,
strokeAlign: -1,
color: (theme.colorScheme.isHighContrast == true
? theme.colorScheme.outlineVariant
: theme.colorScheme.outline),
width: 1,
),
);

return SizedBox(
height: chipHeight,
width: chipHeight,
return SizedBox.square(
dimension: chipHeight - 2,
child: Material(
shape: roundedRectangleBorder,
color: chipBackgroundColor?.scale(lightness: 0.1),
elevation: elevation ?? 0.0,
child: InkWell(
customBorder: roundedRectangleBorder,
Expand Down

0 comments on commit 0365af5

Please sign in to comment.