Quick answer
Start a React design system with the controls that already repeat in real screens: buttons, labelled fields, feedback messages, and layout spacing. Give each component a narrow semantic contract. A button performs an action; a link navigates. Colours and spacing belong in shared tokens, while booking rules, permission checks, and API calls stay with the product feature.
A component catalogue becomes useful when it explains disabled, pending, invalid, focused, and long-text states as carefully as the default appearance. The IMMAGINE project offers a concrete visual review surface: consultation actions, service cards, and a mobile menu. These are examples of recurring interface needs, rather than evidence that its WordPress implementation uses React.
Practical implementation steps
Inventory two or three existing flows before choosing the public API. Compare their labels, error placement, keyboard actions, and responsive spacing. Extract a component only after you can name the repeated behaviour. A single unusual pricing card can remain a feature component until another screen needs the same contract.
Define a small set of tokens for surface, text, border, focus ring, and spacing. Name them by purpose so a dark theme can change their values without renaming every consumer. Then document component variants with examples of when each variant applies. Ten Boolean styling flags produce combinations that somebody must maintain and test.
Implementation example
This button preserves native button props and provides an explicit styling choice. Its default type prevents accidental form submission. Submit actions must opt into type="submit". The consumer supplies its accessible text and loading policy.
import type { ComponentProps } from "react";
type ButtonProps = ComponentProps<"button"> & {
tone?: "primary" | "secondary";
};
export function Button({
tone = "primary", type = "button", className = "", ...props
}: ButtonProps) {
return <button {...props} type={type} data-tone={tone}
className={"button " + className} />;
}
Define the .button styles in the consuming stylesheet, including a visible :focus-visible outline and the two data-tone variants. Keep CSS delivery part of the package contract. In a Next.js app, a presentational component can stay server compatible; a consumer that owns click handlers belongs in a Client Component boundary.
Tradeoffs and alternatives
An established accessible primitive library is useful for menus, dialogs, and complex selection patterns whose focus behaviour exceeds a simple native control. Review its documented interaction contract before wrapping it. A wrapper should preserve useful escape hatches and avoid exposing every private implementation detail as a new public prop.
Common mistakes
Avoid clickable divs, colour-only error states, undocumented CSS imports, and component names tied to one campaign. Reusing a visual card does not require sharing its data fetching. Check long Ukrainian labels before fixing control heights; a translated label can reveal a sizing assumption that the original English screen concealed.
Production checklist
- Keyboard focus remains visible in every supported theme.
- Buttons and links retain their native semantics.
- Each variant has a documented product use.
- Invalid, pending, disabled, and long-text examples are covered.
- Package CSS imports and breaking-change ownership are explicit.
FAQ
When should the library become a separate package?
When multiple applications need independent release cycles and an owner can maintain versioned compatibility. A shared folder is easier to change while the API is still being discovered.
Should every screen use the same components?
Share the stable interactions and visual rules. Keep exceptional layouts local, then promote a pattern after repeated use shows that its behaviour and naming are stable.
Next step
Compare two real forms before publishing the component API. Exercise keyboard focus, invalid input, pending submission, and longer translated labels in both; keep feature-specific behaviour outside the shared control.
Primary sources
Related guides and examples
Need this implemented in a real product?
React and Next.js applications with deliberate rendering, reliable data flows, and a clear path to production.