113 lines
2.9 KiB
TypeScript
113 lines
2.9 KiB
TypeScript
import { createElement, JSX, ReactNode } from "react";
|
|
import { cva, VariantProps } from "class-variance-authority";
|
|
import { cn } from "@/lib/utils";
|
|
import { MarkupText } from "@/components/ui/MarkupText/MarkupText";
|
|
|
|
const typographyVariants = cva(cn("text-center text-foreground block"), {
|
|
variants: {
|
|
size: {
|
|
xs: "text-xs",
|
|
sm: "text-sm",
|
|
md: "text-base",
|
|
lg: "text-lg",
|
|
xl: "text-xl",
|
|
"2xl": "text-2xl",
|
|
"3xl": "text-3xl",
|
|
"4xl": "text-4xl",
|
|
},
|
|
weight: {
|
|
regular: "font-normal",
|
|
medium: "font-medium",
|
|
semiBold: "font-semibold",
|
|
bold: "font-bold",
|
|
extraBold: "font-extrabold",
|
|
black: "font-black",
|
|
},
|
|
color: {
|
|
default: "text-foreground",
|
|
primary: "text-primary-foreground",
|
|
secondary: "text-secondary-foreground",
|
|
destructive: "text-destructive",
|
|
success: "text-success",
|
|
card: "text-card-foreground",
|
|
accent: "text-accent-foreground",
|
|
muted: "text-muted-foreground",
|
|
},
|
|
align: {
|
|
center: "text-center",
|
|
left: "text-left",
|
|
right: "text-right",
|
|
},
|
|
font: {
|
|
manrope: "font-manrope",
|
|
inter: "font-inter",
|
|
geistSans: "font-geist-sans",
|
|
geistMono: "font-geist-mono",
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
size: "md",
|
|
weight: "regular",
|
|
color: "default",
|
|
align: "left",
|
|
font: "manrope",
|
|
},
|
|
});
|
|
|
|
type TypographyElements = Pick<
|
|
JSX.IntrinsicElements,
|
|
"span" | "p" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "div"
|
|
>;
|
|
|
|
export type TypographyProps<T extends keyof TypographyElements = "span"> =
|
|
VariantProps<typeof typographyVariants> &
|
|
Omit<TypographyElements[T], "color"> & {
|
|
as?: T;
|
|
children: ReactNode;
|
|
enableMarkup?: boolean; // 🎨 Новый параметр для включения разметки
|
|
};
|
|
|
|
export default function Typography<
|
|
T extends keyof TypographyElements = "span"
|
|
>({
|
|
as: Component = "span" as T,
|
|
children,
|
|
className,
|
|
weight,
|
|
size,
|
|
color,
|
|
align,
|
|
font,
|
|
enableMarkup = false, // 🎨 По умолчанию выключена для обратной совместимости
|
|
...props
|
|
}: TypographyProps<T>) {
|
|
const classes = cn(
|
|
typographyVariants({ size, weight, color, align, font }),
|
|
className
|
|
);
|
|
|
|
// 🎨 Если включена разметка и это строка, используем MarkupText
|
|
if (enableMarkup && typeof children === 'string') {
|
|
return (
|
|
<MarkupText
|
|
as={Component}
|
|
className={classes}
|
|
boldClassName={weight === 'bold' ? undefined : 'font-bold'} // Наследуем стиль жирного текста
|
|
{...props}
|
|
>
|
|
{children}
|
|
</MarkupText>
|
|
);
|
|
}
|
|
|
|
// 🎨 Обычный рендеринг без разметки
|
|
return createElement(
|
|
Component,
|
|
{
|
|
className: classes,
|
|
...props,
|
|
},
|
|
children
|
|
);
|
|
}
|