Start from the platform contract
A native button participates in forms, keyboard input, focus order, accessibility APIs, and disabled behavior. Recreating that foundation with a generic element introduces a long list of responsibilities that are easy to miss.
Choose the semantic element that best describes the action before deciding how it should look.
Component APIs should preserve meaning
Flexible styling is useful, but polymorphism can silently produce invalid or confusing semantics. Keep defaults safe, constrain exceptional rendering, and document what the consumer must preserve.
- Do not use links for actions or buttons for navigation.
- Connect labels, descriptions, and errors programmatically.
- Use progressive enhancement for disclosure and dialogs.
- Test the rendered HTML, not only component props.
Native does not mean unstyled or simplistic
Coordiation utilities can shape a distinctive visual system while the underlying controls keep their browser contract. Small client components can add behavior only where the platform needs help.
This produces source that is easier for people and agents to inspect because structure, behavior, and style remain legible.
