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

feat: Created dropdown list item #101

Merged
merged 6 commits into from
Jun 12, 2024
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
22 changes: 20 additions & 2 deletions example/lib/pages/components/list_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,29 @@ class ListExample extends StatelessWidget {
return ExampleScaffold(
name: 'List',
child: ZetaList(
showDivider: false,
showDivider: true,
items: [
ZetaListItem(primaryText: 'Item 1'),
ZetaListItem(primaryText: 'Item 2'),
ZetaListItem(primaryText: 'Item 3', showDivider: true),
ZetaDropdownListItem(
primaryText: 'Item 3',
leading: Icon(ZetaIcons.star_round),
expanded: true,
items: [
ZetaListItem.checkbox(
primaryText: 'Dropdown Item 1',
onChanged: (_) {},
),
ZetaListItem.checkbox(
primaryText: 'Dropdown Item 2',
onChanged: (_) {},
),
ZetaListItem.checkbox(
primaryText: 'Dropdown Item 3',
onChanged: (_) {},
),
],
),
ZetaListItem(primaryText: 'Item 4', showDivider: true),
ZetaListItem(primaryText: 'Item 5'),
ZetaListItem(primaryText: 'Item 6'),
Expand Down
66 changes: 41 additions & 25 deletions example/lib/pages/components/list_item_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,31 +66,47 @@ class _ListItemExampleState extends State<ListItemExample> {
},
)),
_buildListItem(
'Radio Right',
Column(
children: [
ZetaListItem.radio(
primaryText: 'Radio option 1',
value: radioOption1,
groupValue: radioGroupValue,
onChanged: (value) {
setState(() {
radioGroupValue = value;
});
},
),
ZetaListItem.radio(
primaryText: 'Radio option 2',
value: radioOption2,
groupValue: radioGroupValue,
onChanged: (value) {
setState(() {
radioGroupValue = value;
});
},
),
],
)),
'Radio Right',
Column(
children: [
ZetaListItem.radio(
primaryText: 'Radio option 1',
value: radioOption1,
groupValue: radioGroupValue,
onChanged: (value) {
setState(() {
radioGroupValue = value;
});
},
),
ZetaListItem.radio(
primaryText: 'Radio option 2',
value: radioOption2,
groupValue: radioGroupValue,
onChanged: (value) {
setState(() {
radioGroupValue = value;
});
},
),
],
),
),
_buildListItem(
'Dropdown list',
ZetaDropdownListItem(
items: [
ZetaListItem(primaryText: 'List Item'),
ZetaListItem(primaryText: 'List Item'),
ZetaListItem(primaryText: 'List Item'),
],
expanded: true,
primaryText: 'List Item',
leading: Icon(
ZetaIcons.star_round,
),
),
),
].divide(const SizedBox(height: 16)).toList(),
),
),
Expand Down
2 changes: 1 addition & 1 deletion example/lib/pages/theme/color_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ class MyRow extends StatelessWidget {
height: 160,
width: 160,
color: e.value,
duration: const Duration(milliseconds: 250),
duration: ZetaAnimationLength.fast,
child: FittedBox(
fit: BoxFit.scaleDown,
child: Column(
Expand Down
9 changes: 8 additions & 1 deletion example/widgetbook/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:zeta_flutter/zeta_flutter.dart';

import 'pages/assets/icon_widgetbook.dart';
import 'pages/components/accordion_widgetbook.dart';
import 'pages/components/dropdown_list_item_widgetbook.dart';
import 'pages/components/notification_list_item_widgetbook.dart';
import 'pages/components/text_input_widgetbook.dart';
import 'pages/components/top_app_bar_widgetbook.dart';
Expand Down Expand Up @@ -159,7 +160,13 @@ class _HotReloadState extends State<HotReload> {
useCases: [
WidgetbookUseCase(name: 'List Item', builder: (context) => listItemUseCase(context)),
WidgetbookUseCase(
name: 'Notification List Item', builder: (context) => notificationListItemUseCase(context)),
name: 'Dropdown List Item',
builder: (context) => dropdownListItemUseCase(context),
),
WidgetbookUseCase(
name: 'Notification List Item',
builder: (context) => notificationListItemUseCase(context),
),
WidgetbookUseCase(name: 'Contact Item', builder: (context) => contactItemUseCase(context)),
WidgetbookUseCase(name: 'Chat List Item', builder: (context) => chatItemWidgetBook(context)),
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:widgetbook/widgetbook.dart';
import 'package:zeta_flutter/zeta_flutter.dart';

import '../../test/test_components.dart';
import '../../utils/utils.dart';

Widget dropdownListItemUseCase(BuildContext context) {
return WidgetbookTestWidget(
widget: StatefulBuilder(
builder: (context, setState) {
final primaryText = context.knobs.string(label: 'Primary text', initialValue: 'Label');

final secondaryText = context.knobs.string(label: 'Secondary text', initialValue: 'Descriptor');

final showIcon = context.knobs.boolean(label: 'Show icon');

final showDivider = context.knobs.boolean(label: 'Show divider');

final rounded = roundedKnob(context);

final leading = showIcon ? Icon(ZetaIcons.star_round) : null;

return ZetaDropdownListItem(
primaryText: primaryText,
items: [
ZetaListItem(primaryText: 'List Item'),
ZetaListItem(primaryText: 'List Item'),
ZetaListItem(primaryText: 'List Item'),
],
rounded: rounded,
secondaryText: secondaryText,
leading: leading,
showDivider: showDivider,
);
},
),
);
}
4 changes: 2 additions & 2 deletions lib/src/components/accordion/accordion.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ class _ZetaAccordionState extends State<ZetaAccordion> with TickerProviderStateM
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 300),
reverseDuration: const Duration(milliseconds: 200),
duration: ZetaAnimationLength.normal,
reverseDuration: ZetaAnimationLength.fast,
vsync: this,
);
_animation = CurvedAnimation(
Expand Down
4 changes: 2 additions & 2 deletions lib/src/components/checkbox/checkbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class _CheckboxState extends State<_Checkbox> {
onTap: !widget.disabled ? () => widget.onChanged.call(!_checked) : null,
borderRadius: ZetaRadius.full,
child: Padding(
padding: const EdgeInsets.all(ZetaSpacing.small),
padding: const EdgeInsets.all(ZetaSpacing.medium),
child: Semantics(
mixed: widget.useIndeterminate,
enabled: !widget.disabled,
Expand Down Expand Up @@ -194,7 +194,7 @@ class _CheckboxState extends State<_Checkbox> {
mainAxisSize: MainAxisSize.min,
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 200),
duration: ZetaAnimationLength.fast,
decoration: BoxDecoration(
boxShadow: [
if (_isFocused && !widget.disabled)
Expand Down
2 changes: 1 addition & 1 deletion lib/src/components/fabs/fab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class _ZetaFABState extends State<ZetaFAB> {
),
),
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
duration: ZetaAnimationLength.normal,
child: Padding(
padding: _isExpanded
? const EdgeInsets.symmetric(horizontal: ZetaSpacingBase.x3_5, vertical: ZetaSpacing.medium)
Expand Down
164 changes: 164 additions & 0 deletions lib/src/components/list_item/dropdown_list_item.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import '../../assets/icons.dart';
import '../../theme/tokens.dart';
import '../../zeta.dart';
import 'list_item.dart';
import 'list_scope.dart';

/// An expandable list item containing other [ZetaListItem]s within it.
class ZetaDropdownListItem extends StatefulWidget {
/// Creates a new [ZetaDropdownListItem]
const ZetaDropdownListItem({
required this.primaryText,
required this.items,
this.secondaryText,
this.expanded = false,
this.leading,
this.rounded = true,
this.showDivider,
super.key,
});

/// The list of [ZetaListItem]s contained within the dropdown.
final List<ZetaListItem> items;

/// {@macro list-item-primary-text}
final String primaryText;

/// {@macro list-item-secondary-text}
final String? secondaryText;

/// {@macro list-item-leading}
final Widget? leading;

/// Expands the list item if set to true.
/// Defaults to false.
final bool expanded;

/// {@macro zeta-component-rounded}
final bool rounded;

/// {@macro list-item-show-divider}
final bool? showDivider;

@override
State<ZetaDropdownListItem> createState() => _ZetaDropdownListItemState();
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(IterableProperty<ZetaListItem>('items', items))
..add(StringProperty('primaryText', primaryText))
..add(StringProperty('secondaryText', secondaryText))
..add(DiagnosticsProperty<bool>('expanded', expanded))
..add(DiagnosticsProperty<bool>('rounded', rounded))
..add(DiagnosticsProperty<bool?>('showDivider', showDivider));
}
}

class _ZetaDropdownListItemState extends State<ZetaDropdownListItem> with SingleTickerProviderStateMixin {
late AnimationController _expandController;
late Animation<double> _animation;

late bool _expanded;

IconData get _icon {
return widget.rounded ? ZetaIcons.expand_more_round : ZetaIcons.expand_more_sharp;
}

@override
void initState() {
_expanded = widget.expanded;
_expandController = AnimationController(
vsync: this,
duration: ZetaAnimationLength.fast,
);
_animation = CurvedAnimation(
parent: _expandController,
curve: Curves.easeInOut,
);
if (_expanded) {
_expandController.value = 1;
}
super.initState();
}

@override
void didUpdateWidget(covariant ZetaDropdownListItem oldWidget) {
if (oldWidget.expanded != widget.expanded) {
_setExpanded(widget.expanded);
}
super.didUpdateWidget(oldWidget);
}

@override
void dispose() {
_expandController.dispose();
super.dispose();
}

void _setExpanded(bool value) {
setState(() {
_expanded = value;
});
if (_expanded) {
_expandController.forward();
} else {
_expandController.reverse();
}
}

void _onTap() => _setExpanded(!_expanded);

@override
Widget build(BuildContext context) {
final divide = widget.showDivider ?? ListScope.of(context)?.showDivider ?? false;
final colors = Zeta.of(context).colors;

// DecoratedBox does not correctly animated the border when the widget expands.
// ignore: use_decorated_box
return Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: divide ? colors.borderDefault : Colors.transparent,
),
),
),
child: Column(
children: [
ZetaListItem(
primaryText: widget.primaryText,
secondaryText: widget.secondaryText,
leading: widget.leading,
onTap: _onTap,
showDivider: false,
trailing: IconButton(
icon: AnimatedRotation(
turns: _expanded ? 0.5 : 0,
duration: ZetaAnimationLength.fast,
child: Icon(
_icon,
color: colors.iconSubtle,
),
),
onPressed: _onTap,
),
),
ListScope(
showDivider: false,
indentItems: true,
child: SizeTransition(
sizeFactor: _animation,
child: Column(
children: widget.items,
),
),
),
],
),
);
}
}
Loading