59 lines
1.5 KiB
TypeScript
59 lines
1.5 KiB
TypeScript
import { AlertCircle, Image as ImageIcon, Loader2 } from 'lucide-react';
|
|
import { Box } from './Box';
|
|
import { Icon } from './Icon';
|
|
import { Text } from './Text';
|
|
|
|
export interface ImagePlaceholderProps {
|
|
width?: string | number;
|
|
height?: string | number;
|
|
animate?: 'pulse' | 'none' | 'spin';
|
|
aspectRatio?: string;
|
|
variant?: 'default' | 'loading' | 'error';
|
|
message?: string;
|
|
rounded?: string;
|
|
}
|
|
|
|
export const ImagePlaceholder = ({
|
|
width = '100%',
|
|
height = '100%',
|
|
animate = 'pulse',
|
|
aspectRatio,
|
|
variant = 'default',
|
|
message,
|
|
rounded
|
|
}: ImagePlaceholderProps) => {
|
|
const icons = {
|
|
default: ImageIcon,
|
|
loading: Loader2,
|
|
error: AlertCircle,
|
|
};
|
|
|
|
return (
|
|
<Box
|
|
width={width}
|
|
height={height}
|
|
aspectRatio={aspectRatio}
|
|
display="flex"
|
|
flexDirection="col"
|
|
alignItems="center"
|
|
justifyContent="center"
|
|
bg="var(--ui-color-bg-surface-muted)"
|
|
style={{ borderRadius: rounded === 'none' ? '0' : (rounded ? `var(--ui-radius-${rounded})` : 'var(--ui-radius-md)') }}
|
|
gap={2}
|
|
>
|
|
<Icon
|
|
icon={icons[variant]}
|
|
size={8}
|
|
intent="low"
|
|
animate={variant === 'loading' ? 'spin' : (animate === 'spin' ? 'spin' : 'none')}
|
|
className={animate === 'pulse' && variant !== 'loading' ? 'animate-pulse' : ''}
|
|
/>
|
|
{message && (
|
|
<Text size="xs" variant="low" align="center" paddingX={4}>
|
|
{message}
|
|
</Text>
|
|
)}
|
|
</Box>
|
|
);
|
|
};
|