uup
This commit is contained in:
102
app/components/layout/Flex.tsx
Normal file
102
app/components/layout/Flex.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user