@loadsmart/react-location-select
TypeScript icon, indicating that this package has built-in type declarations

6.0.0 • Public • Published

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 add @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'],
};

Jest Configuration

If you are using Jest, you need to add this library to transformIgnorePatterns in your Jest configuration to ensure it is properly transformed. Example:

{
	"transformIgnorePatterns": [
		"node_modules/(?!@loadsmart/react-location-select)"
	]
}

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 the logger

If you need to debug any behavior related to the LocationSelect when consuming the @loadsmart/react-location-select library, you can enable component logging by setting the global variable window.__LOCATION_SELECT_ENABLE_LOGGING__.

In the browser console, run the following command:

window.__LOCATION_SELECT_ENABLE_LOGGING__ = true;

During development inside the library, to log from within the components, please use the utils/logger.ts file.

Logging is disabled (not shown) by default. To enable it, set the STORYBOOK_ENABLE_LOGGING environment variable to true in your .env file.

STORYBOOK_ENABLE_LOGGING=true

Using a custom parser

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

const customParser = (query: string, result: GeocodedLocation) => {
	return result;
};

<LocationSelect {...args} config={{ parser: 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.

Contributing

This project is open to contributions. If you want to contribute, please follow the steps below:

Requirements

  1. Node (See the required version at .nvmrc).

  2. Yarn Berry From the Installation Yarn docs

    The preferred way to manage Yarn is by-project and through Corepack, a tool shipped by default with Node.js. Modern releases of Yarn aren't meant to be installed globally, or from npm.

    • Start by enabling Corepack, if it isn't already; this will add the yarn binary to your PATH:
    corepack enable

    or if you use Volta. Run the following.

    npm install -g corepack
    
    # Specifying an explicit install-directory makes corepack overwrite volta's yarn shims, which is what we want
    corepack enable --install-directory ~/.volta/bin

    The "packageManager" field defines which package manager is expected to be used when working on the current project. It can be set to any of the supported package managers, and will ensure that your teams use the exact same package manager versions without having to install anything else other than Node.js.

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

Setting up the environment

  • 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.

Readme

Keywords

none

Package Sidebar

Install

npm i @loadsmart/react-location-select

Weekly Downloads

47

Version

6.0.0

License

MIT

Unpacked Size

345 kB

Total Files

11

Last publish

Collaborators

  • douglasklein2
  • luiz.loadsmart
  • mwconceicao
  • yidi0912
  • lenoir.zamboni
  • diogomafra
  • oliver.tso
  • loadsmart-frontend
  • brennervaz
  • raittes
  • welingtonms-loadsmart
  • gutofoletto
  • giovannitoledo
  • felipe.asantos