@ng-maps/places
Version:
Components related to places library. Currently only an autocomplete directive is implemented that can be attached to an input field to provide places suggestions
271 lines (263 loc) • 11.4 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, EventEmitter, Directive, Inject, Input, Output, NgModule } from '@angular/core';
import { Subscription, fromEventPattern } from 'rxjs';
import * as i1 from '@ng-maps/core';
const NG_MAPS_PLACES_DEFAULT_CONFIGURATION = new InjectionToken('NgMapsPlacesDefaultConfiguration', { providedIn: 'root', factory: () => ({}) });
/**
* @example
* <input [mapAutocomplete]='options' (placeResult)='onPlacesResult($event)' />
*/
class NgMapsAutocompleteDirective {
constructor(element, mapsAPILoader, defaultConfig, _zone) {
this.element = element;
this.mapsAPILoader = mapsAPILoader;
this.defaultConfig = defaultConfig;
this._zone = _zone;
/**
* This event is fired on selection of an element from the autocomplete list.
* The event contains a PlaceResult from GoogleMapsAPI
* https://developers.google.com/maps/documentation/javascript/reference/3.exp/places-service#PlaceResult
*/
this.placeResult = new EventEmitter();
/**
* This event is fired on selection of an element from the autocomplete list.
* The event contains a LatLngBounds from GoogleMapsAPI
* https://developers.google.com/maps/documentation/javascript/reference/3.exp/coordinates#LatLngBounds
*/
this.bounds = new EventEmitter();
this.subscription = new Subscription();
}
/** @internal */
ngOnInit() {
if (typeof this.config === 'undefined') {
this.config = {
types: ['address'],
...(this.defaultConfig?.autocomplete ?? {}),
};
}
else {
this.config = {
types: ['address'],
...(this.defaultConfig?.autocomplete ?? {}),
...this.config,
};
}
if (this.element.nativeElement instanceof HTMLInputElement) {
this.init();
}
else {
throw new Error('Directive can only be applied to an HTMLInputElement');
}
}
/** @internal */
async init() {
await this.mapsAPILoader.load();
this.autocomplete = new google.maps.places.Autocomplete(this.element.nativeElement, this.config);
this.subscription.add(fromEventPattern((handler) => this.addHandler(handler), () => this.removeHandler()).subscribe({
next: () => {
this.placeResult.emit(this.autocomplete.getPlace());
this.bounds.emit(this.autocomplete.getBounds());
},
}));
}
/** @internal */
ngOnChanges(changes) {
if (typeof changes.config !== 'undefined' && !changes.config.firstChange) {
const config = changes.config
.currentValue;
if (typeof config.bounds !== 'undefined') {
this.autocomplete?.setBounds(config.bounds);
}
if (typeof config.componentRestrictions !== 'undefined') {
this.autocomplete?.setComponentRestrictions(config.componentRestrictions);
}
if (typeof config.types !== 'undefined') {
this.autocomplete?.setTypes(config.types);
}
}
}
/** @internal */
ngOnDestroy() {
this.subscription.unsubscribe();
}
/** @internal */
addHandler(handler) {
return this.autocomplete?.addListener('place_changed', () => this._zone.run(handler));
}
/** @internal */
removeHandler() {
this.autocomplete?.unbindAll();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: NgMapsAutocompleteDirective, deps: [{ token: i0.ElementRef }, { token: i1.MapsAPILoader }, { token: NG_MAPS_PLACES_DEFAULT_CONFIGURATION }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.3", type: NgMapsAutocompleteDirective, isStandalone: false, selector: "[mapAutocomplete]", inputs: { config: ["mapAutocomplete", "config"] }, outputs: { placeResult: "placeResult", bounds: "bounds" }, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: NgMapsAutocompleteDirective, decorators: [{
type: Directive,
args: [{
selector: '[mapAutocomplete]',
standalone: false,
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.MapsAPILoader }, { type: undefined, decorators: [{
type: Inject,
args: [NG_MAPS_PLACES_DEFAULT_CONFIGURATION]
}] }, { type: i0.NgZone }], propDecorators: { config: [{
type: Input,
args: ['mapAutocomplete']
}], placeResult: [{
type: Output
}], bounds: [{
type: Output
}] } });
/**
* @example
* <input [mapAutocomplete]='options' (placeResult)='onPlacesResult($event)' />
*/
class NgMapsSearchBoxDirective {
constructor(element, mapsAPILoader, defaultConfig, _zone) {
this.element = element;
this.mapsAPILoader = mapsAPILoader;
this.defaultConfig = defaultConfig;
this._zone = _zone;
/**
* This event is fired on selection of an element from the autocomplete list.
* The event contains a PlaceResult from GoogleMapsAPI
* https://developers.google.com/maps/documentation/javascript/reference/3.exp/places-service#PlaceResult
*/
this.placeResult = new EventEmitter();
/**
* This event is fired on selection of an element from the autocomplete list.
* The event contains a LatLngBounds from GoogleMapsAPI
* https://developers.google.com/maps/documentation/javascript/reference/3.exp/coordinates#LatLngBounds
*/
this.bounds = new EventEmitter();
this.subscription = new Subscription();
}
/** @internal */
ngOnInit() {
if (typeof this.config === 'undefined') {
this.config = this.defaultConfig?.searchBox;
}
else {
this.config = {
...(this.defaultConfig?.searchBox ?? {}),
...this.config,
};
}
if (this.element.nativeElement instanceof HTMLInputElement) {
this.init();
}
else {
throw new Error('Directive can only be applied to an HTMLInputElement');
}
}
/** @internal */
async init() {
await this.mapsAPILoader.load();
this.searchBox = new google.maps.places.SearchBox(this.element.nativeElement, this.config);
this.subscription.add(fromEventPattern((handler) => this.addHandler(handler), () => this.removeHandler()).subscribe({
next: () => {
this.placeResult.emit(this.searchBox.getPlaces());
this.bounds.emit(this.searchBox.getBounds());
},
}));
}
/** @internal */
ngOnChanges(changes) {
if (typeof changes.config !== 'undefined' && !changes.config.firstChange) {
const config = changes.config
.currentValue;
if (typeof config.bounds !== 'undefined' && this.searchBox) {
this.searchBox.setBounds(config.bounds);
}
}
}
/** @internal */
ngOnDestroy() {
this.subscription.unsubscribe();
}
/** @internal */
addHandler(handler) {
return this.searchBox?.addListener('places_changed', () => this._zone.run(handler));
}
/** @internal */
removeHandler() {
this.searchBox?.unbindAll();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: NgMapsSearchBoxDirective, deps: [{ token: i0.ElementRef }, { token: i1.MapsAPILoader }, { token: NG_MAPS_PLACES_DEFAULT_CONFIGURATION }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.3", type: NgMapsSearchBoxDirective, isStandalone: false, selector: "[mapSearchBox]", inputs: { config: ["mapSearchBox", "config"] }, outputs: { placeResult: "placeResult", bounds: "bounds" }, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: NgMapsSearchBoxDirective, decorators: [{
type: Directive,
args: [{
selector: '[mapSearchBox]',
standalone: false,
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.MapsAPILoader }, { type: undefined, decorators: [{
type: Inject,
args: [NG_MAPS_PLACES_DEFAULT_CONFIGURATION]
}] }, { type: i0.NgZone }], propDecorators: { config: [{
type: Input,
args: ['mapSearchBox']
}], placeResult: [{
type: Output
}], bounds: [{
type: Output
}] } });
/**
* @internal
*/
function placesDirectives() {
return [NgMapsAutocompleteDirective, NgMapsSearchBoxDirective];
}
class NgMapsPlacesModule {
/**
* configure the NgMapsPlacesModule with a value
* @param config
*/
static forRoot(config) {
return {
ngModule: NgMapsPlacesModule,
providers: [
{
provide: NG_MAPS_PLACES_DEFAULT_CONFIGURATION,
useValue: config,
},
],
};
}
/**
* configure the NgMapsPlacesModule with a factory
* @param factory
* @param deps
*/
static forRootFactory(factory, deps) {
return {
ngModule: NgMapsPlacesModule,
providers: [
{
provide: NG_MAPS_PLACES_DEFAULT_CONFIGURATION,
useFactory: factory,
deps,
},
],
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: NgMapsPlacesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: NgMapsPlacesModule, declarations: [NgMapsAutocompleteDirective, NgMapsSearchBoxDirective], exports: [NgMapsAutocompleteDirective, NgMapsSearchBoxDirective] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: NgMapsPlacesModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: NgMapsPlacesModule, decorators: [{
type: NgModule,
args: [{
declarations: placesDirectives(),
exports: placesDirectives(),
}]
}] });
/*
* Public API Surface of places
*/
/**
* Generated bundle index. Do not edit.
*/
export { NG_MAPS_PLACES_DEFAULT_CONFIGURATION, NgMapsAutocompleteDirective, NgMapsPlacesModule, NgMapsSearchBoxDirective, placesDirectives };
//# sourceMappingURL=ng-maps-places.mjs.map