Files
tech-log-frontend/src/features/tech-log/presentation/shared/public-render/evidence-figure.tsx
T

100 lines
2.3 KiB
TypeScript

import { useId, useRef } from "react";
import type { ResolveEvidenceAsset } from "../../../domain/public-render-content.ts";
type PublicEvidenceFigureProps = {
evidenceKey: string;
alt: string;
caption: string;
zoom: boolean;
resolveEvidenceAsset: ResolveEvidenceAsset;
};
export function PublicEvidenceFigure({
evidenceKey,
alt,
caption,
zoom,
resolveEvidenceAsset,
}: PublicEvidenceFigureProps) {
const asset = resolveEvidenceAsset(evidenceKey);
const descriptionId = useId();
const triggerRef = useRef<HTMLButtonElement>(null);
const dialogRef = useRef<HTMLDialogElement>(null);
function open() {
dialogRef.current?.showModal();
}
function close() {
dialogRef.current?.close();
}
if (!zoom) {
return (
<figure className="evidence-figure">
<img
src={asset.src}
width={asset.width}
height={asset.height}
alt={alt}
loading="lazy"
/>
<figcaption>{caption}</figcaption>
</figure>
);
}
return (
<>
<figure className="evidence-figure">
<button
ref={triggerRef}
className="evidence-image-button"
type="button"
aria-label={asset.triggerLabel}
aria-describedby={descriptionId}
onClick={open}
>
<img
src={asset.src}
width={asset.width}
height={asset.height}
alt={alt}
loading="lazy"
/>
<span>크게 보기</span>
<span className="visually-hidden" id={descriptionId}>
{alt}
</span>
</button>
<figcaption>{caption}</figcaption>
</figure>
<dialog
ref={dialogRef}
className="figure-dialog"
aria-label={asset.dialogLabel}
onClose={() => triggerRef.current?.focus()}
onClick={(event) => {
if (event.target === event.currentTarget) close();
}}
>
<div>
<button type="button" className="dialog-close" onClick={close}>
닫기
</button>
<img
src={asset.src}
width={asset.width}
height={asset.height}
alt={alt}
loading="lazy"
/>
<p>{caption}</p>
</div>
</dialog>
</>
);
}