mdxui

UI Patterns

Common UI patterns and component compositions in mdxui

UI Patterns

Learn common patterns for composing mdxui components to build complete user interfaces.

Form Patterns

Login Form

Combine Input, Button, and Card for authentication:

import { Card, CardHeader, CardTitle, CardContent, CardFooter } from '@mdxui/primitives'
import { Input, Label, Button } from '@mdxui/primitives'

<Card className="w-96">
  <CardHeader>
    <CardTitle>Sign In</CardTitle>
  </CardHeader>
  <CardContent className="space-y-4">
    <div>
      <Label htmlFor="email">Email</Label>
      <Input id="email" type="email" placeholder="you@example.com" />
    </div>
    <div>
      <Label htmlFor="password">Password</Label>
      <Input id="password" type="password" />
    </div>
  </CardContent>
  <CardFooter>
    <Button className="w-full">Sign In</Button>
  </CardFooter>
</Card>

Multi-Step Wizard

Use Multi-Step Form or Onboarding Wizard for complex flows:

import { Wizard } from '@mdxui/widgets'

<Wizard
  steps={[
    { id: 'account', title: 'Account', fields: [...] },
    { id: 'profile', title: 'Profile', fields: [...] },
    { id: 'confirm', title: 'Confirm', fields: [...] }
  ]}
  onComplete={(data) => console.log(data)}
/>

Form Validation

Combine Form Builder with Zod schemas:

import { FormBuilder } from '@mdxui/primitives'
import { z } from 'zod'

const schema = z.object({
  name: z.string().min(2),
  email: z.string().email(),
  age: z.number().min(18)
})

<FormBuilder schema={schema} onSubmit={handleSubmit} />

Layout Patterns

Dashboard Layout

Combine Dashboard Shell with Sidebar:

import { DashboardShell, Sidebar, SidebarNav } from '@mdxui/primitives'

<DashboardShell>
  <Sidebar>
    <SidebarNav items={navItems} />
  </Sidebar>
  <main className="flex-1 p-6">
    {/* Dashboard content */}
  </main>
</DashboardShell>

Resizable Panels

Create split-pane layouts:

import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from '@mdxui/primitives'

<ResizablePanelGroup direction="horizontal">
  <ResizablePanel defaultSize={30}>
    {/* Sidebar */}
  </ResizablePanel>
  <ResizableHandle />
  <ResizablePanel defaultSize={70}>
    {/* Main content */}
  </ResizablePanel>
</ResizablePanelGroup>

Card Grid

Responsive card layouts:

import { Card } from '@mdxui/primitives'

<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  {items.map(item => (
    <Card key={item.id}>
      {/* Card content */}
    </Card>
  ))}
</div>

Top Navigation

Combine Navigation Menu with Dropdown Menu:

import { NavigationMenu, NavigationMenuItem } from '@mdxui/primitives'

<NavigationMenu>
  <NavigationMenuItem>
    <NavigationMenuLink href="/products">Products</NavigationMenuLink>
  </NavigationMenuItem>
  <NavigationMenuItem>
    <NavigationMenuTrigger>Solutions</NavigationMenuTrigger>
    <NavigationMenuContent>
      {/* Dropdown content */}
    </NavigationMenuContent>
  </NavigationMenuItem>
</NavigationMenu>

Show hierarchical location:

import { Breadcrumb, BreadcrumbItem, BreadcrumbLink } from '@mdxui/primitives'

<Breadcrumb>
  <BreadcrumbItem>
    <BreadcrumbLink href="/">Home</BreadcrumbLink>
  </BreadcrumbItem>
  <BreadcrumbItem>
    <BreadcrumbLink href="/products">Products</BreadcrumbLink>
  </BreadcrumbItem>
  <BreadcrumbItem isCurrentPage>
    <BreadcrumbLink>API</BreadcrumbLink>
  </BreadcrumbItem>
</Breadcrumb>

Command Palette

Global search and actions:

import { Command } from '@mdxui/primitives'

<Command>
  <CommandInput placeholder="Type to search..." />
  <CommandList>
    <CommandGroup heading="Suggestions">
      <CommandItem>Calendar</CommandItem>
      <CommandItem>Settings</CommandItem>
    </CommandGroup>
  </CommandList>
</Command>

Data Display Patterns

Data Table

Sortable, filterable tables:

import { Table, TableHeader, TableBody, TableRow, TableCell } from '@mdxui/primitives'

<Table>
  <TableHeader>
    <TableRow>
      <TableCell>Name</TableCell>
      <TableCell>Email</TableCell>
      <TableCell>Role</TableCell>
    </TableRow>
  </TableHeader>
  <TableBody>
    {users.map(user => (
      <TableRow key={user.id}>
        <TableCell>{user.name}</TableCell>
        <TableCell>{user.email}</TableCell>
        <TableCell>{user.role}</TableCell>
      </TableRow>
    ))}
  </TableBody>
</Table>

Stats Cards

Dashboard metrics:

import { Card, CardHeader, CardTitle, CardContent } from '@mdxui/primitives'

<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
  <Card>
    <CardHeader>
      <CardTitle>Total Users</CardTitle>
    </CardHeader>
    <CardContent>
      <div className="text-3xl font-bold">1,234</div>
      <p className="text-sm text-muted-foreground">+12% from last month</p>
    </CardContent>
  </Card>
  {/* More stat cards */}
</div>

Timeline

Activity feeds and timelines:

import { Accordion, AccordionItem } from '@mdxui/primitives'

<Accordion type="single" collapsible>
  {activities.map(activity => (
    <AccordionItem key={activity.id} value={activity.id}>
      <AccordionTrigger>{activity.title}</AccordionTrigger>
      <AccordionContent>{activity.description}</AccordionContent>
    </AccordionItem>
  ))}
</Accordion>

Feedback Patterns

Toast Notifications

Non-blocking notifications:

import { toast } from 'sonner'

// Success
toast.success('Settings saved successfully')

// Error
toast.error('Failed to save settings')

// Loading
toast.loading('Saving...')

// Promise
toast.promise(saveSettings(), {
  loading: 'Saving...',
  success: 'Saved!',
  error: 'Failed to save'
})

Confirmation Dialogs

Confirm destructive actions:

import { AlertDialog, AlertDialogTrigger, AlertDialogContent } from '@mdxui/primitives'

<AlertDialog>
  <AlertDialogTrigger>Delete</AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Are you sure?</AlertDialogTitle>
      <AlertDialogDescription>
        This action cannot be undone.
      </AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Cancel</AlertDialogCancel>
      <AlertDialogAction onClick={handleDelete}>Delete</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

Loading States

Show loading feedback:

import { Skeleton, Button } from '@mdxui/primitives'

{isLoading ? (
  <Skeleton className="h-20 w-full" />
) : (
  <div>{content}</div>
)}

<Button disabled={isLoading}>
  {isLoading ? 'Loading...' : 'Submit'}
</Button>

Form Modal

Edit items in a modal:

import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@mdxui/primitives'

<Dialog open={isOpen} onOpenChange={setIsOpen}>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Edit Profile</DialogTitle>
    </DialogHeader>
    <form onSubmit={handleSubmit}>
      {/* Form fields */}
      <DialogFooter>
        <Button type="submit">Save</Button>
      </DialogFooter>
    </form>
  </DialogContent>
</Dialog>

Drawer for Mobile

Mobile-friendly side panel:

import { Drawer, DrawerContent, DrawerHeader } from '@mdxui/primitives'

<Drawer open={isOpen} onOpenChange={setIsOpen}>
  <DrawerContent>
    <DrawerHeader>
      <DrawerTitle>Menu</DrawerTitle>
    </DrawerHeader>
    {/* Navigation items */}
  </DrawerContent>
</Drawer>

Search & Filter Patterns

Search with Filters

Combine SearchBox with Select filters:

import { SearchBox } from '@mdxui/widgets'
import { Select } from '@mdxui/primitives'

<div className="flex gap-4">
  <SearchBox onSearch={handleSearch} className="flex-1" />
  <Select value={category} onValueChange={setCategory}>
    <SelectTrigger className="w-40">
      <SelectValue placeholder="Category" />
    </SelectTrigger>
    <SelectContent>
      <SelectItem value="all">All</SelectItem>
      <SelectItem value="api">API</SelectItem>
      <SelectItem value="sdk">SDK</SelectItem>
    </SelectContent>
  </Select>
</div>

Multi-facet filtering:

import { Checkbox, Label } from '@mdxui/primitives'

<div className="space-y-4">
  <div>
    <h3 className="font-medium mb-2">Category</h3>
    {categories.map(cat => (
      <div key={cat} className="flex items-center gap-2">
        <Checkbox id={cat} />
        <Label htmlFor={cat}>{cat}</Label>
      </div>
    ))}
  </div>
</div>

Chat Patterns

AI Chat Interface

Use ChatBox widget for conversational UI:

import { ChatBox } from '@mdxui/widgets'

<ChatBox
  messages={messages}
  onSend={handleSend}
  placeholder="Ask a question..."
  streaming={isStreaming}
/>

Next Steps

On this page