Skip to content

Commit 4a3db5b

Browse files
committed
feat: improve PostForm tab order for better accessibility
- Make textarea first focusable element - Optimize keyboard navigation flow - Set logical tabIndex values - Add tests to verify tab order behavior
1 parent 8af29b5 commit 4a3db5b

2 files changed

Lines changed: 56 additions & 2 deletions

File tree

app/src/components/PostForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export default function PostForm(): ReactElement {
5555
}}
5656
placeholder="Share your thoughts..."
5757
aria-label="Post content"
58-
tabIndex={0}
58+
tabIndex={1}
5959
/>
6060
</div>
6161
<div style={{ display: "none" }}>
@@ -78,7 +78,7 @@ export default function PostForm(): ReactElement {
7878
<button
7979
type="submit"
8080
className="px-4 py-2 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:bg-indigo-800 md:px-5 md:text-lg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
81-
tabIndex={0}
81+
tabIndex={2}
8282
>
8383
Send
8484
</button>

app/src/components/__tests__/PostForm.test.tsx

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,58 @@ describe("PostForm", () => {
147147
expect(consoleErrorSpy).toHaveBeenCalledWith(new Error("API Error"));
148148
consoleErrorSpy.mockRestore();
149149
});
150+
151+
it("renders form elements with correct accessibility attributes", () => {
152+
renderPostForm();
153+
154+
// Check if textarea is present and has correct tabIndex
155+
const textarea = screen.getByRole('textbox', { name: /post content/i });
156+
expect(textarea).toBeInTheDocument();
157+
expect(textarea).toHaveAttribute('tabindex', '1');
158+
159+
// Check if submit button is present and has correct tabIndex
160+
const submitButton = screen.getByRole('button', { name: /send/i });
161+
expect(submitButton).toBeInTheDocument();
162+
expect(submitButton).toHaveAttribute('tabindex', '2');
163+
});
164+
165+
it("maintains correct tab order", async () => {
166+
renderPostForm();
167+
168+
// Get all focusable elements
169+
const textarea = screen.getByRole('textbox', { name: /post content/i });
170+
const submitButton = screen.getByRole('button', { name: /send/i });
171+
172+
// Focus the textarea
173+
textarea.focus();
174+
expect(document.activeElement).toBe(textarea);
175+
176+
// Press Tab to move to submit button
177+
await userEvent.tab();
178+
expect(document.activeElement).toBe(submitButton);
179+
});
180+
181+
it("applies focus styles when elements are focused", () => {
182+
renderPostForm();
183+
184+
const textarea = screen.getByRole('textbox', { name: /post content/i });
185+
const submitButton = screen.getByRole('button', { name: /send/i });
186+
187+
// Check if focus styles are applied
188+
expect(textarea).toHaveClass('focus:ring-2', 'focus:ring-blue-500');
189+
expect(submitButton).toHaveClass('focus:ring-2', 'focus:ring-offset-2', 'focus:ring-indigo-500');
190+
});
191+
192+
it("focuses textarea first when pressing Tab on the page", async () => {
193+
renderPostForm();
194+
195+
// Get the textarea
196+
const textarea = screen.getByRole('textbox', { name: /post content/i });
197+
198+
// Press Tab on the page
199+
await userEvent.tab();
200+
201+
// Verify textarea is focused first
202+
expect(document.activeElement).toBe(textarea);
203+
});
150204
});

0 commit comments

Comments
 (0)