diff --git a/README.md b/README.md index 5da2f6d..44da5ff 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ This project is a fork of [lit-google-map](https://github.com/arkadiuszwojcik/li - update dependencies and keep current with Dependabot - add `zoom_changed`, `center_changed`, and `view_changed` events - move to [AdvancedMarkerElement](https://developers.google.com/maps/documentation/javascript/advanced-markers/migration) +- add location button control for centering map on user's current location ## Table of contents @@ -23,6 +24,8 @@ This project is a fork of [lit-google-map](https://github.com/arkadiuszwojcik/li [Polygon shape element attributes](#Polygon-shape-element-attributes) +[Location button control](#Location-button-control) + [How to build](#How-to-build) [License](#License) @@ -208,6 +211,51 @@ Example: ``` +## Location button control + +The location button control adds a native-looking button to the map that centers the map on the user's current location using the browser's Geolocation API. + +**Note:** Geolocation requires HTTPS (or localhost for development). + +### Location button attributes + +- '_position_' - Control position on map (default: 'RIGHT_BOTTOM') + - Valid values: 'TOP_LEFT', 'TOP_CENTER', 'TOP_RIGHT', 'LEFT_TOP', 'LEFT_CENTER', 'LEFT_BOTTOM', 'RIGHT_TOP', 'RIGHT_CENTER', 'RIGHT_BOTTOM', 'BOTTOM_LEFT', 'BOTTOM_CENTER', 'BOTTOM_RIGHT' +- '_label_' - Accessible label for screen readers (default: 'My Location') +- '_disabled_' - Disable the button (default: false) + +### Location button events + +- '_location-requested_' - Fired when button is clicked and location request begins +- '_location-found_' - Fired when location is successfully obtained + - Detail: `{lat: number, lng: number}` +- '_location-error_' - Fired when geolocation fails + - Detail: `{code: number, message: string}` + +### Example + +Basic usage: + +```html + + + + +``` + +With custom position: + +```html + + + + +``` + ## How to build Before build install all required packages: diff --git a/dist/lit-google-map.bundle.js b/dist/lit-google-map.bundle.js index e671e52..55eddfd 100644 --- a/dist/lit-google-map.bundle.js +++ b/dist/lit-google-map.bundle.js @@ -163,6 +163,7 @@ var LitGoogleMap = (function (exports) { }); this.updateMarkers(); this.updateShapes(); + this.updateControls(); } getMapOptions() { return { @@ -257,6 +258,15 @@ var LitGoogleMap = (function (exports) { s.attachToMap(this.map); } } + updateControls() { + const controlsSelector = this.shadowRoot.getElementById("controls-selector"); + if (!controlsSelector) + return; + this.controls = controlsSelector.items; + for (const c of this.controls) { + c.changeMap(this.map); + } + } fitToMarkersChanged(retryAttempt = 0) { if (this.map && this.fitToMarkers && this.markers.length > 0) { const latLngBounds = new google.maps.LatLngBounds(); @@ -316,6 +326,13 @@ var LitGoogleMap = (function (exports) { > + + +
`; } @@ -471,6 +488,210 @@ var LitGoogleMap = (function (exports) { t("lit-google-map-circle") ], exports.LitGoogleMapCircle); + exports.LitGoogleMapLocationButton = class LitGoogleMapLocationButton extends i { + constructor() { + super(...arguments); + this.position = "RIGHT_BOTTOM"; + this.label = "My Location"; + this.disabled = false; + this.map = null; + this.controlDiv = null; + this.controlButton = null; + this.isRequesting = false; + } + changeMap(newMap) { + this.map = newMap; + this.mapChanged(); + } + mapChanged() { + if (this.controlDiv && this.map) { + this.controlDiv = null; + this.controlButton = null; + } + if (this.map && this.map instanceof google.maps.Map) { + this.mapReady(); + } + } + mapReady() { + this.controlDiv = this.createControlButton(); + const controlPosition = google.maps.ControlPosition[this.position]; + if (controlPosition !== undefined) { + this.map.controls[controlPosition].push(this.controlDiv); + } + } + createControlButton() { + const controlDiv = document.createElement("div"); + controlDiv.style.margin = "10px"; + const controlButton = document.createElement("button"); + controlButton.type = "button"; + controlButton.title = this.label; + controlButton.setAttribute("aria-label", this.label); + controlButton.innerHTML = ` + + + + `; + Object.assign(controlButton.style, { + backgroundColor: "#fff", + border: "0", + borderRadius: "2px", + boxShadow: "0 1px 4px rgba(0,0,0,0.3)", + cursor: "pointer", + padding: "10px", + display: "flex", + alignItems: "center", + justifyContent: "center", + width: "40px", + height: "40px", + color: "#666", + }); + controlButton.addEventListener("mouseenter", () => { + if (!this.disabled && !this.isRequesting) { + controlButton.style.backgroundColor = "#f8f8f8"; + } + }); + controlButton.addEventListener("mouseleave", () => { + if (!this.disabled && !this.isRequesting) { + controlButton.style.backgroundColor = "#fff"; + } + }); + controlButton.addEventListener("click", () => { + if (!this.disabled && !this.isRequesting) { + this.handleLocationRequest(); + } + }); + this.controlButton = controlButton; + controlDiv.appendChild(controlButton); + return controlDiv; + } + async handleLocationRequest() { + if (!navigator.geolocation) { + this.dispatchEvent(new CustomEvent("location-error", { + detail: { + code: -1, + message: "Geolocation is not supported by your browser", + }, + bubbles: true, + composed: true, + })); + return; + } + this.isRequesting = true; + this.setLoadingState(true); + this.dispatchEvent(new CustomEvent("location-requested", { + bubbles: true, + composed: true, + })); + try { + const position = await this.getCurrentPosition(); + const lat = position.coords.latitude; + const lng = position.coords.longitude; + this.map.setCenter({ lat, lng }); + this.map.setZoom(14); + this.dispatchEvent(new CustomEvent("location-found", { + detail: { lat, lng }, + bubbles: true, + composed: true, + })); + } + catch (error) { + let message = "Unable to retrieve your location"; + let code = -1; + if (error instanceof GeolocationPositionError) { + code = error.code; + if (error.code === error.PERMISSION_DENIED) { + message = + "Location access denied. Please enable location permissions."; + } + else if (error.code === error.TIMEOUT) { + message = "Location request timed out. Please try again."; + } + else if (error.code === error.POSITION_UNAVAILABLE) { + message = "Location information is unavailable."; + } + } + this.dispatchEvent(new CustomEvent("location-error", { + detail: { code, message }, + bubbles: true, + composed: true, + })); + } + finally { + this.isRequesting = false; + this.setLoadingState(false); + } + } + getCurrentPosition() { + return new Promise((resolve, reject) => { + navigator.geolocation.getCurrentPosition(resolve, reject, { + timeout: 10000, + enableHighAccuracy: true, + }); + }); + } + setLoadingState(loading) { + if (!this.controlButton) + return; + if (loading) { + this.controlButton.style.backgroundColor = "#f0f0f0"; + this.controlButton.style.cursor = "wait"; + const svg = this.controlButton.querySelector("svg"); + if (svg) { + svg.style.animation = "spin 1s linear infinite"; + const style = document.createElement("style"); + style.textContent = ` + @keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + `; + if (!document.querySelector("style[data-location-button-spin]")) { + style.setAttribute("data-location-button-spin", "true"); + document.head.appendChild(style); + } + } + } + else { + this.controlButton.style.backgroundColor = "#fff"; + this.controlButton.style.cursor = "pointer"; + const svg = this.controlButton.querySelector("svg"); + if (svg) { + svg.style.animation = ""; + } + } + } + attributeChangedCallback(name, oldval, newval) { + super.attributeChangedCallback(name, oldval, newval); + if (name === "disabled" && this.controlButton) { + if (this.disabled) { + this.controlButton.style.backgroundColor = "#f0f0f0"; + this.controlButton.style.cursor = "not-allowed"; + this.controlButton.style.opacity = "0.6"; + } + else { + this.controlButton.style.backgroundColor = "#fff"; + this.controlButton.style.cursor = "pointer"; + this.controlButton.style.opacity = "1"; + } + } + } + }; + __decorate([ + n({ type: String, reflect: true }), + __metadata("design:type", Object) + ], exports.LitGoogleMapLocationButton.prototype, "position", void 0); + __decorate([ + n({ type: String, reflect: true }), + __metadata("design:type", Object) + ], exports.LitGoogleMapLocationButton.prototype, "label", void 0); + __decorate([ + n({ type: Boolean, reflect: true }), + __metadata("design:type", Object) + ], exports.LitGoogleMapLocationButton.prototype, "disabled", void 0); + exports.LitGoogleMapLocationButton = __decorate([ + t("lit-google-map-location-button") + ], exports.LitGoogleMapLocationButton); + exports.LitGoogleMapMarker = class LitGoogleMapMarker extends i { constructor() { super(...arguments); diff --git a/dist/lit-google-map.bundle.min.js b/dist/lit-google-map.bundle.min.js index d86a060..32364dd 100644 --- a/dist/lit-google-map.bundle.min.js +++ b/dist/lit-google-map.bundle.min.js @@ -9,18 +9,18 @@ const s=globalThis,o=s.ShadowRoot&&(void 0===s.ShadyCSS||s.ShadyCSS.nativeShadow * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause - */,{is:h,defineProperty:p,getOwnPropertyDescriptor:c,getOwnPropertyNames:d,getOwnPropertySymbols:u,getPrototypeOf:g}=Object,m=globalThis,y=m.trustedTypes,b=y?y.emptyScript:"",f=m.reactiveElementPolyfillSupport,v=(t,e)=>t,$={toAttribute(t,e){switch(e){case Boolean:t=t?b:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},_=(t,e)=>!h(t,e),k={attribute:!0,type:String,converter:$,reflect:!1,useDefault:!1,hasChanged:_};Symbol.metadata??=Symbol("metadata"),m.litPropertyMetadata??=new WeakMap;let C=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=k){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&p(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:o}=c(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const r=s?.call(this);o?.call(this,e),this.requestUpdate(t,r,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??k}static _$Ei(){if(this.hasOwnProperty(v("elementProperties")))return;const t=g(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(v("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(v("properties"))){const t=this.properties,e=[...d(t),...u(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(l(t))}else void 0!==t&&e.push(l(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((t,e)=>{if(o)t.adoptedStyleSheets=e.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet));else for(const i of e){const e=document.createElement("style"),o=s.litNonce;void 0!==o&&e.setAttribute("nonce",o),e.textContent=i.cssText,t.appendChild(e)}})(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((t=>t.hostConnected?.()))}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach((t=>t.hostDisconnected?.()))}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const o=(void 0!==i.converter?.toAttribute?i.converter:$).toAttribute(e,i.type);this._$Em=t,null==o?this.removeAttribute(s):this.setAttribute(s,o),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),o="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:$;this._$Em=s,this[s]=o.fromAttribute(e,t.type)??this._$Ej?.get(s)??null,this._$Em=null}}requestUpdate(t,e,i){if(void 0!==t){const s=this.constructor,o=this[t];if(i??=s.getPropertyOptions(t),!((i.hasChanged??_)(o,e)||i.useDefault&&i.reflect&&o===this._$Ej?.get(t)&&!this.hasAttribute(s._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:o},r){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,r??e??this[t]),!0!==o||void 0!==r)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach((t=>t.hostUpdate?.())),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach((t=>this._$ET(t,this[t]))),this._$EM()}updated(t){}firstUpdated(t){}};C.elementStyles=[],C.shadowRootOptions={mode:"open"},C[v("elementProperties")]=new Map,C[v("finalized")]=new Map,f?.({ReactiveElement:C}),(m.reactiveElementVersions??=[]).push("2.1.0"); + */,{is:h,defineProperty:c,getOwnPropertyDescriptor:p,getOwnPropertyNames:d,getOwnPropertySymbols:u,getPrototypeOf:g}=Object,m=globalThis,y=m.trustedTypes,b=y?y.emptyScript:"",f=m.reactiveElementPolyfillSupport,v=(t,e)=>t,$={toAttribute(t,e){switch(e){case Boolean:t=t?b:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},C=(t,e)=>!h(t,e),_={attribute:!0,type:String,converter:$,reflect:!1,useDefault:!1,hasChanged:C};Symbol.metadata??=Symbol("metadata"),m.litPropertyMetadata??=new WeakMap;let k=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=_){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&c(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:o}=p(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const r=s?.call(this);o?.call(this,e),this.requestUpdate(t,r,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??_}static _$Ei(){if(this.hasOwnProperty(v("elementProperties")))return;const t=g(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(v("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(v("properties"))){const t=this.properties,e=[...d(t),...u(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(l(t))}else void 0!==t&&e.push(l(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((t,e)=>{if(o)t.adoptedStyleSheets=e.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet));else for(const i of e){const e=document.createElement("style"),o=s.litNonce;void 0!==o&&e.setAttribute("nonce",o),e.textContent=i.cssText,t.appendChild(e)}})(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((t=>t.hostConnected?.()))}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach((t=>t.hostDisconnected?.()))}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const o=(void 0!==i.converter?.toAttribute?i.converter:$).toAttribute(e,i.type);this._$Em=t,null==o?this.removeAttribute(s):this.setAttribute(s,o),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),o="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:$;this._$Em=s,this[s]=o.fromAttribute(e,t.type)??this._$Ej?.get(s)??null,this._$Em=null}}requestUpdate(t,e,i){if(void 0!==t){const s=this.constructor,o=this[t];if(i??=s.getPropertyOptions(t),!((i.hasChanged??C)(o,e)||i.useDefault&&i.reflect&&o===this._$Ej?.get(t)&&!this.hasAttribute(s._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:o},r){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,r??e??this[t]),!0!==o||void 0!==r)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach((t=>t.hostUpdate?.())),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach((t=>this._$ET(t,this[t]))),this._$EM()}updated(t){}firstUpdated(t){}};k.elementStyles=[],k.shadowRootOptions={mode:"open"},k[v("elementProperties")]=new Map,k[v("finalized")]=new Map,f?.({ReactiveElement:k}),(m.reactiveElementVersions??=[]).push("2.1.0"); /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ -const A=globalThis,M=A.trustedTypes,E=M?M.createPolicy("lit-html",{createHTML:t=>t}):void 0,L="$lit$",S=`lit$${Math.random().toFixed(9).slice(2)}$`,O="?"+S,w=`<${O}>`,P=document,x=()=>P.createComment(""),N=t=>null===t||"object"!=typeof t&&"function"!=typeof t,I=Array.isArray,G="[ \t\n\f\r]",j=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,T=/-->/g,U=/>/g,R=RegExp(`>|${G}(?:([^\\s"'>=/]+)(${G}*=${G}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),H=/'/g,z=/"/g,B=/^(?:script|style|textarea|title)$/i,D=(t=>(e,...i)=>({_$litType$:t,strings:e,values:i}))(1),W=Symbol.for("lit-noChange"),q=Symbol.for("lit-nothing"),F=new WeakMap,V=P.createTreeWalker(P,129);function K(t,e){if(!I(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==E?E.createHTML(e):e}const J=(t,e)=>{const i=t.length-1,s=[];let o,r=2===e?"":3===e?"":"",n=j;for(let e=0;e"===l[0]?(n=o??j,h=-1):void 0===l[1]?h=-2:(h=n.lastIndex-l[2].length,a=l[1],n=void 0===l[3]?R:'"'===l[3]?z:H):n===z||n===H?n=R:n===T||n===U?n=j:(n=R,o=void 0);const c=n===R&&t[e+1].startsWith("/>")?" ":"";r+=n===j?i+w:h>=0?(s.push(a),i.slice(0,h)+L+i.slice(h)+S+c):i+S+(-2===h?e:c)}return[K(t,r+(t[i]||"")+(2===e?"":3===e?"":"")),s]};class Z{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let o=0,r=0;const n=t.length-1,a=this.parts,[l,h]=J(t,e);if(this.el=Z.createElement(l,i),V.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=V.nextNode())&&a.length0){s.textContent=M?M.emptyScript:"";for(let i=0;iI(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==q&&N(this._$AH)?this._$AA.nextSibling.data=t:this.T(P.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=Z.createElement(K(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new X(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=F.get(t.strings);return void 0===e&&F.set(t.strings,e=new Z(t)),e}k(t){I(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const o of t)s===e.length?e.push(i=new Y(this.O(x()),this.O(x()),this,this.options)):i=e[s],i._$AI(o),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=q}_$AI(t,e=this,i,s){const o=this.strings;let r=!1;if(void 0===o)t=Q(this,t,e,0),r=!N(t)||t!==this._$AH&&t!==W,r&&(this._$AH=t);else{const s=t;let n,a;for(t=o[0],n=0;nt}):void 0,E="$lit$",S=`lit$${Math.random().toFixed(9).slice(2)}$`,w="?"+S,O=`<${w}>`,x=document,P=()=>x.createComment(""),I=t=>null===t||"object"!=typeof t&&"function"!=typeof t,N=Array.isArray,G="[ \t\n\f\r]",T=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,R=/-->/g,j=/>/g,U=RegExp(`>|${G}(?:([^\\s"'>=/]+)(${G}*=${G}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),B=/'/g,H=/"/g,z=/^(?:script|style|textarea|title)$/i,D=(t=>(e,...i)=>({_$litType$:t,strings:e,values:i}))(1),q=Symbol.for("lit-noChange"),W=Symbol.for("lit-nothing"),V=new WeakMap,F=x.createTreeWalker(x,129);function K(t,e){if(!N(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==A?A.createHTML(e):e}const Z=(t,e)=>{const i=t.length-1,s=[];let o,r=2===e?"":3===e?"":"",n=T;for(let e=0;e"===l[0]?(n=o??T,h=-1):void 0===l[1]?h=-2:(h=n.lastIndex-l[2].length,a=l[1],n=void 0===l[3]?U:'"'===l[3]?H:B):n===H||n===B?n=U:n===R||n===j?n=T:(n=U,o=void 0);const p=n===U&&t[e+1].startsWith("/>")?" ":"";r+=n===T?i+O:h>=0?(s.push(a),i.slice(0,h)+E+i.slice(h)+S+p):i+S+(-2===h?e:p)}return[K(t,r+(t[i]||"")+(2===e?"":3===e?"":"")),s]};class J{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let o=0,r=0;const n=t.length-1,a=this.parts,[l,h]=Z(t,e);if(this.el=J.createElement(l,i),F.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=F.nextNode())&&a.length0){s.textContent=L?L.emptyScript:"";for(let i=0;iN(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==W&&I(this._$AH)?this._$AA.nextSibling.data=t:this.T(x.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=J.createElement(K(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new X(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=V.get(t.strings);return void 0===e&&V.set(t.strings,e=new J(t)),e}k(t){N(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const o of t)s===e.length?e.push(i=new Y(this.O(P()),this.O(P()),this,this.options)):i=e[s],i._$AI(o),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=W}_$AI(t,e=this,i,s){const o=this.strings;let r=!1;if(void 0===o)t=Q(this,t,e,0),r=!I(t)||t!==this._$AH&&t!==q,r&&(this._$AH=t);else{const s=t;let n,a;for(t=o[0],n=0;n{const s=i?.renderBefore??e;let o=s._$litPart$;if(void 0===o){const t=i?.renderBefore??null;s._$litPart$=o=new Y(e.insertBefore(x(),t),t,void 0,i??{})}return o._$AI(t),o})(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return W}}at._$litElement$=!0,at.finalized=!0,nt.litElementHydrateSupport?.({LitElement:at});const lt=nt.litElementPolyfillSupport;lt?.({LitElement:at}),(nt.litElementVersions??=[]).push("4.2.0"); + */class at extends k{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=((t,e,i)=>{const s=i?.renderBefore??e;let o=s._$litPart$;if(void 0===o){const t=i?.renderBefore??null;s._$litPart$=o=new Y(e.insertBefore(P(),t),t,void 0,i??{})}return o._$AI(t),o})(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return q}}at._$litElement$=!0,at.finalized=!0,nt.litElementHydrateSupport?.({LitElement:at});const lt=nt.litElementPolyfillSupport;lt?.({LitElement:at}),(nt.litElementVersions??=[]).push("4.2.0"); /** * @license * Copyright 2017 Google LLC @@ -31,7 +31,7 @@ const ht=t=>(e,i)=>{void 0!==i?i.addInitializer((()=>{customElements.define(t,e) * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause - */,pt={attribute:!0,type:String,converter:$,reflect:!1,hasChanged:_},ct=(t=pt,e,i)=>{const{kind:s,metadata:o}=i;let r=globalThis.litPropertyMetadata.get(o);if(void 0===r&&globalThis.litPropertyMetadata.set(o,r=new Map),"setter"===s&&((t=Object.create(t)).wrapped=!0),r.set(i.name,t),"accessor"===s){const{name:s}=i;return{set(i){const o=e.get.call(this);e.set.call(this,i),this.requestUpdate(s,o,t)},init(e){return void 0!==e&&this.C(s,void 0,t,e),e}}}if("setter"===s){const{name:s}=i;return function(i){const o=this[s];e.call(this,i),this.requestUpdate(s,o,t)}}throw Error("Unsupported decorator location: "+s)};function dt(t){return(e,i)=>"object"==typeof i?ct(t,e,i):((t,e,i)=>{const s=e.hasOwnProperty(i);return e.constructor.createProperty(i,t),s?Object.getOwnPropertyDescriptor(e,i):void 0})(t,e,i)}t.LitGoogleMap=class extends at{constructor(){super(...arguments),this.apiKey="",this.version="3.48",this.styles={},this.zoom=8,this.fitToMarkers=!1,this.mapType="roadmap",this.centerLatitude=-34.397,this.centerLongitude=150.644,this.language="",this.mapId="DEMO_MAP_ID",this.map=null}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),this.map&&e!==i&&null!==i&&("center-latitude"===t||"center-longitude"===t?this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude}):"zoom"===t&&this.map.setZoom(this.zoom))}dispatchViewChanged(){this.dispatchEvent(new CustomEvent("view_changed",{detail:{center:this.map.getCenter().toJSON(),zoom:this.map.getZoom()},bubbles:!0,composed:!0}))}initGMap(){if(null!=this.map)return;const t=this.shadowRoot.getElementById("api");null!=t&&!0===t.libraryLoaded&&(this.map=new google.maps.Map(this.shadowRoot.getElementById("map"),this.getMapOptions()),this.map.addListener("bounds_changed",(()=>{this.dispatchEvent(new CustomEvent("bounds_changed",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("tilesloaded",(()=>{this.dispatchEvent(new CustomEvent("tilesloaded",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("center_changed",(()=>{this.dispatchEvent(new CustomEvent("center_changed",{detail:this.map.getCenter().toJSON(),bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("zoom_changed",(()=>{this.dispatchEvent(new CustomEvent("zoom_changed",{detail:{zoom:this.map.getZoom()},bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("click",(t=>{"placeId"in t&&(t.stop(),this.dispatchEvent(new CustomEvent("place_click",{detail:{placeId:t.placeId},bubbles:!0,composed:!0})))})),this.updateMarkers(),this.updateShapes())}getMapOptions(){return{zoom:this.zoom,center:{lat:this.centerLatitude,lng:this.centerLongitude},mapTypeId:this.mapType,styles:this.styles,mapId:this.mapId}}mapApiLoaded(){this.initGMap()}connectedCallback(){super.connectedCallback(),this.initGMap()}updated(t){super.updated(t),this.map?((t.has("centerLatitude")||t.has("centerLongitude"))&&(t.get("centerLatitude"),t.get("centerLongitude"),this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude})),t.has("zoom")&&(t.get("zoom"),this.map.setZoom(this.zoom))):console.log("Map not initialized yet, skipping update")}attachChildrenToMap(t){if(this.map)for(const e of t)e.changeMap(this.map)}detachChildrenFromMap(t){if(this.map)for(const e of t)e.changeMap(null)}observeMarkers(){this.markerObserverSet||(this.addEventListener("selector-items-changed",(()=>{this.updateMarkers()})),this.markerObserverSet=!0)}updateMarkers(){var t;this.observeMarkers();const e=this.shadowRoot.getElementById("markers-selector");if(!e)return;const i=e.items;if(this.markers&&i.length===this.markers.length){const t=i.filter((t=>this.markers&&-1===this.markers.indexOf(t)));if(0===t.length)return}const s=this.checkBoundsChanged(this.markers,i),o=(null===(t=this.markers)||void 0===t?void 0:t.filter((t=>-1===i.indexOf(t))))||[];this.detachChildrenFromMap(o),this.markers=i,this.attachChildrenToMap(this.markers),this.fitToMarkers&&s&&this.fitToMarkersChanged()}updateShapes(){const t=this.shadowRoot.getElementById("shapes-selector");if(t){this.shapes=t.items;for(const t of this.shapes)t.attachToMap(this.map)}}fitToMarkersChanged(t=0){if(this.map&&this.fitToMarkers&&this.markers.length>0){const e=new google.maps.LatLngBounds;for(const t of this.markers)e.extend(new google.maps.LatLng(t.latitude,t.longitude));const i=this.getBoundingClientRect();if(0===i.width||0===i.height){console.log("Invalid DOM width or height for lit-google-map");return void setTimeout((()=>{this.fitToMarkersChanged(t+1)}),2**t*100)}this.markers.length>1&&this.map.fitBounds(e,0),this.map.setCenter(e.getCenter())}}checkBoundsChanged(t,e){const i=e.filter((e=>!t||!t.includes(e))),s=null==t?void 0:t.filter((t=>!e||!e.includes(t)));return i.length>0||s.length>0}deselectMarker(t){}deselectShape(t){}render(){return D` + */,ct={attribute:!0,type:String,converter:$,reflect:!1,hasChanged:C},pt=(t=ct,e,i)=>{const{kind:s,metadata:o}=i;let r=globalThis.litPropertyMetadata.get(o);if(void 0===r&&globalThis.litPropertyMetadata.set(o,r=new Map),"setter"===s&&((t=Object.create(t)).wrapped=!0),r.set(i.name,t),"accessor"===s){const{name:s}=i;return{set(i){const o=e.get.call(this);e.set.call(this,i),this.requestUpdate(s,o,t)},init(e){return void 0!==e&&this.C(s,void 0,t,e),e}}}if("setter"===s){const{name:s}=i;return function(i){const o=this[s];e.call(this,i),this.requestUpdate(s,o,t)}}throw Error("Unsupported decorator location: "+s)};function dt(t){return(e,i)=>"object"==typeof i?pt(t,e,i):((t,e,i)=>{const s=e.hasOwnProperty(i);return e.constructor.createProperty(i,t),s?Object.getOwnPropertyDescriptor(e,i):void 0})(t,e,i)}t.LitGoogleMap=class extends at{constructor(){super(...arguments),this.apiKey="",this.version="3.48",this.styles={},this.zoom=8,this.fitToMarkers=!1,this.mapType="roadmap",this.centerLatitude=-34.397,this.centerLongitude=150.644,this.language="",this.mapId="DEMO_MAP_ID",this.map=null}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),this.map&&e!==i&&null!==i&&("center-latitude"===t||"center-longitude"===t?this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude}):"zoom"===t&&this.map.setZoom(this.zoom))}dispatchViewChanged(){this.dispatchEvent(new CustomEvent("view_changed",{detail:{center:this.map.getCenter().toJSON(),zoom:this.map.getZoom()},bubbles:!0,composed:!0}))}initGMap(){if(null!=this.map)return;const t=this.shadowRoot.getElementById("api");null!=t&&!0===t.libraryLoaded&&(this.map=new google.maps.Map(this.shadowRoot.getElementById("map"),this.getMapOptions()),this.map.addListener("bounds_changed",(()=>{this.dispatchEvent(new CustomEvent("bounds_changed",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("tilesloaded",(()=>{this.dispatchEvent(new CustomEvent("tilesloaded",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("center_changed",(()=>{this.dispatchEvent(new CustomEvent("center_changed",{detail:this.map.getCenter().toJSON(),bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("zoom_changed",(()=>{this.dispatchEvent(new CustomEvent("zoom_changed",{detail:{zoom:this.map.getZoom()},bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("click",(t=>{"placeId"in t&&(t.stop(),this.dispatchEvent(new CustomEvent("place_click",{detail:{placeId:t.placeId},bubbles:!0,composed:!0})))})),this.updateMarkers(),this.updateShapes(),this.updateControls())}getMapOptions(){return{zoom:this.zoom,center:{lat:this.centerLatitude,lng:this.centerLongitude},mapTypeId:this.mapType,styles:this.styles,mapId:this.mapId}}mapApiLoaded(){this.initGMap()}connectedCallback(){super.connectedCallback(),this.initGMap()}updated(t){super.updated(t),this.map?((t.has("centerLatitude")||t.has("centerLongitude"))&&(t.get("centerLatitude"),t.get("centerLongitude"),this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude})),t.has("zoom")&&(t.get("zoom"),this.map.setZoom(this.zoom))):console.log("Map not initialized yet, skipping update")}attachChildrenToMap(t){if(this.map)for(const e of t)e.changeMap(this.map)}detachChildrenFromMap(t){if(this.map)for(const e of t)e.changeMap(null)}observeMarkers(){this.markerObserverSet||(this.addEventListener("selector-items-changed",(()=>{this.updateMarkers()})),this.markerObserverSet=!0)}updateMarkers(){var t;this.observeMarkers();const e=this.shadowRoot.getElementById("markers-selector");if(!e)return;const i=e.items;if(this.markers&&i.length===this.markers.length){const t=i.filter((t=>this.markers&&-1===this.markers.indexOf(t)));if(0===t.length)return}const s=this.checkBoundsChanged(this.markers,i),o=(null===(t=this.markers)||void 0===t?void 0:t.filter((t=>-1===i.indexOf(t))))||[];this.detachChildrenFromMap(o),this.markers=i,this.attachChildrenToMap(this.markers),this.fitToMarkers&&s&&this.fitToMarkersChanged()}updateShapes(){const t=this.shadowRoot.getElementById("shapes-selector");if(t){this.shapes=t.items;for(const t of this.shapes)t.attachToMap(this.map)}}updateControls(){const t=this.shadowRoot.getElementById("controls-selector");if(t){this.controls=t.items;for(const t of this.controls)t.changeMap(this.map)}}fitToMarkersChanged(t=0){if(this.map&&this.fitToMarkers&&this.markers.length>0){const e=new google.maps.LatLngBounds;for(const t of this.markers)e.extend(new google.maps.LatLng(t.latitude,t.longitude));const i=this.getBoundingClientRect();if(0===i.width||0===i.height){console.log("Invalid DOM width or height for lit-google-map");return void setTimeout((()=>{this.fitToMarkersChanged(t+1)}),2**t*100)}this.markers.length>1&&this.map.fitBounds(e,0),this.map.setCenter(e.getCenter())}}checkBoundsChanged(t,e){const i=e.filter((e=>!t||!t.includes(e))),s=null==t?void 0:t.filter((t=>!e||!e.includes(t)));return i.length>0||s.length>0}deselectMarker(t){}deselectShape(t){}render(){return D` (e,i)=>{void 0!==i?i.addInitializer((()=>{customElements.define(t,e) > + + +
`}},t.LitGoogleMap.styles=((t,...e)=>{const i=1===t.length?t[0]:e.reduce(((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1]),t[0]);return new a(i,t,r)})` #map { width: 100%; height: 100%; } - `,e([dt({type:String,attribute:"api-key"}),i("design:type",Object)],t.LitGoogleMap.prototype,"apiKey",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMap.prototype,"version",void 0),e([dt({type:Object}),i("design:type",Object)],t.LitGoogleMap.prototype,"styles",void 0),e([dt({type:Number}),i("design:type",Object)],t.LitGoogleMap.prototype,"zoom",void 0),e([dt({type:Boolean,attribute:"fit-to-markers"}),i("design:type",Object)],t.LitGoogleMap.prototype,"fitToMarkers",void 0),e([dt({type:String,attribute:"map-type"}),i("design:type",Object)],t.LitGoogleMap.prototype,"mapType",void 0),e([dt({type:Number,attribute:"center-latitude"}),i("design:type",Object)],t.LitGoogleMap.prototype,"centerLatitude",void 0),e([dt({type:Number,attribute:"center-longitude"}),i("design:type",Object)],t.LitGoogleMap.prototype,"centerLongitude",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMap.prototype,"language",void 0),e([dt({type:String,attribute:"map-id"}),i("design:type",Object)],t.LitGoogleMap.prototype,"mapId",void 0),t.LitGoogleMap=e([ht("lit-google-map")],t.LitGoogleMap),t.LitGoogleMapCircle=class extends at{constructor(){super(...arguments),this.centerLatitude=-34.397,this.centerLongitude=150.644,this.radius=1e5,this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.circle=null}attributeChangedCallback(t,e,i){var s;switch(super.attributeChangedCallback(t,e,i),t){case"center-latitude":case"center-longitude":this.updateCenter();break;case"radius":null===(s=this.circle)||void 0===s||s.setRadius(this.radius)}}updateCenter(){var t;null===(t=this.circle)||void 0===t||t.setCenter(new google.maps.LatLng(this.centerLatitude,this.centerLongitude))}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.circle&&(this.circle.setMap(null),google.maps.event.clearInstanceListeners(this.circle)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.circle=new google.maps.Circle({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,center:{lat:this.centerLatitude,lng:this.centerLongitude},radius:this.radius})}},e([dt({type:Number,attribute:"center-latitude"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"centerLatitude",void 0),e([dt({type:Number,attribute:"center-longitude"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"centerLongitude",void 0),e([dt({type:Number}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"radius",void 0),e([dt({type:String,attribute:"fill-color"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"fillColor",void 0),e([dt({type:Number,attribute:"fill-opacity"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"fillOpacity",void 0),e([dt({type:String,attribute:"stroke-color"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeColor",void 0),e([dt({type:Number,attribute:"stroke-opacity"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeOpacity",void 0),e([dt({type:Number,attribute:"stroke-weight"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeWeight",void 0),t.LitGoogleMapCircle=e([ht("lit-google-map-circle")],t.LitGoogleMapCircle),t.LitGoogleMapMarker=class extends at{constructor(){super(...arguments),this.latitude=0,this.longitude=0,this.zIndex=0,this.open=!1,this.id=null,this.glyph=null,this.glyphColor=null,this.background=null,this.borderColor=null,this.scale=null,this.map=null,this.marker=null,this.pin=null}attributeChangedCallback(t,e,i){switch(super.attributeChangedCallback(t,e,i),t){case"open":this.openChanged();break;case"latitude":case"longitude":this.updatePosition();break;case"glyph":this.pin&&(this.pin.glyph=this.glyph);break;case"glyphColor":this.pin&&(this.pin.glyphColor=this.glyphColor);break;case"background":this.pin&&(this.pin.background=this.background);break;case"borderColor":this.pin&&(this.pin.borderColor=this.borderColor);break;case"scale":this.pin&&(this.pin.scale=this.scale);break;case"z-index":this.marker&&(this.marker.zIndex=this.zIndex)}}openChanged(){this.info&&(this.open?(this.info.open(this.map,this.marker),this.dispatchEvent(new CustomEvent("google-map-marker-open",{bubbles:!0}))):(this.info.close(),this.dispatchEvent(new CustomEvent("google-map-marker-close",{bubbles:!0}))))}updatePosition(){this.marker&&(this.marker.position=new google.maps.LatLng(this.latitude,this.longitude))}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.marker&&(this.marker.map=null,google.maps.event.clearInstanceListeners(this.marker)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.pin=new google.maps.marker.PinElement({glyph:this.glyph,glyphColor:this.glyphColor,background:this.background,borderColor:this.borderColor,scale:this.scale}),this.marker=new google.maps.marker.AdvancedMarkerElement({map:this.map,position:{lat:this.latitude,lng:this.longitude},content:this.pin.element,zIndex:this.zIndex,gmpClickable:!0}),this.marker.element.addEventListener("mouseover",(()=>{this.dispatchEvent(new CustomEvent("mouseover",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.element.addEventListener("mouseout",(()=>{this.dispatchEvent(new CustomEvent("mouseout",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.addListener("click",(()=>{this.dispatchEvent(new CustomEvent("click",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.contentChanged()}contentChanged(){this.contentObserver&&this.contentObserver.disconnect(),this.contentObserver=new MutationObserver(this.contentChanged.bind(this)),this.contentObserver.observe(this,{childList:!0,subtree:!0});const t=this.innerHTML.trim();t?(this.info||(this.info=new google.maps.InfoWindow,this.openInfoHandler=google.maps.event.addListener(this.marker,"click",function(){this.open=!0}.bind(this)),this.closeInfoHandler=google.maps.event.addListener(this.info,"closeclick",function(){this.open=!1}.bind(this))),this.info.setContent(t)):this.info&&(google.maps.event.removeListener(this.openInfoHandler),google.maps.event.removeListener(this.closeInfoHandler),this.info=null)}},e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"latitude",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"longitude",void 0),e([dt({type:Number,reflect:!0,attribute:"z-index"}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"zIndex",void 0),e([dt({type:Boolean,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"open",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"id",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"glyph",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"glyphColor",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"background",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"borderColor",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Number)],t.LitGoogleMapMarker.prototype,"scale",void 0),t.LitGoogleMapMarker=e([ht("lit-google-map-marker")],t.LitGoogleMapMarker),t.LitGoogleMapPolygon=class extends at{constructor(){super(...arguments),this.paths=[],this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.polygon=null}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.polygon&&(this.polygon.setMap(null),google.maps.event.clearInstanceListeners(this.polygon)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.polygon=new google.maps.Polygon({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,paths:this.paths})}},e([dt({type:Array}),i("design:type",Array)],t.LitGoogleMapPolygon.prototype,"paths",void 0),e([dt({type:String,attribute:"fill-color"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"fillColor",void 0),e([dt({type:Number,attribute:"fill-opacity"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"fillOpacity",void 0),e([dt({type:String,attribute:"stroke-color"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeColor",void 0),e([dt({type:Number,attribute:"stroke-opacity"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeOpacity",void 0),e([dt({type:Number,attribute:"stroke-weight"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeWeight",void 0),t.LitGoogleMapPolygon=e([ht("lit-google-map-polygon")],t.LitGoogleMapPolygon);class ut{constructor(){this.apiMap={}}require(t,e,i){const s=this.nameFromUrl(t);this.apiMap[s]||(this.apiMap[s]=new gt(s,t,i)),this.apiMap[s].requestNotify(e)}static getInstance(){return ut.instance||(ut.instance=new ut),ut.instance}nameFromUrl(t){return`${t.replace(/[:/%?&.=\-,]/g,"_")}_api`}}class gt{constructor(t,e,i){this.callbackMacro="%%callback%%",this.loaded=!1,this.script=null,this.notifiers=[];let s=e,o=i;if(!o){if(!(s.indexOf(this.callbackMacro)>=0))return void console.error("ScriptLoader class: a %%callback%% parameter is required in libraryUrl");o=`${t}_loaded`,s=s.replace(this.callbackMacro,o)}this.callbackName=o,window[this.callbackName]=this.success.bind(this),this.addScript(s)}addScript(t){const e=document.createElement("script");e.src=t,e.onerror=this.handleError.bind(this);const i=document.querySelector("script")||document.body;i.parentNode.insertBefore(e,i),this.script=e}removeScript(){this.script.parentNode&&this.script.parentNode.removeChild(this.script),this.script=null}handleError(t){this.error=new Error("Library failed to load"),this.notifyAll(),this.cleanup()}success(...t){this.loaded=!0,this.result=t,this.notifyAll(),this.cleanup()}cleanup(){delete window[this.callbackName]}notifyAll(){this.notifiers.forEach(function(t){t(this.error,this.result)}.bind(this)),this.notifiers=[]}requestNotify(t){this.loaded||this.error?t(this.error,this.result):this.notifiers.push(t)}}class mt extends at{constructor(){super(...arguments),this.libraryLoaded=!1,this.libraryErrorMessage=null,this.isReady=!1}get callbackName(){return null}libraryUrlChanged(){this.isReady&&null!=this.libraryUrl&&this.loadLibrary()}libraryLoadCallback(t,e){t?(console.warn("Library load failed:",t.message),this.libraryErrorMessage=t.message):(this.libraryErrorMessage=null,this.libraryLoaded=!0,null!=this.notifyEvent&&this.dispatchEvent(new CustomEvent(this.notifyEvent,{detail:e,composed:!0})))}loadLibrary(){ut.getInstance().require(this.libraryUrl,this.libraryLoadCallback.bind(this),this.callbackName)}connectedCallback(){super.connectedCallback(),this.isReady=!0,null!=this.libraryUrl&&this.loadLibrary()}}t.LitGoogleMapsApi=class extends mt{constructor(){super(...arguments),this.apiKey="",this.clientId="",this.mapsUrl="https://maps.googleapis.com/maps/api/js?callback=%%callback%%",this.version="3.39",this.language="",this.mapId=""}get libraryUrl(){return this.computeUrl(this.mapsUrl,this.version,this.apiKey,this.clientId,this.language,this.mapId)}get notifyEvent(){return"api-load"}computeUrl(t,e,i,s,o,r){let n=`${t}&v=${e}`;if(n+="&libraries=drawing,geometry,places,visualization,marker",i&&!s&&(n+=`&key=${i}`),s&&(n+=`&client=${s}`),!i&&!s){const t="No Google Maps API Key or Client ID specified. See https://developers.google.com/maps/documentation/javascript/get-api-key for instructions to get started with a key or client id.";console.warn(t)}return o&&(n+=`&language=${o}`),r&&(n+=`&map_ids=${r}`),n}},e([dt({type:String,attribute:"api-key"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"apiKey",void 0),e([dt({type:String,attribute:"client-id"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"clientId",void 0),e([dt({type:String,attribute:"maps-url"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"mapsUrl",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"version",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"language",void 0),e([dt({type:String,attribute:"map-id"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"mapId",void 0),t.LitGoogleMapsApi=e([ht("lit-google-maps-api")],t.LitGoogleMapsApi);class yt{constructor(t){this.multi=!1,this.selection=[],this.selectCallback=t}get(){return this.multi?this.selection.slice():this.selection[0]}clear(t){for(const e of this.selection.slice())(!t||t.indexOf(e)<0)&&this.setItemSelected(e,!1)}isSelected(t){return this.selection.indexOf(t)>=0}setItemSelected(t,e){if(null!=t&&e!==this.isSelected(t)){if(e)this.selection.push(t);else{const e=this.selection.indexOf(t);e>=0&&this.selection.splice(e,1)}this.selectCallback&&this.selectCallback(t,e)}}select(t){this.multi?this.toggle(t):this.get()!==t&&(this.setItemSelected(this.get(),!1),this.setItemSelected(t,!0))}toggle(t){this.setItemSelected(t,!this.isSelected(t))}}return t.LitSelector=class extends at{constructor(){super(...arguments),this.activateEvent="tap",this.selectedAttribute=null,this.selected=null,this._selection=new yt(((t,e)=>this.applySelection(t,e))),this._items=[]}get items(){return this._items}connectedCallback(){super.connectedCallback(),this.addEventListener("slotchange",(t=>{t.stopPropagation(),this.updateItems(),this.dispatchEvent(new CustomEvent("selector-items-changed",{detail:{},composed:!0}))})),this.addListener(this.activateEvent)}disconnectedCallback(){super.disconnectedCallback(),this.removeListener(this.activateEvent)}attributeChangedCallback(t,e,i){if(super.attributeChangedCallback(t,e,i),"selected"===t)this.updateSelected()}applySelection(t,e){this.selectedAttribute&&t instanceof Element&&e!==t.hasAttribute(this.selectedAttribute)&&t.toggleAttribute(this.selectedAttribute)}updateItems(){var t;const e=this.querySelector("slot");this._items=null!==(t=null==e?void 0:e.assignedNodes())&&void 0!==t?t:[]}addListener(t){this.addEventListener(t,(t=>this.activateHandler(t)))}removeListener(t){this.removeEventListener(t,(t=>this.activateHandler(t)))}activateHandler(t){let e=t.target;const i=this.items;for(;e&&e!==this;){const t=i.indexOf(e);if(t>=0){const i=this.indexToValue(t);return void this.itemActivate(i,e)}e=e.parentNode}}itemActivate(t,e){this.dispatchEvent(new CustomEvent("selector-item-activate",{detail:{selected:t,item:e},composed:!0,cancelable:!0}))&&this.select(t)}select(t){this.selected=t}updateSelected(){this.selectSelected(this.selected)}selectSelected(t){if(!this._items)return;const e=this.valueToItem(this.selected);e?this._selection.select(e):this._selection.clear()}valueToItem(t){return null==t?null:this._items[this.valueToIndex(t)]}valueToIndex(t){return Number(t)}indexToValue(t){return t}indexOf(t){return this._items?this._items.indexOf(t):-1}},e([dt({type:String,attribute:"activate-event"}),i("design:type",Object)],t.LitSelector.prototype,"activateEvent",void 0),e([dt({type:String,attribute:"selected-attribute"}),i("design:type",String)],t.LitSelector.prototype,"selectedAttribute",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitSelector.prototype,"selected",void 0),t.LitSelector=e([ht("lit-selector")],t.LitSelector),t}({}); + `,e([dt({type:String,attribute:"api-key"}),i("design:type",Object)],t.LitGoogleMap.prototype,"apiKey",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMap.prototype,"version",void 0),e([dt({type:Object}),i("design:type",Object)],t.LitGoogleMap.prototype,"styles",void 0),e([dt({type:Number}),i("design:type",Object)],t.LitGoogleMap.prototype,"zoom",void 0),e([dt({type:Boolean,attribute:"fit-to-markers"}),i("design:type",Object)],t.LitGoogleMap.prototype,"fitToMarkers",void 0),e([dt({type:String,attribute:"map-type"}),i("design:type",Object)],t.LitGoogleMap.prototype,"mapType",void 0),e([dt({type:Number,attribute:"center-latitude"}),i("design:type",Object)],t.LitGoogleMap.prototype,"centerLatitude",void 0),e([dt({type:Number,attribute:"center-longitude"}),i("design:type",Object)],t.LitGoogleMap.prototype,"centerLongitude",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMap.prototype,"language",void 0),e([dt({type:String,attribute:"map-id"}),i("design:type",Object)],t.LitGoogleMap.prototype,"mapId",void 0),t.LitGoogleMap=e([ht("lit-google-map")],t.LitGoogleMap),t.LitGoogleMapCircle=class extends at{constructor(){super(...arguments),this.centerLatitude=-34.397,this.centerLongitude=150.644,this.radius=1e5,this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.circle=null}attributeChangedCallback(t,e,i){var s;switch(super.attributeChangedCallback(t,e,i),t){case"center-latitude":case"center-longitude":this.updateCenter();break;case"radius":null===(s=this.circle)||void 0===s||s.setRadius(this.radius)}}updateCenter(){var t;null===(t=this.circle)||void 0===t||t.setCenter(new google.maps.LatLng(this.centerLatitude,this.centerLongitude))}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.circle&&(this.circle.setMap(null),google.maps.event.clearInstanceListeners(this.circle)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.circle=new google.maps.Circle({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,center:{lat:this.centerLatitude,lng:this.centerLongitude},radius:this.radius})}},e([dt({type:Number,attribute:"center-latitude"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"centerLatitude",void 0),e([dt({type:Number,attribute:"center-longitude"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"centerLongitude",void 0),e([dt({type:Number}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"radius",void 0),e([dt({type:String,attribute:"fill-color"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"fillColor",void 0),e([dt({type:Number,attribute:"fill-opacity"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"fillOpacity",void 0),e([dt({type:String,attribute:"stroke-color"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeColor",void 0),e([dt({type:Number,attribute:"stroke-opacity"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeOpacity",void 0),e([dt({type:Number,attribute:"stroke-weight"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeWeight",void 0),t.LitGoogleMapCircle=e([ht("lit-google-map-circle")],t.LitGoogleMapCircle),t.LitGoogleMapLocationButton=class extends at{constructor(){super(...arguments),this.position="RIGHT_BOTTOM",this.label="My Location",this.disabled=!1,this.map=null,this.controlDiv=null,this.controlButton=null,this.isRequesting=!1}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.controlDiv&&this.map&&(this.controlDiv=null,this.controlButton=null),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.controlDiv=this.createControlButton();const t=google.maps.ControlPosition[this.position];void 0!==t&&this.map.controls[t].push(this.controlDiv)}createControlButton(){const t=document.createElement("div");t.style.margin="10px";const e=document.createElement("button");return e.type="button",e.title=this.label,e.setAttribute("aria-label",this.label),e.innerHTML='\n \n \n \n ',Object.assign(e.style,{backgroundColor:"#fff",border:"0",borderRadius:"2px",boxShadow:"0 1px 4px rgba(0,0,0,0.3)",cursor:"pointer",padding:"10px",display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",color:"#666"}),e.addEventListener("mouseenter",(()=>{this.disabled||this.isRequesting||(e.style.backgroundColor="#f8f8f8")})),e.addEventListener("mouseleave",(()=>{this.disabled||this.isRequesting||(e.style.backgroundColor="#fff")})),e.addEventListener("click",(()=>{this.disabled||this.isRequesting||this.handleLocationRequest()})),this.controlButton=e,t.appendChild(e),t}async handleLocationRequest(){if(navigator.geolocation){this.isRequesting=!0,this.setLoadingState(!0),this.dispatchEvent(new CustomEvent("location-requested",{bubbles:!0,composed:!0}));try{const t=await this.getCurrentPosition(),e=t.coords.latitude,i=t.coords.longitude;this.map.setCenter({lat:e,lng:i}),this.map.setZoom(14),this.dispatchEvent(new CustomEvent("location-found",{detail:{lat:e,lng:i},bubbles:!0,composed:!0}))}catch(t){let e="Unable to retrieve your location",i=-1;t instanceof GeolocationPositionError&&(i=t.code,t.code===t.PERMISSION_DENIED?e="Location access denied. Please enable location permissions.":t.code===t.TIMEOUT?e="Location request timed out. Please try again.":t.code===t.POSITION_UNAVAILABLE&&(e="Location information is unavailable.")),this.dispatchEvent(new CustomEvent("location-error",{detail:{code:i,message:e},bubbles:!0,composed:!0}))}finally{this.isRequesting=!1,this.setLoadingState(!1)}}else this.dispatchEvent(new CustomEvent("location-error",{detail:{code:-1,message:"Geolocation is not supported by your browser"},bubbles:!0,composed:!0}))}getCurrentPosition(){return new Promise(((t,e)=>{navigator.geolocation.getCurrentPosition(t,e,{timeout:1e4,enableHighAccuracy:!0})}))}setLoadingState(t){if(this.controlButton)if(t){this.controlButton.style.backgroundColor="#f0f0f0",this.controlButton.style.cursor="wait";const t=this.controlButton.querySelector("svg");if(t){t.style.animation="spin 1s linear infinite";const e=document.createElement("style");e.textContent="\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n ",document.querySelector("style[data-location-button-spin]")||(e.setAttribute("data-location-button-spin","true"),document.head.appendChild(e))}}else{this.controlButton.style.backgroundColor="#fff",this.controlButton.style.cursor="pointer";const t=this.controlButton.querySelector("svg");t&&(t.style.animation="")}}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),"disabled"===t&&this.controlButton&&(this.disabled?(this.controlButton.style.backgroundColor="#f0f0f0",this.controlButton.style.cursor="not-allowed",this.controlButton.style.opacity="0.6"):(this.controlButton.style.backgroundColor="#fff",this.controlButton.style.cursor="pointer",this.controlButton.style.opacity="1"))}},e([dt({type:String,reflect:!0}),i("design:type",Object)],t.LitGoogleMapLocationButton.prototype,"position",void 0),e([dt({type:String,reflect:!0}),i("design:type",Object)],t.LitGoogleMapLocationButton.prototype,"label",void 0),e([dt({type:Boolean,reflect:!0}),i("design:type",Object)],t.LitGoogleMapLocationButton.prototype,"disabled",void 0),t.LitGoogleMapLocationButton=e([ht("lit-google-map-location-button")],t.LitGoogleMapLocationButton),t.LitGoogleMapMarker=class extends at{constructor(){super(...arguments),this.latitude=0,this.longitude=0,this.zIndex=0,this.open=!1,this.id=null,this.glyph=null,this.glyphColor=null,this.background=null,this.borderColor=null,this.scale=null,this.map=null,this.marker=null,this.pin=null}attributeChangedCallback(t,e,i){switch(super.attributeChangedCallback(t,e,i),t){case"open":this.openChanged();break;case"latitude":case"longitude":this.updatePosition();break;case"glyph":this.pin&&(this.pin.glyph=this.glyph);break;case"glyphColor":this.pin&&(this.pin.glyphColor=this.glyphColor);break;case"background":this.pin&&(this.pin.background=this.background);break;case"borderColor":this.pin&&(this.pin.borderColor=this.borderColor);break;case"scale":this.pin&&(this.pin.scale=this.scale);break;case"z-index":this.marker&&(this.marker.zIndex=this.zIndex)}}openChanged(){this.info&&(this.open?(this.info.open(this.map,this.marker),this.dispatchEvent(new CustomEvent("google-map-marker-open",{bubbles:!0}))):(this.info.close(),this.dispatchEvent(new CustomEvent("google-map-marker-close",{bubbles:!0}))))}updatePosition(){this.marker&&(this.marker.position=new google.maps.LatLng(this.latitude,this.longitude))}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.marker&&(this.marker.map=null,google.maps.event.clearInstanceListeners(this.marker)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.pin=new google.maps.marker.PinElement({glyph:this.glyph,glyphColor:this.glyphColor,background:this.background,borderColor:this.borderColor,scale:this.scale}),this.marker=new google.maps.marker.AdvancedMarkerElement({map:this.map,position:{lat:this.latitude,lng:this.longitude},content:this.pin.element,zIndex:this.zIndex,gmpClickable:!0}),this.marker.element.addEventListener("mouseover",(()=>{this.dispatchEvent(new CustomEvent("mouseover",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.element.addEventListener("mouseout",(()=>{this.dispatchEvent(new CustomEvent("mouseout",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.addListener("click",(()=>{this.dispatchEvent(new CustomEvent("click",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.contentChanged()}contentChanged(){this.contentObserver&&this.contentObserver.disconnect(),this.contentObserver=new MutationObserver(this.contentChanged.bind(this)),this.contentObserver.observe(this,{childList:!0,subtree:!0});const t=this.innerHTML.trim();t?(this.info||(this.info=new google.maps.InfoWindow,this.openInfoHandler=google.maps.event.addListener(this.marker,"click",function(){this.open=!0}.bind(this)),this.closeInfoHandler=google.maps.event.addListener(this.info,"closeclick",function(){this.open=!1}.bind(this))),this.info.setContent(t)):this.info&&(google.maps.event.removeListener(this.openInfoHandler),google.maps.event.removeListener(this.closeInfoHandler),this.info=null)}},e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"latitude",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"longitude",void 0),e([dt({type:Number,reflect:!0,attribute:"z-index"}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"zIndex",void 0),e([dt({type:Boolean,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"open",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"id",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"glyph",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"glyphColor",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"background",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"borderColor",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Number)],t.LitGoogleMapMarker.prototype,"scale",void 0),t.LitGoogleMapMarker=e([ht("lit-google-map-marker")],t.LitGoogleMapMarker),t.LitGoogleMapPolygon=class extends at{constructor(){super(...arguments),this.paths=[],this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.polygon=null}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.polygon&&(this.polygon.setMap(null),google.maps.event.clearInstanceListeners(this.polygon)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.polygon=new google.maps.Polygon({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,paths:this.paths})}},e([dt({type:Array}),i("design:type",Array)],t.LitGoogleMapPolygon.prototype,"paths",void 0),e([dt({type:String,attribute:"fill-color"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"fillColor",void 0),e([dt({type:Number,attribute:"fill-opacity"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"fillOpacity",void 0),e([dt({type:String,attribute:"stroke-color"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeColor",void 0),e([dt({type:Number,attribute:"stroke-opacity"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeOpacity",void 0),e([dt({type:Number,attribute:"stroke-weight"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeWeight",void 0),t.LitGoogleMapPolygon=e([ht("lit-google-map-polygon")],t.LitGoogleMapPolygon);class ut{constructor(){this.apiMap={}}require(t,e,i){const s=this.nameFromUrl(t);this.apiMap[s]||(this.apiMap[s]=new gt(s,t,i)),this.apiMap[s].requestNotify(e)}static getInstance(){return ut.instance||(ut.instance=new ut),ut.instance}nameFromUrl(t){return`${t.replace(/[:/%?&.=\-,]/g,"_")}_api`}}class gt{constructor(t,e,i){this.callbackMacro="%%callback%%",this.loaded=!1,this.script=null,this.notifiers=[];let s=e,o=i;if(!o){if(!(s.indexOf(this.callbackMacro)>=0))return void console.error("ScriptLoader class: a %%callback%% parameter is required in libraryUrl");o=`${t}_loaded`,s=s.replace(this.callbackMacro,o)}this.callbackName=o,window[this.callbackName]=this.success.bind(this),this.addScript(s)}addScript(t){const e=document.createElement("script");e.src=t,e.onerror=this.handleError.bind(this);const i=document.querySelector("script")||document.body;i.parentNode.insertBefore(e,i),this.script=e}removeScript(){this.script.parentNode&&this.script.parentNode.removeChild(this.script),this.script=null}handleError(t){this.error=new Error("Library failed to load"),this.notifyAll(),this.cleanup()}success(...t){this.loaded=!0,this.result=t,this.notifyAll(),this.cleanup()}cleanup(){delete window[this.callbackName]}notifyAll(){this.notifiers.forEach(function(t){t(this.error,this.result)}.bind(this)),this.notifiers=[]}requestNotify(t){this.loaded||this.error?t(this.error,this.result):this.notifiers.push(t)}}class mt extends at{constructor(){super(...arguments),this.libraryLoaded=!1,this.libraryErrorMessage=null,this.isReady=!1}get callbackName(){return null}libraryUrlChanged(){this.isReady&&null!=this.libraryUrl&&this.loadLibrary()}libraryLoadCallback(t,e){t?(console.warn("Library load failed:",t.message),this.libraryErrorMessage=t.message):(this.libraryErrorMessage=null,this.libraryLoaded=!0,null!=this.notifyEvent&&this.dispatchEvent(new CustomEvent(this.notifyEvent,{detail:e,composed:!0})))}loadLibrary(){ut.getInstance().require(this.libraryUrl,this.libraryLoadCallback.bind(this),this.callbackName)}connectedCallback(){super.connectedCallback(),this.isReady=!0,null!=this.libraryUrl&&this.loadLibrary()}}t.LitGoogleMapsApi=class extends mt{constructor(){super(...arguments),this.apiKey="",this.clientId="",this.mapsUrl="https://maps.googleapis.com/maps/api/js?callback=%%callback%%",this.version="3.39",this.language="",this.mapId=""}get libraryUrl(){return this.computeUrl(this.mapsUrl,this.version,this.apiKey,this.clientId,this.language,this.mapId)}get notifyEvent(){return"api-load"}computeUrl(t,e,i,s,o,r){let n=`${t}&v=${e}`;if(n+="&libraries=drawing,geometry,places,visualization,marker",i&&!s&&(n+=`&key=${i}`),s&&(n+=`&client=${s}`),!i&&!s){const t="No Google Maps API Key or Client ID specified. See https://developers.google.com/maps/documentation/javascript/get-api-key for instructions to get started with a key or client id.";console.warn(t)}return o&&(n+=`&language=${o}`),r&&(n+=`&map_ids=${r}`),n}},e([dt({type:String,attribute:"api-key"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"apiKey",void 0),e([dt({type:String,attribute:"client-id"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"clientId",void 0),e([dt({type:String,attribute:"maps-url"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"mapsUrl",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"version",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"language",void 0),e([dt({type:String,attribute:"map-id"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"mapId",void 0),t.LitGoogleMapsApi=e([ht("lit-google-maps-api")],t.LitGoogleMapsApi);class yt{constructor(t){this.multi=!1,this.selection=[],this.selectCallback=t}get(){return this.multi?this.selection.slice():this.selection[0]}clear(t){for(const e of this.selection.slice())(!t||t.indexOf(e)<0)&&this.setItemSelected(e,!1)}isSelected(t){return this.selection.indexOf(t)>=0}setItemSelected(t,e){if(null!=t&&e!==this.isSelected(t)){if(e)this.selection.push(t);else{const e=this.selection.indexOf(t);e>=0&&this.selection.splice(e,1)}this.selectCallback&&this.selectCallback(t,e)}}select(t){this.multi?this.toggle(t):this.get()!==t&&(this.setItemSelected(this.get(),!1),this.setItemSelected(t,!0))}toggle(t){this.setItemSelected(t,!this.isSelected(t))}}return t.LitSelector=class extends at{constructor(){super(...arguments),this.activateEvent="tap",this.selectedAttribute=null,this.selected=null,this._selection=new yt(((t,e)=>this.applySelection(t,e))),this._items=[]}get items(){return this._items}connectedCallback(){super.connectedCallback(),this.addEventListener("slotchange",(t=>{t.stopPropagation(),this.updateItems(),this.dispatchEvent(new CustomEvent("selector-items-changed",{detail:{},composed:!0}))})),this.addListener(this.activateEvent)}disconnectedCallback(){super.disconnectedCallback(),this.removeListener(this.activateEvent)}attributeChangedCallback(t,e,i){if(super.attributeChangedCallback(t,e,i),"selected"===t)this.updateSelected()}applySelection(t,e){this.selectedAttribute&&t instanceof Element&&e!==t.hasAttribute(this.selectedAttribute)&&t.toggleAttribute(this.selectedAttribute)}updateItems(){var t;const e=this.querySelector("slot");this._items=null!==(t=null==e?void 0:e.assignedNodes())&&void 0!==t?t:[]}addListener(t){this.addEventListener(t,(t=>this.activateHandler(t)))}removeListener(t){this.removeEventListener(t,(t=>this.activateHandler(t)))}activateHandler(t){let e=t.target;const i=this.items;for(;e&&e!==this;){const t=i.indexOf(e);if(t>=0){const i=this.indexToValue(t);return void this.itemActivate(i,e)}e=e.parentNode}}itemActivate(t,e){this.dispatchEvent(new CustomEvent("selector-item-activate",{detail:{selected:t,item:e},composed:!0,cancelable:!0}))&&this.select(t)}select(t){this.selected=t}updateSelected(){this.selectSelected(this.selected)}selectSelected(t){if(!this._items)return;const e=this.valueToItem(this.selected);e?this._selection.select(e):this._selection.clear()}valueToItem(t){return null==t?null:this._items[this.valueToIndex(t)]}valueToIndex(t){return Number(t)}indexToValue(t){return t}indexOf(t){return this._items?this._items.indexOf(t):-1}},e([dt({type:String,attribute:"activate-event"}),i("design:type",Object)],t.LitSelector.prototype,"activateEvent",void 0),e([dt({type:String,attribute:"selected-attribute"}),i("design:type",String)],t.LitSelector.prototype,"selectedAttribute",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitSelector.prototype,"selected",void 0),t.LitSelector=e([ht("lit-selector")],t.LitSelector),t}({}); diff --git a/dist/lit-google-map.esm.js b/dist/lit-google-map.esm.js index 1141b9b..f7431e2 100644 --- a/dist/lit-google-map.esm.js +++ b/dist/lit-google-map.esm.js @@ -92,6 +92,7 @@ let LitGoogleMap = class LitGoogleMap extends LitElement { }); this.updateMarkers(); this.updateShapes(); + this.updateControls(); } getMapOptions() { return { @@ -186,6 +187,15 @@ let LitGoogleMap = class LitGoogleMap extends LitElement { s.attachToMap(this.map); } } + updateControls() { + const controlsSelector = this.shadowRoot.getElementById("controls-selector"); + if (!controlsSelector) + return; + this.controls = controlsSelector.items; + for (const c of this.controls) { + c.changeMap(this.map); + } + } fitToMarkersChanged(retryAttempt = 0) { if (this.map && this.fitToMarkers && this.markers.length > 0) { const latLngBounds = new google.maps.LatLngBounds(); @@ -245,6 +255,13 @@ let LitGoogleMap = class LitGoogleMap extends LitElement { > + + +
`; } @@ -400,6 +417,210 @@ LitGoogleMapCircle = __decorate([ customElement("lit-google-map-circle") ], LitGoogleMapCircle); +let LitGoogleMapLocationButton = class LitGoogleMapLocationButton extends LitElement { + constructor() { + super(...arguments); + this.position = "RIGHT_BOTTOM"; + this.label = "My Location"; + this.disabled = false; + this.map = null; + this.controlDiv = null; + this.controlButton = null; + this.isRequesting = false; + } + changeMap(newMap) { + this.map = newMap; + this.mapChanged(); + } + mapChanged() { + if (this.controlDiv && this.map) { + this.controlDiv = null; + this.controlButton = null; + } + if (this.map && this.map instanceof google.maps.Map) { + this.mapReady(); + } + } + mapReady() { + this.controlDiv = this.createControlButton(); + const controlPosition = google.maps.ControlPosition[this.position]; + if (controlPosition !== undefined) { + this.map.controls[controlPosition].push(this.controlDiv); + } + } + createControlButton() { + const controlDiv = document.createElement("div"); + controlDiv.style.margin = "10px"; + const controlButton = document.createElement("button"); + controlButton.type = "button"; + controlButton.title = this.label; + controlButton.setAttribute("aria-label", this.label); + controlButton.innerHTML = ` + + + + `; + Object.assign(controlButton.style, { + backgroundColor: "#fff", + border: "0", + borderRadius: "2px", + boxShadow: "0 1px 4px rgba(0,0,0,0.3)", + cursor: "pointer", + padding: "10px", + display: "flex", + alignItems: "center", + justifyContent: "center", + width: "40px", + height: "40px", + color: "#666", + }); + controlButton.addEventListener("mouseenter", () => { + if (!this.disabled && !this.isRequesting) { + controlButton.style.backgroundColor = "#f8f8f8"; + } + }); + controlButton.addEventListener("mouseleave", () => { + if (!this.disabled && !this.isRequesting) { + controlButton.style.backgroundColor = "#fff"; + } + }); + controlButton.addEventListener("click", () => { + if (!this.disabled && !this.isRequesting) { + this.handleLocationRequest(); + } + }); + this.controlButton = controlButton; + controlDiv.appendChild(controlButton); + return controlDiv; + } + async handleLocationRequest() { + if (!navigator.geolocation) { + this.dispatchEvent(new CustomEvent("location-error", { + detail: { + code: -1, + message: "Geolocation is not supported by your browser", + }, + bubbles: true, + composed: true, + })); + return; + } + this.isRequesting = true; + this.setLoadingState(true); + this.dispatchEvent(new CustomEvent("location-requested", { + bubbles: true, + composed: true, + })); + try { + const position = await this.getCurrentPosition(); + const lat = position.coords.latitude; + const lng = position.coords.longitude; + this.map.setCenter({ lat, lng }); + this.map.setZoom(14); + this.dispatchEvent(new CustomEvent("location-found", { + detail: { lat, lng }, + bubbles: true, + composed: true, + })); + } + catch (error) { + let message = "Unable to retrieve your location"; + let code = -1; + if (error instanceof GeolocationPositionError) { + code = error.code; + if (error.code === error.PERMISSION_DENIED) { + message = + "Location access denied. Please enable location permissions."; + } + else if (error.code === error.TIMEOUT) { + message = "Location request timed out. Please try again."; + } + else if (error.code === error.POSITION_UNAVAILABLE) { + message = "Location information is unavailable."; + } + } + this.dispatchEvent(new CustomEvent("location-error", { + detail: { code, message }, + bubbles: true, + composed: true, + })); + } + finally { + this.isRequesting = false; + this.setLoadingState(false); + } + } + getCurrentPosition() { + return new Promise((resolve, reject) => { + navigator.geolocation.getCurrentPosition(resolve, reject, { + timeout: 10000, + enableHighAccuracy: true, + }); + }); + } + setLoadingState(loading) { + if (!this.controlButton) + return; + if (loading) { + this.controlButton.style.backgroundColor = "#f0f0f0"; + this.controlButton.style.cursor = "wait"; + const svg = this.controlButton.querySelector("svg"); + if (svg) { + svg.style.animation = "spin 1s linear infinite"; + const style = document.createElement("style"); + style.textContent = ` + @keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + `; + if (!document.querySelector("style[data-location-button-spin]")) { + style.setAttribute("data-location-button-spin", "true"); + document.head.appendChild(style); + } + } + } + else { + this.controlButton.style.backgroundColor = "#fff"; + this.controlButton.style.cursor = "pointer"; + const svg = this.controlButton.querySelector("svg"); + if (svg) { + svg.style.animation = ""; + } + } + } + attributeChangedCallback(name, oldval, newval) { + super.attributeChangedCallback(name, oldval, newval); + if (name === "disabled" && this.controlButton) { + if (this.disabled) { + this.controlButton.style.backgroundColor = "#f0f0f0"; + this.controlButton.style.cursor = "not-allowed"; + this.controlButton.style.opacity = "0.6"; + } + else { + this.controlButton.style.backgroundColor = "#fff"; + this.controlButton.style.cursor = "pointer"; + this.controlButton.style.opacity = "1"; + } + } + } +}; +__decorate([ + property({ type: String, reflect: true }), + __metadata("design:type", Object) +], LitGoogleMapLocationButton.prototype, "position", void 0); +__decorate([ + property({ type: String, reflect: true }), + __metadata("design:type", Object) +], LitGoogleMapLocationButton.prototype, "label", void 0); +__decorate([ + property({ type: Boolean, reflect: true }), + __metadata("design:type", Object) +], LitGoogleMapLocationButton.prototype, "disabled", void 0); +LitGoogleMapLocationButton = __decorate([ + customElement("lit-google-map-location-button") +], LitGoogleMapLocationButton); + let LitGoogleMapMarker = class LitGoogleMapMarker extends LitElement { constructor() { super(...arguments); @@ -1040,4 +1261,4 @@ LitSelector = __decorate([ customElement("lit-selector") ], LitSelector); -export { LitGoogleMap, LitGoogleMapCircle, LitGoogleMapMarker, LitGoogleMapPolygon, LitGoogleMapsApi, LitSelector }; +export { LitGoogleMap, LitGoogleMapCircle, LitGoogleMapLocationButton, LitGoogleMapMarker, LitGoogleMapPolygon, LitGoogleMapsApi, LitSelector }; diff --git a/dist/lit-google-map.esm.min.js b/dist/lit-google-map.esm.min.js index f9edbe7..01a396d 100644 --- a/dist/lit-google-map.esm.min.js +++ b/dist/lit-google-map.esm.min.js @@ -1,4 +1,4 @@ -import{__decorate as t,__metadata as e}from"tslib";import{css as i,LitElement as s,html as o}from"lit";import{property as a,customElement as r}from"lit/decorators.js";let n=class extends s{constructor(){super(...arguments),this.apiKey="",this.version="3.48",this.styles={},this.zoom=8,this.fitToMarkers=!1,this.mapType="roadmap",this.centerLatitude=-34.397,this.centerLongitude=150.644,this.language="",this.mapId="DEMO_MAP_ID",this.map=null}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),this.map&&e!==i&&null!==i&&("center-latitude"===t||"center-longitude"===t?this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude}):"zoom"===t&&this.map.setZoom(this.zoom))}dispatchViewChanged(){this.dispatchEvent(new CustomEvent("view_changed",{detail:{center:this.map.getCenter().toJSON(),zoom:this.map.getZoom()},bubbles:!0,composed:!0}))}initGMap(){if(null!=this.map)return;const t=this.shadowRoot.getElementById("api");null!=t&&!0===t.libraryLoaded&&(this.map=new google.maps.Map(this.shadowRoot.getElementById("map"),this.getMapOptions()),this.map.addListener("bounds_changed",(()=>{this.dispatchEvent(new CustomEvent("bounds_changed",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("tilesloaded",(()=>{this.dispatchEvent(new CustomEvent("tilesloaded",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("center_changed",(()=>{this.dispatchEvent(new CustomEvent("center_changed",{detail:this.map.getCenter().toJSON(),bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("zoom_changed",(()=>{this.dispatchEvent(new CustomEvent("zoom_changed",{detail:{zoom:this.map.getZoom()},bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("click",(t=>{"placeId"in t&&(t.stop(),this.dispatchEvent(new CustomEvent("place_click",{detail:{placeId:t.placeId},bubbles:!0,composed:!0})))})),this.updateMarkers(),this.updateShapes())}getMapOptions(){return{zoom:this.zoom,center:{lat:this.centerLatitude,lng:this.centerLongitude},mapTypeId:this.mapType,styles:this.styles,mapId:this.mapId}}mapApiLoaded(){this.initGMap()}connectedCallback(){super.connectedCallback(),this.initGMap()}updated(t){super.updated(t),this.map?((t.has("centerLatitude")||t.has("centerLongitude"))&&(t.get("centerLatitude"),t.get("centerLongitude"),this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude})),t.has("zoom")&&(t.get("zoom"),this.map.setZoom(this.zoom))):console.log("Map not initialized yet, skipping update")}attachChildrenToMap(t){if(this.map)for(const e of t)e.changeMap(this.map)}detachChildrenFromMap(t){if(this.map)for(const e of t)e.changeMap(null)}observeMarkers(){this.markerObserverSet||(this.addEventListener("selector-items-changed",(()=>{this.updateMarkers()})),this.markerObserverSet=!0)}updateMarkers(){var t;this.observeMarkers();const e=this.shadowRoot.getElementById("markers-selector");if(!e)return;const i=e.items;if(this.markers&&i.length===this.markers.length){if(0===i.filter((t=>this.markers&&-1===this.markers.indexOf(t))).length)return}const s=this.checkBoundsChanged(this.markers,i),o=(null===(t=this.markers)||void 0===t?void 0:t.filter((t=>-1===i.indexOf(t))))||[];this.detachChildrenFromMap(o),this.markers=i,this.attachChildrenToMap(this.markers),this.fitToMarkers&&s&&this.fitToMarkersChanged()}updateShapes(){const t=this.shadowRoot.getElementById("shapes-selector");if(t){this.shapes=t.items;for(const t of this.shapes)t.attachToMap(this.map)}}fitToMarkersChanged(t=0){if(this.map&&this.fitToMarkers&&this.markers.length>0){const e=new google.maps.LatLngBounds;for(const t of this.markers)e.extend(new google.maps.LatLng(t.latitude,t.longitude));const i=this.getBoundingClientRect();if(0===i.width||0===i.height){console.log("Invalid DOM width or height for lit-google-map");return void setTimeout((()=>{this.fitToMarkersChanged(t+1)}),2**t*100)}this.markers.length>1&&this.map.fitBounds(e,0),this.map.setCenter(e.getCenter())}}checkBoundsChanged(t,e){const i=e.filter((e=>!t||!t.includes(e))),s=null==t?void 0:t.filter((t=>!e||!e.includes(t)));return i.length>0||s.length>0}deselectMarker(t){}deselectShape(t){}render(){return o` +import{__decorate as t,__metadata as e}from"tslib";import{css as i,LitElement as s,html as o}from"lit";import{property as a,customElement as n}from"lit/decorators.js";let r=class extends s{constructor(){super(...arguments),this.apiKey="",this.version="3.48",this.styles={},this.zoom=8,this.fitToMarkers=!1,this.mapType="roadmap",this.centerLatitude=-34.397,this.centerLongitude=150.644,this.language="",this.mapId="DEMO_MAP_ID",this.map=null}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),this.map&&e!==i&&null!==i&&("center-latitude"===t||"center-longitude"===t?this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude}):"zoom"===t&&this.map.setZoom(this.zoom))}dispatchViewChanged(){this.dispatchEvent(new CustomEvent("view_changed",{detail:{center:this.map.getCenter().toJSON(),zoom:this.map.getZoom()},bubbles:!0,composed:!0}))}initGMap(){if(null!=this.map)return;const t=this.shadowRoot.getElementById("api");null!=t&&!0===t.libraryLoaded&&(this.map=new google.maps.Map(this.shadowRoot.getElementById("map"),this.getMapOptions()),this.map.addListener("bounds_changed",(()=>{this.dispatchEvent(new CustomEvent("bounds_changed",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("tilesloaded",(()=>{this.dispatchEvent(new CustomEvent("tilesloaded",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("center_changed",(()=>{this.dispatchEvent(new CustomEvent("center_changed",{detail:this.map.getCenter().toJSON(),bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("zoom_changed",(()=>{this.dispatchEvent(new CustomEvent("zoom_changed",{detail:{zoom:this.map.getZoom()},bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("click",(t=>{"placeId"in t&&(t.stop(),this.dispatchEvent(new CustomEvent("place_click",{detail:{placeId:t.placeId},bubbles:!0,composed:!0})))})),this.updateMarkers(),this.updateShapes(),this.updateControls())}getMapOptions(){return{zoom:this.zoom,center:{lat:this.centerLatitude,lng:this.centerLongitude},mapTypeId:this.mapType,styles:this.styles,mapId:this.mapId}}mapApiLoaded(){this.initGMap()}connectedCallback(){super.connectedCallback(),this.initGMap()}updated(t){super.updated(t),this.map?((t.has("centerLatitude")||t.has("centerLongitude"))&&(t.get("centerLatitude"),t.get("centerLongitude"),this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude})),t.has("zoom")&&(t.get("zoom"),this.map.setZoom(this.zoom))):console.log("Map not initialized yet, skipping update")}attachChildrenToMap(t){if(this.map)for(const e of t)e.changeMap(this.map)}detachChildrenFromMap(t){if(this.map)for(const e of t)e.changeMap(null)}observeMarkers(){this.markerObserverSet||(this.addEventListener("selector-items-changed",(()=>{this.updateMarkers()})),this.markerObserverSet=!0)}updateMarkers(){var t;this.observeMarkers();const e=this.shadowRoot.getElementById("markers-selector");if(!e)return;const i=e.items;if(this.markers&&i.length===this.markers.length){if(0===i.filter((t=>this.markers&&-1===this.markers.indexOf(t))).length)return}const s=this.checkBoundsChanged(this.markers,i),o=(null===(t=this.markers)||void 0===t?void 0:t.filter((t=>-1===i.indexOf(t))))||[];this.detachChildrenFromMap(o),this.markers=i,this.attachChildrenToMap(this.markers),this.fitToMarkers&&s&&this.fitToMarkersChanged()}updateShapes(){const t=this.shadowRoot.getElementById("shapes-selector");if(t){this.shapes=t.items;for(const t of this.shapes)t.attachToMap(this.map)}}updateControls(){const t=this.shadowRoot.getElementById("controls-selector");if(t){this.controls=t.items;for(const t of this.controls)t.changeMap(this.map)}}fitToMarkersChanged(t=0){if(this.map&&this.fitToMarkers&&this.markers.length>0){const e=new google.maps.LatLngBounds;for(const t of this.markers)e.extend(new google.maps.LatLng(t.latitude,t.longitude));const i=this.getBoundingClientRect();if(0===i.width||0===i.height){console.log("Invalid DOM width or height for lit-google-map");return void setTimeout((()=>{this.fitToMarkersChanged(t+1)}),2**t*100)}this.markers.length>1&&this.map.fitBounds(e,0),this.map.setCenter(e.getCenter())}}checkBoundsChanged(t,e){const i=e.filter((e=>!t||!t.includes(e))),s=null==t?void 0:t.filter((t=>!e||!e.includes(t)));return i.length>0||s.length>0}deselectMarker(t){}deselectShape(t){}render(){return o` + + +
- `}};n.styles=i` + `}};r.styles=i` #map { width: 100%; height: 100%; } - `,t([a({type:String,attribute:"api-key"}),e("design:type",Object)],n.prototype,"apiKey",void 0),t([a({type:String}),e("design:type",Object)],n.prototype,"version",void 0),t([a({type:Object}),e("design:type",Object)],n.prototype,"styles",void 0),t([a({type:Number}),e("design:type",Object)],n.prototype,"zoom",void 0),t([a({type:Boolean,attribute:"fit-to-markers"}),e("design:type",Object)],n.prototype,"fitToMarkers",void 0),t([a({type:String,attribute:"map-type"}),e("design:type",Object)],n.prototype,"mapType",void 0),t([a({type:Number,attribute:"center-latitude"}),e("design:type",Object)],n.prototype,"centerLatitude",void 0),t([a({type:Number,attribute:"center-longitude"}),e("design:type",Object)],n.prototype,"centerLongitude",void 0),t([a({type:String}),e("design:type",Object)],n.prototype,"language",void 0),t([a({type:String,attribute:"map-id"}),e("design:type",Object)],n.prototype,"mapId",void 0),n=t([r("lit-google-map")],n);let l=class extends s{constructor(){super(...arguments),this.centerLatitude=-34.397,this.centerLongitude=150.644,this.radius=1e5,this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.circle=null}attributeChangedCallback(t,e,i){var s;switch(super.attributeChangedCallback(t,e,i),t){case"center-latitude":case"center-longitude":this.updateCenter();break;case"radius":null===(s=this.circle)||void 0===s||s.setRadius(this.radius)}}updateCenter(){var t;null===(t=this.circle)||void 0===t||t.setCenter(new google.maps.LatLng(this.centerLatitude,this.centerLongitude))}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.circle&&(this.circle.setMap(null),google.maps.event.clearInstanceListeners(this.circle)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.circle=new google.maps.Circle({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,center:{lat:this.centerLatitude,lng:this.centerLongitude},radius:this.radius})}};t([a({type:Number,attribute:"center-latitude"}),e("design:type",Object)],l.prototype,"centerLatitude",void 0),t([a({type:Number,attribute:"center-longitude"}),e("design:type",Object)],l.prototype,"centerLongitude",void 0),t([a({type:Number}),e("design:type",Object)],l.prototype,"radius",void 0),t([a({type:String,attribute:"fill-color"}),e("design:type",Object)],l.prototype,"fillColor",void 0),t([a({type:Number,attribute:"fill-opacity"}),e("design:type",Object)],l.prototype,"fillOpacity",void 0),t([a({type:String,attribute:"stroke-color"}),e("design:type",Object)],l.prototype,"strokeColor",void 0),t([a({type:Number,attribute:"stroke-opacity"}),e("design:type",Object)],l.prototype,"strokeOpacity",void 0),t([a({type:Number,attribute:"stroke-weight"}),e("design:type",Object)],l.prototype,"strokeWeight",void 0),l=t([r("lit-google-map-circle")],l);let p=class extends s{constructor(){super(...arguments),this.latitude=0,this.longitude=0,this.zIndex=0,this.open=!1,this.id=null,this.glyph=null,this.glyphColor=null,this.background=null,this.borderColor=null,this.scale=null,this.map=null,this.marker=null,this.pin=null}attributeChangedCallback(t,e,i){switch(super.attributeChangedCallback(t,e,i),t){case"open":this.openChanged();break;case"latitude":case"longitude":this.updatePosition();break;case"glyph":this.pin&&(this.pin.glyph=this.glyph);break;case"glyphColor":this.pin&&(this.pin.glyphColor=this.glyphColor);break;case"background":this.pin&&(this.pin.background=this.background);break;case"borderColor":this.pin&&(this.pin.borderColor=this.borderColor);break;case"scale":this.pin&&(this.pin.scale=this.scale);break;case"z-index":this.marker&&(this.marker.zIndex=this.zIndex)}}openChanged(){this.info&&(this.open?(this.info.open(this.map,this.marker),this.dispatchEvent(new CustomEvent("google-map-marker-open",{bubbles:!0}))):(this.info.close(),this.dispatchEvent(new CustomEvent("google-map-marker-close",{bubbles:!0}))))}updatePosition(){this.marker&&(this.marker.position=new google.maps.LatLng(this.latitude,this.longitude))}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.marker&&(this.marker.map=null,google.maps.event.clearInstanceListeners(this.marker)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.pin=new google.maps.marker.PinElement({glyph:this.glyph,glyphColor:this.glyphColor,background:this.background,borderColor:this.borderColor,scale:this.scale}),this.marker=new google.maps.marker.AdvancedMarkerElement({map:this.map,position:{lat:this.latitude,lng:this.longitude},content:this.pin.element,zIndex:this.zIndex,gmpClickable:!0}),this.marker.element.addEventListener("mouseover",(()=>{this.dispatchEvent(new CustomEvent("mouseover",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.element.addEventListener("mouseout",(()=>{this.dispatchEvent(new CustomEvent("mouseout",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.addListener("click",(()=>{this.dispatchEvent(new CustomEvent("click",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.contentChanged()}contentChanged(){this.contentObserver&&this.contentObserver.disconnect(),this.contentObserver=new MutationObserver(this.contentChanged.bind(this)),this.contentObserver.observe(this,{childList:!0,subtree:!0});const t=this.innerHTML.trim();t?(this.info||(this.info=new google.maps.InfoWindow,this.openInfoHandler=google.maps.event.addListener(this.marker,"click",function(){this.open=!0}.bind(this)),this.closeInfoHandler=google.maps.event.addListener(this.info,"closeclick",function(){this.open=!1}.bind(this))),this.info.setContent(t)):this.info&&(google.maps.event.removeListener(this.openInfoHandler),google.maps.event.removeListener(this.closeInfoHandler),this.info=null)}};t([a({type:Number,reflect:!0}),e("design:type",Object)],p.prototype,"latitude",void 0),t([a({type:Number,reflect:!0}),e("design:type",Object)],p.prototype,"longitude",void 0),t([a({type:Number,reflect:!0,attribute:"z-index"}),e("design:type",Object)],p.prototype,"zIndex",void 0),t([a({type:Boolean,reflect:!0}),e("design:type",Object)],p.prototype,"open",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],p.prototype,"id",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],p.prototype,"glyph",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],p.prototype,"glyphColor",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],p.prototype,"background",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],p.prototype,"borderColor",void 0),t([a({type:Number,reflect:!0}),e("design:type",Number)],p.prototype,"scale",void 0),p=t([r("lit-google-map-marker")],p);let h=class extends s{constructor(){super(...arguments),this.paths=[],this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.polygon=null}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.polygon&&(this.polygon.setMap(null),google.maps.event.clearInstanceListeners(this.polygon)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.polygon=new google.maps.Polygon({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,paths:this.paths})}};t([a({type:Array}),e("design:type",Array)],h.prototype,"paths",void 0),t([a({type:String,attribute:"fill-color"}),e("design:type",Object)],h.prototype,"fillColor",void 0),t([a({type:Number,attribute:"fill-opacity"}),e("design:type",Object)],h.prototype,"fillOpacity",void 0),t([a({type:String,attribute:"stroke-color"}),e("design:type",Object)],h.prototype,"strokeColor",void 0),t([a({type:Number,attribute:"stroke-opacity"}),e("design:type",Object)],h.prototype,"strokeOpacity",void 0),t([a({type:Number,attribute:"stroke-weight"}),e("design:type",Object)],h.prototype,"strokeWeight",void 0),h=t([r("lit-google-map-polygon")],h);class c{constructor(){this.apiMap={}}require(t,e,i){const s=this.nameFromUrl(t);this.apiMap[s]||(this.apiMap[s]=new d(s,t,i)),this.apiMap[s].requestNotify(e)}static getInstance(){return c.instance||(c.instance=new c),c.instance}nameFromUrl(t){return`${t.replace(/[:/%?&.=\-,]/g,"_")}_api`}}class d{constructor(t,e,i){this.callbackMacro="%%callback%%",this.loaded=!1,this.script=null,this.notifiers=[];let s=e,o=i;if(!o){if(!(s.indexOf(this.callbackMacro)>=0))return void console.error("ScriptLoader class: a %%callback%% parameter is required in libraryUrl");o=`${t}_loaded`,s=s.replace(this.callbackMacro,o)}this.callbackName=o,window[this.callbackName]=this.success.bind(this),this.addScript(s)}addScript(t){const e=document.createElement("script");e.src=t,e.onerror=this.handleError.bind(this);const i=document.querySelector("script")||document.body;i.parentNode.insertBefore(e,i),this.script=e}removeScript(){this.script.parentNode&&this.script.parentNode.removeChild(this.script),this.script=null}handleError(t){this.error=new Error("Library failed to load"),this.notifyAll(),this.cleanup()}success(...t){this.loaded=!0,this.result=t,this.notifyAll(),this.cleanup()}cleanup(){delete window[this.callbackName]}notifyAll(){this.notifiers.forEach(function(t){t(this.error,this.result)}.bind(this)),this.notifiers=[]}requestNotify(t){this.loaded||this.error?t(this.error,this.result):this.notifiers.push(t)}}class g extends s{constructor(){super(...arguments),this.libraryLoaded=!1,this.libraryErrorMessage=null,this.isReady=!1}get callbackName(){return null}libraryUrlChanged(){this.isReady&&null!=this.libraryUrl&&this.loadLibrary()}libraryLoadCallback(t,e){t?(console.warn("Library load failed:",t.message),this.libraryErrorMessage=t.message):(this.libraryErrorMessage=null,this.libraryLoaded=!0,null!=this.notifyEvent&&this.dispatchEvent(new CustomEvent(this.notifyEvent,{detail:e,composed:!0})))}loadLibrary(){c.getInstance().require(this.libraryUrl,this.libraryLoadCallback.bind(this),this.callbackName)}connectedCallback(){super.connectedCallback(),this.isReady=!0,null!=this.libraryUrl&&this.loadLibrary()}}let u=class extends g{constructor(){super(...arguments),this.apiKey="",this.clientId="",this.mapsUrl="https://maps.googleapis.com/maps/api/js?callback=%%callback%%",this.version="3.39",this.language="",this.mapId=""}get libraryUrl(){return this.computeUrl(this.mapsUrl,this.version,this.apiKey,this.clientId,this.language,this.mapId)}get notifyEvent(){return"api-load"}computeUrl(t,e,i,s,o,a){let r=`${t}&v=${e}`;if(r+="&libraries=drawing,geometry,places,visualization,marker",i&&!s&&(r+=`&key=${i}`),s&&(r+=`&client=${s}`),!i&&!s){const t="No Google Maps API Key or Client ID specified. See https://developers.google.com/maps/documentation/javascript/get-api-key for instructions to get started with a key or client id.";console.warn(t)}return o&&(r+=`&language=${o}`),a&&(r+=`&map_ids=${a}`),r}};t([a({type:String,attribute:"api-key"}),e("design:type",Object)],u.prototype,"apiKey",void 0),t([a({type:String,attribute:"client-id"}),e("design:type",Object)],u.prototype,"clientId",void 0),t([a({type:String,attribute:"maps-url"}),e("design:type",Object)],u.prototype,"mapsUrl",void 0),t([a({type:String}),e("design:type",Object)],u.prototype,"version",void 0),t([a({type:String}),e("design:type",Object)],u.prototype,"language",void 0),t([a({type:String,attribute:"map-id"}),e("design:type",Object)],u.prototype,"mapId",void 0),u=t([r("lit-google-maps-api")],u);class m{constructor(t){this.multi=!1,this.selection=[],this.selectCallback=t}get(){return this.multi?this.selection.slice():this.selection[0]}clear(t){for(const e of this.selection.slice())(!t||t.indexOf(e)<0)&&this.setItemSelected(e,!1)}isSelected(t){return this.selection.indexOf(t)>=0}setItemSelected(t,e){if(null!=t&&e!==this.isSelected(t)){if(e)this.selection.push(t);else{const e=this.selection.indexOf(t);e>=0&&this.selection.splice(e,1)}this.selectCallback&&this.selectCallback(t,e)}}select(t){this.multi?this.toggle(t):this.get()!==t&&(this.setItemSelected(this.get(),!1),this.setItemSelected(t,!0))}toggle(t){this.setItemSelected(t,!this.isSelected(t))}}let y=class extends s{constructor(){super(...arguments),this.activateEvent="tap",this.selectedAttribute=null,this.selected=null,this._selection=new m(((t,e)=>this.applySelection(t,e))),this._items=[]}get items(){return this._items}connectedCallback(){super.connectedCallback(),this.addEventListener("slotchange",(t=>{t.stopPropagation(),this.updateItems(),this.dispatchEvent(new CustomEvent("selector-items-changed",{detail:{},composed:!0}))})),this.addListener(this.activateEvent)}disconnectedCallback(){super.disconnectedCallback(),this.removeListener(this.activateEvent)}attributeChangedCallback(t,e,i){if(super.attributeChangedCallback(t,e,i),"selected"===t)this.updateSelected()}applySelection(t,e){this.selectedAttribute&&t instanceof Element&&e!==t.hasAttribute(this.selectedAttribute)&&t.toggleAttribute(this.selectedAttribute)}updateItems(){var t;const e=this.querySelector("slot");this._items=null!==(t=null==e?void 0:e.assignedNodes())&&void 0!==t?t:[]}addListener(t){this.addEventListener(t,(t=>this.activateHandler(t)))}removeListener(t){this.removeEventListener(t,(t=>this.activateHandler(t)))}activateHandler(t){let e=t.target;const i=this.items;for(;e&&e!==this;){const t=i.indexOf(e);if(t>=0){const i=this.indexToValue(t);return void this.itemActivate(i,e)}e=e.parentNode}}itemActivate(t,e){this.dispatchEvent(new CustomEvent("selector-item-activate",{detail:{selected:t,item:e},composed:!0,cancelable:!0}))&&this.select(t)}select(t){this.selected=t}updateSelected(){this.selectSelected(this.selected)}selectSelected(t){if(!this._items)return;const e=this.valueToItem(this.selected);e?this._selection.select(e):this._selection.clear()}valueToItem(t){return null==t?null:this._items[this.valueToIndex(t)]}valueToIndex(t){return Number(t)}indexToValue(t){return t}indexOf(t){return this._items?this._items.indexOf(t):-1}};t([a({type:String,attribute:"activate-event"}),e("design:type",Object)],y.prototype,"activateEvent",void 0),t([a({type:String,attribute:"selected-attribute"}),e("design:type",String)],y.prototype,"selectedAttribute",void 0),t([a({type:Number,reflect:!0}),e("design:type",Object)],y.prototype,"selected",void 0),y=t([r("lit-selector")],y);export{n as LitGoogleMap,l as LitGoogleMapCircle,p as LitGoogleMapMarker,h as LitGoogleMapPolygon,u as LitGoogleMapsApi,y as LitSelector}; + `,t([a({type:String,attribute:"api-key"}),e("design:type",Object)],r.prototype,"apiKey",void 0),t([a({type:String}),e("design:type",Object)],r.prototype,"version",void 0),t([a({type:Object}),e("design:type",Object)],r.prototype,"styles",void 0),t([a({type:Number}),e("design:type",Object)],r.prototype,"zoom",void 0),t([a({type:Boolean,attribute:"fit-to-markers"}),e("design:type",Object)],r.prototype,"fitToMarkers",void 0),t([a({type:String,attribute:"map-type"}),e("design:type",Object)],r.prototype,"mapType",void 0),t([a({type:Number,attribute:"center-latitude"}),e("design:type",Object)],r.prototype,"centerLatitude",void 0),t([a({type:Number,attribute:"center-longitude"}),e("design:type",Object)],r.prototype,"centerLongitude",void 0),t([a({type:String}),e("design:type",Object)],r.prototype,"language",void 0),t([a({type:String,attribute:"map-id"}),e("design:type",Object)],r.prototype,"mapId",void 0),r=t([n("lit-google-map")],r);let l=class extends s{constructor(){super(...arguments),this.centerLatitude=-34.397,this.centerLongitude=150.644,this.radius=1e5,this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.circle=null}attributeChangedCallback(t,e,i){var s;switch(super.attributeChangedCallback(t,e,i),t){case"center-latitude":case"center-longitude":this.updateCenter();break;case"radius":null===(s=this.circle)||void 0===s||s.setRadius(this.radius)}}updateCenter(){var t;null===(t=this.circle)||void 0===t||t.setCenter(new google.maps.LatLng(this.centerLatitude,this.centerLongitude))}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.circle&&(this.circle.setMap(null),google.maps.event.clearInstanceListeners(this.circle)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.circle=new google.maps.Circle({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,center:{lat:this.centerLatitude,lng:this.centerLongitude},radius:this.radius})}};t([a({type:Number,attribute:"center-latitude"}),e("design:type",Object)],l.prototype,"centerLatitude",void 0),t([a({type:Number,attribute:"center-longitude"}),e("design:type",Object)],l.prototype,"centerLongitude",void 0),t([a({type:Number}),e("design:type",Object)],l.prototype,"radius",void 0),t([a({type:String,attribute:"fill-color"}),e("design:type",Object)],l.prototype,"fillColor",void 0),t([a({type:Number,attribute:"fill-opacity"}),e("design:type",Object)],l.prototype,"fillOpacity",void 0),t([a({type:String,attribute:"stroke-color"}),e("design:type",Object)],l.prototype,"strokeColor",void 0),t([a({type:Number,attribute:"stroke-opacity"}),e("design:type",Object)],l.prototype,"strokeOpacity",void 0),t([a({type:Number,attribute:"stroke-weight"}),e("design:type",Object)],l.prototype,"strokeWeight",void 0),l=t([n("lit-google-map-circle")],l);let c=class extends s{constructor(){super(...arguments),this.position="RIGHT_BOTTOM",this.label="My Location",this.disabled=!1,this.map=null,this.controlDiv=null,this.controlButton=null,this.isRequesting=!1}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.controlDiv&&this.map&&(this.controlDiv=null,this.controlButton=null),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.controlDiv=this.createControlButton();const t=google.maps.ControlPosition[this.position];void 0!==t&&this.map.controls[t].push(this.controlDiv)}createControlButton(){const t=document.createElement("div");t.style.margin="10px";const e=document.createElement("button");return e.type="button",e.title=this.label,e.setAttribute("aria-label",this.label),e.innerHTML='\n \n \n \n ',Object.assign(e.style,{backgroundColor:"#fff",border:"0",borderRadius:"2px",boxShadow:"0 1px 4px rgba(0,0,0,0.3)",cursor:"pointer",padding:"10px",display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",color:"#666"}),e.addEventListener("mouseenter",(()=>{this.disabled||this.isRequesting||(e.style.backgroundColor="#f8f8f8")})),e.addEventListener("mouseleave",(()=>{this.disabled||this.isRequesting||(e.style.backgroundColor="#fff")})),e.addEventListener("click",(()=>{this.disabled||this.isRequesting||this.handleLocationRequest()})),this.controlButton=e,t.appendChild(e),t}async handleLocationRequest(){if(navigator.geolocation){this.isRequesting=!0,this.setLoadingState(!0),this.dispatchEvent(new CustomEvent("location-requested",{bubbles:!0,composed:!0}));try{const t=await this.getCurrentPosition(),e=t.coords.latitude,i=t.coords.longitude;this.map.setCenter({lat:e,lng:i}),this.map.setZoom(14),this.dispatchEvent(new CustomEvent("location-found",{detail:{lat:e,lng:i},bubbles:!0,composed:!0}))}catch(t){let e="Unable to retrieve your location",i=-1;t instanceof GeolocationPositionError&&(i=t.code,t.code===t.PERMISSION_DENIED?e="Location access denied. Please enable location permissions.":t.code===t.TIMEOUT?e="Location request timed out. Please try again.":t.code===t.POSITION_UNAVAILABLE&&(e="Location information is unavailable.")),this.dispatchEvent(new CustomEvent("location-error",{detail:{code:i,message:e},bubbles:!0,composed:!0}))}finally{this.isRequesting=!1,this.setLoadingState(!1)}}else this.dispatchEvent(new CustomEvent("location-error",{detail:{code:-1,message:"Geolocation is not supported by your browser"},bubbles:!0,composed:!0}))}getCurrentPosition(){return new Promise(((t,e)=>{navigator.geolocation.getCurrentPosition(t,e,{timeout:1e4,enableHighAccuracy:!0})}))}setLoadingState(t){if(this.controlButton)if(t){this.controlButton.style.backgroundColor="#f0f0f0",this.controlButton.style.cursor="wait";const t=this.controlButton.querySelector("svg");if(t){t.style.animation="spin 1s linear infinite";const e=document.createElement("style");e.textContent="\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n ",document.querySelector("style[data-location-button-spin]")||(e.setAttribute("data-location-button-spin","true"),document.head.appendChild(e))}}else{this.controlButton.style.backgroundColor="#fff",this.controlButton.style.cursor="pointer";const t=this.controlButton.querySelector("svg");t&&(t.style.animation="")}}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),"disabled"===t&&this.controlButton&&(this.disabled?(this.controlButton.style.backgroundColor="#f0f0f0",this.controlButton.style.cursor="not-allowed",this.controlButton.style.opacity="0.6"):(this.controlButton.style.backgroundColor="#fff",this.controlButton.style.cursor="pointer",this.controlButton.style.opacity="1"))}};t([a({type:String,reflect:!0}),e("design:type",Object)],c.prototype,"position",void 0),t([a({type:String,reflect:!0}),e("design:type",Object)],c.prototype,"label",void 0),t([a({type:Boolean,reflect:!0}),e("design:type",Object)],c.prototype,"disabled",void 0),c=t([n("lit-google-map-location-button")],c);let h=class extends s{constructor(){super(...arguments),this.latitude=0,this.longitude=0,this.zIndex=0,this.open=!1,this.id=null,this.glyph=null,this.glyphColor=null,this.background=null,this.borderColor=null,this.scale=null,this.map=null,this.marker=null,this.pin=null}attributeChangedCallback(t,e,i){switch(super.attributeChangedCallback(t,e,i),t){case"open":this.openChanged();break;case"latitude":case"longitude":this.updatePosition();break;case"glyph":this.pin&&(this.pin.glyph=this.glyph);break;case"glyphColor":this.pin&&(this.pin.glyphColor=this.glyphColor);break;case"background":this.pin&&(this.pin.background=this.background);break;case"borderColor":this.pin&&(this.pin.borderColor=this.borderColor);break;case"scale":this.pin&&(this.pin.scale=this.scale);break;case"z-index":this.marker&&(this.marker.zIndex=this.zIndex)}}openChanged(){this.info&&(this.open?(this.info.open(this.map,this.marker),this.dispatchEvent(new CustomEvent("google-map-marker-open",{bubbles:!0}))):(this.info.close(),this.dispatchEvent(new CustomEvent("google-map-marker-close",{bubbles:!0}))))}updatePosition(){this.marker&&(this.marker.position=new google.maps.LatLng(this.latitude,this.longitude))}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.marker&&(this.marker.map=null,google.maps.event.clearInstanceListeners(this.marker)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.pin=new google.maps.marker.PinElement({glyph:this.glyph,glyphColor:this.glyphColor,background:this.background,borderColor:this.borderColor,scale:this.scale}),this.marker=new google.maps.marker.AdvancedMarkerElement({map:this.map,position:{lat:this.latitude,lng:this.longitude},content:this.pin.element,zIndex:this.zIndex,gmpClickable:!0}),this.marker.element.addEventListener("mouseover",(()=>{this.dispatchEvent(new CustomEvent("mouseover",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.element.addEventListener("mouseout",(()=>{this.dispatchEvent(new CustomEvent("mouseout",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.addListener("click",(()=>{this.dispatchEvent(new CustomEvent("click",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.contentChanged()}contentChanged(){this.contentObserver&&this.contentObserver.disconnect(),this.contentObserver=new MutationObserver(this.contentChanged.bind(this)),this.contentObserver.observe(this,{childList:!0,subtree:!0});const t=this.innerHTML.trim();t?(this.info||(this.info=new google.maps.InfoWindow,this.openInfoHandler=google.maps.event.addListener(this.marker,"click",function(){this.open=!0}.bind(this)),this.closeInfoHandler=google.maps.event.addListener(this.info,"closeclick",function(){this.open=!1}.bind(this))),this.info.setContent(t)):this.info&&(google.maps.event.removeListener(this.openInfoHandler),google.maps.event.removeListener(this.closeInfoHandler),this.info=null)}};t([a({type:Number,reflect:!0}),e("design:type",Object)],h.prototype,"latitude",void 0),t([a({type:Number,reflect:!0}),e("design:type",Object)],h.prototype,"longitude",void 0),t([a({type:Number,reflect:!0,attribute:"z-index"}),e("design:type",Object)],h.prototype,"zIndex",void 0),t([a({type:Boolean,reflect:!0}),e("design:type",Object)],h.prototype,"open",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],h.prototype,"id",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],h.prototype,"glyph",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],h.prototype,"glyphColor",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],h.prototype,"background",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],h.prototype,"borderColor",void 0),t([a({type:Number,reflect:!0}),e("design:type",Number)],h.prototype,"scale",void 0),h=t([n("lit-google-map-marker")],h);let p=class extends s{constructor(){super(...arguments),this.paths=[],this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.polygon=null}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.polygon&&(this.polygon.setMap(null),google.maps.event.clearInstanceListeners(this.polygon)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.polygon=new google.maps.Polygon({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,paths:this.paths})}};t([a({type:Array}),e("design:type",Array)],p.prototype,"paths",void 0),t([a({type:String,attribute:"fill-color"}),e("design:type",Object)],p.prototype,"fillColor",void 0),t([a({type:Number,attribute:"fill-opacity"}),e("design:type",Object)],p.prototype,"fillOpacity",void 0),t([a({type:String,attribute:"stroke-color"}),e("design:type",Object)],p.prototype,"strokeColor",void 0),t([a({type:Number,attribute:"stroke-opacity"}),e("design:type",Object)],p.prototype,"strokeOpacity",void 0),t([a({type:Number,attribute:"stroke-weight"}),e("design:type",Object)],p.prototype,"strokeWeight",void 0),p=t([n("lit-google-map-polygon")],p);class d{constructor(){this.apiMap={}}require(t,e,i){const s=this.nameFromUrl(t);this.apiMap[s]||(this.apiMap[s]=new u(s,t,i)),this.apiMap[s].requestNotify(e)}static getInstance(){return d.instance||(d.instance=new d),d.instance}nameFromUrl(t){return`${t.replace(/[:/%?&.=\-,]/g,"_")}_api`}}class u{constructor(t,e,i){this.callbackMacro="%%callback%%",this.loaded=!1,this.script=null,this.notifiers=[];let s=e,o=i;if(!o){if(!(s.indexOf(this.callbackMacro)>=0))return void console.error("ScriptLoader class: a %%callback%% parameter is required in libraryUrl");o=`${t}_loaded`,s=s.replace(this.callbackMacro,o)}this.callbackName=o,window[this.callbackName]=this.success.bind(this),this.addScript(s)}addScript(t){const e=document.createElement("script");e.src=t,e.onerror=this.handleError.bind(this);const i=document.querySelector("script")||document.body;i.parentNode.insertBefore(e,i),this.script=e}removeScript(){this.script.parentNode&&this.script.parentNode.removeChild(this.script),this.script=null}handleError(t){this.error=new Error("Library failed to load"),this.notifyAll(),this.cleanup()}success(...t){this.loaded=!0,this.result=t,this.notifyAll(),this.cleanup()}cleanup(){delete window[this.callbackName]}notifyAll(){this.notifiers.forEach(function(t){t(this.error,this.result)}.bind(this)),this.notifiers=[]}requestNotify(t){this.loaded||this.error?t(this.error,this.result):this.notifiers.push(t)}}class g extends s{constructor(){super(...arguments),this.libraryLoaded=!1,this.libraryErrorMessage=null,this.isReady=!1}get callbackName(){return null}libraryUrlChanged(){this.isReady&&null!=this.libraryUrl&&this.loadLibrary()}libraryLoadCallback(t,e){t?(console.warn("Library load failed:",t.message),this.libraryErrorMessage=t.message):(this.libraryErrorMessage=null,this.libraryLoaded=!0,null!=this.notifyEvent&&this.dispatchEvent(new CustomEvent(this.notifyEvent,{detail:e,composed:!0})))}loadLibrary(){d.getInstance().require(this.libraryUrl,this.libraryLoadCallback.bind(this),this.callbackName)}connectedCallback(){super.connectedCallback(),this.isReady=!0,null!=this.libraryUrl&&this.loadLibrary()}}let m=class extends g{constructor(){super(...arguments),this.apiKey="",this.clientId="",this.mapsUrl="https://maps.googleapis.com/maps/api/js?callback=%%callback%%",this.version="3.39",this.language="",this.mapId=""}get libraryUrl(){return this.computeUrl(this.mapsUrl,this.version,this.apiKey,this.clientId,this.language,this.mapId)}get notifyEvent(){return"api-load"}computeUrl(t,e,i,s,o,a){let n=`${t}&v=${e}`;if(n+="&libraries=drawing,geometry,places,visualization,marker",i&&!s&&(n+=`&key=${i}`),s&&(n+=`&client=${s}`),!i&&!s){const t="No Google Maps API Key or Client ID specified. See https://developers.google.com/maps/documentation/javascript/get-api-key for instructions to get started with a key or client id.";console.warn(t)}return o&&(n+=`&language=${o}`),a&&(n+=`&map_ids=${a}`),n}};t([a({type:String,attribute:"api-key"}),e("design:type",Object)],m.prototype,"apiKey",void 0),t([a({type:String,attribute:"client-id"}),e("design:type",Object)],m.prototype,"clientId",void 0),t([a({type:String,attribute:"maps-url"}),e("design:type",Object)],m.prototype,"mapsUrl",void 0),t([a({type:String}),e("design:type",Object)],m.prototype,"version",void 0),t([a({type:String}),e("design:type",Object)],m.prototype,"language",void 0),t([a({type:String,attribute:"map-id"}),e("design:type",Object)],m.prototype,"mapId",void 0),m=t([n("lit-google-maps-api")],m);class y{constructor(t){this.multi=!1,this.selection=[],this.selectCallback=t}get(){return this.multi?this.selection.slice():this.selection[0]}clear(t){for(const e of this.selection.slice())(!t||t.indexOf(e)<0)&&this.setItemSelected(e,!1)}isSelected(t){return this.selection.indexOf(t)>=0}setItemSelected(t,e){if(null!=t&&e!==this.isSelected(t)){if(e)this.selection.push(t);else{const e=this.selection.indexOf(t);e>=0&&this.selection.splice(e,1)}this.selectCallback&&this.selectCallback(t,e)}}select(t){this.multi?this.toggle(t):this.get()!==t&&(this.setItemSelected(this.get(),!1),this.setItemSelected(t,!0))}toggle(t){this.setItemSelected(t,!this.isSelected(t))}}let b=class extends s{constructor(){super(...arguments),this.activateEvent="tap",this.selectedAttribute=null,this.selected=null,this._selection=new y(((t,e)=>this.applySelection(t,e))),this._items=[]}get items(){return this._items}connectedCallback(){super.connectedCallback(),this.addEventListener("slotchange",(t=>{t.stopPropagation(),this.updateItems(),this.dispatchEvent(new CustomEvent("selector-items-changed",{detail:{},composed:!0}))})),this.addListener(this.activateEvent)}disconnectedCallback(){super.disconnectedCallback(),this.removeListener(this.activateEvent)}attributeChangedCallback(t,e,i){if(super.attributeChangedCallback(t,e,i),"selected"===t)this.updateSelected()}applySelection(t,e){this.selectedAttribute&&t instanceof Element&&e!==t.hasAttribute(this.selectedAttribute)&&t.toggleAttribute(this.selectedAttribute)}updateItems(){var t;const e=this.querySelector("slot");this._items=null!==(t=null==e?void 0:e.assignedNodes())&&void 0!==t?t:[]}addListener(t){this.addEventListener(t,(t=>this.activateHandler(t)))}removeListener(t){this.removeEventListener(t,(t=>this.activateHandler(t)))}activateHandler(t){let e=t.target;const i=this.items;for(;e&&e!==this;){const t=i.indexOf(e);if(t>=0){const i=this.indexToValue(t);return void this.itemActivate(i,e)}e=e.parentNode}}itemActivate(t,e){this.dispatchEvent(new CustomEvent("selector-item-activate",{detail:{selected:t,item:e},composed:!0,cancelable:!0}))&&this.select(t)}select(t){this.selected=t}updateSelected(){this.selectSelected(this.selected)}selectSelected(t){if(!this._items)return;const e=this.valueToItem(this.selected);e?this._selection.select(e):this._selection.clear()}valueToItem(t){return null==t?null:this._items[this.valueToIndex(t)]}valueToIndex(t){return Number(t)}indexToValue(t){return t}indexOf(t){return this._items?this._items.indexOf(t):-1}};t([a({type:String,attribute:"activate-event"}),e("design:type",Object)],b.prototype,"activateEvent",void 0),t([a({type:String,attribute:"selected-attribute"}),e("design:type",String)],b.prototype,"selectedAttribute",void 0),t([a({type:Number,reflect:!0}),e("design:type",Object)],b.prototype,"selected",void 0),b=t([n("lit-selector")],b);export{r as LitGoogleMap,l as LitGoogleMapCircle,c as LitGoogleMapLocationButton,h as LitGoogleMapMarker,p as LitGoogleMapPolygon,m as LitGoogleMapsApi,b as LitSelector}; diff --git a/package.json b/package.json index 00ad72f..1e76411 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lit-google-map", - "version": "0.0.4", + "version": "0.0.5", "description": "Google Maps web components based on Lit v2", "private": false, "license": "MIT", diff --git a/src/index.ts b/src/index.ts index f7f36ca..61d1e4e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ export { LitGoogleMap } from "./lit-google-map"; export { LitGoogleMapCircle } from "./lit-google-map-circle"; +export { LitGoogleMapLocationButton } from "./lit-google-map-location-button"; export { LitGoogleMapMarker } from "./lit-google-map-marker"; export { LitGoogleMapPolygon } from "./lit-google-map-polygon"; export { LitGoogleMapsApi } from "./lit-google-maps-api"; diff --git a/src/lit-google-map-location-button.ts b/src/lit-google-map-location-button.ts new file mode 100644 index 0000000..872bcc6 --- /dev/null +++ b/src/lit-google-map-location-button.ts @@ -0,0 +1,238 @@ +import { LitElement } from "lit"; +import { customElement, property } from "lit/decorators.js"; + +@customElement("lit-google-map-location-button") +export class LitGoogleMapLocationButton extends LitElement { + @property({ type: String, reflect: true }) + position = "RIGHT_BOTTOM"; + + @property({ type: String, reflect: true }) + label = "My Location"; + + @property({ type: Boolean, reflect: true }) + disabled = false; + + map: google.maps.Map = null; + controlDiv: HTMLDivElement = null; + controlButton: HTMLButtonElement = null; + isRequesting = false; + + changeMap(newMap: google.maps.Map) { + this.map = newMap; + this.mapChanged(); + } + + mapChanged() { + // Remove existing control if map changed + if (this.controlDiv && this.map) { + // Cannot directly remove from controls array, so we'll just create new one + this.controlDiv = null; + this.controlButton = null; + } + + if (this.map && this.map instanceof google.maps.Map) { + this.mapReady(); + } + } + + mapReady() { + this.controlDiv = this.createControlButton(); + + // Map position string to ControlPosition enum + const controlPosition = + google.maps.ControlPosition[ + this.position as keyof typeof google.maps.ControlPosition + ]; + + if (controlPosition !== undefined) { + this.map.controls[controlPosition].push(this.controlDiv); + } + } + + createControlButton(): HTMLDivElement { + const controlDiv = document.createElement("div"); + controlDiv.style.margin = "10px"; + + const controlButton = document.createElement("button"); + controlButton.type = "button"; + controlButton.title = this.label; + controlButton.setAttribute("aria-label", this.label); + + // Create location icon using SVG + controlButton.innerHTML = ` + + + + `; + + // Apply Google Maps control styling + Object.assign(controlButton.style, { + backgroundColor: "#fff", + border: "0", + borderRadius: "2px", + boxShadow: "0 1px 4px rgba(0,0,0,0.3)", + cursor: "pointer", + padding: "10px", + display: "flex", + alignItems: "center", + justifyContent: "center", + width: "40px", + height: "40px", + color: "#666", + }); + + // Hover effects + controlButton.addEventListener("mouseenter", () => { + if (!this.disabled && !this.isRequesting) { + controlButton.style.backgroundColor = "#f8f8f8"; + } + }); + + controlButton.addEventListener("mouseleave", () => { + if (!this.disabled && !this.isRequesting) { + controlButton.style.backgroundColor = "#fff"; + } + }); + + // Click handler + controlButton.addEventListener("click", () => { + if (!this.disabled && !this.isRequesting) { + this.handleLocationRequest(); + } + }); + + this.controlButton = controlButton; + controlDiv.appendChild(controlButton); + + return controlDiv; + } + + async handleLocationRequest() { + if (!navigator.geolocation) { + this.dispatchEvent( + new CustomEvent("location-error", { + detail: { + code: -1, + message: "Geolocation is not supported by your browser", + }, + bubbles: true, + composed: true, + }), + ); + return; + } + + // Set loading state + this.isRequesting = true; + this.setLoadingState(true); + + this.dispatchEvent( + new CustomEvent("location-requested", { + bubbles: true, + composed: true, + }), + ); + + try { + const position = await this.getCurrentPosition(); + const lat = position.coords.latitude; + const lng = position.coords.longitude; + + // Center the map + this.map.setCenter({ lat, lng }); + this.map.setZoom(14); + + this.dispatchEvent( + new CustomEvent("location-found", { + detail: { lat, lng }, + bubbles: true, + composed: true, + }), + ); + } catch (error) { + let message = "Unable to retrieve your location"; + let code = -1; + + if (error instanceof GeolocationPositionError) { + code = error.code; + if (error.code === error.PERMISSION_DENIED) { + message = + "Location access denied. Please enable location permissions."; + } else if (error.code === error.TIMEOUT) { + message = "Location request timed out. Please try again."; + } else if (error.code === error.POSITION_UNAVAILABLE) { + message = "Location information is unavailable."; + } + } + + this.dispatchEvent( + new CustomEvent("location-error", { + detail: { code, message }, + bubbles: true, + composed: true, + }), + ); + } finally { + this.isRequesting = false; + this.setLoadingState(false); + } + } + + getCurrentPosition(): Promise { + return new Promise((resolve, reject) => { + navigator.geolocation.getCurrentPosition(resolve, reject, { + timeout: 10000, + enableHighAccuracy: true, + }); + }); + } + + setLoadingState(loading: boolean) { + if (!this.controlButton) return; + + if (loading) { + this.controlButton.style.backgroundColor = "#f0f0f0"; + this.controlButton.style.cursor = "wait"; + // Add spinning animation + const svg = this.controlButton.querySelector("svg"); + if (svg) { + svg.style.animation = "spin 1s linear infinite"; + // Add keyframes if not already present + const style = document.createElement("style"); + style.textContent = ` + @keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + `; + if (!document.querySelector("style[data-location-button-spin]")) { + style.setAttribute("data-location-button-spin", "true"); + document.head.appendChild(style); + } + } + } else { + this.controlButton.style.backgroundColor = "#fff"; + this.controlButton.style.cursor = "pointer"; + const svg = this.controlButton.querySelector("svg"); + if (svg) { + svg.style.animation = ""; + } + } + } + + attributeChangedCallback(name: string, oldval: string, newval: string) { + super.attributeChangedCallback(name, oldval, newval); + + if (name === "disabled" && this.controlButton) { + if (this.disabled) { + this.controlButton.style.backgroundColor = "#f0f0f0"; + this.controlButton.style.cursor = "not-allowed"; + this.controlButton.style.opacity = "0.6"; + } else { + this.controlButton.style.backgroundColor = "#fff"; + this.controlButton.style.cursor = "pointer"; + this.controlButton.style.opacity = "1"; + } + } + } +} diff --git a/src/lit-google-map.ts b/src/lit-google-map.ts index ae193fb..7f7f7a0 100644 --- a/src/lit-google-map.ts +++ b/src/lit-google-map.ts @@ -1,5 +1,6 @@ import { css, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; +import type { LitGoogleMapLocationButton } from "./lit-google-map-location-button"; import type { LitGoogleMapMarker } from "./lit-google-map-marker"; import type { LitGoogleMapsApi } from "./lit-google-maps-api"; import type { LitSelector } from "./lit-selector"; @@ -61,6 +62,7 @@ export class LitGoogleMap extends LitElement { markers: Array; shapes: Array; + controls: Array; markerObserverSet: boolean; @@ -175,6 +177,7 @@ export class LitGoogleMap extends LitElement { this.updateMarkers(); this.updateShapes(); + this.updateControls(); } getMapOptions(): google.maps.MapOptions { @@ -298,6 +301,19 @@ export class LitGoogleMap extends LitElement { } } + updateControls() { + const controlsSelector = this.shadowRoot.getElementById( + "controls-selector", + ) as LitSelector; + if (!controlsSelector) return; + + this.controls = controlsSelector.items; + + for (const c of this.controls) { + (c as LitGoogleMapLocationButton).changeMap(this.map); + } + } + fitToMarkersChanged(retryAttempt = 0) { if (this.map && this.fitToMarkers && this.markers.length > 0) { const latLngBounds = new google.maps.LatLngBounds(); @@ -381,6 +397,13 @@ export class LitGoogleMap extends LitElement { > + + +
`; }