88 lines
2.2 KiB
TypeScript
88 lines
2.2 KiB
TypeScript
import { ReactNode } from 'react';
|
|
import { defaultLayoutConfig, type LayoutConfig } from '~/lib/layout-utils';
|
|
|
|
interface GridProps {
|
|
children: ReactNode;
|
|
className?: string;
|
|
config?: Partial<LayoutConfig>;
|
|
cols?: 1 | 2 | 3 | 4 | 6 | 12 | {
|
|
xs?: 1 | 2 | 3 | 4 | 6 | 12;
|
|
sm?: 1 | 2 | 3 | 4 | 6 | 12;
|
|
md?: 1 | 2 | 3 | 4 | 6 | 12;
|
|
lg?: 1 | 2 | 3 | 4 | 6 | 12;
|
|
xl?: 1 | 2 | 3 | 4 | 6 | 12;
|
|
};
|
|
gap?: 'sm' | 'md' | 'lg' | 'xl';
|
|
responsive?: {
|
|
sm?: 1 | 2 | 3 | 4 | 6 | 12;
|
|
md?: 1 | 2 | 3 | 4 | 6 | 12;
|
|
lg?: 1 | 2 | 3 | 4 | 6 | 12;
|
|
xl?: 1 | 2 | 3 | 4 | 6 | 12;
|
|
};
|
|
}
|
|
|
|
export function Grid({
|
|
children,
|
|
className = '',
|
|
config = {},
|
|
cols = 1,
|
|
gap = 'md',
|
|
responsive = {}
|
|
}: GridProps) {
|
|
const layoutConfig = { ...defaultLayoutConfig, ...config };
|
|
|
|
const colsClasses = {
|
|
1: 'grid-cols-1',
|
|
2: 'grid-cols-2',
|
|
3: 'grid-cols-3',
|
|
4: 'grid-cols-4',
|
|
6: 'grid-cols-6',
|
|
12: 'grid-cols-12',
|
|
};
|
|
|
|
const gapClasses = {
|
|
sm: 'gap-2 sm:gap-2.5 md:gap-3',
|
|
md: 'gap-3 sm:gap-4 md:gap-5 lg:gap-6',
|
|
lg: 'gap-4 sm:gap-5 md:gap-6 lg:gap-8',
|
|
xl: 'gap-6 sm:gap-7 md:gap-8 lg:gap-10',
|
|
};
|
|
|
|
// Handle both old responsive prop and new cols object format
|
|
let gridColsClass = '';
|
|
|
|
if (typeof cols === 'object') {
|
|
// New format: cols={{ xs: 1, sm: 2, md: 3, lg: 4 }}
|
|
const xs = cols.xs || 1;
|
|
const sm = cols.sm || cols.xs || 1;
|
|
const md = cols.md || cols.sm || cols.xs || 2;
|
|
const lg = cols.lg || cols.md || cols.sm || 3;
|
|
const xl = cols.xl || cols.lg || cols.md || 4;
|
|
|
|
gridColsClass = `
|
|
${colsClasses[xs]}
|
|
sm:${colsClasses[sm]}
|
|
md:${colsClasses[md]}
|
|
lg:${colsClasses[lg]}
|
|
xl:${colsClasses[xl]}
|
|
`;
|
|
} else {
|
|
// Old format: cols={4} with responsive prop
|
|
gridColsClass = colsClasses[cols];
|
|
|
|
if (Object.keys(responsive).length > 0) {
|
|
const responsiveClasses = Object.entries(responsive)
|
|
.map(([breakpoint, cols]) => `${breakpoint}:${colsClasses[cols]}`)
|
|
.join(' ');
|
|
gridColsClass = `${gridColsClass} ${responsiveClasses}`;
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={`grid ${gridColsClass} ${gapClasses[gap]} ${className}`}
|
|
dir={layoutConfig.direction}
|
|
>
|
|
{children}
|
|
</div>
|
|
);
|
|
} |