(props: {
value: string;
onChange: (value: string) => void;
brandColorSwatches?: OrganizationBrandColorSwatch[];
})
| 58 | } |
| 59 | |
| 60 | export function HexColorInput(props: { |
| 61 | value: string; |
| 62 | onChange: (value: string) => void; |
| 63 | brandColorSwatches?: OrganizationBrandColorSwatch[]; |
| 64 | }) { |
| 65 | const [text, setText] = createWritableMemo(() => props.value); |
| 66 | let prevColor = props.value; |
| 67 | let colorInput!: HTMLInputElement; |
| 68 | |
| 69 | const commitValue = (raw: string) => { |
| 70 | const normalized = normalizeOpaqueHexColor(raw); |
| 71 | if (normalized) { |
| 72 | props.onChange(normalized); |
| 73 | setText(normalized); |
| 74 | return true; |
| 75 | } |
| 76 | return false; |
| 77 | }; |
| 78 | |
| 79 | const selectBrandColor = (color: string) => { |
| 80 | setText(color); |
| 81 | prevColor = color; |
| 82 | props.onChange(color); |
| 83 | }; |
| 84 | |
| 85 | return ( |
| 86 | <div class="flex flex-col gap-2"> |
| 87 | <div class="flex flex-row items-center gap-[0.75rem] relative"> |
| 88 | <button |
| 89 | type="button" |
| 90 | class="size-[2rem] rounded-[0.5rem]" |
| 91 | style={{ |
| 92 | "background-color": text(), |
| 93 | "box-shadow": `inset 0 0 0 1px ${getColorPreviewBorderColor( |
| 94 | text(), |
| 95 | )}`, |
| 96 | }} |
| 97 | onClick={() => colorInput.click()} |
| 98 | /> |
| 99 | <input |
| 100 | ref={colorInput} |
| 101 | type="color" |
| 102 | class="absolute left-0 bottom-0 size-[2rem] opacity-0" |
| 103 | value={text()} |
| 104 | onChange={(e) => { |
| 105 | setText(e.target.value); |
| 106 | props.onChange(e.target.value); |
| 107 | }} |
| 108 | /> |
| 109 | <TextInput |
| 110 | class="w-[5rem] p-[0.375rem] border border-gray-3 text-gray-12 rounded-[0.5rem] bg-gray-2" |
| 111 | value={text()} |
| 112 | onFocus={() => { |
| 113 | prevColor = props.value; |
| 114 | }} |
| 115 | onKeyDown={(e) => { |
| 116 | if (e.key === "Enter") { |
| 117 | e.preventDefault(); |
nothing calls this directly
no test coverage detected