Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
giswqs
GitHub Repository: giswqs/geemap
Path: blob/master/js/basemap_selector.ts
2313 views
1
import type { RenderProps } from "@anywidget/types";
2
import { css, html, PropertyValues, TemplateResult } from "lit";
3
import { property } from "lit/decorators.js";
4
5
import { legacyStyles } from "./ipywidgets_styles";
6
import { LitWidget } from "./lit_widget";
7
import { flexStyles, materialStyles } from "./styles";
8
import { loadFonts, renderSelect } from "./utils";
9
10
import "./container";
11
12
export interface BasemapSelectorModel {
13
basemaps: { [id: string]: string[] };
14
provider: string;
15
resource: string;
16
}
17
18
export class BasemapSelector extends LitWidget<
19
BasemapSelectorModel,
20
BasemapSelector
21
> {
22
static get componentName(): string {
23
return `basemap-selector`;
24
}
25
26
static override styles = [
27
flexStyles,
28
legacyStyles,
29
materialStyles,
30
css`
31
.horizontal-flex {
32
gap: 8px;
33
}
34
35
.legacy-text {
36
min-width: 70px;
37
}
38
39
.legacy-button {
40
padding: 0 12px;
41
}
42
`,
43
];
44
45
modelNameToViewName(): Map<
46
keyof BasemapSelectorModel,
47
keyof BasemapSelector
48
> {
49
return new Map([
50
["basemaps", "basemaps"],
51
["provider", "provider"],
52
["resource", "resource"],
53
]);
54
}
55
56
@property({ type: Object }) basemaps: { [id: string]: string[] } = {};
57
@property({ type: String }) provider: string = "";
58
@property({ type: String }) resource: string = "";
59
60
override render(): TemplateResult {
61
return html`
62
<widget-container
63
icon="map"
64
title="Basemap"
65
@close-clicked="${this.onCloseClicked}"
66
>
67
<div class="vertical-flex">
68
<div class="horizontal-flex">
69
<span class="legacy-text">Provider</span>
70
${renderSelect(
71
Object.keys(this.basemaps),
72
this.provider,
73
this.onProviderChanged
74
)}
75
</div>
76
<div class="horizontal-flex">
77
<span class="legacy-text">Resource</span>
78
${renderSelect(
79
this.getAvailableResources(),
80
this.resource,
81
this.onResourceChanged
82
)}
83
</div>
84
<div class="horizontal-flex ">
85
<button
86
class="legacy-button"
87
@click="${this.onCloseClicked}"
88
>
89
Cancel
90
</button>
91
<button
92
class="legacy-button primary"
93
@click="${this.onApplyClicked}"
94
>
95
Add basemap
96
</button>
97
</div>
98
</div>
99
</widget-container>
100
`;
101
}
102
103
override update(changedProperties: PropertyValues): void {
104
if (changedProperties.has("provider")) {
105
const resources = this.getAvailableResources();
106
this.resource = resources.length > 0 ? resources[0] : "";
107
}
108
super.update(changedProperties);
109
}
110
111
private getAvailableResources(): string[] {
112
if (this.provider in this.basemaps) {
113
return this.basemaps[this.provider];
114
}
115
return [];
116
}
117
118
private onProviderChanged(event: Event): void {
119
this.provider = (event.target as HTMLInputElement).value;
120
}
121
122
private onResourceChanged(event: Event): void {
123
this.resource = (event.target as HTMLInputElement).value;
124
}
125
126
private onApplyClicked(_: Event): void {
127
this.model?.send({ type: "click", id: "apply" });
128
}
129
130
private onCloseClicked(_: Event): void {
131
this.model?.send({ type: "click", id: "close" });
132
}
133
}
134
135
// Without this check, there's a component registry issue when developing locally.
136
if (!customElements.get(BasemapSelector.componentName)) {
137
customElements.define(BasemapSelector.componentName, BasemapSelector);
138
}
139
140
function render({ model, el }: RenderProps<BasemapSelectorModel>) {
141
loadFonts();
142
const row = <BasemapSelector>(
143
document.createElement(BasemapSelector.componentName)
144
);
145
row.model = model;
146
el.appendChild(row);
147
}
148
149
export default { render };
150
151