feat : use custom color picker

This commit is contained in:
2026-09-15 17:56:19 +07:00 Unverified
parent 072310091d
commit 45f11466fe
5 changed files with 696 additions and 9 deletions
+50 -7
View File
@@ -33,6 +33,7 @@ import {
} from "lucide-react";
import {
useEffect,
useCallback,
useRef,
useState,
type ChangeEvent,
@@ -80,6 +81,16 @@ import {
DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import {
ColorPicker,
ColorPickerHue,
ColorPickerSelection,
} from "@/components/ui/color-picker";
import { Slider } from "@/components/ui/slider";
import { Spinner } from "@/components/ui/spinner";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
@@ -559,17 +570,49 @@ function ColorField({
onChange: (value: string) => void;
}) {
const invalid = !normalizeHex(value);
const handlePickerChange = useCallback(
(color: number[] | Record<string, number>) => {
if (!Array.isArray(color)) return;
const hex = color
.slice(0, 3)
.map((channel) => Math.round(channel).toString(16).padStart(2, "0"))
.join("");
onChange(`#${hex.toUpperCase()}`);
},
[onChange],
);
return (
<Field data-invalid={invalid}>
<FieldLabel htmlFor={id}>{label}</FieldLabel>
<div className="flex gap-2">
<Input
aria-label={`${label} picker`}
type="color"
value={normalizeHex(value) ?? "#000000"}
onChange={(event) => onChange(event.target.value.toUpperCase())}
className="w-14 shrink-0 p-1"
/>
<Popover>
<PopoverTrigger
render={
<Button
type="button"
variant="outline"
size="icon"
aria-label={`เลือก${label}`}
>
<span
className="size-5 rounded-sm border"
style={{ backgroundColor: normalizeHex(value) ?? "#000000" }}
/>
</Button>
}
/>
<PopoverContent align="start" className="w-64">
<ColorPicker
value={normalizeHex(value) ?? "#000000"}
onChange={handlePickerChange}
className="h-auto"
>
<ColorPickerSelection className="h-32" />
<ColorPickerHue />
</ColorPicker>
</PopoverContent>
</Popover>
<Input
id={id}
value={value}