From e0e16ac8cee652c59caae6d85d58bcd750fae624 Mon Sep 17 00:00:00 2001 From: Trang Doan Date: Tue, 18 Nov 2025 22:16:49 -0500 Subject: [PATCH 1/2] relation type color picking --- .../components/RelationshipTypeSettings.tsx | 134 ++++++++++++++++-- .../canvas/DiscourseRelationTool.ts | 2 + .../canvas/overlays/RelationPanel.tsx | 3 +- .../components/canvas/utils/relationUtils.tsx | 21 ++- apps/obsidian/src/constants.ts | 6 +- apps/obsidian/src/types.ts | 3 +- apps/obsidian/src/utils/tldrawColors.ts | 60 ++++++++ 7 files changed, 205 insertions(+), 24 deletions(-) create mode 100644 apps/obsidian/src/utils/tldrawColors.ts diff --git a/apps/obsidian/src/components/RelationshipTypeSettings.tsx b/apps/obsidian/src/components/RelationshipTypeSettings.tsx index 24a20ecf3..e3a5f3737 100644 --- a/apps/obsidian/src/components/RelationshipTypeSettings.tsx +++ b/apps/obsidian/src/components/RelationshipTypeSettings.tsx @@ -1,9 +1,112 @@ -import { useState } from "react"; +import { useState, useRef, useEffect } from "react"; import { DiscourseRelationType } from "~/types"; import { Notice } from "obsidian"; import { usePlugin } from "./PluginContext"; import generateUid from "~/utils/generateUid"; import { ConfirmationModal } from "./ConfirmationModal"; +import { + TLDRAW_COLOR_NAMES, + TLDRAW_COLOR_LABELS, + DEFAULT_TLDRAW_COLOR, + COLOR_PALETTE, + type TldrawColorName, +} from "~/utils/tldrawColors"; +import { getContrastColor } from "~/utils/colorUtils"; + +type ColorPickerProps = { + value: string; + onChange: (color: TldrawColorName) => void; +}; + +const ColorPicker = ({ value, onChange }: ColorPickerProps) => { + const [isOpen, setIsOpen] = useState(false); + const dropdownRef = useRef(null); + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if ( + dropdownRef.current && + !dropdownRef.current.contains(event.target as Node) + ) { + setIsOpen(false); + } + }; + + if (isOpen) { + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + } + }, [isOpen]); + + const currentColor = value as TldrawColorName; + const bgColor = COLOR_PALETTE[currentColor] ?? COLOR_PALETTE.black; + const textColor = getContrastColor(bgColor ?? DEFAULT_TLDRAW_COLOR); + + return ( +
+ + + {isOpen && ( +
+ {TLDRAW_COLOR_NAMES.map((colorName) => { + const bgColor = COLOR_PALETTE[colorName] ?? COLOR_PALETTE.black; + return ( + + ); + })} +
+ )} +
+ ); +}; const RelationshipTypeSettings = () => { const plugin = usePlugin(); @@ -24,11 +127,14 @@ const RelationshipTypeSettings = () => { id: newId, label: "", complement: "", - color: "#000000", + color: DEFAULT_TLDRAW_COLOR, }; } - - updatedRelationTypes[index][field] = value; + if (field === "color") { + updatedRelationTypes[index].color = value as TldrawColorName; + } else { + updatedRelationTypes[index][field] = value; + } setRelationTypes(updatedRelationTypes); setHasUnsavedChanges(true); }; @@ -42,7 +148,7 @@ const RelationshipTypeSettings = () => { id: newId, label: "", complement: "", - color: "#000000", + color: DEFAULT_TLDRAW_COLOR, }, ]; setRelationTypes(updatedRelationTypes); @@ -53,7 +159,7 @@ const RelationshipTypeSettings = () => { const relationType = relationTypes[index] || { label: "Unnamed", complement: "", - color: "#000000", + color: DEFAULT_TLDRAW_COLOR, }; const modal = new ConfirmationModal(plugin.app, { title: "Delete Relation Type", @@ -84,7 +190,12 @@ const RelationshipTypeSettings = () => { const handleSave = async (): Promise => { for (const relType of relationTypes) { - if (!relType.id || !relType.label || !relType.complement || !relType.color) { + if ( + !relType.id || + !relType.label || + !relType.complement || + !relType.color + ) { new Notice("All fields are required for relation types."); return; } @@ -132,14 +243,11 @@ const RelationshipTypeSettings = () => { } className="flex-1" /> - - handleRelationTypeChange(index, "color", e.target.value) + onChange={(color) => + handleRelationTypeChange(index, "color", color) } - className="w-12 h-8 rounded border" - title="Relation color" />