feat: add semantics for text fields

This commit is contained in:
Jacques 2025-02-27 17:25:20 +01:00 committed by FlutterJoey
parent 30fc7b4368
commit b3b8b1828e
6 changed files with 158 additions and 106 deletions

View file

@ -7,9 +7,9 @@
/// Class that holds all the semantic ids for the chat component view and
/// the corresponding userstory
class ChatSemantics {
/// ChatTranslations constructor where everything is required use this
/// ChatSemantics constructor where everything is required use this
/// if you want to be sure to have all translations specified
/// If you just want the default values use the empty constructor
/// If you just want the default values use the standard constructor
/// and optionally override the values with the copyWith method
const ChatSemantics({
required this.profileTitle,
@ -28,6 +28,11 @@ class ChatSemantics {
required this.chatsChatSubTitle,
required this.chatsChatLastUsed,
required this.chatsChatUnreadMessages,
required this.chatMessageInput,
required this.newChatNameInput,
required this.newChatBioInput,
required this.newChatSearchInput,
required this.newGroupChatSearchInput,
});
/// Default translations for the chat component view
@ -48,6 +53,11 @@ class ChatSemantics {
this.chatsChatSubTitle = _defaultChatsChatSubTitle,
this.chatsChatLastUsed = _defaultChatsChatLastUsed,
this.chatsChatUnreadMessages = _defaultChatsChatUnreadMessages,
this.chatMessageInput = "input_text_message",
this.newChatNameInput = "input_text_name",
this.newChatBioInput = "input_text_bio",
this.newChatSearchInput = "input_text_search",
this.newGroupChatSearchInput = "input_text_search",
});
// Text
@ -70,6 +80,13 @@ class ChatSemantics {
final String Function(int index) chatsChatLastUsed;
final String Function(int index) chatsChatUnreadMessages;
// Input texts
final String chatMessageInput;
final String newChatNameInput;
final String newChatBioInput;
final String newChatSearchInput;
final String newGroupChatSearchInput;
ChatSemantics copyWith({
String? profileTitle,
String? profileDescription,
@ -87,6 +104,11 @@ class ChatSemantics {
String Function(int)? chatsChatSubTitle,
String Function(int)? chatsChatLastUsed,
String Function(int)? chatsChatUnreadMessages,
String? chatMessageInput,
String? newChatNameInput,
String? newChatBioInput,
String? newChatSearchInput,
String? newGroupChatSearchInput,
}) =>
ChatSemantics(
profileTitle: profileTitle ?? this.profileTitle,
@ -109,6 +131,12 @@ class ChatSemantics {
chatsChatLastUsed: chatsChatLastUsed ?? this.chatsChatLastUsed,
chatsChatUnreadMessages:
chatsChatUnreadMessages ?? this.chatsChatUnreadMessages,
chatMessageInput: chatMessageInput ?? this.chatMessageInput,
newChatNameInput: newChatNameInput ?? this.newChatNameInput,
newChatBioInput: newChatBioInput ?? this.newChatBioInput,
newChatSearchInput: newChatSearchInput ?? this.newChatSearchInput,
newGroupChatSearchInput:
newGroupChatSearchInput ?? this.newGroupChatSearchInput,
);
}

View file

@ -1,5 +1,6 @@
import "package:chat_repository_interface/chat_repository_interface.dart";
import "package:flutter/material.dart";
import "package:flutter_accessibility/flutter_accessibility.dart";
import "package:flutter_chat/src/util/scope.dart";
import "package:flutter_hooks/flutter_hooks.dart";
@ -91,7 +92,10 @@ class ChatBottomInputSection extends HookWidget {
var defaultInputField = Stack(
children: [
TextField(
CustomSemantics(
identifier: options.semantics.chatMessageInput,
isTextField: true,
child: TextField(
textAlign: TextAlign.start,
textAlignVertical: TextAlignVertical.center,
style: theme.textTheme.bodySmall,
@ -133,6 +137,7 @@ class ChatBottomInputSection extends HookWidget {
),
onSubmitted: (_) async => onSubmitField(),
),
),
Positioned(
right: 0,
bottom: 0,

View file

@ -139,6 +139,7 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget {
onSearch: onSearch,
focusNode: focusNode,
text: options.translations.newChatTitle,
semanticId: options.semantics.newChatSearchInput,
),
actions: [
SearchIcon(

View file

@ -226,7 +226,10 @@ class _BodyState extends State<_Body> {
const SizedBox(
height: 12,
),
TextFormField(
CustomSemantics(
identifier: options.semantics.newChatNameInput,
isTextField: true,
child: TextFormField(
style: theme.textTheme.bodySmall,
controller: _chatNameController,
decoration: InputDecoration(
@ -258,6 +261,7 @@ class _BodyState extends State<_Body> {
return null;
},
),
),
const SizedBox(
height: 16,
),
@ -268,7 +272,10 @@ class _BodyState extends State<_Body> {
const SizedBox(
height: 12,
),
TextFormField(
CustomSemantics(
identifier: options.semantics.newChatBioInput,
isTextField: true,
child: TextFormField(
style: theme.textTheme.bodySmall,
controller: _bioController,
minLines: null,
@ -299,6 +306,7 @@ class _BodyState extends State<_Body> {
return null;
},
),
),
const SizedBox(
height: 16,
),

View file

@ -149,6 +149,7 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget {
onSearch: onSearch,
focusNode: focusNode,
text: options.translations.newGroupChatTitle,
semanticId: options.semantics.newGroupChatSearchInput,
),
actions: [
SearchIcon(

View file

@ -1,4 +1,5 @@
import "package:flutter/material.dart";
import "package:flutter_accessibility/flutter_accessibility.dart";
import "package:flutter_chat/src/util/scope.dart";
/// The search field widget
@ -9,6 +10,7 @@ class SearchField extends StatelessWidget {
required this.onSearch,
required this.focusNode,
required this.text,
required this.semanticId,
super.key,
});
@ -24,6 +26,9 @@ class SearchField extends StatelessWidget {
/// The text to display in the search field
final String text;
/// Semantic id for search field
final String semanticId;
@override
Widget build(BuildContext context) {
var chatScope = ChatScope.of(context);
@ -32,7 +37,10 @@ class SearchField extends StatelessWidget {
var translations = options.translations;
if (isSearching) {
return TextField(
return CustomSemantics(
identifier: semanticId,
isTextField: true,
child: TextField(
focusNode: focusNode,
onChanged: onSearch,
decoration: InputDecoration(
@ -46,6 +54,7 @@ class SearchField extends StatelessWidget {
),
style: theme.textTheme.bodySmall,
cursorColor: theme.textSelectionTheme.cursorColor ?? Colors.white,
),
);
}