Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-xarrows

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-xarrows - npm Package Compare versions

Comparing version 1.4.4 to 1.5.0

CHANGELOG.md

2

lib/index.d.ts

@@ -13,3 +13,3 @@ import React from "react";

headSize?: number;
path: "smooth" | "grid" | "straight";
path?: "smooth" | "grid" | "straight";
curveness?: number;

@@ -16,0 +16,0 @@ dashness?: boolean | {

@@ -1,85 +0,49 @@

var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
"use strict";
//// @ts-nocheck
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
import React, { useRef, useEffect, useState } from "react";
import _ from "lodash";
const findCommonAncestor = (elem, elem2) => {
function parents(node) {
var nodes = [node];
for (; node; node = node.parentNode) {
nodes.unshift(node);
}
return nodes;
}
function commonAncestor(node1, node2) {
var parents1 = parents(node1);
var parents2 = parents(node2);
// if (parents1[0] !== parents2[0]) throw new Error("No common ancestor!");
if (parents1[0] !== parents2[0])
throw new Error("No common ancestor!");
for (var i = 0; i < parents1.length; i++) {
if (parents1[i] !== parents2[i])
return parents1[i - 1];
}
}
return commonAncestor(elem, elem2);
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
const findAllChildren = (child, parent) => {
if (child === parent)
return [];
let children = [];
let childParent = child.parentElement;
while (childParent !== parent) {
children.push(childParent);
childParent = childParent.parentElement;
}
return children;
};
const getElementByPropGiven = (ref) => {
var myRef;
if (typeof ref === "string") {
myRef = document.getElementById(ref);
if (myRef === null)
throw Error(`'${ref}' is not an id of element in the dom. make sure you provided current id or provide a React reference to element instead.`);
}
else
myRef = ref.current;
if (myRef === null)
throw Error(`'${ref}' is not a valid react reference to html element
OR
you tried to render Xarrow before one of the anchors.
please provide correct react reference or provide id instead.`);
return myRef;
};
const typeOf = (arg) => {
let type = typeof arg;
if (type === "object") {
if (arg === null)
type = "null";
else if (Array.isArray(arg))
type = "array";
}
return type;
};
const Xarrow = (_a) => {
var props = __rest(_a, []);
const selfRef = useRef(null);
const [anchorsRefs, setAnchorsRefs] = useState({ start: null, end: null });
const [prevPosState, setPrevPosState] = useState(null);
const [prevProps, setPrevProps] = useState(null);
const [anchorsParents, setAnchorsParents] = useState(null); //list children of the common ancestor of the arrow with start and end until start or end
const [commonAncestor, setCommonAncestor] = useState(null); //list children of the common ancestor of the arrow with start and end until start or end
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
const lodash_isequal_1 = __importDefault(require("lodash.isequal"));
const lodash_pick_1 = __importDefault(require("lodash.pick"));
const utils_1 = require("./utils");
const prop_types_1 = __importDefault(require("prop-types"));
const Xarrow = (props) => {
let { startAnchor, endAnchor, label, color, lineColor, headColor, strokeWidth, headSize, path, curveness, dashness, passProps, advanced, } = props;
const selfRef = react_1.useRef(null);
const [anchorsRefs, setAnchorsRefs] = react_1.useState({ start: null, end: null });
const [prevPosState, setPrevPosState] = react_1.useState(null);
const [prevProps, setPrevProps] = react_1.useState(null);
const updateIfNeeded = () => {
if (checkIfAnchorsRefsChanged()) {
// check if anchors refs changed
const start = utils_1.getElementByPropGiven(props.start);
const end = utils_1.getElementByPropGiven(props.end);
// in case one of the elements does not mounted skip any update
if (start == null || end == null)
return;
// if anchors changed re-set them
if (!lodash_isequal_1.default(anchorsRefs, { start, end })) {
initAnchorsRefs();
}
else if (!_.isEqual(props, prevProps)) {
else if (!lodash_isequal_1.default(props, prevProps)) {
//first check if any properties changed

@@ -96,3 +60,3 @@ if (prevProps) {

let posState = getAnchorsPos();
if (!_.isEqual(prevPosState, posState)) {
if (!lodash_isequal_1.default(prevPosState, posState)) {
setPrevPosState(posState);

@@ -103,169 +67,21 @@ updatePosition(posState);

};
const checkIfAnchorsRefsChanged = () => {
var start = getElementByPropGiven(props.start);
var end = getElementByPropGiven(props.end);
return !_.isEqual(anchorsRefs, { start, end });
};
const monitorDOMchanges = () => {
[...anchorsParents.start, ...anchorsParents.end].forEach((elem) => {
elem.addEventListener("scroll", updateIfNeeded);
});
window.addEventListener("resize", updateIfNeeded);
if (window.getComputedStyle(commonAncestor).position !== "relative")
commonAncestor.addEventListener("scroll", updateIfNeeded);
};
const cleanMonitorDOMchanges = () => {
[...anchorsParents.start, ...anchorsParents.end].forEach((elem) => {
elem.removeEventListener("scroll", updateIfNeeded);
});
window.removeEventListener("resize", updateIfNeeded);
if (window.getComputedStyle(commonAncestor).position === "relative")
commonAncestor.removeEventListener("scroll", updateIfNeeded);
};
const initParentsChildren = () => {
let anchorsCommonAncestor = findCommonAncestor(anchorsRefs.start, anchorsRefs.end);
let allAncestor = findCommonAncestor(anchorsCommonAncestor, selfRef.current);
let allAncestorChildrenStart = findAllChildren(anchorsRefs.start, allAncestor);
let allAncestorChildrenEnd = findAllChildren(anchorsRefs.end, allAncestor);
setCommonAncestor(allAncestor);
setAnchorsParents({
start: allAncestorChildrenStart,
end: allAncestorChildrenEnd,
});
let allAncestorPosStyle = window.getComputedStyle(allAncestor).position;
if (props.consoleWarning) {
if (allAncestorPosStyle !== "relative" &&
(allAncestor.scrollHeight > allAncestor.clientHeight || allAncestor.scrollWidth > allAncestor.clientWidth))
console.warn(`Xarrow warning: it is recommended to set common ancestor positioning style to 'relative',this will prevent rerender on every scroll event.
change position style from '${allAncestorPosStyle}' to 'relative' of element `, allAncestor);
if (selfRef.current.parentElement !== anchorsCommonAncestor)
console.warn(`Xarrow warning: you placed Xarrow not as son of the common ancestor of 'start' component and 'end' component.
the suggested element to put Xarrow inside of to prevent redundant rerenders iss `, anchorsCommonAncestor, " and not ", selfRef.current.parentElement, `if this was your intention set monitorDOMchanges to true so Xarrow will render whenever relevant DOM events are triggered.
to disable this warnings set consoleWarning property to false`);
if ((allAncestorChildrenStart.length > 0 || allAncestorChildrenEnd.length > 0) &&
props.monitorDOMchanges === false)
console.warn(`Xarrow warning: set monitorDOMchanges to true - its possible that the positioning will get out of sync on DOM events(like scroll),
on these elements`, _.uniqWith([...allAncestorChildrenStart, ...allAncestorChildrenEnd], _.isEqual), `\nto disable this warnings set consoleWarning property to false`);
}
};
const testUserGivenProperties = () => {
const throwError = (errorMsg, consoleMsg) => {
let err = Error("Xarrows: " + errorMsg);
if (consoleMsg)
console.error("xarrow error: ", ...consoleMsg);
throw err;
};
const typeCheck = (arg, allowedTypes, name) => {
if (!allowedTypes.includes(typeOf(arg))) {
throwError(`'${name}' property error.`, [
`'${name}' property should be from type ${allowedTypes.join(" or ")}, not`,
typeOf(arg),
]);
}
};
const valueCheck = (value, allowedValues, name) => {
if (!allowedValues.includes(value)) {
throwError(`'${name}' property error.`, [
`${name} =`,
value,
` but ${name} prop should be '${allowedValues.join("' or '")}', not`,
"'" + value + "'",
]);
}
};
const checkRef = (ref, name) => {
typeCheck(ref, ["object", "string"], name);
if (typeOf(ref) === "object") {
if (!("current" in ref))
throwError(`'${name}' property error.`, [
`${name}=`,
ref,
`but '${name}' is not of type reference. maybe you set '${name}' property to other object and not to React reference?`,
]);
if (ref.current === null)
throwError(`'${name}' property error`, [
`Make sure the reference to ${name} anchor are provided correctly.
maybe you tried to render Xarrow before ${name} anchor?`,
]);
}
};
const checkAnchor = (anchor, name) => {
typeCheck(anchor, ["string", "array", "object"], name);
if (typeOf(anchor) === "string")
valueCheck(anchor, ["auto", "left", "right", "top", "bottom", "middle"], name);
else if (typeOf(anchor) === "array")
anchor.forEach((an) => valueCheck(an, ["auto", "left", "right", "top", "bottom", "middle"], name));
};
if (getElementByPropGiven(props.start) === getElementByPropGiven(props.end))
throwError(`'start' and 'end' props cannot point to the same element`, [
`'start' and 'end' props cannot point to the same element`,
]);
checkRef(props.start, "start");
checkRef(props.end, "end");
checkAnchor(props.startAnchor, "startAnchor");
checkAnchor(props.endAnchor, "endAnchor");
};
const triggerUpdate = (callback) => {
updateIfNeeded();
if (callback)
callback();
};
const initRegisterEvents = () => {
props.registerEvents.forEach((re) => {
var ref = getElementByPropGiven(re.ref);
ref.addEventListener(re.eventName, () => triggerUpdate(re.callback));
});
};
const cleanRegisterEvents = () => {
props.registerEvents.forEach((re) => {
var ref = getElementByPropGiven(re.ref);
ref.removeEventListener(re.eventName, () => triggerUpdate(re.callback));
});
};
const initAnchorsRefs = () => {
var start = getElementByPropGiven(props.start);
var end = getElementByPropGiven(props.end);
const start = utils_1.getElementByPropGiven(props.start);
const end = utils_1.getElementByPropGiven(props.end);
setAnchorsRefs({ start, end });
};
const initProps = () => {
testUserGivenProperties();
// initXarrowElemPos();
// testUserGivenProperties();
setPrevProps(props);
};
useEffect(() => {
// equivalent to componentDidMount
react_1.useEffect(() => {
// console.log("xarrow mounted");
initProps();
initRegisterEvents();
initAnchorsRefs();
return () => {
// console.log("xarrow unmounted");
cleanRegisterEvents();
};
}, []);
useEffect(() => {
// Happens only at mounting (or props changed) after anchorsRefs initialized
if (anchorsRefs.start) {
initParentsChildren();
}
}, [anchorsRefs]);
useEffect(() => {
// happens only at mounting after anchorsParents initialized
if (anchorsParents && props.monitorDOMchanges) {
monitorDOMchanges();
return () => {
//cleanUp it unmounting!
cleanMonitorDOMchanges();
};
}
}, [anchorsParents]);
// useEffect(() => {
// // triggers position update when prevPosState changed(can happen in any render)
// if (prevPosState) updatePosition(prevPosState);
// }, [prevPosState]);
useEffect(() => {
react_1.useLayoutEffect(() => {
// console.log("xarrow rendered!");
updateIfNeeded();
});
const [st, setSt] = useState({
const [st, setSt] = react_1.useState({
//initial state

@@ -300,3 +116,2 @@ cx0: 0,

});
let { color, lineColor, headColor, headSize, strokeWidth, dashness } = props;
headSize = Number(headSize);

@@ -309,4 +124,8 @@ strokeWidth = Number(strokeWidth);

if (typeof dashness === "object") {
dashStroke = dashness.strokeLen ? Number(dashness.strokeLen) : Number(strokeWidth) * 2;
dashNone = dashness.strokeLen ? Number(dashness.nonStrokeLen) : Number(strokeWidth);
dashStroke = dashness.strokeLen
? Number(dashness.strokeLen)
: Number(strokeWidth) * 2;
dashNone = dashness.strokeLen
? Number(dashness.nonStrokeLen)
: Number(strokeWidth);
animationSpeed = dashness.animation ? Number(dashness.animation) : null;

@@ -326,18 +145,21 @@ }

let labelStart = null, labelMiddle = null, labelEnd = null;
if (props.label) {
if (typeof props.label === "string" || "type" in props.label)
labelMiddle = props.label;
else if (["start", "middle", "end"].some((key) => key in props.label)) {
props.label = props.label;
({ start: labelStart, middle: labelMiddle, end: labelEnd } = props.label);
if (label) {
if (typeof label === "string" || "type" in label)
labelMiddle = label;
else if (["start", "middle", "end"].some((key) => key in label)) {
label = label;
({ start: labelStart, middle: labelMiddle, end: labelEnd } = label);
}
}
let { passProps: adPassProps = { SVGcanvas: {}, arrowHead: {}, arrowBody: {} }, extendSVGcanvas: extendSVGcanvas = 0, } = props.advanced;
let { passProps: adPassProps = { SVGcanvas: {}, arrowHead: {}, arrowBody: {} }, extendSVGcanvas: extendSVGcanvas = 0, } = advanced;
let { SVGcanvas = {}, arrowBody = {}, arrowHead = {} } = adPassProps;
const getSelfPos = () => {
let { x: xarrowElemX, y: xarrowElemY } = selfRef.current.getBoundingClientRect();
let { left: xarrowElemX, top: xarrowElemY, } = selfRef.current.getBoundingClientRect();
let xarrowStyle = getComputedStyle(selfRef.current);
let xarrowStyleLeft = Number(xarrowStyle.left.slice(0, -2));
let xarrowStyleTop = Number(xarrowStyle.top.slice(0, -2));
return { x: xarrowElemX - xarrowStyleLeft, y: xarrowElemY - xarrowStyleTop };
return {
x: xarrowElemX - xarrowStyleLeft,
y: xarrowElemY - xarrowStyleTop,
};
};

@@ -367,5 +189,3 @@ const getAnchorsPos = () => {

const updatePosition = (positions) => {
// Do NOT call this function directly.
// you should set position by 'setPrevPosState(posState)' and that will trigger
// this function in the useEffect hook.
// calculate new position and path and set state based on given properties
let { start: sPos } = positions;

@@ -375,3 +195,3 @@ let { end: ePos } = positions;

//////////////////////////////////////////////////////////////////////
// declare relevant functions for later
// declare relevant functions for later use for start and end refs(instead doing all twice)
const getAnchorsDefaultOffsets = (width, height) => {

@@ -390,9 +210,14 @@ return {

let anchorChoice = Array.isArray(anchor) ? anchor : [anchor];
if (anchorChoice.length == 0)
anchorChoice = ["auto"];
//now map each item in the list to relevant object
let anchorChoiceMapped = anchorChoice.map((anchorChoice) => {
if (typeOf(anchorChoice) === "string") {
if (utils_1.typeOf(anchorChoice) === "string") {
anchorChoice = anchorChoice;
return { position: anchorChoice, offset: { rightness: 0, bottomness: 0 } };
return {
position: anchorChoice,
offset: { rightness: 0, bottomness: 0 },
};
}
else if (typeOf(anchorChoice) === "object") {
else if (utils_1.typeOf(anchorChoice) === "object") {
if (!anchorChoice.offset)

@@ -428,3 +253,3 @@ anchorChoice.offset = { rightness: 0, bottomness: 0 };

// now prepare this list of anchors to object expected by the `getShortestLine` function
let points = anchorPossibilities.map((pos) => ({
return anchorPossibilities.map((pos) => ({
x: anchorPos.x + pos.offset.rightness,

@@ -434,8 +259,7 @@ y: anchorPos.y + pos.offset.bottomness,

}));
return points;
};
//end declare functions
/////////////////////////////////////////////////////////////////////////////////////////
let startPointsObj = prepareAnchorLines(props.startAnchor, sPos);
let endPointsObj = prepareAnchorLines(props.endAnchor, ePos);
let startPointsObj = prepareAnchorLines(startAnchor, sPos);
let endPointsObj = prepareAnchorLines(endAnchor, ePos);
const dist = (p1, p2) => {

@@ -461,4 +285,4 @@ //length of line

let { startPointObj, endPointObj } = getShortestLine(startPointsObj, endPointsObj);
let startAnchor = startPointObj.anchorPosition, endAnchor = endPointObj.anchorPosition;
let startPoint = _.pick(startPointObj, ["x", "y"]), endPoint = _.pick(endPointObj, ["x", "y"]);
let startAnchorPosition = startPointObj.anchorPosition, endAnchorPosition = endPointObj.anchorPosition;
let startPoint = lodash_pick_1.default(startPointObj, ["x", "y"]), endPoint = lodash_pick_1.default(endPointObj, ["x", "y"]);
let xarrowElemPos = getSelfPos();

@@ -474,4 +298,3 @@ let cx0 = Math.min(startPoint.x, endPoint.x) - xarrowElemPos.x;

let headOffset = ((headSize * 3) / 4) * strokeWidth;
let cu = Number(props.curveness);
let { path } = props;
let cu = Number(curveness);
if (path === "straight") {

@@ -491,3 +314,3 @@ cu = 0;

// arrow point to point calculations
let x1 = 0, x2 = absDx + 0, y1 = 0, y2 = absDy + 0;
let x1 = 0, x2 = absDx, y1 = 0, y2 = absDy;
if (dx < 0)

@@ -508,20 +331,24 @@ [x1, x2] = [x2, x1];

headAngel = (Math.PI - headAngel * xSign) * xSign;
xHeadOffset = ((Math.cos(headAngel) * headOffset) / 3 - (Math.sin(headAngel) * (headSize * strokeWidth)) / 2) * 1;
yHeadOffset = ((Math.cos(headAngel) * (headSize * strokeWidth)) / 2 + (Math.sin(headAngel) * headOffset) / 3) * 1;
xHeadOffset =
(Math.cos(headAngel) * headOffset) / 3 -
(Math.sin(headAngel) * (headSize * strokeWidth)) / 2;
yHeadOffset =
(Math.cos(headAngel) * (headSize * strokeWidth)) / 2 +
(Math.sin(headAngel) * headOffset) / 3;
headOrient = (headAngel * 180) / Math.PI;
}
else {
if (endAnchor === "middle") {
if (endAnchorPosition === "middle") {
if (absDx > absDy) {
endAnchor = xSign ? "left" : "right";
endAnchorPosition = xSign ? "left" : "right";
}
else {
endAnchor = ySign ? "top" : "bottom";
endAnchorPosition = ySign ? "top" : "bottom";
}
}
if (["left", "right"].includes(endAnchor)) {
if (["left", "right"].includes(endAnchorPosition)) {
x2 -= headOffset * xSign;
xHeadOffset = (headOffset * xSign) / 3;
yHeadOffset = (headSize * strokeWidth * xSign) / 2;
if (endAnchor === "left") {
if (endAnchorPosition === "left") {
headOrient = 0;

@@ -537,7 +364,7 @@ if (xSign < 0)

}
else if (["top", "bottom"].includes(endAnchor)) {
else if (["top", "bottom"].includes(endAnchorPosition)) {
yHeadOffset = (headOffset * ySign) / 3;
xHeadOffset = (headSize * strokeWidth * -ySign) / 2;
y2 -= headOffset * ySign;
if (endAnchor === "top") {
if (endAnchorPosition === "top") {
headOrient = 270;

@@ -605,13 +432,13 @@ if (ySign > 0)

let selectedCurviness = "";
if (["left", "right"].includes(startAnchor))
if (["left", "right"].includes(startAnchorPosition))
selectedCurviness += "h";
else if (["bottom", "top"].includes(startAnchor))
else if (["bottom", "top"].includes(startAnchorPosition))
selectedCurviness += "v";
else if (startAnchor === "middle")
else if (startAnchorPosition === "middle")
selectedCurviness += "m";
if (["left", "right"].includes(endAnchor))
if (["left", "right"].includes(endAnchorPosition))
selectedCurviness += "h";
else if (["bottom", "top"].includes(endAnchor))
else if (["bottom", "top"].includes(endAnchorPosition))
selectedCurviness += "v";
else if (endAnchor === "middle")
else if (endAnchorPosition === "middle")
selectedCurviness += "m";

@@ -636,3 +463,4 @@ if (absDx > absDy)

6 * cpx2 +
Math.sqrt(Math.pow((6 * x1 - 12 * cpx1 + 6 * cpx2), 2) - 4 * (3 * cpx1 - 3 * x1) * (-3 * x1 + 9 * cpx1 - 9 * cpx2 + 3 * x2))) /
Math.sqrt(Math.pow((6 * x1 - 12 * cpx1 + 6 * cpx2), 2) -
4 * (3 * cpx1 - 3 * x1) * (-3 * x1 + 9 * cpx1 - 9 * cpx2 + 3 * x2))) /
(2 * (-3 * x1 + 9 * cpx1 - 9 * cpx2 + 3 * x2));

@@ -642,3 +470,4 @@ let txSol2 = (-6 * x1 +

6 * cpx2 -
Math.sqrt(Math.pow((6 * x1 - 12 * cpx1 + 6 * cpx2), 2) - 4 * (3 * cpx1 - 3 * x1) * (-3 * x1 + 9 * cpx1 - 9 * cpx2 + 3 * x2))) /
Math.sqrt(Math.pow((6 * x1 - 12 * cpx1 + 6 * cpx2), 2) -
4 * (3 * cpx1 - 3 * x1) * (-3 * x1 + 9 * cpx1 - 9 * cpx2 + 3 * x2))) /
(2 * (-3 * x1 + 9 * cpx1 - 9 * cpx2 + 3 * x2));

@@ -648,3 +477,4 @@ let tySol1 = (-6 * y1 +

6 * cpy2 +
Math.sqrt(Math.pow((6 * y1 - 12 * cpy1 + 6 * cpy2), 2) - 4 * (3 * cpy1 - 3 * y1) * (-3 * y1 + 9 * cpy1 - 9 * cpy2 + 3 * y2))) /
Math.sqrt(Math.pow((6 * y1 - 12 * cpy1 + 6 * cpy2), 2) -
4 * (3 * cpy1 - 3 * y1) * (-3 * y1 + 9 * cpy1 - 9 * cpy2 + 3 * y2))) /
(2 * (-3 * y1 + 9 * cpy1 - 9 * cpy2 + 3 * y2));

@@ -654,6 +484,13 @@ let tySol2 = (-6 * y1 +

6 * cpy2 -
Math.sqrt(Math.pow((6 * y1 - 12 * cpy1 + 6 * cpy2), 2) - 4 * (3 * cpy1 - 3 * y1) * (-3 * y1 + 9 * cpy1 - 9 * cpy2 + 3 * y2))) /
Math.sqrt(Math.pow((6 * y1 - 12 * cpy1 + 6 * cpy2), 2) -
4 * (3 * cpy1 - 3 * y1) * (-3 * y1 + 9 * cpy1 - 9 * cpy2 + 3 * y2))) /
(2 * (-3 * y1 + 9 * cpy1 - 9 * cpy2 + 3 * y2));
const bzx = (t) => Math.pow((1 - t), 3) * x1 + 3 * Math.pow((1 - t), 2) * t * cpx1 + 3 * (1 - t) * Math.pow(t, 2) * cpx2 + Math.pow(t, 3) * x2;
const bzy = (t) => Math.pow((1 - t), 3) * y1 + 3 * Math.pow((1 - t), 2) * t * cpy1 + 3 * (1 - t) * Math.pow(t, 2) * cpy2 + Math.pow(t, 3) * y2;
const bzx = (t) => Math.pow((1 - t), 3) * x1 +
3 * Math.pow((1 - t), 2) * t * cpx1 +
3 * (1 - t) * Math.pow(t, 2) * cpx2 +
Math.pow(t, 3) * x2;
const bzy = (t) => Math.pow((1 - t), 3) * y1 +
3 * Math.pow((1 - t), 2) * t * cpy1 +
3 * (1 - t) * Math.pow(t, 2) * cpy2 +
Math.pow(t, 3) * y2;
////////////////////////////////////

@@ -722,3 +559,2 @@ // canvas smart size adjustments

let yOffsetHead = st.y2 - st.arrowHeadOffset.y;
let { path = "smooth" } = props;
let arrowPath = `M ${st.x1} ${st.y1} C ${st.cpx1} ${st.cpy1}, ${st.cpx2} ${st.cpy2}, ${st.x2} ${st.y2}`;

@@ -729,5 +565,4 @@ if (path === "straight")

arrowPath = `M ${st.x1} ${st.y1} L ${st.cpx1} ${st.cpy1} L ${st.cpx2} ${st.cpy2} L ${st.x2} ${st.y2}`;
// console.log("test");
return (React.createElement("div", { style: { position: "absolute" } },
React.createElement("svg", Object.assign({ ref: selfRef, width: st.cw, height: st.ch, style: {
return (react_1.default.createElement("div", { style: { position: "absolute" } },
react_1.default.createElement("svg", Object.assign({ ref: selfRef, width: st.cw, height: st.ch, style: {
// border: "2px yellow dashed",

@@ -739,9 +574,9 @@ position: "absolute",

}, overflow: "auto" }, SVGcanvas),
React.createElement("path", Object.assign({ d: arrowPath, stroke: lineColor, strokeDasharray: `${dashStroke} ${dashNone}`, strokeWidth: strokeWidth, fill: "transparent",
react_1.default.createElement("path", Object.assign({ d: arrowPath, stroke: lineColor, strokeDasharray: `${dashStroke} ${dashNone}`, strokeWidth: strokeWidth, fill: "transparent",
// markerEnd={`url(#${arrowHeadId})`}
pointerEvents: "visibleStroke" }, props.passProps, arrowBody), animationSpeed ? (React.createElement("animate", { attributeName: "stroke-dashoffset", values: `${dashoffset * animationDirection};0`, dur: `${1 / animationSpeed}s`, repeatCount: "indefinite" })) : null),
React.createElement("path", Object.assign({ d: `M 0 0 L ${fHeadSize} ${fHeadSize / 2} L 0 ${fHeadSize} L ${fHeadSize / 4} ${fHeadSize / 2} z`, fill: headColor,
pointerEvents: "visibleStroke" }, passProps, arrowBody), animationSpeed ? (react_1.default.createElement("animate", { attributeName: "stroke-dashoffset", values: `${dashoffset * animationDirection};0`, dur: `${1 / animationSpeed}s`, repeatCount: "indefinite" })) : null),
react_1.default.createElement("path", Object.assign({ d: `M 0 0 L ${fHeadSize} ${fHeadSize / 2} L 0 ${fHeadSize} L ${fHeadSize / 4} ${fHeadSize / 2} z`, fill: headColor,
// pointerEvents="all"
transform: `translate(${xOffsetHead},${yOffsetHead}) rotate(${st.headOrient})` }, props.passProps, arrowHead))),
labelStart ? (React.createElement("div", { style: {
transform: `translate(${xOffsetHead},${yOffsetHead}) rotate(${st.headOrient})` }, passProps, arrowHead))),
labelStart ? (react_1.default.createElement("div", { style: {
transform: st.dx < 0 ? "translate(-100% , -50%)" : "translate(-0% , -50%)",

@@ -753,3 +588,3 @@ width: "max-content",

} }, labelStart)) : null,
labelMiddle ? (React.createElement("div", { style: {
labelMiddle ? (react_1.default.createElement("div", { style: {
display: "table",

@@ -762,3 +597,3 @@ width: "max-content",

} }, labelMiddle)) : null,
labelEnd ? (React.createElement("div", { style: {
labelEnd ? (react_1.default.createElement("div", { style: {
transform: st.dx > 0 ? "translate(-100% , -50%)" : "translate(-0% , -50%)",

@@ -771,2 +606,39 @@ width: "max-content",

};
const pAnchorPositionType = prop_types_1.default.oneOf([
"middle",
"left",
"right",
"top",
"bottom",
"auto",
]);
const pAnchorCustomPositionType = prop_types_1.default.shape({
position: pAnchorPositionType.isRequired,
offset: prop_types_1.default.shape({
rightness: prop_types_1.default.number,
bottomness: prop_types_1.default.number,
}),
});
const pAnchorType = prop_types_1.default.oneOfType([
pAnchorPositionType,
pAnchorCustomPositionType,
prop_types_1.default.arrayOf(prop_types_1.default.oneOfType([pAnchorPositionType, pAnchorCustomPositionType])),
]);
const pRefType = prop_types_1.default.oneOfType([prop_types_1.default.string, prop_types_1.default.object]);
Xarrow.propTypes = {
start: pRefType.isRequired,
end: pRefType.isRequired,
startAnchor: pAnchorType,
endAnchor: pAnchorType,
label: prop_types_1.default.oneOfType([prop_types_1.default.elementType, prop_types_1.default.object]),
color: prop_types_1.default.string,
lineColor: prop_types_1.default.string,
headColor: prop_types_1.default.string,
strokeWidth: prop_types_1.default.number,
headSize: prop_types_1.default.number,
path: prop_types_1.default.oneOf(["smooth", "grid", "straight"]),
curveness: prop_types_1.default.number,
dashness: prop_types_1.default.oneOfType([prop_types_1.default.bool, prop_types_1.default.object]),
passProps: prop_types_1.default.object,
};
Xarrow.defaultProps = {

@@ -784,9 +656,9 @@ startAnchor: "auto",

dashness: false,
consoleWarning: false,
passProps: {},
advanced: { extendSVGcanvas: 0, passProps: { arrowBody: {}, arrowHead: {}, SVGcanvas: {} } },
monitorDOMchanges: true,
registerEvents: [],
advanced: {
extendSVGcanvas: 0,
passProps: { arrowBody: {}, arrowHead: {}, SVGcanvas: {} },
},
};
export default Xarrow;
exports.default = Xarrow;
//# sourceMappingURL=index.js.map
{
"name": "react-xarrows",
"version": "1.4.4",
"version": "1.5.0",
"author": "Eliav Louski",

@@ -30,3 +30,5 @@ "description": "Draw arrows (or lines) between components in React!",

"dependencies": {
"lodash": "^4.17.15"
"lodash.isequal": "^4.5.0",
"lodash.pick": "^4.4.0",
"prop-types": "^15.7.2"
},

@@ -38,2 +40,3 @@ "peerDependencies": {

"@types/react": "^16.9.19",
"react": "^16.12.0",
"typescript": "^3.7.5"

@@ -40,0 +43,0 @@ },

@@ -92,3 +92,2 @@ # react-xarrows

dashness?: boolean | { strokeLen?: number; nonStrokeLen?: number; animation?: boolean | number };
consoleWarning?: boolean;
passProps?: React.SVGProps<SVGPathElement>;

@@ -103,4 +102,2 @@ advanced?: {

};
monitorDOMchanges?: boolean;
registerEvents?: registerEventsType[];
};

@@ -144,5 +141,5 @@

- `endAnchor="middle"` will choose anchor or the end of the line to in the middle of the element
- `endAnchor="middle"` will set the anchor of the end of the line to the middle of the end element.
- `endAnchor= { position: "auto", offset: { rightness: 20 } }` will choose automatic anchoring for end anchor but will offset it 20 pixels to the right after normal positioning.
- `endAnchor= ["right", {position: "left", offset: {bottomness: -10}}]` only right and left anchors are allowed for endAnchor, and the left side will be offset 10 pixels up
#### label

@@ -214,6 +211,2 @@

#### consoleWarning
we provide some nice warnings (and errors) whenever we detect issues. see 'Example3' at the examples codesandbox.
#### advanced

@@ -236,13 +229,2 @@

#### monitorDOMchanges
A boolean. set this property to true to add relevant eventListeners to the DOM so the xarrow component will update anchors position whenever needed(scroll and resize and so on). (NOTE - maybe will removed in future updates )
examples:
- `monitorDOMchanges={false}` will disable any DOM monitoring.
#### registerEvents
you can register the xarrow to DOM event as you please. each time a event that his registered will fire the xarrow component will update his position and will call `callback` (if provided). (NOTE - planned to be removed)
### default props

@@ -265,15 +247,8 @@

dashness: false,
consoleWarning: false,
passProps: {},
advanced: { extendSVGcanvas: 0, passProps: { arrowBody: {}, arrowHead: {}, SVGcanvas: {} } },
monitorDOMchanges: true,
registerEvents: [],
};
};
```
## Versions
All version notes moved to [releases](https://github.com/Eliav2/react-xarrows/releases).
1.4.0 - changed `label` property API and added `path` property.
1.4.1-2 - minor bug fixes, performance improvement.
See CHANGELOG.md in this repo.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc