Esri welcomes contributions from anyone and everyone. Please see our guidelines for contributing.
Table of Contents
- Before you get started
- I want to contribute, what should I work on?
- Suggesting new snippets
- Development environment
- Add your changes
- Commit message format
- Pull request
- Conventions
- FAQ
- Additional resources
The first thing you should familiarize yourself with, if you have never created a custom snippet in Visual Studio Code, is the most important components that make up Intellisense (intelligent code completion) in Visual Studio Code:
These fields are shown in the image above: prefix
, name
, description
, and body
, have to be defined in a JSON object that looks like this:
"Layer View query features": {
"prefix": ["layerView", "layerViewQF"],
"body": [
"layerView.queryFeatures().then(function(results){",
"\tconsole.log(results.features);",
"});",
],
"description": "Get features in the layer"
}
Where:
- "Layer View query features": is the snippet name. It is displayed via IntelliSense if no
description
is provided prefix
defines one or more trigger words that display the snippet in IntelliSense. Substring matching (fuzzy search) is performed on prefixes, that's why in this case, "lq" matched "layerViewQF"body
is one or more lines of content, which will be joined as multiple lines upon insertion. Newlines and embedded tabs will be formatted according to the context in which the snippet is inserted.description
is a description of the snippet displayed by IntelliSense.
Note: there is another optional component (scope) that can be used to specify in which context (language) the snippet is relevant.
To improve accessibility and usability, Visual Studio Code have a special syntax that can be used inside the body
, for example placeholders, and choices:
Later on, we will see in which file(s) we will have to add this code and the user interface we provide to facilitate the creation of the snippet code.
The most relevant files and folders in this repository are:
- .vscode/: the most important file in this folder is
development.code-snippets
that you will use to test the snippets you will contribute. - builder/: this folder include the code of the Snippets Builder application.
- dev/: this folder contains the files to help you during your development proccess, and the instructions on how to use them.
- images/: contains the assets being used in the README files as well as the icon being use in the Visual Studio Code marketplace.
- snippets/: this folder have all the available snippets within the official extension that is published (defined in the package.json file).
- CHANGELOG.md: this file keeps a log or record of all notable changes made to the project.
You can help mostly by:
- Adding ideas for snippets using the snippet builder. If you are planning to do so, check Suggesting new snippets.
- Requesting enhancements for existing snippets by creating a Enhancement issue.
- Reporting problems by creating a Bug issue.
- Working on the issues marked as
help wanted
. There is also agood first issue
label if you are just getting started.- Comment on the issue and check if any additional context is needed before you start working. This will also help everyone knows that you are already working on it.
- Sharing your own list of snippets to the community snippets
If you plan to propose new snippets, this section contains an overview of the main type of snippets this extension contains for each language, but if you have any another idea(s), do not hesitate to share them.
The list below summarize the main type of snippets within snippets/javascript.json, snippets/typescript.json, and snippets/typescriptreact.json.
1) Initialization of classes.
Instantiate an object of a new class like MapView, FeatureLayers, widgets (e.g. Search widget with multple configurations: multiple sources, custom sources, ...).
Examples: FeatureLayerClientSide
new FeatureLayer({
fields: [{
name: "OBJECTID",
type: "oid"
}, {
name: "${1:url}",
type: "string"
}],
objectIdField: "OBJECTID",
popupTemplate: {
content: "${2:<img src='{url}'>}"
},
renderer: ${3:Renderer},
source: ${4:graphics},
});
2) JS objects with constructor properties
JavaScript objects to facilitate class configuration:
Examples: featureReductionClusterProps
{
type: "cluster",
clusterMaxSize: ${1:37.5},
clusterMinSize: ${2:16.5},
clusterRadius: ${3:60},
labelingInfo: ${4:LabelClass},
labelsVisible: true,
popupEnabled: true,
popupTemplate: ${5:PopupTemplate}
}
3) Common procedures and programming patterns
Like query a layer, disable navigation, project a geometry, ...
Example: queryLayerView
view.whenLayerView(${1:fl}).then(function (layerView) {
layerView.queryFeatures().then(function (results) {
console.log(results.features);
});
});
4) Enumeration of possible values
Snippets to help choosing between multiple enumerations, like basemap styles, renderer types, symbol types, layer types, ...
Example: basemapsWithAPIKeys
${1|arcgis-imagery,arcgis-imagery-standard,arcgis-imagery-labels,arcgis-light-gray,arcgis-dark-gray,arcgis-navigation,arcgis-navigation-night,arcgis-streets,arcgis-streets-night,arcgis-streets-relief,arcgis-topographic,arcgis-oceans,osm-standard,osm-standard-relief,osm-streets,osm-streets-relief,osm-light-gray,osm-dark-gray,arcgis-terrain,arcgis-community,arcgis-charted-territory,arcgis-colored-pencil,arcgis-nova,arcgis-modern-antique,arcgis-midcentury,arcgis-newspaper,arcgis-hillshade-light,arcgis-hillshade-dark|}
The list of snippets within html.json, and json.json is short, so we encourage you to check yourself.
At this point you are almost ready to start doing your contribution.
Go to the dev folder, and read the instructions to learn how to setup and use your local development environment.
Do you have your contribution ready? If so, keep reading.
Although it is possible to make your changes directly through the GitHub web interface, we recommend that you add your changes to a local copy of the repository.
Which branch should I use?
If your are not doing a lot of changes you can use master
, otherwise we encourage you to do the changes in a new branch. Branch name convention:
- For changes associated with an issue:
<username>/<issue-description>-<issue-id>
. - For changes without an associated issue:
<username>/<issue-description>
.
Checklist before doing a Pull Request
Please ensure that you have completed the following steps before making a PR:
- Update the corresponding file in the snippets folder. Depending on the type of snippet, you need to will have to modify:
html.json
,javascript.json
,json.json
,typescript.json
, ...- Make sure your snippet meets our conventions.
- Make sure snippets are sorted in the alphabetical order, by
name
). Use any JSON ABC checking "Spare plain Arrays". - Validate JSON and indentation with JSONLint.
- Update the snippets table within the README.md to reflect the changes.
- Update the CHANGELOG.md file to reflect the changes.
- Commit your changes.
This project do not strictly follows conventional commits, but we will use the format <type>: description [optional #issue-number]
to generate the changelog. Be sure to provide clear and sufficient information in commit messages.
For <type>
you should use:
- feat: A new snippet or feature
- fix: A bug fix with the snippet
- docs: Documentation only changes (changes in markdown)
- style: Changes that do not affect the meaning of the code (conventions, white-space, formatting, missing semi-colons, etc)
- refactor: A code change that neither fixes a bug nor adds a feature
description
:
- The subject contains succinct description of the change
- use the imperative, present tense: "change" not "changed" nor "changes"
- do not capitalize first letter
- do not place a period . at the end
- entire length of the subject must not go over 50 characters
- describe what the commit does, not what issue it relates to or fixes
- be brief, yet descriptive - we should have a good understanding of what the commit does by reading the subject
Examples:
style: apply prefix conventions to all snippets #30
doc: update contributing guidelines and minor conventions changes #37
Reminder: before doing a PR, ensure that you have completed the checklist included in Add your changes.
When submitting:
- If you are adding a new snippet, please provide a codepen example to help during the review process.
- If you are working on an issue, remember to link your PR to it, by use a supported keyword in the pull request description. For example: "
Closes #10
" or "Fixes Esri/arcgis-js-vscode-snippets#10
".
Prefix are the trigger words that display the snippet in the Intellisense:
- Avoid acronyms (like
sms
forSimpleMarkerSymbol
) - Use camelCase (not snake_case, UPPERCASE, etc.)
- Per snippet type:
- Class properties objects: add the suffix "Props".
- Class constructors: match JS SDK capitalization.
⚠️ Important: when changing an exist prefix, or backwards compatibility, if the new prefix is totally different, instead of removing the previous prefix, add a new one (prefix
supportstrings
andarrays
), but new one as the first element in the array.
Examples:
- Class constructors:
SimpleMarkerSymbol
,MapView
, ... - Class properties objects:
popupTemplateProps
,featureReductionClusterProps
... - Common procedures an enumerations:
basemapsWithAPIKeys
,findLayerByTitle
, ...
If you want to suggest a change, please check the issue #10.
Name is the short description that follows the prefix:
- Start your sentence with capitals (do not capitalize, uppercase)
- Use plain english using spaces as needed (don't use camelCase, snake_case, PascalCase, or kebab-case).
- Keep the name short as possible to avoid ellipsis ("..."). Ideally it should be less than 35 characters, but it also depends on the prefix(es) length, so try and adjust it.
Examples:
City scale 3D callout
Create class breaks renderer
Create 3D extruded polygon symbol
Generate icon Point 3D
If you want to suggest a change, please check the issue #20.
Description is a long description that precedes the body:
- It should be a proper description of what the snippet does, and reuse text from the API reference whenever possible.
- For "Initialization of classes" snippets finish with:
AMD path: <path> | ESM path: <path>
- For "JS objects with constructor properties" finish with:
This snippet is usually used to set the property \"<property-name>\" of a <class-name(s)>
Examples:
Load the config, Map and MapView modules using require.
Use of these basemaps requires a valid ArcGIS Online organizational subscription or an ArcGIS Enterprise license.
Specifies how features are placed on the vertical axis (z). This snippets should be used to set the property "elevationInfo" of a FeatureLayer, CSVLayer, WFSLayer, SceneLayer, StreamLayer, GeoJSONLayer, IntegratedMeshLayer, etc.
Creates the labelingInfo for labels in a layer for 3D maps. It is normally used in the property "labelingInfo[]" of a FeatureLayer, SceneLayer or any layyer with that property within a SceneView. AMD path: esri/layers/support/LabelClass | ESM path: @arcgis/core/layers/support/LabelClass.js
If you want to suggest a change, please check the issue #21.
Body contain the code snippet that will be inserted:
If you want to suggest a change, please check the issue #19.
Note: You don't have to worry about this if you use the Snippets Builder.
Example:
{
"tsconfig-basic": {
"prefix": "tsConfigBasic",
"body": [
"{",
"\t\"compilerOptions\": {",
"\t\t\"module\": \"amd\",",
"\t\t\"sourceMap\": true,",
"\t\t\"target\": \"es2019\",",
"\t\t\"esModuleInterop\": true",
"\t}",
"}"
],
"description": "Simple TS Config"
}
Follow the ArcGIS Maps SDK for JavaScript coding conventions define in github.com/esri/jsapi-resources/.prettierrc.json:
- Plain JavaScript:
- Print semicolons at the ends of statements.
- Always require parentheses around arrow function arguments (example).
- Print spaces between brackets in object literals: true (example).
- If at least one property in an object requires quotes, quote all properties.
- No trailing commas (final commas)
- Line length: 120
- JavaScript React (JSX):
- Put the > of a multi-line JSX element at the end of the last line instead of being alone on the next line (does not apply to self closing elements) (example).
- Line length: 100
We have set this prettier.io/playground to help you beautify your code.
Example:
// queries all features in the layer
myLayer.queryFeatures().then(results => {
// queries features and returns a FeatureSet
})
Try not to instantiate more than one class whenever possible. Keeping snippets small helps make them more reusable. So instead of doing this:
Example:
const webmap = new WebMap({
portalItem: {
id: "webmap_id"
}
});
const view = new MapView({
container: "viewDiv",
map: webmap
});
Try to split it in two:
new WebMap({
portalItem: {
id: "webmap_id"
}
});
new MapView({
container: "viewDiv",
map: webmap
});
- Sort properties by alphabetical order.
- For "JS objects with constructor properties"
type
is an exception. It can be set as the first one.
- For "JS objects with constructor properties"
- Include what you think are the most common properties.
- If a property expects another instance of class, add the name of the snippet (if it exists).
- When a property support multiple value types, add just a placeholder.
Example:
new PopupTemplate({
// ...
content: popupContent[] | String | Function | Promise,
title: "Population in {NAME}",
// ...
})
Observe the PopupTemplate property "content" include a list of possible values, and popupContent
will trigger other snippets like:
popupCustomContent
, popupMediaContent
, popupFieldsContent
, popupTextContent
and popupAttachmentsContent
.
Avoid doing this:
const webmap = new WebMap({
portalItem: {
id: "webmap_id"
}
});
Just do this:
new WebMap({
portalItem: {
id: "webmap_id"
}
})
For methods like fromJSON(), which is inherited in many classes, for example: SimpleRenderer, UniqueValueRenderer, HeatmapRenderer, ... do something like this:
${1|Simple,UniqueValue,ClassBreaks,Dictionary,DotDensity,Heatmap|}Renderer.fromJSON(json)
I have made a contribution, but I can't find the contribution in the extension deployed in the marketplace. Why?
The Esri team have to to deploy a new version of the snippet to the Visual Studio Code marketplace in order to make the changes available to every user of the extension.
Can I modify the local installation of the extension to test my edits?
To avoid conflicts and overwrites, we do not recommend editing the local installation of your extension placed in your home folder (~/.vscode/extensions/esri.arcgis-maps-sdk-js-snippets-VERSION_NO
).
- Visual Studio Code Snippets Builder.
- Visual Studio Code official documentation: