"use client";
import { type ReactNode, useRef, useState } from "react";
import {
HINT_DELAY_MS,
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import {
DIVE_TYPE_ABBREVIATIONS,
DIVE_TYPE_LABELS,
WATER_TYPE_ABBREVIATIONS,
WATER_TYPE_LABELS,
type Dive,
} from "@/lib/api/dives";
import { labelOrFallback } from "@/lib/api/labels";
import { owedDeco } from "@/lib/dive-recordings";
// One chip, bordered in its text's colour, with what it stands for in full as
// its hover hint and in a screen reader's words. Without the text's glow, as a
// map's credit chip is: its fill lifts it.
//
// A finger has no hover, so a tap shows the hint, until a press elsewhere. Its
// hit area grows to 44px up and down only, so two chips side by side keep their
// own.
function Chip({ text, label }: { text: string; label: string }) {
const [hovered, setHovered] = useState(false);
const [tapped, setTapped] = useState(false);
const finger = useRef(false);
return (
{
setHovered(open);
if (!open) setTapped(false);
}}
>
{/* The name is already in the chip's words, so the hint describes
nothing a screen reader has not heard: `IconTooltip`'s override. */}
{
finger.current = event.pointerType !== "mouse";
}}
onClick={() => {
if (finger.current) setTapped(true);
}}
render={
}
>
{text}{label}{label}
);
}
// One of the diver's tags, in the brand's teal, its words its own: there is
// nothing shorter to show and nothing longer to hint at. A name too long for
// the row ends in an ellipsis rather than overflowing it.
function TagChip({ tag }: { tag: string }) {
return (
{tag}
);
}
/**
* The chips over a dive's title, on its card and its page's hero alike: the
* water, then the kind of dive, then whether it owed decompression, then the
* diver's tags in their order. Salt water, open circuit and a no-stop dive
* have none - each goes without saying - and a dive with none of the four has
* no row. Lifted over a card's link, so its hints are reachable by a mouse; on
* a card a finger's tap goes through them to the link (`DiveCard`).
*/
export function diveChips(dive: Dive): ReactNode {
const water = dive.water_type && WATER_TYPE_ABBREVIATIONS[dive.water_type];
const type = dive.type && DIVE_TYPE_ABBREVIATIONS[dive.type];
const deco = owedDeco(dive);
const tags = dive.tags ?? [];
if (!water && !type && !deco && tags.length === 0) return null;
return (