UNPKG

react-archer

Version:

Draw arrows between DOM elements in React

163 lines (131 loc) • 5.92 kB
# react-archer [![CircleCI](https://circleci.com/gh/pierpo/react-archer.svg?style=svg)](https://circleci.com/gh/pierpo/react-archer) šŸ¹ Draw arrows between DOM elements in React šŸ–‹ ## Installation `npm install react-archer --save` or `yarn add react-archer` ## Example [Try it out!](https://pierpo.github.io/react-archer/) ![Example](https://raw.githubusercontent.com/pierpo/react-archer/master/example.png) ```javascript import { ArcherContainer, ArcherElement } from 'react-archer'; const rootStyle = { display: 'flex', justifyContent: 'center' }; const rowStyle = { margin: '200px 0', display: 'flex', justifyContent: 'space-between' }; const boxStyle = { padding: '10px', border: '1px solid black' }; const App = () => { return ( <div style={{ height: '500px', margin: '50px' }}> <ArcherContainer strokeColor="red"> <div style={rootStyle}> <ArcherElement id="root" relations={[ { targetId: 'element2', targetAnchor: 'top', sourceAnchor: 'bottom', style: { strokeDasharray: '5,5' }, }, ]} > <div style={boxStyle}>Root</div> </ArcherElement> </div> <div style={rowStyle}> <ArcherElement id="element2" relations={[ { targetId: 'element3', targetAnchor: 'left', sourceAnchor: 'right', style: { strokeColor: 'blue', strokeWidth: 1 }, label: <div style={{ marginTop: '-20px' }}>Arrow 2</div>, }, ]} > <div style={boxStyle}>Element 2</div> </ArcherElement> <ArcherElement id="element3"> <div style={boxStyle}>Element 3</div> </ArcherElement> <ArcherElement id="element4" relations={[ { targetId: 'root', targetAnchor: 'right', sourceAnchor: 'left', label: 'Arrow 3', }, ]} > <div style={boxStyle}>Element 4</div> </ArcherElement> </div> </ArcherContainer> </div> ); }; export default App; ``` ## API ### `ArcherContainer` #### Props <!-- prettier-ignore --> | Name | Type | Description | | - | - | - | | `strokeColor` | `string` | A color string `'#ff0000'` | `strokeWidth` | `number` | A size in `px` | `strokeDasharray` | `string` | Adds dashes to the stroke. It has to be a string representing an array of sizes. See some [SVG strokes documentation](https://www.w3schools.com/graphics/svg_stroking.asp). | `noCurves` | `boolean` | Set this to true if you want angles instead of curves | `lineStyle` |Ā `string` | Can be one of `angle`, `curve` or `straight`. Setting this overrides `noCurves`. | `offset` | `number` | Optional number for space between element and start/end of stroke | `svgContainerStyle` | `Style` | Style of the SVG container element. Useful if you want to add a z-index to your SVG container to draw the arrows under your elements, for example. | `children` | `React.Node` | | `endShape` | `Object` | An object containing the props to configure the "end shape" of the arrow. Can be one of `arrow` (default) or `circle`. See [`ShapeType`](flow-typed/archer-types.js) for a complete list of available options. | `startMarker` | `boolean` | Optional flag (default `false`) to also add a marker at the start of the arrow. | `endMarker` | `boolean` | Optional flag (default `true`) to remove the marker at the end of the arrow. #### Instance methods If you access to the ref of your `ArcherContainer`, you will access the `refreshScreen` method. This will allow you to have more control on when you want to re-draw the arrows. ### `ArcherElement` <!-- prettier-ignore --> | Name | Type | Description | | - | - | - | | `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[]` | The `Relation` type has the following shape: ```javascript { targetId: string, targetAnchor: 'top' | 'bottom' | 'left' | 'right' | 'middle', sourceAnchor: 'top' | 'bottom' | 'left' | 'right' | 'middle', label: React.Node, order?: number, // higher order means arrow will be drawn on top of the others className?: string, // CSS class selectors on the SVG arrow style: ArcherStyle, domAttributes?: DOMAttributes<SVGElement>, // Allows to make selectable arrows by passing dom attributes like onMouseHover cursor?: Property.Cursor, // Allows to customize the hovering cursor of the arrow. Will only work if domAttributes is present hitSlop?: number, // Allows to make the selectable arrow thicker. Will only work if domAttributes is present } ``` > Please note that the `middle` anchor does not look very good: the curve won't look nice and the arrow marker will have a little offset. > The issue won't be solved before a long time. The `ArcherStyle` type has the following shape: ```javascript { strokeColor: string, strokeWidth: number, strokeDasharray: number, noCurves: boolean, lineStyle: string, endShape: Object, startMarker: boolean, endMarker: boolean, } ``` ## Troubleshooting ### My arrows don't re-render correctly... Try using the `refreshScreen` instance method on your `ArcherContainer` element. You can access it through the [ref of the component](https://reactjs.org/docs/refs-and-the-dom.html). Call `refreshScreen` when the event that you need is triggered (`onScroll` etc.).