npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-svg-gps

v2.0.0

Published

Utility for declarative coordination of SVG element positions.

Downloads

22

Readme


build coverage npm minzipped size license

The Problem

Calculating the relative positions of various SVG elements can get complicated quickly. Nested elements are often necessary, each potentially with their own transforms and local units. It becomes a chore to track these positions across successive renders, and to propagate them to other elements that need to know about them.

Furthermore, this is almost always merely a presentation concern. It feels excessive to manually implement application logic to solve this problem, and inappropriate to use an application data store to track this information.

The Solution

React SVG GPS abstracts this problem away. It allows a developer to attach "beacons" to SVG elements and then access their global positions from other components via straightforward declarations. All of the complex math and communication are handled automatically.

It utilizes React Hooks for maximum composability.

Installation

React SVG GPS requires React 18 or later.

npm install react-svg-gps

Basic Usage

import React from 'react';
import { BeaconProvider, useBeaconRef, useBeaconPosition } from 'react-svg-gps';

const Point = ({ id, x, y }) => {
    const ref = useBeaconRef({ id });
    return (
        <circle cx={x} cy={y} r="7" fill="#3E4751" stroke="#FFF" strokeWidth="3" ref={ref} />
    );
};

const Line = ({ fromId, toId }) => {
    const from = useBeaconPosition({ id: fromId });
    const to = useBeaconPosition({ id: toId });
    return from && to && (
        <path d={`M${from.x},${from.y}L${to.x},${to.y}`} fill="none" stroke="#447AB9" strokeWidth="4" />
    );
};

const App = () => (
    <svg width="400" height="400">
        <BeaconProvider>
            <Line fromId="A" toId="B" />
            <Point id="A" x={50} y={50} />
            <Point id="B" x={350} y={350} />
        </BeaconProvider>
    </svg>
);

More Examples

storybook

You can find several usage examples compiled for Storybook by clicking the badge above. The source code for these examples can be found here.

If you want to run and modify these examples locally, just clone this repository and run npm run storybook.

API

<BeaconProvider />

A wrapper component that facilitates beacon communication. All related beacons and beacon subscribers should be contained within a <BeaconProvider />.

useBeaconRef(config)

A hook with which beacons are established. Registers itself with the closest BeaconProvider and reports the position of the element to which the ref is attached on each render.

Arguments

  • config (object)
    • id (string) - The unique identifier for the beacon.
    • anchor ({ x: number, y: number }) [optional] - The relative position on the element from which the beacon originates. Default value: { x: 0.5, y: 0.5 }.
    • offset ({ x: number, y: number }) [optional] - The amount to offset the beacon origin in units local to the element. Default value: { x: 0, y: 0 }.

Return value

Returns a ref that should be attached to an SVGGraphicsElement.

useBeaconPosition(config)

A hook with which components can subscribe to a beacon's global position.

Arguments

  • config (object)
    • id (string) - The beacon ID for which to receive position data.

Return value

Returns the global position of the beacon with the given ID in the form { x: number, y: number }. Returns null if the beacon cannot be found.

FAQs

Why aren't my nested beacons reporting their positions when a parent updates?

A beacon reports its position each time it is rendered. If nested elements are being rendered and then and passed to another component (either through props.children or otherwise), they will not be re-rendered when that enclosing element re-renders. Therefore, it is important to either render nested beacons explicitly within parent components, provide them as render props, or take some other approach to ensure they re-render with their parent (such as iterating over them and cloning them — see the InteractiveNodeGraph example for a demonstration of this).