From 72382ad201d42f2571f3ef80c7ff5fe9c78dbb31 Mon Sep 17 00:00:00 2001 From: Matthias Ngeo Date: Thu, 1 Aug 2024 22:24:35 +0800 Subject: [PATCH] Add semantic label to avatar --- forui/example/lib/example.dart | 55 ++++++++----------- forui/lib/src/widgets/avatar/avatar.dart | 20 +++---- .../src/widgets/avatar/avatar_content.dart | 25 +++++---- 3 files changed, 47 insertions(+), 53 deletions(-) diff --git a/forui/example/lib/example.dart b/forui/example/lib/example.dart index dd036fa4e..132da2294 100644 --- a/forui/example/lib/example.dart +++ b/forui/example/lib/example.dart @@ -17,39 +17,28 @@ class _ExampleState extends State { } @override - Widget build(BuildContext context) => Column( - children: [ - DecoratedBox( - decoration: BoxDecoration( - border: Border.all(color: context.theme.colorScheme.border), - borderRadius: BorderRadius.circular(8), - ), - child: FResizable( - controller: FResizableController.cascade(), - axis: Axis.vertical, - divider: FResizableDivider.dividerThumb, - crossAxisExtent: 300, - children: [ - FResizableRegion( - initialExtent: 200, - minExtent: 100, - builder: (_, data, __) => Label(data: data, icon: FAssets.icons.sunrise, label: 'Morning'), - ), - FResizableRegion( - initialExtent: 200, - minExtent: 100, - builder: (_, data, __) => Label(data: data, icon: FAssets.icons.sun, label: 'Afternoon'), - ), - FResizableRegion( - initialExtent: 200, - minExtent: 100, - builder: (_, data, __) => Label(data: data, icon: FAssets.icons.sunset, label: 'Evening'), - ), - ], - ), - ), - ], - ); + Widget build(BuildContext context) => Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CircleAvatar( + child: Image.network('https://raw.githubusercontent.com/forus-labs/forui/main/samples/assets/avatar.png'), + ), + FAvatar( + image: const NetworkImage('https://raw.githubusercontent.com/forus-labs/forui/main/samples/assets/avatar.png'), + semanticLabel: 'My profile picture', + fallback: const Text('MN'), + ), + const SizedBox(width: 10), + FAvatar( + image: const AssetImage(''), + fallback: const Text('MN'), + ), + const SizedBox(width: 10), + FAvatar( + image: const AssetImage(''), + ), + ], + ); } class Label extends StatelessWidget { diff --git a/forui/lib/src/widgets/avatar/avatar.dart b/forui/lib/src/widgets/avatar/avatar.dart index 2dee94eb2..e2d513263 100644 --- a/forui/lib/src/widgets/avatar/avatar.dart +++ b/forui/lib/src/widgets/avatar/avatar.dart @@ -22,25 +22,25 @@ class FAvatar extends StatelessWidget { /// The circle's size. final double size; - /// The fallback widget displayed if image parameter fails to load. + /// The child, typically an image. /// - /// Typically used to display the user's initials using a [Text] widget - /// styled with [FAvatarStyle.backgroundColor]. - /// - /// Use image parameter to display an image; use [fallback] for initials. - final Widget fallback; + /// If the image fails to load, a fallback widget, typically a [Text] widget used to display the user's initials + /// styled with [FAvatarStyle.backgroundColor] is displayed. + final Widget child; /// Creates an [FAvatar]. FAvatar({ required ImageProvider image, this.style, this.size = 40.0, + String? semanticLabel, Widget? fallback, super.key, - }) : fallback = _AvatarContent( - image: image, + }) : child = _AvatarContent( style: style, size: size, + image: image, + semanticLabel: semanticLabel, fallback: fallback, ); @@ -50,7 +50,7 @@ class FAvatar extends StatelessWidget { this.style, this.size = 40.0, super.key, - }) : fallback = child ?? _Placeholder(style: style, size: size); + }) : child = child ?? _Placeholder(style: style, size: size); @override Widget build(BuildContext context) { @@ -67,7 +67,7 @@ class FAvatar extends StatelessWidget { clipBehavior: Clip.hardEdge, child: DefaultTextStyle( style: style.text, - child: fallback, + child: child, ), ); } diff --git a/forui/lib/src/widgets/avatar/avatar_content.dart b/forui/lib/src/widgets/avatar/avatar_content.dart index e9e9096c8..5595a0fcb 100644 --- a/forui/lib/src/widgets/avatar/avatar_content.dart +++ b/forui/lib/src/widgets/avatar/avatar_content.dart @@ -1,16 +1,18 @@ part of 'avatar.dart'; class _AvatarContent extends StatelessWidget { - final ImageProvider image; - final double size; final FAvatarStyle? style; + final double size; + final ImageProvider image; + final String? semanticLabel; final Widget? fallback; const _AvatarContent({ - required this.image, + required this.style, required this.size, - this.style, - this.fallback, + required this.image, + required this.semanticLabel, + required this.fallback, }); @override @@ -24,6 +26,7 @@ class _AvatarContent extends StatelessWidget { width: size, filterQuality: FilterQuality.medium, image: image, + semanticLabel: semanticLabel, errorBuilder: (context, exception, stacktrace) => fallback, frameBuilder: (context, child, frame, wasSynchronouslyLoaded) { if (wasSynchronouslyLoaded) { @@ -48,15 +51,17 @@ class _AvatarContent extends StatelessWidget { void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties - ..add(DiagnosticsProperty('image', image)) + ..add(DiagnosticsProperty('style', style)) ..add(DoubleProperty('size', size)) - ..add(DiagnosticsProperty('style', style)); + ..add(DiagnosticsProperty('image', image)) + ..add(StringProperty('semanticLabel', semanticLabel)) + ..add(DiagnosticsProperty('fallback', fallback)); } } class _Placeholder extends StatelessWidget { - final double size; final FAvatarStyle? style; + final double size; const _Placeholder({required this.size, this.style}); @@ -73,7 +78,7 @@ class _Placeholder extends StatelessWidget { void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties - ..add(DoubleProperty('size', size)) - ..add(DiagnosticsProperty('style', style)); + ..add(DiagnosticsProperty('style', style)) + ..add(DoubleProperty('size', size)); } }