fix: inject store instance components
chore: update revue-draggable to next tag
This commit is contained in:
@@ -2,8 +2,9 @@ import { createApp } from 'vue';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import { router } from './router';
|
||||
import { DraggablePlugin } from '@braks/revue-draggable';
|
||||
import { createPinia } from 'pinia';
|
||||
import { DraggablePlugin } from '@braks/revue-draggable';
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
app.config.performance = true;
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"lint": "yarn lint:js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@braks/revue-draggable": "^0.1.13",
|
||||
"@braks/revue-draggable": "^0.2.1-5",
|
||||
"@types/d3": "^7.0.0",
|
||||
"d3": "^7.0.0",
|
||||
"d3-selection": "^3.0.0",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { BackgroundVariant } from '../../types';
|
||||
import { BackgroundVariant, RevueFlowStore } from '../../types';
|
||||
import { createGridDotsPath, createGridLinesPath } from './utils';
|
||||
import { computed, defineComponent, HTMLAttributes, PropType } from 'vue';
|
||||
import store from '../../store';
|
||||
import { computed, defineComponent, HTMLAttributes, inject, PropType } from 'vue';
|
||||
|
||||
export interface BackgroundProps extends HTMLAttributes {
|
||||
variant?: BackgroundVariant;
|
||||
@@ -26,7 +25,7 @@ const Background = defineComponent({
|
||||
gap: {
|
||||
type: Number as PropType<BackgroundProps['gap']>,
|
||||
required: false,
|
||||
default: 15
|
||||
default: 10
|
||||
},
|
||||
color: {
|
||||
type: String as PropType<BackgroundProps['color']>,
|
||||
@@ -40,8 +39,8 @@ const Background = defineComponent({
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const pinia = store();
|
||||
const transform = computed(() => pinia.transform);
|
||||
const store = inject<RevueFlowStore>('store')!;
|
||||
const transform = computed(() => store.transform);
|
||||
// when there are multiple flows on a page we need to make sure that every background gets its own pattern.
|
||||
const patternId = `pattern-${Math.floor(Math.random() * 100000)}`;
|
||||
|
||||
@@ -50,12 +49,12 @@ const Background = defineComponent({
|
||||
const xOffset = computed(() => scaledGap.value && transform.value[0] % scaledGap.value);
|
||||
const yOffset = computed(() => scaledGap.value && transform.value[1] % scaledGap.value);
|
||||
|
||||
const isLines = props.variant === BackgroundVariant.Lines;
|
||||
const bgColor = props.color ? props.color : defaultColors[props.variant || BackgroundVariant.Dots];
|
||||
const isLines = computed(() => props.variant === BackgroundVariant.Lines);
|
||||
const bgColor = computed(() => (props.color ? props.color : defaultColors[props.variant || BackgroundVariant.Dots]));
|
||||
const path = computed(() =>
|
||||
isLines
|
||||
? scaledGap.value && props.size && createGridLinesPath(scaledGap.value, props.size, bgColor)
|
||||
: createGridDotsPath(props.size || 0.4 * transform.value[2], bgColor)
|
||||
isLines.value
|
||||
? scaledGap.value && props.size && createGridLinesPath(scaledGap.value, props.size, bgColor.value)
|
||||
: createGridDotsPath(props.size || 0.4 * transform.value[2], bgColor.value)
|
||||
);
|
||||
|
||||
return () => (
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { defineComponent, HTMLAttributes, onMounted, PropType, ref } from 'vue';
|
||||
import { defineComponent, HTMLAttributes, inject, onMounted, PropType, ref } from 'vue';
|
||||
import useZoomPanHelper from '../../hooks/useZoomPanHelper';
|
||||
import { FitViewParams } from '../../types';
|
||||
import store from '../../store';
|
||||
import { FitViewParams, RevueFlowStore } from '../../types';
|
||||
import PlusIcon from '../../../assets/icons/plus.svg';
|
||||
import MinusIcon from '../../../assets/icons/minus.svg';
|
||||
import Fitview from '../../../assets/icons/fitview.svg';
|
||||
@@ -88,7 +87,7 @@ const Controls = defineComponent({
|
||||
}
|
||||
},
|
||||
setup(props, { slots }) {
|
||||
const pinia = store();
|
||||
const store = inject<RevueFlowStore>('store')!;
|
||||
const isVisible = ref<boolean>(false);
|
||||
const zoomHelper = ref(useZoomPanHelper());
|
||||
|
||||
@@ -96,7 +95,7 @@ const Controls = defineComponent({
|
||||
zoomHelper.value = useZoomPanHelper();
|
||||
});
|
||||
|
||||
const isInteractive = pinia.nodesDraggable && pinia.nodesConnectable && pinia.elementsSelectable;
|
||||
const isInteractive = store.nodesDraggable && store.nodesConnectable && store.elementsSelectable;
|
||||
const mapClasses = ['revue-flow__controls'];
|
||||
|
||||
const onZoomInHandler = () => {
|
||||
@@ -115,7 +114,7 @@ const Controls = defineComponent({
|
||||
};
|
||||
|
||||
const onInteractiveChangeHandler = () => {
|
||||
pinia.setInteractive?.(!isInteractive);
|
||||
store.setInteractive?.(!isInteractive);
|
||||
props.onInteractiveChange?.(!isInteractive);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { getRectOfNodes, getBoundsofRects } from '../../utils/graph';
|
||||
import { Node, Rect } from '../../types';
|
||||
import { Node, Rect, RevueFlowStore } from '../../types';
|
||||
import MiniMapNode from './MiniMapNode';
|
||||
import { computed, defineComponent, HTMLAttributes, PropType } from 'vue';
|
||||
import store from '../../store';
|
||||
import { computed, defineComponent, HTMLAttributes, inject, PropType } from 'vue';
|
||||
|
||||
type StringFunc = (node: Node) => string;
|
||||
|
||||
@@ -55,8 +54,8 @@ const MiniMap = defineComponent({
|
||||
}
|
||||
},
|
||||
setup(props, { attrs }: { attrs: Record<string, any> }) {
|
||||
const pinia = store();
|
||||
const transform = computed(() => pinia.transform);
|
||||
const store = inject<RevueFlowStore>('store')!;
|
||||
const transform = computed(() => store.transform);
|
||||
const elementWidth = computed(() => (attrs.style?.width || defaultWidth)! as number);
|
||||
const elementHeight = computed(() => (attrs.style?.height || defaultHeight)! as number);
|
||||
const nodeColorFunc = computed(() => (props.nodeColor instanceof Function ? props.nodeColor : () => props.nodeColor) as StringFunc);
|
||||
@@ -66,13 +65,13 @@ const MiniMap = defineComponent({
|
||||
const nodeClassNameFunc = computed(
|
||||
() => (props.nodeClassName instanceof Function ? props.nodeClassName : () => props.nodeClassName) as StringFunc
|
||||
);
|
||||
const hasNodes = computed(() => pinia.nodes && pinia.nodes.length);
|
||||
const bb = computed(() => getRectOfNodes(pinia.nodes));
|
||||
const hasNodes = computed(() => store.nodes && store.nodes.length);
|
||||
const bb = computed(() => getRectOfNodes(store.nodes));
|
||||
const viewBB = computed<Rect>(() => ({
|
||||
x: -transform.value[0] / transform.value[2],
|
||||
y: -transform.value[1] / transform.value[2],
|
||||
width: pinia.width / transform.value[2],
|
||||
height: pinia.height / transform.value[2]
|
||||
width: store.width / transform.value[2],
|
||||
height: store.height / transform.value[2]
|
||||
}));
|
||||
const boundingRect = computed(() => (hasNodes.value ? getBoundsofRects(bb.value, viewBB.value) : viewBB.value));
|
||||
const scaledWidth = computed(() => boundingRect.value.width / elementWidth.value);
|
||||
@@ -94,7 +93,7 @@ const MiniMap = defineComponent({
|
||||
viewBox={`${x.value} ${y.value} ${width.value} ${height.value}`}
|
||||
class="revue-flow__minimap"
|
||||
>
|
||||
{pinia.nodes
|
||||
{store.nodes
|
||||
.filter((node) => !node.isHidden)
|
||||
.map((node) => (
|
||||
<MiniMapNode
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { Component, computed, defineComponent, PropType, ref } from 'vue';
|
||||
|
||||
import store from '../../store';
|
||||
import { Edge, EdgeProps, Position, WrapEdgeProps } from '../../types';
|
||||
import { computed, DefineComponent, defineComponent, inject, PropType, ref } from 'vue';
|
||||
import { Edge, EdgeProps, Position, RevueFlowStore, WrapEdgeProps } from '../../types';
|
||||
import { onMouseDown } from '../Handle/handler';
|
||||
import { EdgeAnchor } from './EdgeAnchor';
|
||||
|
||||
export default (EdgeComponent: any): Component<EdgeProps> => {
|
||||
export default (EdgeComponent: DefineComponent<EdgeProps>) => {
|
||||
return defineComponent({
|
||||
components: { EdgeComponent },
|
||||
props: {
|
||||
@@ -187,7 +185,7 @@ export default (EdgeComponent: any): Component<EdgeProps> => {
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const pinia = store();
|
||||
const store = inject<RevueFlowStore>('store')!;
|
||||
const updating = ref<boolean>(false);
|
||||
const inactive = computed(() => !props.elementsSelectable && !props.onClick);
|
||||
const edgeClasses = computed(() => [
|
||||
@@ -221,8 +219,8 @@ export default (EdgeComponent: any): Component<EdgeProps> => {
|
||||
|
||||
const onEdgeClick = (event: MouseEvent) => {
|
||||
if (props.elementsSelectable) {
|
||||
pinia.unsetNodesSelection();
|
||||
pinia.addSelectedElements(edgeElement.value as any);
|
||||
store.unsetNodesSelection();
|
||||
store.addSelectedElements(edgeElement.value as any);
|
||||
}
|
||||
|
||||
if (typeof props.onClick === 'function') props.onClick(event, edgeElement.value);
|
||||
@@ -262,12 +260,12 @@ export default (EdgeComponent: any): Component<EdgeProps> => {
|
||||
event,
|
||||
handleId,
|
||||
nodeId,
|
||||
pinia.setConnectionNodeId,
|
||||
pinia.setConnectionPosition,
|
||||
store.setConnectionNodeId,
|
||||
store.setConnectionPosition,
|
||||
props.onConnectEdge as any,
|
||||
isTarget,
|
||||
isValidConnection,
|
||||
pinia.connectionMode,
|
||||
store.connectionMode,
|
||||
isSourceHandle ? 'target' : 'source',
|
||||
_onEdgeUpdate
|
||||
);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Node, RevueFlowStore, WrapNodeProps } from '../../types';
|
||||
import { computed, CSSProperties, DefineComponent, defineComponent, inject, onMounted, provide, ref } from 'vue';
|
||||
import { DraggableCore, DraggableEventHandler } from '@braks/revue-draggable';
|
||||
import { computed, CSSProperties, DefineComponent, defineComponent, inject, onMounted, provide, ref, watchEffect } from 'vue';
|
||||
import { DraggableEventHandler, DraggableCore } from '@braks/revue-draggable';
|
||||
|
||||
export default (NodeComponent: DefineComponent<WrapNodeProps>) => {
|
||||
return defineComponent({
|
||||
props: WrapNodeProps,
|
||||
setup(props) {
|
||||
const store = inject<RevueFlowStore>('store');
|
||||
const store = inject<RevueFlowStore>('store')!;
|
||||
provide('NodeIdContext', props.id);
|
||||
|
||||
const nodeElement = ref<HTMLDivElement | undefined>();
|
||||
@@ -134,7 +134,7 @@ export default (NodeComponent: DefineComponent<WrapNodeProps>) => {
|
||||
props.onNodeDragStop?.(event as MouseEvent, node.value as Node);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
watchEffect(() => {
|
||||
if (nodeElement.value && !props.isHidden) {
|
||||
store?.updateNodeDimensions([{ id: props.id || '', nodeElement: nodeElement.value, forceUpdate: true }]);
|
||||
}
|
||||
@@ -164,14 +164,13 @@ export default (NodeComponent: DefineComponent<WrapNodeProps>) => {
|
||||
|
||||
return () => (
|
||||
<DraggableCore
|
||||
onStart={onDragStart}
|
||||
onDrag={onDrag}
|
||||
onStop={onDragStop}
|
||||
scale={props.scale}
|
||||
start={onDragStart}
|
||||
move={onDrag}
|
||||
stop={onDragStop}
|
||||
scale={store.transform[2]}
|
||||
disabled={!props.isDraggable}
|
||||
cancel=".nodrag"
|
||||
grid={grid.value}
|
||||
nodeRef={nodeElement.value}
|
||||
enableUserSelectHack={false}
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
import { isNode } from '../../utils/graph';
|
||||
import { Node, RevueFlowStore } from '../../types';
|
||||
import { computed, defineComponent, inject, PropType, ref } from 'vue';
|
||||
import Draggable, { DraggableEventHandler } from '@braks/revue-draggable';
|
||||
import { computed, defineComponent, inject, PropType } from 'vue';
|
||||
import { Draggable, DraggableEventHandler } from '@braks/revue-draggable';
|
||||
|
||||
export interface NodesSelectionProps {
|
||||
onSelectionDragStart?: (event: MouseEvent, nodes: Node[]) => void;
|
||||
@@ -39,7 +39,6 @@ const NodesSelection = defineComponent({
|
||||
},
|
||||
setup(props) {
|
||||
const store = inject<RevueFlowStore>('store')!;
|
||||
const nodeRef = ref<HTMLElement | undefined>();
|
||||
const grid = computed(() => (store.snapToGrid ? store.snapGrid : [1, 1])! as [number, number]);
|
||||
|
||||
const selectedNodes = computed(() =>
|
||||
@@ -67,10 +66,12 @@ const NodesSelection = defineComponent({
|
||||
}));
|
||||
|
||||
const onStart: DraggableEventHandler = (event: MouseEvent) => {
|
||||
console.log('ondragstart');
|
||||
props.onSelectionDragStart?.(event, selectedNodes.value);
|
||||
};
|
||||
|
||||
const onDrag: DraggableEventHandler = (event, data) => {
|
||||
console.log('ondrag');
|
||||
props.onSelectionDrag?.(event, selectedNodes.value);
|
||||
|
||||
store.updateNodePosDiff({
|
||||
@@ -83,6 +84,7 @@ const NodesSelection = defineComponent({
|
||||
};
|
||||
|
||||
const onStop: DraggableEventHandler = (event: MouseEvent) => {
|
||||
console.log('ondragend');
|
||||
store.updateNodePosDiff({
|
||||
isDragging: false
|
||||
});
|
||||
@@ -104,16 +106,14 @@ const NodesSelection = defineComponent({
|
||||
) : (
|
||||
<div class="revue-flow__nodesselection" style={style.value}>
|
||||
<Draggable
|
||||
start={onStart}
|
||||
move={onDrag}
|
||||
stop={onStop}
|
||||
scale={store.transform[2]}
|
||||
grid={grid.value}
|
||||
onStart={onStart}
|
||||
onDrag={onDrag}
|
||||
onStop={onStop}
|
||||
nodeRef={nodeRef.value}
|
||||
enableUserSelectHack={false}
|
||||
nodeRef={nodeRef.value}
|
||||
>
|
||||
<div ref={nodeRef} class="revue-flow__nodesselection-rect" onContextmenu={onContextMenu} style={innerStyle.value} />
|
||||
<div class="revue-flow__nodesselection-rect" onContextmenu={onContextMenu} style={innerStyle.value} />
|
||||
</Draggable>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
import { computed, CSSProperties, defineComponent, HTMLAttributes, onBeforeUnmount, PropType, provide, watchEffect } from 'vue';
|
||||
import {
|
||||
computed,
|
||||
CSSProperties,
|
||||
defineComponent,
|
||||
HTMLAttributes,
|
||||
onBeforeUnmount,
|
||||
onUpdated,
|
||||
PropType,
|
||||
provide,
|
||||
watchEffect
|
||||
} from 'vue';
|
||||
import GraphView from '../GraphView';
|
||||
import DefaultNode from '../../components/Nodes/DefaultNode';
|
||||
import InputNode from '../../components/Nodes/InputNode';
|
||||
@@ -547,6 +557,11 @@ const RevueFlow = defineComponent({
|
||||
props.onSelectionChange?.(store.selectedElements);
|
||||
});
|
||||
|
||||
onUpdated(() => {
|
||||
store.setElements(props.elements);
|
||||
props.onSelectionChange?.(store.selectedElements);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
store.$reset();
|
||||
store.setElements([]);
|
||||
|
||||
@@ -2,9 +2,8 @@ import { zoom, zoomIdentity } from 'd3-zoom';
|
||||
import { select, pointer } from 'd3-selection';
|
||||
|
||||
import { clamp } from '../../utils';
|
||||
import { FlowTransform, TranslateExtent, PanOnScrollMode, KeyCode } from '../../types';
|
||||
import { defineComponent, PropType, ref, watch, watchEffect } from 'vue';
|
||||
import store from '../../store';
|
||||
import { FlowTransform, TranslateExtent, PanOnScrollMode, KeyCode, RevueFlowStore } from '../../types';
|
||||
import { defineComponent, inject, PropType, ref, watchEffect } from 'vue';
|
||||
import useKeyPress from '../../hooks/useKeyPress';
|
||||
import useResizeHandler from '../../hooks/useResizeHandler';
|
||||
|
||||
@@ -39,19 +38,19 @@ const eventToFlowTransform = (eventTransform: any): FlowTransform => ({
|
||||
const ZoomPane = defineComponent({
|
||||
props: {
|
||||
onMove: {
|
||||
type: Function() as PropType<ZoomPaneProps['onMove']>,
|
||||
type: Function as unknown as PropType<ZoomPaneProps['onMove']>,
|
||||
required: false,
|
||||
default: undefined as any
|
||||
default: () => {}
|
||||
},
|
||||
onMoveStart: {
|
||||
type: Function() as PropType<ZoomPaneProps['onMoveStart']>,
|
||||
type: Function as unknown as PropType<ZoomPaneProps['onMoveStart']>,
|
||||
required: false,
|
||||
default: undefined as any
|
||||
default: () => {}
|
||||
},
|
||||
onMoveEnd: {
|
||||
type: Function() as PropType<ZoomPaneProps['onMoveEnd']>,
|
||||
type: Function as unknown as PropType<ZoomPaneProps['onMoveEnd']>,
|
||||
required: false,
|
||||
default: undefined as any
|
||||
default: () => {}
|
||||
},
|
||||
zoomOnScroll: {
|
||||
type: Boolean as PropType<ZoomPaneProps['zoomOnScroll']>,
|
||||
@@ -120,30 +119,30 @@ const ZoomPane = defineComponent({
|
||||
}
|
||||
},
|
||||
setup(props, { slots }) {
|
||||
const pinia = store();
|
||||
const store = inject<RevueFlowStore>('store')!;
|
||||
const zoomPane = ref<HTMLDivElement | null>(null);
|
||||
const prevTransform = ref<FlowTransform>({ x: 0, y: 0, zoom: 0 });
|
||||
const zoomActivationKeyPressed = useKeyPress(props.zoomActivationKeyCode);
|
||||
|
||||
watch(zoomPane, () => {
|
||||
if (zoomPane.value) useResizeHandler(zoomPane.value);
|
||||
watchEffect(() => {
|
||||
if (zoomPane.value) useResizeHandler(zoomPane.value, store.updateSize);
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (zoomPane.value && props.defaultPosition && props.defaultZoom) {
|
||||
const currentTranslateExtent =
|
||||
typeof props.translateExtent !== 'undefined' ? props.translateExtent : pinia.translateExtent;
|
||||
const d3ZoomInstance = zoom().scaleExtent([pinia.minZoom, pinia.maxZoom]).translateExtent(currentTranslateExtent);
|
||||
typeof props.translateExtent !== 'undefined' ? props.translateExtent : store.translateExtent;
|
||||
const d3ZoomInstance = zoom().scaleExtent([store.minZoom, store.maxZoom]).translateExtent(currentTranslateExtent);
|
||||
const selection = select(zoomPane.value as Element).call(d3ZoomInstance);
|
||||
|
||||
const clampedX = clamp(props.defaultPosition[0], currentTranslateExtent[0][0], currentTranslateExtent[1][0]);
|
||||
const clampedY = clamp(props.defaultPosition[1], currentTranslateExtent[0][1], currentTranslateExtent[1][1]);
|
||||
const clampedZoom = clamp(props.defaultZoom, pinia.minZoom, pinia.maxZoom);
|
||||
const clampedZoom = clamp(props.defaultZoom, store.minZoom, store.maxZoom);
|
||||
const updatedTransform = zoomIdentity.translate(clampedX, clampedY).scale(clampedZoom);
|
||||
|
||||
d3ZoomInstance.transform(selection, updatedTransform);
|
||||
|
||||
pinia.initD3Zoom({
|
||||
store.initD3Zoom({
|
||||
d3Zoom: d3ZoomInstance,
|
||||
d3Selection: selection,
|
||||
d3ZoomHandler: selection.on('wheel.zoom'),
|
||||
@@ -154,21 +153,21 @@ const ZoomPane = defineComponent({
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (pinia.d3Selection && pinia.d3Zoom) {
|
||||
if (store.d3Selection && store.d3Zoom) {
|
||||
if (props.panOnScroll && zoomActivationKeyPressed) {
|
||||
pinia.d3Selection
|
||||
store.d3Selection
|
||||
.on('wheel', (event: any) => {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
const currentZoom = pinia.d3Selection?.property('__zoom').k || 1;
|
||||
const currentZoom = store.d3Selection?.property('__zoom').k || 1;
|
||||
|
||||
if (event.ctrlKey && props.zoomOnPinch) {
|
||||
const point = pointer(event);
|
||||
// taken from https://github.com/d3/d3-zoom/blob/master/src/zoom.js
|
||||
const pinchDelta = -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * 10;
|
||||
const zoom = currentZoom * Math.pow(2, pinchDelta);
|
||||
if (pinia.d3Selection) pinia.d3Zoom?.scaleTo(pinia.d3Selection, zoom, point);
|
||||
if (store.d3Selection) store.d3Zoom?.scaleTo(store.d3Selection, zoom, point);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -179,27 +178,27 @@ const ZoomPane = defineComponent({
|
||||
const deltaX = props.panOnScrollMode === PanOnScrollMode.Vertical ? 0 : event.deltaX * deltaNormalize;
|
||||
const deltaY = props.panOnScrollMode === PanOnScrollMode.Horizontal ? 0 : event.deltaY * deltaNormalize;
|
||||
|
||||
if (pinia.d3Selection && props.panOnScrollSpeed)
|
||||
pinia.d3Zoom?.translateBy(
|
||||
pinia.d3Selection,
|
||||
if (store.d3Selection && props.panOnScrollSpeed)
|
||||
store.d3Zoom?.translateBy(
|
||||
store.d3Selection,
|
||||
-(deltaX / currentZoom) * props.panOnScrollSpeed,
|
||||
-(deltaY / currentZoom) * props.panOnScrollSpeed
|
||||
);
|
||||
})
|
||||
.on('wheel.zoom', null);
|
||||
} else if (typeof pinia.d3ZoomHandler !== 'undefined') {
|
||||
pinia.d3Selection.on('wheel', null).on('wheel.zoom', pinia.d3ZoomHandler);
|
||||
} else if (typeof store.d3ZoomHandler !== 'undefined') {
|
||||
store.d3Selection.on('wheel', null).on('wheel.zoom', store.d3ZoomHandler);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (pinia.d3Zoom) {
|
||||
if (store.d3Zoom) {
|
||||
if (props.selectionKeyPressed) {
|
||||
pinia.d3Zoom.on('zoom', null);
|
||||
store.d3Zoom.on('zoom', null);
|
||||
} else {
|
||||
pinia.d3Zoom.on('zoom', (event: any) => {
|
||||
pinia.updateTransform([event.transform.x, event.transform.y, event.transform.k]);
|
||||
store.d3Zoom.on('zoom', (event: any) => {
|
||||
store.updateTransform([event.transform.x, event.transform.y, event.transform.k]);
|
||||
|
||||
if (props.onMove) {
|
||||
const flowTransform = eventToFlowTransform(event.transform);
|
||||
@@ -211,9 +210,9 @@ const ZoomPane = defineComponent({
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (pinia.d3Zoom) {
|
||||
if (store.d3Zoom) {
|
||||
if (props.onMoveStart) {
|
||||
pinia.d3Zoom.on('start', (event: any) => {
|
||||
store.d3Zoom.on('start', (event: any) => {
|
||||
if (viewChanged(prevTransform.value, event.transform)) {
|
||||
const flowTransform = eventToFlowTransform(event.transform);
|
||||
prevTransform.value = flowTransform;
|
||||
@@ -222,15 +221,15 @@ const ZoomPane = defineComponent({
|
||||
}
|
||||
});
|
||||
} else {
|
||||
pinia.d3Zoom.on('start', null);
|
||||
store.d3Zoom.on('start', null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (pinia.d3Zoom) {
|
||||
if (store.d3Zoom) {
|
||||
if (props.onMoveEnd) {
|
||||
pinia.d3Zoom.on('end', (event: any) => {
|
||||
store.d3Zoom.on('end', (event: any) => {
|
||||
if (viewChanged(prevTransform.value, event.transform)) {
|
||||
const flowTransform = eventToFlowTransform(event.transform);
|
||||
prevTransform.value = flowTransform;
|
||||
@@ -239,14 +238,14 @@ const ZoomPane = defineComponent({
|
||||
}
|
||||
});
|
||||
} else {
|
||||
pinia.d3Zoom.on('end', null);
|
||||
store.d3Zoom.on('end', null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (pinia.d3Zoom) {
|
||||
pinia.d3Zoom.filter((event: any) => {
|
||||
if (store.d3Zoom) {
|
||||
store.d3Zoom.filter((event: any) => {
|
||||
const zoomScroll = props.zoomOnScroll;
|
||||
const pinchZoom = props.zoomOnPinch && event.ctrlKey;
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { getDimensions } from '../utils';
|
||||
import store from '../store';
|
||||
|
||||
export default (rendererNode: HTMLDivElement) => {
|
||||
const pinia = store();
|
||||
import { Dimensions } from '../types';
|
||||
|
||||
export default (rendererNode: HTMLDivElement, updateSize: (size: Dimensions) => any) => {
|
||||
let resizeObserver: ResizeObserver;
|
||||
|
||||
const updateDimensions = () => {
|
||||
@@ -17,7 +15,7 @@ export default (rendererNode: HTMLDivElement) => {
|
||||
console.log('The revue Flow parent container needs a width and a height to render the graph.');
|
||||
}
|
||||
|
||||
pinia.updateSize(size);
|
||||
updateSize(size);
|
||||
};
|
||||
|
||||
updateDimensions();
|
||||
@@ -27,14 +25,4 @@ export default (rendererNode: HTMLDivElement) => {
|
||||
resizeObserver = new ResizeObserver(() => updateDimensions());
|
||||
resizeObserver.observe(rendererNode);
|
||||
}
|
||||
/*
|
||||
return () => {
|
||||
window.onresize = null;
|
||||
|
||||
if (resizeObserver && rendererNode) {
|
||||
resizeObserver.unobserve(rendererNode);
|
||||
}
|
||||
};
|
||||
|
||||
*/
|
||||
};
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { ElementId, UpdateNodeInternals } from '../types';
|
||||
import store from '../store';
|
||||
import { ElementId, RevueFlowStore, UpdateNodeInternals } from '../types';
|
||||
import { inject } from 'vue';
|
||||
|
||||
function useUpdateNodeInternals(): UpdateNodeInternals {
|
||||
const pinia = store();
|
||||
const store = inject<RevueFlowStore>('store')!;
|
||||
|
||||
return (id: ElementId) => {
|
||||
const nodeElement: HTMLDivElement | null = document.querySelector(`.revue-flow__node[data-id="${id}"]`);
|
||||
|
||||
if (nodeElement) {
|
||||
pinia.updateNodeDimensions([{ id, nodeElement, forceUpdate: true }]);
|
||||
store.updateNodeDimensions([{ id, nodeElement, forceUpdate: true }]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { zoomIdentity } from 'd3-zoom';
|
||||
import { getRectOfNodes, pointToRendererPoint, getTransformForBounds } from '../utils/graph';
|
||||
import { FitViewParams, FlowTransform, ZoomPanHelperFunctions, Rect, XYPosition } from '../types';
|
||||
import store from '../store';
|
||||
import { FitViewParams, FlowTransform, ZoomPanHelperFunctions, Rect, XYPosition, RevueFlowStore } from '../types';
|
||||
import { inject } from 'vue';
|
||||
|
||||
const DEFAULT_PADDING = 0.1;
|
||||
|
||||
@@ -18,20 +18,20 @@ const initialZoomPanHelper: ZoomPanHelperFunctions = {
|
||||
};
|
||||
|
||||
const useZoomPanHelper = (): ZoomPanHelperFunctions => {
|
||||
const pinia = store();
|
||||
const store = inject<RevueFlowStore>('store')!;
|
||||
const zoomPanHelperFunctions = () => {
|
||||
if (pinia.d3Selection && pinia.d3Zoom) {
|
||||
if (store.d3Selection && store.d3Zoom) {
|
||||
return {
|
||||
zoomIn: () => pinia.d3Zoom?.scaleBy(pinia.d3Selection as any, 1.2),
|
||||
zoomOut: () => pinia.d3Zoom?.scaleBy(pinia.d3Selection as any, 1 / 1.2),
|
||||
zoomTo: (zoomLevel: number) => pinia.d3Zoom?.scaleTo(pinia.d3Selection as any, zoomLevel),
|
||||
zoomIn: () => store.d3Zoom?.scaleBy(store.d3Selection as any, 1.2),
|
||||
zoomOut: () => store.d3Zoom?.scaleBy(store.d3Selection as any, 1 / 1.2),
|
||||
zoomTo: (zoomLevel: number) => store.d3Zoom?.scaleTo(store.d3Selection as any, zoomLevel),
|
||||
transform: (transform: FlowTransform) => {
|
||||
const nextTransform = zoomIdentity.translate(transform.x, transform.y).scale(transform.zoom);
|
||||
|
||||
pinia.d3Zoom?.transform(pinia.d3Selection as any, nextTransform);
|
||||
store.d3Zoom?.transform(store.d3Selection as any, nextTransform);
|
||||
},
|
||||
fitView: (options: FitViewParams = { padding: DEFAULT_PADDING, includeHiddenNodes: false }) => {
|
||||
const { nodes, width, height, minZoom, maxZoom } = pinia;
|
||||
const { nodes, width, height, minZoom, maxZoom } = store;
|
||||
|
||||
if (!nodes.length) {
|
||||
return;
|
||||
@@ -48,27 +48,27 @@ const useZoomPanHelper = (): ZoomPanHelperFunctions => {
|
||||
);
|
||||
const transform = zoomIdentity.translate(x, y).scale(zoom);
|
||||
|
||||
pinia.d3Zoom?.transform(pinia.d3Selection as any, transform);
|
||||
store.d3Zoom?.transform(store.d3Selection as any, transform);
|
||||
},
|
||||
setCenter: (x: number, y: number, zoom?: number) => {
|
||||
const { width, height, maxZoom } = pinia;
|
||||
const { width, height, maxZoom } = store;
|
||||
|
||||
const nextZoom = typeof zoom !== 'undefined' ? zoom : maxZoom;
|
||||
const centerX = width / 2 - x * nextZoom;
|
||||
const centerY = height / 2 - y * nextZoom;
|
||||
const transform = zoomIdentity.translate(centerX, centerY).scale(nextZoom);
|
||||
|
||||
pinia.d3Zoom?.transform(pinia.d3Selection as any, transform);
|
||||
store.d3Zoom?.transform(store.d3Selection as any, transform);
|
||||
},
|
||||
fitBounds: (bounds: Rect, padding = DEFAULT_PADDING) => {
|
||||
const { width, height, minZoom, maxZoom } = pinia;
|
||||
const { width, height, minZoom, maxZoom } = store;
|
||||
const [x, y, zoom] = getTransformForBounds(bounds, width, height, minZoom, maxZoom, padding);
|
||||
const transform = zoomIdentity.translate(x, y).scale(zoom);
|
||||
|
||||
pinia.d3Zoom?.transform(pinia.d3Selection as any, transform);
|
||||
store.d3Zoom?.transform(store.d3Selection as any, transform);
|
||||
},
|
||||
project: (position: XYPosition) => {
|
||||
const { transform, snapToGrid, snapGrid } = pinia;
|
||||
const { transform, snapToGrid, snapGrid } = store;
|
||||
return pointToRendererPoint(position, transform, snapToGrid, snapGrid);
|
||||
},
|
||||
initialized: true
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import configureStore from './configure-store';
|
||||
|
||||
import { RevueFlowState, ConnectionMode } from '../types';
|
||||
|
||||
export const initialState: RevueFlowState = {
|
||||
@@ -55,7 +53,3 @@ export const initialState: RevueFlowState = {
|
||||
|
||||
revueFlowVersion: typeof __REVUE_FLOW_VERSION__ !== 'undefined' ? __REVUE_FLOW_VERSION__ : '-'
|
||||
};
|
||||
|
||||
const store = configureStore(initialState);
|
||||
|
||||
export default store;
|
||||
|
||||
29
yarn.lock
29
yarn.lock
@@ -262,11 +262,12 @@
|
||||
"@babel/helper-validator-identifier" "^7.14.5"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@braks/revue-draggable@^0.1.13":
|
||||
version "0.1.13"
|
||||
resolved "https://registry.yarnpkg.com/@braks/revue-draggable/-/revue-draggable-0.1.13.tgz#cff5a9ac21c488de5b0c3fef6cdbd3f8f828dd21"
|
||||
integrity sha512-unczSXZNK3ZnHoIj5w45a4eN7iQH6s0Ot33G2s7zkdMRHcoGh8Cc0ltw5m5XlrEgk4ch0vAEIU+MQiS8/D27uw==
|
||||
"@braks/revue-draggable@^0.2.1-5":
|
||||
version "0.2.1-5"
|
||||
resolved "https://registry.yarnpkg.com/@braks/revue-draggable/-/revue-draggable-0.2.1-5.tgz#280f9cb4dfd5c3bc88dff0f8c70ffa8966536328"
|
||||
integrity sha512-+oDuUvTVd5ST6brdtfXYJMnFrmyQat9W7yUKpKBTI0od3ycfaGgMCT9w+OoQ3rlBi2cV6gFXlhZVIeLi+v55aA==
|
||||
dependencies:
|
||||
"@vueuse/core" "^5.1.3"
|
||||
vue-demi latest
|
||||
|
||||
"@eslint/eslintrc@^0.4.2":
|
||||
@@ -911,6 +912,21 @@
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.4.tgz#c14c461ec42ea2c1556e86f60b0354341d91adc3"
|
||||
integrity sha512-6O45kZAmkLvzGLToBxEz4lR2W6kXohCtebV2UxjH9GXjd8X9AhEn68FN9eNanFtWNzvgw1hqd6HkPRVQalqf7Q==
|
||||
|
||||
"@vueuse/core@^5.1.3":
|
||||
version "5.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-5.1.4.tgz#c590bd1ff5cdd3d2caa033b65ed8cb42fc12a534"
|
||||
integrity sha512-iuRhSaScI1GJS4N3CFPc1GajOr6F6J1Nng1I6ocNOjLx+evss6egImx9wnuX45fxqQstnh7Vfqe3FF7+0NgoWg==
|
||||
dependencies:
|
||||
"@vueuse/shared" "5.1.4"
|
||||
vue-demi "*"
|
||||
|
||||
"@vueuse/shared@5.1.4":
|
||||
version "5.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-5.1.4.tgz#35e3aa8ce7e52b447191915ee8b4afa481838c43"
|
||||
integrity sha512-C0xiMv8+sFI3WhXdlrcLKI4d4dFnouHe4Te51cxWgcmpW7S8eUiM8fXPaQVxUQZ4E9PCx3zEZpNpCLzQa+6Lag==
|
||||
dependencies:
|
||||
vue-demi "*"
|
||||
|
||||
acorn-jsx@^5.2.0, acorn-jsx@^5.3.1:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||
@@ -5625,6 +5641,11 @@ vite@^2.3.8:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
vue-demi@*:
|
||||
version "0.11.2"
|
||||
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.11.2.tgz#faa06da53887c493a695b997f4fcb4784a667990"
|
||||
integrity sha512-J+X8Au6BhQdcej6LY4O986634hZLu55L0ewU2j8my7WIKlu8cK0dqmdUxqVHHMd/cMrKKZ9SywB/id6aLhwCtA==
|
||||
|
||||
vue-demi@latest:
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.10.1.tgz#229b81395510f02f4ee255344557a12cc0120930"
|
||||
|
||||
Reference in New Issue
Block a user