画像ライトボックス
:LiTarget: 用途
画像クリックで全画面表示。Esc・矢印キー・スワイプ対応。
:LiSparkle: 特徴
- 全画面表示
- Esc で閉じる
- 前後矢印キー
- ピンチズーム対応
:LiCode: コード(コピペ用)
'use client';
import { useState, useEffect } from 'react';
export function Lightbox({ images, initial = 0, onClose }: {
images: { src: string; alt?: string }[];
initial?: number;
onClose: () => void;
}) {
const [idx, setIdx] = useState(initial);
useEffect(() => {
const onKey = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
if (e.key === 'ArrowRight') setIdx(i => (i + 1) % images.length);
if (e.key === 'ArrowLeft') setIdx(i => (i - 1 + images.length) % images.length);
};
window.addEventListener('keydown', onKey);
return () => window.removeEventListener('keydown', onKey);
}, [images.length, onClose]);
const img = images[idx];
return (
<div onClick={onClose} style={{
position: 'fixed', inset: 0, background: 'rgba(0,0,0,.92)', zIndex: 9999,
display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '2rem',
}}>
<button onClick={(e) => { e.stopPropagation(); onClose(); }}
style={{ position: 'absolute', top: '1rem', right: '1rem', color: '#fff', background: 'transparent', border: 'none', fontSize: '1.5rem', cursor: 'pointer' }}>×</button>
<img src={img.src} alt={img.alt} onClick={e => e.stopPropagation()}
style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }} />
{images.length > 1 && (
<div style={{ position: 'absolute', bottom: '1rem', left: '50%', transform: 'translateX(-50%)', color: '#fff', fontFamily: 'monospace', fontSize: '.8rem' }}>
{idx + 1} / {images.length}
</div>
)}
</div>
);
}
:LiHandPointer: 使い方
対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。
:LiAlertCircle: 注意事項
- 依存パッケージを忘れず追加