car_mms/app/components/layout/Flex.tsx
2025-09-11 14:22:27 +03:00

102 lines
3.0 KiB
TypeScript

import { ReactNode } from 'react';
import { getResponsiveClasses, defaultLayoutConfig, type LayoutConfig } from '~/lib/layout-utils';
interface FlexProps {
children: ReactNode;
className?: string;
config?: Partial<LayoutConfig>;
direction?: 'row' | 'col' | 'row-reverse' | 'col-reverse';
align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline';
justify?: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';
wrap?: boolean;
gap?: 'sm' | 'md' | 'lg' | 'xl';
responsive?: {
sm?: Partial<Pick<FlexProps, 'direction' | 'align' | 'justify'>>;
md?: Partial<Pick<FlexProps, 'direction' | 'align' | 'justify'>>;
lg?: Partial<Pick<FlexProps, 'direction' | 'align' | 'justify'>>;
xl?: Partial<Pick<FlexProps, 'direction' | 'align' | 'justify'>>;
};
}
export function Flex({
children,
className = '',
config = {},
direction = 'row',
align = 'start',
justify = 'start',
wrap = false,
gap = 'md',
responsive = {}
}: FlexProps) {
const layoutConfig = { ...defaultLayoutConfig, ...config };
const classes = getResponsiveClasses(layoutConfig);
const directionClasses = {
row: layoutConfig.direction === 'rtl' ? 'flex-row-reverse' : 'flex-row',
col: 'flex-col',
'row-reverse': layoutConfig.direction === 'rtl' ? 'flex-row' : 'flex-row-reverse',
'col-reverse': 'flex-col-reverse',
};
const alignClasses = {
start: 'items-start',
center: 'items-center',
end: 'items-end',
stretch: 'items-stretch',
baseline: 'items-baseline',
};
const justifyClasses = {
start: 'justify-start',
center: 'justify-center',
end: 'justify-end',
between: 'justify-between',
around: 'justify-around',
evenly: 'justify-evenly',
};
const gapClasses = {
sm: 'gap-2',
md: 'gap-4',
lg: 'gap-6',
xl: 'gap-8',
};
const wrapClass = wrap ? 'flex-wrap' : '';
// Build responsive classes
const responsiveClasses = Object.entries(responsive)
.map(([breakpoint, props]) => {
const responsiveClassList = [];
if (props.direction) {
const responsiveDirection = props.direction === 'row' && layoutConfig.direction === 'rtl'
? 'flex-row-reverse'
: props.direction === 'row-reverse' && layoutConfig.direction === 'rtl'
? 'flex-row'
: directionClasses[props.direction];
responsiveClassList.push(`${breakpoint}:${responsiveDirection}`);
}
if (props.align) {
responsiveClassList.push(`${breakpoint}:${alignClasses[props.align]}`);
}
if (props.justify) {
responsiveClassList.push(`${breakpoint}:${justifyClasses[props.justify]}`);
}
return responsiveClassList.join(' ');
})
.join(' ');
return (
<div
className={`flex ${directionClasses[direction]} ${alignClasses[align]} ${justifyClasses[justify]} ${gapClasses[gap]} ${wrapClass} ${responsiveClasses} ${className}`}
dir={layoutConfig.direction}
>
{children}
</div>
);
}