UNPKG

@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
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