Build a component
Turn a component’s specification into usable behavior, including keyboard access and error states.
Why this matters
Picture tomorrow's assignments: a crew member opens the list on a phone to find their site. Start from what your piece is for and who touches it. Reuse a solid existing piece before making a near-copy with slightly different behavior.
What to understand
Use a link for going somewhere and a button for doing something. A simple show-and-hide can often use native details and summary; a tab set, menu, combobox, or dialog needs its own interaction model. Keep product logic at the boundary: the generic piece owns look and behavior, the feature piece owns product state and copy, the server owns permission.
Check every state the contract allows — focus, disabled, loading, success, error, cancelling — and isolate failures where the rest of the screen stays useful.
Watch for
- ARIA that fights what the native element already says.
- "Use client" treated as a reason to make the whole page browser-only.
- Objects carrying secrets passed across the client boundary.
- A disabled button assumed to guarantee a single server-side save.
- Focus moved for a routine refresh, or every render announced.
- A broken optional panel wiping out navigation.
- A piece that works alone but breaks in a narrow grid or scrolling dialog.
Strong default
Style the native element's visible focus and spacing to match your product instead of rebuilding it. Announce meaningful outcomes, not every render. Return focus somewhere useful when an overlay closes. Put a boundary where the rest of the screen stays useful.
When this doesn't apply
React error boundaries catch rendering failures below them — not click handlers or failed requests, which you handle where the work happens. A greyed-out button cuts accidental taps; it does not keep the write contract intact across retries and double-taps by itself.
In practice
export function DeliveryDetails() {
return (
<details>
<summary>How delivery works</summary>
<p>The invitation is created first. Email delivery is tracked separately.</p>
</details>
);
}You get built-in meaning and keyboard behavior for free. In a framework with server components, keep browser state and click handlers in the right client spot. Check which props can cross it, and never pass along objects that carry secrets.
A generic Button owns how it looks and acts. AssignShift owns the crew member, the site, loading state, and result copy. The server owns whether this person may assign for that crew. React's built-in boundary uses class methods; helper libraries offer simpler APIs. See the React boundary reference. A broken optional panel shouldn't wipe out navigation.
Verify
Ask your agent: "if they tap twice or retry, does this still save only once?" Check long names, wrapping, themes, keyboard use, and each state change in its real parent. Test meaningful behavior; review the composition by eye.
Related skills
Use $component to create or revise the contract and $craft when the composed screen needs visual refinement.
Last updated on