Receber por email
← Voltar para o catálogo

web-ui-radix-ui

Unstyled accessible UI primitives

11estrelas
Atualizado há 7 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add agents-inc/skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/web-ui-radix-ui/svg)](https://www.skillteca.com.br/skills/web-ui-radix-ui)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Radix UI Primitives

Quick Guide: Radix UI provides unstyled, accessible primitives for building design systems. Use compound component patterns (Root, Trigger, Content), asChild for polymorphism, and data-state attributes for animations. Focus on behavior and accessibility - defer styling decisions to your styling solution. Current: v1.4.x (May 2025) - Full React 19 and RSC compatibility with new preview primitives.

<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST use compound component anatomy - Root, Trigger, Portal, Content, Close - for overlay components)

(You MUST use forwardRef and spread all props when using asChild with custom components - unless using React 19+ where ref is a regular prop)

(You MUST use Portal for overlays to escape CSS stacking contexts and parent overflow constraints)

(You MUST provide accessible labels via Title/Description components or ARIA attributes - Dialog logs console errors for missing Title)

</critical_requirements>

Auto-detection: Radix UI, radix-ui, @radix-ui, Dialog, Dropdown, DropdownMenu, Select, Popover, Tooltip, Accordion, Tabs, AlertDialog, asChild, Slot, Portal, data-state, OneTimePasswordField, PasswordToggleField, unstable_Form, Form.Field, Form.Message

When to use:

  • Building accessible overlay components (dialogs, popovers, dropdowns, tooltips)
  • Creating compound component APIs with multiple coordinated parts
  • Implementing keyboard navigation and focus management
  • Needing polymorphic components via asChild pattern

When NOT to use:

  • Pre-styled components desired (use a component library built on Radix)
  • Simple components without complex interactions (use plain HTML)
  • Non-React projects (Radix primitives are React-specific)

Package Installation:

# Recommended: Unified tree-shakeable package (prevents version conflicts)
npm i radix-ui

# Alternative: Individual packages
npm i @radix-ui/react-dialog @radix-ui/react-dropdown-menu

Detailed Resources:

  • For core code examples (Dialog, asChild, Slot), see [examples/core.md](examples/core.md)
  • For overlay patterns (AlertDialog, controlled Dialog), see [examples/overlays.md](examples/overlays.md)
  • For menu patterns (DropdownMenu, submenus), see [examples/menus.md](examples/menus.md)
  • For animation patterns (data-state, CSS keyframes), see [examples/animation.md](examples/animation.md)
  • For form patterns (Select), see [examples/forms.md](examples/forms.md)
  • For navigation patterns (Accordion, Tabs), see [examples/navigation.md](examples/navigation.md)
  • For preview components (OneTimePasswordField, PasswordToggleField), see [examples/preview.md](examples/preview.md)
  • For decision frameworks and anti-patterns, see [reference.md](reference.md)

<philosophy>

Philosophy

Radix UI Primitives provide behavioral and accessibility foundations without imposing visual design. Each primitive handles:

  • Accessibility: ARIA attributes, roles, keyboard navigation, focus management
  • Behavior: Open/close state, dismissal patterns, collision detection
  • Composition: Compound components that work together as coordinated systems

Radix is styling-agnostic: Apply styles via className prop using your styling solution. The primitives expose data-state attributes for state-based styling.

Compound Component Model: Each primitive consists of multiple parts (Root, Trigger, Content, etc.) that share context. This enables flexible composition while maintaining coordinated behavior.

React 19 & RSC Support (v1.4.3): Full compatibility with React 19 and React Server Components. Enhanced keyboard handling avoids browser hotkey interference.

</philosophy>

<patterns>

Core Patterns

Pattern 1: Compound Component Anatomy

Radix primitives use a compound component pattern where multiple parts work together through shared context.

Standard Structure for Overlay Components

import { Dialog } from "radix-ui";

// Root provides context and state management
// Trigger opens the dialog
// Portal renders content outside React tree
// Overlay covers the page
// Content contains the dialog body
// Close dismisses the dialog
// Title and Description provide accessibility

<Dialog.Root>
  <Dialog.Trigger>Open</Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay className={className} />
    <Dialog.Content className={className}>
      <Dialog.Title>Dialog Title</Dialog.Title>
      <Dialog.Description>Accessible description</Dialog.Description>
      {/* Dialog content */}
      <Dialog.Close>Close</Dialog.Close>
    </Dialog.Content>
  </Dialog.Portal>
</Dialog.Root>

Why this structure: Root manages state and context, Portal escapes CSS stacking contexts, Overlay provides visual backdrop, Title/Description ensure screen reader accessibility

Pattern 2: Controlled vs Uncontrolled State

Radix primitives support both controlled and uncontrolled state patterns.

Uncontrolled (Radix Manages State)

// Let Radix manage internal state - simpler for basic use cases
<Dialog.Root defaultOpen={false}>
  <Dialog.Trigger>Open</Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Content>
      {/* Content */}
    </Dialog.Content>
  </Dialog.Portal>
</Dialog.Root>

When to use: Simple dialogs without external state requirements

Controlled (You Manage State)

import { useState } from "react";
import { Dialog } from "radix-ui";

function ControlledDialog() {
  const [open, setOpen] = useState(false);

  const handleSave = async () => {
    await saveData();
    setOpen(false); // Programmatically close after async operation
  };

  return (
    <Dialog.Root open={open} onOpenChange={setOpen}>
      <Dialog.Trigger>Open</Dialog.Trigger>
      <Dialog.Portal>
        <Dialog.Content>
          <Dialog.Title>Edit Profile</Dialog.Title>
          <button onClick={handleSave}>Save</button>
        </Dialog.Content>
      </Dialog.Portal>
    </Dialog.Root>
  );
}

When to use: Programmatic control needed (close after async, open from external trigger, sync with URL state)

Pattern 3: asChild for Polymorphism

The asChild prop enables Radix to merge behavior onto your custom components or different element types.

Changing Element Type

import { Tooltip } from "radix-ui";

// Tooltip trigger defaults to button, but you may want a link
<Tooltip.Root>
  <Tooltip.Trigger asChild>
    <a href="/docs">Documentation</a>
  </Tooltip.Trigger>
  <Tooltip.Portal>
    <Tooltip.Content>View the docs</Tooltip.Content>
  </Tooltip.Portal>
</Tooltip.Root>

Why good: Radix passes all required props and event handlers to the anchor, maintaining accessibility

With Custom Components

import { forwardRef } from "react";
import { Dialog } from "radix-ui";

// Custom component MUST use forwardRef and spread props
const CustomButton = forwardRef<HTMLButtonElement, React.ComponentProps<"button">>(
  ({ className, ...props }, ref) => {
    return <button ref={ref} className={className} {...props} />;
  }
);
CustomButton.displayName = "CustomButton";

// Use with asChild
<Dialog.Trigger asChild>
  <CustomButton className="custom-class">Open Dialog</CustomButton>
</Dialog.Trigger>

Why this works: forwardRef allows Radix to attach refs for positioning/focus, spreading props passes event handlers and ARIA attributes

Pattern 4: Building Custom asChild Components with Slot

Use the Slot utility to build your own components with asChild support.

import { forwardRef } from "react";
import { Slot } from "radix-ui";

export type ButtonProps = React.ComponentProps<"button"> & {
  asChild?: boolean;
};

export const Button = forwardRef<HTMLButtonElement, Button
Compartilhar X LinkedIn