146 lines
3.8 KiB
TypeScript
146 lines
3.8 KiB
TypeScript
/**
|
|
* Layout utilities for RTL support and responsive design
|
|
*/
|
|
|
|
export interface LayoutConfig {
|
|
direction: 'rtl' | 'ltr';
|
|
language: 'ar' | 'en';
|
|
sidebarCollapsed: boolean;
|
|
isMobile: boolean;
|
|
}
|
|
|
|
export const defaultLayoutConfig: LayoutConfig = {
|
|
direction: 'rtl',
|
|
language: 'ar',
|
|
sidebarCollapsed: false,
|
|
isMobile: false,
|
|
};
|
|
|
|
/**
|
|
* Get responsive classes based on screen size and RTL direction
|
|
*/
|
|
export function getResponsiveClasses(config: LayoutConfig) {
|
|
const { direction, sidebarCollapsed, isMobile } = config;
|
|
|
|
return {
|
|
container: `container-rtl ${direction === 'rtl' ? 'rtl' : 'ltr'}`,
|
|
flexRow: direction === 'rtl' ? 'flex-rtl-reverse' : 'flex-rtl',
|
|
textAlign: direction === 'rtl' ? 'text-right' : 'text-left',
|
|
marginStart: direction === 'rtl' ? 'mr-auto' : 'ml-auto',
|
|
marginEnd: direction === 'rtl' ? 'ml-auto' : 'mr-auto',
|
|
paddingStart: direction === 'rtl' ? 'pr-4' : 'pl-4',
|
|
paddingEnd: direction === 'rtl' ? 'pl-4' : 'pr-4',
|
|
borderStart: direction === 'rtl' ? 'border-r' : 'border-l',
|
|
borderEnd: direction === 'rtl' ? 'border-l' : 'border-r',
|
|
roundedStart: direction === 'rtl' ? 'rounded-r' : 'rounded-l',
|
|
roundedEnd: direction === 'rtl' ? 'rounded-l' : 'rounded-r',
|
|
sidebar: getSidebarClasses(config),
|
|
mainContent: getMainContentClasses(config),
|
|
};
|
|
}
|
|
|
|
function getSidebarClasses(config: LayoutConfig) {
|
|
const { direction, sidebarCollapsed, isMobile } = config;
|
|
|
|
let classes = 'sidebar-rtl';
|
|
|
|
if (isMobile) {
|
|
classes += ' mobile-sidebar-rtl';
|
|
if (sidebarCollapsed) {
|
|
classes += ' closed';
|
|
}
|
|
} else {
|
|
if (sidebarCollapsed) {
|
|
classes += ' collapsed';
|
|
}
|
|
}
|
|
|
|
return classes;
|
|
}
|
|
|
|
function getMainContentClasses(config: LayoutConfig) {
|
|
const { sidebarCollapsed, isMobile } = config;
|
|
|
|
let classes = 'main-content-rtl';
|
|
|
|
if (!isMobile && !sidebarCollapsed) {
|
|
classes += ' sidebar-open';
|
|
}
|
|
|
|
return classes;
|
|
}
|
|
|
|
/**
|
|
* Get Arabic text rendering classes
|
|
*/
|
|
export function getArabicTextClasses(size: 'sm' | 'base' | 'lg' | 'xl' | '2xl' = 'base') {
|
|
const sizeClasses = {
|
|
sm: 'text-sm',
|
|
base: 'text-base',
|
|
lg: 'text-lg',
|
|
xl: 'text-xl',
|
|
'2xl': 'text-2xl',
|
|
};
|
|
|
|
return `arabic-text font-arabic ${sizeClasses[size]}`;
|
|
}
|
|
|
|
/**
|
|
* Get form input classes with RTL support
|
|
*/
|
|
export function getFormInputClasses(error?: boolean) {
|
|
let classes = 'w-full px-3 py-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500';
|
|
|
|
if (error) {
|
|
classes += ' border-red-500 focus:ring-red-500 focus:border-red-500';
|
|
} else {
|
|
classes += ' border-gray-300';
|
|
}
|
|
|
|
return classes;
|
|
}
|
|
|
|
/**
|
|
* Get button classes with RTL support
|
|
*/
|
|
export function getButtonClasses(
|
|
variant: 'primary' | 'secondary' | 'danger' = 'primary',
|
|
size: 'sm' | 'md' | 'lg' = 'md'
|
|
) {
|
|
const baseClasses = 'btn inline-flex items-center justify-center font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2';
|
|
|
|
const variantClasses = {
|
|
primary: 'bg-blue-600 hover:bg-blue-700 text-white focus:ring-blue-500',
|
|
secondary: 'bg-gray-200 hover:bg-gray-300 text-gray-900 focus:ring-gray-500',
|
|
danger: 'bg-red-600 hover:bg-red-700 text-white focus:ring-red-500',
|
|
};
|
|
|
|
const sizeClasses = {
|
|
sm: 'px-3 py-2 text-sm',
|
|
md: 'px-4 py-2 text-base',
|
|
lg: 'px-6 py-3 text-lg',
|
|
};
|
|
|
|
return `${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]}`;
|
|
}
|
|
|
|
/**
|
|
* Breakpoint utilities for responsive design
|
|
*/
|
|
export const breakpoints = {
|
|
xs: 475,
|
|
sm: 640,
|
|
md: 768,
|
|
lg: 1024,
|
|
xl: 1280,
|
|
'2xl': 1536,
|
|
};
|
|
|
|
/**
|
|
* Check if current screen size matches breakpoint
|
|
*/
|
|
export function useBreakpoint(breakpoint: keyof typeof breakpoints) {
|
|
if (typeof window === 'undefined') return false;
|
|
|
|
return window.innerWidth >= breakpoints[breakpoint];
|
|
} |