Pure UI components for admin dashboards - bring your own data layer
npm install @mdxui/admin> Pure UI components for admin dashboards. API-compatible with ra-ui-materialui.
Choose @mdxui/admin if you are:
- Starting a new project without an existing react-admin codebase
- Building a custom admin UI with your own data layer (TanStack Query, SWR, etc.)
- Want zero react-admin dependencies in your bundle
- Building on the dotdo platform with @dotdo/react/tanstack
- Need maximum flexibility - bring your own routing, state management, and data fetching
Choose shadmin instead if you are:
- Migrating an existing react-admin application to modern styling
- Need drop-in compatibility with react-admin hooks (useRecordContext, useListContext)
- Want to preserve existing business logic while upgrading the UI
- Require react-admin's DataProvider/AuthProvider abstractions
```
┌─────────────────────────────────────────────────────────────────┐
│ "Which package do I use?" │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Do you have an existing react-admin app? │
│ │
│ YES ──────────► Use shadmin (drop-in replacement) │
│ • Keep ra-core hooks │
│ • Replace Material UI with ShadCN │
│ │
│ NO ───────────► Use @mdxui/admin (this package) │
│ • Zero ra-core dependency │
│ • Wire to any data layer │
│ │
└─────────────────────────────────────────────────────────────────┘
@mdxui/admin provides admin-specific UI components with zero data-fetching opinions. Built on @mdxui/primitives (Radix + Tailwind), it serves as the shared UI layer for both saaskit and shadmin.
`bash`
npm install @mdxui/admin
Supabase-style spreadsheet grid with full keyboard navigation.
`tsx
import { TableEditor } from '@mdxui/admin'
{ accessorKey: 'id', header: 'ID', dataType: 'text' },
{ accessorKey: 'name', header: 'Name', dataType: 'text', editable: true },
{ accessorKey: 'email', header: 'Email', dataType: 'email', editable: true },
{ accessorKey: 'status', header: 'Status', dataType: 'enum', enumValues: ['active', 'inactive'] },
{ accessorKey: 'createdAt', header: 'Created', dataType: 'date' },
]}
data={rows}
onCellChange={(rowIndex, columnId, value) => updateCell(rowIndex, columnId, value)}
onRowCreate={(row) => createRow(row)}
onRowDelete={(ids) => deleteRows(ids)}
editable
filterable
sortable
selectable
/>
`
Keyboard shortcuts:
| Key | Action |
|-----|--------|
| Arrow keys | Navigate cells |
| Enter / F2 | Edit cell |
| Tab / Shift+Tab | Next/prev cell |
| Escape | Cancel edit |
| Delete | Clear cell (NULL) |
| Ctrl+Z | Undo |
| Ctrl+Shift+Z | Redo |
| Ctrl+C | Copy |
| Home/End | First/last column |
Read-only components for displaying data in lists and show views.
`tsx
import { TextField, NumberField, DateField, BooleanField, EmailField, UrlField, ImageField, BadgeField, ReferenceField, ArrayField, ChipField } from '@mdxui/admin'
`
Form inputs for create/edit views. Integrate with react-hook-form.
`tsx
import { TextInput, NumberInput, SelectInput, BooleanInput, DateInput, TextareaInput, PasswordInput, ReferenceInput } from '@mdxui/admin'
{ id: 'inactive', name: 'Inactive' },
]} />
`
Admin shell components for building dashboard layouts.
`tsx
import { AdminLayout, Sidebar, SidebarItem, SidebarGroup, AppBar, Breadcrumbs, PageHeader } from '@mdxui/admin'
}
appBar={
>
{children}
`
All components are type-compatible with ra-ui-materialui, enabling gradual migration from react-admin.
`tsx`
// These props interfaces match react-admin
import type { TextFieldProps, TextInputProps, ListProps, DatagridProps } from '@mdxui/admin'
Components use Tailwind CSS via @mdxui/primitives. Override styles via className or CSS variables.
`tsx`
Theme variables in your globals.css:`css`
:root {
--admin-sidebar-width: 280px;
--admin-header-height: 64px;
}
@mdxui/admin is purely presentational with zero data-fetching dependencies. You wire it to your data layer:
`tsx
// 1. Create your data provider (implements DataProvider interface from mdxui)
const dataProvider = createMyDataProvider()
// 2. Wire up your components with your state management
function UserList() {
const { data, isLoading } = useMyDataHook('users') // TanStack Query, SWR, etc.
return (
loading={isLoading}
columns={columns}
/>
)
}
`
Popular integrations:
- TanStack Query - Use @tanstack/react-query for data fetchingswr
- SWR - Use for data fetching
- Zustand/Redux - Manage state externally
- react-admin - Compatible with react-admin's DataProvider
@mdxui/admin sits at the admin patterns layer - extending @mdxui/app with CRUD and data management components for operators and admins.
``
┌─────────────────────────────────────────────────────────────────┐
│ mdxui (interfaces) │
│ DataProvider, AuthProvider, AdminComponents │
└─────────────────────────────────────────────────────────────────┘
↓ implements
┌─────────────────────────────────────────────────────────────────┐
│ @mdxui/primitives (raw UI) │
│ Button, Card, Dialog, Input, Table, Sidebar, etc. │
└─────────────────────────────────────────────────────────────────┘
↓ uses
┌─────────────────────────────────────────────────────────────────┐
│ @mdxui/app (app framework) │
│
└─────────────────────────────────────────────────────────────────┘
↓ extends
┌─────────────────────────────────────────────────────────────────┐
│ ★ @mdxui/admin (admin patterns) ← YOU ARE HERE │
│
│ For: Operators, admins, internal teams │
└─────────────────────────────────────────────────────────────────┘
↓ used by
┌─────────────────────────────────────────────────────────────────┐
│ Your Application (data layer) │
│ TanStack Query, SWR, Zustand, or any data fetching solution │
└─────────────────────────────────────────────────────────────────┘
| Component Type | Examples | Purpose |
|----------------|----------|---------|
| CRUD Views | ListView, EditView, CreateView, ShowView | Standard admin pages |
| Resources | , | Declarative resource management |
| Data Display | Fields, DataGrid, DataBrowser | Read-only data presentation |
| Data Entry | Inputs, Forms | Create/edit functionality |
| Editors | TableEditor, DocumentEditor, CodeEditor | Advanced editing interfaces |
@mdxui/admin is purely presentational with no data-fetching dependencies. Data binding is your application's responsibility - use TanStack Query, SWR, or any other solution.
| Package | Relationship |
|---------|--------------|
| @mdxui/primitives | Base UI components (dependency) |@mdxui/app
| | App framework (extends this) |mdxui
| | Type definitions and interfaces |
- react ^18.0.0 || ^19.0.0react-router-dom` ^6.0.0 (optional, for routing components)
-
- Documentation
- GitHub
- Storybook
MIT