import React, { useState } from "react"; import { ColorPicker, Popover, Dropdown, Button, Space, Tooltip, InputNumber, Input, } from "antd"; import type { ColorPickerProps } from "antd"; import noColorImg from "@/assets/icon/no-color.png"; import { ArrowRightOutlined, CaretDownOutlined, CheckOutlined, SwapOutlined, } from "@ant-design/icons"; import morePng from "@/assets/icon/more-color.png"; import insertCss from "insert-css"; import { useModel } from "umi"; // 系统色 const presetColors1 = [ "#EFECEB", "#F2F2F2", "#E7EBED", "#FADCDB", "#FBEADA", "#FCF9EA", "#E5F6DA", "#DBF5F5", "#D2D6F9", "#FADDED", "#DED9D7", "#D9D9D9", "#E0E0E0", "#F5B9B7", "#F8D5B5", "#F6EDC1", "#CAEDB4", "#B7EAEB", "#A6AEF3", "#F6BBDB", "#BEB3AF", "#BFBFBF", "#9E9E9E", "#F19594", "#F4C18F", "#F1E4A2", "#B0E38F", "#94E0E1", "#7985EC", "#F199C8", "#9D8C88", "#A6A6A6", "#616161", "#EC7270", "#F1AC6A", "#E9D66F", "#95DA69", "#70D5D7", "#5B79E8", "#ED77B6", "#5C4038", "#7F7F7F", "#262626", "#A23735", "#A66A30", "#A7932C", "#569230", "#358E90", "#314AA4", "#A23C73", ]; // 莫兰迪 const presetColors2 = [ "#F1F1E8", "#ECECED", "#F3FAF9", "#F4F0EA", "#F9FAEE", "#F8F9F5", "#F5E9ED", "#FCE7EB", "#F9EEE1", "#FEF5EF", "#E3E2D1", "#D9DADB", "#E8F5F4", "#E9E1D5", "#F3F6DD", "#F0F3EC", "#EBD2DC", "#F9CFD7", "#F3DDC3", "#FDEBDF", "#D6D4BA", "#C5C7CA", "#DCEFEE", "#DDD1C1", "#EEF1CB", "#E9ECE2", "#E0BCCA", "#F6B6C4", "#EDCCA5", "#FCE2CF", "#C8C5A3", "#B2B5B8", "#D1EAE9", "#D2C2AC", "#E8EDBA", "#E1E6D9", "#D6A5B9", "#F39EB0", "#E7BB87", "#FBD8BF", "#959270", "#7F8285", "#9EB7B6", "#9F8F79", "#B5BA87", "#AEB3A6", "#A37286", "#C06B7D", "#B48854", "#C8A58C", ]; // 中国风 const presetColors3 = [ "#866B50", "#705138", "#5A5645", "#5C3719", "#775550", "#5A1216", "#B0913E", "#964D22", "#E28342", "#C37940", "#2C2305", "#645822", "#6B5E4C", "#556980", "#70887D", "#5B8483", "#975F42", "#A2825E", "#DDAB4C", "#91A45A", "#4D5255", "#587D8C", "#737C7B", "#B1AD94", "#ADB4A9", "#467E7D", "#94B68E", "#894276", "#C36077", "#D59482", "#144A74", "#495C69", "#314656", "#134857", "#7E8489", "#8F927F", "#B2BBBE", "#67907C", "#539271", "#D2B116", "#322F3B", "#525288", "#8076A3", "#1A94BC", "#5D3131", "#314A43", "#C1651A", "#DE9E44", "#D2B116", "#D2D97A", ]; // 潘通色 const presetColors4 = [ "#E3F0E1", "#EEE7F1", "#E4D5D8", "#FDF8DC", "#DFE3F5", "#FFF1D5", "#DFE5DB", "#E2EFF5", "#DEE6E6", "#F9DDD6", "#C7E1C3", "#DED0E4", "#CAAAB1", "#FBF1B8", "#BFC7EA", "#FEE2AB", "#BFCAB6", "#C6DFEA", "#BDCECD", "#F3BBAD", "#ABD1A6", "#CDB8D6", "#AF808A", "#F8EB95", "#9EAAE0", "#FED480", "#A0B092", "#A9CEE0", "#9DB5B5", "#ED9984", "#8FC288", "#BDA1C9", "#955563", "#F6E471", "#7E8ED5", "#FDC556", "#80956D", "#8DBED5", "#7C9D9C", "#E7775B", "#5C8F55", "#8A6E96", "#622230", "#C3B13E", "#4B5BA2", "#CA9223", "#4D623A", "#5A8BA2", "#496A69", "#B44428", ]; const baseColor = [ "#FFFFFF", "#7F8B98", "#000000", "#E74F4C", "#ED9745", "#E0C431", "#7BD144", "#4CCBCD", "#4669EA", "#E855A4", ]; const colorTxts = ["系统色", "莫兰迪", "中国风", "潘通色"]; const colors = [presetColors1, presetColors2, presetColors3, presetColors4]; export default function CustomColorPicker(props: { onChange?: (color: string) => void; color?: string; pickerOption?: ColorPickerProps; children?: React.ReactNode; disabled?: boolean; otherPopoverAttr?: Partial[0]>; }) { const { color } = props; const [colorSystem, setColorSystem] = useState(0); const [colorType, setColorType] = useState<"rgb" | "hex">("rgb"); const [open, setOpen] = useState(false); const { historyColor, addHistoryCoolor } = useModel('appModel'); // 修改值 const onChange = (value: string) => { props.onChange?.(value); handleOpenChange(false); addHistoryCoolor(value); }; insertCss(` .rgb .shalu-input-number-input { padding: 0 !important; } `); const handleSystemAbsorption = () => { // @ts-ignore 系统拾色 const dropper = new EyeDropper(); dropper.open().then((result: { sRGBHex: string }) => { onChange(result.sRGBHex); }); }; const handleChangeColorType = () => { setColorType(colorType === "rgb" ? "hex" : "rgb"); }; // hex转rgb const hexToRGB = (hex?: string) => { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex || ""); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16), } : { r: 255, g: 255, b: 255, }; }; const handleChangeRGB = (value: number | null, type: "r" | "g" | "b") => { const rgb = hexToRGB(color); const val = value?.toString(16); onChange( `${type === "r" ? val : rgb.r}${type === "g" ? val : rgb.g}${type === "b" ? val : rgb.b}` ); }; const handleOpenChange = (newOpen: boolean) => { setOpen(newOpen && !props.disabled); }; const PopoverContent = () => { return (
{ return { key: index, label: ( setColorSystem(index)}> {colorSystem === index && } {item} ), }; }), }} >
{colorTxts[colorSystem]}
{[...colors[colorSystem], ...baseColor].map((item, index) => { return (
onChange(item)} /> ); })}
最近使用
{[...historyColor].map((item, index) => { return (
onChange(item)} /> ); })}
{colorType === "rgb" ? (
handleChangeRGB(value, "r")} /> handleChangeRGB(value, "g")} /> handleChangeRGB(value, "b")} />
) : ( )}
onChange(value.toHexString())} className="w-0 h-0" >
); }; const backgroundStyle = color === "transparent" ? { background: `url(${noColorImg})`, backgroundSize: "cover" } : { background: color }; const popoverAttrs = props.otherPopoverAttr || {}; return (
} trigger="click" placement="bottom" arrow={false} open={open} onOpenChange={handleOpenChange} {...popoverAttrs} > {props.children ? ( props.children ) : (
)}
); }