ReactMaterial3/src/components/Typography.tsx

229 lines
6.3 KiB
TypeScript

import React, { useMemo } from "react";
import '../../fonts/roboto.css';
import { AriaProps } from '../types/aria';
type TypographyProps = AriaProps & {
children: React.ReactNode;
variant?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span" | "label";
className?: string;
color?: 'primary' | 'secondary' | 'tertiary' | 'error' | 'on-primary' | 'on-secondary' | 'on-tertiary' | 'on-error' | 'scrim' | 'outline' | 'outline-variant' | string;
align?: "left" | "center" | "right";
style?: React.CSSProperties;
noWrap?: boolean;
id?: string;
size?: "small" | "medium" | "large" | "auto";
htmlFor?: string;
};
export const Typography = ({ children, variant = "span", className, color = "", align, style, noWrap, id, size = "auto", htmlFor }: TypographyProps) => {
const clr = useMemo(() => {
if (color === 'primary') return 'var(--md-sys-color-primary)';
if (color === 'secondary') return 'var(--md-sys-color-secondary)';
if (color === 'tertiary') return 'var(--md-sys-color-tertiary)';
if (color === 'error') return 'var(--md-sys-color-error)';
if (color === 'on-primary') return 'var(--md-sys-color-on-primary)';
if (color === 'on-secondary') return 'var(--md-sys-color-on-secondary)';
if (color === 'on-tertiary') return 'var(--md-sys-color-on-tertiary)';
if (color === 'on-error') return 'var(--md-sys-color-on-error)';
if (color === 'on-surface') return 'var(--md-sys-color-on-surface)';
if (color === 'scrim') return 'var(--md-sys-color-scrim)';
if (color === 'outline') return 'var(--md-sys-color-outline)';
if (color === 'outline-variant') return 'var(--md-sys-color-outline-variant)';
return color;
}, [color]);
const sz = useMemo(() => {
if (size === 'auto') {
const sizes = {
h1: 'large',
h2: 'large',
h3: 'medium',
h4: 'medium',
h5: 'small',
h6: 'small',
p: 'large',
span: 'large',
label: 'large',
};
return sizes[variant as keyof typeof sizes];
};
if (size === 'small') return 'small';
if (size === 'medium') return 'medium';
if (size === 'large') return 'large';
}, [size]);
if (variant === "h1") {
return (
<h1 className={className} style={{
color: clr,
fontWeight: `var(--md-sys-typescale-headline-${sz}-weight)`,
fontSize: `var(--md-sys-typescale-headline-${sz}-size)`,
lineHeight: `var(--md-sys-typescale-headline-${sz}-line-height)`,
fontFamily: `var(--md-sys-typescale-headline-${sz}-font)`,
textAlign: align,
whiteSpace: noWrap ? "nowrap" : "normal",
...style,
}}
id={id}
>
{children}
</h1>
);
};
if (variant === "h2") {
return (
<h2 className={className} style={{
color: clr,
fontWeight: `var(--md-sys-typescale-headline-${sz}-weight)`,
fontSize: `var(--md-sys-typescale-headline-${sz}-size)`,
lineHeight: `var(--md-sys-typescale-headline-${sz}-line-height)`,
fontFamily: `var(--md-sys-typescale-headline-${sz}-font)`,
textAlign: align,
whiteSpace: noWrap ? "nowrap" : "normal",
...style,
}}
id={id}
>
{children}
</h2>
);
}
if (variant === "h3") {
return (
<h3 className={className} style={{
color: clr,
fontWeight: `var(--md-sys-typescale-headline-${sz}-weight)`,
fontSize: `var(--md-sys-typescale-headline-${sz}-size)`,
lineHeight: `var(--md-sys-typescale-headline-${sz}-line-height)`,
fontFamily: `var(--md-sys-typescale-headline-${sz}-font)`,
textAlign: align,
whiteSpace: noWrap ? "nowrap" : "normal",
...style,
}}
id={id}
>
{children}
</h3>
);
}
if (variant === "h4") {
return (
<h4 className={className} style={{
color: clr,
fontWeight: `var(--md-sys-typescale-headline-${sz}-weight)`,
fontSize: `var(--md-sys-typescale-headline-${sz}-size)`,
lineHeight: `var(--md-sys-typescale-headline-${sz}-line-height)`,
fontFamily: `var(--md-sys-typescale-headline-${sz}-font)`,
textAlign: align,
whiteSpace: noWrap ? "nowrap" : "normal",
...style,
}}
id={id}
>
{children}
</h4>
);
}
if (variant === "h5") {
return (
<h5 className={className} style={{
color: clr,
fontWeight: `var(--md-sys-typescale-headline-${sz}-weight)`,
fontSize: `var(--md-sys-typescale-headline-${sz}-size)`,
lineHeight: `var(--md-sys-typescale-headline-${sz}-line-height)`,
fontFamily: `var(--md-sys-typescale-headline-${sz}-font)`,
textAlign: align,
whiteSpace: noWrap ? "nowrap" : "normal",
...style,
}}
id={id}
>
{children}
</h5>
);
}
if (variant === "h6") {
return (
<h6 className={className} style={{
color: clr,
fontWeight: `var(--md-sys-typescale-headline-${sz}-weight)`,
fontSize: `var(--md-sys-typescale-headline-${sz}-size)`,
lineHeight: `var(--md-sys-typescale-headline-${sz}-line-height)`,
fontFamily: `var(--md-sys-typescale-headline-${sz}-font)`,
textAlign: align,
whiteSpace: noWrap ? "nowrap" : "normal",
...style,
}}
id={id}
>
{children}
</h6>
);
}
if (variant === "p") {
return (
<p className={className} style={{
color: clr,
fontWeight: `var(--md-sys-typescale-body-${sz}-weight)`,
fontSize: `var(--md-sys-typescale-body-${sz}-size)`,
lineHeight: `var(--md-sys-typescale-body-${sz}-line-height)`,
fontFamily: `var(--md-sys-typescale-body-${sz}-font)`,
textAlign: align,
whiteSpace: noWrap ? "nowrap" : "normal",
...style,
}}
id={id}
>
{children}
</p>
);
}
if (variant === "span") {
return (
<span className={className} style={{
color: clr,
fontWeight: `var(--md-sys-typescale-body-${sz}-weight)`,
fontSize: `var(--md-sys-typescale-body-${sz}-size)`,
lineHeight: `var(--md-sys-typescale-body-${sz}-line-height)`,
fontFamily: `var(--md-sys-typescale-body-${sz}-font)`,
textAlign: align,
whiteSpace: noWrap ? "nowrap" : "normal",
...style,
}}
id={id}
>
{children}
</span>
);
}
if (variant === "label") {
return (
<label htmlFor={htmlFor} className={className} style={{
color: clr,
fontWeight: `var(--md-sys-typescale-label-${sz}-weight)`,
fontSize: `var(--md-sys-typescale-label-${sz}-size)`,
lineHeight: `var(--md-sys-typescale-label-${sz}-line-height)`,
fontFamily: `var(--md-sys-typescale-label-${sz}-font)`,
textAlign: align,
whiteSpace: noWrap ? "nowrap" : "normal",
...style,
}}
id={id}
>
{children}
</label>
);
}
return null;
};