Blazor port of shadcn/ui
Beautifully designed, accessible UI components built with Tailwind CSS for .NET Blazor applications.
- 56 component categories — A comprehensive UI library with 195+ Razor component files
- Based on shadcn/ui — A proven design system from the web, ported directly to Blazor
- Tailwind CSS — oklch color system with CSS custom property-based theming
- Dark mode — Built-in light/dark mode support
- Accessible — Components designed with accessibility in mind
- Zero external dependencies — Only ASP.NET Core framework references
- Multi-target — .NET 8.0, 9.0, 10.0 support | Blazor Server & WebAssembly compatible
dotnet add package Daeha.RnUIAdd the following to your _Imports.razor:
@using Daeha.RnUI.Components.UIAdd the CSS to your App.razor or _Host.cshtml:
<link rel="stylesheet" href="_content/Daeha.RnUI/css/shadcn.css" />RnUI uses Tailwind CSS v4. You need to set up Tailwind CSS in your Blazor project to scan and compile utility classes.
Install Tailwind CSS in your project root:
npm init -y
npm install -D tailwindcss @tailwindcss/cliCreate a wwwroot/input.css file and include your Razor files as scan targets:
@import "tailwindcss";
@source "../**/*.razor";When using the NuGet package: If installed via NuGet, the library's
.razorfiles are not available locally. However, RnUI component base styles (.cn-*classes) are already included inshadcn.css, so they work without additional@sourceconfiguration. You only need to scan Tailwind utility classes used in your own.razorfiles.
Add build scripts to your package.json:
{
"scripts": {
"build:css": "npx @tailwindcss/cli -i wwwroot/input.css -o wwwroot/css/tailwindcss.css",
"watch:css": "npx @tailwindcss/cli -i wwwroot/input.css -o wwwroot/css/tailwindcss.css --watch"
}
}Link both the RnUI styles and the Tailwind CSS output file in your App.razor or _Host.cshtml:
<!-- RnUI component styles -->
<link rel="stylesheet" href="_content/Daeha.RnUI/css/shadcn.css" />
<!-- Tailwind utility classes -->
<link rel="stylesheet" href="css/tailwindcss.css" />Use watch mode during development and build for production:
npm run watch:css # Development (watches for file changes)
npm run build:css # Production (one-time build)See live demos and detailed usage for each component on the Demo Site.
| Component | Description | Demo |
|---|---|---|
RnButton |
Supports Default, Secondary, Outline, Ghost, Destructive, Link variants | Live |
RnInput |
Text input field | Live |
RnTextarea |
Multi-line text input | Live |
RnLabel |
Form label | Live |
RnCheckbox |
Checkbox | Live |
RnSwitch |
Toggle switch | Live |
RnRadioGroup |
Radio button group | Live |
RnSelect |
Dropdown selection | Live |
RnToggle |
Toggle button | Live |
RnToggleGroup |
Toggle button group | Live |
RnCombobox |
Searchable dropdown selection | Live |
RnInputOTP |
OTP input field | Live |
RnField |
Field container (integrates Label, Description, Error) | Live |
RnTextField |
Convenience wrapper for RnField + RnFieldLabel + RnInput | Live |
RnDateField |
Convenience wrapper for RnField + RnFieldLabel + RnDatePicker (string? binding) | Live |
RnForm |
Form validation | Live |
| Component | Description | Demo |
|---|---|---|
RnCard |
Composed of Header, Title, Description, Content, Footer, Action | Live |
RnAlert |
Alert message (Default, Destructive) | Live |
RnBadge |
Status badge | Live |
RnAspectRatio |
Aspect ratio container | Live |
RnScrollArea |
Custom scroll area | Live |
RnSeparator |
Divider | Live |
RnResizable |
Resizable panels | Live |
| Component | Description | Demo |
|---|---|---|
RnTable |
Basic table (Head, Body, Row, Header, Cell) | Live |
RnDataTable |
Advanced data table (sorting, filtering, pagination, selection, row expansion) | Live |
RnAvatar |
User avatar (with group support) | Live |
RnProgress |
Progress bar | Live |
RnSlider |
Slider | Live |
RnSkeleton |
Loading skeleton | Live |
RnSpinner |
Loading spinner | Live |
RnKbd |
Keyboard shortcut display | Live |
RnCalendar |
Calendar | Live |
| Component | Description | Demo |
|---|---|---|
RnTabs |
Tab component (Default, Line variants) | Live |
RnBreadcrumb |
Breadcrumb navigation | Live |
RnPagination |
Pagination | Live |
RnNavigationMenu |
Navigation menu | Live |
RnSidebar |
Sidebar (Header, Content, Footer, Group, Menu) | Live |
RnMainLayout01 |
Three-slot layout (Header/Content/Footer) for use inside RnSidebarInset | Live |
RnMenubar |
Menu bar | Live |
| Component | Description | Demo |
|---|---|---|
RnDialog |
Modal dialog | Live |
RnAlertDialog |
Confirmation dialog | Live |
RnSheet |
Side sheet | Live |
RnPopover |
Popover | Live |
RnTooltip |
Tooltip | Live |
RnHoverCard |
Hover card | Live |
RnDropdownMenu |
Dropdown menu | Live |
RnContextMenu |
Context menu | Live |
RnDrawer |
Drawer (mobile bottom sheet) | Live |
RnToast |
Toast notification | Live |
| Component | Description | Demo |
|---|---|---|
RnAccordion |
Accordion | Live |
RnCollapsible |
Collapsible | Live |
RnEmpty |
Empty state | Live |
RnCarousel |
Carousel / slider | Live |
RnCommand |
Command palette | Live |
RnDatePicker |
Date picker | Live |
RnGantt |
Gantt chart | Live |
RnButtonGroup |
Button group | Live |
Supports 6 variants and 8 sizes.
@* Variants *@
<RnButton>Default</RnButton>
<RnButton Variant="ButtonVariant.Secondary">Secondary</RnButton>
<RnButton Variant="ButtonVariant.Outline">Outline</RnButton>
<RnButton Variant="ButtonVariant.Ghost">Ghost</RnButton>
<RnButton Variant="ButtonVariant.Destructive">Destructive</RnButton>
<RnButton Variant="ButtonVariant.Link">Link</RnButton>
@* Sizes *@
<RnButton Size="ButtonSize.Sm">Small</RnButton>
<RnButton Size="ButtonSize.Default">Default</RnButton>
<RnButton Size="ButtonSize.Lg">Large</RnButton>
<RnButton Size="ButtonSize.Icon">🔔</RnButton><RnCard>
<RnCardHeader>
<RnCardTitle>Card Title</RnCardTitle>
<RnCardDescription>Card description goes here.</RnCardDescription>
</RnCardHeader>
<RnCardContent>
<p>Card content with some example text.</p>
</RnCardContent>
<RnCardFooter>
<RnButton>Save</RnButton>
<RnButton Variant="ButtonVariant.Outline">Cancel</RnButton>
</RnCardFooter>
</RnCard><RnButton OnClick="() => _dialogOpen = true">Open Dialog</RnButton>
<RnDialog @bind-Open="_dialogOpen">
<RnDialogHeader>
<RnDialogTitle>Edit Profile</RnDialogTitle>
<RnDialogDescription>Make changes to your profile here.</RnDialogDescription>
</RnDialogHeader>
<div class="space-y-4 py-4">
<RnInput Placeholder="Name" @bind-Value="_name" />
<RnInput Type="email" Placeholder="Email" @bind-Value="_email" />
</div>
<RnDialogFooter>
<RnButton Variant="ButtonVariant.Outline" OnClick="() => _dialogOpen = false">Cancel</RnButton>
<RnButton OnClick="Save">Save Changes</RnButton>
</RnDialogFooter>
</RnDialog>A convenience wrapper that combines RnField + RnFieldLabel + RnInput into a single component.
<RnTextField Label="Name" @bind-Value="_name" Placeholder="Enter your name" />
<RnTextField Label="Email" @bind-Value="_email" Type="email" Placeholder="Enter your email" />A convenience wrapper that combines RnField + RnFieldLabel + RnDatePicker into a single component. Accepts string? binding (yyyy-MM-dd format) for easy migration.
<RnDateField Label="Date of Birth" @bind-Value="_birthDate" />
<RnDateField Label="Start Date" @bind-Value="_startDate" Placeholder="Select a date..." /><RnDataTable TItem="PaymentRecord"
Items="_payments"
SelectionMode="SelectionMode.Multiple"
PageSize="10">
<Columns>
<RnDataTableColumn TItem="PaymentRecord" Property="x => x.Id" Title="ID" Sortable />
<RnDataTableColumn TItem="PaymentRecord" Property="x => x.Name" Title="Name" Sortable Filterable />
<RnDataTableColumn TItem="PaymentRecord" Property="x => x.Amount" Title="Amount" Sortable>
<CellTemplate Context="item">
<div class="text-right font-medium">@item.Amount.ToString("C")</div>
</CellTemplate>
</RnDataTableColumn>
</Columns>
</RnDataTable>For more examples, visit the Demo Site.
RnUI uses CSS custom properties for theming. Override the following variables to customize colors:
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--destructive: 0 84.2% 60.2%;
--muted: 0 0% 96.1%;
--accent: 0 0% 96.1%;
--border: 0 0% 89.8%;
--ring: 0 0% 3.9%;
--radius-lg: 0.5rem;
}Online demo: https://daeha76.github.io/RnUI/
To run the demo locally, use the Daeha.RnUI.Demo.Wasm project:
# Build demo CSS
cd src/Daeha.RnUI.Demo.Wasm && npm install && npm run build:css
# Run the demo
dotnet run --project src/Daeha.RnUI.Demo.WasmOpen https://localhost:7256 in your browser to explore all components.
Contributions are welcome! Feel free to submit issues or pull requests.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License
Made with ❤️ for the Blazor community