mirror of
https://github.com/lux-tel/websites.git
synced 2026-10-30 20:31:36 +00:00
165 lines
4.2 KiB
TypeScript
165 lines
4.2 KiB
TypeScript
import { type VariantProps, cva } from 'class-variance-authority';
|
|
import { type HTMLAttributes, type ReactNode, forwardRef } from 'react';
|
|
import { cn } from '../lib/utils';
|
|
import { Loading } from './loading';
|
|
|
|
const moduleGridVariants = cva('module-grid', {
|
|
variants: {
|
|
variant: {
|
|
grid: 'grid auto-rows-min',
|
|
section:
|
|
'flex flex-col rounded-2xl border-[#54797241] border-[2px] bg-gradient-to-b from-[#0A0C0C] to-[#081512] bg-blend-lighten shadow-md',
|
|
action:
|
|
'flex flex-col overflow-hidden rounded-2xl border-[#668C83] border-[2px] border-opacity-80 shadow-md',
|
|
},
|
|
size: {
|
|
md: 'grid-cols-1 gap-1 sm:grid-cols-2 md:gap-2',
|
|
lg: 'grid-cols-1 lg:gap-8 xl:grid-cols-3',
|
|
},
|
|
colSpan: {
|
|
1: 'col-span-1 xl:col-span-1',
|
|
2: 'col-span-1 xl:col-span-2',
|
|
3: 'col-span-2 xl:col-span-3',
|
|
4: 'col-span-2 xl:col-span-4',
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
variant: 'grid',
|
|
size: 'md',
|
|
colSpan: 1,
|
|
},
|
|
});
|
|
|
|
export interface ModuleGridProps
|
|
extends HTMLAttributes<HTMLDivElement>,
|
|
VariantProps<typeof moduleGridVariants> {
|
|
loading?: boolean;
|
|
}
|
|
|
|
const ModuleGrid = forwardRef<HTMLDivElement, ModuleGridProps>(
|
|
({ className, variant, size, colSpan, loading, children, ...props }, ref) => {
|
|
return (
|
|
<div
|
|
className={cn('relative', moduleGridVariants({ variant, size, colSpan, className }))}
|
|
ref={ref}
|
|
{...props}
|
|
>
|
|
{loading ? <Loading /> : children}
|
|
</div>
|
|
);
|
|
}
|
|
);
|
|
|
|
ModuleGrid.displayName = 'ModuleGrid';
|
|
|
|
const ModuleGridTitle = forwardRef<HTMLHeadingElement, HTMLAttributes<HTMLHeadingElement>>(
|
|
({ className, ...props }, ref) => (
|
|
<h2
|
|
ref={ref}
|
|
className={cn(
|
|
'mx-4 my-2 text-2xl leading-none tracking-tight md:block md:text-3xl',
|
|
className
|
|
)}
|
|
{...props}
|
|
/>
|
|
)
|
|
);
|
|
ModuleGridTitle.displayName = 'ModuleGridTitle';
|
|
|
|
type ModuleGridHeaderProps = HTMLAttributes<HTMLDivElement> & {
|
|
keepDesktopHeaderOnMobile?: boolean;
|
|
};
|
|
|
|
const ModuleGridHeader = forwardRef<HTMLDivElement, ModuleGridHeaderProps>(
|
|
({ className, keepDesktopHeaderOnMobile, ...props }, ref) => (
|
|
<div
|
|
ref={ref}
|
|
className={cn(
|
|
'flex w-full flex-row items-center justify-between px-2 pt-3',
|
|
keepDesktopHeaderOnMobile ? 'relative top-0' : '-top-14 absolute md:relative md:top-0',
|
|
className
|
|
)}
|
|
{...props}
|
|
/>
|
|
)
|
|
);
|
|
ModuleGridHeader.displayName = 'ModuleGridHeader';
|
|
|
|
export enum MODULE_GRID_ALIGNMENT {
|
|
/** Centers the content */
|
|
CENTER = 'center',
|
|
/** Aligns the content to the top */
|
|
TOP = 'top',
|
|
/** Aligns the content to the top with a 1/3 offset */
|
|
TOP_1_3 = 'top-1/3',
|
|
}
|
|
|
|
type ModuleGridContentProps = HTMLAttributes<HTMLDivElement> & {
|
|
containerClassName?: string;
|
|
/** The alignment of the content Defaults to {@link MODULE_GRID_ALIGNMENT.TOP_1_3} */
|
|
alignment?: MODULE_GRID_ALIGNMENT;
|
|
};
|
|
|
|
const ModuleGridContent = forwardRef<HTMLDivElement, ModuleGridContentProps>(
|
|
(
|
|
{
|
|
alignment = MODULE_GRID_ALIGNMENT.TOP_1_3,
|
|
className,
|
|
containerClassName,
|
|
children,
|
|
...props
|
|
},
|
|
ref
|
|
) => (
|
|
<div
|
|
ref={ref}
|
|
className={cn(
|
|
'flex h-full flex-col overflow-y-auto',
|
|
alignment === MODULE_GRID_ALIGNMENT.CENTER ? 'justify-center' : 'justify-start',
|
|
containerClassName
|
|
)}
|
|
{...props}
|
|
>
|
|
<div
|
|
className={cn(
|
|
'fade-to-transparent-b flex h-max flex-col gap-2 p-4 align-middle md:p-6',
|
|
alignment === MODULE_GRID_ALIGNMENT.TOP_1_3 ? 'py-[20vh] xl:py-0 xl:pt-[20vh]' : '',
|
|
className
|
|
)}
|
|
>
|
|
{children}
|
|
</div>
|
|
</div>
|
|
)
|
|
);
|
|
ModuleGridContent.displayName = 'ModuleGridContent';
|
|
|
|
function ModuleGridInfoContent({
|
|
children,
|
|
className,
|
|
}: {
|
|
children: ReactNode;
|
|
className?: string;
|
|
}) {
|
|
return (
|
|
<ModuleGridContent
|
|
alignment={MODULE_GRID_ALIGNMENT.CENTER}
|
|
className={cn(
|
|
'flex w-full max-w-xl flex-col items-center gap-6 self-center text-center text-session-text text-xl',
|
|
className
|
|
)}
|
|
>
|
|
{children}
|
|
</ModuleGridContent>
|
|
);
|
|
}
|
|
|
|
export {
|
|
ModuleGrid,
|
|
ModuleGridContent,
|
|
ModuleGridHeader,
|
|
ModuleGridInfoContent,
|
|
ModuleGridTitle,
|
|
moduleGridVariants,
|
|
};
|