Skip to content

Commit

Permalink
feat: improve YaruChipChoice parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
Feichtmeier committed Jun 22, 2023
1 parent af297d0 commit cb05fbb
Showing 1 changed file with 66 additions and 40 deletions.
106 changes: 66 additions & 40 deletions lib/src/widgets/yaru_choice_chip_bar.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:yaru_icons/yaru_icons.dart';
import 'package:yaru_widgets/constants.dart';

class YaruChoiceChipBar extends StatefulWidget {
const YaruChoiceChipBar({
Expand All @@ -10,15 +11,21 @@ class YaruChoiceChipBar extends StatefulWidget {
required this.isSelected,
this.yaruChoiceChipBarStyle = YaruChoiceChipBarStyle.row,
this.spacing = 10.0,
this.duration = const Duration(milliseconds: 200),
this.animationStep = 100.0,
this.animationDuration = const Duration(milliseconds: 300),
this.navigationStep = 100.0,
this.animationCurve = Curves.bounceIn,
this.radius = kYaruContainerRadius,
this.chipHeight = 34.0,
}) : assert(labels.length == isSelected.length);

final Axis wrapScrollDirection;
final YaruChoiceChipBarStyle yaruChoiceChipBarStyle;
final double spacing;
final Duration duration;
final double animationStep;
final Duration animationDuration;
final double navigationStep;
final Curve animationCurve;
final double radius;
final double chipHeight;

final List<Widget> labels;
final List<bool> isSelected;
Expand Down Expand Up @@ -68,21 +75,32 @@ 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(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(widget.radius),
side: BorderSide(
color: theme.colorScheme.outline,
width: 1,
),
),
),
child: ChoiceChip(
label: widget.labels[index],
selected: widget.isSelected[index],
onSelected: (v) => widget.onSelected(index),
),
);
}

final children = [
for (int index = 0; index < widget.labels.length; index++)
if (widget.isSelected[index])
ChoiceChip(
label: widget.labels[index],
selected: widget.isSelected[index],
onSelected: (v) => widget.onSelected(index),
),
if (widget.isSelected[index]) themedChip(index),
for (int index = 0; index < widget.labels.length; index++)
if (!widget.isSelected[index])
ChoiceChip(
label: widget.labels[index],
selected: widget.isSelected[index],
onSelected: (v) => widget.onSelected(index),
)
if (!widget.isSelected[index]) themedChip(index)
];

final listView = ListView(
Expand All @@ -101,29 +119,31 @@ class _YaruChoiceChipBarState extends State<YaruChoiceChipBar> {
);

final goPreviousButton = _NavigationButton(
radius: widget.radius,
chipHeight: widget.chipHeight,
icon: const Icon(YaruIcons.go_previous),
onTap: _enableGoPreviousButton
? () => _controller.animateTo(
_controller.position.pixels - widget.animationStep,
duration: widget.duration,
curve: Curves.bounceIn,
_controller.position.pixels - widget.navigationStep,
duration: widget.animationDuration,
curve: widget.animationCurve,
)
: null,
);

final goNextButton = _NavigationButton(
chipHeight: widget.chipHeight,
radius: widget.radius,
icon: const Icon(YaruIcons.go_next),
onTap: _enableGoNextButton
? () => _controller.animateTo(
_controller.position.pixels + widget.animationStep,
duration: widget.duration,
curve: Curves.bounceIn,
_controller.position.pixels + widget.navigationStep,
duration: widget.animationDuration,
curve: widget.animationCurve,
)
: null,
);

const clipRadius = 40.0;

if (widget.yaruChoiceChipBarStyle == YaruChoiceChipBarStyle.wrap) {
return Wrap(
spacing: widget.spacing,
Expand All @@ -133,35 +153,37 @@ class _YaruChoiceChipBarState extends State<YaruChoiceChipBar> {
);
} else if (widget.yaruChoiceChipBarStyle == YaruChoiceChipBarStyle.stack) {
return SizedBox(
height: 60,
height: widget.chipHeight,
child: Stack(
alignment: Alignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.only(
topLeft:
Radius.circular(_enableGoPreviousButton ? clipRadius : 0.0),
bottomLeft:
Radius.circular(_enableGoPreviousButton ? clipRadius : 0.0),
topRight:
Radius.circular(_enableGoNextButton ? clipRadius : 0.0),
bottomRight:
Radius.circular(_enableGoNextButton ? clipRadius : 0.0),
topLeft: Radius.circular(
_enableGoPreviousButton ? widget.chipHeight : 0.0,
),
bottomLeft: Radius.circular(
_enableGoPreviousButton ? widget.chipHeight : 0.0,
),
topRight: Radius.circular(
_enableGoNextButton ? widget.chipHeight : 0.0),
bottomRight: Radius.circular(
_enableGoNextButton ? widget.chipHeight : 0.0),
),
child: listView,
),
Positioned(
left: 0,
child: AnimatedOpacity(
duration: const Duration(milliseconds: 300),
duration: widget.animationDuration,
opacity: _enableGoPreviousButton ? 1.0 : 0.0,
child: goPreviousButton,
),
),
Positioned(
right: 0,
child: AnimatedOpacity(
duration: const Duration(milliseconds: 300),
duration: widget.animationDuration,
opacity: _enableGoNextButton ? 1.0 : 0.0,
child: goNextButton,
),
Expand All @@ -171,7 +193,7 @@ class _YaruChoiceChipBarState extends State<YaruChoiceChipBar> {
);
} else {
return SizedBox(
height: 60,
height: widget.chipHeight,
child: Row(
children: [
goPreviousButton,
Expand All @@ -196,25 +218,29 @@ class _NavigationButton extends StatelessWidget {
const _NavigationButton({
this.onTap,
required this.icon,
required this.radius,
required this.chipHeight,
});

final Function()? onTap;
final Widget icon;
final double radius;
final double chipHeight;

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
const navigationButtonSize = 34.0;
final roundedRectangleBorder = RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
borderRadius: BorderRadius.circular(radius),
side: BorderSide(
color: theme.colorScheme.outline,
width: 1,
),
);

return SizedBox(
height: navigationButtonSize,
width: navigationButtonSize,
height: chipHeight,
width: chipHeight,
child: Material(
shape: roundedRectangleBorder,
child: InkWell(
Expand Down

0 comments on commit cb05fbb

Please sign in to comment.