composite-components

Guides authoring of Radix-style namespaced composite React components in DXOS UI packages.

518|49|Updated Apr 7, 2021
One-click install
npx skills add https://github.com/dxos/dxos --skill composite-components
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: composite-components
Source: https://github.com/dxos/dxos/tree/main/.agents/skills/composite-components
Command: npx skills add https://github.com/dxos/dxos --skill composite-components

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Teams building UI libraries in @dxos/react-ui need consistent conventions for creating namespaced composite components like Dialog.Root and Dialog.Trigger, and this Skill codifies the exact patterns, naming rules, and theme integration so every composite follows the same structure.

Core Features & Use Cases

  • Two construction styles: Choose between slottable()/composable() for pure DXOS parts and forwardRef wrapping for Radix primitive parts, with clear rules on when each applies.
  • Naming and structure rules: Enforces prefixed internal names, dotted displayName values, object-literal namespace assembly, and exported Props types for every part.
  • Theme integration: Routes classNames through the tx() theme function with composableProps reconciliation and sibling Foo.theme.ts token files.
  • Use Case: When adding a new Popover composite to react-ui, follow the exemplar files Panel.tsx and Dialog.tsx, apply the ten rules, and avoid the documented counter-examples like FunctionComponent annotations that strip ref support.

Quick Start

Ask the AI to scaffold a new composite component named Menu with Root, Trigger, and Content parts following the composite-components conventions in @dxos/react-ui.

Frequently Asked Questions about composite-components

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create a Radix-style composite component in React?

Define each part as a prefixed component like FooRoot or FooTrigger, set dotted displayName values such as 'Foo.Root', then assemble them into a namespace object literal exported as Foo. Wrap Radix primitives with forwardRef or use slottable() for plain elements.

When should I use slottable() versus forwardRef for component parts?

Use slottable() or composable() when the part renders a plain DXOS element like a div and needs asChild support. Use forwardRef when the part wraps a @radix-ui/react-* primitive that already provides ref forwarding and ARIA wiring. Never mix both styles within a single part.

Why does typing a Radix alias as FunctionComponent break ref forwarding?

Annotating an alias like const FooTrigger: FunctionComponent<Props> = FooPrimitive.Trigger strips the forwardRef type information from the primitive. Let the alias inherit the primitive's type directly so consumers retain ref support.

How do composite components handle className and theme tokens?

ClassNames flow through the tx() theme function as tx('foo.part', variants, classNames), with tokens defined in a sibling Foo.theme.ts file. For slottable parts, composableProps reconciles consumer classNames with any className injected by a parent Slot.

When should I use createContextScope instead of createContext?

Prefer createContext from @radix-ui/react-context for typed Provider and useContext tuples with part-name error messages. Use createContextScope only when the composite must nest inside another scoped composite, such as Popover inside DropdownMenu.