diff --git a/Data/Server/WebUI/src/Borealis.css b/Data/Server/WebUI/src/Borealis.css index 24c28f5..aadeb8d 100644 --- a/Data/Server/WebUI/src/Borealis.css +++ b/Data/Server/WebUI/src/Borealis.css @@ -88,13 +88,13 @@ position: absolute; left: 0; top: 0; - width: 3px; /* Accent width */ + width: 3px; height: 100%; background: linear-gradient( to bottom, - #58a6ff 0%, - #0475c2 100% - ); /* Or any accent color(s) you want */ + var(--borealis-accent, #58a6ff) 0%, + var(--borealis-accent-dark, #0475c2) 100% + ); border-top-left-radius: 4px; border-bottom-left-radius: 4px; } @@ -104,7 +104,7 @@ border-top-left-radius: 4px; border-top-right-radius: 4px; font-weight: bold; - color: #58a6ff; + color: var(--borealis-title, #58a6ff); font-size: 10px; } .borealis-node-content { diff --git a/Data/Server/WebUI/src/Node_Configuration_Sidebar.jsx b/Data/Server/WebUI/src/Node_Configuration_Sidebar.jsx index 4a3936a..81d4e09 100644 --- a/Data/Server/WebUI/src/Node_Configuration_Sidebar.jsx +++ b/Data/Server/WebUI/src/Node_Configuration_Sidebar.jsx @@ -1,9 +1,24 @@ ////////// PROJECT FILE SEPARATION LINE ////////// CODE AFTER THIS LINE ARE FROM: /Data/WebUI/src/Node_Configuration_Sidebar.jsx -import { Box, Typography, Tabs, Tab, TextField, MenuItem, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button } from "@mui/material"; +import { Box, Typography, Tabs, Tab, TextField, MenuItem, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button, Tooltip } from "@mui/material"; import React, { useState } from "react"; import { useReactFlow } from "reactflow"; import ReactMarkdown from "react-markdown"; // Used for Node Usage Documentation import EditIcon from "@mui/icons-material/Edit"; +import PaletteIcon from "@mui/icons-material/Palette"; +import { SketchPicker } from "react-color"; + +// ---- NEW: Brightness utility for gradient ---- +function darkenColor(hex, percent = 0.7) { + if (!/^#[0-9A-Fa-f]{6}$/.test(hex)) return hex; + let r = parseInt(hex.slice(1, 3), 16); + let g = parseInt(hex.slice(3, 5), 16); + let b = parseInt(hex.slice(5, 7), 16); + r = Math.round(r * percent); + g = Math.round(g * percent); + b = Math.round(b * percent); + return `#${r.toString(16).padStart(2,"0")}${g.toString(16).padStart(2,"0")}${b.toString(16).padStart(2,"0")}`; +} +// -------------------------------------------- export default function NodeConfigurationSidebar({ drawerOpen, setDrawerOpen, title, nodeData, setNodes, selectedNode }) { const [activeTab, setActiveTab] = useState(0); @@ -16,6 +31,11 @@ export default function NodeConfigurationSidebar({ drawerOpen, setDrawerOpen, ti const [renameOpen, setRenameOpen] = useState(false); const [renameValue, setRenameValue] = useState(title || ""); + // ---- NEW: Accent Color Picker ---- + const [colorDialogOpen, setColorDialogOpen] = useState(false); + const accentColor = selectedNode?.data?.accentColor || "#58a6ff"; + // ---------------------------------- + const renderConfigFields = () => { const config = nodeData?.config || []; const nodeId = nodeData?.nodeId; @@ -39,11 +59,21 @@ export default function NodeConfigurationSidebar({ drawerOpen, setDrawerOpen, ti const newValue = e.target.value; if (!nodeId) return; effectiveSetNodes((nds) => - nds.map((n) => - n.id === nodeId - ? { ...n, data: { ...n.data, [field.key]: newValue } } - : n - ) + nds.map((n) => { + if (n.id !== nodeId) return n; + const accentColor = color.hex; + const accentColorDark = darkenColor(accentColor, 0.7); + return { + ...n, + data: { ...n.data, accentColor }, + style: { + ...n.style, + "--borealis-accent": accentColor, + "--borealis-accent-dark": accentColorDark, + "--borealis-title": accentColor, + }, + }; + }) ); window.BorealisValueBus[nodeId] = newValue; }} @@ -133,6 +163,27 @@ export default function NodeConfigurationSidebar({ drawerOpen, setDrawerOpen, ti }); }; + // ---- NEW: Accent Color Button ---- + const renderAccentColorButton = () => ( + + setColorDialogOpen(true)} + sx={{ + ml: 1, + border: "1px solid #58a6ff", + background: accentColor, + color: "#222", + width: 28, height: 28, p: 0 + }} + > + + + + ); + // ---------------------------------- + return ( <> {"Edit " + (title || "Node")} - { - setRenameValue(title || ""); - setRenameOpen(true); - }} - sx={{ ml: 1, color: "#58a6ff" }} - > - - + + { + setRenameValue(title || ""); + setRenameOpen(true); + }} + sx={{ ml: 1, color: "#58a6ff" }} + > + + + {/* ---- NEW: Accent Color Picker button next to pencil ---- */} + {renderAccentColorButton()} + {/* ------------------------------------------------------ */} + + + {/* ---- NEW: Accent Color Picker Dialog ---- */} + setColorDialogOpen(false)} + PaperProps={{ sx: { bgcolor: "#232323" } }} + > + Pick Node Header/Accent Color + + { + const nodeId = selectedNode?.id || nodeData?.nodeId; + if (!nodeId) return; + const accent = color.hex; + const accentDark = darkenColor(accent, 0.7); + effectiveSetNodes((nds) => + nds.map((n) => + n.id === nodeId + ? { + ...n, + data: { ...n.data, accentColor: accent }, + style: { + ...n.style, + "--borealis-accent": accent, + "--borealis-accent-dark": accentDark, + "--borealis-title": accent, + }, + } + : n + ) + ); + }} + disableAlpha + presetColors={[ + "#58a6ff", "#0475c2", "#00d18c", "#ff4f4f", "#ff8c00", + "#6b21a8", "#0e7490", "#888", "#fff", "#000" + ]} + /> + + + The node's header text and accent gradient will use your selected color.
+ The accent gradient fades to a slightly darker version. +
+ + + + {accentColor} + + +
+
+ + + +
+ {/* ---- END ACCENT COLOR PICKER DIALOG ---- */} ); }