Skip to main content
Use Case

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" });

Related Blocks

Component Docs

FAQ