Files
gunshiz e0794822b1
CI / Verify (push) Successful in 1m18s
CI / Build immutable images and deploy (push) Successful in 1m57s
feat(i18n) : add personal languages and compact weapon exports
2026-09-14 16:44:44 +07:00

81 lines
2.2 KiB
TypeScript

"use client";
import { useTranslation } from "@/components/i18n/locale-provider";
import { InfoIcon } from "lucide-react";
import { useSyncExternalStore } from "react";
import {
Drawer,
DrawerContent,
DrawerDescription,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card";
const finePointerQuery = "(hover: hover) and (pointer: fine)";
function subscribe(callback: () => void) {
const query = window.matchMedia(finePointerQuery);
query.addEventListener("change", callback);
return () => query.removeEventListener("change", callback);
}
function getSnapshot() {
return window.matchMedia(finePointerQuery).matches;
}
function Trigger({ label }: { label: string }) {
return (
<span className="inline-flex min-h-11 cursor-help items-center gap-1 rounded-md text-left font-medium underline decoration-border underline-offset-4 outline-none hover:text-primary focus-visible:ring-2 focus-visible:ring-ring md:min-h-0">
{label}
<InfoIcon aria-hidden="true" className="size-3.5 text-muted-foreground" />
</span>
);
}
export function TermDetail({
label,
detail,
}: {
label: string;
detail: string;
}) {
const { t } = useTranslation();
const finePointer = useSyncExternalStore(subscribe, getSnapshot, () => false);
if (finePointer) {
return (
<HoverCard>
<HoverCardTrigger aria-label={t("ดูรายละเอียด {label}", { label: label })}>
<Trigger label={label} />
</HoverCardTrigger>
<HoverCardContent align="start">
<p className="font-medium">{label}</p>
<p className="mt-1 text-muted-foreground">{detail}</p>
</HoverCardContent>
</HoverCard>
);
}
return (
<Drawer showSwipeHandle>
<DrawerTrigger aria-label={t("เปิดรายละเอียด {label}", { label: label })}>
<Trigger label={label} />
</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>{label}</DrawerTitle>
<DrawerDescription>{detail}</DrawerDescription>
</DrawerHeader>
<div className="h-6" />
</DrawerContent>
</Drawer>
);
}