Files
ChloeGarciaMillerandandGildas Garcia 8d4a16beea fix: ESLint errors relating to accessibility in database section (#49638)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Improving accessibility by adding `aria-label` and associating the
switches with their labels in database section.
Adding `Tooltip` for icon only buttons.

## What is the current behavior?

`Switch` components are not connected with their labels, `aria-label`
and some `Tooltip` are missing.

## What is the new behavior?

Icon-only buttons have now buttons and `aria-label` have been added.
`Switch` components are connected to their labels.

## Additional context

No visual changes have been made.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Accessibility Improvements**
- Added descriptive labels and tooltips to database management actions,
including remove, delete, and “More options” controls.
- Improved screen reader support for function editor maximize/minimize
controls, privilege switches, publication switches, and column actions.
- Connected privilege labels with their corresponding controls for
clearer navigation.
  - Clarified permission-related messaging when deleting columns.
- Reduced duplicate announcements from tooltips and accessible
descriptions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
2026-09-01 17:15:07 +02:00

121 lines
3.7 KiB
TypeScript

import { Label, Switch } from 'ui'
import {
ALL_PRIVILEGE_TYPES,
COLUMN_PRIVILEGE_TYPES,
TABLE_PRIVILEGE_TYPES,
} from './Privileges.constants'
import { usePrivilegesState } from './Privileges.utils'
import Table from '@/components/to-be-cleaned/Table'
import type { ColumnPrivilege } from '@/data/privileges/column-privileges-query'
export interface PrivilegesTableProps extends Pick<
ReturnType<typeof usePrivilegesState>,
'tableCheckedStates' | 'columnCheckedStates' | 'toggleTablePrivilege' | 'toggleColumnPrivilege'
> {
columnPrivileges: ColumnPrivilege[]
disabled: boolean
isApplyingChanges?: boolean
}
const PrivilegesTable = ({
columnPrivileges,
tableCheckedStates,
columnCheckedStates,
toggleTablePrivilege,
toggleColumnPrivilege,
disabled,
isApplyingChanges = false,
}: PrivilegesTableProps) => {
const handleClickColumnName = (columnId: string) => {
const hasAllPrivileges = COLUMN_PRIVILEGE_TYPES.every(
(privilege) => columnCheckedStates[columnId][privilege]
)
const privilegesToToggle = COLUMN_PRIVILEGE_TYPES.filter((privilege) =>
hasAllPrivileges
? columnCheckedStates[columnId][privilege]
: !columnCheckedStates[columnId][privilege]
)
privilegesToToggle.forEach((privilege) => {
toggleColumnPrivilege(columnId, privilege)
})
}
return (
<Table
className="table-fixed mb-4"
head={[
<Table.th key="header-column">
<span>Column</span>
</Table.th>,
...ALL_PRIVILEGE_TYPES.map((privilege) => {
const checked = tableCheckedStates[privilege]
const switchThId = `privilege-th-${privilege}`
return (
<Table.th key={`header-${privilege}`}>
<div className="inline-flex items-center gap-2">
<Label htmlFor={switchThId}>
{privilege.charAt(0) + privilege.slice(1).toLowerCase()}
</Label>
<Switch
id={switchThId}
checked={checked}
onCheckedChange={() => {
toggleTablePrivilege(privilege)
}}
disabled={disabled || isApplyingChanges}
/>
</div>
</Table.th>
)
}),
]}
body={columnPrivileges.map((column) => (
<Table.tr key={column.column_id}>
<Table.td>
<button
tabIndex={0}
onClick={() => handleClickColumnName(column.column_id)}
className="block w-full truncate text-left text-foreground"
>
{column.column_name}
</button>
</Table.td>
{COLUMN_PRIVILEGE_TYPES.map((privilege) => {
const checked = columnCheckedStates[column.column_id][privilege]
return (
<Table.td key={privilege}>
{COLUMN_PRIVILEGE_TYPES.includes(privilege as any) && (
<div className="ml-5 inline-flex">
<Switch
aria-label={`${privilege} privilege for ${column.column_name}`}
checked={checked}
onCheckedChange={() => {
toggleColumnPrivilege(column.column_id, privilege)
}}
disabled={disabled || isApplyingChanges}
/>
</div>
)}
</Table.td>
)
})}
{TABLE_PRIVILEGE_TYPES.map((privilege) => {
return (
<Table.td key={privilege}>
<span className="ml-5 text-xs text-foreground-lighter">N/A</span>
</Table.td>
)
})}
</Table.tr>
))}
/>
)
}
export default PrivilegesTable