Merge remote-tracking branch 'origin/main-demo' into main-dev
This commit is contained in:
@@ -8,9 +8,11 @@ import { handleBlurAmountChange } from "../../functions/helpers/handleBlurAmount
|
|||||||
import InputRange from "../../../ui/inputs/InputRange";
|
import InputRange from "../../../ui/inputs/InputRange";
|
||||||
import { DeleteIcon } from "../../../icons/ContextMenuIcons";
|
import { DeleteIcon } from "../../../icons/ContextMenuIcons";
|
||||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||||
import { ResizeHeightIcon } from "../../../icons/ExportCommonIcons";
|
import { ArrowIcon, ResizeHeightIcon } from "../../../icons/ExportCommonIcons";
|
||||||
import RenameInput from "../../../ui/inputs/RenameInput";
|
import RenameInput from "../../../ui/inputs/RenameInput";
|
||||||
import { useVisualizationStore } from "../../../../store/visualization/useVisualizationStore";
|
import { useVisualizationStore } from "../../../../store/visualization/useVisualizationStore";
|
||||||
|
import { ResetIcon } from "../../../icons/SimulationIcons";
|
||||||
|
import { Color } from "../../../ui/inputs/Color";
|
||||||
|
|
||||||
interface BlockEditorProps {
|
interface BlockEditorProps {
|
||||||
blockEditorRef: RefObject<HTMLDivElement>;
|
blockEditorRef: RefObject<HTMLDivElement>;
|
||||||
@@ -27,6 +29,9 @@ interface BlockEditorProps {
|
|||||||
const BlockEditor: React.FC<BlockEditorProps> = ({ blockEditorRef, currentBlock, selectedBlock, updateBlockStyle, updateBlockSize, updateBlockPositionType, updateBlockZIndex, handleRemoveBlock }) => {
|
const BlockEditor: React.FC<BlockEditorProps> = ({ blockEditorRef, currentBlock, selectedBlock, updateBlockStyle, updateBlockSize, updateBlockPositionType, updateBlockZIndex, handleRemoveBlock }) => {
|
||||||
const [color, setColor] = useState("#000000");
|
const [color, setColor] = useState("#000000");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setColor(rgbaToHex(getCurrentBlockStyleValue(currentBlock, "backgroundColor") || "#000000"));
|
||||||
|
}, [currentBlock]);
|
||||||
// Use position from VisualizationStore
|
// Use position from VisualizationStore
|
||||||
const { editorPosition, setEditorPosition } = useVisualizationStore();
|
const { editorPosition, setEditorPosition } = useVisualizationStore();
|
||||||
const panelRef = useRef<HTMLDivElement | null>(null);
|
const panelRef = useRef<HTMLDivElement | null>(null);
|
||||||
@@ -87,6 +92,8 @@ const BlockEditor: React.FC<BlockEditorProps> = ({ blockEditorRef, currentBlock,
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Initialize position on mount
|
// Initialize position on mount
|
||||||
|
|
||||||
|
// compute exact initial position once we have panel dimensions
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!editorPosition) {
|
if (!editorPosition) {
|
||||||
const { width } = getPanelDimensions();
|
const { width } = getPanelDimensions();
|
||||||
@@ -277,13 +284,48 @@ const BlockEditor: React.FC<BlockEditorProps> = ({ blockEditorRef, currentBlock,
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="design-section-footer">
|
<div className="design-section-footer">
|
||||||
<InputWithDropDown label="Layer" value={String(currentBlock.zIndex || 1)} placeholder={"Layer"} onChange={(newValue) => updateBlockZIndex(selectedBlock, Number(newValue))} />
|
<div className="layer-system">
|
||||||
|
|
||||||
<InputWithDropDown
|
<InputWithDropDown
|
||||||
label="Border Radius"
|
label="Layer"
|
||||||
|
value={String(currentBlock.zIndex ?? 1)}
|
||||||
|
placeholder={"Layer"}
|
||||||
|
onChange={(newValue) => updateBlockZIndex(selectedBlock, Number(newValue))}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
className="increase-z"
|
||||||
|
onClick={() => {
|
||||||
|
updateBlockZIndex(selectedBlock, Number(currentBlock.zIndex) + 1);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ArrowIcon />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="decrease-z"
|
||||||
|
onClick={() => {
|
||||||
|
updateBlockZIndex(selectedBlock, Number(currentBlock.zIndex) - 1);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ArrowIcon />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="reset"
|
||||||
|
onClick={() => {
|
||||||
|
updateBlockZIndex(selectedBlock, Number(1));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ResetIcon />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="design-section">
|
||||||
|
<div className="section-header">Apperance</div>
|
||||||
|
<InputRange
|
||||||
|
label={"Border Radius"}
|
||||||
min={0}
|
min={0}
|
||||||
value={String(parseInt(getCurrentBlockStyleValue(currentBlock, "borderRadius")) || 8)}
|
max={100}
|
||||||
placeholder={"Width"}
|
value={parseInt(getCurrentBlockStyleValue(currentBlock, "borderRadius")) || 8}
|
||||||
onChange={(newValue) => {
|
onChange={(newValue) => {
|
||||||
updateBlockStyle(selectedBlock, {
|
updateBlockStyle(selectedBlock, {
|
||||||
borderRadius: Number(newValue),
|
borderRadius: Number(newValue),
|
||||||
@@ -291,41 +333,24 @@ const BlockEditor: React.FC<BlockEditorProps> = ({ blockEditorRef, currentBlock,
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="design-section">
|
<div className="design-section">
|
||||||
<div className="section-header">Background</div>
|
<div className="section-header">Background</div>
|
||||||
<div className="data-picker">
|
|
||||||
<div className="label">Color</div>
|
<Color
|
||||||
<div className="left">
|
label="Color"
|
||||||
<input
|
|
||||||
type="color"
|
|
||||||
value={rgbaToHex(getCurrentBlockStyleValue(currentBlock, "backgroundColor"))}
|
|
||||||
// onChange={(e) => setColor(e.target.value)}
|
|
||||||
onChange={(e) => {
|
|
||||||
handleBackgroundColorChange(currentBlock, selectedBlock, updateBlockStyle, e.target.value);
|
|
||||||
setColor(e.target.value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
handleBackgroundColorChange(currentBlock, selectedBlock, updateBlockStyle, color);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
className="colorValue"
|
|
||||||
value={color}
|
value={color}
|
||||||
onChange={(e) => {
|
onChange={(value) => {
|
||||||
setColor(e.target.value);
|
setColor(value);
|
||||||
|
if (/^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(value)) {
|
||||||
|
handleBackgroundColorChange(currentBlock, selectedBlock, updateBlockStyle, value);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
onBlur={(e) => {
|
onUpdate={(value) => {
|
||||||
handleBackgroundColorChange(currentBlock, selectedBlock, updateBlockStyle, color);
|
handleBackgroundColorChange(currentBlock, selectedBlock, updateBlockStyle, value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<InputRange
|
<InputRange
|
||||||
label={"Opacity"}
|
label={"Opacity"}
|
||||||
min={0}
|
min={0}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { getAlphaFromRgba, hexToRgba, rgbaToHex } from "../../functions/helpers/
|
|||||||
import { ExtendedCSSProperties, UIElement } from "../../../../types/exportedTypes";
|
import { ExtendedCSSProperties, UIElement } from "../../../../types/exportedTypes";
|
||||||
import { getCurrentElementStyleValue } from "../../functions/helpers/getCurrentElementStyleValue";
|
import { getCurrentElementStyleValue } from "../../functions/helpers/getCurrentElementStyleValue";
|
||||||
import { ResetIcon } from "../../../icons/SimulationIcons";
|
import { ResetIcon } from "../../../icons/SimulationIcons";
|
||||||
|
import { Color } from "../../../ui/inputs/Color";
|
||||||
|
|
||||||
interface ElementDesignProps {
|
interface ElementDesignProps {
|
||||||
element: UIElement | undefined;
|
element: UIElement | undefined;
|
||||||
@@ -277,43 +278,27 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
|||||||
|
|
||||||
<div className="design-section element-color">
|
<div className="design-section element-color">
|
||||||
<div className="section-header">Background</div>
|
<div className="section-header">Background</div>
|
||||||
<div className="data-picker">
|
|
||||||
<div className="label">Color</div>
|
<Color
|
||||||
<div className="left">
|
label="Color"
|
||||||
<input
|
|
||||||
type="color"
|
|
||||||
value={color}
|
value={color}
|
||||||
onChange={(e) => {
|
onChange={(value) => {
|
||||||
|
const currentBg = getCurrentElementStyleValue(currentElement, "backgroundColor") || "rgba(0,0,0,1)";
|
||||||
|
const currentAlpha = getAlphaFromRgba(currentBg);
|
||||||
updateElementStyle(selectedBlock, selectedElement, {
|
updateElementStyle(selectedBlock, selectedElement, {
|
||||||
backgroundColor: hexToRgba(e.target.value),
|
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),
|
||||||
});
|
});
|
||||||
setColor(e.target.value);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
updateElementStyle(selectedBlock, selectedElement, {
|
|
||||||
backgroundColor: color,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
className="colorValue"
|
|
||||||
value={color}
|
|
||||||
onChange={(e) => {
|
|
||||||
setColor(e.target.value);
|
|
||||||
}}
|
|
||||||
onBlur={(e) => {
|
|
||||||
updateElementStyle(selectedBlock, selectedElement, {
|
|
||||||
backgroundColor: color,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<InputRange
|
<InputRange
|
||||||
label={"Opacity"}
|
label={"Opacity"}
|
||||||
min={0}
|
min={0}
|
||||||
|
|||||||
@@ -572,7 +572,9 @@ const ElementEditor: React.FC<ElementEditorProps> = ({
|
|||||||
{selectType === "data" && (
|
{selectType === "data" && (
|
||||||
<div className="data-details">
|
<div className="data-details">
|
||||||
{element?.type === "label-value" && (
|
{element?.type === "label-value" && (
|
||||||
<div className="data-wrapper">
|
<>
|
||||||
|
<div className="design-section">
|
||||||
|
<div className="sub-header">Data Handling</div>
|
||||||
<InputWithDropDown
|
<InputWithDropDown
|
||||||
label="Label"
|
label="Label"
|
||||||
type="string"
|
type="string"
|
||||||
@@ -639,6 +641,7 @@ const ElementEditor: React.FC<ElementEditorProps> = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Data Mapping */}
|
{/* Data Mapping */}
|
||||||
|
|||||||
70
app/src/components/ui/inputs/Color.tsx
Normal file
70
app/src/components/ui/inputs/Color.tsx
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface ColorProps {
|
||||||
|
value: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
label?: string;
|
||||||
|
className?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
|
||||||
|
onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;
|
||||||
|
onUpdate?: (value: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Color: React.FC<ColorProps> = ({
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
label = "Color",
|
||||||
|
className = "",
|
||||||
|
disabled = false,
|
||||||
|
onBlur,
|
||||||
|
onFocus,
|
||||||
|
onUpdate,
|
||||||
|
}) => {
|
||||||
|
const handleTextChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
onChange(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleColorPickerChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
onChange(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (e?: React.FormEvent) => {
|
||||||
|
if (e) e.preventDefault();
|
||||||
|
if (onUpdate) {
|
||||||
|
onUpdate(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
|
||||||
|
handleSubmit();
|
||||||
|
if (onBlur) onBlur(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`data-picker ${className}`}>
|
||||||
|
{label && <div className="label">{label}</div>}
|
||||||
|
<div className="left">
|
||||||
|
<input
|
||||||
|
type="color"
|
||||||
|
value={value}
|
||||||
|
onChange={handleColorPickerChange}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
disabled={disabled}
|
||||||
|
className="cursor-pointer"
|
||||||
|
/>
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="colorValue"
|
||||||
|
value={value}
|
||||||
|
onChange={handleTextChange}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
onFocus={onFocus}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -46,6 +46,7 @@ textarea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input[type="number"] {
|
input[type="number"] {
|
||||||
|
|
||||||
// Chrome, Safari, Edge, Opera
|
// Chrome, Safari, Edge, Opera
|
||||||
&::-webkit-outer-spin-button,
|
&::-webkit-outer-spin-button,
|
||||||
&::-webkit-inner-spin-button {
|
&::-webkit-inner-spin-button {
|
||||||
@@ -228,22 +229,26 @@ input[type="number"] {
|
|||||||
.key {
|
.key {
|
||||||
text-overflow: none;
|
text-overflow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-header {
|
.dropdown-header {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: #{$border-radius-large};
|
border-radius: #{$border-radius-large};
|
||||||
|
|
||||||
.key {
|
.key {
|
||||||
width: calc(100% - 18px);
|
width: calc(100% - 18px);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-options {
|
.dropdown-options {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -167,10 +167,10 @@
|
|||||||
padding: 8px;
|
padding: 8px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
|
outline: 1px solid transparent;
|
||||||
|
|
||||||
&.edit-mode {
|
&.edit-mode {
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
outline: 1px solid transparent;
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
outline-color: var(--border-color);
|
outline-color: var(--border-color);
|
||||||
@@ -285,7 +285,7 @@
|
|||||||
gap: 11px;
|
gap: 11px;
|
||||||
min-width: 280px;
|
min-width: 280px;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
min-width: 320px;
|
max-width: 320px;
|
||||||
min-height: 60vh;
|
min-height: 60vh;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
|
|
||||||
@@ -460,39 +460,6 @@
|
|||||||
padding: 0;
|
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 {
|
.design-section-footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import { useSceneContext } from "../../modules/scene/sceneContext";
|
|||||||
const KeyPressListener: React.FC = () => {
|
const KeyPressListener: React.FC = () => {
|
||||||
const { comparisonScene, clearComparisonState } = useSimulationState();
|
const { comparisonScene, clearComparisonState } = useSimulationState();
|
||||||
const { activeModule, setActiveModule } = useModuleStore();
|
const { activeModule, setActiveModule } = useModuleStore();
|
||||||
const { assetStore, versionStore } = useSceneContext();
|
const { assetStore, versionStore, simulationDashBoardStore } = useSceneContext();
|
||||||
const { selectedAssets } = assetStore();
|
const { selectedAssets } = assetStore();
|
||||||
const { setSubModule } = useSubModuleStore();
|
const { setSubModule } = useSubModuleStore();
|
||||||
const { setActiveSubTool } = useActiveSubTool();
|
const { setActiveSubTool } = useActiveSubTool();
|
||||||
@@ -46,6 +46,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
const { setSelectedComment } = useSelectedComment();
|
const { setSelectedComment } = useSelectedComment();
|
||||||
const { setDfxUploaded } = useDfxUpload();
|
const { setDfxUploaded } = useDfxUpload();
|
||||||
const isTextInput = (element: Element | null): boolean => element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element?.getAttribute("contenteditable") === "true";
|
const isTextInput = (element: Element | null): boolean => element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element?.getAttribute("contenteditable") === "true";
|
||||||
|
const { setSelectedBlock, setSelectedElement } = simulationDashBoardStore();
|
||||||
|
|
||||||
const handleModuleSwitch = (keyCombination: string) => {
|
const handleModuleSwitch = (keyCombination: string) => {
|
||||||
const modules: Record<string, string> = {
|
const modules: Record<string, string> = {
|
||||||
@@ -189,6 +190,8 @@ const KeyPressListener: React.FC = () => {
|
|||||||
setIsRenameMode(false);
|
setIsRenameMode(false);
|
||||||
setDfxUploaded([]);
|
setDfxUploaded([]);
|
||||||
setSelectedComment(null);
|
setSelectedComment(null);
|
||||||
|
setSelectedBlock(null);
|
||||||
|
setSelectedElement(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!keyCombination || ["F5", "F11", "F12"].includes(event.key) || keyCombination === "Ctrl+R") return;
|
if (!keyCombination || ["F5", "F11", "F12"].includes(event.key) || keyCombination === "Ctrl+R") return;
|
||||||
|
|||||||
Reference in New Issue
Block a user