Composition
Composing the primitives with your own React components using the render prop.
Every part accepts render, which replaces the element the part would have
produced. The part keeps its behavior, ARIA wiring, and event handlers; you
decide what it renders into.
Composing your own components
Pass an element to render a part as one of your components:
<Composer.Submit render={<Button variant="accent" />}>Send</Composer.Submit>The component you pass must spread the props it receives onto its underlying DOM
node and accept a ref. In React 19 that means taking ref as a regular prop —
no forwardRef needed.
Changing the rendered element
Each part renders the element that fits its role — Composer.Root a <form>,
Message.Root a <div>, Composer.Submit a <button>. Pass a plain element to
change it:
// A step label as a real heading, so the timeline is navigable.
<Steps.Label render={<h4 />}>Searched the web</Steps.Label>Change the element when the semantics call for it, not by default.
Nesting
render props nest as deeply as you need, which is how a part composes with
another library's trigger:
<Composer.Submit
render={
<Tooltip.Trigger render={<Button variant="accent" />} />
}
>
Send
</Composer.Submit>Render functions
Pass a function instead of an element when the output depends on the part's state. It receives the props to spread and the state object:
<Composer.Submit
render={(props, state) => (
<button {...props}>{state.generating ? <StopIcon /> : <SendIcon />}</button>
)}
/>This is also the form to use when you need control over how props are spread — merging your own handlers in, or splitting them across elements.
State is only available on the parts that declare it; the rest receive an empty
object. Styling lists which parts those are, and covers
the className and style callbacks that take the same state.