☰ fix: Side Panel Accessibility Improvements (#10830)

* fix: pad cards so focus outline doesn't clip in prompts list

* feat: pad snippet top for space between text and button

* fix: prompt menu focus outline clipping with overflow-visible

* fix: clipping in AgentBuilder for advanced and admin buttons

* fix: clipping in memory panel for admin settings

* fix: better contrast thresholds on focus outlines for admin settings and advanced buttons in agent builder

* fix: better contrast thresholds on focus outlines for admin settings  button in memory panel

* fix: clipping on focus outline for manage files button in files panel

* fix: focus outline clipping table cells for files panel table

* fix: clipping on new bookmark button in bookmarks panel

* fix: clipping on Admin Settings button in MCP Settings panel

* fix: better contrast threshold outline and aria-label for Admin Settings button in MCP Settings panel

* fix: misaligned globe because of new unnested menu button positioning

* fix: localize global group aria-label

* fix: screen reader not reading out proper prompt name for dropdown menu button
This commit is contained in:
Dustin Healy 2025-12-09 17:17:23 -08:00 committed by Danny Avila
parent 9e67eee294
commit 6fc6471010
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
15 changed files with 32 additions and 23 deletions

View file

@ -152,7 +152,7 @@ const AdminSettings = () => {
<Button
size={'sm'}
variant={'outline'}
className="btn btn-neutral border-token-border-light relative h-9 w-full gap-1 rounded-lg font-medium"
className="btn btn-neutral border-token-border-light relative h-9 w-full gap-1 rounded-lg font-medium focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-primary"
aria-label={localize('com_ui_admin_settings')}
>
<ShieldEllipsis className="cursor-pointer" aria-hidden="true" />
@ -218,7 +218,7 @@ const AdminSettings = () => {
type="button"
onClick={handleSubmit(onSubmit)}
disabled={isSubmitting || isLoading}
className="btn rounded bg-green-500 font-bold text-white transition-all hover:bg-green-600"
className="btn rounded bg-green-500 font-bold text-white transition-all hover:bg-green-600 focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring-primary"
>
{localize('com_ui_save')}
</button>

View file

@ -15,7 +15,7 @@ const AdvancedButton: React.FC<AdvancedButtonProps> = ({ setActivePanel }) => {
<Button
size={'sm'}
variant={'outline'}
className="btn btn-neutral border-token-border-light relative h-9 w-full gap-1 rounded-lg font-medium"
className="btn btn-neutral border-token-border-light relative h-9 w-full gap-1 rounded-lg font-medium focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-primary"
onClick={() => setActivePanel(Panel.advanced)}
aria-label={localize('com_ui_advanced')}
>

View file

@ -476,7 +476,7 @@ export default function AgentPanel() {
<FormProvider {...methods}>
<form
onSubmit={handleSubmit(onSubmit)}
className="scrollbar-gutter-stable h-auto w-full flex-shrink-0 overflow-x-hidden"
className="scrollbar-gutter-stable h-auto w-full flex-shrink-0 overflow-x-visible"
aria-label="Agent configuration form"
>
<div className="mx-1 mt-2 flex w-full flex-wrap gap-2">

View file

@ -6,7 +6,7 @@ const BookmarkPanel = () => {
const { data } = useConversationTagsQuery();
return (
<div className="h-auto max-w-full overflow-x-hidden">
<div className="h-auto max-w-full overflow-x-visible">
<BookmarkContext.Provider value={{ bookmarks: data || [] }}>
<BookmarkTable />
</BookmarkContext.Provider>

View file

@ -7,7 +7,7 @@ export default function FilesPanel() {
const { data: files = [] } = useGetFiles<TFile[]>();
return (
<div className="h-auto max-w-full overflow-x-hidden">
<div className="h-auto max-w-full overflow-x-visible">
<DataTable columns={columns} data={files} />
</div>
);

View file

@ -241,6 +241,11 @@ export default function DataTable<TData, TValue>({ columns, data }: DataTablePro
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
className={
isFilenameCell
? 'focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-text-primary'
: ''
}
data-skip-refocus="true"
key={cell.id}
role={isFilenameCell ? 'button' : undefined}

View file

@ -151,7 +151,8 @@ const MCPAdminSettings = () => {
<Button
size={'sm'}
variant={'outline'}
className="btn btn-neutral border-token-border-light relative h-9 w-full gap-1 rounded-lg font-medium"
className="btn btn-neutral border-token-border-light relative h-9 w-full gap-1 rounded-lg font-medium focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-primary"
aria-label={localize('com_ui_admin_settings')}
>
<ShieldEllipsis className="cursor-pointer" aria-hidden="true" />
{localize('com_ui_admin_settings')}
@ -216,7 +217,7 @@ const MCPAdminSettings = () => {
type="button"
onClick={handleSubmit(onSubmit)}
disabled={isSubmitting || isLoading}
className="btn rounded bg-green-500 font-bold text-white transition-all hover:bg-green-600"
className="btn rounded bg-green-500 font-bold text-white transition-all hover:bg-green-600 focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-primary"
>
{localize('com_ui_save')}
</button>

View file

@ -22,7 +22,7 @@ export default function MCPBuilderPanel() {
const configDialogProps = getConfigDialogProps();
return (
<div className="flex h-full w-full flex-col overflow-hidden">
<div className="flex h-full w-full flex-col overflow-visible">
<div role="region" aria-label="MCP Builder" className="mt-2 space-y-2">
{/* Admin Settings Button */}
<MCPAdminSettings />

View file

@ -141,7 +141,7 @@ const AdminSettings = () => {
<Button
size={'sm'}
variant={'outline'}
className="btn btn-neutral border-token-border-light relative h-9 w-full gap-1 rounded-lg font-medium"
className="btn btn-neutral border-token-border-light relative h-9 w-full gap-1 rounded-lg font-medium focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-primary"
aria-label={localize('com_ui_admin_settings')}
>
<ShieldEllipsis className="cursor-pointer" aria-hidden="true" />
@ -206,7 +206,7 @@ const AdminSettings = () => {
<button
type="submit"
disabled={isSubmitting || isLoading}
className="btn rounded bg-green-500 font-bold text-white transition-all hover:bg-green-600"
className="btn rounded bg-green-500 font-bold text-white transition-all hover:bg-green-600 focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-primary"
>
{localize('com_ui_save')}
</button>

View file

@ -239,7 +239,7 @@ export default function MemoryViewer() {
}
return (
<div className="flex h-full w-full flex-col overflow-hidden">
<div className="flex h-full w-full flex-col">
<div role="region" aria-label={localize('com_ui_memories')} className="mt-2 space-y-2">
<div className="relative">
<Input