Is this the best way to build typography components? #1527
-
Unless I'm missing something, it doesn't look like the typography components work the same as the others (I only see the examples). So, I used those examples to create two UI components: type HeadingElements = "h1" | "h2" | "h3" | "h4";
const Heading = ({
children,
as,
}: {
children: React.ReactNode;
as: HeadingElements;
}) => {
switch (as) {
case "h1":
return (
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
{children}
</h1>
);
case "h2":
return (
<h2 className="scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0">
{children}
</h2>
);
case "h3":
return (
<h3 className="scroll-m-20 text-2xl font-semibold tracking-tight">
{children}
</h3>
);
case "h4":
return (
<h4 className="scroll-m-20 text-xl font-semibold tracking-tight">
{children}
</h4>
);
default:
return (
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
{children}
</h1>
);
}
};
export default Heading; type TextElements =
| "p"
| "blockquote"
| "code"
| "lead"
| "large"
| "small"
| "muted";
const Text = ({
children,
as,
}: {
children: React.ReactNode;
as: TextElements;
}) => {
switch (as) {
case "p":
return <p className="leading-7 [&:not(:first-child)]:mt-6">{children}</p>;
case "blockquote":
return (
<blockquote className="mt-6 border-l-2 pl-6 italic">
{children}
</blockquote>
);
case "code":
return (
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">
{children}
</code>
);
case "lead":
return <p className="text-xl text-muted-foreground">{children}</p>;
case "large":
return <div className="text-lg font-semibold">{children}</div>;
case "small":
return (
<small className="text-sm font-medium leading-none">{children}</small>
);
case "muted":
return <p className="text-sm text-muted-foreground">{children}.</p>;
default:
return <p className="leading-7 [&:not(:first-child)]:mt-6">{children}</p>;
}
};
export default Text; And then using Anyone else doing something like this? Am I making it more complicated than it needs to be. There doesn't seem to be a typical; Typography import like in other libraries. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
In the past I've done typography with tailwind using https://tailwindcss.com/docs/typography-plugin and customizing the styles to my needs in the That said, if you wanted to use a component based approach like above, what I've seen in some other libraries is a generic import { Slot } from "@radix-ui/react-slot";
import { type VariantProps, cva } from "class-variance-authority";
import React from "react";
const typeVariants = cva("text-foreground", {
variants: {
variant: {
body: "text-foreground font-medium",
},
size: {
sm: "text-sm",
md: "text-md",
lg: "text-lg",
},
},
defaultVariants: {
variant: "body",
},
});
export interface TypographyProps
extends React.HTMLAttributes<HTMLElement>,
VariantProps<typeof typeVariants> {
asChild?: boolean;
}
export const Typography = React.forwardRef<
HTMLParagraphElement,
TypographyProps
>(({ variant, className, asChild, ...rest }, ref) => {
const Comp = asChild ? Slot : "p";
return (
<Comp
ref={ref}
className={typeVariants({ variant, className })}
{...rest}
/>
);
});
Typography.displayName = "Typography"; This will however make everything a |
Beta Was this translation helpful? Give feedback.
-
Hey @jimburch, It's been a while since you asked, and I'm not sure if it's even a better approach, but I simply add the tailwind formatting suggested on shadcn's typography to my globals.css file via the "@apply" decorator so that I can keep my semantic OCD in check 😜. Here is what it looks like:
You can then use your standard tags on your code. hope this helps. ✌️😎 |
Beta Was this translation helpful? Give feedback.
Hey @jimburch, It's been a while since you asked, and I'm not sure if it's even a better approach, but I simply add the tailwind formatting suggested on shadcn's typography to my globals.css file via the "@apply" decorator so that I can keep my semantic OCD in check 😜. Here is what it looks like: