UNPKG

ng-leaflet-universal-cm

Version:

NgLeafletUniversal is an open source Angular module that extends and simplifies the Leaflet implementation for Angular.

159 lines (152 loc) 10.9 kB
import { map, tileLayer, FeatureGroup, Marker, divIcon } from 'leaflet'; import * as i0 from '@angular/core'; import { output, input, effect, ChangeDetectionStrategy, Component, NgModule } from '@angular/core'; function generate(prefix = 'ng-leaflet-universal') { const hexstring = Math.random().toString(16).slice(2); return [prefix, hexstring].filter(Boolean).join('-'); } const getCardHtml = (card) => card?.customHtml ? card.customHtml : ` <div class="map-card"> <div class="map-card-body"> <div class="top-card"> <img src="${card?.image?.url}" alt="${card?.title?.text}" /> <div class="content"> <h2 class="map-card-title">${card?.title?.text}</h2> <h4 class="map-card-subtitle">${card?.subtitle?.text}</h4> <h5 class="map-address">${card?.address?.text}</h5> </div> </div> <div class="map-card-content"> ${card?.content?.text} </div> <div class="cta-wrapper"> ${card?.callToActions ?.map((cta) => ` <a href="${cta.link}" target="_blank" style=" background-color: ${cta.backgroundColor || '#007FFF'}; color: ${cta.textColor || 'white'};" class="map-card-cta"> ${cta.icon ? `<i class="${cta.icon}"></i>` : ''} ${cta.text}</a> `) .reduce((a, b) => a + b)} </div> </div> </div>`; class MapComponent { constructor() { this.mapEvent = output(); this.markers = input([]); this.id = generate('div'); this.#effet = effect(() => { if (this.map) { this.updateMarkers(this.markers()); } }); } #effet; ngAfterViewInit() { this.map = map(this.id).setView([18.4, -66.9], 4); tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: 'Map data © OpenStreetMap contributors', }).addTo(this.map); this.updateMarkers(this.markers()); } removeMarkers() { this.map.eachLayer((layer) => { // Ignore tile layer if (layer.options?.attribution) return; // Previous (markers) layer.remove(); }); } updateMarkers(markers) { this.removeMarkers(); if (!markers?.length) return; const leafletMarkers = markers.map(createLeafletMarker).map((marker, i) => { return marker.on('click', () => this.mapEvent.emit(markers[i])); }); const group = new FeatureGroup(leafletMarkers); group.addTo(this.map); this.map.fitBounds(group.getBounds()); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.6", type: MapComponent, isStandalone: false, selector: "ng-leaflet-universal", inputs: { markers: { classPropertyName: "markers", publicName: "markers", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mapEvent: "mapEvent" }, ngImport: i0, template: ` <div class="map"> <div class="map-frame"> <div [id]="id"></div> </div> </div> `, isInline: true, styles: [".map{position:absolute;inset:0}.map .map-frame,.map .map-frame div{height:100%}::ng-deep .leaflet-popup-tip{border-radius:0 0 20%!important}::ng-deep .map-marker-icon .item-marker{border-radius:100% 100% 100% 35%;border:2px solid #444444;width:22px!important;height:22px!important;background-color:#444;box-shadow:0 0 3px #0000005d;transform:rotate(-45deg);overflow:hidden}::ng-deep .map-marker-icon .item-marker .icon-image{width:100%;height:100%;border-radius:100%;background-position:center;background-size:cover;transform:rotate(38deg)}::ng-deep .leaflet-container a.leaflet-popup-close-button{position:absolute;top:5px;right:5px;padding:3px!important;color:#ff0f0f98;text-decoration:none;font-weight:700;background:#f2f2f2}::ng-deep .leaflet-container a.leaflet-popup-close-button:hover{color:#ff0f0f}::ng-deep .leaflet-popup{bottom:32px!important}::ng-deep .leaflet-popup-content{min-width:350px!important;height:auto!important}::ng-deep .leaflet-popup-content .map-card .map-card-body{padding:10px}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card{display:flex;align-items:center}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card img{width:100px;height:100px;margin-right:20px}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card .content .map-card-title{font-weight:700;margin:0}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card .content .map-card-subtitle{font-weight:400;font-size:14px;color:#585858;margin:0}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card .content .map-card-content h4{font-size:16px}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card .content .map-card-content p{font-size:14px}::ng-deep .leaflet-popup-content .map-card .map-card-body .cta-wrapper{margin-top:20px;width:100%;display:grid;grid-template-columns:repeat(3,1fr);grid-gap:15px}::ng-deep .leaflet-popup-content .map-card .map-card-body .cta-wrapper .map-card-cta{cursor:pointer;text-decoration:none;border:none;padding:8px 10px;font-size:12px;text-align:center;margin-bottom:6px;height:20px;display:flex;justify-content:center;align-items:center;border-radius:2px}::ng-deep .leaflet-popup-content .map-card .map-card-body .cta-wrapper .map-card-cta:hover{opacity:.6}::ng-deep .leaflet-popup-content .map-card .map-card-body .cta-wrapper .map-card-cta i{margin-right:5px;font-size:10px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: MapComponent, decorators: [{ type: Component, args: [{ selector: 'ng-leaflet-universal', template: ` <div class="map"> <div class="map-frame"> <div [id]="id"></div> </div> </div> `, changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, styles: [".map{position:absolute;inset:0}.map .map-frame,.map .map-frame div{height:100%}::ng-deep .leaflet-popup-tip{border-radius:0 0 20%!important}::ng-deep .map-marker-icon .item-marker{border-radius:100% 100% 100% 35%;border:2px solid #444444;width:22px!important;height:22px!important;background-color:#444;box-shadow:0 0 3px #0000005d;transform:rotate(-45deg);overflow:hidden}::ng-deep .map-marker-icon .item-marker .icon-image{width:100%;height:100%;border-radius:100%;background-position:center;background-size:cover;transform:rotate(38deg)}::ng-deep .leaflet-container a.leaflet-popup-close-button{position:absolute;top:5px;right:5px;padding:3px!important;color:#ff0f0f98;text-decoration:none;font-weight:700;background:#f2f2f2}::ng-deep .leaflet-container a.leaflet-popup-close-button:hover{color:#ff0f0f}::ng-deep .leaflet-popup{bottom:32px!important}::ng-deep .leaflet-popup-content{min-width:350px!important;height:auto!important}::ng-deep .leaflet-popup-content .map-card .map-card-body{padding:10px}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card{display:flex;align-items:center}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card img{width:100px;height:100px;margin-right:20px}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card .content .map-card-title{font-weight:700;margin:0}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card .content .map-card-subtitle{font-weight:400;font-size:14px;color:#585858;margin:0}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card .content .map-card-content h4{font-size:16px}::ng-deep .leaflet-popup-content .map-card .map-card-body .top-card .content .map-card-content p{font-size:14px}::ng-deep .leaflet-popup-content .map-card .map-card-body .cta-wrapper{margin-top:20px;width:100%;display:grid;grid-template-columns:repeat(3,1fr);grid-gap:15px}::ng-deep .leaflet-popup-content .map-card .map-card-body .cta-wrapper .map-card-cta{cursor:pointer;text-decoration:none;border:none;padding:8px 10px;font-size:12px;text-align:center;margin-bottom:6px;height:20px;display:flex;justify-content:center;align-items:center;border-radius:2px}::ng-deep .leaflet-popup-content .map-card .map-card-body .cta-wrapper .map-card-cta:hover{opacity:.6}::ng-deep .leaflet-popup-content .map-card .map-card-body .cta-wrapper .map-card-cta i{margin-right:5px;font-size:10px}\n"] }] }] }); function createLeafletMarker(marker) { const leafletMarker = new Marker({ lat: marker.location.latitude, lng: marker.location.longitude, }); leafletMarker.setIcon(divIcon({ html: marker.html || ` <div class="item-marker"> <div class="icon-image" style="background-image: url('${marker.icon}')"> </div> </div>`, className: 'map-marker-icon', iconSize: [26, 30], iconAnchor: [13, 30], })); leafletMarker.on('click', function ({ target, latlng }) { if (marker.cardActivated && marker?.card) { const html = getCardHtml(marker.card); const popup = target.getPopup(); if (popup) popup?.openPopup(); else { target .bindPopup(html, { autoClose: false, maxWidth: 200, }) .openPopup(); } } target._map.setView(latlng, 15); }); return leafletMarker; } class NgLeafletUniversalModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: NgLeafletUniversalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.6", ngImport: i0, type: NgLeafletUniversalModule, declarations: [MapComponent], exports: [MapComponent] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: NgLeafletUniversalModule }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: NgLeafletUniversalModule, decorators: [{ type: NgModule, args: [{ declarations: [MapComponent], exports: [MapComponent], }] }] }); /* * Public API Surface of ng-leaflet-universal */ /** * Generated bundle index. Do not edit. */ export { MapComponent, NgLeafletUniversalModule }; //# sourceMappingURL=ng-leaflet-universal-cm.mjs.map