Files
kandev/apps/web/components/task/chat/image-preview-dialog.tsx
T
João Salavisa d3058276d7 feat(i18n): localize task chat surface (#2303)
Co-authored-by: Kandev Agent <agent@kandev.dev>
2026-08-06 03:01:51 +02:00

66 lines
1.9 KiB
TypeScript

"use client";
import { Dialog, DialogContent, DialogTitle, DialogTrigger } from "@kandev/ui/dialog";
import { cn } from "@/lib/utils";
import { useTranslation } from "react-i18next";
type ImagePreviewDialogProps = {
src: string;
alt: string;
thumbnailClassName?: string;
interactive?: boolean;
};
export const IMAGE_PREVIEW_DIALOG_CONTENT_CLASSNAME =
"flex w-fit max-w-[calc(100vw-1rem)] items-center justify-center overflow-hidden p-2 sm:max-w-[calc(100vw-2rem)] sm:p-3";
const IMAGE_PREVIEW_IMAGE_CLASSNAME =
"block h-auto max-h-[calc(100dvh-5rem)] w-[min(92vw,1100px)] max-w-full rounded object-contain";
type ImagePreviewContentProps = {
src: string;
alt: string;
};
export function ImagePreviewContent({ src, alt }: ImagePreviewContentProps) {
const { t } = useTranslation();
return (
<>
<DialogTitle className="sr-only">{t("task:imagePreview")}</DialogTitle>
<img src={src} alt={alt} className={IMAGE_PREVIEW_IMAGE_CLASSNAME} />
</>
);
}
export function ImagePreviewDialog({
src,
alt,
thumbnailClassName,
interactive = true,
}: ImagePreviewDialogProps) {
const { t } = useTranslation();
if (!interactive) {
return <img src={src} alt={alt} className={thumbnailClassName} />;
}
return (
<Dialog>
<DialogTrigger asChild>
<button
type="button"
aria-label={t("task:openImage", { alt })}
className="inline-flex max-w-full cursor-pointer items-center justify-center rounded-md focus:outline-none focus:ring-2 focus:ring-primary"
>
<img src={src} alt="" className={cn("pointer-events-none", thumbnailClassName)} />
</button>
</DialogTrigger>
<DialogContent
aria-describedby={undefined}
className={IMAGE_PREVIEW_DIALOG_CONTENT_CLASSNAME}
>
<ImagePreviewContent src={src} alt={t("task:fullSize", { alt })} />
</DialogContent>
</Dialog>
);
}