From 1690a30422567f650f9d31deab8bbfbde0274406 Mon Sep 17 00:00:00 2001 From: Luke Walton Date: Mon, 8 Jul 2024 14:01:29 +0100 Subject: [PATCH] fix: Improve semantics for ChatListItem (#128) --- coverage/lcov.info | 156 ++++----- .../pages/components/chat_item_example.dart | 1 + lib/src/components/chat_item/chat_item.dart | 302 +++++++++--------- 3 files changed, 236 insertions(+), 223 deletions(-) diff --git a/coverage/lcov.info b/coverage/lcov.info index a5f30c22..aa09329f 100644 --- a/coverage/lcov.info +++ b/coverage/lcov.info @@ -1098,22 +1098,20 @@ LH:0 end_of_record SF:lib/src/components/chat_item/chat_item.dart DA:12,0 -DA:97,0 -DA:98,0 -DA:100,0 +DA:101,0 +DA:102,0 DA:104,0 -DA:105,0 -DA:107,0 +DA:108,0 +DA:109,0 DA:110,0 -DA:111,0 DA:112,0 -DA:114,0 +DA:115,0 +DA:116,0 DA:117,0 DA:119,0 -DA:121,0 -DA:123,0 +DA:122,0 DA:124,0 -DA:125,0 +DA:126,0 DA:128,0 DA:129,0 DA:130,0 @@ -1122,134 +1120,140 @@ DA:134,0 DA:135,0 DA:138,0 DA:139,0 -DA:142,0 +DA:140,0 DA:143,0 DA:144,0 -DA:145,0 -DA:146,0 DA:147,0 DA:148,0 DA:149,0 -DA:150,0 +DA:151,0 +DA:152,0 +DA:153,0 DA:154,0 DA:155,0 DA:156,0 DA:158,0 -DA:159,0 -DA:160,0 +DA:162,0 +DA:163,0 DA:164,0 +DA:166,0 DA:167,0 DA:168,0 DA:169,0 DA:170,0 -DA:171,0 DA:173,0 +DA:174,0 +DA:175,0 DA:176,0 DA:177,0 -DA:178,0 DA:179,0 -DA:180,0 +DA:182,0 +DA:183,0 DA:184,0 +DA:185,0 DA:186,0 -DA:187,0 -DA:189,0 DA:190,0 -DA:191,0 -DA:194,0 +DA:192,0 +DA:193,0 +DA:195,0 +DA:196,0 DA:197,0 -DA:198,0 -DA:201,0 -DA:202,0 +DA:200,0 DA:203,0 DA:204,0 -DA:205,0 +DA:207,0 DA:208,0 -DA:212,0 -DA:213,0 +DA:209,0 +DA:210,0 +DA:211,0 DA:214,0 -DA:215,0 -DA:216,0 +DA:218,0 +DA:219,0 DA:220,0 +DA:221,0 DA:222,0 -DA:225,0 DA:226,0 -DA:230,0 +DA:228,0 +DA:231,0 DA:232,0 -DA:235,0 DA:236,0 -DA:243,0 -DA:244,0 -DA:247,0 -DA:248,0 +DA:238,0 +DA:241,0 +DA:242,0 DA:249,0 DA:250,0 -DA:264,0 -DA:266,0 -DA:267,0 -DA:268,0 -DA:269,0 +DA:253,0 +DA:254,0 +DA:255,0 +DA:256,0 +DA:270,0 DA:272,0 DA:273,0 +DA:274,0 DA:275,0 DA:278,0 DA:279,0 -DA:283,0 +DA:281,0 DA:284,0 DA:285,0 -DA:308,0 -DA:310,0 -DA:312,0 -DA:313,0 -DA:314,0 +DA:289,0 +DA:290,0 +DA:291,0 DA:315,0 -DA:316,0 DA:317,0 -DA:318,0 DA:319,0 DA:320,0 DA:321,0 DA:322,0 DA:323,0 +DA:324,0 +DA:325,0 +DA:326,0 +DA:327,0 +DA:328,0 +DA:329,0 DA:330,0 DA:331,0 -DA:333,0 -DA:334,0 -DA:335,0 -DA:336,0 -DA:337,0 DA:338,0 DA:339,0 -DA:340,0 DA:341,0 DA:342,0 +DA:343,0 +DA:344,0 +DA:345,0 +DA:346,0 +DA:347,0 +DA:348,0 +DA:349,0 DA:350,0 -DA:360,0 -DA:365,0 -DA:376,0 -DA:387,0 -DA:398,0 -DA:442,0 -DA:444,0 -DA:445,0 -DA:446,0 -DA:448,0 -DA:449,0 +DA:358,0 +DA:368,0 +DA:373,0 +DA:384,0 +DA:395,0 +DA:406,0 +DA:450,0 +DA:452,0 DA:453,0 DA:454,0 -DA:455,0 DA:456,0 DA:457,0 DA:461,0 +DA:462,0 +DA:463,0 +DA:464,0 +DA:465,0 DA:469,0 -DA:471,0 -DA:473,0 -DA:474,0 -DA:475,0 -DA:476,0 DA:477,0 -DA:478,0 DA:479,0 -LF:152 +DA:481,0 +DA:482,0 +DA:483,0 +DA:484,0 +DA:485,0 +DA:486,0 +DA:487,0 +LF:156 LH:0 end_of_record SF:lib/src/components/checkbox/checkbox.dart diff --git a/example/lib/pages/components/chat_item_example.dart b/example/lib/pages/components/chat_item_example.dart index b05eaa42..f1e4f039 100644 --- a/example/lib/pages/components/chat_item_example.dart +++ b/example/lib/pages/components/chat_item_example.dart @@ -20,6 +20,7 @@ class _ChatItemExampleState extends State { child: Column( children: [ ZetaChatItem( + explicitChildNodes: false, time: DateTime.now(), enabledWarningIcon: true, enabledNotificationIcon: true, diff --git a/lib/src/components/chat_item/chat_item.dart b/lib/src/components/chat_item/chat_item.dart index c3dcc126..5fa76d16 100644 --- a/lib/src/components/chat_item/chat_item.dart +++ b/lib/src/components/chat_item/chat_item.dart @@ -25,6 +25,7 @@ class ZetaChatItem extends ZetaStatelessWidget { this.onTap, this.starred, this.slidableActions = const [], + this.explicitChildNodes = true, @Deprecated('Use slidableActions instead.' ' This variable has been replaced as of 0.12.1') this.onMenuMoreTap, @Deprecated('Use slidableActions instead.' ' This variable has been replaced as of 0.12.1') this.onCallTap, @Deprecated('Use slidableActions instead.' ' This variable has been replaced as of 0.12.1') this.onDeleteTap, @@ -73,6 +74,9 @@ class ZetaChatItem extends ZetaStatelessWidget { /// If null, the star will not be rendered. final bool? starred; + /// Whether to show explicit child nodes in the semantics tree. + final bool explicitChildNodes; + /// Callback for slidable action - menu more. @Deprecated('Use slidableActions instead.' ' This variable has been replaced as of 0.12.1') final VoidCallback? onMenuMoreTap; @@ -99,12 +103,13 @@ class ZetaChatItem extends ZetaStatelessWidget { double _getSlidableExtend({ required int slidableActionsCount, - required double maxWidth, + required double maxScreenWidth, }) { - final actionsExtend = slidableActionsCount * ZetaSpacing.xl_10; - final extend = actionsExtend / maxWidth; + final actionWith = slidableActionsCount * ZetaSpacing.xl_10; + final maxButtonWidth = actionWith / maxScreenWidth; + final extend = actionWith / maxScreenWidth; - return extend.clamp(0.5, 1); + return extend.clamp(0, maxButtonWidth); } Widget? get _formatLeading { @@ -141,165 +146,167 @@ class ZetaChatItem extends ZetaStatelessWidget { return ZetaRoundedScope( rounded: context.rounded, - child: SelectionContainer.disabled( - child: LayoutBuilder( - builder: (context, constraints) { - return Slidable( - enabled: actions.isNotEmpty, - endActionPane: ActionPane( - extentRatio: _getSlidableExtend(slidableActionsCount: actions.length, maxWidth: constraints.maxWidth), - motion: const ScrollMotion(), - children: actions, - ), - child: ColoredBox( - color: highlighted ? colors.blue.shade10 : colors.surfacePrimary, - child: Material( - color: Colors.transparent, - child: InkWell( - onTap: onTap, - child: Semantics( - container: true, - button: true, - excludeSemantics: true, - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: ZetaSpacing.medium, vertical: ZetaSpacing.small), - child: Row( - children: [ - if (leading != null) _formatLeading!, - Flexible( - child: Padding( - padding: const EdgeInsets.only(left: ZetaSpacing.medium), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - if (highlighted) - Container( - margin: const EdgeInsets.only(right: ZetaSpacing.minimum), - height: ZetaSpacing.small, - width: ZetaSpacing.small, - decoration: BoxDecoration(color: colors.primary, shape: BoxShape.circle), - ), - Flexible( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: DefaultTextStyle( - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: (highlighted - ? ZetaTextStyles.labelLarge - : ZetaTextStyles.bodyMedium) - .copyWith(color: colors.textDefault), - child: title, + child: Semantics( + button: true, + child: SelectionContainer.disabled( + child: LayoutBuilder( + builder: (context, constraints) { + return Slidable( + enabled: actions.isNotEmpty, + endActionPane: ActionPane( + extentRatio: + _getSlidableExtend(slidableActionsCount: actions.length, maxScreenWidth: constraints.maxWidth), + motion: const ScrollMotion(), + children: actions, + ), + child: ColoredBox( + color: highlighted ? colors.blue.shade10 : colors.surfacePrimary, + child: Material( + color: Colors.transparent, + child: InkWell( + onTap: onTap, + child: Semantics( + explicitChildNodes: explicitChildNodes, + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: ZetaSpacing.medium, vertical: ZetaSpacing.small), + child: Row( + children: [ + if (leading != null) _formatLeading!, + Flexible( + child: Padding( + padding: const EdgeInsets.only(left: ZetaSpacing.medium), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + if (highlighted) + Container( + margin: const EdgeInsets.only(right: ZetaSpacing.minimum), + height: ZetaSpacing.small, + width: ZetaSpacing.small, + decoration: BoxDecoration(color: colors.primary, shape: BoxShape.circle), + ), + Flexible( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: DefaultTextStyle( + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: (highlighted + ? ZetaTextStyles.labelLarge + : ZetaTextStyles.bodyMedium) + .copyWith(color: colors.textDefault), + child: title, + ), ), - ), - Row( - children: [ - if (time != null) - Text( - _dateFormat.format(time!), - style: ZetaTextStyles.bodyXSmall, - ), - IconTheme( - data: const IconThemeData( - size: ZetaSpacing.large, - ), - child: Row( - children: [ - ...additionalIcons, - if (enabledNotificationIcon) - Padding( - padding: const EdgeInsets.only( - left: ZetaSpacing.minimum, - ), - child: ZetaIcon( - ZetaIcons.error, - color: colors.cool.shade70, - ), - ), - if (enabledWarningIcon) - Padding( - padding: const EdgeInsets.only( - left: ZetaSpacing.minimum, - ), - child: Icon( - Icons.circle_notifications, - color: colors.surfaceNegative, - ), - ), - if (_count != null) - Container( - margin: const EdgeInsets.only( - left: ZetaSpacing.minimum, - ), - padding: const EdgeInsets.symmetric( - horizontal: ZetaSpacing.small, + Row( + children: [ + if (time != null) + Text( + _dateFormat.format(time!), + style: ZetaTextStyles.bodyXSmall, + ), + IconTheme( + data: const IconThemeData( + size: ZetaSpacing.large, + ), + child: Row( + children: [ + ...additionalIcons, + if (enabledNotificationIcon) + Padding( + padding: const EdgeInsets.only( + left: ZetaSpacing.minimum, + ), + child: ZetaIcon( + ZetaIcons.error, + color: colors.cool.shade70, + ), ), - decoration: BoxDecoration( - color: colors.primary, - borderRadius: ZetaRadius.full, + if (enabledWarningIcon) + Padding( + padding: const EdgeInsets.only( + left: ZetaSpacing.minimum, + ), + child: Icon( + Icons.circle_notifications, + color: colors.surfaceNegative, + ), ), - child: Text( - _count!, - style: ZetaTextStyles.labelSmall.copyWith( - color: colors.textInverse, + if (_count != null) + Container( + margin: const EdgeInsets.only( + left: ZetaSpacing.minimum, + ), + padding: const EdgeInsets.symmetric( + horizontal: ZetaSpacing.small, + ), + decoration: BoxDecoration( + color: colors.primary, + borderRadius: ZetaRadius.full, + ), + child: Text( + _count!, + style: ZetaTextStyles.labelSmall.copyWith( + color: colors.textInverse, + ), ), ), - ), - ], + ], + ), ), - ), - ], - ), - ], - ), - ), - ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - if (subtitle != null) - Flexible( - child: DefaultTextStyle( - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: ZetaTextStyles.bodySmall.copyWith( - color: colors.textSubtle, - ), - child: subtitle!, + ], + ), + ], ), ), - if (starred != null) - Padding( - padding: const EdgeInsets.only( - left: ZetaSpacing.minimum, + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + if (subtitle != null) + Flexible( + child: DefaultTextStyle( + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: ZetaTextStyles.bodySmall.copyWith( + color: colors.textSubtle, + ), + child: subtitle!, + ), ), - child: ZetaIcon( - starred! ? ZetaIcons.star : ZetaIcons.star_outline, - color: starred! ? colors.yellow.shade60 : null, + if (starred != null) + Padding( + padding: const EdgeInsets.only( + left: ZetaSpacing.minimum, + ), + child: ZetaIcon( + starred! ? ZetaIcons.star : ZetaIcons.star_outline, + color: starred! ? colors.yellow.shade60 : null, + ), ), - ), - ], - ), - ], + ], + ), + ], + ), ), ), - ), - ], + ], + ), ), ), ), ), ), - ), - ); - }, + ); + }, + ), ), ), ); @@ -320,7 +327,8 @@ class ZetaChatItem extends ZetaStatelessWidget { ..add(ObjectFlagProperty.has('onMenuMoreTap', onMenuMoreTap)) ..add(ObjectFlagProperty.has('onCallTap', onCallTap)) ..add(ObjectFlagProperty.has('onDeleteTap', onDeleteTap)) - ..add(ObjectFlagProperty.has('onPttTap', onPttTap)); + ..add(ObjectFlagProperty.has('onPttTap', onPttTap)) + ..add(DiagnosticsProperty('explicitChildNodes', explicitChildNodes)); } }