refactor(nodes): don't move or select nodes when input is focused
This commit is contained in:
@@ -8,7 +8,7 @@ import { ARIA_NODE_DESC_KEY } from '../A11yDescriptions';
|
|||||||
import useDrag from '../../hooks/useDrag';
|
import useDrag from '../../hooks/useDrag';
|
||||||
import useUpdateNodePositions from '../../hooks/useUpdateNodePositions';
|
import useUpdateNodePositions from '../../hooks/useUpdateNodePositions';
|
||||||
import { getMouseHandler, handleNodeClick } from './utils';
|
import { getMouseHandler, handleNodeClick } from './utils';
|
||||||
import { elementSelectionKeys } from '../../utils';
|
import { elementSelectionKeys, isInputDOMNode } from '../../utils';
|
||||||
import type { NodeProps, WrapNodeProps, XYPosition } from '../../types';
|
import type { NodeProps, WrapNodeProps, XYPosition } from '../../types';
|
||||||
|
|
||||||
export const arrowKeyDiffs: Record<string, XYPosition> = {
|
export const arrowKeyDiffs: Record<string, XYPosition> = {
|
||||||
@@ -84,7 +84,12 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onKeyDown = (event: KeyboardEvent) => {
|
const onKeyDown = (event: KeyboardEvent) => {
|
||||||
|
if (isInputDOMNode(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { snapGrid, snapToGrid } = store.getState();
|
const { snapGrid, snapToGrid } = store.getState();
|
||||||
|
|
||||||
if (elementSelectionKeys.includes(event.key) && isSelectable) {
|
if (elementSelectionKeys.includes(event.key) && isSelectable) {
|
||||||
const unselect = event.key === 'Escape';
|
const unselect = event.key === 'Escape';
|
||||||
if (unselect) {
|
if (unselect) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useState, useEffect, useRef, useMemo } from 'react';
|
import { useState, useEffect, useRef, useMemo } from 'react';
|
||||||
|
|
||||||
|
import { isInputDOMNode } from '../utils';
|
||||||
import type { KeyCode } from '../types';
|
import type { KeyCode } from '../types';
|
||||||
|
|
||||||
type Keys = Array<string>;
|
type Keys = Array<string>;
|
||||||
@@ -106,14 +107,3 @@ function isMatchingKey(keyCodes: Array<Keys>, pressedKeys: PressedKeys, isUp: bo
|
|||||||
function useKeyOrCode(eventCode: string, keysToWatch: KeyCode): KeyOrCode {
|
function useKeyOrCode(eventCode: string, keysToWatch: KeyCode): KeyOrCode {
|
||||||
return keysToWatch.includes(eventCode) ? 'code' : 'key';
|
return keysToWatch.includes(eventCode) ? 'code' : 'key';
|
||||||
}
|
}
|
||||||
|
|
||||||
function isInputDOMNode(event: KeyboardEvent): boolean {
|
|
||||||
// using composed path for handling shadow dom
|
|
||||||
const target = (event.composedPath?.()[0] || event.target) as HTMLElement;
|
|
||||||
|
|
||||||
return (
|
|
||||||
['INPUT', 'SELECT', 'TEXTAREA'].includes(target?.nodeName) ||
|
|
||||||
target?.hasAttribute('contenteditable') ||
|
|
||||||
!!target?.closest('.nokey')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { KeyboardEvent as ReactKeyboardEvent } from 'react';
|
||||||
import type { Dimensions, Node, XYPosition, CoordinateExtent, Box, Rect } from '../types';
|
import type { Dimensions, Node, XYPosition, CoordinateExtent, Box, Rect } from '../types';
|
||||||
|
|
||||||
export const getDimensions = (node: HTMLDivElement): Dimensions => ({
|
export const getDimensions = (node: HTMLDivElement): Dimensions => ({
|
||||||
@@ -69,3 +70,18 @@ export const devWarn = (message: string) => {
|
|||||||
console.warn(`[React Flow]: ${message}`);
|
console.warn(`[React Flow]: ${message}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isReactKeyboardEvent = (event: KeyboardEvent | ReactKeyboardEvent): event is ReactKeyboardEvent =>
|
||||||
|
'nativeEvent' in event;
|
||||||
|
|
||||||
|
export function isInputDOMNode(event: KeyboardEvent | ReactKeyboardEvent): boolean {
|
||||||
|
const kbEvent = isReactKeyboardEvent(event) ? event.nativeEvent : event;
|
||||||
|
// using composed path for handling shadow dom
|
||||||
|
const target = (kbEvent.composedPath?.()?.[0] || event.target) as HTMLElement;
|
||||||
|
|
||||||
|
return (
|
||||||
|
['INPUT', 'SELECT', 'TEXTAREA'].includes(target?.nodeName) ||
|
||||||
|
target?.hasAttribute('contenteditable') ||
|
||||||
|
!!target?.closest('.nokey')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user