tercul-frontend/client/src/components/ui/typography/heading.tsx
mukimovd 66dd28e128 Implement core text formatting components enhancing content presentation
Adds typography components (Heading, Paragraph, BlockQuote, CodeBlock, Prose) with variants and updates COMPONENT-IMPLEMENTATION-TRACKER.md.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: bddfbb2b-6d6b-457b-b18c-05792cdaa035
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/39b5c689-6e8a-4d5a-9792-69cc81a56534/d046f5ac-7f62-419b-8fdb-893187a139f2.jpg
2025-05-10 21:10:41 +00:00

76 lines
1.9 KiB
TypeScript

import { forwardRef } from "react";
import { Slot } from "@radix-ui/react-slot";
import { cn } from "@/lib/utils";
import { cva, type VariantProps } from "class-variance-authority";
/**
* Heading component for displaying titles and section headings
*
* @example
* ```tsx
* <Heading>Default Heading (h2)</Heading>
* <Heading level="h1">Main Page Title</Heading>
* <Heading level="h3" variant="serif">Section Heading</Heading>
* ```
*/
const headingVariants = cva(
"scroll-m-20 font-semibold tracking-tight",
{
variants: {
level: {
h1: "text-4xl lg:text-5xl",
h2: "text-3xl lg:text-4xl",
h3: "text-2xl lg:text-3xl",
h4: "text-xl lg:text-2xl",
h5: "text-lg lg:text-xl",
h6: "text-base lg:text-lg",
},
variant: {
default: "text-foreground",
muted: "text-muted-foreground",
primary: "text-primary",
serif: "font-serif",
display: "font-serif font-bold",
decorative: "font-serif italic",
},
weight: {
default: "font-semibold",
light: "font-normal",
medium: "font-medium",
bold: "font-bold",
},
},
defaultVariants: {
level: "h2",
variant: "default",
weight: "default",
},
}
);
export interface HeadingProps
extends React.HTMLAttributes<HTMLHeadingElement>,
VariantProps<typeof headingVariants> {
/**
* Whether to render as a different HTML element via Radix Slot
*/
asChild?: boolean;
}
const Heading = forwardRef<HTMLHeadingElement, HeadingProps>(
({ className, level, variant, weight, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : level || "h2";
return (
<Comp
className={cn(headingVariants({ level, variant, weight, className }))}
ref={ref}
{...props}
/>
);
}
);
Heading.displayName = "Heading";
export { Heading, headingVariants };