Merge branch 'fix-modifier-keys' of github.com:danielgek/react-flow into danielgek-fix-modifier-keys

This commit is contained in:
moklick
2023-03-06 15:19:16 +01:00
4 changed files with 32 additions and 6 deletions

View File

@@ -38,6 +38,9 @@ const BasicFlow = () => {
onSelectionContextMenu={onPaneContextMenu}
>
<Background variant={BackgroundVariant.Cross} />
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
<input type={'text'} placeholder={'name'} />
</div>
</ReactFlow>
);
};

View File

@@ -18,6 +18,20 @@ const initialNodes: Node[] = [
data: { label: 'Node 1' },
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 = () => {
@@ -34,7 +48,7 @@ const SelectionLogger = () => {
const Flow = () => {
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]);
return (
@@ -52,6 +66,9 @@ const WrappedFlow = () => (
<ReactFlowProvider>
<Flow />
<SelectionLogger />
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
<input type={'text'} placeholder={'name'} />
</div>
</ReactFlowProvider>
);

View File

@@ -19,6 +19,9 @@ const doc = typeof document !== 'undefined' ? document : null;
export default (keyCode: KeyCode | null = null, options: UseKeyPressOptions = { target: doc }): boolean => {
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
const pressedKeys = useRef<PressedKeys>(new Set([]));
@@ -43,7 +46,10 @@ export default (keyCode: KeyCode | null = null, options: UseKeyPressOptions = {
useEffect(() => {
if (keyCode !== null) {
const downHandler = (event: KeyboardEvent) => {
if (isInputDOMNode(event)) {
modifierPressed.current = event.ctrlKey || event.metaKey || event.shiftKey;
if (!modifierPressed.current && isInputDOMNode(event)) {
return false;
}
const keyOrCode = useKeyOrCode(event.code, keysToWatch);
@@ -56,7 +62,7 @@ export default (keyCode: KeyCode | null = null, options: UseKeyPressOptions = {
};
const upHandler = (event: KeyboardEvent) => {
if (isInputDOMNode(event)) {
if (!modifierPressed.current && isInputDOMNode(event)) {
return false;
}
const keyOrCode = useKeyOrCode(event.code, keysToWatch);
@@ -67,6 +73,7 @@ export default (keyCode: KeyCode | null = null, options: UseKeyPressOptions = {
} else {
pressedKeys.current.delete(event[keyOrCode]);
}
modifierPressed.current = false;
};
const resetHandler = () => {

View File

@@ -104,11 +104,10 @@ export function isInputDOMNode(event: KeyboardEvent | ReactKeyboardEvent): boole
const target = (kbEvent.composedPath?.()?.[0] || event.target) as HTMLElement;
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
return (isInput && !isModifierKey) || !!target?.closest('.nokey');
return isInput || !!target?.closest('.nokey');
}
export const isMouseEvent = (