Skip to content

Commit

Permalink
Merge pull request #179 from pierpo/fix/arrow-markers-not-drawn
Browse files Browse the repository at this point in the history
fix: fix arrow markers not drawn sometimes
  • Loading branch information
pierpo authored Aug 15, 2022
2 parents 56618d9 + f8198c6 commit a8db7de
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 26 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ This will allow you to have more control on when you want to re-draw the arrows.
<!-- prettier-ignore -->
| Name | Type | Description |
| - | - | - |
| `id` | `string` | The id that will identify the Archer Element. Should only contain alphanumeric characters and standard characters that you can find in HTML ids.
| `id` | `string` | The id that will identify the Archer Element.
| `children` | `React.Node \| (ArcherContext) => React.Node` | :warning: Must be a **single** element or a function of the internal context. If you are passing a custom component, it should be wrapped in a div or you should forward the reference (see [this](https://github.com/pierpo/react-archer/releases/tag/v2.0.0))
| `relations` | `Relation[]` |

Expand Down
4 changes: 2 additions & 2 deletions example/SecondExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const SecondExample = () => {
</div>
<ArcherContainer strokeColor="red">
<div style={rootStyle}>
<ArcherElement id="root">
<ArcherElement id="root with spaces et accents héhéhéhé">
<div style={boxStyle}>Root</div>
</ArcherElement>
</div>
Expand All @@ -58,7 +58,7 @@ const SecondExample = () => {
id={`element${i}`}
relations={[
{
targetId: 'root',
targetId: 'root with spaces et accents héhéhéhé',
targetAnchor: 'bottom',
sourceAnchor: 'top',
label: (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ exports[`ArcherContainer rendering an svg with the marker element used to draw a
<g>
<path
d="M0,0 C10,0 10,0 20,0"
marker-end="url(about:blank#arrow00001elem-leftelem-right)"
marker-end="url(#arrow00001elem-leftelem-right)"
style="fill: none; stroke: #f00; stroke-width: 2;"
/>
</g>
Expand Down Expand Up @@ -117,8 +117,8 @@ exports[`ArcherContainer rendering an svg with the marker element used to draw a
<g>
<path
d="M-20,0 C0,0 0,0 20,0"
marker-end="url(about:blank#arrow00001elem-leftelem-right)"
marker-start="url(about:blank#arrow00001elem-leftelem-right)"
marker-end="url(#arrow00001elem-leftelem-right)"
marker-start="url(#arrow00001elem-leftelem-right)"
style="fill: none; stroke: #f00; stroke-width: 2;"
/>
</g>
Expand Down Expand Up @@ -166,7 +166,7 @@ exports[`ArcherContainer rendering an svg with the marker element used to draw a
<g>
<path
d="M-20,0 C-10,0 -10,0 0,0"
marker-start="url(about:blank#arrow00001elem-leftelem-right)"
marker-start="url(#arrow00001elem-leftelem-right)"
style="fill: none; stroke: #f00; stroke-width: 2;"
/>
</g>
Expand Down Expand Up @@ -218,7 +218,7 @@ exports[`ArcherContainer rendering an svg with the marker element used to draw a
<g>
<path
d="M0,0 C11,0 11,0 22,0"
marker-end="url(about:blank#arrow00001elem-leftelem-right)"
marker-end="url(#arrow00001elem-leftelem-right)"
style="fill: none; stroke: #f00; stroke-width: 2;"
/>
</g>
Expand Down Expand Up @@ -266,7 +266,7 @@ exports[`ArcherContainer rendering an svg with the marker element used to draw a
<g>
<path
d="M0,0 C-10,0 -10,0 -20,0"
marker-end="url(about:blank#arrow00001elem-rightelem-left)"
marker-end="url(#arrow00001elem-rightelem-left)"
style="fill: none; stroke: #f00; stroke-width: 2;"
/>
</g>
Expand Down Expand Up @@ -314,7 +314,7 @@ exports[`ArcherContainer rendering an svg with the marker element used to draw a
<g>
<path
d="M-20,0 C-10,0 -10,0 0,0"
marker-start="url(about:blank#arrow00001elem-leftelem-right)"
marker-start="url(#arrow00001elem-leftelem-right)"
style="fill: none; stroke: #f00; stroke-width: 2;"
/>
<foreignobject
Expand Down
5 changes: 3 additions & 2 deletions src/ArcherElement/ArcherElement.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ArcherContainerContextType } from '../ArcherContainer/ArcherContainer.context';
import { RelationType, SourceToTargetType } from '../types';
import { encodeId } from '../utils/encodeId';

export function assertContextExists(
context: ArcherContainerContextType | null,
Expand All @@ -18,11 +19,11 @@ export const generateSourceToTarget = (
return relations.map(
({ targetId, sourceAnchor, targetAnchor, label, style, order = 0 }: RelationType) => ({
source: {
id,
id: encodeId(id),
anchor: sourceAnchor,
},
target: {
id: targetId,
id: encodeId(targetId),
anchor: targetAnchor,
},
label,
Expand Down
16 changes: 9 additions & 7 deletions src/ArcherElement/ArcherElement.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,49 @@
import React, { useContext, useEffect } from 'react';
import React, { useContext, useEffect, useMemo } from 'react';
import { ArcherContainerContext } from '../ArcherContainer/ArcherContainer.context';
import { RelationType } from '../types';
import { encodeId } from '../utils/encodeId';
import { useDeepCompareEffect } from '../utils/useDeepCompareEffect';
import { generateSourceToTarget, assertContextExists } from './ArcherElement.helpers';

type ArcherElementProps = {
/**
* The id that will identify the Archer Element. Should only contain alphanumeric characters and standard characters that you can find in HTML ids.
* The id that will identify the Archer Element.
*/
id: string;
relations?: Array<RelationType>;
children: React.ReactElement<React.ComponentProps<any>, any>;
};

const ArcherElement = ({ id, relations = [], children }: ArcherElementProps) => {
const encodedId = useMemo(() => encodeId(id), [id]);
const context = useContext(ArcherContainerContext);

const registerTransitions = (newRelations: Array<RelationType>) => {
const newSourceToTarget = generateSourceToTarget(id, newRelations);
const newSourceToTarget = generateSourceToTarget(encodedId, newRelations);

assertContextExists(context);

context.registerTransitions(id, newSourceToTarget);
context.registerTransitions(encodedId, newSourceToTarget);
};

const unregisterTransitions = () => {
assertContextExists(context);

context.unregisterTransitions(id);
context.unregisterTransitions(encodedId);
};

const onRefUpdate = (ref: HTMLElement | null | undefined) => {
if (!ref) return;

assertContextExists(context);

context.registerChild(id, ref);
context.registerChild(encodedId, ref);
};

const unregisterChild = () => {
assertContextExists(context);

context.unregisterChild(id);
context.unregisterChild(encodedId);
};

useEffect(() => {
Expand Down
6 changes: 3 additions & 3 deletions src/SvgArrow/SvgArrow.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ describe('SvgArrow', () => {
const path = getBySelector('path');
const attributes = path?.attributes;
expectAttribute(attributes, 'd', 'M10,10 C10,10 30,10 30,10');
expectAttribute(attributes, 'marker-end', 'url(about:blank#arrow123123)');
expectAttribute(attributes, 'marker-end', 'url(#arrow123123)');
expectAttribute(attributes, 'style', 'fill: none; stroke: blue; stroke-width: 2;');
});

Expand All @@ -255,7 +255,7 @@ describe('SvgArrow', () => {
const path = getBySelector('path');
const attributes = path?.attributes;
expectAttribute(attributes, 'd', 'M10,10 C10,10 30,10 30,10');
expectAttribute(attributes, 'marker-end', 'url(about:blank#arrow123123)');
expectAttribute(attributes, 'marker-end', 'url(#arrow123123)');
expectAttribute(attributes, 'style', 'fill: none; stroke: blue; stroke-width: 2;');
});

Expand All @@ -264,7 +264,7 @@ describe('SvgArrow', () => {
const path = getBySelector('path');
const attributes = path?.attributes;
expectAttribute(attributes, 'd', 'M10,10 15.85786437626905,15.857864376269049');
expectAttribute(attributes, 'marker-end', 'url(about:blank#arrow123123)');
expectAttribute(attributes, 'marker-end', 'url(#arrow123123)');
expectAttribute(attributes, 'style', 'fill: none; stroke: blue; stroke-width: 2;');
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/SvgArrow/SvgArrow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ const SvgArrow = ({
yEnd,
);

const markerUrl = `url(${location.href.split('#')[0]}#${arrowMarkerId})`;
const markerUrl = `url(#${arrowMarkerId})`;

return (
<g>
Expand Down
6 changes: 3 additions & 3 deletions src/__tests__/__snapshots__/Archer-integration.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ exports[`Archer Integration Uses a functional child API to work with third party
<g>
<path
d="M0,0 C0,-10 0,-10 0,-20"
marker-end="url(about:blank#arrow00001rootelement2)"
marker-end="url(#arrow00001rootelement2)"
style="fill: none; stroke: red; stroke-width: 2; stroke-dasharray: 5,5;"
/>
</g>
<g>
<path
d="M0,0 C-1.5,0 -1.5,0 -3,0"
marker-end="url(about:blank#arrow00001element2element3)"
marker-end="url(#arrow00001element2element3)"
style="fill: none; stroke: blue; stroke-width: 1;"
/>
<foreignobject
Expand All @@ -100,7 +100,7 @@ exports[`Archer Integration Uses a functional child API to work with third party
<g>
<path
d="M0,0 C2,0 2,0 4,0"
marker-end="url(about:blank#arrow00001element4root)"
marker-end="url(#arrow00001element4root)"
style="fill: none; stroke: red; stroke-width: 2;"
/>
<foreignobject
Expand Down
1 change: 1 addition & 0 deletions src/utils/encodeId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const encodeId = (id: string): string => encodeURI(id).replace(/%/g, '_');

0 comments on commit a8db7de

Please sign in to comment.