update: use store injection in UserSelection component

fix: keypress not displaying working properly
This commit is contained in:
Braks
2021-07-14 23:48:19 +02:00
parent f5580b6d96
commit c7fda830a6
9 changed files with 83 additions and 72 deletions

View File

@@ -3,9 +3,11 @@ import './index.css';
import App from './App';
import { router } from './router';
import { DraggablePlugin } from '@braks/revue-draggable';
import { createPinia } from 'pinia';
const app = createApp(App);
app.config.performance = true;
app.use(router);
app.use(DraggablePlugin);
app.use(createPinia());
app.mount('#root');

View File

@@ -28,7 +28,7 @@
"lint": "yarn lint:js"
},
"dependencies": {
"@braks/revue-draggable": "^0.1.2",
"@braks/revue-draggable": "^0.1.3",
"@types/d3": "^7.0.0",
"d3": "^7.0.0",
"d3-selection": "^3.0.0",

View File

@@ -1,9 +1,8 @@
/**
* The user selection rectangle gets displayed when a user drags the mouse while pressing shift
*/
import { XYPosition } from '../../types';
import { defineComponent, PropType } from 'vue';
import store from '../../store';
import { RevueFlowStore, XYPosition } from '../../types';
import { computed, defineComponent, inject, PropType } from 'vue';
type UserSelectionProps = {
selectionKeyPressed: boolean;
@@ -25,19 +24,20 @@ function getMousePosition(event: MouseEvent): XYPosition | void {
const SelectionRect = defineComponent({
setup() {
const pinia = store();
const store = inject<RevueFlowStore>('store');
if (!pinia.userSelectionRect.draw) {
if (!store?.userSelectionRect.draw) {
return null;
}
console.log('selectionrect');
return () => (
<div
class="revue-flow__selection"
style={{
width: pinia.userSelectionRect.width,
height: pinia.userSelectionRect.height,
transform: `translate(${pinia.userSelectionRect.x}px, ${pinia.userSelectionRect.y}px)`
width: store?.userSelectionRect.width,
height: store?.userSelectionRect.height,
transform: `translate(${store?.userSelectionRect.x}px, ${store?.userSelectionRect.y}px)`
}}
/>
);
@@ -53,10 +53,14 @@ export default defineComponent({
}
},
setup(props) {
const pinia = store();
const renderUserSelectionPane = pinia.selectionActive || props.selectionKeyPressed;
const store = inject<RevueFlowStore>('store')!;
const renderUserSelectionPane = computed(() => {
return props.selectionKeyPressed || store.selectionActive;
});
if (!pinia.elementsSelectable || !renderUserSelectionPane) {
const shouldRender = computed(() => renderUserSelectionPane.value || store.elementsSelectable);
if (!shouldRender.value) {
return null;
}
@@ -66,11 +70,11 @@ export default defineComponent({
return;
}
pinia.setUserSelection(mousePos);
store?.setUserSelection(mousePos);
};
const onMouseMove = (event: MouseEvent): void => {
if (!props.selectionKeyPressed || !pinia.selectionActive) {
if (!props.selectionKeyPressed || !store?.selectionActive) {
return;
}
const mousePos = getMousePosition(event);
@@ -79,14 +83,14 @@ export default defineComponent({
return;
}
pinia.updateUserSelection(mousePos);
store?.updateUserSelection(mousePos);
};
const onMouseUp = () => pinia.unsetUserSelection();
const onMouseUp = () => store?.unsetUserSelection();
const onMouseLeave = () => {
pinia.unsetUserSelection();
pinia.unsetNodesSelection();
store?.unsetUserSelection();
store?.unsetNodesSelection();
};
return () => (

View File

@@ -157,8 +157,7 @@ const FlowRenderer = defineComponent({
},
setup(props, { slots }) {
const store = inject<RevueFlowStore>('store');
const selectionKeyPressed = useKeyPress(props.selectionKeyCode);
const keyPressed = useKeyPress(props.selectionKeyCode);
useGlobalKeyHandler({
onElementsRemove: props.onElementsRemove,
@@ -200,7 +199,7 @@ const FlowRenderer = defineComponent({
zoomActivationKeyCode={props.zoomActivationKeyCode}
>
{slots.default ? slots.default() : ''}
<UserSelection selectionKeyPressed={selectionKeyPressed} />
{keyPressed.value ? <UserSelection selectionKeyPressed={keyPressed.value} /> : ''}
{store?.nodesSelectionActive && (
<NodesSelection
onSelectionDragStart={props.onSelectionDragStart}

View File

@@ -1,8 +1,7 @@
import useKeyPress from './useKeyPress';
import { isNode, getConnectedEdges } from '../utils/graph';
import { Elements, KeyCode, ElementId, FlowElement } from '../types';
import store from '../store';
import { onMounted } from 'vue';
import { Elements, KeyCode, ElementId, FlowElement, RevueFlowStore } from '../types';
import { inject, onMounted } from 'vue';
interface HookParams {
deleteKeyCode: KeyCode;
@@ -11,29 +10,27 @@ interface HookParams {
}
export default ({ deleteKeyCode, multiSelectionKeyCode, onElementsRemove }: HookParams): void => {
const pinia = store();
const store = inject<RevueFlowStore>('store');
const deleteKeyPressed = useKeyPress(deleteKeyCode);
const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode);
onMounted(() => {
const { edges, selectedElements } = pinia;
if (onElementsRemove && deleteKeyPressed && selectedElements) {
const selectedNodes = selectedElements.filter(isNode);
const connectedEdges = getConnectedEdges(selectedNodes, edges);
const elementsToRemove = [...selectedElements, ...connectedEdges].reduce(
if (onElementsRemove && deleteKeyPressed.value && store?.selectedElements) {
const selectedNodes = store?.selectedElements.filter(isNode);
const connectedEdges = getConnectedEdges(selectedNodes, store?.edges);
const elementsToRemove = [...store?.selectedElements, ...connectedEdges].reduce(
(res, item) => res.set(item.id, item),
new Map<ElementId, FlowElement>()
);
onElementsRemove(Array.from(elementsToRemove.values()));
pinia.unsetNodesSelection();
pinia.resetSelectedElements();
store?.unsetNodesSelection();
store?.resetSelectedElements();
}
});
onMounted(() => {
pinia.setMultiSelectionActive(multiSelectionKeyPressed);
store?.setMultiSelectionActive(multiSelectionKeyPressed.value);
});
};

View File

@@ -1,38 +1,45 @@
import { isInputDOMNode } from '../utils';
import { KeyCode } from '../types';
import { onMounted, ref } from 'vue';
import { onBeforeUnmount, onMounted, ref, Ref } from 'vue';
export default (keyCode?: KeyCode): boolean => {
export default (keyCode?: KeyCode): Ref<boolean> => {
const keyPressed = ref<boolean>(false);
onMounted(() => {
const downHandler = (event: KeyboardEvent) => {
if (!isInputDOMNode(event) && (event.key === keyCode || event.keyCode === keyCode)) {
event.preventDefault();
keyPressed.value = true;
}
};
const upHandler = (event: KeyboardEvent) => {
if (!isInputDOMNode(event) && (event.key === keyCode || event.keyCode === keyCode)) {
keyPressed.value = false;
}
};
const resetHandler = () => (keyPressed.value = false);
const bindEvents = () => {
if (typeof keyCode !== 'undefined') {
const downHandler = (event: KeyboardEvent) => {
if (!isInputDOMNode(event) && (event.key === keyCode || event.keyCode === keyCode)) {
event.preventDefault();
keyPressed.value = true;
}
};
const upHandler = (event: KeyboardEvent) => {
if (!isInputDOMNode(event) && (event.key === keyCode || event.keyCode === keyCode)) {
keyPressed.value = false;
}
};
const resetHandler = () => (keyPressed.value = false);
window.addEventListener('keydown', downHandler);
window.addEventListener('keyup', upHandler);
window.addEventListener('blur', resetHandler);
return () => {
window.removeEventListener('keydown', downHandler);
window.removeEventListener('keyup', upHandler);
window.removeEventListener('blur', resetHandler);
};
}
};
const unbindEvents = () => {
window.removeEventListener('keydown', downHandler);
window.removeEventListener('keyup', upHandler);
window.removeEventListener('blur', resetHandler);
};
onMounted(() => {
bindEvents();
});
onBeforeUnmount(() => {
unbindEvents();
});
return keyPressed.value;
return keyPressed;
};

View File

@@ -191,13 +191,13 @@ export default function configureStore(
const nextSelectedElements = [...selectedNodes, ...selectedEdges];
const selectedElementsChanged = !isEqual(nextSelectedElements, this.selectedElements);
const selectedElementsUpdate = selectedElementsChanged
? {
selectedElements: nextSelectedElements.length > 0 ? nextSelectedElements : null
}
: {};
? nextSelectedElements.length > 0
? nextSelectedElements
: []
: [];
this.userSelectionRect = nextUserSelectRect;
this.selectedElements = selectedElementsUpdate.selectedElements as any;
this.selectedElements = selectedElementsUpdate;
},
unsetUserSelection() {
const selectedNodes = this.selectedElements?.filter((node) => isNode(node) && node.__rf) as Node[];
@@ -206,9 +206,11 @@ export default function configureStore(
this.userSelectionRect.draw = false;
if (!selectedNodes || selectedNodes.length === 0) {
console.log('Foo');
this.selectedElements = null;
this.nodesSelectionActive = false;
} else {
console.log('bar');
this.selectedNodesBbox = getRectOfNodes(selectedNodes);
this.nodesSelectionActive = true;
}

View File

@@ -1,9 +1,9 @@
import { Dimensions, XYPosition, NodeExtent } from '../types';
import { DraggableEvent } from '@braks/revue-draggable';
export const isInputDOMNode = (e: MouseEvent | /* DraggableEvent | */ KeyboardEvent): boolean => {
export const isInputDOMNode = (e: MouseEvent | DraggableEvent | KeyboardEvent): boolean => {
const target = e.target as HTMLElement;
return ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON'].includes(target.nodeName) || target.hasAttribute('contenteditable');
return ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON'].includes(target.nodeName) || target.hasAttribute('contentEditable');
};
export const getDimensions = (node: HTMLDivElement): Dimensions => ({
@@ -13,7 +13,7 @@ export const getDimensions = (node: HTMLDivElement): Dimensions => ({
export const clamp = (val: number, min = 0, max = 1): number => Math.min(Math.max(val, min), max);
export const clampPosition = (position: XYPosition, extent: NodeExtent) => ({
export const clampPosition = (position: XYPosition, extent: NodeExtent): XYPosition => ({
x: clamp(position.x, extent[0][0], extent[1][0]),
y: clamp(position.y, extent[0][1], extent[1][1])
});

View File

@@ -262,10 +262,10 @@
"@babel/helper-validator-identifier" "^7.14.5"
to-fast-properties "^2.0.0"
"@braks/revue-draggable@^0.1.2":
version "0.1.2"
resolved "https://registry.yarnpkg.com/@braks/revue-draggable/-/revue-draggable-0.1.2.tgz#7eb53c5ecd3cdae905b873a4c70418d2f4f649b7"
integrity sha512-sgtLSL4NClw2ajU/8IS7/qhUPRSO1uHd3iKCRmsCF1Lrygkj9qJ7m5DjiN7R8ifrCGvnYA9BDqNnYMcPKr/d8g==
"@braks/revue-draggable@^0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@braks/revue-draggable/-/revue-draggable-0.1.3.tgz#837a46bde7c87f8f6642ed4fb85697653ee6d068"
integrity sha512-9Ad35cUzkuaC7wTXSpJIYAH2kmgIh/VtL062MXTiFZ9OIZxAUMUfCnIgDTWY0sZNoxmO8CPD3XUP/YfbxoMESQ==
dependencies:
vue-demi latest