mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-12 11:56:34 +00:00
Location selector: Move location on map click (#22198)
* Add button to location-selector to move marker to current view * move on click * double-click handling
This commit is contained in:
parent
a7406b3201
commit
a3ca889ca3
@ -79,6 +79,7 @@ export class HaLocationSelector extends LitElement {
|
||||
.locations=${this._location(this.selector, this.value)}
|
||||
@location-updated=${this._locationChanged}
|
||||
@radius-updated=${this._radiusChanged}
|
||||
pin-on-click
|
||||
></ha-locations-editor>
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
|
@ -58,6 +58,9 @@ export class HaLocationsEditor extends LitElement {
|
||||
@property({ attribute: "theme-mode", type: String })
|
||||
public themeMode: ThemeMode = "auto";
|
||||
|
||||
@property({ type: Boolean, attribute: "pin-on-click" })
|
||||
public pinOnClick = false;
|
||||
|
||||
@state() private _locationMarkers?: Record<string, Marker | Circle>;
|
||||
|
||||
@state() private _circles: Record<string, Circle> = {};
|
||||
@ -129,6 +132,8 @@ export class HaLocationsEditor extends LitElement {
|
||||
.zoom=${this.zoom}
|
||||
.autoFit=${this.autoFit}
|
||||
.themeMode=${this.themeMode}
|
||||
.clickable=${this.pinOnClick}
|
||||
@map-clicked=${this._mapClicked}
|
||||
></ha-map>
|
||||
${this.helper
|
||||
? html`<ha-input-helper-text>${this.helper}</ha-input-helper-text>`
|
||||
@ -193,15 +198,21 @@ export class HaLocationsEditor extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _normalizeLongitude(longitude: number): number {
|
||||
if (Math.abs(longitude) > 180.0) {
|
||||
// Normalize longitude if map provides values beyond -180 to +180 degrees.
|
||||
return (((longitude % 360.0) + 540.0) % 360.0) - 180.0;
|
||||
}
|
||||
return longitude;
|
||||
}
|
||||
|
||||
private _updateLocation(ev: DragEndEvent) {
|
||||
const marker = ev.target;
|
||||
const latlng: LatLng = marker.getLatLng();
|
||||
let longitude: number = latlng.lng;
|
||||
if (Math.abs(longitude) > 180.0) {
|
||||
// Normalize longitude if map provides values beyond -180 to +180 degrees.
|
||||
longitude = (((longitude % 360.0) + 540.0) % 360.0) - 180.0;
|
||||
}
|
||||
const location: [number, number] = [latlng.lat, longitude];
|
||||
const location: [number, number] = [
|
||||
latlng.lat,
|
||||
this._normalizeLongitude(latlng.lng),
|
||||
];
|
||||
fireEvent(
|
||||
this,
|
||||
"location-updated",
|
||||
@ -226,6 +237,22 @@ export class HaLocationsEditor extends LitElement {
|
||||
fireEvent(this, "marker-clicked", { id: marker.id }, { bubbles: false });
|
||||
}
|
||||
|
||||
private _mapClicked(ev) {
|
||||
if (this.pinOnClick && this._locationMarkers) {
|
||||
const id = Object.keys(this._locationMarkers)[0];
|
||||
const location: [number, number] = [
|
||||
ev.detail.location[0],
|
||||
this._normalizeLongitude(ev.detail.location[1]),
|
||||
];
|
||||
fireEvent(this, "location-updated", { id, location }, { bubbles: false });
|
||||
|
||||
// If the normalized longitude wraps around the globe, pan to the new location.
|
||||
if (location[1] !== ev.detail.location[1]) {
|
||||
this.map.leafletMap?.panTo({ lat: location[0], lng: location[1] });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _updateMarkers(): void {
|
||||
if (!this.locations || !this.locations.length) {
|
||||
this._circles = {};
|
||||
|
@ -12,6 +12,7 @@ import type {
|
||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||
import { ReactiveElement, css } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { formatDateTime } from "../../common/datetime/format_date_time";
|
||||
import {
|
||||
formatTimeWeekday,
|
||||
@ -26,6 +27,13 @@ import { isTouch } from "../../util/is_touch";
|
||||
import "../ha-icon-button";
|
||||
import "./ha-entity-marker";
|
||||
|
||||
declare global {
|
||||
// for fire event
|
||||
interface HASSDomEvents {
|
||||
"map-clicked": { location: [number, number] };
|
||||
}
|
||||
}
|
||||
|
||||
const getEntityId = (entity: string | HaMapEntity): string =>
|
||||
typeof entity === "string" ? entity : entity.entity_id;
|
||||
|
||||
@ -59,6 +67,8 @@ export class HaMap extends ReactiveElement {
|
||||
|
||||
@property({ attribute: false }) public layers?: Layer[];
|
||||
|
||||
@property({ type: Boolean }) public clickable = false;
|
||||
|
||||
@property({ type: Boolean }) public autoFit = false;
|
||||
|
||||
@property({ type: Boolean }) public renderPassive = false;
|
||||
@ -90,6 +100,8 @@ export class HaMap extends ReactiveElement {
|
||||
|
||||
private _mapPaths: Array<Polyline | CircleMarker> = [];
|
||||
|
||||
private _clickCount = 0;
|
||||
|
||||
public connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this._loadMap();
|
||||
@ -173,6 +185,7 @@ export class HaMap extends ReactiveElement {
|
||||
|
||||
private _updateMapStyle(): void {
|
||||
const map = this.renderRoot.querySelector("#map");
|
||||
map!.classList.toggle("clickable", this.clickable);
|
||||
map!.classList.toggle("dark", this._darkMode);
|
||||
map!.classList.toggle("forced-dark", this.themeMode === "dark");
|
||||
map!.classList.toggle("forced-light", this.themeMode === "light");
|
||||
@ -192,6 +205,19 @@ export class HaMap extends ReactiveElement {
|
||||
try {
|
||||
[this.leafletMap, this.Leaflet] = await setupLeafletMap(map);
|
||||
this._updateMapStyle();
|
||||
this.leafletMap.on("click", (ev) => {
|
||||
if (this._clickCount === 0) {
|
||||
setTimeout(() => {
|
||||
if (this._clickCount === 1) {
|
||||
fireEvent(this, "map-clicked", {
|
||||
location: [ev.latlng.lat, ev.latlng.lng],
|
||||
});
|
||||
}
|
||||
this._clickCount = 0;
|
||||
}, 250);
|
||||
}
|
||||
this._clickCount++;
|
||||
});
|
||||
this._loaded = true;
|
||||
} finally {
|
||||
this._loading = false;
|
||||
@ -558,6 +584,9 @@ export class HaMap extends ReactiveElement {
|
||||
#map {
|
||||
height: 100%;
|
||||
}
|
||||
#map.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
#map.dark {
|
||||
background: #090909;
|
||||
}
|
||||
@ -571,6 +600,7 @@ export class HaMap extends ReactiveElement {
|
||||
color: #000000;
|
||||
--map-filter: invert(0);
|
||||
}
|
||||
#map.clickable:active,
|
||||
#map:active {
|
||||
cursor: grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
|
Loading…
x
Reference in New Issue
Block a user