diff --git a/app/src/components/SimulationDashboard/components/block/BlockEditor.tsx b/app/src/components/SimulationDashboard/components/block/BlockEditor.tsx index 24b2142..951b8e8 100644 --- a/app/src/components/SimulationDashboard/components/block/BlockEditor.tsx +++ b/app/src/components/SimulationDashboard/components/block/BlockEditor.tsx @@ -8,9 +8,11 @@ import { handleBlurAmountChange } from "../../functions/helpers/handleBlurAmount import InputRange from "../../../ui/inputs/InputRange"; import { DeleteIcon } from "../../../icons/ContextMenuIcons"; import InputWithDropDown from "../../../ui/inputs/InputWithDropDown"; -import { ResizeHeightIcon } from "../../../icons/ExportCommonIcons"; +import { ArrowIcon, ResizeHeightIcon } from "../../../icons/ExportCommonIcons"; import RenameInput from "../../../ui/inputs/RenameInput"; import { useVisualizationStore } from "../../../../store/visualization/useVisualizationStore"; +import { ResetIcon } from "../../../icons/SimulationIcons"; +import { Color } from "../../../ui/inputs/Color"; interface BlockEditorProps { blockEditorRef: RefObject; @@ -39,6 +41,13 @@ const BlockEditor: React.FC = ({ }) => { const [color, setColor] = useState("#000000"); + useEffect(() => { + setColor( + rgbaToHex( + getCurrentBlockStyleValue(currentBlock, "backgroundColor") || "#000000" + ) + ); + }, [currentBlock]); // Use position from VisualizationStore const { editorPosition, setEditorPosition } = useVisualizationStore(); const panelRef = useRef(null); @@ -54,6 +63,7 @@ const BlockEditor: React.FC = ({ setEditorPosition(newPosition); }; + // compute exact initial position once we have panel dimensions useEffect(() => { if (!editorPosition) { @@ -262,82 +272,71 @@ const BlockEditor: React.FC = ({
- - updateBlockZIndex(selectedBlock, Number(newValue)) - } - /> - - { - updateBlockStyle(selectedBlock, { - borderRadius: Number(newValue), - }); - }} - /> +
+ + updateBlockZIndex(selectedBlock, Number(newValue)) + } + /> + + + +
Background
-
-
Color
-
- setColor(e.target.value)} - onChange={(e) => { - handleBackgroundColorChange( - currentBlock, - selectedBlock, - updateBlockStyle, - e.target.value - ); - setColor(e.target.value); - }} - /> -
{ - e.preventDefault(); - handleBackgroundColorChange( - currentBlock, - selectedBlock, - updateBlockStyle, - color - ); - }} - > - { - setColor(e.target.value); - }} - onBlur={(e) => { - handleBackgroundColorChange( - currentBlock, - selectedBlock, - updateBlockStyle, - color - ); - }} - /> -
-
-
+ + { + setColor(value); + if (/^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(value)) { + handleBackgroundColorChange( + currentBlock, + selectedBlock, + updateBlockStyle, + value + ); + } + }} + onUpdate={(value) => { + handleBackgroundColorChange( + currentBlock, + selectedBlock, + updateBlockStyle, + value + ); + }} + /> + + = ({ value={parseInt(getCurrentBlockStyleValue(currentBlock, "backdropFilter")?.match(/\d+/)?.[0] || "10")} onChange={(value: number) => handleBlurAmountChange(selectedBlock, updateBlockStyle, Number(value))} /> + { + updateBlockStyle(selectedBlock, { + borderRadius: Number(newValue), + }); + }} + />
diff --git a/app/src/components/SimulationDashboard/components/element/ElementDesign.tsx b/app/src/components/SimulationDashboard/components/element/ElementDesign.tsx index 1696481..3c8cb62 100644 --- a/app/src/components/SimulationDashboard/components/element/ElementDesign.tsx +++ b/app/src/components/SimulationDashboard/components/element/ElementDesign.tsx @@ -16,6 +16,7 @@ import { getAlphaFromRgba, hexToRgba, rgbaToHex } from "../../functions/helpers/ import { ExtendedCSSProperties, UIElement } from "../../../../types/exportedTypes"; import { getCurrentElementStyleValue } from "../../functions/helpers/getCurrentElementStyleValue"; import { ResetIcon } from "../../../icons/SimulationIcons"; +import { Color } from "../../../ui/inputs/Color"; interface ElementDesignProps { element: UIElement | undefined; @@ -384,43 +385,27 @@ const ElementDesign: React.FC = ({
Background
-
-
Color
-
- { - updateElementStyle(selectedBlock, selectedElement, { - backgroundColor: hexToRgba(e.target.value), - }); - setColor(e.target.value); - }} - /> -
{ - e.preventDefault(); - updateElementStyle(selectedBlock, selectedElement, { - backgroundColor: color, - }); - }} - > - { - setColor(e.target.value); - }} - onBlur={(e) => { - updateElementStyle(selectedBlock, selectedElement, { - backgroundColor: color, - }); - }} - /> -
-
-
+ { + const currentBg = getCurrentElementStyleValue(currentElement, "backgroundColor") || "rgba(0,0,0,1)"; + const currentAlpha = getAlphaFromRgba(currentBg); + updateElementStyle(selectedBlock, selectedElement, { + backgroundColor: hexToRgba(value, currentAlpha), + }); + setColor(value); + }} + onUpdate={(value) => { + const currentBg = getCurrentElementStyleValue(currentElement, "backgroundColor") || "rgba(0,0,0,1)"; + const currentAlpha = getAlphaFromRgba(currentBg); + updateElementStyle(selectedBlock, selectedElement, { + backgroundColor: hexToRgba(value, currentAlpha), + }); + }} + /> + = ({ void; + label?: string; + className?: string; + disabled?: boolean; + onBlur?: (e: React.FocusEvent) => void; + onFocus?: (e: React.FocusEvent) => void; + onUpdate?: (value: string) => void; +} + +export const Color: React.FC = ({ + value, + onChange, + label = "Color", + className = "", + disabled = false, + onBlur, + onFocus, + onUpdate, +}) => { + const handleTextChange = (e: React.ChangeEvent) => { + onChange(e.target.value); + }; + + const handleColorPickerChange = (e: React.ChangeEvent) => { + onChange(e.target.value); + }; + + const handleSubmit = (e?: React.FormEvent) => { + if (e) e.preventDefault(); + if (onUpdate) { + onUpdate(value); + } + }; + + const handleBlur = (e: React.FocusEvent) => { + handleSubmit(); + if (onBlur) onBlur(e); + }; + + return ( +
+ {label &&
{label}
} +
+ +
+ +
+
+
+ ); +}; diff --git a/app/src/styles/components/_input.scss b/app/src/styles/components/_input.scss index 7bd9f6f..cb64933 100644 --- a/app/src/styles/components/_input.scss +++ b/app/src/styles/components/_input.scss @@ -46,6 +46,7 @@ textarea { } input[type="number"] { + // Chrome, Safari, Edge, Opera &::-webkit-outer-spin-button, &::-webkit-inner-spin-button { @@ -225,25 +226,29 @@ input[type="number"] { position: relative; cursor: pointer; - .key{ + .key { text-overflow: none; } + .dropdown-header { height: 100%; display: flex; justify-content: space-between; cursor: pointer; border-radius: #{$border-radius-large}; - .key{ + + .key { width: calc(100% - 18px); overflow: hidden; text-overflow: ellipsis; } - } + } + .icon { height: auto; } } + .dropdown-options { position: absolute; width: 100%; @@ -787,3 +792,39 @@ input[type="number"] { } } } + + +.data-picker { + display: flex; + justify-content: space-between; + align-items: center; + + .label { + width: 50%; + white-space: nowrap; + } + + input[type="color"] { + width: 42px; + padding: 0; + background: transparent; + outline: none; + } + + .left { + width: 100%; + display: flex; + align-items: center; + gap: 6px; + + .colorValue { + width: 100%; + background: linear-gradient(90.85deg, + rgba(240, 228, 255, 0.3) 3.6%, + rgba(211, 174, 253, 0.3) 96.04%); + text-align: center; + padding: 4px 0; + border-radius: 100px; + } + } +} \ No newline at end of file diff --git a/app/src/styles/components/simulationDashboard/_simulationDashBoard.scss b/app/src/styles/components/simulationDashboard/_simulationDashBoard.scss index 2012686..ef98849 100644 --- a/app/src/styles/components/simulationDashboard/_simulationDashBoard.scss +++ b/app/src/styles/components/simulationDashboard/_simulationDashBoard.scss @@ -161,10 +161,10 @@ padding: 8px; user-select: none; border: 1px solid transparent; + outline: 1px solid transparent; &.edit-mode { transition: all 0.2s; - outline: 1px solid transparent; &:hover { outline-color: var(--border-color); @@ -279,7 +279,7 @@ gap: 11px; min-width: 280px; height: fit-content; - min-width: 320px; + max-width: 320px; min-height: 60vh; padding: 12px; @@ -454,41 +454,6 @@ padding: 0; } - .data-picker { - display: flex; - justify-content: space-between; - align-items: center; - - .label { - width: 50%; - white-space: nowrap; - } - - input[type="color"] { - width: 42px; - padding: 0; - background: transparent; - outline: none; - } - - .left { - width: 100%; - display: flex; - align-items: center; - gap: 6px; - - .colorValue { - width: 100%; - background: linear-gradient(90.85deg, - rgba(240, 228, 255, 0.3) 3.6%, - rgba(211, 174, 253, 0.3) 96.04%); - text-align: center; - padding: 4px 0; - border-radius: 100px; - } - } - } - .design-section-footer { display: flex; flex-direction: column;