Production-ready React blocks you copy and own.
For ERP, SaaS and B2B apps: data tables, forms, settings, billing, sign-in and dashboards. Accessible, tested, and yours to change, with upgrades that merge into your edits.
npx rdloom init
npx rdloom add date-range-picker data-grid --installThe hard ones, live
- DateRangePickerPresets, typed or picked, one month on phonesReport periodmmddyyyymmddyyyy
- ComboboxTags, async search, 5,000+ optionsIndiaJapan
- DataGridSorting, selection, editing, 100k rows
0 selected
- DialogFocus trapped and restored, validated form
What you can build with it
Admin dashboards
A sidebar, a top bar, stat cards, charts and tables that fold down to a phone.
Data tables with search and filters
Sorting, filters, pages, bulk actions and row menus, with permissions per action.
Forms that validate
Fields, error summaries and repeating rows that work with a keyboard and a screen reader.
Settings and billing pages
Settings sections, plan pickers, usage meters, payment methods and API keys.
Sign-in and sign-up screens
Sign in, sign up, forgot password and one-time code screens in several layouts.
User management and invites
Invite people by email, search a directory, pick from a list and assign roles.
Calendars and booking
A month calendar with events, and a time slot picker for appointments.
AI chat and agent screens
Chat, streaming replies, tool steps, approvals, sources, tables and charts.
Why rdloom
The hard components, done right
DateRangePicker with presets, a Combobox with async search and tags, a DataGrid that stays fast at 100,000 rows. Built on React Aria, tested with axe.
You own the code, and it still upgrades
rdloom add copies the source into your project. rdloom upgrade merges new versions into your edits, like git, instead of overwriting them.
One spec for code, design and docs
Each component is defined once. Its types, tokens, Figma variants, this site and the accessibility checklist are all generated from that spec.
Made for AI coding agents
An MCP server gives Claude Code, Cursor and others the props, usage rules, accessibility requirements and tested examples, so they write correct code.
Questions
What is rdloom?
A collection of production-ready React blocks and components that you copy into your project and own. It covers the screens around an API call: tables, forms, settings, billing, sign-in and dashboards. It never fetches data itself, so it works with any backend.
How is it different from a UI library installed from npm?
One command copies the source into your project, so you can change anything. When a new version comes out, rdloom upgrade merges it into your edits the way git does, instead of overwriting them.
Does it work with Next.js, Vite and other React setups?
It is built for React 19 and Tailwind CSS 4, and also supports React 18.3 and Tailwind CSS 3.4. rdloom has no router and no data layer of its own, and every component is marked "use client", so it should fit most React apps. Our test app uses Vite. The Next.js App Router and other setups have not been tested yet.
Is it accessible?
Every component is built on React Aria and every example is checked with automated accessibility tests. Each component page lists its keyboard and screen reader behaviour. A full audit by people using screen readers is still planned.
Is it free?
Yes. The source is open and uses the MIT licence.
Can I use it with Figma and AI coding tools?
Yes. A Figma plugin syncs the design tokens and component variants, and an MCP server gives AI coding tools each component's props, usage rules and tested examples.
Does it support dark mode and my own fonts?
Dark mode comes from the design tokens. Components use your app's font and never ship or force a font of their own.
99 components and 21 blocks
- AccordionA stack of sections whose content expands and collapses under a heading, like an FAQ. Use with AccordionItem.
- ActionButtonOne button that handles the permission check, an optional confirmation, the pending state and a result message for an action. It does not fetch data, show toasts, cache or route: you pass the function that does the work.
- AgentActivityA short summary of what the assistant is doing or did, such as "Used 3 tools", that opens into each step. It stays open while a step needs approval.
- AlertAn inline message about the state of the page or a task: a tip, a success, a warning or an error. For brief confirmations that disappear, use Toast.
- AlertDialogConfirmation dialog for destructive or irreversible actions. It cannot be dismissed by clicking outside, and can ask the user to type a word before the confirm button works. Open it with DialogTrigger.
- ApiKeyListA list of API keys with their name, prefix, creation and last use, and scopes as badges. Create key opens a dialog with a name and scopes, then shows the secret once with a Copy button and a warning; it is never shown again. Revoke needs the key name typed to confirm. Your callbacks do the work. UI permission is not security: the server must check again.
- AppFooterThe footer of an application or marketing page: a line of text, link lists and social links. It stacks on a phone and has the same size and spacing on every page.
- AppHeaderThe top bar of an application: a slot for a sidebar toggle, the breadcrumbs, a search button that opens your command palette, your own actions, a notifications bell with an unread count and the account menu. In a narrow space the search folds to an icon.
- ApprovalBoxAsks someone to approve or decline something the assistant wants to do. It says what will happen, how risky it is and whether it can be undone, in words as well as color.
- AspectRatioA box that keeps a fixed width to height ratio for what it holds, such as an image, a video or a map. It reserves the space before the content loads, so the page does not jump.
- AttachmentA chip or card for a file attached to a message or a prompt: its name, size, a type icon, an upload progress bar or error, and an optional remove button. A preview variant shows a thumbnail for pictures. AttachmentList groups several as a list.
- AuthCardThe centered card for sign in, sign up, forgot password and verify code screens: a logo, a title, your form, other ways to sign in and links underneath.
- AvatarA person's or account's picture, falling back to their initials when there is no image or it fails to load.
- AvatarGroupAn overlapping stack of avatars with a +N chip for the rest, for showing who is on a team, thread or file.
- BadgeA small label that states a status or category, like Paid, Overdue or Beta. Not interactive.
- BlurFadeContent that sharpens and slides into place when it first appears or when it scrolls into view. It is visible to start with, so it never hides content from anyone.
- BreadcrumbsThe path from the top of the site to the current page, as links. Use BreadcrumbItem for each step; the last one is the current page.
- BubbleA chat bubble for plain, short messages. Bubble is the chrome around one message: alignment and colour for who sent it, an avatar, a name and a time, a delivery status with Retry, grouped bubbles that merge their corners, and a footer for actions. It does not render structured replies. Message renders an AI turn from typed parts (markdown, tools, charts, sources) and Chat holds the whole conversation; use Bubble for person-to-person or simple text chats, or put a Response inside a Bubble when you want the bubble look around formatted text.
- ButtonTriggers an action or event, such as submitting a form or opening a dialog.
- ButtonGroupJoins related Buttons into one visual unit with shared borders and rounded outer corners only, horizontal or vertical. Also the base for a split button and an icon toolbar.
- CalendarMonth grid for picking a date. RangeCalendar picks a start and end. Used inside DatePicker and DateRangePicker.
- CardA container that groups related content under an optional heading. Compose it with media, an overlay, header, meta, actions, body, a footer and a coloured band for destination, profile, listing and detail-panel cards.
- CarouselA row (or column) of slides that scrolls and snaps, with previous and next buttons and slide dots, for a small set of related items such as featured cards or screenshots. Use CarouselItem for each slide. Built on native scroll snapping, so touch and trackpad swiping work without extra code.
- ChartA bar, line, area or donut chart drawn in plain SVG without a chart library. It fits its container, can be explored with a pointer or the arrow keys, and always comes with a written summary and a View as table switch that shows the same numbers.
- ChatA whole conversation with an assistant: the messages, a box to write in, and the stop and jump-to-latest controls. It shows what you give it and reports what the person does; it never calls a model.
- CheckboxLets the user turn a single option on or off, with an optional indeterminate state.
- CitationA small numbered marker, like [1], inside a reply that jumps to the source it refers to.
- CollapsibleOne region that opens and closes under a trigger, for detail most people do not need at first. For a stack of related sections, use Accordion.
- ColorPickerPicks a color. A button shows the current color and opens a panel with a saturation and brightness area, a hue slider, an optional opacity slider, a hex field and preset swatches. ColorPickerPanel is the same panel inline. Values are hex strings.
- ComboboxText input that filters a list of options as you type. Supports multi-select tags, async loading and long, virtualized lists.
- CommandPaletteA search box in a dialog that finds and runs commands, jumps to pages and triggers actions from the keyboard. Opens with Ctrl or Cmd + K. Use CommandGroup and CommandItem for the results.
- ContextMenuThe menu that opens at the pointer on a right click, a long press or the keyboard (Shift+F10 or the Menu key) over an area such as a file row. It never replaces a visible way to do the same thing.
- CustomerTableA ready-to-use customer list: search, filters, sorting, pages, CSV export, loading rows, an empty state, an error with retry, cards on a phone, and totals with a chart above that follow the filters. Give it customers and it works.
- DashboardPageOne page of a dashboard: a title with its actions, a row of key numbers, then your content. It sits inside DashboardShell but works anywhere. The title is the page's h1.
- DashboardShellThe frame of a dashboard or admin app: a sidebar of navigation that folds down to icons, a top bar with search and actions, an account menu, and the page. On a phone, or in any narrow space, the sidebar becomes a menu that slides in.
- DataGridA fast, accessible data grid for thousands of rows: sorting, filtering, grouping, editing, copy and paste, export and server-side data. Columns are TanStack Table column definitions.
- DataTableThe list screen every admin, ERP and SaaS app has: a table of rows with search, filters, sorting, pages, selection with bulk actions, a row menu with confirmed actions, CSV export, loading, empty and error states, and cards on a narrow screen. It never fetches: you pass the rows (or one page of them with serverSide) and handle the actions. Permissions only change what people see and can try; they are not security, so the server must check every action again.
- DatePickerDate field with a calendar popover. Typing and picking both work, in the user's locale.
- DateRangePickerStart and end date fields with a two-month calendar and optional presets like 'Last 7 days'.
- DialogModal window that asks for focus, such as a confirmation or a short form. Open it with DialogTrigger.
- DirectionSets the reading direction for everything inside it. It writes the dir attribute and gives React Aria the matching locale, so arrow keys and logical CSS flip together.
- DrawerA modal panel that slides up from the bottom of the screen and can be dragged down to dismiss, for short tasks on phones. Open it with DialogTrigger.
- EmptyStateWhat to show when a list, table or page has nothing in it yet: a short explanation and the next step.
- ErrorStateWhat to show when a page or a panel could not be shown: a failed load, or a 404, 403 or 500 screen, with what happened and how to go on.
- ErrorSummaryThe list of problems at the top of a Form after a failed submit. Focus moves to it and each item takes the person to its field. It shows nothing until a submit has failed and goes away when everything is fixed.
- EventCalendarA month grid that shows events on the days they happen. People move between months, step through days with the arrow keys, pick an event, and add one from a day when the app allows it. The app owns the events and the month. Days with more events than fit show a +N more button that opens the full list for that day. UI permission is not security: the server must check again.
- FieldArrayRepeating rows of fields inside a Form, such as invoice lines or team members. Add, remove, move up or down and insert are all buttons, so the keyboard does everything; focus lands somewhere sensible and a polite message says what changed. The contents of the rows and any totals are yours.
- FileUploadA drop zone and button for choosing files, with type, size and count limits and a list of the chosen files you can remove from. The component picks the files; you upload them.
- FormA form that holds the values, runs your validators or a schema, and exposes its progress as an action state (idle, pending, success, error). Fields connect by name and the inputs already link label, help text and error. It never fetches or saves anything: your onSubmit does.
- GeneratedChartA bar or line chart an assistant produced, drawn without a chart library, always with a written summary and a View as table switch that shows the same numbers as a table.
- GeneratedTableA table an assistant produced, shown as a real sortable table with a title and summary, numbers aligned, long results cut to a few rows, and a CSV download.
- GradientButtonA button with a colour that travels around its edge. The label sits on the normal button surface, so its contrast is the plain Button's. Builds on Button.
- GradientTextText filled with a gradient that keeps flowing, for a short headline or a highlighted word. The words stay real text.
- HoverCardA richer preview that opens when a link is hovered or reached with the keyboard, like a profile summary on a user name. It only repeats information that is available elsewhere.
- InputGroupOne bordered text field that wraps an input with addons before or after it: a currency sign, a URL prefix, a search icon, a clear, show or copy button. Built from InputGroup, InputGroupAddon and InputGroupInput.
- InputOTPOne-time code input for verification and two-factor sign in. One real input holds the code and drawn cells show it, so paste, autofill from SMS and screen readers all work.
- InviteDialogA dialog for inviting people, in three shapes: typed emails with a role on one compact line each, a search of a directory you pass, or a two-step pick-from-a-list with a role per person. Checks for format, duplicates and people who are already members, an error summary, an optional message and a submit button that says how many invitations it sends. Your onInvite does the work. UI permission is not security: the server must check again.
- ItemA flexible list row with a leading media slot (icon box, avatar or picture), a title, a description and trailing actions. The whole row can be a link or a button while its actions stay separately clickable.
- KbdShows a keyboard key or shortcut, like Ctrl or ⌘K, in a keycap style. Not interactive.
- MarkerA divider that labels a moment inside a conversation or feed: a centered label between two lines. Use date for a new day, unread for where new messages start, and event for something that happened, like someone joining.
- MenuA list of actions or options that opens from a button, like a More (…) or Account menu. Use with MenuTrigger and MenuItem.
- MenubarA horizontal bar of menus like File, Edit and View, as in a desktop application. Each MenubarMenu opens a list of actions with shortcuts, checkbox and radio items and submenus. Arrow keys move between the menus.
- MessageOne message in a conversation, from you or the assistant. It renders each part in order with the right component: text as formatted markdown, tool calls as activity, tables and charts as real components, sources at the end.
- MessageScrollerThe scrolling region of a conversation. It follows new messages while the reader is at the bottom, stays put when the reader has scrolled up (with a Jump to latest button), and keeps the place when older messages are added at the top.
- NativeSelectThe browser's own select menu, dressed like the other fields. It gives the native picker on phones and works with plain form posts. For custom option rows or search, use Select or Combobox.
- NavigationMenuSite navigation along the top of a page: plain links, and triggers that open a shared panel of grouped links (a mega-menu). Built from NavigationMenuItem, NavigationMenuTrigger, NavigationMenuContent and NavigationMenuLink. It is a set of links, not a menu of actions.
- NumberFieldA text field for numbers, with increment and decrement buttons, keyboard stepping, and locale-aware formatting for decimals, currency, units and percentages.
- PageHeaderThe top of a page: breadcrumbs, a title with badges, a description, actions on the right and tabs underneath. Every part is optional except the title.
- PaginationPage numbers with previous and next buttons, for content split across pages. Long ranges collapse to the first page, the last page, and the pages around the current one.
- PaymentMethodCardOne payment method: a generic card mark, the last four digits, the expiry with an expires soon notice, a default badge, and the actions Update, Remove (confirmed) and Make default. With no method it offers Add a payment method. It never holds a full card number; your callbacks do the work. UI permission is not security: the server must check again.
- PlanCardThe current subscription plan: name, price and interval, status with the right text, renewal or end date, feature list, a usage hint, and the actions Change plan and Cancel subscription (confirmed, with the end date). A past due plan shows an alert. PlanPicker, exported beside it, lets people choose another plan. Your callbacks do the work. UI permission is not security: the server must check again.
- PopoverNon-modal panel anchored to a trigger, for extra controls or details. Open it with DialogTrigger.
- ProgressA bar showing how far along a task is, or that something is working when the amount is unknown.
- PromptInputThe message box of a chat: one rounded bar with a + menu on the left, the text in the middle, and your own controls, a microphone and Send on the right. Added files show above the text. You get only the buttons you ask for.
- PulseButtonA button with a soft ring that keeps radiating out, to draw the eye to the one action that matters now. Builds on Button.
- QuestionnaireA short flow of questions asked one at a time, for onboarding or for an assistant that needs a few details. It shows progress, keeps answers when going back, and ends with a review step where each answer can be edited.
- RadioGroupLets the user pick exactly one option from a small, visible set. Use with Radio children.
- RatingA star rating. As an input it is a radio group of stars; with isReadOnly it is a display like "4.5 out of 5 stars" with an optional count.
- ResizablePanelsPanels side by side or stacked that the person can resize by dragging or with the keyboard, for a sidebar and content, an editor and a console, or a split view. Build it from ResizablePanelGroup, ResizablePanel (id, defaultSize, minSize, maxSize, collapsible, collapsedSize) and ResizableHandle (withHandle, label).
- ResponseShows an assistant's reply as formatted text: headings, lists, tables, code, links and source markers. It is safe for text you do not control and for text that is still arriving.
- RevealButtonA button that opens an arrow beside its label when you hover or focus it, to suggest "go". Only a transition, so there is nothing to pause. Builds on Button.
- RippleConcentric rings that swell outward from the centre, as a calm backdrop behind a heading or a call to action. Content goes in front of the rings.
- RippleButtonA button that sends a ripple out from where you pressed it, or from its centre when pressed with the keyboard. Builds on Button.
- ScrollAreaA scrollable region with a thin themed scrollbar, reachable by keyboard, with optional fades at the edges that still have content.
- SectionHeaderThe heading of a section inside a page, for a card or a table: a title, a description and actions on the right.
- SegmentedControlA row of connected buttons where exactly one option is chosen, for switching a view or a setting with two to five choices. Use SegmentedControlItem for each option.
- SelectPicks one option from a list shown in a popover. Use with SelectItem children.
- SeparatorA thin line that divides content, horizontal or vertical, with an optional label in the middle such as "or".
- SettingsSectionThe repeating unit of a settings page: a title and description on the left, a card with the content on the right, and a Save and Cancel bar that appears only when something has changed. Use SettingsRow inside for toggle lists. Your onSave does the work. UI permission is not security: the server must check again.
- SheetA modal panel that slides in from the edge of the screen, for filters, details or navigation on small screens. Open it with DialogTrigger.
- ShimmerButtonA button with a soft band of light that crosses its surface now and then, for one standout action. Builds on Button, so focus, disabled and loading work the same.
- ShineBorderA band of colour that slides steadily along a border, so the edge seems to catch the light. Wrap a card or a field.
- ShuttleBorderA point of light that runs around the edge of whatever is inside, like the shuttle of a loom crossing the threads. Wrap a card, an input or a button; give it your radius and background.
- SidebarA sidebar of navigation: the team or product name at the top, grouped links with sub-items and badges, an optional footer, and the signed-in person at the bottom. It can fold down to icons, and comes in four looks. It is only the panel; DashboardShell adds the top bar and the phone menu.
- SkeletonA grey placeholder shaped like the content that is loading, so the page doesn't jump when it arrives.
- SliderPicks a number, or a range with two thumbs, by dragging along a track. Shows the formatted value.
- SourcesThe numbered list of sources a reply drew on, with title, site and a short excerpt. Each entry is where a Citation marker lands.
- SparklineA tiny line or bar graphic that shows the shape of a trend, without axes. Decoration unless it has a label.
- SpinnerA small loading indicator for work of unknown length: inline with text, inside a button, or over a whole area.
- StatA key number with its label and context: a value, an optional change over time and an optional small trend graphic. Unframed: place it in a Card or a grid.
- StepsShows where someone is in a multi-step process, such as checkout or setup: done, current and upcoming steps. It displays progress; you control the steps and buttons.
- SwitchTurns a setting on or off, taking effect immediately.
- TableA simple, accessible table for a small number of rows: optional sorting and row selection. Build it from TableHeader, TableColumn, TableBody, TableRow and TableCell. For thousands of rows, filtering, editing or grouping, use DataGrid.
- TabsSwitches between related panels of content in the same place. Use with TabList, Tab and TabPanel.
- TagInputA text field that turns what you type into removable tags when you press Enter or comma: for keywords, recipients and labels.
- TextFieldSingle-line or multi-line text input with a label, help text and error message.
- TextShimmerText with a band of light sweeping across it, for a loading message or a quiet accent. The words stay real text: selectable and read as normal.
- TimeFieldA field for a time of day, with separate hour, minute and (optional) second segments that follow the visitor's locale and 12 or 24 hour clock.
- TimeSlotPickerPick a day, then a time on that day. A calendar chooses the date; the times for it come from your getSlots function, sync or async, and show as a group of radio buttons. Times that are taken are disabled and say why. A Confirm button hands back the date and the slot. The app owns which times exist. UI permission is not security: the server must check again before it books anything.
- ToastBrief, non-blocking message about the result of an action. Render ToastRegion once and call toast().
- ToggleButtonA button that stays pressed until pressed again, for turning a mode on or off, like Bold or Mute. Group several with ToggleButtonGroup for single or multiple choice.
- ToggleGroupA row or column of joined toggle buttons with shared borders, for formatting options or a choice between a few modes. Pick single or multiple selection.
- ToolCallOne thing the assistant did, such as searching or running a query: its name, where it is (waiting, running, needs approval, done, failed), how long it took, and on request what went in and out.
- TooltipShort text label shown on hover or keyboard focus. Wrap the trigger and tooltip in TooltipTrigger.
- TopNavNavigation across the top of an application or marketing site: your brand, links (some opening a short list), and a slot for buttons or the account menu. In a narrow space it becomes a menu button that opens the same links in a sheet. It comes plain, with a line, or as a floating pill.
- TreeAn expandable hierarchy such as folders and files or a nested menu, with keyboard navigation and optional selection. Build it from nested TreeItem elements.
- TypographyText components that use the font of the host app: Heading (H1 to H4) with the visual size separate from the semantic level, Text, Lead, Prose for raw HTML, InlineCode, Blockquote and List.
- UsageMeterA labeled meter for a limit: seats 8 of 10, storage 4.2 of 5 GB, API calls. It warns at 80 percent and at the limit with words and an icon, not only color, and can offer an upgrade when near the limit. UsageMeterList shows several. Built on role="meter"; the app owns the numbers. UI permission is not security: the server must check again.
- UserFormA form to create or edit a user, in three presentations: a whole page (variant page), a compact form for a Dialog (modal) and a single-column form for a Sheet (sheet). Fields: profile picture, name, job title, email, phone with a calling-code select, address, time zone, language, bio, role, active switch and team, chosen with a plain fields object. Edit mode adds a danger zone to suspend or reinstate and delete, each behind a confirmation. Save stays disabled until something changes, and Cancel asks before throwing changes away. Your onSubmit does the work. UI permission is not security: the server must check again.
- UserMenuThe avatar button that opens the account menu: the person's name and email at the top, your own entries (settings, billing, help) in groups, a row for the theme, and a Sign out entry that can ask first, shows that it is working, and tells screen readers how it went.