@saschabrunnerch/arcgis-maps-sdk-js-ai-context 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -201
- package/bin/cli.js +157 -173
- package/contexts/4.34/{claude → skills}/arcgis-3d-advanced/SKILL.md +586 -586
- package/contexts/4.34/{claude → skills}/arcgis-advanced-layers/SKILL.md +431 -431
- package/contexts/4.34/{claude → skills}/arcgis-analysis-services/SKILL.md +607 -607
- package/contexts/4.34/{claude → skills}/arcgis-authentication/SKILL.md +301 -301
- package/contexts/4.34/{claude → skills}/arcgis-cim-symbols/SKILL.md +486 -486
- package/contexts/4.34/{claude → skills}/arcgis-coordinates-projection/SKILL.md +406 -406
- package/contexts/4.34/{claude → skills}/arcgis-core-maps/SKILL.md +739 -739
- package/contexts/4.34/{claude → skills}/arcgis-core-utilities/SKILL.md +732 -732
- package/contexts/4.34/{claude → skills}/arcgis-custom-rendering/SKILL.md +445 -445
- package/contexts/4.34/{claude → skills}/arcgis-editing-advanced/SKILL.md +702 -702
- package/contexts/4.34/{claude → skills}/arcgis-feature-effects/SKILL.md +393 -393
- package/contexts/4.34/{claude → skills}/arcgis-geometry-operations/SKILL.md +489 -489
- package/contexts/4.34/{claude → skills}/arcgis-imagery/SKILL.md +307 -307
- package/contexts/4.34/{claude → skills}/arcgis-interaction/SKILL.md +572 -572
- package/contexts/4.34/{claude → skills}/arcgis-knowledge-graphs/SKILL.md +582 -582
- package/contexts/4.34/{claude → skills}/arcgis-layers/SKILL.md +601 -601
- package/contexts/4.34/{claude → skills}/arcgis-map-tools/SKILL.md +668 -668
- package/contexts/4.34/{claude → skills}/arcgis-media-layers/SKILL.md +290 -290
- package/contexts/4.34/{claude → skills}/arcgis-portal-content/SKILL.md +679 -679
- package/contexts/4.34/{claude → skills}/arcgis-scene-effects/SKILL.md +512 -512
- package/contexts/4.34/{claude → skills}/arcgis-smart-mapping/SKILL.md +686 -686
- package/contexts/4.34/skills/arcgis-starter-app/SKILL.md +273 -0
- package/contexts/4.34/skills/arcgis-starter-app-extended/SKILL.md +649 -0
- package/contexts/4.34/{claude → skills}/arcgis-tables-forms/SKILL.md +877 -877
- package/contexts/4.34/{claude → skills}/arcgis-time-animation/SKILL.md +722 -722
- package/contexts/4.34/{claude → skills}/arcgis-utility-networks/SKILL.md +301 -301
- package/contexts/4.34/{claude → skills}/arcgis-visualization/SKILL.md +580 -580
- package/contexts/4.34/{claude → skills}/arcgis-widgets-ui/SKILL.md +574 -574
- package/lib/installer.js +294 -379
- package/package.json +45 -45
- package/contexts/4.34/copilot/arcgis-3d.instructions.md +0 -267
- package/contexts/4.34/copilot/arcgis-analysis.instructions.md +0 -294
- package/contexts/4.34/copilot/arcgis-arcade.instructions.md +0 -234
- package/contexts/4.34/copilot/arcgis-authentication.instructions.md +0 -187
- package/contexts/4.34/copilot/arcgis-cim-symbols.instructions.md +0 -177
- package/contexts/4.34/copilot/arcgis-core-maps.instructions.md +0 -246
- package/contexts/4.34/copilot/arcgis-core-utilities.instructions.md +0 -247
- package/contexts/4.34/copilot/arcgis-editing.instructions.md +0 -262
- package/contexts/4.34/copilot/arcgis-geometry.instructions.md +0 -225
- package/contexts/4.34/copilot/arcgis-layers.instructions.md +0 -278
- package/contexts/4.34/copilot/arcgis-popup-templates.instructions.md +0 -266
- package/contexts/4.34/copilot/arcgis-portal-advanced.instructions.md +0 -275
- package/contexts/4.34/copilot/arcgis-smart-mapping.instructions.md +0 -184
- package/contexts/4.34/copilot/arcgis-time-animation.instructions.md +0 -112
- package/contexts/4.34/copilot/arcgis-visualization.instructions.md +0 -321
- package/contexts/4.34/copilot/arcgis-widgets-ui.instructions.md +0 -277
- /package/contexts/4.34/{claude → skills}/arcgis-arcade/SKILL.md +0 -0
- /package/contexts/4.34/{claude → skills}/arcgis-popup-templates/SKILL.md +0 -0
|
@@ -1,574 +1,574 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: arcgis-widgets-ui
|
|
3
|
-
description: Build map user interfaces with ArcGIS widgets, Map Components, and Calcite Design System. Use for adding legends, layer lists, search, tables, time sliders, and custom UI layouts.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# ArcGIS Widgets & UI
|
|
7
|
-
|
|
8
|
-
Use this skill when building user interfaces with widgets, Map Components, and Calcite.
|
|
9
|
-
|
|
10
|
-
> **Best Practice:** Prefer Map Components (web components like `arcgis-legend`, `arcgis-search`) over Core API widgets when possible. Esri is transitioning to web components, and some widgets are already deprecated. See [Esri's component transition plan](https://developers.arcgis.com/javascript/latest/components-transition-plan/).
|
|
11
|
-
|
|
12
|
-
## Map Components Approach
|
|
13
|
-
|
|
14
|
-
### Available Map Components
|
|
15
|
-
|
|
16
|
-
| Component | Purpose |
|
|
17
|
-
|-----------|---------|
|
|
18
|
-
| `arcgis-map` | 2D map container |
|
|
19
|
-
| `arcgis-scene` | 3D scene container |
|
|
20
|
-
| `arcgis-zoom` | Zoom in/out buttons |
|
|
21
|
-
| `arcgis-compass` | Orientation indicator |
|
|
22
|
-
| `arcgis-home` | Return to initial extent |
|
|
23
|
-
| `arcgis-locate` | Find user location |
|
|
24
|
-
| `arcgis-track` | Track user location |
|
|
25
|
-
| `arcgis-navigation-toggle` | Pan/rotate mode (3D) |
|
|
26
|
-
| `arcgis-fullscreen` | Toggle fullscreen |
|
|
27
|
-
| `arcgis-scale-bar` | Display map scale |
|
|
28
|
-
| `arcgis-legend` | Layer symbology legend |
|
|
29
|
-
| `arcgis-layer-list` | Layer visibility control |
|
|
30
|
-
| `arcgis-basemap-gallery` | Switch basemaps |
|
|
31
|
-
| `arcgis-basemap-toggle` | Toggle two basemaps |
|
|
32
|
-
| `arcgis-search` | Location search |
|
|
33
|
-
| `arcgis-popup` | Feature popups |
|
|
34
|
-
| `arcgis-editor` | Feature editing |
|
|
35
|
-
| `arcgis-sketch` | Draw geometries |
|
|
36
|
-
| `arcgis-feature-table` | Tabular data view |
|
|
37
|
-
| `arcgis-time-slider` | Temporal navigation |
|
|
38
|
-
| `arcgis-time-zone-label` | Display time zone |
|
|
39
|
-
| `arcgis-expand` | Collapsible container |
|
|
40
|
-
| `arcgis-print` | Map printing |
|
|
41
|
-
| `arcgis-bookmarks` | Navigate to bookmarks |
|
|
42
|
-
| `arcgis-directions` | Turn-by-turn routing |
|
|
43
|
-
| `arcgis-swipe` | Compare layers |
|
|
44
|
-
| `arcgis-coordinate-conversion` | Coordinate formats |
|
|
45
|
-
| `arcgis-daylight` | 3D lighting control |
|
|
46
|
-
| `arcgis-weather` | 3D weather effects |
|
|
47
|
-
| `arcgis-distance-measurement-2d` | 2D distance measurement |
|
|
48
|
-
| `arcgis-area-measurement-2d` | 2D area measurement |
|
|
49
|
-
| `arcgis-direct-line-measurement-3d` | 3D line measurement |
|
|
50
|
-
| `arcgis-area-measurement-3d` | 3D area measurement |
|
|
51
|
-
| `arcgis-utility-network-trace` | Utility network tracing |
|
|
52
|
-
| `arcgis-utility-network-associations` | Utility associations |
|
|
53
|
-
|
|
54
|
-
> **Note:** Not all widgets have component equivalents yet. FeatureForm, Histogram, and some specialized widgets only have Core API versions.
|
|
55
|
-
|
|
56
|
-
### Slot-Based Positioning
|
|
57
|
-
|
|
58
|
-
```html
|
|
59
|
-
<arcgis-map basemap="streets-vector">
|
|
60
|
-
<!-- Position widgets using slots -->
|
|
61
|
-
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
62
|
-
<arcgis-home slot="top-left"></arcgis-home>
|
|
63
|
-
<arcgis-compass slot="top-left"></arcgis-compass>
|
|
64
|
-
|
|
65
|
-
<arcgis-search slot="top-right"></arcgis-search>
|
|
66
|
-
<arcgis-layer-list slot="top-right"></arcgis-layer-list>
|
|
67
|
-
|
|
68
|
-
<arcgis-legend slot="bottom-left"></arcgis-legend>
|
|
69
|
-
<arcgis-scale-bar slot="bottom-right"></arcgis-scale-bar>
|
|
70
|
-
|
|
71
|
-
<!-- Popup must use popup slot -->
|
|
72
|
-
<arcgis-popup slot="popup"></arcgis-popup>
|
|
73
|
-
</arcgis-map>
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Available slots: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `popup`, `manual`
|
|
77
|
-
|
|
78
|
-
### Expand Component
|
|
79
|
-
|
|
80
|
-
Wrap widgets in `arcgis-expand` for collapsible behavior:
|
|
81
|
-
|
|
82
|
-
```html
|
|
83
|
-
<arcgis-map basemap="streets-vector">
|
|
84
|
-
<arcgis-expand slot="top-right" expand-tooltip="Show Legend" mode="floating">
|
|
85
|
-
<arcgis-legend></arcgis-legend>
|
|
86
|
-
</arcgis-expand>
|
|
87
|
-
|
|
88
|
-
<arcgis-expand slot="top-left" expanded>
|
|
89
|
-
<arcgis-layer-list></arcgis-layer-list>
|
|
90
|
-
</arcgis-expand>
|
|
91
|
-
</arcgis-map>
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### Reference Element (External Components)
|
|
95
|
-
|
|
96
|
-
Place components outside the map and reference them:
|
|
97
|
-
|
|
98
|
-
```html
|
|
99
|
-
<calcite-shell>
|
|
100
|
-
<calcite-shell-panel slot="panel-start">
|
|
101
|
-
<arcgis-legend reference-element="arcgis-map"></arcgis-legend>
|
|
102
|
-
</calcite-shell-panel>
|
|
103
|
-
|
|
104
|
-
<arcgis-map id="arcgis-map" basemap="topo-vector">
|
|
105
|
-
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
106
|
-
</arcgis-map>
|
|
107
|
-
</calcite-shell>
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Core Widget Approach
|
|
111
|
-
|
|
112
|
-
### Adding Widgets to View
|
|
113
|
-
|
|
114
|
-
```javascript
|
|
115
|
-
import Legend from "@arcgis/core/widgets/Legend.js";
|
|
116
|
-
import LayerList from "@arcgis/core/widgets/LayerList.js";
|
|
117
|
-
import Search from "@arcgis/core/widgets/Search.js";
|
|
118
|
-
|
|
119
|
-
// Create widget
|
|
120
|
-
const legend = new Legend({ view: view });
|
|
121
|
-
|
|
122
|
-
// Add to view UI
|
|
123
|
-
view.ui.add(legend, "bottom-left");
|
|
124
|
-
|
|
125
|
-
// Add multiple widgets
|
|
126
|
-
view.ui.add([
|
|
127
|
-
{ component: legend, position: "bottom-left" },
|
|
128
|
-
{ component: search, position: "top-right" }
|
|
129
|
-
]);
|
|
130
|
-
|
|
131
|
-
// Add to specific index (order in position)
|
|
132
|
-
view.ui.add(legend, { position: "bottom-left", index: 0 });
|
|
133
|
-
|
|
134
|
-
// Remove widget
|
|
135
|
-
view.ui.remove(legend);
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
### Widget in Custom Container
|
|
139
|
-
|
|
140
|
-
```html
|
|
141
|
-
<div id="legendDiv"></div>
|
|
142
|
-
|
|
143
|
-
<script type="module">
|
|
144
|
-
import Legend from "@arcgis/core/widgets/Legend.js";
|
|
145
|
-
|
|
146
|
-
const legend = new Legend({
|
|
147
|
-
view: view,
|
|
148
|
-
container: "legendDiv" // Or document.getElementById("legendDiv")
|
|
149
|
-
});
|
|
150
|
-
</script>
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
## Common Widgets
|
|
154
|
-
|
|
155
|
-
### Legend
|
|
156
|
-
|
|
157
|
-
```html
|
|
158
|
-
<!-- Map Component -->
|
|
159
|
-
<arcgis-legend slot="bottom-left"></arcgis-legend>
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
```javascript
|
|
163
|
-
// Core API
|
|
164
|
-
import Legend from "@arcgis/core/widgets/Legend.js";
|
|
165
|
-
|
|
166
|
-
const legend = new Legend({
|
|
167
|
-
view: view,
|
|
168
|
-
layerInfos: [{
|
|
169
|
-
layer: featureLayer,
|
|
170
|
-
title: "Custom Title"
|
|
171
|
-
}]
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
view.ui.add(legend, "bottom-left");
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### LayerList
|
|
178
|
-
|
|
179
|
-
```html
|
|
180
|
-
<!-- Map Component -->
|
|
181
|
-
<arcgis-layer-list slot="top-right"></arcgis-layer-list>
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
```javascript
|
|
185
|
-
// Core API with actions
|
|
186
|
-
import LayerList from "@arcgis/core/widgets/LayerList.js";
|
|
187
|
-
|
|
188
|
-
const layerList = new LayerList({
|
|
189
|
-
view: view,
|
|
190
|
-
listItemCreatedFunction: (event) => {
|
|
191
|
-
const item = event.item;
|
|
192
|
-
item.actionsSections = [[{
|
|
193
|
-
title: "Zoom to layer",
|
|
194
|
-
icon: "zoom-to-object",
|
|
195
|
-
id: "zoom-to"
|
|
196
|
-
}]];
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
layerList.on("trigger-action", (event) => {
|
|
201
|
-
if (event.action.id === "zoom-to") {
|
|
202
|
-
view.goTo(event.item.layer.fullExtent);
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
view.ui.add(layerList, "top-right");
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### BasemapGallery
|
|
210
|
-
|
|
211
|
-
```html
|
|
212
|
-
<!-- Map Component -->
|
|
213
|
-
<arcgis-basemap-gallery slot="top-right"></arcgis-basemap-gallery>
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
```javascript
|
|
217
|
-
// Core API
|
|
218
|
-
import BasemapGallery from "@arcgis/core/widgets/BasemapGallery.js";
|
|
219
|
-
|
|
220
|
-
const basemapGallery = new BasemapGallery({
|
|
221
|
-
view: view
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
view.ui.add(basemapGallery, "top-right");
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Search
|
|
228
|
-
|
|
229
|
-
```html
|
|
230
|
-
<!-- Map Component -->
|
|
231
|
-
<arcgis-search slot="top-right"></arcgis-search>
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
```javascript
|
|
235
|
-
// Core API with custom sources
|
|
236
|
-
import Search from "@arcgis/core/widgets/Search.js";
|
|
237
|
-
|
|
238
|
-
const search = new Search({
|
|
239
|
-
view: view,
|
|
240
|
-
sources: [{
|
|
241
|
-
layer: featureLayer,
|
|
242
|
-
searchFields: ["name", "address"],
|
|
243
|
-
displayField: "name",
|
|
244
|
-
exactMatch: false,
|
|
245
|
-
outFields: ["*"],
|
|
246
|
-
name: "My Layer",
|
|
247
|
-
placeholder: "Search features"
|
|
248
|
-
}]
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
view.ui.add(search, "top-right");
|
|
252
|
-
|
|
253
|
-
// Events
|
|
254
|
-
search.on("select-result", (event) => {
|
|
255
|
-
console.log("Selected:", event.result);
|
|
256
|
-
});
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
### FeatureTable
|
|
260
|
-
|
|
261
|
-
```html
|
|
262
|
-
<!-- Map Component -->
|
|
263
|
-
<arcgis-feature-table reference-element="arcgis-map"></arcgis-feature-table>
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
```javascript
|
|
267
|
-
// Core API
|
|
268
|
-
import FeatureTable from "@arcgis/core/widgets/FeatureTable.js";
|
|
269
|
-
|
|
270
|
-
const featureTable = new FeatureTable({
|
|
271
|
-
view: view,
|
|
272
|
-
layer: featureLayer,
|
|
273
|
-
container: "tableDiv",
|
|
274
|
-
visibleElements: {
|
|
275
|
-
header: true,
|
|
276
|
-
columnMenus: true,
|
|
277
|
-
selectionColumn: true
|
|
278
|
-
},
|
|
279
|
-
fieldConfigs: [
|
|
280
|
-
{ name: "name", label: "Name" },
|
|
281
|
-
{ name: "population", label: "Population" }
|
|
282
|
-
]
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
// Selection events
|
|
286
|
-
featureTable.on("selection-change", (event) => {
|
|
287
|
-
console.log("Selected rows:", event.added);
|
|
288
|
-
});
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### TimeSlider
|
|
292
|
-
|
|
293
|
-
```html
|
|
294
|
-
<!-- Map Component -->
|
|
295
|
-
<arcgis-time-slider
|
|
296
|
-
slot="bottom-right"
|
|
297
|
-
layout="auto"
|
|
298
|
-
mode="time-window"
|
|
299
|
-
time-visible
|
|
300
|
-
loop>
|
|
301
|
-
</arcgis-time-slider>
|
|
302
|
-
|
|
303
|
-
<script type="module">
|
|
304
|
-
const timeSlider = document.querySelector("arcgis-time-slider");
|
|
305
|
-
await layer.load();
|
|
306
|
-
|
|
307
|
-
timeSlider.fullTimeExtent = layer.timeInfo.fullTimeExtent;
|
|
308
|
-
timeSlider.stops = {
|
|
309
|
-
interval: layer.timeInfo.interval
|
|
310
|
-
};
|
|
311
|
-
</script>
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
```javascript
|
|
315
|
-
// Core API
|
|
316
|
-
import TimeSlider from "@arcgis/core/widgets/TimeSlider.js";
|
|
317
|
-
|
|
318
|
-
const timeSlider = new TimeSlider({
|
|
319
|
-
view: view,
|
|
320
|
-
mode: "time-window", // instant, time-window, cumulative-from-start, cumulative-from-end
|
|
321
|
-
fullTimeExtent: layer.timeInfo.fullTimeExtent,
|
|
322
|
-
stops: {
|
|
323
|
-
interval: {
|
|
324
|
-
value: 1,
|
|
325
|
-
unit: "hours"
|
|
326
|
-
}
|
|
327
|
-
},
|
|
328
|
-
playRate: 1000, // ms between stops
|
|
329
|
-
loop: true
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
view.ui.add(timeSlider, "bottom-right");
|
|
333
|
-
|
|
334
|
-
// Events
|
|
335
|
-
timeSlider.watch("timeExtent", (timeExtent) => {
|
|
336
|
-
console.log("Time changed:", timeExtent.start, timeExtent.end);
|
|
337
|
-
});
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
### Print
|
|
341
|
-
|
|
342
|
-
```html
|
|
343
|
-
<!-- Map Component -->
|
|
344
|
-
<arcgis-print slot="top-right"></arcgis-print>
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
```javascript
|
|
348
|
-
// Core API
|
|
349
|
-
import Print from "@arcgis/core/widgets/Print.js";
|
|
350
|
-
|
|
351
|
-
const print = new Print({
|
|
352
|
-
view: view,
|
|
353
|
-
printServiceUrl: "https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task"
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
view.ui.add(print, "top-right");
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
## Calcite Design System Integration
|
|
360
|
-
|
|
361
|
-
### Basic Layout with Calcite
|
|
362
|
-
|
|
363
|
-
```html
|
|
364
|
-
<!DOCTYPE html>
|
|
365
|
-
<html>
|
|
366
|
-
<head>
|
|
367
|
-
<script type="module" src="https://js.arcgis.com/calcite-components/3.3.3/calcite.esm.js"></script>
|
|
368
|
-
<script src="https://js.arcgis.com/4.34/"></script>
|
|
369
|
-
<script type="module" src="https://js.arcgis.com/4.34/map-components/"></script>
|
|
370
|
-
<style>
|
|
371
|
-
html, body { height: 100%; margin: 0; }
|
|
372
|
-
</style>
|
|
373
|
-
</head>
|
|
374
|
-
<body class="calcite-mode-light">
|
|
375
|
-
<calcite-shell>
|
|
376
|
-
<!-- Header -->
|
|
377
|
-
<calcite-navigation slot="header">
|
|
378
|
-
<calcite-navigation-logo slot="logo" heading="My Map App"></calcite-navigation-logo>
|
|
379
|
-
</calcite-navigation>
|
|
380
|
-
|
|
381
|
-
<!-- Side Panel -->
|
|
382
|
-
<calcite-shell-panel slot="panel-start">
|
|
383
|
-
<calcite-panel heading="Layers">
|
|
384
|
-
<arcgis-layer-list reference-element="map"></arcgis-layer-list>
|
|
385
|
-
</calcite-panel>
|
|
386
|
-
</calcite-shell-panel>
|
|
387
|
-
|
|
388
|
-
<!-- Map -->
|
|
389
|
-
<arcgis-map id="map" basemap="streets-vector">
|
|
390
|
-
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
391
|
-
</arcgis-map>
|
|
392
|
-
|
|
393
|
-
<!-- End Panel -->
|
|
394
|
-
<calcite-shell-panel slot="panel-end">
|
|
395
|
-
<calcite-panel heading="Legend">
|
|
396
|
-
<arcgis-legend reference-element="map"></arcgis-legend>
|
|
397
|
-
</calcite-panel>
|
|
398
|
-
</calcite-shell-panel>
|
|
399
|
-
</calcite-shell>
|
|
400
|
-
</body>
|
|
401
|
-
</html>
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
### Calcite Action Bar
|
|
405
|
-
|
|
406
|
-
```html
|
|
407
|
-
<calcite-shell>
|
|
408
|
-
<calcite-shell-panel slot="panel-start">
|
|
409
|
-
<calcite-action-bar slot="action-bar">
|
|
410
|
-
<calcite-action icon="layers" text="Layers" data-panel="layers"></calcite-action>
|
|
411
|
-
<calcite-action icon="legend" text="Legend" data-panel="legend"></calcite-action>
|
|
412
|
-
<calcite-action icon="bookmark" text="Bookmarks" data-panel="bookmarks"></calcite-action>
|
|
413
|
-
</calcite-action-bar>
|
|
414
|
-
|
|
415
|
-
<calcite-panel id="layers" heading="Layers">
|
|
416
|
-
<arcgis-layer-list reference-element="map"></arcgis-layer-list>
|
|
417
|
-
</calcite-panel>
|
|
418
|
-
|
|
419
|
-
<calcite-panel id="legend" heading="Legend" hidden>
|
|
420
|
-
<arcgis-legend reference-element="map"></arcgis-legend>
|
|
421
|
-
</calcite-panel>
|
|
422
|
-
</calcite-shell-panel>
|
|
423
|
-
|
|
424
|
-
<arcgis-map id="map" basemap="topo-vector"></arcgis-map>
|
|
425
|
-
</calcite-shell>
|
|
426
|
-
|
|
427
|
-
<script>
|
|
428
|
-
// Toggle panels on action click
|
|
429
|
-
document.querySelectorAll("calcite-action").forEach(action => {
|
|
430
|
-
action.addEventListener("click", () => {
|
|
431
|
-
const panelId = action.dataset.panel;
|
|
432
|
-
document.querySelectorAll("calcite-panel").forEach(panel => {
|
|
433
|
-
panel.hidden = panel.id !== panelId;
|
|
434
|
-
});
|
|
435
|
-
});
|
|
436
|
-
});
|
|
437
|
-
</script>
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
### Common Calcite Components
|
|
441
|
-
|
|
442
|
-
| Component | Purpose |
|
|
443
|
-
|-----------|---------|
|
|
444
|
-
| `calcite-shell` | App layout container |
|
|
445
|
-
| `calcite-shell-panel` | Side panels |
|
|
446
|
-
| `calcite-panel` | Content panel |
|
|
447
|
-
| `calcite-navigation` | Header/footer |
|
|
448
|
-
| `calcite-action-bar` | Icon button bar |
|
|
449
|
-
| `calcite-action` | Icon button |
|
|
450
|
-
| `calcite-button` | Standard button |
|
|
451
|
-
| `calcite-input` | Text input |
|
|
452
|
-
| `calcite-list` | List container |
|
|
453
|
-
| `calcite-list-item` | List item |
|
|
454
|
-
| `calcite-card` | Card container |
|
|
455
|
-
| `calcite-modal` | Modal dialog |
|
|
456
|
-
| `calcite-alert` | Alert message |
|
|
457
|
-
| `calcite-loader` | Loading indicator |
|
|
458
|
-
|
|
459
|
-
### Theming
|
|
460
|
-
|
|
461
|
-
```html
|
|
462
|
-
<!-- Light mode -->
|
|
463
|
-
<body class="calcite-mode-light">
|
|
464
|
-
|
|
465
|
-
<!-- Dark mode -->
|
|
466
|
-
<body class="calcite-mode-dark">
|
|
467
|
-
|
|
468
|
-
<!-- Custom theme colors -->
|
|
469
|
-
<style>
|
|
470
|
-
:root {
|
|
471
|
-
--calcite-color-brand: #007ac2;
|
|
472
|
-
--calcite-color-brand-hover: #005a8e;
|
|
473
|
-
--calcite-color-text-1: #323232;
|
|
474
|
-
}
|
|
475
|
-
</style>
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
## Custom Widget Placement
|
|
479
|
-
|
|
480
|
-
### Manual Positioning
|
|
481
|
-
|
|
482
|
-
```javascript
|
|
483
|
-
// Add widget at specific position
|
|
484
|
-
view.ui.add(widget, {
|
|
485
|
-
position: "manual",
|
|
486
|
-
index: 0
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
// Position with CSS
|
|
490
|
-
document.getElementById("myWidget").style.cssText = `
|
|
491
|
-
position: absolute;
|
|
492
|
-
top: 10px;
|
|
493
|
-
left: 50%;
|
|
494
|
-
transform: translateX(-50%);
|
|
495
|
-
`;
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
### DOM Container
|
|
499
|
-
|
|
500
|
-
```html
|
|
501
|
-
<div id="mapDiv" style="position: relative;">
|
|
502
|
-
<div id="customWidget" style="position: absolute; top: 10px; right: 10px; z-index: 1;">
|
|
503
|
-
<!-- Custom content -->
|
|
504
|
-
</div>
|
|
505
|
-
</div>
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
## Widget Events
|
|
509
|
-
|
|
510
|
-
```javascript
|
|
511
|
-
// Search select
|
|
512
|
-
search.on("select-result", (event) => {
|
|
513
|
-
console.log(event.result);
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
// LayerList trigger action
|
|
517
|
-
layerList.on("trigger-action", (event) => {
|
|
518
|
-
console.log(event.action, event.item);
|
|
519
|
-
});
|
|
520
|
-
|
|
521
|
-
// TimeSlider time change
|
|
522
|
-
timeSlider.watch("timeExtent", (value) => {
|
|
523
|
-
console.log(value.start, value.end);
|
|
524
|
-
});
|
|
525
|
-
|
|
526
|
-
// FeatureTable selection
|
|
527
|
-
featureTable.on("selection-change", (event) => {
|
|
528
|
-
console.log(event.added, event.removed);
|
|
529
|
-
});
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
## TypeScript Usage
|
|
533
|
-
|
|
534
|
-
Widget configurations use autocasting with `type` properties. For TypeScript safety, use `as const`:
|
|
535
|
-
|
|
536
|
-
```typescript
|
|
537
|
-
// Use 'as const' for widget configurations
|
|
538
|
-
const layerList = new LayerList({
|
|
539
|
-
view: view,
|
|
540
|
-
listItemCreatedFunction: (event) => {
|
|
541
|
-
const item = event.item;
|
|
542
|
-
item.actionsSections = [[{
|
|
543
|
-
title: "Zoom to layer",
|
|
544
|
-
icon: "zoom-to-object",
|
|
545
|
-
id: "zoom-to"
|
|
546
|
-
}]];
|
|
547
|
-
}
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
// For layer configurations in widgets
|
|
551
|
-
const featureTable = new FeatureTable({
|
|
552
|
-
view: view,
|
|
553
|
-
layer: featureLayer,
|
|
554
|
-
fieldConfigs: [
|
|
555
|
-
{ name: "name", label: "Name" },
|
|
556
|
-
{ name: "population", label: "Population" }
|
|
557
|
-
]
|
|
558
|
-
});
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
> **Tip:** See [arcgis-core-maps skill](../arcgis-core-maps/SKILL.md) for detailed guidance on autocasting vs explicit classes.
|
|
562
|
-
|
|
563
|
-
## Common Pitfalls
|
|
564
|
-
|
|
565
|
-
1. **Missing reference-element**: When placing components outside the map, use `reference-element` attribute
|
|
566
|
-
|
|
567
|
-
2. **Slot names are specific**: Use exact slot names (`top-left`, not `topleft`)
|
|
568
|
-
|
|
569
|
-
3. **Calcite CSS not loading**: Ensure Calcite script is loaded before using Calcite components
|
|
570
|
-
|
|
571
|
-
4. **Widget container conflicts**: Don't add the same widget to both a container and view.ui
|
|
572
|
-
|
|
573
|
-
5. **Dark/light mode mismatch**: Add `calcite-mode-light` or `calcite-mode-dark` class to body
|
|
574
|
-
|
|
1
|
+
---
|
|
2
|
+
name: arcgis-widgets-ui
|
|
3
|
+
description: Build map user interfaces with ArcGIS widgets, Map Components, and Calcite Design System. Use for adding legends, layer lists, search, tables, time sliders, and custom UI layouts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ArcGIS Widgets & UI
|
|
7
|
+
|
|
8
|
+
Use this skill when building user interfaces with widgets, Map Components, and Calcite.
|
|
9
|
+
|
|
10
|
+
> **Best Practice:** Prefer Map Components (web components like `arcgis-legend`, `arcgis-search`) over Core API widgets when possible. Esri is transitioning to web components, and some widgets are already deprecated. See [Esri's component transition plan](https://developers.arcgis.com/javascript/latest/components-transition-plan/).
|
|
11
|
+
|
|
12
|
+
## Map Components Approach
|
|
13
|
+
|
|
14
|
+
### Available Map Components
|
|
15
|
+
|
|
16
|
+
| Component | Purpose |
|
|
17
|
+
|-----------|---------|
|
|
18
|
+
| `arcgis-map` | 2D map container |
|
|
19
|
+
| `arcgis-scene` | 3D scene container |
|
|
20
|
+
| `arcgis-zoom` | Zoom in/out buttons |
|
|
21
|
+
| `arcgis-compass` | Orientation indicator |
|
|
22
|
+
| `arcgis-home` | Return to initial extent |
|
|
23
|
+
| `arcgis-locate` | Find user location |
|
|
24
|
+
| `arcgis-track` | Track user location |
|
|
25
|
+
| `arcgis-navigation-toggle` | Pan/rotate mode (3D) |
|
|
26
|
+
| `arcgis-fullscreen` | Toggle fullscreen |
|
|
27
|
+
| `arcgis-scale-bar` | Display map scale |
|
|
28
|
+
| `arcgis-legend` | Layer symbology legend |
|
|
29
|
+
| `arcgis-layer-list` | Layer visibility control |
|
|
30
|
+
| `arcgis-basemap-gallery` | Switch basemaps |
|
|
31
|
+
| `arcgis-basemap-toggle` | Toggle two basemaps |
|
|
32
|
+
| `arcgis-search` | Location search |
|
|
33
|
+
| `arcgis-popup` | Feature popups |
|
|
34
|
+
| `arcgis-editor` | Feature editing |
|
|
35
|
+
| `arcgis-sketch` | Draw geometries |
|
|
36
|
+
| `arcgis-feature-table` | Tabular data view |
|
|
37
|
+
| `arcgis-time-slider` | Temporal navigation |
|
|
38
|
+
| `arcgis-time-zone-label` | Display time zone |
|
|
39
|
+
| `arcgis-expand` | Collapsible container |
|
|
40
|
+
| `arcgis-print` | Map printing |
|
|
41
|
+
| `arcgis-bookmarks` | Navigate to bookmarks |
|
|
42
|
+
| `arcgis-directions` | Turn-by-turn routing |
|
|
43
|
+
| `arcgis-swipe` | Compare layers |
|
|
44
|
+
| `arcgis-coordinate-conversion` | Coordinate formats |
|
|
45
|
+
| `arcgis-daylight` | 3D lighting control |
|
|
46
|
+
| `arcgis-weather` | 3D weather effects |
|
|
47
|
+
| `arcgis-distance-measurement-2d` | 2D distance measurement |
|
|
48
|
+
| `arcgis-area-measurement-2d` | 2D area measurement |
|
|
49
|
+
| `arcgis-direct-line-measurement-3d` | 3D line measurement |
|
|
50
|
+
| `arcgis-area-measurement-3d` | 3D area measurement |
|
|
51
|
+
| `arcgis-utility-network-trace` | Utility network tracing |
|
|
52
|
+
| `arcgis-utility-network-associations` | Utility associations |
|
|
53
|
+
|
|
54
|
+
> **Note:** Not all widgets have component equivalents yet. FeatureForm, Histogram, and some specialized widgets only have Core API versions.
|
|
55
|
+
|
|
56
|
+
### Slot-Based Positioning
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<arcgis-map basemap="streets-vector">
|
|
60
|
+
<!-- Position widgets using slots -->
|
|
61
|
+
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
62
|
+
<arcgis-home slot="top-left"></arcgis-home>
|
|
63
|
+
<arcgis-compass slot="top-left"></arcgis-compass>
|
|
64
|
+
|
|
65
|
+
<arcgis-search slot="top-right"></arcgis-search>
|
|
66
|
+
<arcgis-layer-list slot="top-right"></arcgis-layer-list>
|
|
67
|
+
|
|
68
|
+
<arcgis-legend slot="bottom-left"></arcgis-legend>
|
|
69
|
+
<arcgis-scale-bar slot="bottom-right"></arcgis-scale-bar>
|
|
70
|
+
|
|
71
|
+
<!-- Popup must use popup slot -->
|
|
72
|
+
<arcgis-popup slot="popup"></arcgis-popup>
|
|
73
|
+
</arcgis-map>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Available slots: `top-left`, `top-right`, `bottom-left`, `bottom-right`, `popup`, `manual`
|
|
77
|
+
|
|
78
|
+
### Expand Component
|
|
79
|
+
|
|
80
|
+
Wrap widgets in `arcgis-expand` for collapsible behavior:
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<arcgis-map basemap="streets-vector">
|
|
84
|
+
<arcgis-expand slot="top-right" expand-tooltip="Show Legend" mode="floating">
|
|
85
|
+
<arcgis-legend></arcgis-legend>
|
|
86
|
+
</arcgis-expand>
|
|
87
|
+
|
|
88
|
+
<arcgis-expand slot="top-left" expanded>
|
|
89
|
+
<arcgis-layer-list></arcgis-layer-list>
|
|
90
|
+
</arcgis-expand>
|
|
91
|
+
</arcgis-map>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Reference Element (External Components)
|
|
95
|
+
|
|
96
|
+
Place components outside the map and reference them:
|
|
97
|
+
|
|
98
|
+
```html
|
|
99
|
+
<calcite-shell>
|
|
100
|
+
<calcite-shell-panel slot="panel-start">
|
|
101
|
+
<arcgis-legend reference-element="arcgis-map"></arcgis-legend>
|
|
102
|
+
</calcite-shell-panel>
|
|
103
|
+
|
|
104
|
+
<arcgis-map id="arcgis-map" basemap="topo-vector">
|
|
105
|
+
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
106
|
+
</arcgis-map>
|
|
107
|
+
</calcite-shell>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Core Widget Approach
|
|
111
|
+
|
|
112
|
+
### Adding Widgets to View
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
import Legend from "@arcgis/core/widgets/Legend.js";
|
|
116
|
+
import LayerList from "@arcgis/core/widgets/LayerList.js";
|
|
117
|
+
import Search from "@arcgis/core/widgets/Search.js";
|
|
118
|
+
|
|
119
|
+
// Create widget
|
|
120
|
+
const legend = new Legend({ view: view });
|
|
121
|
+
|
|
122
|
+
// Add to view UI
|
|
123
|
+
view.ui.add(legend, "bottom-left");
|
|
124
|
+
|
|
125
|
+
// Add multiple widgets
|
|
126
|
+
view.ui.add([
|
|
127
|
+
{ component: legend, position: "bottom-left" },
|
|
128
|
+
{ component: search, position: "top-right" }
|
|
129
|
+
]);
|
|
130
|
+
|
|
131
|
+
// Add to specific index (order in position)
|
|
132
|
+
view.ui.add(legend, { position: "bottom-left", index: 0 });
|
|
133
|
+
|
|
134
|
+
// Remove widget
|
|
135
|
+
view.ui.remove(legend);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Widget in Custom Container
|
|
139
|
+
|
|
140
|
+
```html
|
|
141
|
+
<div id="legendDiv"></div>
|
|
142
|
+
|
|
143
|
+
<script type="module">
|
|
144
|
+
import Legend from "@arcgis/core/widgets/Legend.js";
|
|
145
|
+
|
|
146
|
+
const legend = new Legend({
|
|
147
|
+
view: view,
|
|
148
|
+
container: "legendDiv" // Or document.getElementById("legendDiv")
|
|
149
|
+
});
|
|
150
|
+
</script>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Common Widgets
|
|
154
|
+
|
|
155
|
+
### Legend
|
|
156
|
+
|
|
157
|
+
```html
|
|
158
|
+
<!-- Map Component -->
|
|
159
|
+
<arcgis-legend slot="bottom-left"></arcgis-legend>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
// Core API
|
|
164
|
+
import Legend from "@arcgis/core/widgets/Legend.js";
|
|
165
|
+
|
|
166
|
+
const legend = new Legend({
|
|
167
|
+
view: view,
|
|
168
|
+
layerInfos: [{
|
|
169
|
+
layer: featureLayer,
|
|
170
|
+
title: "Custom Title"
|
|
171
|
+
}]
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
view.ui.add(legend, "bottom-left");
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### LayerList
|
|
178
|
+
|
|
179
|
+
```html
|
|
180
|
+
<!-- Map Component -->
|
|
181
|
+
<arcgis-layer-list slot="top-right"></arcgis-layer-list>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
```javascript
|
|
185
|
+
// Core API with actions
|
|
186
|
+
import LayerList from "@arcgis/core/widgets/LayerList.js";
|
|
187
|
+
|
|
188
|
+
const layerList = new LayerList({
|
|
189
|
+
view: view,
|
|
190
|
+
listItemCreatedFunction: (event) => {
|
|
191
|
+
const item = event.item;
|
|
192
|
+
item.actionsSections = [[{
|
|
193
|
+
title: "Zoom to layer",
|
|
194
|
+
icon: "zoom-to-object",
|
|
195
|
+
id: "zoom-to"
|
|
196
|
+
}]];
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
layerList.on("trigger-action", (event) => {
|
|
201
|
+
if (event.action.id === "zoom-to") {
|
|
202
|
+
view.goTo(event.item.layer.fullExtent);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
view.ui.add(layerList, "top-right");
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### BasemapGallery
|
|
210
|
+
|
|
211
|
+
```html
|
|
212
|
+
<!-- Map Component -->
|
|
213
|
+
<arcgis-basemap-gallery slot="top-right"></arcgis-basemap-gallery>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
// Core API
|
|
218
|
+
import BasemapGallery from "@arcgis/core/widgets/BasemapGallery.js";
|
|
219
|
+
|
|
220
|
+
const basemapGallery = new BasemapGallery({
|
|
221
|
+
view: view
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
view.ui.add(basemapGallery, "top-right");
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Search
|
|
228
|
+
|
|
229
|
+
```html
|
|
230
|
+
<!-- Map Component -->
|
|
231
|
+
<arcgis-search slot="top-right"></arcgis-search>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
```javascript
|
|
235
|
+
// Core API with custom sources
|
|
236
|
+
import Search from "@arcgis/core/widgets/Search.js";
|
|
237
|
+
|
|
238
|
+
const search = new Search({
|
|
239
|
+
view: view,
|
|
240
|
+
sources: [{
|
|
241
|
+
layer: featureLayer,
|
|
242
|
+
searchFields: ["name", "address"],
|
|
243
|
+
displayField: "name",
|
|
244
|
+
exactMatch: false,
|
|
245
|
+
outFields: ["*"],
|
|
246
|
+
name: "My Layer",
|
|
247
|
+
placeholder: "Search features"
|
|
248
|
+
}]
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
view.ui.add(search, "top-right");
|
|
252
|
+
|
|
253
|
+
// Events
|
|
254
|
+
search.on("select-result", (event) => {
|
|
255
|
+
console.log("Selected:", event.result);
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### FeatureTable
|
|
260
|
+
|
|
261
|
+
```html
|
|
262
|
+
<!-- Map Component -->
|
|
263
|
+
<arcgis-feature-table reference-element="arcgis-map"></arcgis-feature-table>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
// Core API
|
|
268
|
+
import FeatureTable from "@arcgis/core/widgets/FeatureTable.js";
|
|
269
|
+
|
|
270
|
+
const featureTable = new FeatureTable({
|
|
271
|
+
view: view,
|
|
272
|
+
layer: featureLayer,
|
|
273
|
+
container: "tableDiv",
|
|
274
|
+
visibleElements: {
|
|
275
|
+
header: true,
|
|
276
|
+
columnMenus: true,
|
|
277
|
+
selectionColumn: true
|
|
278
|
+
},
|
|
279
|
+
fieldConfigs: [
|
|
280
|
+
{ name: "name", label: "Name" },
|
|
281
|
+
{ name: "population", label: "Population" }
|
|
282
|
+
]
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// Selection events
|
|
286
|
+
featureTable.on("selection-change", (event) => {
|
|
287
|
+
console.log("Selected rows:", event.added);
|
|
288
|
+
});
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### TimeSlider
|
|
292
|
+
|
|
293
|
+
```html
|
|
294
|
+
<!-- Map Component -->
|
|
295
|
+
<arcgis-time-slider
|
|
296
|
+
slot="bottom-right"
|
|
297
|
+
layout="auto"
|
|
298
|
+
mode="time-window"
|
|
299
|
+
time-visible
|
|
300
|
+
loop>
|
|
301
|
+
</arcgis-time-slider>
|
|
302
|
+
|
|
303
|
+
<script type="module">
|
|
304
|
+
const timeSlider = document.querySelector("arcgis-time-slider");
|
|
305
|
+
await layer.load();
|
|
306
|
+
|
|
307
|
+
timeSlider.fullTimeExtent = layer.timeInfo.fullTimeExtent;
|
|
308
|
+
timeSlider.stops = {
|
|
309
|
+
interval: layer.timeInfo.interval
|
|
310
|
+
};
|
|
311
|
+
</script>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
```javascript
|
|
315
|
+
// Core API
|
|
316
|
+
import TimeSlider from "@arcgis/core/widgets/TimeSlider.js";
|
|
317
|
+
|
|
318
|
+
const timeSlider = new TimeSlider({
|
|
319
|
+
view: view,
|
|
320
|
+
mode: "time-window", // instant, time-window, cumulative-from-start, cumulative-from-end
|
|
321
|
+
fullTimeExtent: layer.timeInfo.fullTimeExtent,
|
|
322
|
+
stops: {
|
|
323
|
+
interval: {
|
|
324
|
+
value: 1,
|
|
325
|
+
unit: "hours"
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
playRate: 1000, // ms between stops
|
|
329
|
+
loop: true
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
view.ui.add(timeSlider, "bottom-right");
|
|
333
|
+
|
|
334
|
+
// Events
|
|
335
|
+
timeSlider.watch("timeExtent", (timeExtent) => {
|
|
336
|
+
console.log("Time changed:", timeExtent.start, timeExtent.end);
|
|
337
|
+
});
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Print
|
|
341
|
+
|
|
342
|
+
```html
|
|
343
|
+
<!-- Map Component -->
|
|
344
|
+
<arcgis-print slot="top-right"></arcgis-print>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
```javascript
|
|
348
|
+
// Core API
|
|
349
|
+
import Print from "@arcgis/core/widgets/Print.js";
|
|
350
|
+
|
|
351
|
+
const print = new Print({
|
|
352
|
+
view: view,
|
|
353
|
+
printServiceUrl: "https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task"
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
view.ui.add(print, "top-right");
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## Calcite Design System Integration
|
|
360
|
+
|
|
361
|
+
### Basic Layout with Calcite
|
|
362
|
+
|
|
363
|
+
```html
|
|
364
|
+
<!DOCTYPE html>
|
|
365
|
+
<html>
|
|
366
|
+
<head>
|
|
367
|
+
<script type="module" src="https://js.arcgis.com/calcite-components/3.3.3/calcite.esm.js"></script>
|
|
368
|
+
<script src="https://js.arcgis.com/4.34/"></script>
|
|
369
|
+
<script type="module" src="https://js.arcgis.com/4.34/map-components/"></script>
|
|
370
|
+
<style>
|
|
371
|
+
html, body { height: 100%; margin: 0; }
|
|
372
|
+
</style>
|
|
373
|
+
</head>
|
|
374
|
+
<body class="calcite-mode-light">
|
|
375
|
+
<calcite-shell>
|
|
376
|
+
<!-- Header -->
|
|
377
|
+
<calcite-navigation slot="header">
|
|
378
|
+
<calcite-navigation-logo slot="logo" heading="My Map App"></calcite-navigation-logo>
|
|
379
|
+
</calcite-navigation>
|
|
380
|
+
|
|
381
|
+
<!-- Side Panel -->
|
|
382
|
+
<calcite-shell-panel slot="panel-start">
|
|
383
|
+
<calcite-panel heading="Layers">
|
|
384
|
+
<arcgis-layer-list reference-element="map"></arcgis-layer-list>
|
|
385
|
+
</calcite-panel>
|
|
386
|
+
</calcite-shell-panel>
|
|
387
|
+
|
|
388
|
+
<!-- Map -->
|
|
389
|
+
<arcgis-map id="map" basemap="streets-vector">
|
|
390
|
+
<arcgis-zoom slot="top-left"></arcgis-zoom>
|
|
391
|
+
</arcgis-map>
|
|
392
|
+
|
|
393
|
+
<!-- End Panel -->
|
|
394
|
+
<calcite-shell-panel slot="panel-end">
|
|
395
|
+
<calcite-panel heading="Legend">
|
|
396
|
+
<arcgis-legend reference-element="map"></arcgis-legend>
|
|
397
|
+
</calcite-panel>
|
|
398
|
+
</calcite-shell-panel>
|
|
399
|
+
</calcite-shell>
|
|
400
|
+
</body>
|
|
401
|
+
</html>
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Calcite Action Bar
|
|
405
|
+
|
|
406
|
+
```html
|
|
407
|
+
<calcite-shell>
|
|
408
|
+
<calcite-shell-panel slot="panel-start">
|
|
409
|
+
<calcite-action-bar slot="action-bar">
|
|
410
|
+
<calcite-action icon="layers" text="Layers" data-panel="layers"></calcite-action>
|
|
411
|
+
<calcite-action icon="legend" text="Legend" data-panel="legend"></calcite-action>
|
|
412
|
+
<calcite-action icon="bookmark" text="Bookmarks" data-panel="bookmarks"></calcite-action>
|
|
413
|
+
</calcite-action-bar>
|
|
414
|
+
|
|
415
|
+
<calcite-panel id="layers" heading="Layers">
|
|
416
|
+
<arcgis-layer-list reference-element="map"></arcgis-layer-list>
|
|
417
|
+
</calcite-panel>
|
|
418
|
+
|
|
419
|
+
<calcite-panel id="legend" heading="Legend" hidden>
|
|
420
|
+
<arcgis-legend reference-element="map"></arcgis-legend>
|
|
421
|
+
</calcite-panel>
|
|
422
|
+
</calcite-shell-panel>
|
|
423
|
+
|
|
424
|
+
<arcgis-map id="map" basemap="topo-vector"></arcgis-map>
|
|
425
|
+
</calcite-shell>
|
|
426
|
+
|
|
427
|
+
<script>
|
|
428
|
+
// Toggle panels on action click
|
|
429
|
+
document.querySelectorAll("calcite-action").forEach(action => {
|
|
430
|
+
action.addEventListener("click", () => {
|
|
431
|
+
const panelId = action.dataset.panel;
|
|
432
|
+
document.querySelectorAll("calcite-panel").forEach(panel => {
|
|
433
|
+
panel.hidden = panel.id !== panelId;
|
|
434
|
+
});
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
</script>
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Common Calcite Components
|
|
441
|
+
|
|
442
|
+
| Component | Purpose |
|
|
443
|
+
|-----------|---------|
|
|
444
|
+
| `calcite-shell` | App layout container |
|
|
445
|
+
| `calcite-shell-panel` | Side panels |
|
|
446
|
+
| `calcite-panel` | Content panel |
|
|
447
|
+
| `calcite-navigation` | Header/footer |
|
|
448
|
+
| `calcite-action-bar` | Icon button bar |
|
|
449
|
+
| `calcite-action` | Icon button |
|
|
450
|
+
| `calcite-button` | Standard button |
|
|
451
|
+
| `calcite-input` | Text input |
|
|
452
|
+
| `calcite-list` | List container |
|
|
453
|
+
| `calcite-list-item` | List item |
|
|
454
|
+
| `calcite-card` | Card container |
|
|
455
|
+
| `calcite-modal` | Modal dialog |
|
|
456
|
+
| `calcite-alert` | Alert message |
|
|
457
|
+
| `calcite-loader` | Loading indicator |
|
|
458
|
+
|
|
459
|
+
### Theming
|
|
460
|
+
|
|
461
|
+
```html
|
|
462
|
+
<!-- Light mode -->
|
|
463
|
+
<body class="calcite-mode-light">
|
|
464
|
+
|
|
465
|
+
<!-- Dark mode -->
|
|
466
|
+
<body class="calcite-mode-dark">
|
|
467
|
+
|
|
468
|
+
<!-- Custom theme colors -->
|
|
469
|
+
<style>
|
|
470
|
+
:root {
|
|
471
|
+
--calcite-color-brand: #007ac2;
|
|
472
|
+
--calcite-color-brand-hover: #005a8e;
|
|
473
|
+
--calcite-color-text-1: #323232;
|
|
474
|
+
}
|
|
475
|
+
</style>
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
## Custom Widget Placement
|
|
479
|
+
|
|
480
|
+
### Manual Positioning
|
|
481
|
+
|
|
482
|
+
```javascript
|
|
483
|
+
// Add widget at specific position
|
|
484
|
+
view.ui.add(widget, {
|
|
485
|
+
position: "manual",
|
|
486
|
+
index: 0
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
// Position with CSS
|
|
490
|
+
document.getElementById("myWidget").style.cssText = `
|
|
491
|
+
position: absolute;
|
|
492
|
+
top: 10px;
|
|
493
|
+
left: 50%;
|
|
494
|
+
transform: translateX(-50%);
|
|
495
|
+
`;
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### DOM Container
|
|
499
|
+
|
|
500
|
+
```html
|
|
501
|
+
<div id="mapDiv" style="position: relative;">
|
|
502
|
+
<div id="customWidget" style="position: absolute; top: 10px; right: 10px; z-index: 1;">
|
|
503
|
+
<!-- Custom content -->
|
|
504
|
+
</div>
|
|
505
|
+
</div>
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
## Widget Events
|
|
509
|
+
|
|
510
|
+
```javascript
|
|
511
|
+
// Search select
|
|
512
|
+
search.on("select-result", (event) => {
|
|
513
|
+
console.log(event.result);
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
// LayerList trigger action
|
|
517
|
+
layerList.on("trigger-action", (event) => {
|
|
518
|
+
console.log(event.action, event.item);
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
// TimeSlider time change
|
|
522
|
+
timeSlider.watch("timeExtent", (value) => {
|
|
523
|
+
console.log(value.start, value.end);
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
// FeatureTable selection
|
|
527
|
+
featureTable.on("selection-change", (event) => {
|
|
528
|
+
console.log(event.added, event.removed);
|
|
529
|
+
});
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
## TypeScript Usage
|
|
533
|
+
|
|
534
|
+
Widget configurations use autocasting with `type` properties. For TypeScript safety, use `as const`:
|
|
535
|
+
|
|
536
|
+
```typescript
|
|
537
|
+
// Use 'as const' for widget configurations
|
|
538
|
+
const layerList = new LayerList({
|
|
539
|
+
view: view,
|
|
540
|
+
listItemCreatedFunction: (event) => {
|
|
541
|
+
const item = event.item;
|
|
542
|
+
item.actionsSections = [[{
|
|
543
|
+
title: "Zoom to layer",
|
|
544
|
+
icon: "zoom-to-object",
|
|
545
|
+
id: "zoom-to"
|
|
546
|
+
}]];
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
// For layer configurations in widgets
|
|
551
|
+
const featureTable = new FeatureTable({
|
|
552
|
+
view: view,
|
|
553
|
+
layer: featureLayer,
|
|
554
|
+
fieldConfigs: [
|
|
555
|
+
{ name: "name", label: "Name" },
|
|
556
|
+
{ name: "population", label: "Population" }
|
|
557
|
+
]
|
|
558
|
+
});
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
> **Tip:** See [arcgis-core-maps skill](../arcgis-core-maps/SKILL.md) for detailed guidance on autocasting vs explicit classes.
|
|
562
|
+
|
|
563
|
+
## Common Pitfalls
|
|
564
|
+
|
|
565
|
+
1. **Missing reference-element**: When placing components outside the map, use `reference-element` attribute
|
|
566
|
+
|
|
567
|
+
2. **Slot names are specific**: Use exact slot names (`top-left`, not `topleft`)
|
|
568
|
+
|
|
569
|
+
3. **Calcite CSS not loading**: Ensure Calcite script is loaded before using Calcite components
|
|
570
|
+
|
|
571
|
+
4. **Widget container conflicts**: Don't add the same widget to both a container and view.ui
|
|
572
|
+
|
|
573
|
+
5. **Dark/light mode mismatch**: Add `calcite-mode-light` or `calcite-mode-dark` class to body
|
|
574
|
+
|