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

@loadsmart/react-location-select

v5.0.0

Published

Location Select component, based on Miranda's Select, for React applications.

Downloads

821

Readme

LocationSelect

This project belongs to Loadsmart's front-end team.

This is a spin-off of Miranda [React] Select powered with Google Autocomplete, Places, and Geocoder capabilities.

Getting started

To install it, run:

npm i @loadsmart/react-location-select

or

yarn add @loadsmart/react-location-select

Please, make sure that you also have all the peer dependencies listed in the package.json installed.

How to use

Important:

  • You need to provide the googleMapsAPIKey prop for the Select to be visible and ready for location selection.
  • If you add a custom datasource, make sure its reference is stable (i.e., you won't generate a new reference unnecessarily) so the Select can appropriately optimize its data source management.
  • If you add a custom config for the Google Maps datasource, make sure its reference is stable (i.e., you won't generate a new reference unnecessarily) so the Select can appropriately optimize its data source management.
import LocationSelect from '@loadsmart/react-location-select';

<LocationSelect {...props} googleMapsAPIKey={'<Your Google Maps API key>'} />;

The Google Maps datasource will always be included. You can customize how it fetches locations, if needed, by providing the config prop. This is the default config:

const DEFAULT_CONFIG = {
	// Source: https://developers.google.com/maps/documentation/places/web-service/supported_types#table3
	types: 'cities',
	// Source: https://developers.google.com/maps/documentation/javascript/reference/places-autocomplete-service#ComponentRestrictions
	restrictions: { country: ['us', 'ca'] },
	// Source: https://developers.google.com/maps/documentation/javascript/reference/3.45/places-service#PlaceResult
	fields: ['address_components', 'place_id'],
};

Mocking the returned locations

You most certainly will need unit tests around the code that will use the LocationSelect component. We export a mock factory to help returning the locations you want to work on your tests.

import {
	GoogleMapsMock,
	GoogleMapsMockFactory,
} from '@loadsmart/react-location-select/dist/testing';

// Save the original google reference to reset it after the test is completed
const originalWindowGoogle = window.google;

// Generate mock data using a default info.
// e.g. { "address": "New York, NY, United States" }
window.google = GoogleMapsMock();

// Or generate mock data with an overridden info.
window.google = GoogleMapsMockFactory({
	predictionStub(query) {
		return new Promise((resolve) => {
			resolve({
				predictions: [
					{
						description: 'New York, NY, United States',
						id: '7eae6a016a9c6f58e2044573fb8f14227b6e1f96',
						matched_substrings: [
							{
								length: 2,
								offset: 0,
							},
						],
						place_id: 'ChIJOwg_06VPwokRYv534QaPC8g',
						reference: '...',
						structured_formatting: {
							main_text: 'New York, NY, United States',
							main_text_matched_substrings: [
								{
									length: 2,
									offset: 0,
								},
							],
							secondary_text: '',
						},
						terms: [
							{
								offset: 0,
								value: 'New York',
							},
							{
								offset: 10,
								value: 'NY',
							},
							{
								offset: 14,
								value: 'United States',
							},
						],
						types: ['locality', 'political', 'geocode'],
					},
				],
			});
		});
	},
	geocodeStub(query, callback) {
		if (query.address === '' || query.placeId === '') {
			callback([], 'ZERO_RESULTS');
			return;
		}

		callback(
			[
				{
					address_components: [
						{
							long_name: 'New York',
							short_name: 'New York',
							types: ['locality', 'political'],
						},
						{
							long_name: 'New York',
							short_name: 'NY',
							types: ['administrative_area_level_1', 'political'],
						},
						{
							long_name: 'United States',
							short_name: 'US',
							types: ['country', 'political'],
						},
					],
					formatted_address: 'New York, NY, USA',
					geometry: {
						bounds: {
							south: 40.4773991,
							west: -74.25908989999999,
							north: 40.9175771,
							east: -73.70027209999999,
						},
						location: { lat: 40.7127753, lng: -74.0059728 },
						location_type: 'APPROXIMATE',
						viewport: {
							south: 40.4773991,
							west: -74.25908989999999,
							north: 40.9175771,
							east: -73.70027209999999,
						},
					},
					place_id: 'ChIJOwg_06VPwokRYv534QaPC8g',
					types: ['locality', 'political'],
				},
			],
			'OK',
		);
	},
	placesStub(query, callback) {
		callback(
			{
				address_components: [
					{
						long_name: 'Newark',
						short_name: 'Newark',
						types: ['locality', 'political'],
					},
					{
						long_name: 'Essex County',
						short_name: 'Essex County',
						types: ['administrative_area_level_2', 'political'],
					},
					{
						long_name: 'New Jersey',
						short_name: 'NJ',
						types: ['administrative_area_level_1', 'political'],
					},
					{
						long_name: 'United States',
						short_name: 'US',
						types: ['country', 'political'],
					},
				],
				place_id: 'ChIJHQ6aMnBTwokRc-T-3CrcvOE',
				geometry: {
					location: {
						lat: () => 0,
						lng: () => 0,
					},
				},
				html_attributions: [],
			},
			'OK',
		);
	},
});

// Reset the mock after the test is completed.
afterAll(() => {
	window.google = originalWindowGoogle;
});

Using a custom parser

You can pass one or more custom parsers and manipulate the returned data if you need a different result than the default LocationSelect config.

const customParser = (query, location) => {
	return location;
};

<LocationSelect {...args} config={{ parsers: [customParser] }} />;

Using a custom adapter

If you need a different adapter to display the select options, you can pass a custom adapter and change the data that is returned.

const customAdapter = {
	getKey(location) {
		return location?.address;
	},
	getLabel(location) {
		return location?.address;
	},
};

<LocationSelect {...args} config={{ adapter: customAdapter }} />;

Using on a TypeScript project

You can import the types from this package.

import { LocationSelect } from '@loadsmart/react-location-select';
import type {
	Location,
	LocationParser,
	// ... Any other type
} from '@loadsmart/react-location-select';

The @types/google.maps is installed by this package, don't worry about it. You can use it without importing or installing anything.

Contribute

First, make sure you have your env set to Node >= 16.

To successfully run this project on your local environment and obtain data from Compass, please adhere to the following steps:

  • Change the component stories by adding the compassConfig.APIKey in src/location-select/location-select.stories.tsx.
    • You can learn how to get a key here
export const Demo: Story = {
  args: {
    name: 'location',
    googleMapsAPIKey: '<YOUR GOOGLE MAPS API KEY GOES HERE>',
    multiple: true,
    disableMapsLoading: false,
    googleMapsAPIVersion: '3.51',
+   compassConfig: {
+    baseURL: 'https://api.staging.loadsmart.com',
+    APIKey: '<API_KEY>',
+    },
    },
    render: DemoRenderer,
};

The dev command runs on port 8080, which has the necessary permissions to establish requests to Compass in stating.