refactor(viewpane): accept KeyFilter instead of KeyCode

# What's changed?

* accept type of `KeyFilter` instead of `KeyCode` for zoom/select/delete keypress
* don't filter on input dom elements
This commit is contained in:
braks
2022-07-31 14:48:23 +02:00
committed by Braks
parent a095052c84
commit bd36253cd0
7 changed files with 29 additions and 51 deletions

View File

@@ -1,43 +1,32 @@
import type { Ref } from 'vue'
import { onKeyDown, onKeyPressed, onKeyUp } from '@vueuse/core'
import type { KeyFilter } from '@vueuse/core'
import useWindow from './useWindow'
import type { KeyCode } from '~/types'
import { isInputDOMNode } from '~/utils'
export default (keyCode: Ref<KeyCode>, onChange?: (keyPressed: boolean) => void): Ref<boolean> => {
export default (keyFilter: KeyFilter, onChange?: (keyPressed: boolean) => void): Ref<boolean> => {
const window = useWindow()
let isPressed = $ref(false)
watchEffect(
() => {
if (onChange && typeof onChange === 'function') onChange(isPressed)
},
{ flush: 'post' },
)
watch($$(isPressed), () => {
if (onChange && typeof onChange === 'function') onChange(isPressed)
})
onKeyPressed(
(e) => !isInputDOMNode(e) && (e.key === keyCode.value || e.keyCode === keyCode.value),
onKeyStroke(
keyFilter,
(e) => {
e.preventDefault()
isPressed = true
},
{ eventName: 'keydown' },
)
onKeyDown(
(e) => !isInputDOMNode(e) && (e.key === keyCode.value || e.keyCode === keyCode.value),
(e) => {
e.preventDefault()
isPressed = true
},
)
onKeyUp(
(e) => !isInputDOMNode(e) && (e.key === keyCode.value || e.keyCode === keyCode.value),
onKeyStroke(
keyFilter,
(e) => {
e.preventDefault()
isPressed = false
},
{ eventName: 'keyup' },
)
if (typeof window.addEventListener !== 'undefined') {

View File

@@ -1,7 +1,6 @@
<script lang="ts" setup>
import type { EdgeChange, GraphNode, NodeChange } from '../../types'
import type { GraphNode } from '../../types'
import { useKeyPress, useVueFlow } from '../../composables'
import { getConnectedEdges } from '../../utils'
import { NodesSelection, UserSelection } from '../../components'
const {
@@ -41,7 +40,7 @@ const onMouseLeave = (event: MouseEvent) => emits.paneMouseLeave(event)
const onMouseMove = (event: MouseEvent) => emits.paneMouseMove(event)
useKeyPress($$(deleteKeyCode), (keyPressed) => {
useKeyPress(deleteKeyCode, (keyPressed) => {
const nodesToRemove = getNodes.reduce<GraphNode[]>((res, node) => {
if (!node.selected && node.parentNode && res.find((n) => n.id === node.parentNode)) {
res.push(node)
@@ -71,13 +70,13 @@ useKeyPress($$(deleteKeyCode), (keyPressed) => {
}
})
useKeyPress($$(multiSelectionKeyCode), (keyPressed) => {
useKeyPress(multiSelectionKeyCode, (keyPressed) => {
setState({
multiSelectionActive: keyPressed,
})
})
const selectionKeyPressed = useKeyPress($$(selectionKeyCode), (keyPressed) => {
const selectionKeyPressed = useKeyPress(selectionKeyCode, (keyPressed) => {
if (userSelectionActive && keyPressed) return
setState({
userSelectionActive: keyPressed && elementsSelectable,

View File

@@ -97,7 +97,7 @@ onMounted(() => {
viewportRef: viewportEl.value,
})
const selectionKeyPressed = useKeyPress($$(selectionKeyCode), (keyPress) => {
const selectionKeyPressed = useKeyPress(selectionKeyCode, (keyPress) => {
if (keyPress && !isZoomingOrPanning) {
d3Zoom.on('zoom', null)
} else if (!keyPress) {
@@ -109,7 +109,7 @@ onMounted(() => {
}
})
const zoomKeyPressed = useKeyPress($$(zoomActivationKeyCode))
const zoomKeyPressed = useKeyPress(zoomActivationKeyCode)
d3Zoom.on('start', (event: D3ZoomEvent<HTMLDivElement, any>) => {
isZoomingOrPanning = true

View File

@@ -1,8 +1,9 @@
import type { CSSProperties } from 'vue'
import type { KeyFilter } from '@vueuse/core'
import type { DefaultEdgeOptions, Edge, GraphEdge } from './edge'
import type { CoordinateExtent, GraphNode, Node } from './node'
import type { ConnectionLineOptions, ConnectionLineType, ConnectionMode, Connector } from './connection'
import type { KeyCode, PanOnScrollMode } from './zoom'
import type { PanOnScrollMode } from './zoom'
import type { EdgeTypesObject, NodeTypesObject } from './components'
export type ElementData = any
@@ -90,10 +91,10 @@ export interface FlowProps {
/** @deprecated use {@link ConnectionLineOptions.style} */
connectionLineStyle?: CSSProperties | null
connectionLineOptions?: ConnectionLineOptions
deleteKeyCode?: KeyCode
selectionKeyCode?: KeyCode
multiSelectionKeyCode?: KeyCode
zoomActivationKeyCode?: KeyCode
deleteKeyCode?: KeyFilter
selectionKeyCode?: KeyFilter
multiSelectionKeyCode?: KeyFilter
zoomActivationKeyCode?: KeyFilter
snapToGrid?: boolean
snapGrid?: SnapGrid
onlyRenderVisibleElements?: boolean

View File

@@ -1,10 +1,11 @@
import type { CSSProperties, ComputedRef, ToRefs } from 'vue'
import type { KeyFilter } from '@vueuse/core'
import type { Dimensions, Elements, FlowElements, FlowExportObject, FlowOptions, SnapGrid, XYPosition } from './flow'
import type { DefaultEdgeTypes, DefaultNodeTypes, EdgeComponent, NodeComponent } from './components'
import type { Connection, ConnectionLineOptions, ConnectionLineType, ConnectionMode, Connector } from './connection'
import type { DefaultEdgeOptions, Edge, GraphEdge } from './edge'
import type { CoordinateExtent, GraphNode, Node } from './node'
import type { D3Selection, D3Zoom, D3ZoomHandler, KeyCode, PanOnScrollMode, Viewport, ViewportFunctions } from './zoom'
import type { D3Selection, D3Zoom, D3ZoomHandler, PanOnScrollMode, Viewport, ViewportFunctions } from './zoom'
import type { FlowHooks, FlowHooksEmit, FlowHooksOn } from './hooks'
import type { EdgeChange, NodeChange, NodeDragItem } from './changes'
import type { HandleType, StartHandle } from './handle'
@@ -54,10 +55,10 @@ export interface State extends Omit<FlowOptions, 'id' | 'modelValue'> {
userSelectionActive: boolean
multiSelectionActive: boolean
deleteKeyCode: KeyCode
selectionKeyCode: KeyCode
multiSelectionKeyCode: KeyCode
zoomActivationKeyCode: KeyCode
deleteKeyCode: KeyFilter
selectionKeyCode: KeyFilter
multiSelectionKeyCode: KeyFilter
zoomActivationKeyCode: KeyFilter
connectionNodeId: string | null
connectionHandleId: string | null

View File

@@ -12,8 +12,6 @@ export interface Viewport {
zoom: number
}
export type KeyCode = number | string
export enum PanOnScrollMode {
Free = 'free',
Vertical = 'vertical',

View File

@@ -19,16 +19,6 @@ import type {
} from '~/types'
import { useWindow } from '~/composables'
const isHTMLElement = (el: EventTarget): el is HTMLElement => ('nodeName' || 'hasAttribute') in el
export const isInputDOMNode = (e: KeyboardEvent | MouseEvent): boolean => {
const target = e.target
if (target && isHTMLElement(target)) {
return ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON'].includes(target.nodeName) || target.hasAttribute('contentEditable')
}
return false
}
export const getDimensions = (node: HTMLElement): Dimensions => ({
width: node.offsetWidth,
height: node.offsetHeight,