website refactor

This commit is contained in:
2026-01-18 21:31:08 +01:00
parent 502d4aa092
commit b43a23a48c
96 changed files with 3461 additions and 4067 deletions

View File

@@ -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';