update: use store injection in UserSelection component
fix: keypress not displaying working properly
This commit is contained in:
@@ -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
@@ -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",
|
||||||
|
|||||||
@@ -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 () => (
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
@@ -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])
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user