Performance: - Add loading="lazy" decoding="async" to product card images - Preconnect to Square S3 image CDN and fonts.googleapis.com in layout - Cache-Control headers on catalog (20s), inventory (10s), occasions/categories (5min) Scroll lock: - Update useLockBodyScroll to use position:fixed + scroll-restore for iOS Safari - Apply same fix to CartDrawer's inline scroll lock Color names: - Remove word-break:break-word so single words never split across lines; multi-word names still wrap at spaces Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
28 lines
954 B
TypeScript
28 lines
954 B
TypeScript
import { useEffect } from 'react'
|
|
|
|
/** Locks body scroll while the calling component is mounted.
|
|
* Uses position:fixed + scroll-position restore so iOS Safari
|
|
* rubber-band scrolling is also prevented. */
|
|
export function useLockBodyScroll() {
|
|
useEffect(() => {
|
|
const scrollY = window.scrollY
|
|
const prevOverflow = document.body.style.overflow
|
|
const prevPosition = document.body.style.position
|
|
const prevTop = document.body.style.top
|
|
const prevWidth = document.body.style.width
|
|
|
|
document.body.style.overflow = 'hidden'
|
|
document.body.style.position = 'fixed'
|
|
document.body.style.top = `-${scrollY}px`
|
|
document.body.style.width = '100%'
|
|
|
|
return () => {
|
|
document.body.style.overflow = prevOverflow
|
|
document.body.style.position = prevPosition
|
|
document.body.style.top = prevTop
|
|
document.body.style.width = prevWidth
|
|
window.scrollTo(0, scrollY)
|
|
}
|
|
}, [])
|
|
}
|