Accessibility features (#14518)

* Add screen reader aria labels to buttons and menu items

* Fix sub_label score in search detail dialog
This commit is contained in:
Josh Hawkins
2024-10-22 17:07:42 -05:00
committed by GitHub
parent c7d9f83638
commit ad308252a1
61 changed files with 358 additions and 115 deletions

View File

@@ -167,7 +167,11 @@ export default function CameraInfoDialog({
</div>
<DialogFooter>
<Button variant="select" onClick={() => onCopyFfprobe()}>
<Button
variant="select"
aria-label="Copy"
onClick={() => onCopyFfprobe()}
>
Copy
</Button>
</DialogFooter>

View File

@@ -98,7 +98,11 @@ export default function CreateUserDialog({
)}
/>
<DialogFooter className="mt-4">
<Button variant="select" disabled={isLoading}>
<Button
variant="select"
aria-label="Create user"
disabled={isLoading}
>
{isLoading && <ActivityIndicator className="mr-2 h-4 w-4" />}
Create User
</Button>

View File

@@ -27,6 +27,7 @@ export default function DeleteUserDialog({
<DialogFooter>
<Button
className="flex items-center gap-1"
aria-label="Confirm delete"
variant="destructive"
size="sm"
onClick={onDelete}

View File

@@ -142,6 +142,7 @@ export default function ExportDialog({
<Trigger asChild>
<Button
className="flex items-center gap-2"
aria-label="Export"
size="sm"
onClick={() => {
const now = new Date(latestTime * 1000);
@@ -307,6 +308,7 @@ export function ExportContent({
</div>
<Button
className={isDesktop ? "" : "w-full"}
aria-label="Select or export"
variant="select"
size="sm"
onClick={() => {
@@ -420,6 +422,7 @@ function CustomTimeSelector({
<PopoverTrigger asChild>
<Button
className={`text-primary ${isDesktop ? "" : "text-xs"}`}
aria-label="Start time"
variant={startOpen ? "select" : "default"}
size="sm"
onClick={() => {
@@ -485,6 +488,7 @@ function CustomTimeSelector({
<PopoverTrigger asChild>
<Button
className={`text-primary ${isDesktop ? "" : "text-xs"}`}
aria-label="End time"
variant={endOpen ? "select" : "default"}
size="sm"
onClick={() => {

View File

@@ -59,8 +59,17 @@ export default function GPUInfoDialog({
<ActivityIndicator />
)}
<DialogFooter>
<Button onClick={() => setShowGpuInfo(false)}>Close</Button>
<Button variant="select" onClick={() => onCopyInfo()}>
<Button
aria-label="Close GPU info"
onClick={() => setShowGpuInfo(false)}
>
Close
</Button>
<Button
aria-label="Copy GPU info"
variant="select"
onClick={() => onCopyInfo()}
>
Copy
</Button>
</DialogFooter>
@@ -88,8 +97,17 @@ export default function GPUInfoDialog({
<ActivityIndicator />
)}
<DialogFooter>
<Button onClick={() => setShowGpuInfo(false)}>Close</Button>
<Button variant="select" onClick={() => onCopyInfo()}>
<Button
aria-label="Close GPU info"
onClick={() => setShowGpuInfo(false)}
>
Close
</Button>
<Button
aria-label="Copy GPU info"
variant="select"
onClick={() => onCopyInfo()}
>
Copy
</Button>
</DialogFooter>

View File

@@ -23,7 +23,11 @@ export default function MobileCameraDrawer({
return (
<Drawer open={cameraDrawer} onOpenChange={setCameraDrawer}>
<DrawerTrigger asChild>
<Button className="rounded-lg capitalize" size="sm">
<Button
className="rounded-lg capitalize"
aria-label="Cameras"
size="sm"
>
<FaVideo className="text-secondary-foreground" />
</Button>
</DrawerTrigger>

View File

@@ -132,6 +132,7 @@ export default function MobileReviewSettingsDrawer({
{features.includes("export") && (
<Button
className="flex w-full items-center justify-center gap-2"
aria-label="Export"
onClick={() => {
setDrawerMode("export");
setMode("select");
@@ -144,6 +145,7 @@ export default function MobileReviewSettingsDrawer({
{features.includes("calendar") && (
<Button
className="flex w-full items-center justify-center gap-2"
aria-label="Calendar"
variant={filter?.after ? "select" : "default"}
onClick={() => setDrawerMode("calendar")}
>
@@ -156,6 +158,7 @@ export default function MobileReviewSettingsDrawer({
{features.includes("filter") && (
<Button
className="flex w-full items-center justify-center gap-2"
aria-label="Filter"
variant={filter?.labels || filter?.zones ? "select" : "default"}
onClick={() => setDrawerMode("filter")}
>
@@ -226,6 +229,7 @@ export default function MobileReviewSettingsDrawer({
<SelectSeparator />
<div className="flex items-center justify-center p-2">
<Button
aria-label="Reset"
onClick={() => {
onUpdateFilter({
...filter,
@@ -306,6 +310,7 @@ export default function MobileReviewSettingsDrawer({
<DrawerTrigger asChild>
<Button
className="rounded-lg capitalize"
aria-label="Filters"
variant={
filter?.labels || filter?.after || filter?.zones
? "select"

View File

@@ -22,7 +22,11 @@ export default function MobileTimelineDrawer({
return (
<Drawer open={drawer} onOpenChange={setDrawer}>
<DrawerTrigger asChild>
<Button className="rounded-lg capitalize" size="sm">
<Button
className="rounded-lg capitalize"
aria-label="Select timeline or events list"
size="sm"
>
<FaFlag className="text-secondary-foreground" />
</Button>
</DrawerTrigger>

View File

@@ -28,6 +28,7 @@ export default function SaveExportOverlay({
>
<Button
className="flex items-center gap-1 text-primary"
aria-label="Cancel"
size="sm"
onClick={onCancel}
>
@@ -36,6 +37,7 @@ export default function SaveExportOverlay({
</Button>
<Button
className="flex items-center gap-1"
aria-label="Preview export"
size="sm"
onClick={onPreview}
>
@@ -44,6 +46,7 @@ export default function SaveExportOverlay({
</Button>
<Button
className="flex items-center gap-1"
aria-label="Save export"
variant="select"
size="sm"
onClick={onSave}

View File

@@ -36,6 +36,7 @@ export default function SetPasswordDialog({
<DialogFooter>
<Button
className="flex items-center gap-1"
aria-label="Save Password"
variant="select"
size="sm"
onClick={() => {

View File

@@ -207,12 +207,14 @@ export function AnnotationSettingsPane({
<div className="flex flex-row gap-2 pt-5">
<Button
className="flex flex-1"
aria-label="Apply"
onClick={form.handleSubmit(onApply)}
>
Apply
</Button>
<Button
variant="select"
aria-label="Save"
disabled={isLoading}
className="flex flex-1"
type="submit"

View File

@@ -242,6 +242,7 @@ export default function ObjectLifecycle({
<div className={cn("flex items-center gap-2")}>
<Button
className="mb-2 mt-3 flex items-center gap-2.5 rounded-lg md:mt-0"
aria-label="Go back"
size="sm"
onClick={() => setPane("overview")}
>
@@ -346,6 +347,7 @@ export default function ObjectLifecycle({
<Button
variant={showControls ? "select" : "default"}
className="size-7 p-1.5"
aria-label="Adjust annotation settings"
>
<LuSettings
className="size-5"

View File

@@ -153,6 +153,7 @@ export default function ReviewDetailDialog({
<Tooltip>
<TooltipTrigger>
<Button
aria-label="Share this review item"
size="sm"
onClick={() =>
shareOrCopy(`${baseUrl}review?id=${review.id}`)

View File

@@ -296,7 +296,7 @@ function ObjectDetailsTab({
}
if (search.sub_label) {
return Math.round((search.data?.top_score ?? 0) * 100);
return Math.round((search.data?.sub_label_score ?? 0) * 100);
} else {
return undefined;
}
@@ -440,6 +440,7 @@ function ObjectDetailsTab({
/>
{config?.semantic_search.enabled && (
<Button
aria-label="Find similar tracked objects"
onClick={() => {
setSearch(undefined);
@@ -466,6 +467,7 @@ function ObjectDetailsTab({
<div className="flex items-center">
<Button
className="rounded-r-none border-r-0"
aria-label="Regenerate tracked object description"
onClick={() => regenerateDescription("thumbnails")}
>
Regenerate
@@ -473,19 +475,24 @@ function ObjectDetailsTab({
{search.has_snapshot && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button className="rounded-l-none border-l-0 px-2">
<Button
className="rounded-l-none border-l-0 px-2"
aria-label="Expand regeneration menu"
>
<FaChevronDown className="size-3" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem
className="cursor-pointer"
aria-label="Regenerate from snapshot"
onClick={() => regenerateDescription("snapshot")}
>
Regenerate from Snapshot
</DropdownMenuItem>
<DropdownMenuItem
className="cursor-pointer"
aria-label="Regenerate from thumbnails"
onClick={() => regenerateDescription("thumbnails")}
>
Regenerate from Thumbnails
@@ -495,7 +502,11 @@ function ObjectDetailsTab({
)}
</div>
)}
<Button variant="select" onClick={updateDescription}>
<Button
variant="select"
aria-label="Save"
onClick={updateDescription}
>
Save
</Button>
</div>
@@ -601,6 +612,7 @@ function ObjectSnapshotTab({
<>
<Button
className="bg-success"
aria-label="Confirm this label for Frigate Plus"
onClick={() => {
setState("uploading");
onSubmitToPlus(false);
@@ -610,6 +622,7 @@ function ObjectSnapshotTab({
</Button>
<Button
className="text-white"
aria-label="Do not confirm this label for Frigate Plus"
variant="destructive"
onClick={() => {
setState("uploading");

View File

@@ -131,9 +131,14 @@ export function FrigatePlusDialog({
<DialogFooter className="flex flex-row justify-end gap-2">
{state == "reviewing" && (
<>
{dialog && <Button onClick={onClose}>Cancel</Button>}
{dialog && (
<Button aria-label="Cancel" onClick={onClose}>
Cancel
</Button>
)}
<Button
className="bg-success"
aria-label="Confirm this label for Frigate Plus"
onClick={() => {
setState("uploading");
onSubmitToPlus(false);
@@ -143,6 +148,7 @@ export function FrigatePlusDialog({
</Button>
<Button
className="text-white"
aria-label="Do not confirm this label for Frigate Plus"
variant="destructive"
onClick={() => {
setState("uploading");

View File

@@ -76,6 +76,7 @@ export default function SearchFilterDialog({
const trigger = (
<Button
className="flex items-center gap-2"
aria-label="More Filters"
size="sm"
variant={moreFiltersSelected ? "select" : "default"}
>
@@ -141,6 +142,7 @@ export default function SearchFilterDialog({
<div className="flex items-center justify-evenly p-2">
<Button
variant="select"
aria-label="Apply"
onClick={() => {
if (currentFilter != filter) {
onUpdateFilter(currentFilter);
@@ -152,6 +154,7 @@ export default function SearchFilterDialog({
Apply
</Button>
<Button
aria-label="Reset filters to default values"
onClick={() => {
setCurrentFilter((prevFilter) => ({
...prevFilter,
@@ -256,6 +259,7 @@ function TimeRangeFilterContent({
<PopoverTrigger asChild>
<Button
className={`text-primary ${isDesktop ? "" : "text-xs"} `}
aria-label="Select Start Time"
variant={startOpen ? "select" : "default"}
size="sm"
onClick={() => {
@@ -293,6 +297,7 @@ function TimeRangeFilterContent({
<PopoverTrigger asChild>
<Button
className={`text-primary ${isDesktop ? "" : "text-xs"}`}
aria-label="Select End Time"
variant={endOpen ? "select" : "default"}
size="sm"
onClick={() => {