feat: introduce BlockEditor for interactive block style, size, and position management within the simulation dashboard.
This commit is contained in:
@@ -272,7 +272,7 @@ const BlockEditor: React.FC<BlockEditorProps> = ({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<InputWithDropDown
|
<InputWithDropDown
|
||||||
label="Corner Radius"
|
label="Border Radius"
|
||||||
min={0}
|
min={0}
|
||||||
value={String(
|
value={String(
|
||||||
parseInt(getCurrentBlockStyleValue(currentBlock, "borderRadius")) ||
|
parseInt(getCurrentBlockStyleValue(currentBlock, "borderRadius")) ||
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { RefObject, useState } from "react";
|
import React, { RefObject, useEffect, useState } from "react";
|
||||||
import DataSourceSelector from "../../../ui/inputs/DataSourceSelector";
|
import DataSourceSelector from "../../../ui/inputs/DataSourceSelector";
|
||||||
import RenameInput from "../../../ui/inputs/RenameInput";
|
import RenameInput from "../../../ui/inputs/RenameInput";
|
||||||
import {
|
import {
|
||||||
@@ -78,6 +78,13 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
|||||||
setShowSwapUI,
|
setShowSwapUI,
|
||||||
}) => {
|
}) => {
|
||||||
const [color, setColor] = useState("#000000");
|
const [color, setColor] = useState("#000000");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setColor(
|
||||||
|
rgbaToHex(getCurrentElementStyleValue(currentElement, "backgroundColor") || "#000000")
|
||||||
|
);
|
||||||
|
}, [currentElement]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ display: "flex", flexDirection: "column", gap: 6 }} ref={elementEditorRef}>
|
<div style={{ display: "flex", flexDirection: "column", gap: 6 }} ref={elementEditorRef}>
|
||||||
{element?.type === "graph" && (
|
{element?.type === "graph" && (
|
||||||
@@ -274,27 +281,52 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="design-section-footer">
|
<div className="design-section-footer">
|
||||||
|
<div className="layer-system">
|
||||||
<InputWithDropDown
|
<InputWithDropDown
|
||||||
label="Layer"
|
label="Layer"
|
||||||
value={String(currentElement.zIndex || 1)}
|
value={String(currentElement.zIndex || 1)}
|
||||||
placeholder={"Layer"}
|
placeholder={"Layer"}
|
||||||
onChange={(newValue: string) => updateElementZIndex(selectedBlock, selectedElement, Number(newValue))}
|
onChange={(newValue: string) =>
|
||||||
/>
|
updateElementZIndex(
|
||||||
<InputRange
|
selectedBlock,
|
||||||
label={"Radius"}
|
selectedElement,
|
||||||
min={0}
|
Number(newValue)
|
||||||
max={8}
|
)
|
||||||
value={
|
|
||||||
parseInt(
|
|
||||||
getCurrentElementStyleValue(currentElement, "borderRadius") || ""
|
|
||||||
) || 8
|
|
||||||
}
|
}
|
||||||
onChange={(newValue: number) => {
|
|
||||||
updateElementStyle(selectedBlock, selectedElement, {
|
|
||||||
borderRadius: Number(newValue),
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
<button
|
||||||
|
className="increase-z"
|
||||||
|
onClick={() => {
|
||||||
|
updateElementZIndex(
|
||||||
|
selectedBlock,
|
||||||
|
selectedElement,
|
||||||
|
Number(currentElement.zIndex ? currentElement.zIndex + 1 : 1)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ArrowIcon />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="decrease-z"
|
||||||
|
onClick={() => {
|
||||||
|
updateElementZIndex(
|
||||||
|
selectedBlock,
|
||||||
|
selectedElement,
|
||||||
|
Number(currentElement.zIndex ? currentElement.zIndex - 1 : 1)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ArrowIcon />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="reset"
|
||||||
|
onClick={() => {
|
||||||
|
updateElementZIndex(selectedBlock, selectedElement, Number(1));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ResetIcon />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -361,9 +393,6 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
|||||||
<div className="left">
|
<div className="left">
|
||||||
<input
|
<input
|
||||||
type="color"
|
type="color"
|
||||||
defaultValue={rgbaToHex(
|
|
||||||
getCurrentElementStyleValue(currentElement, "backgroundColor")
|
|
||||||
)}
|
|
||||||
value={color}
|
value={color}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
updateElementStyle(selectedBlock, selectedElement, {
|
updateElementStyle(selectedBlock, selectedElement, {
|
||||||
@@ -399,12 +428,13 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
|||||||
<InputRange
|
<InputRange
|
||||||
label={"Opacity"}
|
label={"Opacity"}
|
||||||
min={0}
|
min={0}
|
||||||
max={100}
|
max={1}
|
||||||
value={Math.round(getAlphaFromRgba(getCurrentElementStyleValue(currentElement, "backgroundColor") || "rgba(0,0,0,1)") * 100)}
|
step={0.1}
|
||||||
|
value={getAlphaFromRgba(getCurrentElementStyleValue(currentElement, "backgroundColor") || "rgba(0,0,0,1)")}
|
||||||
onChange={(value: number) => {
|
onChange={(value: number) => {
|
||||||
const currentBg = getCurrentElementStyleValue(currentElement, "backgroundColor") || "rgba(0,0,0,1)";
|
const currentBg = getCurrentElementStyleValue(currentElement, "backgroundColor") || "rgba(0,0,0,1)";
|
||||||
const currentHex = rgbaToHex(currentBg);
|
const currentHex = rgbaToHex(currentBg);
|
||||||
const newBg = hexToRgba(currentHex, Number(value) / 100);
|
const newBg = hexToRgba(currentHex, Number(value));
|
||||||
updateElementStyle(selectedBlock, selectedElement, { backgroundColor: newBg });
|
updateElementStyle(selectedBlock, selectedElement, { backgroundColor: newBg });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -417,6 +447,21 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
|||||||
updateElementStyle(selectedBlock, selectedElement, { backdropFilter: `blur(${Number(value)}px)` });
|
updateElementStyle(selectedBlock, selectedElement, { backdropFilter: `blur(${Number(value)}px)` });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<InputRange
|
||||||
|
label={"Border Radius"}
|
||||||
|
min={0}
|
||||||
|
max={8}
|
||||||
|
value={
|
||||||
|
parseInt(
|
||||||
|
getCurrentElementStyleValue(currentElement, "borderRadius") || ""
|
||||||
|
) || 8
|
||||||
|
}
|
||||||
|
onChange={(newValue: number) => {
|
||||||
|
updateElementStyle(selectedBlock, selectedElement, {
|
||||||
|
borderRadius: Number(newValue),
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
* > {
|
*> {
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +88,7 @@
|
|||||||
|
|
||||||
&.edit-mode {
|
&.edit-mode {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
outline: 1px solid var(--border-color-accent);
|
outline: 1px solid var(--border-color-accent);
|
||||||
}
|
}
|
||||||
@@ -185,6 +186,7 @@
|
|||||||
&.edit-mode {
|
&.edit-mode {
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
outline: 1px solid transparent;
|
outline: 1px solid transparent;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
outline-color: var(--border-color);
|
outline-color: var(--border-color);
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
@@ -200,6 +202,7 @@
|
|||||||
&.selected {
|
&.selected {
|
||||||
outline: 2px solid var(--border-color-accent) !important;
|
outline: 2px solid var(--border-color-accent) !important;
|
||||||
background-color: rgba(98, 0, 255, 0.089);
|
background-color: rgba(98, 0, 255, 0.089);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
@@ -365,7 +368,6 @@
|
|||||||
.value-field-container {
|
.value-field-container {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
// padding: 6px 0px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-type {
|
.select-type {
|
||||||
@@ -498,11 +500,9 @@
|
|||||||
|
|
||||||
.colorValue {
|
.colorValue {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: linear-gradient(
|
background: linear-gradient(90.85deg,
|
||||||
90.85deg,
|
|
||||||
rgba(240, 228, 255, 0.3) 3.6%,
|
rgba(240, 228, 255, 0.3) 3.6%,
|
||||||
rgba(211, 174, 253, 0.3) 96.04%
|
rgba(211, 174, 253, 0.3) 96.04%);
|
||||||
);
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 4px 0;
|
padding: 4px 0;
|
||||||
border-radius: 100px;
|
border-radius: 100px;
|
||||||
@@ -514,10 +514,12 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 7px;
|
gap: 7px;
|
||||||
|
|
||||||
.layer-system {
|
.layer-system {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 3px;
|
gap: 3px;
|
||||||
|
|
||||||
.increase-z,
|
.increase-z,
|
||||||
.decrease-z,
|
.decrease-z,
|
||||||
.reset {
|
.reset {
|
||||||
@@ -530,13 +532,16 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background 0.2s;
|
transition: background 0.2s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--background-color-accent);
|
background: var(--background-color-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.increase-z {
|
.increase-z {
|
||||||
svg {
|
svg {
|
||||||
rotate: 180deg;
|
rotate: 180deg;
|
||||||
@@ -556,7 +561,7 @@
|
|||||||
gap: 0px;
|
gap: 0px;
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
min-width: 82px;
|
min-width: 92px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-container {
|
.input-container {
|
||||||
@@ -568,6 +573,7 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
width: 136px;
|
width: 136px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="number"] {
|
input[type="number"] {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 48px;
|
width: 48px;
|
||||||
@@ -760,6 +766,7 @@
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
top: 80px;
|
top: 80px;
|
||||||
right: 40px;
|
right: 40px;
|
||||||
|
|
||||||
.appearance {
|
.appearance {
|
||||||
.design-datas-wrapper {
|
.design-datas-wrapper {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
Reference in New Issue
Block a user