arcgis-interaction
Skill0 starsChanged 7 months agoMITView on GitHub
Handle user interaction with map views including hit testing, feature highlighting, sketching, and event handling. Use when detecting clicks on features, highlighting selections, drawing or editing shapes on the map, or responding to pointer, keyboard, and drag events.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- geoai-latam/SKILL_JS5_ARCGIStheir own version, first seen Nov 8, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- geoai-latam/SKILL_JS5_ARCGIS★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository47 other files it gives its agents.
- AGENTS.mdAGENTS.md
- skills/arcgis-ai-components/AGENTS.mdAGENTS.md
- skills/arcgis-authentication/AGENTS.mdAGENTS.md
- skills/arcgis-charts/AGENTS.mdAGENTS.md
- skills/arcgis-coding-components/AGENTS.mdAGENTS.md
- skills/arcgis-core-maps/AGENTS.mdAGENTS.md
- skills/arcgis-editing/AGENTS.mdAGENTS.md
- skills/arcgis-embeddable-maps/AGENTS.mdAGENTS.md
- skills/arcgis-interaction/AGENTS.mdAGENTS.md
- skills/arcgis-layers/AGENTS.mdAGENTS.md
- skills/arcgis-starter-app/AGENTS.mdAGENTS.md
- skills/arcgis-visualization/AGENTS.mdAGENTS.md
- skills/arcgis-widgets-ui/AGENTS.mdAGENTS.md
- arcgis-3d-layersSkill
- arcgis-advanced-layersSkill
- arcgis-ai-componentsSkill
- arcgis-arcadeSkill
- arcgis-authenticationSkill
- arcgis-chartsSkill
- arcgis-cim-symbolsSkill
- arcgis-coding-componentsSkill
- arcgis-coordinates-projectionSkill
- arcgis-core-mapsSkill
- arcgis-core-utilitiesSkill
- arcgis-custom-renderingSkill
- arcgis-editingSkill
- arcgis-embeddable-mapsSkill
- arcgis-feature-effectsSkill
- arcgis-geometry-operationsSkill
- arcgis-imagerySkill
- arcgis-knowledge-graphsSkill
- arcgis-layersSkill
- arcgis-map-toolsSkill
- arcgis-performanceSkill
- arcgis-popup-templatesSkill
- arcgis-portal-contentSkill
- arcgis-rest-servicesSkill
- arcgis-scene-environmentSkill
- arcgis-smart-mappingSkill
- arcgis-spatial-analysisSkill
- arcgis-starter-appSkill
- arcgis-tables-formsSkill
- arcgis-time-animationSkill
- arcgis-utility-networksSkill
- arcgis-visualizationSkill
- arcgis-widgets-advancedSkill
- arcgis-widgets-uiSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 2 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 8
Use this skill when implementing user interactions like hit testing, feature highlighting, sketching, coordinate conversion, and event …
- Distinctive: line 550
Hit test returns nothing: Check if layers are included/excluded correctly, and ensure the view is ready.
- Very specific: line 554
Popup not showing: Ensure layer has popupEnabled: true (default) and a popupTemplate set.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
ArcGIS Interaction
Use this skill when implementing user interactions like hit testing, feature highlighting, sketching, coordinate conversion, and event handling.
Import Patterns
Direct ESM Imports
import Draw from "@arcgis/core/views/draw/Draw.js";
import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js";Dynamic Imports (CDN)
const Draw = await $arcgis.import("@arcgis/core/views/draw/Draw.js");
const reactiveUtils = await $arcgis.import(
"@arcgis/core/core/reactiveUtils.js",
);Note: The examples in this skill use Direct ESM imports. For CDN usage, replace
import X from "path"withconst X = await $arcgis.import("path").
Hit Testing
Basic Hit Test
view.on("click", async (event) => {
const response = await view.hitTest(event);
if (response.results.length > 0) {
const graphic = response.results[0].graphic;
console.log("Clicked feature:", graphic.attributes);
}
});Hit Test with Layer Filter
view.on("click", async (event) => {
const response = await view.hitTest(event, {
include: [featureLayer], // Only test this layer
});
// Or exclude layers
const response2 = await view.hitTest(event, {
exclude: [graphicsLayer],
});
});Pointer Move Hit Test
view.on("pointer-move", async (event) => {
const response = await view.hitTest(event, {
include: featureLayer,
});
if (response.results.length > 0) {
document.body.style.cursor = "pointer";
} else {
document.body.style.cursor = "default";
}
});Hit Test Result Types
The hitTest returns ViewHitTestResult containing an array of result objects. Each result has a type:
| Result Type | Description |
graphic | A graphic from a layer or GraphicsLayer |
media | A media element hit (images in popups) |
route | A route hit from RouteLayer |
view.on("click", async (event) => {
const response = await view.hitTest(event);
response.results.forEach((result) => {
if (result.type === "graphic") {
console.log("Layer:", result.graphic.layer.title);
console.log("Attributes:", result.graphic.attributes);
}
});
});Highlighting
Highlight Features
const layerView = await view.whenLayerView(featureLayer);
// Highlight a single feature
const highlight = layerView.highlight(graphic);
// Highlight multiple features
const highlight = layerView.highlight([graphic1, graphic2]);
// Highlight by object IDs
const highlight = layerView.highlight([1, 2, 3]);
// Remove highlight
highlight.remove();Highlight on Click
let highlightHandle;
view.on("click", async (event) => {
// Remove previous highlight
if (highlightHandle) {
highlightHandle.remove();
}
const response = await view.hitTest(event, { include: featureLayer });
if (response.results.length > 0) {
const graphic = response.results[0].graphic;
const layerView = await view.whenLayerView(featureLayer);
highlightHandle = layerView.highlight(graphic);
}
});Highlight Options
// Set highlight options on the view
view.highlightOptions = {
color: [255, 255, 0, 1],
haloOpacity: 0.9,
fillOpacity: 0.2,
};Sketching
Sketch Component (Simplest)
<arcgis-map basemap="topo-vector" center="139.5716,35.696" zoom="18">
<arcgis-sketch slot="top-right" creation-mode="update"></arcgis-sketch>
</arcgis-map>The arcgis-sketch component provides drawing tools for point, polyline, polygon, rectangle, and circle geometries with snapping, undo/redo, and selection support.
Key Attributes:
| Attribute | Type | Description |
creation-mode | "single" | "update" | "continuous" | How sketched graphics are handled after creation |
available-create-tools | string | Comma-separated list of enabled create tools |
multiple-selection-enabled | boolean | Allow selecting multiple graphics |
update-on-graphic-click | boolean | Start updating when clicking a graphic |
Key Events:
| Event | Description |
arcgisCreate | Fires during graphic creation |
arcgisUpdate | Fires during graphic update |
arcgisDelete | Fires when graphics are deleted |
arcgisUndo | Fires on undo |
arcgisRedo | Fires on redo |
Key Methods:
| Method | Description |
create(tool) | Start creating a graphic ("point", "polyline", "polygon", "rectangle", "circle") |
update(graphics) | Start updating graphics |
delete() | Delete selected graphics |
undo() / redo() | Undo/redo last action |
Sketch Component with Events
<arcgis-map basemap="topo-vector">
<arcgis-sketch slot="top-right" creation-mode="update"></arcgis-sketch>
</arcgis-map>
<script type="module">
const sketch = document.querySelector("arcgis-sketch");
sketch.addEventListener("arcgisCreate", (event) => {
const { state, graphic } = event.detail;
if (state === "complete") {
console.log("Created:", graphic.geometry.type);
}
});
sketch.addEventListener("arcgisUpdate", (event) => {
const { state, graphics } = event.detail;
if (state === "complete") {
console.log("Updated:", graphics.length, "graphics");
}
});
sketch.addEventListener("arcgisDelete", (event) => {
console.log("Deleted:", event.detail.graphics.length, "graphics");
});
</script>Sketch Widget (Core API)
import Sketch from "@arcgis/core/widgets/Sketch.js";
import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer.js";
const graphicsLayer = new GraphicsLayer();
map.add(graphicsLayer);
const sketch = new Sketch({
view: view,
layer: graphicsLayer,
creationMode: "update", // or "single", "continuous"
});
view.ui.add(sketch, "top-right");
// Listen for events
sketch.on("create", (event) => {
if (event.state === "complete") {
console.log("Created:", event.graphic);
}
});
sketch.on("update", (event) => {
if (event.state === "complete") {
console.log("Updated:", event.graphics);
}
});
sketch.on("delete", (event) => {
console.log("Deleted:", event.graphics);
});Draw Tool (Low-level)
import Draw from "@arcgis/core/views/draw/Draw.js";
const draw = new Draw({ view: view });
// Create a polygon
const action = draw.create("polygon");
action.on("vertex-add", (event) => {
console.log("Vertex added:", event.vertices);
});
action.on("draw-complete", (event) => {
const polygon = {
type: "polygon",
rings: event.vertices,
spatialReference: view.spatialReference,
};
// Create graphic with polygon
});Event Handling
View Events
// Click (waits for potential double-click delay)
view.on("click", (event) => {
console.log("Map point:", event.mapPoint);
console.log("Screen point:", event.x, event.y);
});
// Immediate-click (fires without delay, recommended for hit testing)
view.on("immediate-click", (event) => {
console.log("Immediate click at:", event.mapPoint);
});
// Double-click
view.on("double-click", (event) => {
event.stopPropagation(); // Prevent default zoom
});
// Immediate-double-click (cannot be prevented by immediate-click stopPropagation)
view.on("immediate-double-click", (event) => {
console.log("Double clicked");
});
// Pointer move
view.on("pointer-move", (event) => {
const point = view.toMap(event);
console.log("Coordinates:", point.longitude, point.latitude);
});
// Drag
view.on("drag", (event) => {
if (event.action === "start") {
}
if (event.action === "update") {
}
if (event.action === "end") {
}
});
// Key events
view.on("key-down", (event) => {
if (event.key === "Escape") {
// Cancel operation
}
});Tip: Use
immediate-clickinstead ofclickwhen responding to user clicks without delay (e.g., for hit testing). Theclickevent waits to check for a double-click, which adds latency.
Property Watching with reactiveUtils
import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js";
// Watch for view stationary state
reactiveUtils.when(
() => view.stationary === true,
() => {
console.log("Navigation complete, extent:", view.extent);
},
);
// Watch zoom changes
reactiveUtils.watch(
() => view.zoom,
(zoom) => {
console.log("Zoom changed to:", zoom);
},
);
// Watch multiple properties
reactiveUtils.watch(
() => [view.center, view.zoom],
([center, zoom]) => {
console.log("View changed:", center, zoom);
},
);
// One-time wait
await reactiveUtils.whenOnce(() => view.ready);
console.log("View is ready");Layer Events
const layerView = await view.whenLayerView(featureLayer);
reactiveUtils.watch(
() => layerView.updating,
(updating) => {
if (!updating) {
console.log("Layer update complete");
}
},
);Coordinate Conversion
// Screen to map coordinates
const mapPoint = view.toMap({ x: screenX, y: screenY });
// Map to screen coordinates
const screenPoint = view.toScreen(mapPoint);Programmatic Popup Control
For detailed PopupTemplate configuration, see
arcgis-popup-templates.
// Open popup programmatically
view.openPopup({
title: "Custom Popup",
content: "Hello World",
location: view.center,
});
// Close popup
view.closePopup();Complete Example: Hit Test with Highlight
Map Components
<!DOCTYPE html>
<html>
<head>
<script src="https://js.arcgis.com/5.0/"></script>
<script
type="module"
src="https://js.arcgis.com/5.0/map-components/"
></script>
<style>
html,
body {
height: 100%;
margin: 0;
}
</style>
</head>
<body>
<arcgis-map
basemap="streets-navigation-vector"
center="-118.805,34.027"
zoom="13"
>
<arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-map>
<script type="module">
const [FeatureLayer] = await $arcgis.import([
"@arcgis/core/layers/FeatureLayer.js",
]);
const mapElement = document.querySelector("arcgis-map");
const view = await mapElement.view;
await view.when();
const featureLayer = new FeatureLayer({
url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0",
});
mapElement.map.add(featureLayer);
let highlightHandle;
view.on("pointer-move", async (event) => {
const response = await view.hitTest(event, { include: featureLayer });
if (highlightHandle) {
highlightHandle.remove();
highlightHandle = null;
}
if (response.results.length > 0) {
const graphic = response.results[0].graphic;
const layerView = await view.whenLayerView(featureLayer);
highlightHandle = layerView.highlight(graphic);
document.body.style.cursor = "pointer";
} else {
document.body.style.cursor = "default";
}
});
</script>
</body>
</html>Reference Samples
view-hittest- Hit testing to identify features at screen coordinatesmap-component-hittest- Access features with hitTest using Map Componentssketch- Sketch component for drawing geometriessketch-geometries- Sketching geometries with the Sketch widgetsketch-update-validation- Validating sketch updatessketch-snapping-magnifier- Snapping and magnifier with Sketch
Common Pitfalls
Highlight handle leak: Creating new highlights without removing previous ones causes memory leaks.
// Anti-pattern: creating highlights without cleaning up previous ones view.on("pointer-move", async (event) => { const response = await view.hitTest(event); if (response.results.length > 0) { const feature = response.results[0].graphic; // New highlight created every pointer-move - old ones never removed layerView.highlight(feature); } });// Correct: store handle and remove before creating a new highlight let highlightHandle = null; view.on("pointer-move", async (event) => { const response = await view.hitTest(event); if (highlightHandle) { highlightHandle.remove(); highlightHandle = null; } if (response.results.length > 0) { const feature = response.results[0].graphic; highlightHandle = layerView.highlight(feature); } });Impact: Each pointer-move adds another highlight without removing the previous one. Highlights accumulate visually and in memory, causing performance degradation.
Events fire multiple times: Adding event listeners repeatedly without cleanup causes handler accumulation.
// Anti-pattern: adding listeners in a function that gets called multiple times function setupInteraction() { view.on("click", async (event) => { const result = await view.hitTest(event); console.log("Clicked:", result); }); } setupInteraction(); // First handler setupInteraction(); // Second handler - now click fires twice// Correct: store handle and remove before re-adding, or add once let clickHandle = null; function setupInteraction() { if (clickHandle) { clickHandle.remove(); } clickHandle = view.on("click", async (event) => { const result = await view.hitTest(event); console.log("Clicked:", result); }); }Impact: Each call to the setup function adds another listener. Clicks fire multiple duplicate callbacks.
- Hit test returns nothing: Check if layers are included/excluded correctly, and ensure the view is ready.
- Using click instead of immediate-click: The
clickevent has a built-in delay to check for double-clicks. Useimmediate-clickfor responsive hit testing. - Popup not showing: Ensure layer has
popupEnabled: true(default) and apopupTemplateset.
Related Skills
- See
arcgis-popup-templatesfor detailed PopupTemplate configuration. - See
arcgis-editingfor feature editing workflows. - See
arcgis-core-mapsfor view initialization and navigation.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

