Build an Accessible Admin Panel with React and Tailwind CSS v4
Build an accessible admin panel with sidebar navigation, data tables, forms, modals, and toast notifications — all with Ninna UI and Tailwind CSS v4.
Admin panels need accessibility too
Admin panels are often built quickly with accessibility as an afterthought. But admin users benefit from keyboard navigation, focus management, and screen reader support just as much as end users. Ninna UI gives you all of this by default through its Radix internals.
1. Sidebar navigation with Accordion
Use the Accordion component for collapsible nav sections. Keyboard navigation (arrow keys, Enter, Escape) works out of the box:
import { Accordion } from "@ninna-ui/navigation";
import { Link } from "@ninna-ui/primitives";
<Accordion collapsible>
<Accordion.Item value="users">
<Accordion.Trigger>Users</Accordion.Trigger>
<Accordion.Content>
<VStack gap="2">
<Link href="/admin/users">All Users</Link>
<Link href="/admin/users/new">Add User</Link>
</VStack>
</Accordion.Content>
</Accordion.Item>
</Accordion>2. Data table with actions
Combine Table with DropdownMenu for row-level actions. The DropdownMenu handles focus trapping and keyboard navigation:
import { Table } from "@ninna-ui/data-display";
import { DropdownMenu } from "@ninna-ui/overlays";
import { Button } from "@ninna-ui/primitives";
<Table.Body>
<Table.Row>
<Table.Cell>Alice</Table.Cell>
<Table.Cell>alice@example.com</Table.Cell>
<Table.Cell>
<DropdownMenu>
<DropdownMenu.Trigger asChild>
<Button variant="ghost" size="sm">Actions</Button>
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Item>Edit</DropdownMenu.Item>
<DropdownMenu.Item>Delete</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
</Table.Cell>
</Table.Row>
</Table.Body>3. Form modal for creating records
Use Modal with Form components for creating or editing records. The Modal handles focus trapping, Escape to close, and focus restoration:
import { Modal } from "@ninna-ui/overlays";
import { Field, Input, Select } from "@ninna-ui/forms";
import { Button } from "@ninna-ui/primitives";
import { VStack } from "@ninna-ui/layout";
<Modal>
<Modal.Trigger asChild>
<Button color="primary">Add User</Button>
</Modal.Trigger>
<Modal.Content>
<Modal.Header>Add New User</Modal.Header>
<Modal.Body>
<VStack gap="4" as="form">
<Field label="Name"><Input /></Field>
<Field label="Email"><Input type="email" /></Field>
<Field label="Role"><Select><Select.Item value="admin">Admin</Select.Item></Select></Field>
</VStack>
</Modal.Body>
<Modal.Footer>
<Button type="submit" color="primary">Save</Button>
</Modal.Footer>
</Modal.Content>
</Modal>4. Toast notifications
Use the Toaster from @ninna-ui/feedback for success/error notifications after form submissions:
import { toast } from "@ninna-ui/feedback";
toast({ title: "User created", description: "Alice has been added.", color: "success" });