import { isTransparent } from "../../utils"; import type { ExcalidrawElement } from "../../element/types"; import type { AppState } from "../../types"; import { TopPicks } from "./TopPicks"; import { ButtonSeparator } from "../ButtonSeparator"; import { Picker } from "./Picker"; import * as Popover from "@radix-ui/react-popover"; import type { ColorPickerType } from "./colorPickerUtils"; import { activeColorPickerSectionAtom } from "./colorPickerUtils"; import { useExcalidrawContainer } from "../App"; import type { ColorTuple, ColorPaletteCustom } from "../../colors"; import { COLOR_PALETTE } from "../../colors"; import PickerHeading from "./PickerHeading"; import { t } from "../../i18n"; import clsx from "clsx"; import { useRef } from "react"; import { useAtom } from "../../editor-jotai"; import { ColorInput } from "./ColorInput"; import { activeEyeDropperAtom } from "../EyeDropper"; import { PropertiesPopover } from "../PropertiesPopover"; import "./ColorPicker.scss"; const isValidColor = (color: string) => { const style = new Option().style; style.color = color; return !!style.color; }; export const getColor = (color: string): string | null => { if (isTransparent(color)) { return color; } // testing for `#` first fixes a bug on Electron (more specfically, an // Obsidian popout window), where a hex color without `#` is (incorrectly) // considered valid return isValidColor(`#${color}`) ? `#${color}` : isValidColor(color) ? color : null; }; interface ColorPickerProps { type: ColorPickerType; color: string; onChange: (color: string) => void; label: string; elements: readonly ExcalidrawElement[]; appState: AppState; palette?: ColorPaletteCustom | null; topPicks?: ColorTuple; updateData: (formData?: any) => void; } const ColorPickerPopupContent = ({ type, color, onChange, label, elements, palette = COLOR_PALETTE, updateData, }: Pick< ColorPickerProps, | "type" | "color" | "onChange" | "label" | "elements" | "palette" | "updateData" >) => { const { container } = useExcalidrawContainer(); const [, setActiveColorPickerSection] = useAtom(activeColorPickerSectionAtom); const [eyeDropperState, setEyeDropperState] = useAtom(activeEyeDropperAtom); const colorInputJSX = (