radix-ui-design-system

$npx mdskill add tranhieutt/software_development_department/radix-ui-design-system

Build accessible design systems with Radix UI headless components.

  • Prevents nested button DOM errors by enforcing asChild on Trigger.
  • Depends on Radix UI primitives and Framer Motion for animations.
  • Recommends forceMount for exit animations and Portal for dropdown positioning.
  • Delivers accessible dialog patterns with required Title and Description.

SKILL.md

.github/skills/radix-ui-design-systemView on GitHub ↗
---
name: radix-ui-design-system
type: reference
description: "Provides Radix UI patterns for building accessible design systems with headless components, theming, and compound component architecture. Use when building UI with Radix UI primitives or when the user mentions Radix UI, headless components, or accessible component libraries."
paths: ["**/*.tsx", "**/*.jsx", "**/components.json"]
when_to_use: "When building accessible component libraries with Radix UI primitives, headless components, or design system theming"
allowed-tools: Read, Glob, Grep, Write, Edit, Bash
user-invocable: true
effort: 3
---

# Radix UI Design System

## Critical rules (non-obvious)

- **Always use `asChild`** on Trigger/Close — prevents nested `<button>` inside `<button>` DOM errors
- **Always include `<Dialog.Title>` and `<Dialog.Description>`** — screen readers require them; omitting causes a11y violations
- **Never mix controlled + uncontrolled** — don't use both `defaultValue` and `value` on same component
- **Animations need `forceMount`** — without it Portal unmounts instantly, killing Framer Motion exit animations
- **Dropdown positioning off?** — parent has `overflow: hidden` or CSS transform; always wrap in `<Portal>`

## Core pattern: Dialog

```tsx
<Dialog.Root open={open} onOpenChange={setOpen}>
  <Dialog.Trigger asChild><button>Open</button></Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay className="overlay" />
    <Dialog.Content className="content">
      <Dialog.Title>Title</Dialog.Title>       {/* required */}
      <Dialog.Description>Desc</Dialog.Description> {/* required */}
      <Dialog.Close asChild><button>Close</button></Dialog.Close>
    </Dialog.Content>
  </Dialog.Portal>
</Dialog.Root>
```

## Theming: CSS variables (recommended)

```css
:root { --color-primary: 220 90% 56%; --radius: 0.5rem; }
[data-theme="dark"] { --color-primary: 220 90% 66%; }
```
```tsx
<Dialog.Content className="bg-[hsl(var(--color-primary))] rounded-[var(--radius)]" />
```

## Theming: CVA for variants

```tsx
import { cva } from 'class-variance-authority';
const button = cva("base-styles", {
  variants: {
    variant: { default: "bg-primary", destructive: "bg-red-500" },
    size: { sm: "h-9 px-3", md: "h-10 px-4" },
  },
  defaultVariants: { variant: "default", size: "md" },
});
```

## Animation with Framer Motion

```tsx
<Dialog.Portal forceMount>           {/* forceMount: critical */}
  <AnimatePresence>
    {open && (
      <Dialog.Overlay asChild>
        <motion.div initial={{opacity:0}} animate={{opacity:1}} exit={{opacity:0}} />
      </Dialog.Overlay>
    )}
  </AnimatePresence>
</Dialog.Portal>
```

## Hook form integration (Select)

```tsx
<Controller name="country" control={control} render={({ field }) => (
  <Select.Root onValueChange={field.onChange} value={field.value}>
    <Select.Trigger><Select.Value placeholder="Select..." /><Select.Icon /></Select.Trigger>
    <Select.Portal>
      <Select.Content><Select.Viewport>
        <Select.Item value="us"><Select.ItemText>US</Select.ItemText></Select.Item>
      </Select.Viewport></Select.Content>
    </Select.Portal>
  </Select.Root>
)} />
```

## Primitives quick reference

| Component    | Key parts |
|---|---|
| Dialog       | Root · Trigger · Portal · Overlay · Content · Title · Description · Close |
| DropdownMenu | Root · Trigger · Portal · Content · Item · Separator · CheckboxItem · RadioGroup · Sub |
| Tabs         | Root · List · Trigger · Content |
| Tooltip      | Provider · Root · Trigger · Portal · Content · Arrow |
| Select       | Root · Trigger · Value · Icon · Portal · Content · Viewport · Item · ItemText · ItemIndicator |

## shadcn vs raw Radix

- **shadcn**: quick prototyping, standard designs; run `npx shadcn@latest add dialog`
- **Raw Radix**: full customization, unique designs, zero-dependency component library

More from tranhieutt/software_development_department

SkillDescription
agent-healthReads production/traces/agent-metrics.jsonl and displays a per-agent performance summary table for the current or a specified session. Highlights agents with high error rates or OPEN circuit breaker state.
agent-styleProvides the vendored agent-style v0.3.5 prose rule pack as a portable Claude skill. Use when installing, syncing, applying, or auditing SDD Agent-Style support in another project, or when a style-review workflow needs the bundled rules.
angular-best-practicesProvides Angular best practices for components, modules, services, and reactive patterns. Use when working with Angular TypeScript files, component templates, NgModules, RxJS observables, or when the user mentions Angular, ng, or Angular CLI.
annotateRecords unexpected API behaviors, undocumented caveats, version bugs, or non-obvious workarounds into .claude/memory/annotations.md. Use immediately when an undocumented behavior or surprising caveat is discovered during development.
aws-serverlessProvides AWS serverless architecture patterns for Lambda, API Gateway, DynamoDB, SQS, and SAM/CDK. Use when working with AWS serverless files (serverless.yml, CDK stacks) or when the user mentions Lambda, API Gateway, serverless, or AWS SAM.
backend-architectDesigns scalable backend architectures covering microservices, event-driven systems, API gateways, and data stores. Use when designing a backend system or when the user mentions backend architecture, scalability, or distributed systems.
cloud-run-puppeteerDeploys Puppeteer browser automation on Google Cloud Run with Docker. Use when running headless browser tasks on Cloud Run, or when the user mentions Cloud Run, Puppeteer, headless Chrome, or serverless browser automation.
codex-sddAdapts SDD for Codex while preserving Claude Code behavior. Use when working in Codex, setting up Codex compatibility, mapping Claude tools to Codex tools, or explaining how SDD should run outside Claude Code.
database-architectDesigns relational and NoSQL database schemas, indexing strategies, migration plans, and data modeling patterns. Use when designing a database or when the user mentions database architecture, schema design, or data modeling.
db-reviewReviews database schemas, queries, and migrations for correctness, performance, security, and best practices. Use when reviewing SQL migration files or when the user mentions database review, schema review, or query audit.