Skip to content

Commit

Permalink
feat(skip-link): add SkipLink component WD-15080
Browse files Browse the repository at this point in the history
  • Loading branch information
lorumic committed Sep 30, 2024
1 parent 3879dc0 commit 213084e
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/components/ApplicationLayout/ApplicationLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import AppStatus from "./AppStatus";
import Application from "./Application";
import Button from "components/Button";
import Icon from "components/Icon";
import SkipLink from "components/SkipLink";

export type BaseProps<
NI = SideNavigationLinkDefaultElement,
Expand Down Expand Up @@ -145,6 +146,7 @@ const ApplicationLayout = <

return (
<Application {...props}>
<SkipLink />
{(navItems || sideNavigation) && (
<>
<AppNavigationBar className={navigationBarClassName}>
Expand Down Expand Up @@ -222,7 +224,9 @@ const ApplicationLayout = <
</AppNavigation>
</>
)}
<AppMain className={mainClassName}>{children}</AppMain>
<AppMain id="main-content" className={mainClassName}>
{children}
</AppMain>
{aside}
{status && <AppStatus className={statusClassName}>{status}</AppStatus>}
</Application>
Expand Down
16 changes: 16 additions & 0 deletions src/components/SkipLink/SkipLink.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Meta, StoryObj } from "@storybook/react";

import SkipLink from "./SkipLink";

const meta: Meta<typeof SkipLink> = {
component: SkipLink,
tags: ["autodocs"],
};

export default meta;

type Story = StoryObj<typeof SkipLink>;

export const Default: Story = {
name: "Default",
};
43 changes: 43 additions & 0 deletions src/components/SkipLink/SkipLink.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import React from "react";

import SkipLink from "./SkipLink";

describe("<SkipLink />", () => {
it("renders and is found in the DOM", () => {
render(<SkipLink />);

expect(screen.getByText("Skip to main content")).toBeInTheDocument();
});

it("gets focused only after a TAB press", async () => {
render(<SkipLink />);

const skipLink = screen.getByText("Skip to main content");
expect(skipLink).not.toHaveFocus();

await userEvent.tab();
expect(skipLink).toHaveFocus();
});

it("redirects focus to the main content", async () => {
render(
<div>
<SkipLink />
<main id="#main-content">
<input />
</main>
</div>,
);

const input = screen.getByRole("textbox");
expect(input).not.toHaveFocus();

await userEvent.click(screen.getByText("Skip to main content"));
expect(window.location.hash).toBe("#main-content");

await userEvent.tab();
expect(input).toHaveFocus();
});
});
14 changes: 14 additions & 0 deletions src/components/SkipLink/SkipLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from "react";

/**
* This is a [React](https://reactjs.org/) component for the Vanilla [Skip link](https://vanillaframework.io/docs/patterns/links#skip-link) component.
*/
export const SkipLink = (): JSX.Element => {
return (
<a className="p-link--skip" href="#main-content">
Skip to main content
</a>
);
};

export default SkipLink;
1 change: 1 addition & 0 deletions src/components/SkipLink/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./SkipLink";
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export { default as SideNavigation } from "./components/SideNavigation";
export { default as SideNavigationItem } from "./components/SideNavigation/SideNavigationItem";
export { default as SideNavigationLink } from "./components/SideNavigation/SideNavigationLink";
export { default as SideNavigationText } from "./components/SideNavigation/SideNavigationText";
export { default as SkipLink } from "./components/SkipLink";
export { default as Slider } from "./components/Slider";
export { default as Switch } from "./components/Switch";
export { default as Spinner } from "./components/Spinner";
Expand Down

0 comments on commit 213084e

Please sign in to comment.