From 321b57de1cfc39cc940d28716fa1a49efc577d84 Mon Sep 17 00:00:00 2001 From: Daniel Eshkeri Date: Fri, 8 Nov 2024 10:08:45 +0000 Subject: [PATCH] feat(UX-1233): Added disabled variant to chip (#203) feat: Added disabled variant to chip test: Added debugfillproperties test to chip_test feat: Added onTaps to chips in example app fix: changed _updateControllerState to _handleDisabledState fix: used variable feat: added onTap to widgetbook feat: added rounded to widgetbook --- .../lib/pages/components/chip_example.dart | 3 + .../pages/components/chip_widgetbook.dart | 6 ++ lib/src/components/chips/chip.dart | 88 +++++++++++++------ test/src/components/chips/chip_test.dart | 22 +++-- 4 files changed, 85 insertions(+), 34 deletions(-) diff --git a/example/lib/pages/components/chip_example.dart b/example/lib/pages/components/chip_example.dart index 899a8c38..39bd4cc1 100644 --- a/example/lib/pages/components/chip_example.dart +++ b/example/lib/pages/components/chip_example.dart @@ -25,6 +25,7 @@ class _ChipExampleState extends State { label: 'Label', leading: ZetaIcon(ZetaIcons.user), trailing: IconButton(icon: Icon(ZetaIcons.close), onPressed: () {}), + onTap: () {}, ), ]); @@ -42,6 +43,7 @@ class _ChipExampleState extends State { leading: ZetaIcon(ZetaIcons.star), draggable: true, data: 'Assist chip', + onTap: () {}, ), ), ]); @@ -60,6 +62,7 @@ class _ChipExampleState extends State { selected: true, data: 'Filter chip', draggable: true, + onTap: (bool selected) {}, ), ), ]); diff --git a/example/widgetbook/pages/components/chip_widgetbook.dart b/example/widgetbook/pages/components/chip_widgetbook.dart index 057d6d6c..ca802db2 100644 --- a/example/widgetbook/pages/components/chip_widgetbook.dart +++ b/example/widgetbook/pages/components/chip_widgetbook.dart @@ -10,6 +10,8 @@ Widget inputChipUseCase(BuildContext context) { return WidgetbookScaffold( builder: (context, _) => ZetaInputChip( + onTap: context.knobs.boolean(label: 'Disabled', initialValue: false) ? null : () {}, + rounded: context.knobs.boolean(label: 'Rounded', initialValue: true), label: context.knobs.string(label: 'Label', initialValue: 'Label'), leading: context.knobs.boolean(label: 'Avatar', initialValue: true) ? ZetaAvatar( @@ -26,6 +28,8 @@ Widget inputChipUseCase(BuildContext context) { Widget filterChipUseCase(BuildContext context) => WidgetbookScaffold( builder: (context, _) => ZetaFilterChip( + onTap: context.knobs.boolean(label: 'Disabled', initialValue: false) ? null : (i) {}, + rounded: context.knobs.boolean(label: 'Rounded', initialValue: true), label: context.knobs.string(label: 'Label', initialValue: 'Label'), selected: context.knobs.boolean(label: 'Selected', initialValue: true), ), @@ -34,6 +38,8 @@ Widget filterChipUseCase(BuildContext context) => WidgetbookScaffold( Widget assistChipUseCase(BuildContext context) { return WidgetbookScaffold( builder: (context, _) => ZetaAssistChip( + onTap: context.knobs.boolean(label: 'Disabled', initialValue: false) ? null : () {}, + rounded: context.knobs.boolean(label: 'Rounded', initialValue: true), label: context.knobs.string(label: 'Label', initialValue: 'Label'), leading: ZetaIcon(iconKnob(context)), ), diff --git a/lib/src/components/chips/chip.dart b/lib/src/components/chips/chip.dart index 9f3a0fca..b6cb8449 100644 --- a/lib/src/components/chips/chip.dart +++ b/lib/src/components/chips/chip.dart @@ -88,11 +88,14 @@ class ZetaChip extends ZetaStatefulWidget { class _ZetaChipState extends State { bool selected = false; + bool _draggable = false; @override void initState() { super.initState(); selected = widget.selected ?? false; + _draggable = widget.draggable; + _handleDisabledState(); } @override @@ -101,10 +104,25 @@ class _ZetaChipState extends State { if (oldWidget.selected != widget.selected) { selected = widget.selected ?? false; } + _handleDisabledState(); + } + + void _handleDisabledState() { + if (widget.onTap == null && widget.onToggle == null) { + _controller.update(WidgetState.disabled, true); + setState(() { + _draggable = false; + }); + } else { + _controller.update(WidgetState.disabled, false); + setState(() { + _draggable = widget.draggable; + }); + } } Widget _renderLeading(Color foregroundColor) { - if (widget.leading.runtimeType == Icon) { + if (widget.leading.runtimeType == ZetaIcon || widget.leading.runtimeType == Icon) { return IconTheme( data: IconThemeData(color: foregroundColor, size: Zeta.of(context).spacing.xl), child: widget.leading!, @@ -120,7 +138,6 @@ class _ZetaChipState extends State { @override Widget build(BuildContext context) { final colors = Zeta.of(context).colors; - final foregroundColor = selected ? colors.textInverse : colors.textDefault; return ZetaRoundedScope( rounded: context.rounded, @@ -129,18 +146,18 @@ class _ZetaChipState extends State { button: widget.onTap != null, label: widget.semanticLabel, child: SelectionContainer.disabled( - child: widget.draggable + child: _draggable ? Draggable( feedback: Material( color: Colors.transparent, - child: child(colors, foregroundColor, isDragging: true), + child: child(colors, isDragging: true), ), childWhenDragging: const Nothing(), data: widget.data, onDragCompleted: widget.onDragCompleted, - child: child(colors, foregroundColor), + child: child(colors), ) - : child(colors, foregroundColor), + : child(colors), ), ), ); @@ -171,25 +188,41 @@ class _ZetaChipState extends State { return Zeta.of(context).spacing.large; } + Color _foregroundColor(ZetaColors colors, bool disabled) { + if (!disabled) { + if (selected) { + return colors.textInverse; + } else { + return colors.textDefault; + } + } else { + return colors.textDisabled; + } + } + ValueListenableBuilder> child( - ZetaColors colors, - Color foregroundColor, { + ZetaColors colors, { bool isDragging = false, }) { return ValueListenableBuilder( valueListenable: _controller, builder: (context, states, child) { + final disabled = states.contains(WidgetState.disabled); + final Color foregroundColor = _foregroundColor(colors, disabled); final double iconSize = selected ? Zeta.of(context).spacing.xl_2 : Zeta.of(context).spacing.none; final bool rounded = context.rounded; return InkWell( - statesController: _controller, + statesController: !disabled ? _controller : null, + mouseCursor: !disabled ? SystemMouseCursors.click : SystemMouseCursors.basic, borderRadius: rounded ? Zeta.of(context).radius.full : Zeta.of(context).radius.none, onTap: () { - if (widget.selected != null) { - setState(() => selected = !selected); - widget.onToggle?.call(selected); - } else { - widget.onTap?.call(); + if (!disabled) { + if (widget.selected != null) { + setState(() => selected = !selected); + widget.onToggle?.call(selected); + } else { + widget.onTap?.call(); + } } }, child: AnimatedContainer( @@ -203,22 +236,23 @@ class _ZetaChipState extends State { ), decoration: BoxDecoration( color: () { - if (states.contains(WidgetState.disabled)) { + if (disabled) { return colors.surfaceDisabled; - } - if (selected) { + } else { + if (selected) { + if (states.contains(WidgetState.hovered)) { + return colors.borderHover; + } + return colors.surfaceDefaultInverse; + } + if (states.contains(WidgetState.pressed) || isDragging) { + return colors.surfaceSelected; + } if (states.contains(WidgetState.hovered)) { - return colors.borderHover; + return colors.surfaceHover; } - return colors.surfaceDefaultInverse; - } - if (states.contains(WidgetState.pressed) || isDragging) { - return colors.surfaceSelected; - } - if (states.contains(WidgetState.hovered)) { - return colors.surfaceHover; + return colors.surfacePrimary; } - return colors.surfacePrimary; }(), borderRadius: rounded ? Zeta.of(context).radius.full : Zeta.of(context).radius.none, border: Border.fromBorderSide( @@ -242,7 +276,7 @@ class _ZetaChipState extends State { child: (selected ? ZetaIcon( ZetaIcons.check_mark, - color: widget.selected! ? colors.iconInverse : Colors.transparent, + color: disabled ? colors.iconDisabled : colors.iconInverse, ) : const Nothing()), ) diff --git a/test/src/components/chips/chip_test.dart b/test/src/components/chips/chip_test.dart index 9a9781e2..aa324ae7 100644 --- a/test/src/components/chips/chip_test.dart +++ b/test/src/components/chips/chip_test.dart @@ -16,13 +16,21 @@ void main() { group('Accessibility Tests', () {}); group('Content Tests', () { - // final debugFillProperties = { - // '': '', - // }; - // debugFillPropertiesTest( - // widget, - // debugFillProperties, - // ); + final debugFillProperties = { + 'label': '"Test Chip"', + 'rounded': 'null', + 'selected': 'null', + 'draggable': 'false', + 'data': 'null', + 'onDragCompleted': 'null', + 'semanticLabel': 'null', + 'onTap': 'null', + 'onToggle': 'null', + }; + debugFillPropertiesTest( + const ZetaChip(label: 'Test Chip'), + debugFillProperties, + ); testWidgets('renders label correctly', (WidgetTester tester) async { await tester.pumpWidget(