Skip to content

Lesson 2 of 6

Composition

Put named pieces together so each piece has one easy-to-understand job.

Some roots are invisible helpers

A root such as Dialog or TextField can hold state and connect its children without adding an extra HTML box. By default, its children become the visible DOM. This keeps your HTML clean and lets each child own the element it really is.

Add thistsx
<TextField>
  <Label>Email</Label>
  <Input name="email" />
</TextField>

Add a wrapper only when you need one

The default children behave like a React Fragment, so no wrapper is rendered. If layout or semantics need a real element, pass as with the element you want. Do not add a wrapper just because a component has a root name.

Add thistsx
<Dialog as="section" aria-label="Account settings">
  {children}
</Dialog>

Keep named parts in their jobs

Triggers open things, content holds what appears, and items are the choices inside a collection. Put each part where its parent pattern expects it. This gives comp0 enough information to connect IDs, focus, and keyboard behavior for you.

Add thistsx
<Popover>
  <PopoverTrigger>More</PopoverTrigger>
  <PopoverOverlay>Extra choices</PopoverOverlay>
</Popover>