Files
_hublib-web/packages/tach-typography/src/react/index.tsx

111 lines
3.9 KiB
TypeScript

import React from "react";
import { Typography } from "antd";
import type { LinkProps } from "antd/lib/typography/Link";
import type { ParagraphProps } from "antd/lib/typography/Paragraph";
import type { TextProps } from "antd/lib/typography/Text";
import type { TitleProps } from "antd/lib/typography/Title";
import {
tachTypographyMarkdownToHtml,
tachTypographyClassName,
type TypographyColor,
type TypographyVariant,
type TypographyWeight,
} from "../core";
interface AdditionalProps {
color?: TypographyColor;
weight?: TypographyWeight;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
className?: string | undefined;
markdownEnabled?: boolean;
children?: React.ReactNode;
}
const createTypographyVariant = <P extends object>(
Component: React.ComponentType<P>,
variant: TypographyVariant,
) => {
const Variant = React.forwardRef<HTMLElement, P & AdditionalProps>(
(
{
color = "primary",
weight = "normal",
className,
onClick,
markdownEnabled = false,
children,
...rest
},
ref,
) => {
const markdownHtml =
markdownEnabled && typeof children === "string"
? tachTypographyMarkdownToHtml(children)
: undefined;
const renderedChildren = markdownHtml ? (
<span dangerouslySetInnerHTML={{ __html: markdownHtml }} />
) : (
children
);
const contentProps = { children: renderedChildren } as unknown as P;
return (
<Component
ref={ref as never}
className={tachTypographyClassName({
variant,
color,
weight,
className,
clickable: Boolean(onClick),
})}
onClick={onClick}
{...(rest as P)}
{...contentProps}
/>
);
},
);
Variant.displayName = String(variant);
return Variant;
};
const createTypographyComponent = <P extends object>(Component: React.ComponentType<P>) => ({
LargeTitle: createTypographyVariant(Component, "LargeTitle"),
Title1: createTypographyVariant(Component, "Title1"),
Title2: createTypographyVariant(Component, "Title2"),
Title3: createTypographyVariant(Component, "Title3"),
Headline: createTypographyVariant(Component, "Headline"),
Body: createTypographyVariant(Component, "Body"),
Inputs: createTypographyVariant(Component, "Inputs"),
Subheadline: createTypographyVariant(Component, "Subheadline"),
FootnoteUnderline: createTypographyVariant(Component, "FootnoteUnderline"),
Footnote: createTypographyVariant(Component, "Footnote"),
Caption: createTypographyVariant(Component, "Caption"),
Caption2: createTypographyVariant(Component, "Caption2"),
AccentH1: createTypographyVariant(Component, "AccentH1"),
AccentH2: createTypographyVariant(Component, "AccentH2"),
AccentSubttl: createTypographyVariant(Component, "AccentSubttl"),
AccentSubttl2: createTypographyVariant(Component, "AccentSubttl2"),
AccentCaption: createTypographyVariant(Component, "AccentCaption"),
AccentCaption2: createTypographyVariant(Component, "AccentCaption2"),
AccentRegularM: createTypographyVariant(Component, "AccentRegularM"),
AccentRegularS: createTypographyVariant(Component, "AccentRegularS"),
AccentLargeTtl: createTypographyVariant(Component, "AccentLargeTtl"),
AppMediumBody: createTypographyVariant(Component, "AppMediumBody"),
AppMediumSubtext: createTypographyVariant(Component, "AppMediumSubtext"),
AppMediumSubtextUnderline: createTypographyVariant(Component, "AppMediumSubtextUnderline"),
});
export const TachTypography = {
Text: createTypographyComponent<TextProps & Pick<ParagraphProps, "ellipsis">>(Typography.Text),
Paragraph: createTypographyComponent<ParagraphProps>(Typography.Paragraph),
Link: createTypographyComponent<LinkProps>(Typography.Link),
Title: createTypographyComponent<TitleProps>(Typography.Title),
};