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
+2
View File
@@ -3,9 +3,11 @@ import './index.css';
import App from './App'; import App from './App';
import { router } from './router'; import { router } from './router';
import { DraggablePlugin } from '@braks/revue-draggable'; import { DraggablePlugin } from '@braks/revue-draggable';
import { createPinia } from 'pinia';
const app = createApp(App); const app = createApp(App);
app.config.performance = true; app.config.performance = true;
app.use(router); app.use(router);
app.use(DraggablePlugin); app.use(DraggablePlugin);
app.use(createPinia());
app.mount('#root'); app.mount('#root');
+1 -1
View File
@@ -28,7 +28,7 @@
"lint": "yarn lint:js" "lint": "yarn lint:js"
}, },
"dependencies": { "dependencies": {
"@braks/revue-draggable": "^0.1.2", "@braks/revue-draggable": "^0.1.3",
"@types/d3": "^7.0.0", "@types/d3": "^7.0.0",
"d3": "^7.0.0", "d3": "^7.0.0",
"d3-selection": "^3.0.0", "d3-selection": "^3.0.0",
+21 -17
View File
@@ -1,9 +1,8 @@
/** /**
* The user selection rectangle gets displayed when a user drags the mouse while pressing shift * The user selection rectangle gets displayed when a user drags the mouse while pressing shift
*/ */
import { XYPosition } from '../../types'; import { RevueFlowStore, XYPosition } from '../../types';
import { defineComponent, PropType } from 'vue'; import { computed, defineComponent, inject, PropType } from 'vue';
import store from '../../store';
type UserSelectionProps = { type UserSelectionProps = {
selectionKeyPressed: boolean; selectionKeyPressed: boolean;
@@ -25,19 +24,20 @@ function getMousePosition(event: MouseEvent): XYPosition | void {
const SelectionRect = defineComponent({ const SelectionRect = defineComponent({
setup() { setup() {
const pinia = store(); const store = inject<RevueFlowStore>('store');
if (!pinia.userSelectionRect.draw) { if (!store?.userSelectionRect.draw) {
return null; return null;
} }
console.log('selectionrect');
return () => ( return () => (
<div <div
class="revue-flow__selection" class="revue-flow__selection"
style={{ style={{
width: pinia.userSelectionRect.width, width: store?.userSelectionRect.width,
height: pinia.userSelectionRect.height, height: store?.userSelectionRect.height,
transform: `translate(${pinia.userSelectionRect.x}px, ${pinia.userSelectionRect.y}px)` transform: `translate(${store?.userSelectionRect.x}px, ${store?.userSelectionRect.y}px)`
}} }}
/> />
); );
@@ -53,10 +53,14 @@ export default defineComponent({
} }
}, },
setup(props) { setup(props) {
const pinia = store(); const store = inject<RevueFlowStore>('store')!;
const renderUserSelectionPane = pinia.selectionActive || props.selectionKeyPressed; const renderUserSelectionPane = computed(() => {
return props.selectionKeyPressed || store.selectionActive;
});
if (!pinia.elementsSelectable || !renderUserSelectionPane) { const shouldRender = computed(() => renderUserSelectionPane.value || store.elementsSelectable);
if (!shouldRender.value) {
return null; return null;
} }
@@ -66,11 +70,11 @@ export default defineComponent({
return; return;
} }
pinia.setUserSelection(mousePos); store?.setUserSelection(mousePos);
}; };
const onMouseMove = (event: MouseEvent): void => { const onMouseMove = (event: MouseEvent): void => {
if (!props.selectionKeyPressed || !pinia.selectionActive) { if (!props.selectionKeyPressed || !store?.selectionActive) {
return; return;
} }
const mousePos = getMousePosition(event); const mousePos = getMousePosition(event);
@@ -79,14 +83,14 @@ export default defineComponent({
return; return;
} }
pinia.updateUserSelection(mousePos); store?.updateUserSelection(mousePos);
}; };
const onMouseUp = () => pinia.unsetUserSelection(); const onMouseUp = () => store?.unsetUserSelection();
const onMouseLeave = () => { const onMouseLeave = () => {
pinia.unsetUserSelection(); store?.unsetUserSelection();
pinia.unsetNodesSelection(); store?.unsetNodesSelection();
}; };
return () => ( return () => (
+2 -3
View File
@@ -157,8 +157,7 @@ const FlowRenderer = defineComponent({
}, },
setup(props, { slots }) { setup(props, { slots }) {
const store = inject<RevueFlowStore>('store'); const store = inject<RevueFlowStore>('store');
const keyPressed = useKeyPress(props.selectionKeyCode);
const selectionKeyPressed = useKeyPress(props.selectionKeyCode);
useGlobalKeyHandler({ useGlobalKeyHandler({
onElementsRemove: props.onElementsRemove, onElementsRemove: props.onElementsRemove,
@@ -200,7 +199,7 @@ const FlowRenderer = defineComponent({
zoomActivationKeyCode={props.zoomActivationKeyCode} zoomActivationKeyCode={props.zoomActivationKeyCode}
> >
{slots.default ? slots.default() : ''} {slots.default ? slots.default() : ''}
<UserSelection selectionKeyPressed={selectionKeyPressed} /> {keyPressed.value ? <UserSelection selectionKeyPressed={keyPressed.value} /> : ''}
{store?.nodesSelectionActive && ( {store?.nodesSelectionActive && (
<NodesSelection <NodesSelection
onSelectionDragStart={props.onSelectionDragStart} onSelectionDragStart={props.onSelectionDragStart}
+10 -13
View File
@@ -1,8 +1,7 @@
import useKeyPress from './useKeyPress'; import useKeyPress from './useKeyPress';
import { isNode, getConnectedEdges } from '../utils/graph'; import { isNode, getConnectedEdges } from '../utils/graph';
import { Elements, KeyCode, ElementId, FlowElement } from '../types'; import { Elements, KeyCode, ElementId, FlowElement, RevueFlowStore } from '../types';
import store from '../store'; import { inject, onMounted } from 'vue';
import { onMounted } from 'vue';
interface HookParams { interface HookParams {
deleteKeyCode: KeyCode; deleteKeyCode: KeyCode;
@@ -11,29 +10,27 @@ interface HookParams {
} }
export default ({ deleteKeyCode, multiSelectionKeyCode, onElementsRemove }: HookParams): void => { export default ({ deleteKeyCode, multiSelectionKeyCode, onElementsRemove }: HookParams): void => {
const pinia = store(); const store = inject<RevueFlowStore>('store');
const deleteKeyPressed = useKeyPress(deleteKeyCode); const deleteKeyPressed = useKeyPress(deleteKeyCode);
const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode); const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode);
onMounted(() => { onMounted(() => {
const { edges, selectedElements } = pinia; if (onElementsRemove && deleteKeyPressed.value && store?.selectedElements) {
const selectedNodes = store?.selectedElements.filter(isNode);
if (onElementsRemove && deleteKeyPressed && selectedElements) { const connectedEdges = getConnectedEdges(selectedNodes, store?.edges);
const selectedNodes = selectedElements.filter(isNode); const elementsToRemove = [...store?.selectedElements, ...connectedEdges].reduce(
const connectedEdges = getConnectedEdges(selectedNodes, edges);
const elementsToRemove = [...selectedElements, ...connectedEdges].reduce(
(res, item) => res.set(item.id, item), (res, item) => res.set(item.id, item),
new Map<ElementId, FlowElement>() new Map<ElementId, FlowElement>()
); );
onElementsRemove(Array.from(elementsToRemove.values())); onElementsRemove(Array.from(elementsToRemove.values()));
pinia.unsetNodesSelection(); store?.unsetNodesSelection();
pinia.resetSelectedElements(); store?.resetSelectedElements();
} }
}); });
onMounted(() => { onMounted(() => {
pinia.setMultiSelectionActive(multiSelectionKeyPressed); store?.setMultiSelectionActive(multiSelectionKeyPressed.value);
}); });
}; };
+32 -25
View File
@@ -1,38 +1,45 @@
import { isInputDOMNode } from '../utils'; import { isInputDOMNode } from '../utils';
import { KeyCode } from '../types'; 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); 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') { 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('keydown', downHandler);
window.addEventListener('keyup', upHandler); window.addEventListener('keyup', upHandler);
window.addEventListener('blur', resetHandler); 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;
}; };
+7 -5
View File
@@ -191,13 +191,13 @@ export default function configureStore(
const nextSelectedElements = [...selectedNodes, ...selectedEdges]; const nextSelectedElements = [...selectedNodes, ...selectedEdges];
const selectedElementsChanged = !isEqual(nextSelectedElements, this.selectedElements); const selectedElementsChanged = !isEqual(nextSelectedElements, this.selectedElements);
const selectedElementsUpdate = selectedElementsChanged const selectedElementsUpdate = selectedElementsChanged
? { ? nextSelectedElements.length > 0
selectedElements: nextSelectedElements.length > 0 ? nextSelectedElements : null ? nextSelectedElements
} : []
: {}; : [];
this.userSelectionRect = nextUserSelectRect; this.userSelectionRect = nextUserSelectRect;
this.selectedElements = selectedElementsUpdate.selectedElements as any; this.selectedElements = selectedElementsUpdate;
}, },
unsetUserSelection() { unsetUserSelection() {
const selectedNodes = this.selectedElements?.filter((node) => isNode(node) && node.__rf) as Node[]; const selectedNodes = this.selectedElements?.filter((node) => isNode(node) && node.__rf) as Node[];
@@ -206,9 +206,11 @@ export default function configureStore(
this.userSelectionRect.draw = false; this.userSelectionRect.draw = false;
if (!selectedNodes || selectedNodes.length === 0) { if (!selectedNodes || selectedNodes.length === 0) {
console.log('Foo');
this.selectedElements = null; this.selectedElements = null;
this.nodesSelectionActive = false; this.nodesSelectionActive = false;
} else { } else {
console.log('bar');
this.selectedNodesBbox = getRectOfNodes(selectedNodes); this.selectedNodesBbox = getRectOfNodes(selectedNodes);
this.nodesSelectionActive = true; this.nodesSelectionActive = true;
} }
+4 -4
View File
@@ -1,9 +1,9 @@
import { Dimensions, XYPosition, NodeExtent } from '../types'; 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; 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 => ({ 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 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]), x: clamp(position.x, extent[0][0], extent[1][0]),
y: clamp(position.y, extent[0][1], extent[1][1]) y: clamp(position.y, extent[0][1], extent[1][1])
}); });
+4 -4
View File
@@ -262,10 +262,10 @@
"@babel/helper-validator-identifier" "^7.14.5" "@babel/helper-validator-identifier" "^7.14.5"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@braks/revue-draggable@^0.1.2": "@braks/revue-draggable@^0.1.3":
version "0.1.2" version "0.1.3"
resolved "https://registry.yarnpkg.com/@braks/revue-draggable/-/revue-draggable-0.1.2.tgz#7eb53c5ecd3cdae905b873a4c70418d2f4f649b7" resolved "https://registry.yarnpkg.com/@braks/revue-draggable/-/revue-draggable-0.1.3.tgz#837a46bde7c87f8f6642ed4fb85697653ee6d068"
integrity sha512-sgtLSL4NClw2ajU/8IS7/qhUPRSO1uHd3iKCRmsCF1Lrygkj9qJ7m5DjiN7R8ifrCGvnYA9BDqNnYMcPKr/d8g== integrity sha512-9Ad35cUzkuaC7wTXSpJIYAH2kmgIh/VtL062MXTiFZ9OIZxAUMUfCnIgDTWY0sZNoxmO8CPD3XUP/YfbxoMESQ==
dependencies: dependencies:
vue-demi latest vue-demi latest