import { useState, useRef, useEffect } from "react"; import { MoreHorizontal } from "lucide-react"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { useBoardStore } from "@/stores/board-store"; import type { Column, ColumnWidth } from "@/types/board"; interface ColumnHeaderProps { column: Column; cardCount: number; filteredCount?: number; } const COLOR_PRESETS = [ { hue: "160", label: "Teal" }, { hue: "240", label: "Blue" }, { hue: "300", label: "Purple" }, { hue: "350", label: "Pink" }, { hue: "25", label: "Red" }, { hue: "55", label: "Orange" }, { hue: "85", label: "Yellow" }, { hue: "130", label: "Lime" }, { hue: "200", label: "Cyan" }, { hue: "0", label: "Slate" }, ]; export function ColumnHeader({ column, cardCount, filteredCount }: ColumnHeaderProps) { const [editing, setEditing] = useState(false); const [editValue, setEditValue] = useState(column.title); const inputRef = useRef(null); const updateColumnTitle = useBoardStore((s) => s.updateColumnTitle); const deleteColumn = useBoardStore((s) => s.deleteColumn); const setColumnWidth = useBoardStore((s) => s.setColumnWidth); const setColumnColor = useBoardStore((s) => s.setColumnColor); const setColumnWipLimit = useBoardStore((s) => s.setColumnWipLimit); const toggleColumnCollapse = useBoardStore((s) => s.toggleColumnCollapse); useEffect(() => { if (editing && inputRef.current) { inputRef.current.focus(); inputRef.current.select(); } }, [editing]); function commitRename() { const trimmed = editValue.trim(); if (trimmed && trimmed !== column.title) { updateColumnTitle(column.id, trimmed); } else { setEditValue(column.title); } setEditing(false); } function handleKeyDown(e: React.KeyboardEvent) { if (e.key === "Enter") { commitRename(); } else if (e.key === "Escape") { setEditValue(column.title); setEditing(false); } } function handleWidthChange(width: ColumnWidth) { setColumnWidth(column.id, width); } return (
{editing ? ( setEditValue(e.target.value)} onBlur={commitRename} onKeyDown={handleKeyDown} aria-label="Column title" className="h-5 w-full bg-transparent font-mono text-xs font-semibold uppercase tracking-widest text-pylon-text-secondary outline-none" /> ) : ( { setEditValue(column.title); setEditing(true); }} > {column.title} )} column.wipLimit ? "text-pylon-danger font-bold" : column.wipLimit != null && cardCount === column.wipLimit ? "text-[oklch(65%_0.15_70)]" : "text-pylon-text-secondary" }`}> {filteredCount != null ? `${filteredCount} of ` : ""}{cardCount}{column.wipLimit != null ? `/${column.wipLimit}` : ""}
{ setEditValue(column.title); setEditing(true); }} > Rename toggleColumnCollapse(column.id)}> Collapse Width handleWidthChange(v as ColumnWidth)}> Narrow Standard Wide Color setColumnColor(column.id, null)} > None
{COLOR_PRESETS.map(({ hue, label }) => (
WIP Limit setColumnWipLimit(column.id, v === "none" ? null : parseInt(v))} > None 3 5 7 10 deleteColumn(column.id)} > Delete
); }