Files
gridpilot.gg/apps/website/ui/Heading.tsx
2026-01-19 12:35:16 +01:00

75 lines
1.7 KiB
TypeScript

import { ReactNode, forwardRef } from 'react';
import { Box, BoxProps, ResponsiveValue, Spacing } from './Box';
export interface HeadingProps extends BoxProps<any> {
children: ReactNode;
level?: 1 | 2 | 3 | 4 | 5 | 6;
weight?: 'normal' | 'medium' | 'semibold' | 'bold';
align?: 'left' | 'center' | 'right';
fontSize?: string | ResponsiveValue<string>;
icon?: ReactNode;
groupHoverColor?: string;
uppercase?: boolean;
letterSpacing?: string;
mb?: Spacing;
}
export const Heading = forwardRef<HTMLHeadingElement, HeadingProps>(({
children,
level = 1,
weight = 'bold',
align = 'left',
fontSize,
icon,
groupHoverColor,
uppercase,
letterSpacing,
mb,
...props
}, ref) => {
const Tag = `h${level}` as const;
const weightClasses = {
normal: 'font-normal',
medium: 'font-medium',
semibold: 'font-semibold',
bold: 'font-bold'
};
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 classes = [
'text-[var(--ui-color-text-high)]',
weightClasses[weight],
fontSize ? '' : sizeClasses[level],
align === 'center' ? 'text-center' : (align === 'right' ? 'text-right' : 'text-left'),
uppercase ? 'uppercase' : '',
].join(' ');
return (
<Box
as={Tag}
ref={ref}
className={classes}
fontSize={typeof fontSize === 'string' ? fontSize : undefined}
letterSpacing={letterSpacing}
mb={mb}
{...props}
>
<Box display="flex" alignItems="center" gap={2}>
{icon}
{children}
</Box>
</Box>
);
});
Heading.displayName = 'Heading';