Skip to content

Commit

Permalink
Merge pull request #563 from openSUSE/hide-sidebar-siblings
Browse files Browse the repository at this point in the history
[web] Set sidebar siblings as inert and aria-hidden when it's open
  • Loading branch information
dgdavid committed May 10, 2023
2 parents d504e04 + 3179f7d commit 32e51e2
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
6 changes: 6 additions & 0 deletions web/package/cockpit-agama.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
-------------------------------------------------------------------
Mon May 8 15:20:14 UTC 2023 - David Diaz <dgonzalez@suse.com>

- Set sidebar siblings as aria-hiden while it's open
(gh#openSUSE/agama#563)

-------------------------------------------------------------------
Fri Apr 28 15:16:04 UTC 2023 - José Iván López González <jlopez@suse.com>

Expand Down
31 changes: 29 additions & 2 deletions web/src/components/core/Sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ import { Icon, AppActions } from "~/components/layout";
import { If, NotificationMark } from "~/components/core";
import { useNotification } from "~/context/notification";

/**
* Returns siblings for given HTML node
*
* @param {HTMLElement} node
* @returns {HTMLElement[]}
*/
const siblingsFor = (node) => {
if (!node) return [];

return [...node.parentNode.children].filter(n => n !== node);
};

/**
* Agama sidebar navigation
* @component
Expand All @@ -34,11 +46,25 @@ import { useNotification } from "~/context/notification";
*/
export default function Sidebar ({ children }) {
const [isOpen, setIsOpen] = useState(false);
const asideRef = useRef(null);
const closeButtonRef = useRef(null);
const [notification] = useNotification();

const open = () => setIsOpen(true);
const close = () => setIsOpen(false);
const open = () => {
setIsOpen(true);
siblingsFor(asideRef.current).forEach(s => {
s.setAttribute('inert', '');
s.setAttribute('aria-hidden', true);
});
};

const close = () => {
setIsOpen(false);
siblingsFor(asideRef.current).forEach(s => {
s.removeAttribute('inert');
s.removeAttribute('aria-hidden');
});
};

/**
* Handler for automatically closing the sidebar when a click bubbles from a
Expand Down Expand Up @@ -106,6 +132,7 @@ export default function Sidebar ({ children }) {

<aside
id="global-options"
ref={asideRef}
className="wrapper sidebar"
aria-label="Global options"
data-state={isOpen ? "visible" : "hidden"}
Expand Down
21 changes: 21 additions & 0 deletions web/src/components/core/Sidebar.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,27 @@ it("renders a link for hiding the sidebar", async () => {
expect(sidebar).toHaveAttribute("data-state", "hidden");
});

it("sets siblings as inert and aria-hidden while it's open", async () => {
const { user } = installerRender(withNotificationProvider(
<>
<div>A sidebar sibling</div>
<Sidebar />
</>
));

const openLink = await screen.findByLabelText(/Show/i);
const closeLink = await screen.findByLabelText(/Hide/i);
const sidebarSibling = screen.getByText("A sidebar sibling");
expect(sidebarSibling).not.toHaveAttribute("aria-hidden");
expect(sidebarSibling).not.toHaveAttribute("inert");
await user.click(openLink);
expect(sidebarSibling).toHaveAttribute("aria-hidden");
expect(sidebarSibling).toHaveAttribute("inert");
await user.click(closeLink);
expect(sidebarSibling).not.toHaveAttribute("aria-hidden");
expect(sidebarSibling).not.toHaveAttribute("inert");
});

it("moves the focus to the close action after opening it", async () => {
const { user } = installerRender(withNotificationProvider(<Sidebar />));

Expand Down

0 comments on commit 32e51e2

Please sign in to comment.