---
title: "Radix UI Primitives"
description: "Radix UI primitives form the accessible foundation of the documentation interface, wrapping underlying @radix-ui/react-* libraries to provide styled components for custom scrollable viewports, cont..."
last_updated: "2026-10-12T07:53:59.981993+00:00"
canonical_url: "https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/ui-layouts/radix-ui-primitives"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/radix-ui/src/components/dialog/search.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/dialog/search.tsx)
- [packages/radix-ui/src/components/ui/scroll-area.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/scroll-area.tsx)
- [packages/radix-ui/src/layouts/notebook/slots/sidebar.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/layouts/notebook/slots/sidebar.tsx)
- [packages/api-docs/src/components/accordion.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/api-docs/src/components/accordion.tsx)
- [packages/radix-ui/src/layouts/flux/index.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/layouts/flux/index.tsx)
- [packages/radix-ui/registry/index.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/registry/index.ts)
- [packages/base-ui/src/layouts/notebook/slots/sidebar.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/src/layouts/notebook/slots/sidebar.tsx)
- [packages/radix-ui/src/components/sidebar/base.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/sidebar/base.tsx)
- [packages/radix-ui/src/components/ui/popover.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/popover.tsx)
- [packages/base-ui/src/components/dialog/search.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/src/components/dialog/search.tsx)
- [packages/radix-ui/src/components/toc/index.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/toc/index.tsx)
- [packages/radix-ui/src/layouts/flux/page/slots/toc.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/layouts/flux/page/slots/toc.tsx)
- [packages/api-docs/src/components/dialog.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/api-docs/src/components/dialog.tsx)
- [packages/api-docs/src/components/select.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/api-docs/src/components/select.tsx)
- [packages/base-ui/src/layouts/flux/index.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/src/layouts/flux/index.tsx)
- [packages/radix-ui/src/layouts/notebook/page/slots/toc.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/layouts/notebook/page/slots/toc.tsx)
- [packages/radix-ui/src/components/toc/clerk.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/toc/clerk.tsx)
- [packages/radix-ui/src/layouts/flux/slots/sidebar.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/layouts/flux/slots/sidebar.tsx)
- [packages/base-ui/src/layouts/flux/page/slots/toc.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/src/layouts/flux/page/slots/toc.tsx)
- [packages/radix-ui/src/components/ui/accordion.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/accordion.tsx)
- [packages/api-docs/src/components/schema/client.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/api-docs/src/components/schema/client.tsx)
- [packages/story/src/client/components/select.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/story/src/client/components/select.tsx)
- [packages/base-ui/src/layouts/flux/slots/sidebar.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/src/layouts/flux/slots/sidebar.tsx)
- [packages/radix-ui/src/components/accordion.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/accordion.tsx)
- [packages/radix-ui/src/components/ui/collapsible.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/collapsible.tsx)
- [packages/base-ui/src/components/sidebar/base.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/src/components/sidebar/base.tsx)
- [packages/radix-ui/src/components/ui/navigation-menu.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/navigation-menu.tsx)
- [packages/base-ui/src/components/ui/scroll-area.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/src/components/ui/scroll-area.tsx)
- [packages/base-ui/src/components/toc/index.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/src/components/toc/index.tsx)
- [packages/base-ui/src/components/ui/popover.tsx](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/base-ui/src/components/ui/popover.tsx)
</details>

## Overview

Radix UI primitives form the accessible foundation of the documentation interface, wrapping underlying `@radix-ui/react-*` libraries to provide styled components for custom scrollable viewports, contextual floating popovers, and interactive collapsible or accordion panels. By encapsulating core behavior, these components manage complex UI states such as keyboard navigation, modal focus traps, and smooth CSS animations across search dialogs and navigation menus.

Sources: [packages/radix-ui/src/components/dialog/search.tsx:268-296](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/dialog/search.tsx#L268-L296), [packages/radix-ui/src/components/ui/scroll-area.tsx:1-17](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/scroll-area.tsx#L1-L17), [packages/radix-ui/src/components/ui/popover.tsx:1-30](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/popover.tsx#L1-L30), [packages/radix-ui/src/components/ui/accordion.tsx:1-17](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/accordion.tsx#L1-L17), [packages/radix-ui/src/components/ui/collapsible.tsx:1-34](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/collapsible.tsx#L1-L34), [packages/radix-ui/src/components/ui/navigation-menu.tsx:1-69](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/navigation-menu.tsx#L1-L69)

## Scroll area primitive and viewport scrolling

### Component API and DOM Structure

The scroll area primitive wraps `@radix-ui/react-scroll-area` primitives to construct custom styled viewports and scrollbars across documentation sidebars and scrollable containers. The public exports consist of `ScrollArea`, `ScrollViewport`, and `ScrollBar`, along with helper abstractions such as `SidebarViewport` that structure vertical lists and page trees with fade masks and containment rules.

```typescript
export function ScrollArea({
  className,
  children,
  ...props
}: React.ComponentPropsWithRef<typeof Primitive.Root>) {
  return (
    <Primitive.Root type="scroll" className={cn('overflow-hidden', className)} {...props}>
      {children}
      <Primitive.Corner />
      <ScrollBar orientation="vertical" />
    </Primitive.Root>
  );
}
```
Sources: [packages/radix-ui/src/components/ui/scroll-area.tsx:5-17](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/scroll-area.tsx#L5-L17)

The underlying component renders a root container with hidden overflow, automatically appending a corner piece and a vertical scrollbar instance. Inside this structure, `ScrollViewport` manages the inner scrolling container with full sizing, inherited border radius, and utility modifier classes.

```typescript
export function ScrollViewport({
  className,
  children,
  ...props
}: React.ComponentPropsWithRef<typeof Primitive.Viewport>) {
  return (
    <Primitive.Viewport className={cn('size-full rounded-[inherit]', className)} {...props}>
      {children}
    </Primitive.Viewport>
  );
}
```
Sources: [packages/radix-ui/src/components/ui/scroll-area.tsx:19-29](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/scroll-area.tsx#L19-L29)

The scrollbar sub-component supports both vertical and horizontal orientations, applying dynamic width or height constraints and fade-out transition animations via data states.

```typescript
export function ScrollBar({
  className,
  orientation = 'vertical',
  ...props
}: React.ComponentPropsWithRef<typeof Primitive.Scrollbar>) {
  return (
    <Primitive.Scrollbar
      orientation={orientation}
      className={cn(
        'flex select-none data-[state=hidden]:animate-fd-fade-out',
        orientation === 'vertical' && 'h-full w-1.5',
        orientation === 'horizontal' && 'h-1.5 flex-col',
        className,
      )}
      {...props}
    >
      <Primitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-fd-border" />
    </Primitive.Scrollbar>
  );
}
```
Sources: [packages/radix-ui/src/components/ui/scroll-area.tsx:31-50](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/scroll-area.tsx#L31-L50)

| Component Name | Radix Underlying Primitive | Default Class Names / Styles | Purpose |
| --- | --- | --- | --- |
| `ScrollArea` | `Primitive.Root` | `overflow-hidden` | Root wrapper providing scroll context, corner element, and default vertical scrollbar. |
| `ScrollViewport` | `Primitive.Viewport` | `size-full rounded-[inherit]` | Scrollable content container matching parent boundaries and inheritance. |
| `ScrollBar` | `Primitive.Scrollbar` | `flex select-none data-[state=hidden]:animate-fd-fade-out` | Track container handling orientation styles and thumb rendering. |
| `ScrollAreaThumb` | `Primitive.ScrollAreaThumb` | `relative flex-1 rounded-full bg-fd-border` | Draggable thumb indicator inside the scrollbar track. |

Sources: [packages/radix-ui/src/components/ui/scroll-area.tsx:1-50](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/scroll-area.tsx#L1-L50)

> [!NOTE]
> `ScrollViewport` applies `overscroll-contain` and linear gradient mask utilities when composed inside `SidebarViewport`, preventing scroll chaining to the main document body while fading overflowing edge contents.
> Sources: [packages/radix-ui/src/components/sidebar/base.tsx:185-207](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/sidebar/base.tsx#L185-L207)

### Execution Walkthrough and Component Composition

```mermaid
sequenceDiagram
  participant Sidebar as Sidebar
  participant SidebarViewport as SidebarViewport
  participant ScrollArea as ScrollArea
  participant ScrollBar as ScrollBar

  Sidebar->>SidebarViewport: Renders menu items and page tree inside container
  SidebarViewport->>ScrollArea: Wraps children with <ScrollArea min-h-0 flex-1>
  ScrollArea->>ScrollBar: Appends <ScrollViewport> and <ScrollBar orientation="vertical">
  ScrollBar->>ScrollBar: Renders <Primitive.Scrollbar> and <Primitive.ScrollAreaThumb>
```
Sources: [packages/radix-ui/src/components/sidebar/base.tsx:185-207](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/sidebar/base.tsx#L185-L207), [packages/radix-ui/src/layouts/flux/slots/sidebar.tsx:64-81](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/layouts/flux/slots/sidebar.tsx#L64-L81)

The rendering pipeline flows through structured sidebar components down to the primitive scrollbar.
1. `Sidebar` initiates composition by rendering banners, navigation links, and page trees.
Sources: [packages/radix-ui/src/layouts/flux/slots/sidebar.tsx:64-81](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/layouts/flux/slots/sidebar.tsx#L64-L81)
2. `SidebarViewport` receives the elements and injects them into `ScrollArea` with flex sizing.
Sources: [packages/radix-ui/src/components/sidebar/base.tsx:185-207](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/sidebar/base.tsx#L185-L207)
3. `ScrollArea` encapsulates the viewport with `Primitive.Root`, establishing overflow rules and default corner elements.
Sources: [packages/radix-ui/src/components/ui/scroll-area.tsx:5-17](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/scroll-area.tsx#L5-L17)
4. `ScrollBar` configures orientation (`vertical` or `horizontal`) and populates the track with a styled `Primitive.ScrollAreaThumb`.
Sources: [packages/radix-ui/src/components/ui/scroll-area.tsx:31-50](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/scroll-area.tsx#L31-L50)

> [!WARNING]
> Omitting `SidebarViewport` in custom sidebar layouts breaks vertical flex constraints (`min-h-0 flex-1`), causing long documentation trees to overflow outside visible viewport bounds.
> Sources: [packages/radix-ui/src/components/sidebar/base.tsx:185-207](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/sidebar/base.tsx#L185-L207)

## Popover primitive for contextual overlays

### Component API and Primitives

The popover component architecture builds upon `@radix-ui/react-popover` primitives, supplying wrapper exports and customized content rendering. The exposed exports map directly to root, trigger, content, and close subcomponents.

| Component Export | Underlying Radix Primitive | Default Configuration / Props | Purpose |
| --- | --- | --- | --- |
| `Popover` | `PopoverPrimitive.Root` | None | Root context provider managing open and closed state for the popover layer. |
| `PopoverTrigger` | `PopoverPrimitive.Trigger` | None | Interactive toggle element that opens or closes the popover panel. |
| `PopoverContent` | `PopoverPrimitive.Content` | `align = 'center'`, `sideOffset = 4`, `side = 'bottom'` | Portal-wrapped floating overlay panel containing customized positioning and styling. |
| `PopoverClose` | `PopoverPrimitive.PopoverClose` | None | Action element that triggers closing of the active popover panel. |

Sources: [packages/radix-ui/src/components/ui/popover.tsx:1-32](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/popover.tsx#L1-L32)

### Styling and Content Layout

`PopoverContent` wraps its elements in `PopoverPrimitive.Portal` and `PopoverPrimitive.Content`, applying default alignment and offset settings. The styling uses utility classes for z-index stacking, layout constraints, backdrop filters, and open/closed animations.

```tsx
className={cn(
  'z-50 origin-(--radix-popover-content-transform-origin) overflow-y-auto max-h-(--radix-popover-content-available-height) min-w-[240px] max-w-[98vw] rounded-xl border bg-fd-popover/60 backdrop-blur-lg p-2 text-sm text-fd-popover-foreground shadow-lg focus-visible:outline-none data-[state=closed]:animate-fd-popover-out data-[state=open]:animate-fd-popover-in',
  className,
)}
{...props}
```
Sources: [packages/radix-ui/src/components/ui/popover.tsx:22-26](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/popover.tsx#L22-L26)

> [!NOTE]
> `PopoverContent` forces `side="bottom"` by default while inheriting custom `align` and `sideOffset` props, ensuring predictable dropdown placement beneath trigger buttons across documentation overlays.
> Sources: [packages/radix-ui/src/components/ui/popover.tsx:10-21](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/popover.tsx#L10-L21)

> [!WARNING]
> Omitting `PopoverPrimitive.Portal` when wrapping custom popover structures causes content panels to clip within parent containers that have `overflow: hidden` or restricted bounding boxes.
> Sources: [packages/radix-ui/src/components/ui/popover.tsx:17-28](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/popover.tsx#L17-L28)

## Collapsible triggers and expandable sections

### Primitive Exports and Component API

The collapsible component architecture builds upon `@radix-ui/react-collapsible` primitives to drive accessible disclosure panels and folder hierarchies within documentation sidebars. The components exported by the wrapper module expose underlying Radix primitives while injecting custom animation classes and mounting states.

| Component Export | Underlying Radix Primitive | Purpose |
| --- | --- | --- |
| `Collapsible` | `Primitive.Root` | Root container managing open and closed state for expandable sections. |
| `CollapsibleTrigger` | `Primitive.CollapsibleTrigger` | Interactive control element toggling the expanded or collapsed state. |
| `CollapsibleContent` | `Primitive.CollapsibleContent` | Animated container wrapper holding collapsible content sections. |

Sources: [packages/radix-ui/src/components/ui/collapsible.tsx:7-14](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/collapsible.tsx#L7-L14)

### Animation and Mounting State

`CollapsibleContent` manages client-side hydration and enter/exit animations by tracking a local `mounted` state via `useState` and `useEffect`. Once mounted, the component applies conditional keyframe animations (`animate-fd-collapsible-up` and `animate-fd-collapsible-down`) governed by the current `data-[state]` attribute.

```tsx
export function CollapsibleContent({
  children,
  ...props
}: React.ComponentPropsWithRef<typeof Primitive.CollapsibleContent>) {
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);
  }, []);

  return (
    <Primitive.CollapsibleContent
      {...props}
      className={cn(
        'overflow-hidden',
        mounted &&
          'data-[state=closed]:animate-fd-collapsible-up data-[state=open]:animate-fd-collapsible-down',
        props.className,
      )}
    >
      {children}
    </Primitive.CollapsibleContent>
  );
}
```
Sources: [packages/radix-ui/src/components/ui/collapsible.tsx:11-34](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/collapsible.tsx#L11-L34)

> [!NOTE]
> `CollapsibleContent` delays application of collapse and expand animations until after initial client mount, preventing unwanted transition flashes during SSR hydration.
> Sources: [packages/radix-ui/src/components/ui/collapsible.tsx:15-29](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/collapsible.tsx#L15-29)

> [!WARNING]
> Omitting `overflow-hidden` on `CollapsibleContent` causes inner child elements to overflow their bounds during the collapse and expansion height transition phases.
> Sources: [packages/radix-ui/src/components/ui/collapsible.tsx:24-26](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/collapsible.tsx#L24-L26)

## Accordion wrappers and expandable panels

### Component Composition and Primitives

The accordion architecture builds upon `@radix-ui/react-accordion` primitives to provide multi-item expandable panels with copy-link capabilities, keyboard navigation support, and hash-based anchor integration. The base primitives are re-exported and wrapped across specialized UI files to configure styling, layout, and interaction handlers.

| Component Export | Underlying Primitive / Module | Purpose |
| --- | --- | --- |
| `Accordions` | `Primitive.Root` | Root container managing single or multiple selection modes and state synchronization. |
| `Accordion` | `AccordionItem` wrapper | High-level wrapper combining an item, header, trigger, optional copy button, and content block. |
| `AccordionItem` | `Primitive.Item` | Individual collapsible container section with scroll margin alignment. |
| `AccordionHeader` | `Primitive.Header` | Header element managing layout, typography, and focus ring styling. |
| `AccordionTrigger` | `Primitive.Trigger` | Interactive toggle control featuring a rotating chevron icon and accessible triggers. |
| `AccordionContent` | `Primitive.Content` | Animated container holding collapsible panel contents with height transition classes. |

Sources: [packages/radix-ui/src/components/ui/accordion.tsx:8-84](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/accordion.tsx#L8-L84), [packages/radix-ui/src/components/accordion.tsx:11-81](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/accordion.tsx#L11-L81)

### State Management and Hash Navigation

`Accordions` initializes its state based on the configured `type` prop, defaulting to `'single'` with collapsible behavior enabled. On initial mount, an effect inspects `window.location.hash`, matches the element ID against the accordion tree, reads its `data-accordion-value` attribute, and automatically expands the corresponding panel.

```tsx
export function Accordions({
  type = 'single',
  ref,
  className,
  defaultValue,
  ...props
}: ComponentProps<typeof Root>) {
  const rootRef = useRef<HTMLDivElement>(null);
  const composedRef = mergeRefs(ref, rootRef);
  const [value, setValue] = useState<string | string[]>(() =>
    type === 'single' ? (defaultValue ?? '') : (defaultValue ?? []),
  );

  useEffect(() => {
    const id = window.location.hash.substring(1);
    const element = rootRef.current;
    if (!element || id.length === 0) return;

    const selected = document.getElementById(id);
    if (!selected || !element.contains(selected)) return;
    const value = selected.getAttribute('data-accordion-value');

    if (value) setValue((prev) => (typeof prev === 'string' ? value : [value, ...prev]));
  }, []);
```
Sources: [packages/radix-ui/src/components/accordion.tsx:18-41](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/accordion.tsx#L18-L41)

> [!NOTE]
> When `type` is set to `'single'`, `Accordions` forces `collapsible={true}` on the root primitive, allowing users to collapse all open panels by clicking the active trigger again.
> Sources: [packages/radix-ui/src/components/accordion.tsx:45-50](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/accordion.tsx#L45-L50)

> [!WARNING]
> Omitting the `data-accordion-value` attribute on `AccordionHeader` prevents hash-based URL navigation from automatically expanding target panels on page load.
> Sources: [packages/radix-ui/src/components/accordion.tsx:32-40](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/accordion.tsx#L32-L40)

## Search dialog modal structure

### Search Dialog Modal Structure and Primitives

The search dialog modal architecture relies on `@radix-ui/react-dialog` primitives alongside specialized components to render accessible modal overlays, dialog content wrappers, animated list containers, and keyboard-navigational list items.

| Component Export | Underlying Primitive / Module | Purpose |
| --- | --- | --- |
| `SearchDialogContent` | `DialogContent` wrapper | Renders the primary search container with centered positioning, width clamping, and entrance/exit animation hooks. |
| `SearchDialogOverlay` | `DialogOverlay` wrapper | Provides a fixed backdrop layer featuring blur styling and open/closed fade animations. |
| `SearchDialogList` | DOM `div` container | Manages active item indexes, keyboard arrow navigation, enter key selection, and dynamic height observers. |
| `SearchDialogListItem` | DOM `button` element | Renders individual search result options, supporting custom markdown formatting, icons, and breadcrumb trails. |
| `SearchDialogFooter` | DOM `div` container | Renders a styled container at the bottom of the dialog that hides itself automatically when empty. |

Sources: [packages/radix-ui/src/components/dialog/search.tsx:264-417](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/dialog/search.tsx#L264-L417), [packages/api-docs/src/components/dialog.tsx:3-17](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/api-docs/src/components/dialog.tsx#L3-L17)

### Keyboard Navigation and Focus Management

`SearchDialogList` registers a global keydown event listener through an effect event hook (`onKey`) to capture keyboard navigation events without re-subscribing on every render change. When `ArrowDown` or `ArrowUp` events fire, it computes the newly active item identifier based on the current index relative to the total items length, while `Enter` triggers the selection callback for the active item.

```tsx
const onKey = useEffectEvent((e: KeyboardEvent) => {
  if (!items || e.isComposing) return;

  if (e.key === 'ArrowDown' || e.key == 'ArrowUp') {
    let idx = items.findIndex((item) => item.id === active);
    if (idx === -1) idx = 0;
    else if (e.key === 'ArrowDown') idx++;
    else idx--;

    setActive(items.at(idx % items.length)?.id ?? null);
    e.preventDefault();
  }

  if (e.key === 'Enter') {
    const selected = items.find((item) => item.id === active);

    if (selected) onSelect(selected);
    e.preventDefault();
  }
});
```
Sources: [packages/radix-ui/src/components/dialog/search.tsx:325-344](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/dialog/search.tsx#L325-L344)

> [!NOTE]
> `SearchDialogContent` explicitly sets `aria-describedby={undefined}` and injects a hidden `DialogTitle` component containing translated search strings to satisfy accessibility requirements without disrupting visual layouts.
> Sources: [packages/radix-ui/src/components/dialog/search.tsx:283-294](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/dialog/search.tsx#L283-294)

> [!WARNING]
> Ignoring `e.isComposing` inside the keyboard handler can cause unintended list item cycling while users are actively typing composition characters with an Input Method Editor (IME).
> Sources: [packages/radix-ui/src/components/dialog/search.tsx:326-326](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/dialog/search.tsx#L326-L326)

## Select dropdowns and navigation menus

### Select Dropdown Component Architecture

Form selection controls are built on top of `@radix-ui/react-select` primitives, offering robust keyboard navigation, dropdown portals, scrollable item viewports, and item indicators. The component architecture exposes granular parts including root, group, value, trigger, content, label, item, separator, and scroll buttons.

| Component Export | Underlying Primitive | Purpose |
| --- | --- | --- |
| `Select` | `SelectPrimitive.Root` | Manages selection state and context for the entire dropdown control. |
| `SelectGroup` | `SelectPrimitive.Group` | Groups related select items together semantically. |
| `SelectValue` | `SelectPrimitive.Value` | Renders the currently selected option inside the trigger. |
| `SelectTrigger` | `SelectPrimitive.Trigger` | Renders the interactive button wrapper with layout styling, focus rings, disabled states, and a trailing `ChevronDown` icon. |
| `SelectContent` | `SelectPrimitive.Content` | Portals and wraps dropdown options in a popover container complete with viewport clipping and scroll buttons. |
| `SelectItem` | `SelectPrimitive.Item` | Represents an individual selectable option, pairing item text with an option check indicator. |
| `SelectSeparator` | `SelectPrimitive.Separator` | Renders a styled divider line between option groups or items. |
| `SelectScrollUpButton` / `SelectScrollDownButton` | `SelectPrimitive.ScrollUpButton` / `ScrollDownButton` | Provides scroll navigation triggers equipped with chevron icons when content overflows the viewport height. |

Sources: [packages/api-docs/src/components/select.tsx:6-124](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/api-docs/src/components/select.tsx#L6-L124), [packages/story/src/client/components/select.tsx:7-139](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/story/src/client/components/select.tsx#L7-L139)

### Navigation Menu Integration and Motion Variants

Responsive header navigation utilizes `@radix-ui/react-navigation-menu` primitives to deliver accessible dropdown panels and menu links. `NavigationMenuContent` applies absolute positioning, `fd-scroll-container` scroll handling, a maximum height constraint of `80svh`, and motion-driven data attributes for directional entry and exit animations (`data-[motion=from-end]`, `data-[motion=from-start]`, `data-[motion=to-end]`, `data-[motion=to-start]`).

```tsx
export function NavigationMenuContent({
  className,
  ...props
}: React.ComponentPropsWithRef<typeof Primitive.Content>) {
  return (
    <Primitive.Content
      className={cn(
        'absolute inset-x-0 top-0 overflow-auto fd-scroll-container max-h-[80svh] data-[motion=from-end]:animate-fd-enterFromRight data-[motion=from-start]:animate-fd-enterFromLeft data-[motion=to-end]:animate-fd-exitToRight data-[motion=to-start]:animate-fd-exitToLeft',
        className,
      )}
      {...props}
    />
  );
}
```
Sources: [packages/radix-ui/src/components/ui/navigation-menu.tsx:37-50](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/navigation-menu.tsx#L37-L50)

> [!NOTE]
> `NavigationMenuViewport` wraps the Radix viewport primitive inside a centered flex container and binds height transition variables to `--radix-navigation-menu-viewport-height` alongside open and closed animation classes.
> Sources: [packages/radix-ui/src/components/ui/navigation-menu.tsx:54-69](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/navigation-menu.tsx#L54-69)

> [!WARNING]
> Failing to wrap navigation menu content items in list-none item containers can introduce unexpected bullet point styling and layout distortions across different browser engines.
> Sources: [packages/radix-ui/src/components/ui/navigation-menu.tsx:13-23](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/radix-ui/src/components/ui/navigation-menu.tsx#L13-23)

## Related

- [Base UI Components](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/ui-layouts/base-ui-components)
- [Shared Layout Architecture](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/ui-layouts/shared-layout-architecture)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/llms.txt) for all pages in this wiki.
