UI Components
The UI layer is split into four packages built on Radix primitives and Tailwind CSS v4.
For Tailwind v4 migration details and CSS config see Tailwind v4 recipe.
Package Hierarchy
@djangocfg/ui-core Pure React (133 components, Radix + Tailwind v4)
└── @djangocfg/ui-nextjs Next.js extensions (Link, Sidebar, Pagination, SSR)
└── @djangocfg/ui-tools Heavy tools, lazy-loaded (maps, mermaid, code, video, audio)
└── @djangocfg/layouts App layouts (Public, Private, Auth, Admin, Dashboard)In Next.js apps always import from @djangocfg/ui-nextjs, not @djangocfg/ui-core directly. ui-nextjs re-exports everything from ui-core plus Next.js-specific components.
Component Categories
| Category | Count | Examples |
|---|---|---|
| Forms | 23 | Button, Input, Select, Combobox, MultiSelect, Switch, Slider, PhoneInput |
| Layout | 14 | Card, Sidebar, ScrollArea, Resizable, Skeleton, Separator |
| Navigation | 6 | Breadcrumb, Tabs, Pagination, NavigationMenu |
| Overlay | 9 | Dialog, Sheet, Drawer, Popover, Tooltip, DropdownMenu |
| Feedback | 4 | Alert, Badge, Progress, Toaster (sonner) |
| Data Display | 9 | Table, Accordion, Calendar, DatePicker, SSRPagination |
| Interactive | 3 | Command (cmdk), Toggle, ToggleGroup |
| Charts | 7 | ChartContainer + recharts (Area, Bar, Line, Pie, Donut, Radial) |
| Hooks | 15 | useDebounce, useHotkey, useLocalStorage, useMediaQuery, useIsMobile |
| Layouts | — | BaseApp (providers) + PrivateLayout / PublicLayout / AuthLayout (shells) |
Import Patterns
// Components — ui-core is framework-agnostic, import directly
import { Button, Card, Badge, Dialog } from '@djangocfg/ui-core/components';
import { Sidebar, SidebarProvider, useSidebar } from '@djangocfg/ui-core/components';
// Hooks
import { useDebounce, useHotkey, useLocalStorage } from '@djangocfg/ui-core/hooks';
import { useQueryParams } from '@djangocfg/ui-core/hooks';
// Next.js router adapter (Next apps only)
import { NextRouterAdapter } from '@djangocfg/ui-core/adapters/nextjs';
// Layouts — BaseApp = providers (mount once); shells per route-group
import { BaseApp, PrivateLayout, PublicLayout, AuthDialog } from '@djangocfg/layouts';
import { AIChatWidget, AIChatProvider } from '@djangocfg/layouts/snippets';
// Heavy tools (lazy-loaded)
import { LazyMermaid } from '@djangocfg/ui-tools/mermaid';
import { LazyPrettyCode } from '@djangocfg/ui-tools/pretty-code';
import { LazyJsonTree } from '@djangocfg/ui-tools/json-tree';
import { GalleryCompact } from '@djangocfg/ui-tools/gallery';DRF Pagination
Integrate DRF paginated responses with the pagination component:
import { SSRPagination, useDRFPagination } from '@djangocfg/ui-nextjs';
const { page, pageSize, setPage, setPageSize, paginationInfo } = useDRFPagination({
total: data?.count ?? 0,
defaultPageSize: 20,
});
<SSRPagination
currentPage={page}
totalPages={paginationInfo.totalPages}
onPageChange={setPage}
/>useDRFPagination converts DRF’s count field into page info and provides setter functions.
Sidebar System
Full sidebar with 17 exports for building navigation:
<SidebarProvider>
<Sidebar>
<SidebarHeader>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton>Dashboard</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Main</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton>Catalog</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>...</SidebarFooter>
</Sidebar>
</SidebarProvider>Rules
- Import directly from
@djangocfg/ui-core(framework-agnostic); in Next.js add the@djangocfg/ui-core/adapters/nextjsrouter adapter - Use
@djangocfg/ui-toolsfor heavy components (maps, code, mermaid) — they are lazy-loaded - Use
@djangocfg/layoutsfor app-level chrome:BaseApp(providers, once at root) +PrivateLayout/PublicLayout(shells, per route-group) - Use
useDRFPaginationto convert DRFcountresponses into page state — do not compute pages manually - Wrap sidebar navigation with
SidebarProvider— useuseSidebar()for programmatic open/close
Last updated on