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

stepwise-map

v0.0.1

Published

### Map

Downloads

11

Readme

Key components

Map

This component represents map feature and is responsible for creating map using Google Maps Javascript API
It takes following props:

  • google or window.google - it's main library object added under window to be a namespace for all useful features of Google Maps API.
  • options - configuration object for the map which reflects google.maps.MapOptions.
  • bounds - collection of LatLng literals which represent area of interests and to which map will be adjusted. Map updates the bounds only when the reference to collection is changed.
  • zoom - represents the map zoom which is adjusted when the property changes.
  • onMapZoomChanged - callback which will be fired when the map zoom changes. It's worth notice that zoom may change internally by fitting map bounds or scrolling the mouse wheel.
  • listers - it's the object representing map events listeners its properties are names of google.Map events and values are callbacks which is called after event fires.
const listeners = {
  click: () => console.log("Map clicked"),
  zoomed_out: () => console.log("Map zoomed out")
};

Main concept

Map component is designed to be easily extendable with other map features. It provides the context (MapContext) which is responsible for transferring map object as map and Google Maps global object as google and it's available to all children elements which are map context consumers MapContext.Consumer.
It's also design to be fully declarative
This approach should provide you a way for attaching new features to the map with simple composition

<Map
  google={google}
  options={this.state.mapOptions}
  listeners={this.state.listeners}
>
  <FancyMarker position={this.state.fancyMarkerPosition} />
  <AmazingPolygon border={this.state.amazingPolygonBorder} />
</Map>

In above example FancyMarker and AmazingPolygon are map features and became a map members thanks to compositional approach and being a map context consumers. This approach also ensure that only components that are inside the particular map may appear on context map instance - it helps to keep code representing map easy to reason about and clean.

MapItem

It's HOC that provides a wrapped component with map instance and google global object. It uses MapContext consumer to pass context data to wrapped component:

render() {
      return (
        <MapContext.Consumer>
          {({ google, map }) => {
            const options = { ...this.props.options, map };
            return <Item {...this.props} google={google} options={options} />;
          }}
        </MapContext.Consumer>
      );
    }

Easiest way for creating map feature is to use this HOC with component that expects google and map as a properties.

MapMarker

MapMarker is a component that it's created by MapItem HOC wrapping Marker component.
NOTE: It does not render anything - it returns null from its render method.

  • Marker - it's just component that takes map and google along with options as its props. It listens to properties change and updates its internal state accordingly. It's main purpose is to add new instance of google.maps.Marker to map passed to the component as a property. All behavior of this components relays on its props - it does not import any external state by ES6 modules or any other way. Thanks to this it keeps testing easy.
  • MapItem - as described above its responsibility is to provide Marker with google and map instances by MapContext.Consumer.

GoogleApi

GoogleApi is render props based component. Its responsibility is to pass global google object to rendered components. It communicates with existing DependencyLoader instance to make sure that https://maps.googleapis.com/maps/api/js script is loaded, then it passes google object as render function argument. It allows for lazy loading of google maps script and keeping WorldMapViz as the only component that must be imported in order to show map on the screen.

Examples:
You can pass any type of component to render function - GoogleApi does not render any additional components by itself.

const config = { key: "YOUR_API_KEY" }
//...
<GoogleApi
  apiConfig={config}
  render={google => <MyComponent google={google} />}
/>

DependencyLoader

DependencyLoader class is responsible for async loading of external dependencies. By calling load method of the loader and passing the script path as an argument, you will be able to add new external dependencies asynchronously. Load method returns a promise which resolves when script loading ends with success and rejects when it throws an error.
Every DependencyLoader instance keeps tracking of scripts paths added by itself. However if you create a multiple instances of DependencyLoader it's possible to load the same script twice.
NOTE:
This method interacts with DOM - when you call load method, DependencyLoader creates new script tag under body element.

Examples:
If you want to use existing loader (preferred way) just import it from library root

import { loader } from "world-map-viz";

const src = "https://path_to_script.js";
loader.load(src).then(() => console.log("script loaded"));

If you want to create new loader, import the DependencyLoader class from the root module:

import { DependencyLoader } from "world-map-viz";

const loader = new DependencyLoader(document);
const src = "https://path_to_script.js";
loader.load(src).then(onScriptLoaded, onScriptFailed);

Although it's not recommended to create new instance of loader - in most cases it's not needed as you can use existing one.