Merge pull request #2892 from wbkd/danielgek-fix-modifier-keys
Danielgek fix modifier keys
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'@reactflow/core': major
|
||||||
|
---
|
||||||
|
|
||||||
|
track modifier keys on useKeypress
|
||||||
@@ -38,6 +38,9 @@ const BasicFlow = () => {
|
|||||||
onSelectionContextMenu={onPaneContextMenu}
|
onSelectionContextMenu={onPaneContextMenu}
|
||||||
>
|
>
|
||||||
<Background variant={BackgroundVariant.Cross} />
|
<Background variant={BackgroundVariant.Cross} />
|
||||||
|
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
|
||||||
|
<input type={'text'} placeholder={'name'} />
|
||||||
|
</div>
|
||||||
</ReactFlow>
|
</ReactFlow>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,6 +18,20 @@ const initialNodes: Node[] = [
|
|||||||
data: { label: 'Node 1' },
|
data: { label: 'Node 1' },
|
||||||
position: { x: 250, y: 5 },
|
position: { x: 250, y: 5 },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
type: 'default',
|
||||||
|
data: { label: 'Node 2' },
|
||||||
|
position: { x: 250, y: 100 },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const initialEdges: Edge[] = [
|
||||||
|
{
|
||||||
|
id: 'e1-2',
|
||||||
|
source: '1',
|
||||||
|
target: '2',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const SelectionLogger = () => {
|
const SelectionLogger = () => {
|
||||||
@@ -34,7 +48,7 @@ const SelectionLogger = () => {
|
|||||||
|
|
||||||
const Flow = () => {
|
const Flow = () => {
|
||||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||||
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||||
const onConnect = useCallback((params: Edge | Connection) => setEdges((els) => addEdge(params, els)), [setEdges]);
|
const onConnect = useCallback((params: Edge | Connection) => setEdges((els) => addEdge(params, els)), [setEdges]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -52,6 +66,9 @@ const WrappedFlow = () => (
|
|||||||
<ReactFlowProvider>
|
<ReactFlowProvider>
|
||||||
<Flow />
|
<Flow />
|
||||||
<SelectionLogger />
|
<SelectionLogger />
|
||||||
|
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
|
||||||
|
<input type={'text'} placeholder={'name'} />
|
||||||
|
</div>
|
||||||
</ReactFlowProvider>
|
</ReactFlowProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ const doc = typeof document !== 'undefined' ? document : null;
|
|||||||
export default (keyCode: KeyCode | null = null, options: UseKeyPressOptions = { target: doc }): boolean => {
|
export default (keyCode: KeyCode | null = null, options: UseKeyPressOptions = { target: doc }): boolean => {
|
||||||
const [keyPressed, setKeyPressed] = useState(false);
|
const [keyPressed, setKeyPressed] = useState(false);
|
||||||
|
|
||||||
|
// we need to remember if a modifier key is pressed in order to track it
|
||||||
|
const modifierPressed = useRef(false);
|
||||||
|
|
||||||
// we need to remember the pressed keys in order to support combinations
|
// we need to remember the pressed keys in order to support combinations
|
||||||
const pressedKeys = useRef<PressedKeys>(new Set([]));
|
const pressedKeys = useRef<PressedKeys>(new Set([]));
|
||||||
|
|
||||||
@@ -43,7 +46,10 @@ export default (keyCode: KeyCode | null = null, options: UseKeyPressOptions = {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (keyCode !== null) {
|
if (keyCode !== null) {
|
||||||
const downHandler = (event: KeyboardEvent) => {
|
const downHandler = (event: KeyboardEvent) => {
|
||||||
if (isInputDOMNode(event)) {
|
|
||||||
|
modifierPressed.current = event.ctrlKey || event.metaKey || event.shiftKey;
|
||||||
|
|
||||||
|
if (!modifierPressed.current && isInputDOMNode(event)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const keyOrCode = useKeyOrCode(event.code, keysToWatch);
|
const keyOrCode = useKeyOrCode(event.code, keysToWatch);
|
||||||
@@ -56,7 +62,7 @@ export default (keyCode: KeyCode | null = null, options: UseKeyPressOptions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const upHandler = (event: KeyboardEvent) => {
|
const upHandler = (event: KeyboardEvent) => {
|
||||||
if (isInputDOMNode(event)) {
|
if (!modifierPressed.current && isInputDOMNode(event)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const keyOrCode = useKeyOrCode(event.code, keysToWatch);
|
const keyOrCode = useKeyOrCode(event.code, keysToWatch);
|
||||||
@@ -67,6 +73,7 @@ export default (keyCode: KeyCode | null = null, options: UseKeyPressOptions = {
|
|||||||
} else {
|
} else {
|
||||||
pressedKeys.current.delete(event[keyOrCode]);
|
pressedKeys.current.delete(event[keyOrCode]);
|
||||||
}
|
}
|
||||||
|
modifierPressed.current = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetHandler = () => {
|
const resetHandler = () => {
|
||||||
|
|||||||
@@ -104,11 +104,10 @@ export function isInputDOMNode(event: KeyboardEvent | ReactKeyboardEvent): boole
|
|||||||
const target = (kbEvent.composedPath?.()?.[0] || event.target) as HTMLElement;
|
const target = (kbEvent.composedPath?.()?.[0] || event.target) as HTMLElement;
|
||||||
|
|
||||||
const isInput = ['INPUT', 'SELECT', 'TEXTAREA'].includes(target?.nodeName) || target?.hasAttribute('contenteditable');
|
const isInput = ['INPUT', 'SELECT', 'TEXTAREA'].includes(target?.nodeName) || target?.hasAttribute('contenteditable');
|
||||||
// we want to be able to do a multi selection event if we are in an input field
|
|
||||||
const isModifierKey = event.ctrlKey || event.metaKey || event.shiftKey;
|
|
||||||
|
|
||||||
// when an input field is focused we don't want to trigger deletion or movement of nodes
|
// when an input field is focused we don't want to trigger deletion or movement of nodes
|
||||||
return (isInput && !isModifierKey) || !!target?.closest('.nokey');
|
return isInput || !!target?.closest('.nokey');
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isMouseEvent = (
|
export const isMouseEvent = (
|
||||||
|
|||||||
Reference in New Issue
Block a user