Shadcn Blocks + React Aria
BetaEvery Shadcnblocks block, component and page is available for Adobe's React Aria Components, alongside Radix UI and Base UI. Same blocks, accessibility-first primitives underneath.
Accessibility-First Primitives
React Aria Components is Adobe's library of unstyled, accessible components: consistent press handling across mouse, touch and keyboard, collection semantics, internationalised dates and numbers, and screen reader behaviour that has been tested rather than assumed. Same shadcn/ui wrappers, same blocks.
Radix UI
The established choice
- Battle-tested in production
- Extensive component library
- Large community ecosystem
React Aria
Accessibility and internationalisation first
- Adaptive press, hover and focus across every input
- Tested against real screen readers and devices
- Over 30 locales, 13 calendar systems, RTL layout
"use client"
import { cn } from "cn"
import * as React from "react"
import { Tooltip as TooltipPrimitive } from "radix-ui"
function TooltipProvider({
delayDuration = 0,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
return (
<TooltipPrimitive.Provider
data-slot="tooltip-provider"
delayDuration={delayDuration}
{...props}
/>
)
}
function Tooltip({
...props
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />
}
function TooltipTrigger({
...props
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
}
function TooltipContent({
className,
sideOffset = 0,
children,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
return (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
data-slot="tooltip-content"
sideOffset={sideOffset}
className={cn(
"data-open:animate-in data-open:fade-in-0...",
className
)}
{...props}
>
{children}
<TooltipPrimitive.Arrow className="..." />
</TooltipPrimitive.Content>
</TooltipPrimitive.Portal>
)
}
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }"use client"
import { cn } from "cn"
import * as React from "react"
import {
Focusable,
OverlayArrow,
Tooltip as TooltipPrimitive,
TooltipTrigger as TooltipTriggerPrimitive,
} from "react-aria-components"
function TooltipTrigger({
delay = 0,
children,
...props
}: React.ComponentProps<typeof TooltipTriggerPrimitive>) {
const [trigger, tooltip] = React.Children.toArray(children)
return (
<TooltipTriggerPrimitive
data-slot="tooltip-trigger"
delay={delay}
{...props}
>
<Focusable>{trigger}</Focusable>
{tooltip}
</TooltipTriggerPrimitive>
)
}
function Tooltip({
className,
placement = "top",
offset = 4,
children,
...props
}: React.ComponentProps<typeof TooltipPrimitive>) {
return (
<TooltipPrimitive
data-slot="tooltip-content"
placement={placement}
offset={offset}
className={cn(
"data-entering:animate-in data-entering:fade-in-0...",
className
)}
{...props}
>
{children}
<OverlayArrow className="..." />
</TooltipPrimitive>
)
}
export { Tooltip, TooltipTrigger }radix-ui vs react-aria-componentsWhy React Aria is in Beta
Every block works with React Aria today. The Beta label is about two pieces of code that only exist because we wrote them.
Wrappers shadcn does not ship
shadcn's React Aria preset has no navigation menu, menubar or form wrapper. Rather than drop those blocks, we ship our own React Aria implementations as @shadcnblocks/ui-extras/*. The CLI installs them into components/ui automatically when a block needs them.
ui-extras/navigation-menuUsed by most navbar blocks. Same exports as the Radix wrapper.
ui-extras/menubarDashboard and app-shell blocks. Same exports as the Radix wrapper.
ui-extras/formForm, FormField, FormMessage and friends for react-hook-form blocks.
Third-party components without a React Aria build
Some blocks use Kibo UI components, and Kibo does not publish React Aria variants. For those we maintain React Aria builds and serve them from our registry. Your block still imports @/components/kibo-ui/…; the CLI simply fetches the file from us.
What beta does not mean
- Not incomplete: every block, component and page resolves.
- Not unstable for you: the code you install is yours and keeps working.
- Not unsupported: bugs in React Aria blocks are bugs we fix.
The label comes off when the shims have settled, or when shadcn ships official versions and we can delete ours. Read the full write-up
Simple Configuration
One setting in your components.json controls both the UI library and visual style. The registry URL's {style} placeholder sends it to us.
{"$schema": "https://ui.shadcn.com/schema.json","style": "aria-vega","rsc": true,"tsx": true,"tailwind": {"config": "","css": "app/globals.css","baseColor": "neutral","cssVariables": true},"aliases": {"components": "@/components","utils": "@/lib/utils","ui": "@/components/ui"},"registries": {"@shadcnblocks": "https://www.shadcnblocks.com/r/{style}/{name}"}}
{library}-{style}npx shadcn@latest add --all --overwrite and add blocks as usual with npx shadcn@latest add @shadcnblocks/hero1. The CLI installs the block, the React Aria wrappers, any ui-extras shims, and react-aria-components.Ready to Try React Aria?
Open any block, switch the library to React Aria in the toolbar, and compare the code against Radix in the Diff view.