New features: - Saved searches dashboard page with CRUD hooks and API client - Image lightbox component for property gallery full-screen viewing - Web vitals provider and reporting utilities for performance monitoring - Image blur placeholder generation utility Co-Authored-By: Paperclip <noreply@paperclip.ing>
54 lines
1.7 KiB
TypeScript
54 lines
1.7 KiB
TypeScript
/**
|
|
* Tiny SVG-based blur placeholder for next/image.
|
|
*
|
|
* Generates a small, inline base64-encoded SVG that next/image displays while
|
|
* the real image loads. This eliminates layout shift (CLS) and provides a smooth
|
|
* visual transition without needing to pre-compute per-image blur hashes.
|
|
*
|
|
* Usage:
|
|
* <Image placeholder="blur" blurDataURL={shimmerBlurDataURL()} ... />
|
|
*/
|
|
|
|
const SHIMMER_SVG = `
|
|
<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
<stop offset="0%" stop-color="#e5e7eb"/>
|
|
<stop offset="50%" stop-color="#f3f4f6"/>
|
|
<stop offset="100%" stop-color="#e5e7eb"/>
|
|
</linearGradient>
|
|
</defs>
|
|
<rect width="400" height="300" fill="#e5e7eb"/>
|
|
<rect width="400" height="300" fill="url(#g)">
|
|
<animate attributeName="x" from="-400" to="400" dur="1.5s" repeatCount="indefinite"/>
|
|
</rect>
|
|
</svg>`.trim();
|
|
|
|
const STATIC_BLUR_SVG = `
|
|
<svg width="8" height="6" xmlns="http://www.w3.org/2000/svg">
|
|
<rect width="8" height="6" fill="#d1d5db"/>
|
|
</svg>`.trim();
|
|
|
|
function toBase64(str: string): string {
|
|
if (typeof window === 'undefined') {
|
|
return Buffer.from(str).toString('base64');
|
|
}
|
|
return btoa(str);
|
|
}
|
|
|
|
/**
|
|
* Animated shimmer blur placeholder (for listing thumbnails).
|
|
* Shows a shimmer animation while the image loads.
|
|
*/
|
|
export function shimmerBlurDataURL(): string {
|
|
return `data:image/svg+xml;base64,${toBase64(SHIMMER_SVG)}`;
|
|
}
|
|
|
|
/**
|
|
* Static grey blur placeholder (for small thumbnails like table rows).
|
|
* Lightweight, no animation.
|
|
*/
|
|
export function staticBlurDataURL(): string {
|
|
return `data:image/svg+xml;base64,${toBase64(STATIC_BLUR_SVG)}`;
|
|
}
|