import { CONDITION_DEFINITIONS, type ConditionId } from "@initiative/domain"; import type { LucideIcon } from "lucide-react"; import { ArrowDown, Ban, BatteryLow, Droplet, EarOff, EyeOff, Gem, Ghost, Hand, Heart, Link, Moon, Siren, Sparkles, ZapOff, } from "lucide-react"; import { useEffect, useLayoutEffect, useRef, useState } from "react"; import { cn } from "../lib/utils"; const ICON_MAP: Record = { EyeOff, Heart, EarOff, BatteryLow, Siren, Hand, Ban, Ghost, ZapOff, Gem, Droplet, ArrowDown, Link, Sparkles, Moon, }; const COLOR_CLASSES: Record = { neutral: "text-muted-foreground", pink: "text-pink-400", amber: "text-amber-400", orange: "text-orange-400", gray: "text-gray-400", violet: "text-violet-400", yellow: "text-yellow-400", slate: "text-slate-400", green: "text-green-400", indigo: "text-indigo-400", }; interface ConditionPickerProps { activeConditions: readonly ConditionId[] | undefined; onToggle: (conditionId: ConditionId) => void; onClose: () => void; } export function ConditionPicker({ activeConditions, onToggle, onClose, }: Readonly) { const ref = useRef(null); const [flipped, setFlipped] = useState(false); const [maxHeight, setMaxHeight] = useState(undefined); useLayoutEffect(() => { const el = ref.current; if (!el) return; const rect = el.getBoundingClientRect(); const spaceBelow = window.innerHeight - rect.top; const spaceAbove = rect.bottom; const shouldFlip = rect.bottom > window.innerHeight && spaceAbove > spaceBelow; setFlipped(shouldFlip); const available = shouldFlip ? spaceAbove : spaceBelow; if (rect.height > available) { setMaxHeight(available - 16); } }, []); useEffect(() => { function handleClickOutside(e: MouseEvent) { if (ref.current && !ref.current.contains(e.target as Node)) { onClose(); } } document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, [onClose]); const active = new Set(activeConditions ?? []); return (
{CONDITION_DEFINITIONS.map((def) => { const Icon = ICON_MAP[def.iconName]; if (!Icon) return null; const isActive = active.has(def.id); const colorClass = COLOR_CLASSES[def.color] ?? "text-muted-foreground"; return ( ); })}
); }