fix: make settings sidebar accordion items keyboard accessible (#20663)
* fix: make settings sidebar accordion items keyboard accessible Co-Authored-By: sean@cal.com <sean@cal.com> * fix: ensure keyboard events properly toggle accordion content Co-Authored-By: sean@cal.com <sean@cal.com> * fix: add toggle functionality to accordion buttons Co-Authored-By: sean@cal.com <sean@cal.com> * fix: clean up accordion code and improve keyboard accessibility Co-Authored-By: sean@cal.com <sean@cal.com> * fix: add keyboard event handlers for accordion toggle Co-Authored-By: sean@cal.com <sean@cal.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: sean@cal.com <sean@cal.com>
This commit is contained in:
co-authored by
sean@cal.com <sean@cal.com>
sean@cal.com <sean@cal.com>
sean@cal.com <sean@cal.com>
sean@cal.com <sean@cal.com>
sean@cal.com <sean@cal.com>
Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
sean@cal.com <sean@cal.com>
parent
ad4aeee45b
commit
65abf4edc6
+73
-41
@@ -314,27 +314,41 @@ const TeamListCollapsible = () => {
|
||||
className="cursor-pointer"
|
||||
key={team.id}
|
||||
open={teamMenuState[index].teamMenuOpen}
|
||||
onOpenChange={() =>
|
||||
setTeamMenuState([
|
||||
...teamMenuState,
|
||||
(teamMenuState[index] = {
|
||||
...teamMenuState[index],
|
||||
teamMenuOpen: !teamMenuState[index].teamMenuOpen,
|
||||
}),
|
||||
])
|
||||
}>
|
||||
onOpenChange={(open) => {
|
||||
const newTeamMenuState = [...teamMenuState];
|
||||
newTeamMenuState[index] = {
|
||||
...newTeamMenuState[index],
|
||||
teamMenuOpen: open,
|
||||
};
|
||||
setTeamMenuState(newTeamMenuState);
|
||||
}}>
|
||||
<CollapsibleTrigger asChild>
|
||||
<div
|
||||
<button
|
||||
className="hover:bg-subtle [&[aria-current='page']]:bg-emphasis [&[aria-current='page']]:text-emphasis text-default flex h-9 w-full flex-row items-center rounded-md px-2 py-[10px] text-left text-sm font-medium leading-none transition"
|
||||
onClick={() =>
|
||||
setTeamMenuState([
|
||||
...teamMenuState,
|
||||
(teamMenuState[index] = {
|
||||
...teamMenuState[index],
|
||||
aria-controls={`team-content-${team.id}`}
|
||||
aria-expanded={teamMenuState[index].teamMenuOpen}
|
||||
onClick={() => {
|
||||
const newTeamMenuState = [...teamMenuState];
|
||||
newTeamMenuState[index] = {
|
||||
...newTeamMenuState[index],
|
||||
teamMenuOpen: !teamMenuState[index].teamMenuOpen,
|
||||
};
|
||||
setTeamMenuState(newTeamMenuState);
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
const newTeamMenuState = [...teamMenuState];
|
||||
newTeamMenuState[index] = {
|
||||
...newTeamMenuState[index],
|
||||
teamMenuOpen: !teamMenuState[index].teamMenuOpen,
|
||||
}),
|
||||
])
|
||||
}>
|
||||
};
|
||||
setTeamMenuState(newTeamMenuState);
|
||||
}
|
||||
}}
|
||||
aria-label={`${team.name} ${
|
||||
teamMenuState[index].teamMenuOpen ? t("collapse_menu") : t("expand_menu")
|
||||
}`}>
|
||||
<div className="me-3">
|
||||
{teamMenuState[index].teamMenuOpen ? (
|
||||
<Icon name="chevron-down" className="h-4 w-4" />
|
||||
@@ -355,9 +369,9 @@ const TeamListCollapsible = () => {
|
||||
Inv.
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent className="space-y-0.5">
|
||||
<CollapsibleContent className="space-y-0.5" id={`team-content-${team.id}`}>
|
||||
{team.accepted && (
|
||||
<VerticalTabItem
|
||||
name={t("profile")}
|
||||
@@ -484,7 +498,7 @@ const SettingsSidebarContainer = ({
|
||||
? "translate-x-0 opacity-100"
|
||||
: "-translate-x-full opacity-0 lg:translate-x-0 lg:opacity-100"
|
||||
)}
|
||||
aria-label="Tabs">
|
||||
aria-label={t("settings_navigation")}>
|
||||
<>
|
||||
<BackButtonInSidebar name={t("back")} />
|
||||
{tabsWithPermissions.map((tab) => {
|
||||
@@ -600,27 +614,43 @@ const SettingsSidebarContainer = ({
|
||||
className="cursor-pointer"
|
||||
key={otherTeam.id}
|
||||
open={otherTeamMenuState[index].teamMenuOpen}
|
||||
onOpenChange={() =>
|
||||
setOtherTeamMenuState([
|
||||
...otherTeamMenuState,
|
||||
(otherTeamMenuState[index] = {
|
||||
...otherTeamMenuState[index],
|
||||
teamMenuOpen: !otherTeamMenuState[index].teamMenuOpen,
|
||||
}),
|
||||
])
|
||||
}>
|
||||
onOpenChange={(open) => {
|
||||
const newOtherTeamMenuState = [...otherTeamMenuState];
|
||||
newOtherTeamMenuState[index] = {
|
||||
...newOtherTeamMenuState[index],
|
||||
teamMenuOpen: open,
|
||||
};
|
||||
setOtherTeamMenuState(newOtherTeamMenuState);
|
||||
}}>
|
||||
<CollapsibleTrigger asChild>
|
||||
<div
|
||||
<button
|
||||
className="hover:bg-subtle [&[aria-current='page']]:bg-emphasis [&[aria-current='page']]:text-emphasis text-default flex h-9 w-full flex-row items-center rounded-md px-2 py-[10px] text-left text-sm font-medium leading-none transition"
|
||||
onClick={() =>
|
||||
setOtherTeamMenuState([
|
||||
...otherTeamMenuState,
|
||||
(otherTeamMenuState[index] = {
|
||||
...otherTeamMenuState[index],
|
||||
aria-controls={`other-team-content-${otherTeam.id}`}
|
||||
aria-expanded={otherTeamMenuState[index].teamMenuOpen}
|
||||
onClick={() => {
|
||||
const newOtherTeamMenuState = [...otherTeamMenuState];
|
||||
newOtherTeamMenuState[index] = {
|
||||
...newOtherTeamMenuState[index],
|
||||
teamMenuOpen: !otherTeamMenuState[index].teamMenuOpen,
|
||||
};
|
||||
setOtherTeamMenuState(newOtherTeamMenuState);
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
const newOtherTeamMenuState = [...otherTeamMenuState];
|
||||
newOtherTeamMenuState[index] = {
|
||||
...newOtherTeamMenuState[index],
|
||||
teamMenuOpen: !otherTeamMenuState[index].teamMenuOpen,
|
||||
}),
|
||||
])
|
||||
}>
|
||||
};
|
||||
setOtherTeamMenuState(newOtherTeamMenuState);
|
||||
}
|
||||
}}
|
||||
aria-label={`${otherTeam.name} ${
|
||||
otherTeamMenuState[index].teamMenuOpen
|
||||
? t("collapse_menu")
|
||||
: t("expand_menu")
|
||||
}`}>
|
||||
<div className="me-3">
|
||||
{otherTeamMenuState[index].teamMenuOpen ? (
|
||||
<Icon name="chevron-down" className="h-4 w-4" />
|
||||
@@ -636,9 +666,11 @@ const SettingsSidebarContainer = ({
|
||||
/>
|
||||
)}
|
||||
<p className="w-1/2 truncate leading-normal">{otherTeam.name}</p>
|
||||
</div>
|
||||
</button>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent className="space-y-0.5">
|
||||
<CollapsibleContent
|
||||
className="space-y-0.5"
|
||||
id={`other-team-content-${otherTeam.id}`}>
|
||||
<VerticalTabItem
|
||||
name={t("profile")}
|
||||
href={`/settings/organizations/teams/other/${otherTeam.id}/profile`}
|
||||
|
||||
Reference in New Issue
Block a user