In professional design systems (such as Radix UI, Headless UI, or custom enterprise component libraries), UI primitives like buttons, cards, and typography must adapt to diverse semantic roles without duplicating code.
Consider a <Button> component. In standard scenarios, it should render an HTML <button> element. However:
When linking to an external website, it semantically needs to render an <a> tag.
When used with React Router, it should render a client-side <Link> component.
In custom dashboard toolbars, it might render as a <div> with ARIA roles.
If you create separate <Button>, <LinkButton>, and <RouteButton> components, you fracture style maintenance, prop contracts, and accessibility attributes.
The solution is the Polymorphic Component Pattern (commonly implemented via the as prop).
2. Implementing a Polymorphic Component in JavaScript/React
In React, JSX tag names that start with an uppercase letter are evaluated dynamically as variables. By accepting an as prop and aliasing it to a capitalized variable name (Component), we can dynamically determine the rendered tag:
JSX
1import React from'react';
2
3exportdefaultfunctionText({
4as: Component ='p',// Default to paragraph if omitted