chore: transfer repo
This commit is contained in:
182
components/ui/Typography.tsx
Normal file
182
components/ui/Typography.tsx
Normal file
@@ -0,0 +1,182 @@
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
// Typography scale common props
|
||||
interface TypographyProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
as?: React.ElementType;
|
||||
}
|
||||
|
||||
// Heading component props
|
||||
interface HeadingProps extends TypographyProps {
|
||||
level?: 1 | 2 | 3 | 4;
|
||||
align?: 'left' | 'center' | 'right';
|
||||
}
|
||||
|
||||
export function Heading({
|
||||
children,
|
||||
className = '',
|
||||
level = 2,
|
||||
align = 'left',
|
||||
as,
|
||||
}: HeadingProps) {
|
||||
const Component = as || `h${level}` as React.ElementType;
|
||||
|
||||
// Responsive sizes based on provided specs
|
||||
const sizeClasses = {
|
||||
// H1
|
||||
// Desktop: 60px/76px, Mobile: 44px/52px
|
||||
1: 'text-[44px] leading-[52px] lg:text-[60px] lg:leading-[76px] font-allenoire',
|
||||
|
||||
// H2
|
||||
// Desktop: 48px/56px, Mobile: 36px/44px
|
||||
2: 'text-[36px] leading-[44px] lg:text-[48px] lg:leading-[56px] font-allenoire',
|
||||
|
||||
// H3
|
||||
// Desktop: 28px/36px, Mobile: 24px/32px
|
||||
3: 'text-[24px] leading-[32px] lg:text-[28px] lg:leading-[36px] font-allenoire',
|
||||
|
||||
// H4
|
||||
// Desktop: 20px/28px
|
||||
4: 'text-[20px] leading-[28px] font-allenoire',
|
||||
};
|
||||
|
||||
const alignClasses = {
|
||||
left: 'text-left',
|
||||
center: 'text-center',
|
||||
right: 'text-right',
|
||||
};
|
||||
|
||||
return (
|
||||
<Component
|
||||
className={clsx(
|
||||
sizeClasses[level],
|
||||
alignClasses[align],
|
||||
'tracking-[0px]',
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
|
||||
// Text component props
|
||||
interface TextProps extends TypographyProps {
|
||||
size?: 'xs' | 'sm' | 'base' | 'lg' | 'xl';
|
||||
weight?: 'regular' | 'semibold';
|
||||
color?: 'default' | 'muted' | 'accent';
|
||||
}
|
||||
|
||||
export function Text({
|
||||
children,
|
||||
className = '',
|
||||
size = 'base',
|
||||
weight = 'regular',
|
||||
color = 'default',
|
||||
as = 'p',
|
||||
}: TextProps) {
|
||||
const Component = as;
|
||||
|
||||
// Base size classes without font family
|
||||
const sizeClasses = {
|
||||
xs: 'text-[12px] leading-[20px]',
|
||||
sm: 'text-[14px] leading-[22px]',
|
||||
base: 'text-[16px] leading-[24px]',
|
||||
lg: 'text-[16px] leading-[28px]',
|
||||
xl: 'text-[20px] leading-[28px]',
|
||||
};
|
||||
|
||||
// Use Poppins for all text, either regular or semibold
|
||||
const fontClass = weight === 'regular' ? 'font-poppins' : 'font-poppins-semibold';
|
||||
|
||||
const colorClasses = {
|
||||
default: 'text-black',
|
||||
muted: 'text-gray-600',
|
||||
accent: 'text-blue-600',
|
||||
};
|
||||
|
||||
return (
|
||||
<Component
|
||||
className={clsx(
|
||||
sizeClasses[size],
|
||||
fontClass,
|
||||
colorClasses[color],
|
||||
'tracking-[0px]',
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
|
||||
// Caption component props
|
||||
interface CaptionProps extends TypographyProps {
|
||||
size?: 'sm' | 'base';
|
||||
}
|
||||
|
||||
export function Caption({
|
||||
children,
|
||||
className = '',
|
||||
size = 'sm',
|
||||
as = 'span',
|
||||
}: CaptionProps) {
|
||||
const Component = as;
|
||||
|
||||
const sizeClasses = {
|
||||
sm: 'text-[12px] leading-[20px]',
|
||||
base: 'text-[14px] leading-[22px]',
|
||||
};
|
||||
|
||||
return (
|
||||
<Component
|
||||
className={clsx(
|
||||
sizeClasses[size],
|
||||
'text-gray-500',
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
|
||||
// Label component props
|
||||
interface LabelProps extends TypographyProps {
|
||||
size?: 'sm' | 'base' | 'lg';
|
||||
required?: boolean;
|
||||
htmlFor?: string;
|
||||
}
|
||||
|
||||
export function Label({
|
||||
children,
|
||||
className = '',
|
||||
size = 'base',
|
||||
required = false,
|
||||
htmlFor,
|
||||
as = 'label',
|
||||
}: LabelProps) {
|
||||
const Component = as;
|
||||
|
||||
const sizeClasses = {
|
||||
sm: 'text-[14px] leading-[22px]',
|
||||
base: 'text-[16px] leading-[24px]',
|
||||
lg: 'text-[18px] leading-[28px]',
|
||||
};
|
||||
|
||||
return (
|
||||
<Component
|
||||
htmlFor={htmlFor}
|
||||
className={clsx(
|
||||
sizeClasses[size],
|
||||
'font-allenoire tracking-[0px]',
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
{required && <span className="ml-1 text-red-500">*</span>}
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user