# Component Building Guidelines **Version 1.0.0** Shadcraft January 2026 > **Note:** > This document is mainly for agents and LLMs to follow when building, > generating, or refactoring registry components. Humans may also find it > useful, but guidance here is optimized for automation and consistency by > AI-assisted workflows. --- ## Abstract Comprehensive component authoring guide for building registry components that follow shadcn/ui patterns. Contains 10 rules covering composition, accessibility, state management, design tokens, styling, TypeScript patterns, polymorphism, asChild, data attributes, and documentation. Each rule includes DO/DON'T patterns with references to components.build guides. --- ## Table of Contents 1. [Composition](#1-composition) 2. [Accessibility](#2-accessibility) 3. [State Management](#3-state-management) 4. [Design Tokens](#4-design-tokens) 5. [Styling Patterns](#5-styling-patterns) 6. [TypeScript Patterns](#6-typescript-patterns) 7. [Polymorphism](#7-polymorphism) 8. [asChild Pattern](#8-aschild-pattern) 9. [Data Attributes](#9-data-attributes) 10. [Component Documentation](#10-component-documentation) --- ## 1. Composition Component composition patterns for building flexible, reusable components. ### DO - Default to **shadcn/ui + Radix primitives** for UI building blocks; compose them into registry blocks instead of rebuilding primitives. - Use composition to avoid "one component with dozens of props". Composition distributes responsibility across cooperating components instead of cramming functionality into a single component. ([components.build/composition](https://www.components.build/composition)) - When a component needs to be composable, split it into focused parts (typical pattern from the guide): - **Root**: container that holds everything and owns shared state (often via React context) - **Item**: wrapper for a single item - **Trigger**: interactive element that toggles state (button by default; may support `asChild`) - **Content**: element that shows/hides content based on state - Follow the naming conventions called out in the guide (used by shadcn/ui and Radix UI): ([components.build/composition](https://www.components.build/composition)) - **Root**, **Trigger**, **Content** - **Header**, **Body**, **Footer** - **Title**, **Description** - When creating your own composable "mini-library" inside a registry block: - Use context to share state (ex: `open` + `setOpen`) from Root to children. - Extend native element props using `React.ComponentProps<'div'>`, `React.ComponentProps<'button'>`, etc. so consumers can customize the underlying elements. - Keep each exported component close to "one component = one element" (ties into the Types guidance). ([components.build/types](https://www.components.build/types)) ### DON'T - Don't ship monolithic "data-driven" components that accept `data` and own all rendering/state/styling; the composition guide explicitly calls out that this couples responsibilities and makes customization difficult. ([components.build/composition](https://www.components.build/composition)) - Don't invent a new naming scheme for subcomponents when established patterns exist (Root/Trigger/Content, etc.). - Don't rebuild shadcn primitives (Button, Dialog, DropdownMenu, Tabs, etc.) just to re-learn accessibility/state — compose the primitives and only add custom composition when primitives don't cover the use case. --- ## 2. Accessibility Accessibility requirements for building inclusive, usable components. ### DO - Default to **shadcn/ui + Radix primitives** for interactive UI. They come with accessibility behaviors (roles, keyboard interaction, focus management) baked in; don't re-implement them in registry blocks. - When you must build something not covered by primitives, follow the **core principles** from the Accessibility guide. ([components.build/accessibility](https://www.components.build/accessibility)) - **Semantic HTML first**: start with the most appropriate element (ex: use `