'use client';
import { cn } from '../../utils/cn';
export interface ContentLoaderProps {
/**
* The type of content being loaded
*/
variant?: 'card' | 'form' | 'detail' | 'list';
/**
* Number of items to show in the skeleton
*/
items?: number;
/**
* Show a title skeleton
*/
showTitle?: boolean;
/**
* Additional CSS classes
*/
className?: string;
/**
* Container CSS classes
*/
containerClassName?: string;
}
/**
* Unified content loader component that replaces duplicate loading patterns
* Uses ODS design tokens for consistent theming
*/
export function ContentLoader({
variant = 'card',
items = 4,
showTitle = true,
className,
containerClassName,
}: ContentLoaderProps) {
const renderCardSkeleton = () => (
{showTitle &&
}
{Array.from({ length: items }).map((_, i) => (
))}
);
const renderFormSkeleton = () => (
{showTitle &&
}
{Array.from({ length: items }).map((_, i) => (
))}
);
const renderDetailSkeleton = () => (
{showTitle &&
}
{Array.from({ length: 3 }).map((_, i) => (
))}
{Array.from({ length: items }).map((_, i) => (
))}
);
const renderListSkeleton = () => (
{showTitle &&
}
{Array.from({ length: items }).map((_, i) => (
))}
);
const renderSkeleton = () => {
switch (variant) {
case 'form':
return renderFormSkeleton();
case 'detail':
return renderDetailSkeleton();
case 'list':
return renderListSkeleton();
case 'card':
default:
return renderCardSkeleton();
}
};
return (
);
}
// Export individual skeleton variants for specific use cases
export const CardLoader = (props: Omit) => ;
export const FormLoader = (props: Omit) => ;
export const DetailLoader = (props: Omit) => (
);
export const ListLoader = (props: Omit) => ;