From 0446d0e1900f4d75c6b0e7e8b94deffc4478d3b2 Mon Sep 17 00:00:00 2001 From: Dustin Healy <54083382+dustinhealy@users.noreply.github.com> Date: Tue, 28 Oct 2025 00:46:43 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BF=20fix:=20Address=20Accessibility=20Is?= =?UTF-8?q?sues=20(#10260)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: add i18n localization comment for AlwaysMakeProd component * feat: enhance accessibility by adding aria-label and aria-labelledby to Switch component * feat: add aria-labels for accessibility in Agent and Assistant avatar buttons * fix: add switch aria-labels for accessibility in various components * feat: add aria-labels and localization keys for accessibility in DataTable, DataTableColumnHeader, and OGDialogTemplate components * chore: refactor out nested ternary * feat: add aria-label to DataTable filter button for My Files modal * feat: add aria-labels for Buttons and localization strings * feat: add aria-labels to Checkboxes in Agent Builder * feat: enhance accessibility by adding aria-label and aria-labelledby to Checkbox component * feat: add aria-label to FileSearchCheckbox in Agent Builder * feat: add aria-label to Prompts text input area * feat: enhance accessibility by adding aria-label and aria-labelledby to TextAreaAutosize component * feat: remove improper role: "list" prop from List in Conversations.tsx to enhance accessibility and stop aria rules conflicting within react-virtualized component * feat: enhance accessibility by allowing tab navigation and adding ring highlights for conversation title editing accept/reject buttons * feat: add aria-label to Copy Link button in the conversation share modal * feat: add title to QR code svg in conversation share modal to describe the image content * feat: enhance accessibility by making Agent Avatar upload keyboard navigable and round out highlight border on focus * feat: enhance accessibility by adding aria attributes around alerting users with screen readers to invalid email address inputs in the Agent Builder * feat: add aria-labels to buttons in Advanced panel of Agent Builder * feat: enhance accessibility by making FileUpload and Clear All buttons in PresetItems keyboard navigable * feat: enchance accessiblity by indexing view and delete button aria-labels in shared links management modal to their specific chat titles * feat: add border highlighting on focus for AnimatedSearchInput * feat: add category description to aria-labels for prompts in ListCard * feat: add proper scoping to rows and columns in table headers * feat: add localized aria-labelling to EditTextPart's TextAreaAutosize component and base dynamic paramters panel components and their supporting translation keys * feat: add localized aria-labels and aria-labelledBy to Checkbox components without them * feat: add localized aria-labeledBy for endpoint settings Sliders * feat: add localized aria-labels for TextareaAutosize components * chore: remove unused i18n string * feat: add localized aria-label for BookmarkForm Checkbox * fix: add stopPropagation onKeyDown for Preview and Edit menu items in prompts that was causing the prompts to inadvertently be sent when triggered with keyboard navigation when Auto-send Prompts was toggled on * fix: switch TableCell to TableHead for title cells according to harvard issue #789 * fix: add more descriptive localization key for file filter button in DataTable * chore: remove self-explanatory code comment from RenameForm * fix: remove stray bg-yellow highlight that was left in during debugging * fix: add aria-label to model configurator panel back button * fix: undo incorrect hoist of tool name split for aria-label and span in MCPInput --------- Co-authored-by: Danny Avila --- .../Agents/MarketplaceAdminSettings.tsx | 1 + .../src/components/Bookmarks/BookmarkForm.tsx | 8 ++- client/src/components/Chat/Input/ChatForm.tsx | 3 ++ .../Chat/Input/Files/FileUpload.tsx | 34 ++++++++---- .../Chat/Input/Files/Table/DataTable.tsx | 6 ++- .../Chat/Menus/Presets/PresetItems.tsx | 10 ++-- .../Chat/Messages/Content/EditMessage.tsx | 1 + .../Messages/Content/Parts/EditTextPart.tsx | 1 + .../Conversations/Conversations.tsx | 1 - .../ConvoOptions/ShareButton.tsx | 9 +++- .../components/Conversations/RenameForm.tsx | 9 ++-- .../Endpoints/Settings/Advanced.tsx | 18 +++++-- .../Endpoints/Settings/AgentSettings.tsx | 7 ++- .../components/Endpoints/Settings/Google.tsx | 4 ++ .../components/Endpoints/Settings/Plugins.tsx | 4 ++ .../Nav/ExportConversation/ExportModal.tsx | 16 ++++-- .../Nav/SettingsTabs/Chat/SaveBadgesState.tsx | 1 + .../Nav/SettingsTabs/Chat/ShowThinking.tsx | 1 + .../Nav/SettingsTabs/Data/SharedLinks.tsx | 53 ++++++++----------- .../src/components/Prompts/AdminSettings.tsx | 8 ++- .../Prompts/Groups/AlwaysMakeProd.tsx | 2 +- .../Prompts/Groups/AutoSendPrompt.tsx | 2 +- .../Prompts/Groups/ChatGroupItem.tsx | 6 +++ .../Prompts/Groups/CreatePromptForm.tsx | 1 + client/src/components/Prompts/Groups/List.tsx | 1 + .../components/Prompts/Groups/ListCard.tsx | 4 +- .../Prompts/Groups/NoPromptGroup.tsx | 1 + .../Prompts/Groups/VariableForm.tsx | 3 +- .../src/components/Prompts/PromptEditor.tsx | 1 + .../Sharing/GenericGrantAccessDialog.tsx | 7 ++- .../Sharing/PeoplePickerAdminSettings.tsx | 2 + .../SidePanel/Agents/AdminSettings.tsx | 2 + .../Agents/Advanced/AdvancedButton.tsx | 1 + .../Agents/Advanced/AdvancedPanel.tsx | 1 + .../SidePanel/Agents/Advanced/AgentChain.tsx | 3 ++ .../SidePanel/Agents/AgentAvatar.tsx | 6 ++- .../SidePanel/Agents/AgentConfig.tsx | 18 ++++++- .../SidePanel/Agents/AgentPanel.tsx | 7 +++ .../components/SidePanel/Agents/Artifacts.tsx | 1 + .../SidePanel/Agents/Code/Action.tsx | 7 ++- .../SidePanel/Agents/Code/ApiKeyDialog.tsx | 1 + .../SidePanel/Agents/FileSearchCheckbox.tsx | 1 + .../components/SidePanel/Agents/Images.tsx | 7 +-- .../components/SidePanel/Agents/MCPInput.tsx | 13 ++++- .../components/SidePanel/Agents/MCPTool.tsx | 7 +++ .../SidePanel/Agents/ModelPanel.tsx | 1 + .../SidePanel/Agents/Search/Action.tsx | 1 + .../SidePanel/Agents/Search/ApiKeyDialog.tsx | 6 ++- .../Agents/Version/VersionButton.tsx | 1 + .../SidePanel/Bookmarks/BookmarkTable.tsx | 1 + .../SidePanel/Builder/AssistantAvatar.tsx | 6 ++- .../src/components/SidePanel/Builder/Code.tsx | 2 + .../SidePanel/Builder/ImageVision.tsx | 2 + .../SidePanel/Builder/Retrieval.tsx | 2 + .../SidePanel/Files/PanelColumns.tsx | 2 + .../src/components/SidePanel/MCP/MCPPanel.tsx | 9 +++- .../SidePanel/Memories/AdminSettings.tsx | 2 + .../SidePanel/Memories/MemoryCreateDialog.tsx | 1 + .../SidePanel/Memories/MemoryEditDialog.tsx | 1 + .../SidePanel/Memories/MemoryViewer.tsx | 6 ++- .../SidePanel/Parameters/DynamicCheckbox.tsx | 1 + .../SidePanel/Parameters/DynamicSlider.tsx | 3 ++ .../SidePanel/Parameters/DynamicSwitch.tsx | 3 ++ .../SidePanel/Parameters/DynamicTextarea.tsx | 1 + client/src/locales/en/translation.json | 14 ++++- client/src/routes/RouteErrorBoundary.tsx | 15 ++++-- .../src/components/AnimatedSearchInput.tsx | 2 +- packages/client/src/components/Checkbox.tsx | 50 +++++++++++------ packages/client/src/components/DataTable.tsx | 26 ++++++++- .../src/components/DataTableColumnHeader.tsx | 29 +++++++--- .../src/components/OGDialogTemplate.tsx | 4 +- packages/client/src/components/Switch.tsx | 48 +++++++++++------ .../src/components/TextareaAutosize.tsx | 14 ++++- .../client/src/locales/en/translation.json | 5 +- 74 files changed, 427 insertions(+), 131 deletions(-) diff --git a/client/src/components/Agents/MarketplaceAdminSettings.tsx b/client/src/components/Agents/MarketplaceAdminSettings.tsx index fa5fa34fbc..e09f168afe 100644 --- a/client/src/components/Agents/MarketplaceAdminSettings.tsx +++ b/client/src/components/Agents/MarketplaceAdminSettings.tsx @@ -58,6 +58,7 @@ const LabelController: React.FC = ({ checked={field.value} onCheckedChange={field.onChange} value={field.value.toString()} + aria-label={label} /> )} /> diff --git a/client/src/components/Bookmarks/BookmarkForm.tsx b/client/src/components/Bookmarks/BookmarkForm.tsx index 3b2633485b..23e94dbfb1 100644 --- a/client/src/components/Bookmarks/BookmarkForm.tsx +++ b/client/src/components/Bookmarks/BookmarkForm.tsx @@ -129,7 +129,11 @@ const BookmarkForm = ({
-
{conversationId != null && conversationId && ( @@ -161,6 +166,7 @@ const BookmarkForm = ({ onCheckedChange={field.onChange} className="relative float-left mr-2 inline-flex h-4 w-4 cursor-pointer" value={field.value?.toString()} + aria-label={localize('com_ui_bookmarks_add_to_conversation')} /> )} /> diff --git a/client/src/components/Chat/Input/ChatForm.tsx b/client/src/components/Chat/Input/ChatForm.tsx index b807369082..f1dc1ef076 100644 --- a/client/src/components/Chat/Input/ChatForm.tsx +++ b/client/src/components/Chat/Input/ChatForm.tsx @@ -12,6 +12,7 @@ import { import { useTextarea, useAutoSave, + useLocalize, useRequiresKey, useHandleKeyUp, useQueryParams, @@ -38,6 +39,7 @@ const ChatForm = memo(({ index = 0 }: { index?: number }) => { const submitButtonRef = useRef(null); const textAreaRef = useRef(null); useFocusChatEffect(textAreaRef); + const localize = useLocalize(); const [isCollapsed, setIsCollapsed] = useState(false); const [, setIsScrollable] = useState(false); @@ -279,6 +281,7 @@ const ChatForm = memo(({ index = 0 }: { index?: number }) => { setIsTextAreaFocused(true); }} onBlur={setIsTextAreaFocused.bind(null, false)} + aria-label={localize('com_ui_message_input')} onClick={handleFocusOrClick} style={{ height: 44, overflowY: 'auto' }} className={cn( diff --git a/client/src/components/Chat/Input/Files/FileUpload.tsx b/client/src/components/Chat/Input/Files/FileUpload.tsx index 723fa32e86..718c8c1f5d 100644 --- a/client/src/components/Chat/Input/Files/FileUpload.tsx +++ b/client/src/components/Chat/Input/Files/FileUpload.tsx @@ -62,17 +62,28 @@ const FileUpload: React.FC = ({ statusText = invalidText ?? localize('com_ui_upload_invalid'); } + const handleClick = () => { + const fileInput = document.getElementById(`file-upload-${id}`) as HTMLInputElement; + if (fileInput) { + fileInput.click(); + } + }; + return ( - + ); }; diff --git a/client/src/components/Chat/Input/Files/Table/DataTable.tsx b/client/src/components/Chat/Input/Files/Table/DataTable.tsx index ffb3e2825b..70459b2d66 100644 --- a/client/src/components/Chat/Input/Files/Table/DataTable.tsx +++ b/client/src/components/Chat/Input/Files/Table/DataTable.tsx @@ -122,7 +122,11 @@ export default function DataTable({ columns, data }: DataTablePro /> - diff --git a/client/src/components/Chat/Menus/Presets/PresetItems.tsx b/client/src/components/Chat/Menus/Presets/PresetItems.tsx index 4e7710e0a7..a0c65bc04c 100644 --- a/client/src/components/Chat/Menus/Presets/PresetItems.tsx +++ b/client/src/components/Chat/Menus/Presets/PresetItems.tsx @@ -59,9 +59,10 @@ const PresetItems: FC<{ - + diff --git a/client/src/components/Chat/Messages/Content/Parts/EditTextPart.tsx b/client/src/components/Chat/Messages/Content/Parts/EditTextPart.tsx index 242b13765e..5422d9733d 100644 --- a/client/src/components/Chat/Messages/Content/Parts/EditTextPart.tsx +++ b/client/src/components/Chat/Messages/Content/Parts/EditTextPart.tsx @@ -170,6 +170,7 @@ const EditTextPart = ({ 'max-h-[65vh] pr-3 md:max-h-[75vh] md:pr-4', removeFocusRings, )} + aria-label={localize('com_ui_editable_message')} dir={isRTL ? 'rtl' : 'ltr'} /> diff --git a/client/src/components/Conversations/Conversations.tsx b/client/src/components/Conversations/Conversations.tsx index b16c6458c7..b6a7032e9f 100644 --- a/client/src/components/Conversations/Conversations.tsx +++ b/client/src/components/Conversations/Conversations.tsx @@ -201,7 +201,6 @@ const Conversations: FC = ({ overscanRowCount={10} className="outline-none" style={{ outline: 'none' }} - role="list" aria-label="Conversations" onRowsRendered={handleRowsRendered} tabIndex={-1} diff --git a/client/src/components/Conversations/ConvoOptions/ShareButton.tsx b/client/src/components/Conversations/ConvoOptions/ShareButton.tsx index 46310268f0..cbbb612251 100644 --- a/client/src/components/Conversations/ConvoOptions/ShareButton.tsx +++ b/client/src/components/Conversations/ConvoOptions/ShareButton.tsx @@ -77,7 +77,13 @@ export default function ShareButton({
{showQR && (
- +
)} @@ -87,6 +93,7 @@ export default function ShareButton({ diff --git a/client/src/components/Endpoints/Settings/Advanced.tsx b/client/src/components/Endpoints/Settings/Advanced.tsx index d0beaa9020..504e6cd94d 100644 --- a/client/src/components/Endpoints/Settings/Advanced.tsx +++ b/client/src/components/Endpoints/Settings/Advanced.tsx @@ -151,6 +151,7 @@ export default function Settings({ min={0} step={0.01} className="flex h-4 w-full" + aria-labelledby="temp-int" /> @@ -160,7 +161,9 @@ export default function Settings({
@@ -199,7 +203,9 @@ export default function Settings({
@@ -238,7 +245,9 @@ export default function Settings({
@@ -306,6 +316,7 @@ export default function Settings({ onCheckedChange={(checked: boolean) => setResendFiles(checked)} disabled={readonly} className="flex" + aria-label={localize('com_endpoint_plug_resend_files')} /> @@ -323,6 +334,7 @@ export default function Settings({ max={2} min={0} step={1} + aria-label={localize('com_endpoint_plug_image_detail')} /> diff --git a/client/src/components/Endpoints/Settings/AgentSettings.tsx b/client/src/components/Endpoints/Settings/AgentSettings.tsx index f41a8bc19e..f4425a4db4 100644 --- a/client/src/components/Endpoints/Settings/AgentSettings.tsx +++ b/client/src/components/Endpoints/Settings/AgentSettings.tsx @@ -53,7 +53,9 @@ export default function Settings({ conversation, setOption, models, readonly }:
@@ -101,6 +104,7 @@ export default function Settings({ conversation, setOption, models, readonly }: onCheckedChange={onCheckedChangeAgent} disabled={readonly} className="ml-4 mt-2" + aria-label={localize('com_endpoint_plug_use_functions')} /> @@ -119,6 +123,7 @@ export default function Settings({ conversation, setOption, models, readonly }: onCheckedChange={onCheckedChangeSkip} disabled={readonly} className="ml-4 mt-2" + aria-label={localize('com_endpoint_plug_skip_completion')} /> diff --git a/client/src/components/Endpoints/Settings/Google.tsx b/client/src/components/Endpoints/Settings/Google.tsx index 6e513c1791..18bf95a1d0 100644 --- a/client/src/components/Endpoints/Settings/Google.tsx +++ b/client/src/components/Endpoints/Settings/Google.tsx @@ -171,6 +171,7 @@ export default function Settings({ conversation, setOption, models, readonly }: min={google.temperature.min} step={google.temperature.step} className="flex h-4 w-full" + aria-labelledby="temp-int" /> @@ -211,6 +212,7 @@ export default function Settings({ conversation, setOption, models, readonly }: min={google.topP.min} step={google.topP.step} className="flex h-4 w-full" + aria-labelledby="top-p-int" /> @@ -252,6 +254,7 @@ export default function Settings({ conversation, setOption, models, readonly }: min={google.topK.min} step={google.topK.step} className="flex h-4 w-full" + aria-labelledby="top-k-int" /> @@ -296,6 +299,7 @@ export default function Settings({ conversation, setOption, models, readonly }: min={google.maxOutputTokens.min} step={google.maxOutputTokens.step} className="flex h-4 w-full" + aria-labelledby="max-tokens-int" /> @@ -296,6 +297,7 @@ export default function Settings({ min={0} step={0.01} className="flex h-4 w-full" + aria-labelledby="top-p-int" /> @@ -337,6 +339,7 @@ export default function Settings({ min={-2} step={0.01} className="flex h-4 w-full" + aria-labelledby="freq-penalty-int" /> @@ -378,6 +381,7 @@ export default function Settings({ min={-2} step={0.01} className="flex h-4 w-full" + aria-labelledby="pres-penalty-int" /> diff --git a/client/src/components/Nav/ExportConversation/ExportModal.tsx b/client/src/components/Nav/ExportConversation/ExportModal.tsx index 642b5bbc81..2083ddec1a 100644 --- a/client/src/components/Nav/ExportConversation/ExportModal.tsx +++ b/client/src/components/Nav/ExportConversation/ExportModal.tsx @@ -124,13 +124,15 @@ export default function ExportModal({ disabled={!exportOptionsSupport} checked={includeOptions} onCheckedChange={setIncludeOptions} + aria-labelledby="includeOptions-label" />
@@ -146,13 +148,15 @@ export default function ExportModal({ disabled={!exportBranchesSupport} checked={exportBranches} onCheckedChange={setExportBranches} + aria-labelledby="exportBranches-label" />
@@ -163,8 +167,14 @@ export default function ExportModal({ {localize('com_nav_export_recursive_or_sequential')}
- +
); diff --git a/client/src/components/Nav/SettingsTabs/Chat/ShowThinking.tsx b/client/src/components/Nav/SettingsTabs/Chat/ShowThinking.tsx index 02a5ee256e..949453cb5c 100644 --- a/client/src/components/Nav/SettingsTabs/Chat/ShowThinking.tsx +++ b/client/src/components/Nav/SettingsTabs/Chat/ShowThinking.tsx @@ -30,6 +30,7 @@ export default function SaveDraft({ onCheckedChange={handleCheckedChange} className="ml-4" data-testid="showThinking" + aria-label={localize('com_nav_show_thinking')} />
); diff --git a/client/src/components/Nav/SettingsTabs/Data/SharedLinks.tsx b/client/src/components/Nav/SettingsTabs/Data/SharedLinks.tsx index ae25223a9b..bcc6a4af9c 100644 --- a/client/src/components/Nav/SettingsTabs/Data/SharedLinks.tsx +++ b/client/src/components/Nav/SettingsTabs/Data/SharedLinks.tsx @@ -13,7 +13,6 @@ import { useMediaQuery, OGDialogHeader, OGDialogTitle, - TooltipAnchor, DataTable, Spinner, Button, @@ -246,37 +245,27 @@ export default function SharedLinks() { }, cell: ({ row }) => (
- { - window.open(`/c/${row.original.conversationId}`, '_blank'); - }} - title={localize('com_ui_view_source')} - > - - - } - /> - { - setDeleteRow(row.original); - setIsDeleteOpen(true); - }} - title={localize('com_ui_delete')} - > - - - } - /> + +
), }, diff --git a/client/src/components/Prompts/AdminSettings.tsx b/client/src/components/Prompts/AdminSettings.tsx index 6f1580800e..7b25db721c 100644 --- a/client/src/components/Prompts/AdminSettings.tsx +++ b/client/src/components/Prompts/AdminSettings.tsx @@ -53,6 +53,7 @@ const LabelController: React.FC = ({ } }} value={field.value.toString()} + aria-label={label} /> )} /> @@ -216,7 +217,12 @@ const AdminSettings = () => { ))}
-
diff --git a/client/src/components/Prompts/Groups/AlwaysMakeProd.tsx b/client/src/components/Prompts/Groups/AlwaysMakeProd.tsx index 17c82c648d..64d6bd60ec 100644 --- a/client/src/components/Prompts/Groups/AlwaysMakeProd.tsx +++ b/client/src/components/Prompts/Groups/AlwaysMakeProd.tsx @@ -28,7 +28,7 @@ export default function AlwaysMakeProd({ checked={alwaysMakeProd} onCheckedChange={handleCheckedChange} data-testid="alwaysMakeProd" - aria-label="Always make prompt production" + aria-label={localize('com_nav_always_make_prod')} />
{localize('com_nav_always_make_prod')}
diff --git a/client/src/components/Prompts/Groups/AutoSendPrompt.tsx b/client/src/components/Prompts/Groups/AutoSendPrompt.tsx index 430506a748..182580a49c 100644 --- a/client/src/components/Prompts/Groups/AutoSendPrompt.tsx +++ b/client/src/components/Prompts/Groups/AutoSendPrompt.tsx @@ -30,7 +30,7 @@ export default function AutoSendPrompt({ >
{localize('com_nav_auto_send_prompts')}
{ + e.stopPropagation(); + }} className="w-full cursor-pointer rounded-lg text-text-primary hover:bg-surface-hover focus:bg-surface-hover disabled:cursor-not-allowed" >