Polymorphic heading
How big a heading looks and which level it is are two separate decisions. A card title might need to look large and still be an <h3> in the outline. So the component shouldn't be locked to one tag: the size is a typed variant, and the tag is picked wherever the heading is used.
Define it
components/heading.css.ts
import { styled } from "@salty-css/react/styled";
// "h2" is only the default tag — every instance can swap it.
export const Heading = styled("h2", {
base: {
margin: 0,
lineHeight: 1.15,
fontWeight: 600,
},
variants: {
size: {
small: { fontSize: "1.25rem" },
regular: { fontSize: "1.75rem" },
large: { fontSize: "2.5rem", letterSpacing: "-0.01em" },
},
},
defaultVariants: {
size: "regular",
},
});Use it
Example
import { Heading } from "./heading.css";
<>
<Heading as="h1" size="large">Pricing</Heading>
{/* Looks just as big, but sits lower in the outline. */}
<Heading as="h3" size="large">Pro plan</Heading>
<Heading>Defaults to an h2 at regular size</Heading>
</>;as is a per-instance shorthand for the element option — use element: "h3" in the styled() options when every instance should default to another tag. The size prop is consumed by Salty for styling and never reaches the DOM; what ships is a hashed class per size, compiled ahead of time.