diff --git a/example/lib/pages/components/list_item_example.dart b/example/lib/pages/components/list_item_example.dart index cc0cf1d4..7a271232 100644 --- a/example/lib/pages/components/list_item_example.dart +++ b/example/lib/pages/components/list_item_example.dart @@ -38,6 +38,14 @@ class _ListItemExampleState extends State { primaryText: 'List Item', secondaryText: 'Descriptor', )), + _buildListItem( + 'Custom Title', + ZetaListItem( + title: ZetaButton( + label: 'Custom Title Button', + onPressed: () {}, + ), + )), _buildListItem( 'Icon Left', ZetaListItem(primaryText: 'List Item', leading: ZetaIcon(ZetaIcons.star)), diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index 8c72a8c7..63ad0d13 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,7 +7,7 @@ import Foundation import path_provider_foundation import shared_preferences_foundation -import sqflite_darwin +import sqflite import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { diff --git a/lib/src/components/list_item/dropdown_list_item.dart b/lib/src/components/list_item/dropdown_list_item.dart index 2a922002..8b8d508e 100644 --- a/lib/src/components/list_item/dropdown_list_item.dart +++ b/lib/src/components/list_item/dropdown_list_item.dart @@ -15,24 +15,40 @@ class ZetaDropdownListItem extends ZetaStatefulWidget { const ZetaDropdownListItem({ super.key, super.rounded, - required this.primaryText, required this.items, + this.title, + this.primaryText, this.secondaryText, + this.primaryTextStyle, + this.secondaryTextStyle, this.expanded = false, this.leading, this.showDivider, this.semanticLabel, - }); + }) : assert( + (title != null && primaryText == null && secondaryText == null) || + (title == null && (primaryText != null || secondaryText != null)), + 'Provide one of either title or primaryText/secondaryText', + ); /// The list of [ZetaListItem]s contained within the dropdown. final List items; + /// {@macro list-item-title} + final Widget? title; + /// {@macro list-item-primary-text} - final String primaryText; + final String? primaryText; + + /// {@macro list-item-primary-text-style} + final TextStyle? primaryTextStyle; /// {@macro list-item-secondary-text} final String? secondaryText; + /// {@macro list-item-secondary-text-style} + final TextStyle? secondaryTextStyle; + /// {@macro list-item-leading} final Widget? leading; @@ -61,7 +77,9 @@ class ZetaDropdownListItem extends ZetaStatefulWidget { ..add(DiagnosticsProperty('expanded', expanded)) ..add(DiagnosticsProperty('rounded', rounded)) ..add(DiagnosticsProperty('showDivider', showDivider)) - ..add(StringProperty('semanticLabel', semanticLabel)); + ..add(StringProperty('semanticLabel', semanticLabel)) + ..add(DiagnosticsProperty('primaryTextStyle', primaryTextStyle)) + ..add(DiagnosticsProperty('secondaryTextStyle', secondaryTextStyle)); } } @@ -125,7 +143,7 @@ class _ZetaDropdownListItemState extends State with Single child: Semantics( button: true, selected: _expanded, - label: widget.semanticLabel ?? (widget.primaryText + (widget.secondaryText ?? '')), + label: widget.semanticLabel ?? ((widget.primaryText ?? '') + (widget.secondaryText ?? '')), // DecoratedBox does not correctly animated the border when the widget expands. // ignore: use_decorated_box child: Container( @@ -140,8 +158,11 @@ class _ZetaDropdownListItemState extends State with Single children: [ ExcludeSemantics( child: ZetaListItem( + title: widget.title, primaryText: widget.primaryText, + primaryTextStyle: widget.primaryTextStyle, secondaryText: widget.secondaryText, + secondaryTextStyle: widget.secondaryTextStyle, leading: widget.leading, onTap: _onTap, showDivider: false, diff --git a/lib/src/components/list_item/list_item.dart b/lib/src/components/list_item/list_item.dart index 01d69254..d5b14d02 100644 --- a/lib/src/components/list_item/list_item.dart +++ b/lib/src/components/list_item/list_item.dart @@ -61,22 +61,32 @@ class ZetaList extends ZetaStatelessWidget { class ZetaListItem extends ZetaStatelessWidget { /// Creates a [ZetaListItem]. const ZetaListItem({ - required this.primaryText, + this.title, + this.primaryText, this.secondaryText, + this.primaryTextStyle, + this.secondaryTextStyle, this.leading, this.onTap, this.showDivider, this.trailing, super.key, super.rounded, - }); + }) : assert( + (title != null && primaryText == null && secondaryText == null) || + (title == null && primaryText != null || secondaryText != null), + 'Provide one of either title or primaryText/secondaryText', + ); /// Creates a [ZetaListItem] with a [ZetaSwitch] in the trailing widget space. ZetaListItem.toggle({ super.key, super.rounded, - required this.primaryText, + this.title, + this.primaryText, this.secondaryText, + this.primaryTextStyle, + this.secondaryTextStyle, this.showDivider, this.leading, bool value = false, @@ -86,14 +96,22 @@ class ZetaListItem extends ZetaStatelessWidget { onChanged: onChanged, variant: ZetaSwitchType.android, ), - onTap = (() => onChanged?.call(!value)); + onTap = (() => onChanged?.call(!value)), + assert( + (title != null && primaryText == null && secondaryText == null) || + (title == null && (primaryText != null || secondaryText != null)), + 'Provide one of either title or primaryText/secondaryText', + ); /// Creates a [ZetaListItem] with a [ZetaCheckbox] in the trailing widget space. ZetaListItem.checkbox({ super.key, super.rounded, - required this.primaryText, + this.title, + this.primaryText, this.secondaryText, + this.primaryTextStyle, + this.secondaryTextStyle, this.leading, this.showDivider, bool value = false, @@ -105,13 +123,21 @@ class ZetaListItem extends ZetaStatelessWidget { useIndeterminate: useIndeterminate, rounded: rounded, ), - onTap = (() => onChanged?.call(!value)); + onTap = (() => onChanged?.call(!value)), + assert( + (title != null && primaryText == null && secondaryText == null) || + (title == null && (primaryText != null || secondaryText != null)), + 'Provide one of either title or primaryText/secondaryText', + ); /// Creates a [ZetaListItem] with a [ZetaRadio] in the trailing widget space. ZetaListItem.radio({ - required this.primaryText, required dynamic value, + this.title, + this.primaryText, this.secondaryText, + this.primaryTextStyle, + this.secondaryTextStyle, this.leading, this.showDivider, dynamic groupValue, @@ -123,7 +149,12 @@ class ZetaListItem extends ZetaStatelessWidget { groupValue: groupValue, onChanged: onChanged, ), - onTap = (() => onChanged?.call(value)); + onTap = (() => onChanged?.call(value)), + assert( + (title != null && primaryText == null && secondaryText == null) || + (title == null && (primaryText != null || secondaryText != null)), + 'Provide one of either title or primaryText/secondaryText', + ); /// {@template list-item-leading} /// A widget to display before the title; @@ -133,16 +164,34 @@ class ZetaListItem extends ZetaStatelessWidget { /// Called when user taps on the [ZetaListItem]. final VoidCallback? onTap; + /// {@template list-item-title} + /// The primary content of the list item. + /// Cannot be provided with [primaryText] or [secondaryText]. + /// {@endtemplate} + final Widget? title; + /// {@template list-item-primary-text} /// The primary text of the [ZetaListItem]. + /// Cannot be provided with [title]. + /// {@endtemplate} + final String? primaryText; + + /// {@template list-item-primary-text-style} + /// The text style applied to [primaryText]. /// {@endtemplate} - final String primaryText; + final TextStyle? primaryTextStyle; /// {@template list-item-secondary-text} /// The secondary text of the [ZetaListItem]. + /// Cannot be provided with [title]. /// {@endtemplate} final String? secondaryText; + /// {@template list-item-secondary-text-style} + /// The text style applied to [secondaryText]. + /// {@endtemplate} + final TextStyle? secondaryTextStyle; + /// A widget to display after the primary text. /// If this is a checkbox, radio button, or switch, use the relevant named constructor. final Widget? trailing; @@ -162,7 +211,9 @@ class ZetaListItem extends ZetaStatelessWidget { ..add(DiagnosticsProperty('trailing', trailing)) ..add(StringProperty('label', primaryText)) ..add(StringProperty('secondaryText', secondaryText)) - ..add(DiagnosticsProperty('showDivider', showDivider)); + ..add(DiagnosticsProperty('showDivider', showDivider)) + ..add(DiagnosticsProperty('secondaryTextStyle', secondaryTextStyle)) + ..add(DiagnosticsProperty('primaryTextStyle', primaryTextStyle)); } @override @@ -209,23 +260,26 @@ class ZetaListItem extends ZetaStatelessWidget { child: leadingWidget, ), Flexible( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - primaryText, - maxLines: 1, - overflow: TextOverflow.ellipsis, + child: title ?? + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (primaryText != null && primaryText!.isNotEmpty) + Text( + primaryText!, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: primaryTextStyle, + ), + if (secondaryText != null && secondaryText!.isNotEmpty) + Text( + secondaryText!, + style: secondaryTextStyle ?? ZetaTextStyles.bodySmall, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], ), - if (secondaryText != null && secondaryText!.isNotEmpty) - Text( - secondaryText!, - style: ZetaTextStyles.bodySmall, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ], - ), ), ], ),