website refactor
This commit is contained in:
@@ -1,93 +1,52 @@
|
||||
import React, { ReactNode, ElementType } from 'react';
|
||||
import { Stack } from './primitives/Stack';
|
||||
import React, { ReactNode, forwardRef } from 'react';
|
||||
import { Box, BoxProps, ResponsiveValue } from './primitives/Box';
|
||||
|
||||
interface ResponsiveFontSize {
|
||||
base?: string;
|
||||
sm?: string;
|
||||
md?: string;
|
||||
lg?: string;
|
||||
xl?: string;
|
||||
'2xl'?: string;
|
||||
}
|
||||
|
||||
interface HeadingProps extends Omit<BoxProps<'h1'>, 'children' | 'as' | 'fontSize'> {
|
||||
level: 1 | 2 | 3 | 4 | 5 | 6;
|
||||
export interface HeadingProps extends BoxProps<any> {
|
||||
children: ReactNode;
|
||||
icon?: ReactNode;
|
||||
id?: string;
|
||||
groupHoverColor?: string;
|
||||
truncate?: boolean;
|
||||
uppercase?: boolean;
|
||||
fontSize?: string | ResponsiveFontSize;
|
||||
weight?: 'light' | 'normal' | 'medium' | 'semibold' | 'bold' | string;
|
||||
letterSpacing?: string;
|
||||
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
||||
weight?: 'normal' | 'medium' | 'semibold' | 'bold';
|
||||
align?: 'left' | 'center' | 'right';
|
||||
fontSize?: string | ResponsiveValue<string>;
|
||||
}
|
||||
|
||||
export function Heading({ level, children, icon, groupHoverColor, truncate, uppercase, fontSize, weight, letterSpacing, ...props }: HeadingProps) {
|
||||
const Tag = `h${level}` as ElementType;
|
||||
export const Heading = forwardRef<HTMLHeadingElement, HeadingProps>(({
|
||||
children,
|
||||
level = 1,
|
||||
weight = 'bold',
|
||||
align = 'left',
|
||||
fontSize,
|
||||
...props
|
||||
}, ref) => {
|
||||
const Tag = `h${level}` as const;
|
||||
|
||||
const levelClasses = {
|
||||
1: 'text-3xl md:text-4xl font-bold text-white tracking-tight',
|
||||
2: 'text-xl md:text-2xl font-bold text-white tracking-tight',
|
||||
3: 'text-lg font-bold text-white tracking-tight',
|
||||
4: 'text-base font-bold text-white tracking-tight',
|
||||
5: 'text-sm font-bold text-white tracking-tight uppercase tracking-wider',
|
||||
6: 'text-xs font-bold text-white tracking-tight uppercase tracking-widest',
|
||||
};
|
||||
|
||||
const weightClasses: Record<string, string> = {
|
||||
light: 'font-light',
|
||||
const weightClasses = {
|
||||
normal: 'font-normal',
|
||||
medium: 'font-medium',
|
||||
semibold: 'font-semibold',
|
||||
bold: 'font-bold'
|
||||
};
|
||||
|
||||
const getFontSizeClasses = (value: string | ResponsiveFontSize | undefined) => {
|
||||
if (value === undefined) return '';
|
||||
if (typeof value === 'object') {
|
||||
const classes = [];
|
||||
if (value.base) classes.push(`text-${value.base}`);
|
||||
if (value.sm) classes.push(`sm:text-${value.sm}`);
|
||||
if (value.md) classes.push(`md:text-${value.md}`);
|
||||
if (value.lg) classes.push(`lg:text-${value.lg}`);
|
||||
if (value.xl) classes.push(`xl:text-${value.xl}`);
|
||||
if (value['2xl']) classes.push(`2xl:text-${value['2xl']}`);
|
||||
return classes.join(' ');
|
||||
}
|
||||
return `text-${value}`;
|
||||
|
||||
const sizeClasses = {
|
||||
1: 'text-4xl md:text-5xl',
|
||||
2: 'text-3xl md:text-4xl',
|
||||
3: 'text-2xl md:text-3xl',
|
||||
4: 'text-xl md:text-2xl',
|
||||
5: 'text-lg md:text-xl',
|
||||
6: 'text-base md:text-lg'
|
||||
};
|
||||
|
||||
const content = icon ? (
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
{icon}
|
||||
{children}
|
||||
</Stack>
|
||||
) : children;
|
||||
|
||||
const classes = [
|
||||
levelClasses[level],
|
||||
getFontSizeClasses(fontSize),
|
||||
weight && weightClasses[weight as keyof typeof weightClasses] ? weightClasses[weight as keyof typeof weightClasses] : '',
|
||||
letterSpacing ? `tracking-${letterSpacing}` : '',
|
||||
uppercase ? 'uppercase' : '',
|
||||
groupHoverColor ? `group-hover:text-${groupHoverColor}` : '',
|
||||
truncate ? 'truncate' : '',
|
||||
props.className
|
||||
].filter(Boolean).join(' ');
|
||||
'text-[var(--ui-color-text-high)]',
|
||||
weightClasses[weight],
|
||||
fontSize ? '' : sizeClasses[level],
|
||||
align === 'center' ? 'text-center' : (align === 'right' ? 'text-right' : 'text-left'),
|
||||
].join(' ');
|
||||
|
||||
return (
|
||||
<Box
|
||||
as={Tag}
|
||||
{...props}
|
||||
className={classes}
|
||||
style={{
|
||||
...(weight && !weightClasses[weight as keyof typeof weightClasses] ? { fontWeight: weight } : {}),
|
||||
...(props.style || {})
|
||||
}}
|
||||
>
|
||||
{content}
|
||||
<Box as={Tag} ref={ref} className={classes} fontSize={typeof fontSize === 'string' ? fontSize : undefined} {...props}>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Heading.displayName = 'Heading';
|
||||
|
||||
Reference in New Issue
Block a user