103 lines
3.4 KiB
JavaScript
103 lines
3.4 KiB
JavaScript
let previewOverlay = null
|
|
let previewImage = null
|
|
let previewCaption = null
|
|
let scrollPosition = 0
|
|
|
|
function ensurePreviewOverlay() {
|
|
if (previewOverlay) {
|
|
return previewOverlay
|
|
}
|
|
|
|
previewOverlay = document.createElement('div')
|
|
previewOverlay.className = 'fixed inset-0 z-[130] hidden items-center justify-center bg-[#020611e8] p-4 backdrop-blur-md'
|
|
previewOverlay.setAttribute('role', 'dialog')
|
|
previewOverlay.setAttribute('aria-modal', 'true')
|
|
previewOverlay.setAttribute('aria-label', 'Image preview')
|
|
|
|
const frame = document.createElement('div')
|
|
frame.className = 'relative max-h-[92vh] max-w-6xl'
|
|
|
|
previewImage = document.createElement('img')
|
|
previewImage.className = 'max-h-[92vh] max-w-full rounded-[28px] border border-white/10 shadow-[0_28px_90px_rgba(2,6,23,0.6)]'
|
|
previewImage.alt = 'Image preview'
|
|
|
|
previewCaption = document.createElement('div')
|
|
previewCaption.className = 'absolute inset-x-0 bottom-0 rounded-b-[28px] bg-gradient-to-t from-black/80 to-transparent px-5 py-4 text-sm font-medium text-white/90'
|
|
|
|
const closeButton = document.createElement('button')
|
|
closeButton.type = 'button'
|
|
closeButton.setAttribute('aria-label', 'Close image preview')
|
|
closeButton.className = 'absolute right-4 top-4 inline-flex h-11 w-11 items-center justify-center rounded-full border border-white/10 bg-black/35 text-white transition hover:border-white/25 hover:bg-white/10'
|
|
closeButton.innerHTML = '<i class="fa-solid fa-xmark text-lg"></i>'
|
|
closeButton.addEventListener('click', hidePreview)
|
|
|
|
frame.appendChild(previewImage)
|
|
frame.appendChild(previewCaption)
|
|
frame.appendChild(closeButton)
|
|
previewOverlay.appendChild(frame)
|
|
|
|
previewOverlay.addEventListener('click', (event) => {
|
|
if (event.target === previewOverlay) {
|
|
hidePreview()
|
|
}
|
|
})
|
|
|
|
document.body.appendChild(previewOverlay)
|
|
return previewOverlay
|
|
}
|
|
|
|
function showPreview(src, alt) {
|
|
if (!src) return
|
|
|
|
ensurePreviewOverlay()
|
|
scrollPosition = window.scrollY || document.documentElement.scrollTop || 0
|
|
document.body.style.position = 'fixed'
|
|
document.body.style.top = `-${scrollPosition}px`
|
|
document.body.style.left = '0'
|
|
document.body.style.right = '0'
|
|
document.body.style.width = '100%'
|
|
|
|
previewImage.src = src
|
|
previewImage.alt = alt || 'Image preview'
|
|
previewCaption.textContent = alt || 'Image preview'
|
|
previewOverlay.classList.remove('hidden')
|
|
previewOverlay.classList.add('flex')
|
|
}
|
|
|
|
function hidePreview() {
|
|
if (!previewOverlay) return
|
|
|
|
previewOverlay.classList.add('hidden')
|
|
previewOverlay.classList.remove('flex')
|
|
previewImage.removeAttribute('src')
|
|
document.body.style.position = ''
|
|
document.body.style.top = ''
|
|
document.body.style.left = ''
|
|
document.body.style.right = ''
|
|
document.body.style.width = ''
|
|
window.scrollTo(0, scrollPosition)
|
|
}
|
|
|
|
function handleNewsImagePreview(event) {
|
|
const trigger = event.target?.closest?.('[data-news-image-preview]')
|
|
if (!trigger) return
|
|
|
|
const src = trigger.getAttribute('data-news-image-src') || trigger.getAttribute('href')
|
|
if (!src) return
|
|
|
|
event.preventDefault()
|
|
showPreview(src, trigger.getAttribute('data-news-image-alt') || trigger.getAttribute('aria-label') || 'Image preview')
|
|
}
|
|
|
|
function handleKeyDown(event) {
|
|
if (event.key === 'Escape') {
|
|
hidePreview()
|
|
}
|
|
}
|
|
|
|
if (typeof document !== 'undefined') {
|
|
document.addEventListener('click', handleNewsImagePreview)
|
|
document.addEventListener('keydown', handleKeyDown)
|
|
}
|
|
|
|
export default null |