feat: added basic functionality for editable name bar
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
import {Handle, type NodeProps, NodeToolbar, Position} from '@xyflow/react';
|
||||
import {
|
||||
Handle,
|
||||
type NodeProps,
|
||||
NodeToolbar,
|
||||
Position
|
||||
} from '@xyflow/react';
|
||||
import '@xyflow/react/dist/style.css';
|
||||
import styles from '../../VisProg.module.css';
|
||||
import useFlowStore from "../VisProgStores.tsx";
|
||||
@@ -9,7 +14,7 @@ import type {
|
||||
NormNode
|
||||
} from "../VisProgTypes.tsx";
|
||||
|
||||
//
|
||||
//Toolbar definitions
|
||||
|
||||
type ToolbarProps = {
|
||||
nodeId: string;
|
||||
@@ -39,6 +44,56 @@ export function Toolbar({nodeId, allowDelete}: ToolbarProps) {
|
||||
</NodeToolbar>);
|
||||
}
|
||||
|
||||
// Renaming component
|
||||
|
||||
/**
|
||||
* Adds a component that can be used to edit a node's label entry inside its Data
|
||||
* can be added to any custom node that has a label inside its Data
|
||||
*
|
||||
* @param {string} nodeLabel
|
||||
* @param {string} nodeId
|
||||
* @returns {React.JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
export function EditableName({nodeLabel = "new node", nodeId} : { nodeLabel : string, nodeId: string}) {
|
||||
const {updateNodeData} = useFlowStore();
|
||||
|
||||
const updateData = (event: React.FocusEvent<HTMLInputElement>) => {
|
||||
const input = event.target.value;
|
||||
updateNodeData(nodeId, {label: input});
|
||||
event.currentTarget.setAttribute("readOnly", "true");
|
||||
window.getSelection()?.empty();
|
||||
event.currentTarget.classList.replace("nodrag", "drag"); // enable dragging of the node with cursor on the input box
|
||||
};
|
||||
|
||||
const updateOnEnter = (event: React.KeyboardEvent<HTMLInputElement>) => { if (event.key === "Enter") (event.target as HTMLInputElement).blur(); };
|
||||
|
||||
const enableEditing = (event: React.MouseEvent<HTMLInputElement>) => {
|
||||
if(event.currentTarget.hasAttribute("readOnly")) {
|
||||
event.currentTarget.removeAttribute("readOnly"); // enable editing
|
||||
event.currentTarget.select(); // select the text input
|
||||
window.getSelection()?.collapseToEnd(); // move the caret to the end of the current value
|
||||
event.currentTarget.classList.replace("drag", "nodrag"); // disable dragging using input box
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.NodeTextBar }>
|
||||
<label>name: </label>
|
||||
<input
|
||||
className={`drag ${styles.nodeTextInput}`} // prevents dragging the component when user has focused the text input
|
||||
type={"text"}
|
||||
defaultValue={nodeLabel}
|
||||
onKeyDown={updateOnEnter}
|
||||
onBlur={updateData}
|
||||
onClick={enableEditing}
|
||||
maxLength={25}
|
||||
readOnly
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// Definitions of Nodes
|
||||
|
||||
@@ -54,7 +109,7 @@ export const StartNodeComponent = ({id, data}: NodeProps<StartNode>) => {
|
||||
return (
|
||||
<>
|
||||
<Toolbar nodeId={id} allowDelete={false}/>
|
||||
<div className={styles.defaultNodeStart}>
|
||||
<div className={`${styles.defaultNode} ${styles.nodeStart}`}>
|
||||
<div> data test {data.label} </div>
|
||||
<Handle type="source" position={Position.Right} id="start"/>
|
||||
</div>
|
||||
@@ -75,7 +130,7 @@ export const EndNodeComponent = ({id, data}: NodeProps<EndNode>) => {
|
||||
return (
|
||||
<>
|
||||
<Toolbar nodeId={id} allowDelete={false}/>
|
||||
<div className={styles.defaultNodeEnd}>
|
||||
<div className={`${styles.defaultNode} ${styles.nodeEnd}`}>
|
||||
<div> {data.label} </div>
|
||||
<Handle type="target" position={Position.Left} id="end"/>
|
||||
</div>
|
||||
@@ -96,8 +151,8 @@ export const PhaseNodeComponent = ({id, data}: NodeProps<PhaseNode>) => {
|
||||
return (
|
||||
<>
|
||||
<Toolbar nodeId={id} allowDelete={true}/>
|
||||
<div className={styles.defaultNodePhase}>
|
||||
<div> phase {data.number} {data.label} </div>
|
||||
<div className={`${styles.defaultNode} ${styles.nodePhase}`}>
|
||||
<EditableName nodeLabel={data.label} nodeId={id}/>
|
||||
<Handle type="target" position={Position.Left} id="target"/>
|
||||
<Handle type="target" position={Position.Bottom} id="norms"/>
|
||||
<Handle type="source" position={Position.Right} id="source"/>
|
||||
@@ -119,8 +174,8 @@ export const NormNodeComponent = ({id, data}: NodeProps<NormNode>) => {
|
||||
return (
|
||||
<>
|
||||
<Toolbar nodeId={id} allowDelete={true}/>
|
||||
<div className={styles.defaultNodeNorm}>
|
||||
<div> Norm {data.label} </div>
|
||||
<div className={`${styles.defaultNode} ${styles.nodeNorm}`}>
|
||||
<EditableName nodeLabel={data.label} nodeId={id}/>
|
||||
<Handle type="source" position={Position.Right} id="NormSource"/>
|
||||
</div>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user