AgentSkillsCN

radix-primitives

Radix UI 无样式、可访问的原语组件,适用于对话框、弹出框、下拉菜单等场景。当您需要构建自定义可访问组件、深入了解 shadcn 内部实现,或需要实现多态组合时,可选用此技能。

SKILL.md
--- frontmatter
name: radix-primitives
description: Radix UI unstyled accessible primitives for dialogs, popovers, dropdowns, and more. Use when building custom accessible components, understanding shadcn internals, or needing polymorphic composition.
context: fork
agent: frontend-ui-developer
version: 1.0.0
tags: [radix, ui, primitives, accessibility, dialog, popover, dropdown, aschild, a11y]
user-invocable: false

Radix Primitives

Unstyled, accessible React components for building high-quality design systems.

Overview

  • Building custom styled components with full accessibility
  • Understanding how shadcn/ui works under the hood
  • Need polymorphic composition without wrapper divs
  • Implementing complex UI patterns (modals, menus, tooltips)

Primitives Catalog

Overlay Components

PrimitiveUse Case
DialogModal dialogs, forms, confirmations
AlertDialogDestructive action confirmations
SheetSide panels, mobile drawers

Popover Components

PrimitiveUse Case
PopoverRich content on trigger
TooltipSimple text hints
HoverCardPreview cards on hover
ContextMenuRight-click menus

Menu Components

PrimitiveUse Case
DropdownMenuAction menus
MenubarApplication menubars
NavigationMenuSite navigation

Form Components

PrimitiveUse Case
SelectCustom select dropdowns
RadioGroupSingle selection groups
CheckboxBoolean toggles
SwitchOn/off toggles
SliderRange selection

Disclosure Components

PrimitiveUse Case
AccordionExpandable sections
CollapsibleSingle toggle content
TabsTabbed interfaces

Core Pattern: asChild

The asChild prop enables polymorphic rendering without wrapper divs:

tsx
// Without asChild - creates nested elements
<Button>
  <Link href="/about">About</Link>
</Button>

// With asChild - merges into single element
<Button asChild>
  <Link href="/about">About</Link>
</Button>

How it works:

  • Uses Radix's internal Slot component
  • Merges props from parent to child
  • Forwards refs correctly
  • Combines event handlers (both fire)
  • Merges classNames

Built-in Accessibility

Every primitive includes:

  • Keyboard navigation: Arrow keys, Escape, Enter, Tab
  • Focus management: Trap, return, visible focus rings
  • ARIA attributes: Roles, states, properties
  • Screen reader: Proper announcements

Styling with Data Attributes

Radix exposes state via data attributes:

css
/* Style based on state */
[data-state="open"] { /* open styles */ }
[data-state="closed"] { /* closed styles */ }
[data-disabled] { /* disabled styles */ }
[data-highlighted] { /* keyboard focus */ }
tsx
// Tailwind arbitrary variants
<Dialog.Content className="data-[state=open]:animate-in data-[state=closed]:animate-out">

Quick Reference

tsx
import { Dialog, DropdownMenu, Tooltip } from 'radix-ui'

// Basic Dialog
<Dialog.Root>
  <Dialog.Trigger>Open</Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay />
    <Dialog.Content>
      <Dialog.Title>Title</Dialog.Title>
      <Dialog.Description>Description</Dialog.Description>
      <Dialog.Close>Close</Dialog.Close>
    </Dialog.Content>
  </Dialog.Portal>
</Dialog.Root>

Key Decisions

DecisionRecommendation
Styling approachData attributes + Tailwind arbitrary variants
CompositionUse asChild to avoid wrapper divs
AnimationCSS-only with data-state selectors
Form componentsCombine with react-hook-form

Related Skills

  • shadcn-patterns - Pre-styled Radix components
  • focus-management - Accessibility patterns
  • design-system-starter - Design system foundation

References