From 0042a3996b6ee3d78b45eac67498c9e7cf7325d2 Mon Sep 17 00:00:00 2001 From: Lavender Date: Tue, 15 Apr 2025 16:21:01 +1000 Subject: [PATCH 1/2] feature/MIG-6604 Modify edges to make way for markers --- src/components/canvas/use-canvas.test.tsx | 4 +-- src/components/edge/floating-edge.test.tsx | 2 +- src/components/edge/floating-edge.tsx | 14 ++++++-- .../edge/self-referencing-edge.test.tsx | 2 +- src/components/edge/self-referencing-edge.tsx | 22 ++++++++---- src/mocks/datasets/edges.ts | 4 +-- src/utilities/constants.ts | 1 + src/utilities/get-edge-params.test.ts | 4 +-- src/utilities/get-edge-params.ts | 36 ++++++++++++++++--- tsconfig.json | 3 +- 10 files changed, 69 insertions(+), 23 deletions(-) diff --git a/src/components/canvas/use-canvas.test.tsx b/src/components/canvas/use-canvas.test.tsx index e3e3ff7..d2d0803 100644 --- a/src/components/canvas/use-canvas.test.tsx +++ b/src/components/canvas/use-canvas.test.tsx @@ -58,7 +58,7 @@ describe('use-canvas', () => { { id: 'employees-to-orders', markerEnd: 'one', - markerStart: 'one', + markerStart: 'many', source: 'employees', target: 'orders', type: 'floatingEdge', @@ -73,7 +73,7 @@ describe('use-canvas', () => { source: 'employees', target: 'employees', markerEnd: 'one', - markerStart: 'oneOrMany', + markerStart: 'many', type: 'selfReferencingEdge', }, ]); diff --git a/src/components/edge/floating-edge.test.tsx b/src/components/edge/floating-edge.test.tsx index b68fd46..c590061 100644 --- a/src/components/edge/floating-edge.test.tsx +++ b/src/components/edge/floating-edge.test.tsx @@ -46,7 +46,7 @@ describe('floating-edge', () => { expect(path).toHaveAttribute('id', 'orders-to-employees'); expect(path).toHaveAttribute( 'd', - 'M240 136L240 156L 240,213Q 240,218 245,218L 381,218Q 386,218 386,223L386 280L386 300', + 'M240 143.5L240 163.5L 240,213Q 240,218 245,218L 381,218Q 386,218 386,223L386 272.5L386 292.5', ); }); diff --git a/src/components/edge/floating-edge.tsx b/src/components/edge/floating-edge.tsx index 596eec7..340c5a6 100644 --- a/src/components/edge/floating-edge.tsx +++ b/src/components/edge/floating-edge.tsx @@ -1,10 +1,16 @@ -import { EdgeProps, getSmoothStepPath, useNodes } from '@xyflow/react'; +import { EdgeProps, getSmoothStepPath, useNodes, BaseEdge } from '@xyflow/react'; import { useMemo } from 'react'; +import styled from '@emotion/styled'; +import { palette } from '@leafygreen-ui/palette'; import { getEdgeParams } from '@/utilities/get-edge-params'; import { InternalNode } from '@/types/internal'; -export const FloatingEdge = ({ id, source, target }: EdgeProps) => { +const Edge = styled(BaseEdge)` + stroke: ${palette.gray.base}; +`; + +export const FloatingEdge = ({ id, source, target, markerEnd, markerStart }: EdgeProps) => { const nodes = useNodes(); const { sourceNode, targetNode } = useMemo(() => { @@ -26,5 +32,7 @@ export const FloatingEdge = ({ id, source, target }: EdgeProps) => { targetY: ty, }); - return ; + return ( + + ); }; diff --git a/src/components/edge/self-referencing-edge.test.tsx b/src/components/edge/self-referencing-edge.test.tsx index 541adbf..a87d10c 100644 --- a/src/components/edge/self-referencing-edge.test.tsx +++ b/src/components/edge/self-referencing-edge.test.tsx @@ -42,7 +42,7 @@ describe('self-referencing-edge', () => { renderComponent(); const path = screen.getByTestId('self-referencing-edge-employees-to-employees'); expect(path).toHaveAttribute('id', 'employees-to-employees'); - expect(path).toHaveAttribute('d', 'M422,300L422,270L584,270L584,336L544,336'); + expect(path).toHaveAttribute('d', 'M422,292.5L422,262.5L584,262.5L584,328.5L551.5,328.5'); }); it('Should not render edge if source does not exist', () => { diff --git a/src/components/edge/self-referencing-edge.tsx b/src/components/edge/self-referencing-edge.tsx index ea0ab7d..5ef868d 100644 --- a/src/components/edge/self-referencing-edge.tsx +++ b/src/components/edge/self-referencing-edge.tsx @@ -1,10 +1,17 @@ -import { EdgeProps, useNodes } from '@xyflow/react'; +import { BaseEdge, EdgeProps, useNodes } from '@xyflow/react'; import { useMemo } from 'react'; import { path } from 'd3-path'; +import styled from '@emotion/styled'; +import { palette } from '@leafygreen-ui/palette'; import { InternalNode } from '@/types/internal'; +import { DEFAULT_MARKER_SIZE } from '@/utilities/constants'; -export const SelfReferencingEdge = ({ id, source }: EdgeProps) => { +const Edge = styled(BaseEdge)` + stroke: ${palette.gray.base}; +`; + +export const SelfReferencingEdge = ({ id, source, markerEnd, markerStart }: EdgeProps) => { const nodes = useNodes(); const { sourceNode } = useMemo(() => { @@ -24,7 +31,7 @@ export const SelfReferencingEdge = ({ id, source }: EdgeProps) => { const rightHeight = centerY + leftHeight; const startX = sourceNode.position.x + centerX; - const startY = sourceNode.position.y; + const startY = sourceNode.position.y - DEFAULT_MARKER_SIZE / 2; const topLeftCornerX = startX; const topLeftCornerY = startY - leftHeight; @@ -35,7 +42,7 @@ export const SelfReferencingEdge = ({ id, source }: EdgeProps) => { const bottomRightCornerX = topRightCornerX; const bottomRightCornerY = topRightCornerY + rightHeight; - const bottomLeftCornerX = topRightCornerX - width + centerX; + const bottomLeftCornerX = topRightCornerX - width + centerX + DEFAULT_MARKER_SIZE / 2; const bottomLeftCornerY = bottomRightCornerY; const context = path(); @@ -46,10 +53,11 @@ export const SelfReferencingEdge = ({ id, source }: EdgeProps) => { context.lineTo(bottomLeftCornerX, bottomLeftCornerY); return ( - ); diff --git a/src/mocks/datasets/edges.ts b/src/mocks/datasets/edges.ts index 2382d7c..49898ef 100644 --- a/src/mocks/datasets/edges.ts +++ b/src/mocks/datasets/edges.ts @@ -5,7 +5,7 @@ export const ORDERS_TO_EMPLOYEES_EDGE: Edge = { source: 'employees', target: 'orders', markerEnd: 'one', - markerStart: 'one', + markerStart: 'many', }; export const EMPLOYEES_TO_EMPLOYEES_EDGE: Edge = { @@ -13,5 +13,5 @@ export const EMPLOYEES_TO_EMPLOYEES_EDGE: Edge = { source: 'employees', target: 'employees', markerEnd: 'one', - markerStart: 'oneOrMany', + markerStart: 'many', }; diff --git a/src/utilities/constants.ts b/src/utilities/constants.ts index 28d1935..221b501 100644 --- a/src/utilities/constants.ts +++ b/src/utilities/constants.ts @@ -7,3 +7,4 @@ export const DEFAULT_NODE_HEADER_HEIGHT = 28; export const DEFAULT_FIELD_HEIGHT = 18; export const DEFAULT_FIELD_PADDING = 8; export const DEFAULT_DEPTH_SPACING = 8; +export const DEFAULT_MARKER_SIZE = 15; diff --git a/src/utilities/get-edge-params.test.ts b/src/utilities/get-edge-params.test.ts index 97e2b7a..1d847a6 100644 --- a/src/utilities/get-edge-params.test.ts +++ b/src/utilities/get-edge-params.test.ts @@ -10,10 +10,10 @@ describe('get-edge-params', () => { expect(result).toEqual({ sourcePos: 'bottom', sx: 240, - sy: 136, + sy: 143.5, targetPos: 'top', tx: 386, - ty: 300, + ty: 292.5, }); }); }); diff --git a/src/utilities/get-edge-params.ts b/src/utilities/get-edge-params.ts index 1e2f1b9..ed11860 100644 --- a/src/utilities/get-edge-params.ts +++ b/src/utilities/get-edge-params.ts @@ -1,6 +1,7 @@ import { Position, XYPosition } from '@xyflow/react'; import { InternalNode } from '@/types/internal'; +import { DEFAULT_MARKER_SIZE } from '@/utilities/constants'; /** * Returns the coordinates where a line connecting the centers of the source and target nodes intersects @@ -66,6 +67,30 @@ const getEdgePosition = (node: InternalNode, intersectionPoint: XYPosition) => { return Position.Top; }; +/** + * Offsets the edge position based on the size of the marker + * + * @param position Direction of the edge + * @param x Co-ordinates of the edge + * @param y Co-ordinates of the edge + * @param offset Amount of pixels to offset by + */ +const offsetPosition = (position: Position, { x, y }: { x: number; y: number }) => { + const offset = DEFAULT_MARKER_SIZE / 2; + switch (position) { + case Position.Left: + return { x: x - offset, y }; + case Position.Top: + return { x, y: y - offset }; + case Position.Right: + return { x: x + offset, y }; + case Position.Bottom: + return { x, y: y + offset }; + default: + return { x, y }; + } +}; + /** * Returns the coordinates where a line connecting the centers of the source and target nodes intersects * the edges of those nodes. This implementation is copied from: @@ -81,11 +106,14 @@ export const getEdgeParams = (source: InternalNode, target: InternalNode) => { const sourcePos = getEdgePosition(source, sourceIntersectionPoint); const targetPos = getEdgePosition(target, targetIntersectionPoint); + const sourcePosition = offsetPosition(sourcePos, sourceIntersectionPoint); + const targetPosition = offsetPosition(targetPos, targetIntersectionPoint); + return { - sx: sourceIntersectionPoint.x, - sy: sourceIntersectionPoint.y, - tx: targetIntersectionPoint.x, - ty: targetIntersectionPoint.y, + sx: sourcePosition.x, + sy: sourcePosition.y, + tx: targetPosition.x, + ty: targetPosition.y, sourcePos, targetPos, }; diff --git a/tsconfig.json b/tsconfig.json index 335b62f..cd887c1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -30,7 +30,8 @@ }, "include": [ "src", - ".storybook" + ".storybook", + "vite-env.d.ts" ], "exclude": [ "node_modules", From a131fe8bdf02d570f241dcf83e87b2c5121a89a7 Mon Sep 17 00:00:00 2001 From: Lavender Date: Wed, 16 Apr 2025 09:54:12 +1000 Subject: [PATCH 2/2] feature/MIG-6604 Modify name and remove parameter from JSDoc --- src/utilities/get-edge-params.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/utilities/get-edge-params.ts b/src/utilities/get-edge-params.ts index ed11860..338cc00 100644 --- a/src/utilities/get-edge-params.ts +++ b/src/utilities/get-edge-params.ts @@ -73,7 +73,6 @@ const getEdgePosition = (node: InternalNode, intersectionPoint: XYPosition) => { * @param position Direction of the edge * @param x Co-ordinates of the edge * @param y Co-ordinates of the edge - * @param offset Amount of pixels to offset by */ const offsetPosition = (position: Position, { x, y }: { x: number; y: number }) => { const offset = DEFAULT_MARKER_SIZE / 2; @@ -106,14 +105,14 @@ export const getEdgeParams = (source: InternalNode, target: InternalNode) => { const sourcePos = getEdgePosition(source, sourceIntersectionPoint); const targetPos = getEdgePosition(target, targetIntersectionPoint); - const sourcePosition = offsetPosition(sourcePos, sourceIntersectionPoint); - const targetPosition = offsetPosition(targetPos, targetIntersectionPoint); + const sourceOffsetPosition = offsetPosition(sourcePos, sourceIntersectionPoint); + const targetOffsetPosition = offsetPosition(targetPos, targetIntersectionPoint); return { - sx: sourcePosition.x, - sy: sourcePosition.y, - tx: targetPosition.x, - ty: targetPosition.y, + sx: sourceOffsetPosition.x, + sy: sourceOffsetPosition.y, + tx: targetOffsetPosition.x, + ty: targetOffsetPosition.y, sourcePos, targetPos, };