import { useEffect, useRef, useState } from "react"; export type BottomControlColorPickerProps = { value: string; "aria-label": string; onValueChange: (value: string) => void; }; export function BottomControlColorPicker({ value, onValueChange, ...props }: BottomControlColorPickerProps) { const inputRef = useRef(null); const [draft, setDraft] = useState(value); useEffect(() => { setDraft(value); }, [value]); const commitDraft = () => { const normalized = normalizeHexColor(draft); if (!normalized) { setDraft(value); return; } setDraft(normalized); if (normalized !== value) onValueChange(normalized); }; return (
onValueChange(event.target.value)} /> setDraft(event.target.value)} onBlur={commitDraft} onFocus={(event) => event.currentTarget.select()} onKeyDown={(event) => { event.stopPropagation(); if (event.key === "Enter") { commitDraft(); event.currentTarget.blur(); } if (event.key === "Escape") { setDraft(value); event.currentTarget.blur(); } }} />
); } function normalizeHexColor(value: string): string | undefined { const trimmed = value.trim(); const hex = trimmed.startsWith("#") ? trimmed.slice(1) : trimmed; if (/^[0-9a-fA-F]{3}$/.test(hex)) { const [r, g, b] = hex; return `#${r}${r}${g}${g}${b}${b}`.toLowerCase(); } if (/^[0-9a-fA-F]{6}$/.test(hex)) return `#${hex}`.toLowerCase(); return undefined; }