@saschabrunnerch/arcgis-maps-sdk-js-ai-context 0.0.2 → 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.
Files changed (52) hide show
  1. package/README.md +163 -203
  2. package/bin/cli.js +157 -173
  3. package/contexts/4.34/{claude → skills}/arcgis-3d-advanced/SKILL.md +586 -586
  4. package/contexts/4.34/{claude → skills}/arcgis-advanced-layers/SKILL.md +431 -431
  5. package/contexts/4.34/{claude → skills}/arcgis-analysis-services/SKILL.md +607 -607
  6. package/contexts/4.34/{claude → skills}/arcgis-authentication/SKILL.md +301 -301
  7. package/contexts/4.34/{claude → skills}/arcgis-cim-symbols/SKILL.md +486 -486
  8. package/contexts/4.34/{claude → skills}/arcgis-coordinates-projection/SKILL.md +406 -406
  9. package/contexts/4.34/{claude → skills}/arcgis-core-maps/SKILL.md +739 -739
  10. package/contexts/4.34/{claude → skills}/arcgis-core-utilities/SKILL.md +732 -732
  11. package/contexts/4.34/{claude → skills}/arcgis-custom-rendering/SKILL.md +445 -445
  12. package/contexts/4.34/{claude → skills}/arcgis-editing-advanced/SKILL.md +702 -702
  13. package/contexts/4.34/{claude → skills}/arcgis-feature-effects/SKILL.md +393 -393
  14. package/contexts/4.34/{claude → skills}/arcgis-geometry-operations/SKILL.md +489 -489
  15. package/contexts/4.34/{claude → skills}/arcgis-imagery/SKILL.md +307 -307
  16. package/contexts/4.34/{claude → skills}/arcgis-interaction/SKILL.md +572 -572
  17. package/contexts/4.34/{claude → skills}/arcgis-knowledge-graphs/SKILL.md +582 -582
  18. package/contexts/4.34/{claude → skills}/arcgis-layers/SKILL.md +601 -601
  19. package/contexts/4.34/{claude → skills}/arcgis-map-tools/SKILL.md +668 -668
  20. package/contexts/4.34/{claude → skills}/arcgis-media-layers/SKILL.md +290 -290
  21. package/contexts/4.34/{claude → skills}/arcgis-portal-content/SKILL.md +679 -679
  22. package/contexts/4.34/{claude → skills}/arcgis-scene-effects/SKILL.md +512 -512
  23. package/contexts/4.34/{claude → skills}/arcgis-smart-mapping/SKILL.md +686 -686
  24. package/contexts/4.34/{claude → skills}/arcgis-starter-app-extended/SKILL.md +649 -649
  25. package/contexts/4.34/{claude → skills}/arcgis-tables-forms/SKILL.md +877 -877
  26. package/contexts/4.34/{claude → skills}/arcgis-time-animation/SKILL.md +722 -722
  27. package/contexts/4.34/{claude → skills}/arcgis-utility-networks/SKILL.md +301 -301
  28. package/contexts/4.34/{claude → skills}/arcgis-visualization/SKILL.md +580 -580
  29. package/contexts/4.34/{claude → skills}/arcgis-widgets-ui/SKILL.md +574 -574
  30. package/lib/installer.js +19 -104
  31. package/package.json +45 -45
  32. package/contexts/4.34/copilot/arcgis-3d.instructions.md +0 -267
  33. package/contexts/4.34/copilot/arcgis-analysis.instructions.md +0 -294
  34. package/contexts/4.34/copilot/arcgis-arcade.instructions.md +0 -234
  35. package/contexts/4.34/copilot/arcgis-authentication.instructions.md +0 -187
  36. package/contexts/4.34/copilot/arcgis-cim-symbols.instructions.md +0 -177
  37. package/contexts/4.34/copilot/arcgis-core-maps.instructions.md +0 -246
  38. package/contexts/4.34/copilot/arcgis-core-utilities.instructions.md +0 -247
  39. package/contexts/4.34/copilot/arcgis-editing.instructions.md +0 -262
  40. package/contexts/4.34/copilot/arcgis-geometry.instructions.md +0 -225
  41. package/contexts/4.34/copilot/arcgis-layers.instructions.md +0 -278
  42. package/contexts/4.34/copilot/arcgis-popup-templates.instructions.md +0 -266
  43. package/contexts/4.34/copilot/arcgis-portal-advanced.instructions.md +0 -275
  44. package/contexts/4.34/copilot/arcgis-smart-mapping.instructions.md +0 -184
  45. package/contexts/4.34/copilot/arcgis-starter-app-extended.instructions.md +0 -643
  46. package/contexts/4.34/copilot/arcgis-starter-app.instructions.md +0 -268
  47. package/contexts/4.34/copilot/arcgis-time-animation.instructions.md +0 -112
  48. package/contexts/4.34/copilot/arcgis-visualization.instructions.md +0 -321
  49. package/contexts/4.34/copilot/arcgis-widgets-ui.instructions.md +0 -277
  50. /package/contexts/4.34/{claude → skills}/arcgis-arcade/SKILL.md +0 -0
  51. /package/contexts/4.34/{claude → skills}/arcgis-popup-templates/SKILL.md +0 -0
  52. /package/contexts/4.34/{claude → skills}/arcgis-starter-app/SKILL.md +0 -0
@@ -1,572 +1,572 @@
1
- ---
2
- name: arcgis-interaction
3
- description: Handle user interaction with map features including popups, editing, sketching, and event handling. Use for creating interactive map applications with feature selection, editing workflows, and custom interactions.
4
- ---
5
-
6
- # ArcGIS Interaction
7
-
8
- Use this skill when implementing user interactions like popups, editing, sketching, hit testing, and event handling.
9
-
10
- ## Popups
11
-
12
- ### Basic PopupTemplate
13
- ```javascript
14
- const layer = new FeatureLayer({
15
- url: "...",
16
- popupTemplate: {
17
- title: "{name}",
18
- content: "Population: {population}"
19
- }
20
- });
21
- ```
22
-
23
- ### PopupTemplate with Field Formatting
24
- ```javascript
25
- const popupTemplate = {
26
- title: "Feature: {name}",
27
- content: [{
28
- type: "fields",
29
- fieldInfos: [
30
- {
31
- fieldName: "population",
32
- label: "Population",
33
- format: {
34
- digitSeparator: true,
35
- places: 0
36
- }
37
- },
38
- {
39
- fieldName: "date_created",
40
- label: "Created",
41
- format: {
42
- dateFormat: "short-date"
43
- }
44
- },
45
- {
46
- fieldName: "area_sqkm",
47
- label: "Area (km²)",
48
- format: {
49
- places: 2
50
- }
51
- }
52
- ]
53
- }]
54
- };
55
- ```
56
-
57
- ### Multiple Content Elements
58
- ```javascript
59
- const popupTemplate = {
60
- title: "{name}",
61
- content: [
62
- {
63
- type: "text",
64
- text: "<b>Description:</b> {description}"
65
- },
66
- {
67
- type: "fields",
68
- fieldInfos: [...]
69
- },
70
- {
71
- type: "media",
72
- mediaInfos: [{
73
- type: "image",
74
- value: {
75
- sourceURL: "{image_url}"
76
- }
77
- }]
78
- },
79
- {
80
- type: "attachments"
81
- }
82
- ]
83
- };
84
- ```
85
-
86
- ### Custom Content Function
87
- ```javascript
88
- const popupTemplate = {
89
- title: "{name}",
90
- content: (feature) => {
91
- const div = document.createElement("div");
92
- div.innerHTML = `
93
- <p>Custom content for ${feature.graphic.attributes.name}</p>
94
- <button id="customBtn">Click me</button>
95
- `;
96
- return div;
97
- }
98
- };
99
- ```
100
-
101
- ### Arcade Expressions in Popups
102
- ```javascript
103
- const popupTemplate = {
104
- title: "{name}",
105
- expressionInfos: [{
106
- name: "density",
107
- title: "Population Density",
108
- expression: "Round($feature.population / $feature.area_sqkm, 2)"
109
- }],
110
- content: "Population Density: {expression/density} people/km²"
111
- };
112
- ```
113
-
114
- ### Popup Actions
115
- ```javascript
116
- const measureAction = {
117
- title: "Measure Length",
118
- id: "measure-this",
119
- icon: "measure"
120
- };
121
-
122
- const popupTemplate = {
123
- title: "{name}",
124
- content: "{description}",
125
- actions: [measureAction]
126
- };
127
-
128
- // Listen for action clicks
129
- import reactiveUtils from "@arcgis/core/core/reactiveUtils.js";
130
-
131
- reactiveUtils.on(
132
- () => view.popup,
133
- "trigger-action",
134
- (event) => {
135
- if (event.action.id === "measure-this") {
136
- const geometry = view.popup.selectedFeature.geometry;
137
- // Do something with the geometry
138
- }
139
- }
140
- );
141
- ```
142
-
143
- ### Programmatic Popup Control
144
- ```javascript
145
- // Open popup at location
146
- view.openPopup({
147
- title: "Custom Popup",
148
- content: "Hello World",
149
- location: view.center
150
- });
151
-
152
- // Open popup with features
153
- view.openPopup({
154
- features: [graphic1, graphic2],
155
- location: mapPoint
156
- });
157
-
158
- // Close popup
159
- view.closePopup();
160
-
161
- // Access popup properties
162
- const selectedFeature = view.popup.selectedFeature;
163
- const isVisible = view.popup.visible;
164
- ```
165
-
166
- ### Popup Component
167
- ```html
168
- <arcgis-map basemap="streets-vector">
169
- <arcgis-popup slot="popup"></arcgis-popup>
170
- </arcgis-map>
171
- ```
172
-
173
- ## Hit Testing
174
-
175
- ### Basic Hit Test
176
- ```javascript
177
- view.on("click", async (event) => {
178
- const response = await view.hitTest(event);
179
-
180
- if (response.results.length > 0) {
181
- const graphic = response.results[0].graphic;
182
- console.log("Clicked feature:", graphic.attributes);
183
- }
184
- });
185
- ```
186
-
187
- ### Hit Test with Layer Filter
188
- ```javascript
189
- view.on("click", async (event) => {
190
- const response = await view.hitTest(event, {
191
- include: [featureLayer] // Only test this layer
192
- });
193
-
194
- // Or exclude layers
195
- const response2 = await view.hitTest(event, {
196
- exclude: [graphicsLayer]
197
- });
198
- });
199
- ```
200
-
201
- ### Pointer Move Hit Test
202
- ```javascript
203
- view.on("pointer-move", async (event) => {
204
- const response = await view.hitTest(event, {
205
- include: featureLayer
206
- });
207
-
208
- if (response.results.length > 0) {
209
- document.body.style.cursor = "pointer";
210
- } else {
211
- document.body.style.cursor = "default";
212
- }
213
- });
214
- ```
215
-
216
- ## Highlighting
217
-
218
- ### Highlight Features
219
- ```javascript
220
- const layerView = await view.whenLayerView(featureLayer);
221
-
222
- // Highlight a single feature
223
- const highlight = layerView.highlight(graphic);
224
-
225
- // Highlight multiple features
226
- const highlight = layerView.highlight([graphic1, graphic2]);
227
-
228
- // Highlight by object IDs
229
- const highlight = layerView.highlight([1, 2, 3]);
230
-
231
- // Remove highlight
232
- highlight.remove();
233
- ```
234
-
235
- ### Highlight on Click
236
- ```javascript
237
- let highlightHandle;
238
-
239
- view.on("click", async (event) => {
240
- // Remove previous highlight
241
- if (highlightHandle) {
242
- highlightHandle.remove();
243
- }
244
-
245
- const response = await view.hitTest(event, { include: featureLayer });
246
-
247
- if (response.results.length > 0) {
248
- const graphic = response.results[0].graphic;
249
- const layerView = await view.whenLayerView(featureLayer);
250
- highlightHandle = layerView.highlight(graphic);
251
- }
252
- });
253
- ```
254
-
255
- ### Highlight Options
256
- ```javascript
257
- // Set highlight options on the layer view
258
- layerView.highlightOptions = {
259
- color: [255, 255, 0, 1],
260
- haloOpacity: 0.9,
261
- fillOpacity: 0.2
262
- };
263
- ```
264
-
265
- ## Editing
266
-
267
- ### Editor Component (Simplest)
268
- ```html
269
- <arcgis-map item-id="YOUR_WEBMAP_ID">
270
- <arcgis-editor slot="top-right"></arcgis-editor>
271
- </arcgis-map>
272
- ```
273
-
274
- ### Editor Widget
275
- ```javascript
276
- import Editor from "@arcgis/core/widgets/Editor.js";
277
-
278
- const editor = new Editor({
279
- view: view,
280
- layerInfos: [{
281
- layer: featureLayer,
282
- formTemplate: {
283
- elements: [
284
- { type: "field", fieldName: "name" },
285
- { type: "field", fieldName: "description" }
286
- ]
287
- }
288
- }]
289
- });
290
-
291
- view.ui.add(editor, "top-right");
292
- ```
293
-
294
- ### FeatureForm
295
- ```javascript
296
- import FeatureForm from "@arcgis/core/widgets/FeatureForm.js";
297
-
298
- const featureForm = new FeatureForm({
299
- container: "formDiv",
300
- layer: featureLayer,
301
- formTemplate: {
302
- title: "Edit Feature",
303
- elements: [
304
- {
305
- type: "field",
306
- fieldName: "name",
307
- label: "Name"
308
- },
309
- {
310
- type: "field",
311
- fieldName: "type",
312
- label: "Type"
313
- }
314
- ]
315
- }
316
- });
317
-
318
- // Set feature to edit
319
- featureForm.feature = graphic;
320
-
321
- // Listen for submit
322
- featureForm.on("submit", () => {
323
- const values = featureForm.getValues();
324
- // Update feature attributes
325
- Object.keys(values).forEach(key => {
326
- graphic.attributes[key] = values[key];
327
- });
328
- });
329
-
330
- // Submit programmatically
331
- featureForm.submit();
332
- ```
333
-
334
- ### applyEdits API
335
-
336
- ```javascript
337
- // Add features
338
- const edits = {
339
- addFeatures: [newGraphic]
340
- };
341
- const result = await featureLayer.applyEdits(edits);
342
- console.log("Added:", result.addFeatureResults);
343
-
344
- // Update features
345
- const edits = {
346
- updateFeatures: [updatedGraphic]
347
- };
348
- const result = await featureLayer.applyEdits(edits);
349
-
350
- // Delete features
351
- const edits = {
352
- deleteFeatures: [graphicToDelete]
353
- };
354
- const result = await featureLayer.applyEdits(edits);
355
-
356
- // Combined edits
357
- const edits = {
358
- addFeatures: [newGraphic1, newGraphic2],
359
- updateFeatures: [updatedGraphic],
360
- deleteFeatures: [deleteGraphic]
361
- };
362
- const result = await featureLayer.applyEdits(edits);
363
- ```
364
-
365
- ## Sketching
366
-
367
- ### Sketch Component (Simplest)
368
- ```html
369
- <arcgis-map basemap="topo-vector">
370
- <arcgis-sketch slot="top-right" creation-mode="update"></arcgis-sketch>
371
- </arcgis-map>
372
- ```
373
-
374
- ### Sketch Widget
375
- ```javascript
376
- import Sketch from "@arcgis/core/widgets/Sketch.js";
377
- import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer.js";
378
-
379
- const graphicsLayer = new GraphicsLayer();
380
- map.add(graphicsLayer);
381
-
382
- const sketch = new Sketch({
383
- view: view,
384
- layer: graphicsLayer,
385
- creationMode: "update" // or "single", "continuous"
386
- });
387
-
388
- view.ui.add(sketch, "top-right");
389
-
390
- // Listen for events
391
- sketch.on("create", (event) => {
392
- if (event.state === "complete") {
393
- console.log("Created:", event.graphic);
394
- }
395
- });
396
-
397
- sketch.on("update", (event) => {
398
- if (event.state === "complete") {
399
- console.log("Updated:", event.graphics);
400
- }
401
- });
402
-
403
- sketch.on("delete", (event) => {
404
- console.log("Deleted:", event.graphics);
405
- });
406
- ```
407
-
408
- ### Draw Tool (Low-level)
409
- ```javascript
410
- import Draw from "@arcgis/core/views/draw/Draw.js";
411
-
412
- const draw = new Draw({ view: view });
413
-
414
- // Create a polygon
415
- const action = draw.create("polygon");
416
-
417
- action.on("vertex-add", (event) => {
418
- console.log("Vertex added:", event.vertices);
419
- });
420
-
421
- action.on("draw-complete", (event) => {
422
- const polygon = {
423
- type: "polygon",
424
- rings: event.vertices,
425
- spatialReference: view.spatialReference
426
- };
427
- // Create graphic with polygon
428
- });
429
- ```
430
-
431
- ## Event Handling
432
-
433
- ### View Events
434
- ```javascript
435
- // Click
436
- view.on("click", (event) => {
437
- console.log("Map point:", event.mapPoint);
438
- console.log("Screen point:", event.x, event.y);
439
- });
440
-
441
- // Double-click
442
- view.on("double-click", (event) => {
443
- event.stopPropagation(); // Prevent default zoom
444
- });
445
-
446
- // Pointer move
447
- view.on("pointer-move", (event) => {
448
- const point = view.toMap(event);
449
- console.log("Coordinates:", point.longitude, point.latitude);
450
- });
451
-
452
- // Drag
453
- view.on("drag", (event) => {
454
- if (event.action === "start") { }
455
- if (event.action === "update") { }
456
- if (event.action === "end") { }
457
- });
458
-
459
- // Key events
460
- view.on("key-down", (event) => {
461
- if (event.key === "Escape") {
462
- // Cancel operation
463
- }
464
- });
465
- ```
466
-
467
- ### Property Watching
468
- ```javascript
469
- // Watch single property
470
- view.watch("zoom", (newZoom) => {
471
- console.log("Zoom changed to:", newZoom);
472
- });
473
-
474
- // Watch multiple properties
475
- view.watch(["center", "zoom"], ([center, zoom]) => {
476
- console.log("View changed:", center, zoom);
477
- });
478
-
479
- // Watch stationary (after navigation completes)
480
- view.watch("stationary", (isStationary) => {
481
- if (isStationary) {
482
- console.log("Navigation complete");
483
- }
484
- });
485
-
486
- // One-time watch
487
- import { when } from "@arcgis/core/core/reactiveUtils.js";
488
-
489
- await when(() => view.stationary === true);
490
- console.log("View is now stationary");
491
- ```
492
-
493
- ### Layer Events
494
- ```javascript
495
- // Layer view updating
496
- const layerView = await view.whenLayerView(featureLayer);
497
-
498
- layerView.watch("updating", (updating) => {
499
- if (updating) {
500
- console.log("Layer is updating...");
501
- } else {
502
- console.log("Layer update complete");
503
- }
504
- });
505
- ```
506
-
507
- ### Widget Events
508
- ```javascript
509
- // Search widget
510
- searchWidget.on("select-result", (event) => {
511
- console.log("Selected:", event.result);
512
- });
513
-
514
- // Sketch widget
515
- sketchWidget.on("create", (event) => {
516
- if (event.state === "complete") {
517
- console.log("Sketch complete");
518
- }
519
- });
520
- ```
521
-
522
- ## Coordinate Conversion
523
-
524
- ```javascript
525
- // Screen to map coordinates
526
- const mapPoint = view.toMap({ x: screenX, y: screenY });
527
-
528
- // Map to screen coordinates
529
- const screenPoint = view.toScreen(mapPoint);
530
- ```
531
-
532
- ## TypeScript Usage
533
-
534
- Popup and symbol configurations use autocasting with `type` properties. For TypeScript safety, use `as const`:
535
-
536
- ```typescript
537
- // Use 'as const' for popup content types
538
- layer.popupTemplate = {
539
- title: "{name}",
540
- content: [{
541
- type: "fields",
542
- fieldInfos: [
543
- { fieldName: "name", label: "Name" }
544
- ]
545
- }]
546
- } as const;
547
-
548
- // Use 'as const' for symbol configurations
549
- const graphic = new Graphic({
550
- geometry: point,
551
- symbol: {
552
- type: "simple-marker",
553
- color: "red",
554
- size: 12
555
- } as const
556
- });
557
- ```
558
-
559
- > **Tip:** See [arcgis-core-maps skill](../arcgis-core-maps/SKILL.md) for detailed guidance on autocasting vs explicit classes.
560
-
561
- ## Common Pitfalls
562
-
563
- 1. **Popup not showing**: Ensure layer has `popupEnabled: true` (default)
564
-
565
- 2. **Hit test returns nothing**: Check if layers are included/excluded correctly
566
-
567
- 3. **Highlight not visible**: Make sure to store the highlight handle and call `remove()` before creating new highlights
568
-
569
- 4. **applyEdits fails**: Ensure layer is editable and user has edit permissions
570
-
571
- 5. **Events fire multiple times**: Remove event handlers when no longer needed
572
-
1
+ ---
2
+ name: arcgis-interaction
3
+ description: Handle user interaction with map features including popups, editing, sketching, and event handling. Use for creating interactive map applications with feature selection, editing workflows, and custom interactions.
4
+ ---
5
+
6
+ # ArcGIS Interaction
7
+
8
+ Use this skill when implementing user interactions like popups, editing, sketching, hit testing, and event handling.
9
+
10
+ ## Popups
11
+
12
+ ### Basic PopupTemplate
13
+ ```javascript
14
+ const layer = new FeatureLayer({
15
+ url: "...",
16
+ popupTemplate: {
17
+ title: "{name}",
18
+ content: "Population: {population}"
19
+ }
20
+ });
21
+ ```
22
+
23
+ ### PopupTemplate with Field Formatting
24
+ ```javascript
25
+ const popupTemplate = {
26
+ title: "Feature: {name}",
27
+ content: [{
28
+ type: "fields",
29
+ fieldInfos: [
30
+ {
31
+ fieldName: "population",
32
+ label: "Population",
33
+ format: {
34
+ digitSeparator: true,
35
+ places: 0
36
+ }
37
+ },
38
+ {
39
+ fieldName: "date_created",
40
+ label: "Created",
41
+ format: {
42
+ dateFormat: "short-date"
43
+ }
44
+ },
45
+ {
46
+ fieldName: "area_sqkm",
47
+ label: "Area (km²)",
48
+ format: {
49
+ places: 2
50
+ }
51
+ }
52
+ ]
53
+ }]
54
+ };
55
+ ```
56
+
57
+ ### Multiple Content Elements
58
+ ```javascript
59
+ const popupTemplate = {
60
+ title: "{name}",
61
+ content: [
62
+ {
63
+ type: "text",
64
+ text: "<b>Description:</b> {description}"
65
+ },
66
+ {
67
+ type: "fields",
68
+ fieldInfos: [...]
69
+ },
70
+ {
71
+ type: "media",
72
+ mediaInfos: [{
73
+ type: "image",
74
+ value: {
75
+ sourceURL: "{image_url}"
76
+ }
77
+ }]
78
+ },
79
+ {
80
+ type: "attachments"
81
+ }
82
+ ]
83
+ };
84
+ ```
85
+
86
+ ### Custom Content Function
87
+ ```javascript
88
+ const popupTemplate = {
89
+ title: "{name}",
90
+ content: (feature) => {
91
+ const div = document.createElement("div");
92
+ div.innerHTML = `
93
+ <p>Custom content for ${feature.graphic.attributes.name}</p>
94
+ <button id="customBtn">Click me</button>
95
+ `;
96
+ return div;
97
+ }
98
+ };
99
+ ```
100
+
101
+ ### Arcade Expressions in Popups
102
+ ```javascript
103
+ const popupTemplate = {
104
+ title: "{name}",
105
+ expressionInfos: [{
106
+ name: "density",
107
+ title: "Population Density",
108
+ expression: "Round($feature.population / $feature.area_sqkm, 2)"
109
+ }],
110
+ content: "Population Density: {expression/density} people/km²"
111
+ };
112
+ ```
113
+
114
+ ### Popup Actions
115
+ ```javascript
116
+ const measureAction = {
117
+ title: "Measure Length",
118
+ id: "measure-this",
119
+ icon: "measure"
120
+ };
121
+
122
+ const popupTemplate = {
123
+ title: "{name}",
124
+ content: "{description}",
125
+ actions: [measureAction]
126
+ };
127
+
128
+ // Listen for action clicks
129
+ import reactiveUtils from "@arcgis/core/core/reactiveUtils.js";
130
+
131
+ reactiveUtils.on(
132
+ () => view.popup,
133
+ "trigger-action",
134
+ (event) => {
135
+ if (event.action.id === "measure-this") {
136
+ const geometry = view.popup.selectedFeature.geometry;
137
+ // Do something with the geometry
138
+ }
139
+ }
140
+ );
141
+ ```
142
+
143
+ ### Programmatic Popup Control
144
+ ```javascript
145
+ // Open popup at location
146
+ view.openPopup({
147
+ title: "Custom Popup",
148
+ content: "Hello World",
149
+ location: view.center
150
+ });
151
+
152
+ // Open popup with features
153
+ view.openPopup({
154
+ features: [graphic1, graphic2],
155
+ location: mapPoint
156
+ });
157
+
158
+ // Close popup
159
+ view.closePopup();
160
+
161
+ // Access popup properties
162
+ const selectedFeature = view.popup.selectedFeature;
163
+ const isVisible = view.popup.visible;
164
+ ```
165
+
166
+ ### Popup Component
167
+ ```html
168
+ <arcgis-map basemap="streets-vector">
169
+ <arcgis-popup slot="popup"></arcgis-popup>
170
+ </arcgis-map>
171
+ ```
172
+
173
+ ## Hit Testing
174
+
175
+ ### Basic Hit Test
176
+ ```javascript
177
+ view.on("click", async (event) => {
178
+ const response = await view.hitTest(event);
179
+
180
+ if (response.results.length > 0) {
181
+ const graphic = response.results[0].graphic;
182
+ console.log("Clicked feature:", graphic.attributes);
183
+ }
184
+ });
185
+ ```
186
+
187
+ ### Hit Test with Layer Filter
188
+ ```javascript
189
+ view.on("click", async (event) => {
190
+ const response = await view.hitTest(event, {
191
+ include: [featureLayer] // Only test this layer
192
+ });
193
+
194
+ // Or exclude layers
195
+ const response2 = await view.hitTest(event, {
196
+ exclude: [graphicsLayer]
197
+ });
198
+ });
199
+ ```
200
+
201
+ ### Pointer Move Hit Test
202
+ ```javascript
203
+ view.on("pointer-move", async (event) => {
204
+ const response = await view.hitTest(event, {
205
+ include: featureLayer
206
+ });
207
+
208
+ if (response.results.length > 0) {
209
+ document.body.style.cursor = "pointer";
210
+ } else {
211
+ document.body.style.cursor = "default";
212
+ }
213
+ });
214
+ ```
215
+
216
+ ## Highlighting
217
+
218
+ ### Highlight Features
219
+ ```javascript
220
+ const layerView = await view.whenLayerView(featureLayer);
221
+
222
+ // Highlight a single feature
223
+ const highlight = layerView.highlight(graphic);
224
+
225
+ // Highlight multiple features
226
+ const highlight = layerView.highlight([graphic1, graphic2]);
227
+
228
+ // Highlight by object IDs
229
+ const highlight = layerView.highlight([1, 2, 3]);
230
+
231
+ // Remove highlight
232
+ highlight.remove();
233
+ ```
234
+
235
+ ### Highlight on Click
236
+ ```javascript
237
+ let highlightHandle;
238
+
239
+ view.on("click", async (event) => {
240
+ // Remove previous highlight
241
+ if (highlightHandle) {
242
+ highlightHandle.remove();
243
+ }
244
+
245
+ const response = await view.hitTest(event, { include: featureLayer });
246
+
247
+ if (response.results.length > 0) {
248
+ const graphic = response.results[0].graphic;
249
+ const layerView = await view.whenLayerView(featureLayer);
250
+ highlightHandle = layerView.highlight(graphic);
251
+ }
252
+ });
253
+ ```
254
+
255
+ ### Highlight Options
256
+ ```javascript
257
+ // Set highlight options on the layer view
258
+ layerView.highlightOptions = {
259
+ color: [255, 255, 0, 1],
260
+ haloOpacity: 0.9,
261
+ fillOpacity: 0.2
262
+ };
263
+ ```
264
+
265
+ ## Editing
266
+
267
+ ### Editor Component (Simplest)
268
+ ```html
269
+ <arcgis-map item-id="YOUR_WEBMAP_ID">
270
+ <arcgis-editor slot="top-right"></arcgis-editor>
271
+ </arcgis-map>
272
+ ```
273
+
274
+ ### Editor Widget
275
+ ```javascript
276
+ import Editor from "@arcgis/core/widgets/Editor.js";
277
+
278
+ const editor = new Editor({
279
+ view: view,
280
+ layerInfos: [{
281
+ layer: featureLayer,
282
+ formTemplate: {
283
+ elements: [
284
+ { type: "field", fieldName: "name" },
285
+ { type: "field", fieldName: "description" }
286
+ ]
287
+ }
288
+ }]
289
+ });
290
+
291
+ view.ui.add(editor, "top-right");
292
+ ```
293
+
294
+ ### FeatureForm
295
+ ```javascript
296
+ import FeatureForm from "@arcgis/core/widgets/FeatureForm.js";
297
+
298
+ const featureForm = new FeatureForm({
299
+ container: "formDiv",
300
+ layer: featureLayer,
301
+ formTemplate: {
302
+ title: "Edit Feature",
303
+ elements: [
304
+ {
305
+ type: "field",
306
+ fieldName: "name",
307
+ label: "Name"
308
+ },
309
+ {
310
+ type: "field",
311
+ fieldName: "type",
312
+ label: "Type"
313
+ }
314
+ ]
315
+ }
316
+ });
317
+
318
+ // Set feature to edit
319
+ featureForm.feature = graphic;
320
+
321
+ // Listen for submit
322
+ featureForm.on("submit", () => {
323
+ const values = featureForm.getValues();
324
+ // Update feature attributes
325
+ Object.keys(values).forEach(key => {
326
+ graphic.attributes[key] = values[key];
327
+ });
328
+ });
329
+
330
+ // Submit programmatically
331
+ featureForm.submit();
332
+ ```
333
+
334
+ ### applyEdits API
335
+
336
+ ```javascript
337
+ // Add features
338
+ const edits = {
339
+ addFeatures: [newGraphic]
340
+ };
341
+ const result = await featureLayer.applyEdits(edits);
342
+ console.log("Added:", result.addFeatureResults);
343
+
344
+ // Update features
345
+ const edits = {
346
+ updateFeatures: [updatedGraphic]
347
+ };
348
+ const result = await featureLayer.applyEdits(edits);
349
+
350
+ // Delete features
351
+ const edits = {
352
+ deleteFeatures: [graphicToDelete]
353
+ };
354
+ const result = await featureLayer.applyEdits(edits);
355
+
356
+ // Combined edits
357
+ const edits = {
358
+ addFeatures: [newGraphic1, newGraphic2],
359
+ updateFeatures: [updatedGraphic],
360
+ deleteFeatures: [deleteGraphic]
361
+ };
362
+ const result = await featureLayer.applyEdits(edits);
363
+ ```
364
+
365
+ ## Sketching
366
+
367
+ ### Sketch Component (Simplest)
368
+ ```html
369
+ <arcgis-map basemap="topo-vector">
370
+ <arcgis-sketch slot="top-right" creation-mode="update"></arcgis-sketch>
371
+ </arcgis-map>
372
+ ```
373
+
374
+ ### Sketch Widget
375
+ ```javascript
376
+ import Sketch from "@arcgis/core/widgets/Sketch.js";
377
+ import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer.js";
378
+
379
+ const graphicsLayer = new GraphicsLayer();
380
+ map.add(graphicsLayer);
381
+
382
+ const sketch = new Sketch({
383
+ view: view,
384
+ layer: graphicsLayer,
385
+ creationMode: "update" // or "single", "continuous"
386
+ });
387
+
388
+ view.ui.add(sketch, "top-right");
389
+
390
+ // Listen for events
391
+ sketch.on("create", (event) => {
392
+ if (event.state === "complete") {
393
+ console.log("Created:", event.graphic);
394
+ }
395
+ });
396
+
397
+ sketch.on("update", (event) => {
398
+ if (event.state === "complete") {
399
+ console.log("Updated:", event.graphics);
400
+ }
401
+ });
402
+
403
+ sketch.on("delete", (event) => {
404
+ console.log("Deleted:", event.graphics);
405
+ });
406
+ ```
407
+
408
+ ### Draw Tool (Low-level)
409
+ ```javascript
410
+ import Draw from "@arcgis/core/views/draw/Draw.js";
411
+
412
+ const draw = new Draw({ view: view });
413
+
414
+ // Create a polygon
415
+ const action = draw.create("polygon");
416
+
417
+ action.on("vertex-add", (event) => {
418
+ console.log("Vertex added:", event.vertices);
419
+ });
420
+
421
+ action.on("draw-complete", (event) => {
422
+ const polygon = {
423
+ type: "polygon",
424
+ rings: event.vertices,
425
+ spatialReference: view.spatialReference
426
+ };
427
+ // Create graphic with polygon
428
+ });
429
+ ```
430
+
431
+ ## Event Handling
432
+
433
+ ### View Events
434
+ ```javascript
435
+ // Click
436
+ view.on("click", (event) => {
437
+ console.log("Map point:", event.mapPoint);
438
+ console.log("Screen point:", event.x, event.y);
439
+ });
440
+
441
+ // Double-click
442
+ view.on("double-click", (event) => {
443
+ event.stopPropagation(); // Prevent default zoom
444
+ });
445
+
446
+ // Pointer move
447
+ view.on("pointer-move", (event) => {
448
+ const point = view.toMap(event);
449
+ console.log("Coordinates:", point.longitude, point.latitude);
450
+ });
451
+
452
+ // Drag
453
+ view.on("drag", (event) => {
454
+ if (event.action === "start") { }
455
+ if (event.action === "update") { }
456
+ if (event.action === "end") { }
457
+ });
458
+
459
+ // Key events
460
+ view.on("key-down", (event) => {
461
+ if (event.key === "Escape") {
462
+ // Cancel operation
463
+ }
464
+ });
465
+ ```
466
+
467
+ ### Property Watching
468
+ ```javascript
469
+ // Watch single property
470
+ view.watch("zoom", (newZoom) => {
471
+ console.log("Zoom changed to:", newZoom);
472
+ });
473
+
474
+ // Watch multiple properties
475
+ view.watch(["center", "zoom"], ([center, zoom]) => {
476
+ console.log("View changed:", center, zoom);
477
+ });
478
+
479
+ // Watch stationary (after navigation completes)
480
+ view.watch("stationary", (isStationary) => {
481
+ if (isStationary) {
482
+ console.log("Navigation complete");
483
+ }
484
+ });
485
+
486
+ // One-time watch
487
+ import { when } from "@arcgis/core/core/reactiveUtils.js";
488
+
489
+ await when(() => view.stationary === true);
490
+ console.log("View is now stationary");
491
+ ```
492
+
493
+ ### Layer Events
494
+ ```javascript
495
+ // Layer view updating
496
+ const layerView = await view.whenLayerView(featureLayer);
497
+
498
+ layerView.watch("updating", (updating) => {
499
+ if (updating) {
500
+ console.log("Layer is updating...");
501
+ } else {
502
+ console.log("Layer update complete");
503
+ }
504
+ });
505
+ ```
506
+
507
+ ### Widget Events
508
+ ```javascript
509
+ // Search widget
510
+ searchWidget.on("select-result", (event) => {
511
+ console.log("Selected:", event.result);
512
+ });
513
+
514
+ // Sketch widget
515
+ sketchWidget.on("create", (event) => {
516
+ if (event.state === "complete") {
517
+ console.log("Sketch complete");
518
+ }
519
+ });
520
+ ```
521
+
522
+ ## Coordinate Conversion
523
+
524
+ ```javascript
525
+ // Screen to map coordinates
526
+ const mapPoint = view.toMap({ x: screenX, y: screenY });
527
+
528
+ // Map to screen coordinates
529
+ const screenPoint = view.toScreen(mapPoint);
530
+ ```
531
+
532
+ ## TypeScript Usage
533
+
534
+ Popup and symbol configurations use autocasting with `type` properties. For TypeScript safety, use `as const`:
535
+
536
+ ```typescript
537
+ // Use 'as const' for popup content types
538
+ layer.popupTemplate = {
539
+ title: "{name}",
540
+ content: [{
541
+ type: "fields",
542
+ fieldInfos: [
543
+ { fieldName: "name", label: "Name" }
544
+ ]
545
+ }]
546
+ } as const;
547
+
548
+ // Use 'as const' for symbol configurations
549
+ const graphic = new Graphic({
550
+ geometry: point,
551
+ symbol: {
552
+ type: "simple-marker",
553
+ color: "red",
554
+ size: 12
555
+ } as const
556
+ });
557
+ ```
558
+
559
+ > **Tip:** See [arcgis-core-maps skill](../arcgis-core-maps/SKILL.md) for detailed guidance on autocasting vs explicit classes.
560
+
561
+ ## Common Pitfalls
562
+
563
+ 1. **Popup not showing**: Ensure layer has `popupEnabled: true` (default)
564
+
565
+ 2. **Hit test returns nothing**: Check if layers are included/excluded correctly
566
+
567
+ 3. **Highlight not visible**: Make sure to store the highlight handle and call `remove()` before creating new highlights
568
+
569
+ 4. **applyEdits fails**: Ensure layer is editable and user has edit permissions
570
+
571
+ 5. **Events fire multiple times**: Remove event handlers when no longer needed
572
+