A searchable member table with a role filter, status badges, row actions and pagination.
| Member | Role | Status | Last active | Actions |
|---|---|---|---|---|
Ingrid Solbergingrid@meridianhq.com | Owner | Active | 2 minutes ago | |
Marcus Chenmarcus.chen@meridianhq.com | Admin | Active | 1 hour ago | |
Amara Dialloamara.diallo@meridianhq.com | Active | Yesterday | ||
Felix Weberfelix.weber@meridianhq.com | Invited | Invite sent Jul 10 | ||
Rosa Delgadorosa.delgado@meridianhq.com | Active | 3 days ago | ||
Jonah Kaplanjonah.kaplan@meridianhq.com | Suspended | Apr 2, 2026 |
Install with the CLI, or add the packages and paste the source below.
Add User management to your app with its source-owned dependencies.
npx cronus-ui add user-management
Install the Cronus UI packages, then paste the block below.
Copy the source for Directory table. Every class is a semantic token, so it re-themes with your app.
import {Avatar,AvatarFallback,Badge,Button,Card,CardAction,CardContent,CardDescription,CardFooter,CardHeader,CardTitle,DropdownMenu,DropdownMenuContent,DropdownMenuItem,DropdownMenuLabel,DropdownMenuSeparator,DropdownMenuTrigger,Input,Pagination,PaginationContent,PaginationItem,PaginationLink,PaginationNext,PaginationPrevious,Select,SelectContent,SelectItem,SelectTrigger,SelectValue,Separator,Table,TableBody,TableCell,TableHead,TableHeader,TableRow,} from "@cronus-ui/ui";import { MoreHorizontal, Search, UserPlus } from "lucide-react";interface TeamMember {id: string;name: string;email: string;initials: string;role: string;roleVariant: "primary" | "info" | "secondary";status: "Active" | "Invited" | "Suspended";statusVariant: "success" | "warning" | "destructive";lastActive: string;}const teamMembers: TeamMember[] = [{ id: "usr-01", name: "Ingrid Solberg", email: "ingrid@meridianhq.com", initials: "IS", role: "Owner", roleVariant: "primary", status: "Active", statusVariant: "success", lastActive: "2 minutes ago" },{ id: "usr-02", name: "Marcus Chen", email: "marcus.chen@meridianhq.com", initials: "MC", role: "Admin", roleVariant: "info", status: "Active", statusVariant: "success", lastActive: "1 hour ago" },{ id: "usr-03", name: "Amara Diallo", email: "amara.diallo@meridianhq.com", initials: "AD", role: "Editor", roleVariant: "secondary", status: "Active", statusVariant: "success", lastActive: "Yesterday" },{ id: "usr-04", name: "Felix Weber", email: "felix.weber@meridianhq.com", initials: "FW", role: "Editor", roleVariant: "secondary", status: "Invited", statusVariant: "warning", lastActive: "Invite sent Jul 10" },{ id: "usr-05", name: "Rosa Delgado", email: "rosa.delgado@meridianhq.com", initials: "RD", role: "Viewer", roleVariant: "secondary", status: "Active", statusVariant: "success", lastActive: "3 days ago" },{ id: "usr-06", name: "Jonah Kaplan", email: "jonah.kaplan@meridianhq.com", initials: "JK", role: "Viewer", roleVariant: "secondary", status: "Suspended", statusVariant: "destructive", lastActive: "Apr 2, 2026" },];export function UserManagementTableBlock() {return (<Card aria-label="User management" className="mx-auto w-full max-w-5xl gap-0 pb-0 shadow-md"><CardHeader><CardTitle className="font-display text-lg">Team members</CardTitle><CardDescription>Manage roles and access for the Meridian workspace.</CardDescription><CardAction><Button variant="primary" size="sm"><UserPlus className="size-4" aria-hidden="true" />Invite member</Button></CardAction></CardHeader><CardContent className="flex flex-col gap-3 pt-5 sm:flex-row sm:items-center"><div className="relative flex-1"><SearchclassName="pointer-events-none absolute start-3 top-1/2 size-4 -translate-y-1/2 text-fg-tertiary"aria-hidden="true"/><Inputtype="search"placeholder="Search by name or email…"aria-label="Search members"className="ps-9"/></div><Select defaultValue="all"><SelectTrigger className="w-full sm:w-40" aria-label="Filter by role"><SelectValue placeholder="All roles" /></SelectTrigger><SelectContent><SelectItem value="all">All roles</SelectItem><SelectItem value="owner">Owner</SelectItem><SelectItem value="admin">Admin</SelectItem><SelectItem value="editor">Editor</SelectItem><SelectItem value="viewer">Viewer</SelectItem></SelectContent></Select></CardContent><CardContent className="px-0 pt-4"><Table><TableHeader><TableRow><TableHead className="ps-4 sm:ps-6">Member</TableHead><TableHead>Role</TableHead><TableHead>Status</TableHead><TableHead>Last active</TableHead><TableHead className="pe-4 text-end sm:pe-6"><span className="sr-only">Actions</span></TableHead></TableRow></TableHeader><TableBody>{teamMembers.map((member) => (<TableRow key={member.id}><TableCell className="ps-4 sm:ps-6"><div className="flex items-center gap-3"><Avatar className="size-8"><AvatarFallback>{member.initials}</AvatarFallback></Avatar><div className="flex min-w-0 flex-col"><span className="truncate text-sm font-medium text-fg">{member.name}</span><span className="truncate text-xs text-fg-tertiary">{member.email}</span></div></div></TableCell><TableCell><Badge variant={member.roleVariant}>{member.role}</Badge></TableCell><TableCell><Badge variant={member.statusVariant}>{member.status}</Badge></TableCell><TableCell className="text-fg-secondary">{member.lastActive}</TableCell><TableCell className="pe-4 text-end sm:pe-6"><DropdownMenu><DropdownMenuTrigger asChild><Button variant="ghost" size="icon-sm"><MoreHorizontal className="size-4" aria-hidden="true" /><span className="sr-only">Actions for {member.name}</span></Button></DropdownMenuTrigger><DropdownMenuContent align="end"><DropdownMenuLabel>{member.name}</DropdownMenuLabel><DropdownMenuSeparator /><DropdownMenuItem>View profile</DropdownMenuItem><DropdownMenuItem>Change role</DropdownMenuItem><DropdownMenuItem>Reset password</DropdownMenuItem><DropdownMenuSeparator /><DropdownMenuItem className="text-error-strong">Suspend account</DropdownMenuItem></DropdownMenuContent></DropdownMenu></TableCell></TableRow>))}</TableBody></Table></CardContent><Separator /><CardFooter className="flex-wrap justify-between gap-3 py-4"><span className="text-sm text-fg-tertiary">Showing 6 of 24 members</span><Pagination className="mx-0 w-auto justify-end"><PaginationContent><PaginationItem><PaginationPrevious href="#previous" /></PaginationItem><PaginationItem><PaginationLink href="#page-1" isActive>1</PaginationLink></PaginationItem><PaginationItem><PaginationLink href="#page-2">2</PaginationLink></PaginationItem><PaginationItem><PaginationLink href="#page-3">3</PaginationLink></PaginationItem><PaginationItem><PaginationLink href="#page-4">4</PaginationLink></PaginationItem><PaginationItem><PaginationNext href="#next" /></PaginationItem></PaginationContent></Pagination></CardFooter></Card>);}
| Member | Role | Status | Last active | Actions |
|---|---|---|---|---|
Ingrid Solbergingrid@meridianhq.com | Owner | Active | 2 minutes ago | |
Marcus Chenmarcus.chen@meridianhq.com | Admin | Active | 1 hour ago | |
Amara Dialloamara.diallo@meridianhq.com | Active | Yesterday | ||
Felix Weberfelix.weber@meridianhq.com | Invited | Invite sent Jul 10 | ||
Rosa Delgadorosa.delgado@meridianhq.com | Active | 3 days ago | ||
Jonah Kaplanjonah.kaplan@meridianhq.com | Suspended | Apr 2, 2026 |