From 6ec259a0e71174651bae95d4628138bf6fd68742 Mon Sep 17 00:00:00 2001 From: kj_sh604 Date: Sun, 15 Mar 2026 16:19:35 -0400 Subject: refactor: packages/ --- .../excalidraw/components/ColorPicker/Picker.tsx | 178 +++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 packages/excalidraw/components/ColorPicker/Picker.tsx (limited to 'packages/excalidraw/components/ColorPicker/Picker.tsx') diff --git a/packages/excalidraw/components/ColorPicker/Picker.tsx b/packages/excalidraw/components/ColorPicker/Picker.tsx new file mode 100644 index 0000000..88d6876 --- /dev/null +++ b/packages/excalidraw/components/ColorPicker/Picker.tsx @@ -0,0 +1,178 @@ +import React, { useEffect, useState } from "react"; +import { t } from "../../i18n"; + +import type { ExcalidrawElement } from "../../element/types"; +import { ShadeList } from "./ShadeList"; + +import PickerColorList from "./PickerColorList"; +import { useAtom } from "../../editor-jotai"; +import { CustomColorList } from "./CustomColorList"; +import { colorPickerKeyNavHandler } from "./keyboardNavHandlers"; +import PickerHeading from "./PickerHeading"; +import type { ColorPickerType } from "./colorPickerUtils"; +import { + activeColorPickerSectionAtom, + getColorNameAndShadeFromColor, + getMostUsedCustomColors, + isCustomColor, +} from "./colorPickerUtils"; +import type { ColorPaletteCustom } from "../../colors"; +import { + DEFAULT_ELEMENT_BACKGROUND_COLOR_INDEX, + DEFAULT_ELEMENT_STROKE_COLOR_INDEX, +} from "../../colors"; +import { KEYS } from "../../keys"; +import { EVENT } from "../../constants"; + +interface PickerProps { + color: string; + onChange: (color: string) => void; + label: string; + type: ColorPickerType; + elements: readonly ExcalidrawElement[]; + palette: ColorPaletteCustom; + updateData: (formData?: any) => void; + children?: React.ReactNode; + onEyeDropperToggle: (force?: boolean) => void; + onEscape: (event: React.KeyboardEvent | KeyboardEvent) => void; +} + +export const Picker = ({ + color, + onChange, + label, + type, + elements, + palette, + updateData, + children, + onEyeDropperToggle, + onEscape, +}: PickerProps) => { + const [customColors] = React.useState(() => { + if (type === "canvasBackground") { + return []; + } + return getMostUsedCustomColors(elements, type, palette); + }); + + const [activeColorPickerSection, setActiveColorPickerSection] = useAtom( + activeColorPickerSectionAtom, + ); + + const colorObj = getColorNameAndShadeFromColor({ + color, + palette, + }); + + useEffect(() => { + if (!activeColorPickerSection) { + const isCustom = isCustomColor({ color, palette }); + const isCustomButNotInList = isCustom && !customColors.includes(color); + + setActiveColorPickerSection( + isCustomButNotInList + ? "hex" + : isCustom + ? "custom" + : colorObj?.shade != null + ? "shades" + : "baseColors", + ); + } + }, [ + activeColorPickerSection, + color, + palette, + setActiveColorPickerSection, + colorObj, + customColors, + ]); + + const [activeShade, setActiveShade] = useState( + colorObj?.shade ?? + (type === "elementBackground" + ? DEFAULT_ELEMENT_BACKGROUND_COLOR_INDEX + : DEFAULT_ELEMENT_STROKE_COLOR_INDEX), + ); + + useEffect(() => { + if (colorObj?.shade != null) { + setActiveShade(colorObj.shade); + } + + const keyup = (event: KeyboardEvent) => { + if (event.key === KEYS.ALT) { + onEyeDropperToggle(false); + } + }; + document.addEventListener(EVENT.KEYUP, keyup, { capture: true }); + return () => { + document.removeEventListener(EVENT.KEYUP, keyup, { capture: true }); + }; + }, [colorObj, onEyeDropperToggle]); + + const pickerRef = React.useRef(null); + + return ( +
+
{ + const handled = colorPickerKeyNavHandler({ + event, + activeColorPickerSection, + palette, + color, + onChange, + onEyeDropperToggle, + customColors, + setActiveColorPickerSection, + updateData, + activeShade, + onEscape, + }); + + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } + }} + className="color-picker-content properties-content" + // to allow focusing by clicking but not by tabbing + tabIndex={-1} + > + {!!customColors.length && ( +
+ + {t("colorPicker.mostUsedCustomColors")} + + +
+ )} + +
+ {t("colorPicker.colors")} + +
+ +
+ {t("colorPicker.shades")} + +
+ {children} +
+
+ ); +}; -- cgit v1.2.3