Skip to content

Commit

Permalink
Add webview view sample
Browse files Browse the repository at this point in the history
  • Loading branch information
mjbvz committed Aug 25, 2020
1 parent 8d43af0 commit 69409d5
Show file tree
Hide file tree
Showing 15 changed files with 1,801 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .scripts/samples.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ const samples = [
description: 'Webview Sample',
path: 'webview-sample',
guide: '/api/extension-guides/webview',
apis: ['window.registerWebviewViewProvider'],
contributions: []
},
{
description: 'Webview View Sample',
path: 'webview-view-sample',
guide: '/api/extension-guides/webview',
apis: ['window.createWebviewPanel', 'window.registerWebviewPanelSerializer'],
contributions: []
},
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ You need to have [node](https://nodejs.org/en/) and [npm](https://nodejs.org/en/
<!-- SAMPLES_BEGIN -->
| Sample | Guide on VS Code Website | API & Contribution |
| ------ | ----- | --- |
| [Webview Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/webview-sample) | [/api/extension-guides/webview](https://code.visualstudio.com/api/extension-guides/webview) | [window.createWebviewPanel](https://code.visualstudio.com/api/references/vscode-api#window.createWebviewPanel)<br>[window.registerWebviewPanelSerializer](https://code.visualstudio.com/api/references/vscode-api#window.registerWebviewPanelSerializer) |
| [Webview Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/webview-sample) | [/api/extension-guides/webview](https://code.visualstudio.com/api/extension-guides/webview) | [window.registerWebviewViewProvider](https://code.visualstudio.com/api/references/vscode-api#window.registerWebviewViewProvider) |
| [Webview View Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/webview-view-sample) | [/api/extension-guides/webview](https://code.visualstudio.com/api/extension-guides/webview) | [window.createWebviewPanel](https://code.visualstudio.com/api/references/vscode-api#window.createWebviewPanel)<br>[window.registerWebviewPanelSerializer](https://code.visualstudio.com/api/references/vscode-api#window.registerWebviewPanelSerializer) |
| [Status Bar Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/statusbar-sample) | N/A | [window.createStatusBarItem](https://code.visualstudio.com/api/references/vscode-api#window.createStatusBarItem)<br>[StatusBarItem](https://code.visualstudio.com/api/references/vscode-api#StatusBarItem) |
| [Tree View Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/tree-view-sample) | [/api/extension-guides/tree-view](https://code.visualstudio.com/api/extension-guides/tree-view) | [window.createTreeView](https://code.visualstudio.com/api/references/vscode-api#window.createTreeView)<br>[window.registerTreeDataProvider](https://code.visualstudio.com/api/references/vscode-api#window.registerTreeDataProvider)<br>[TreeView](https://code.visualstudio.com/api/references/vscode-api#TreeView)<br>[TreeDataProvider](https://code.visualstudio.com/api/references/vscode-api#TreeDataProvider)<br>[contributes.views](https://code.visualstudio.com/api/references/contribution-points#contributes.views)<br>[contributes.viewsContainers](https://code.visualstudio.com/api/references/contribution-points#contributes.viewsContainers) |
| [Task Provider Sample](https://github.com/Microsoft/vscode-extension-samples/tree/master/task-provider-sample) | [/api/extension-guides/task-provider](https://code.visualstudio.com/api/extension-guides/task-provider) | [tasks.registerTaskProvider](https://code.visualstudio.com/api/references/vscode-api#tasks.registerTaskProvider)<br>[Task](https://code.visualstudio.com/api/references/vscode-api#Task)<br>[ShellExecution](https://code.visualstudio.com/api/references/vscode-api#ShellExecution)<br>[contributes.taskDefinitions](https://code.visualstudio.com/api/references/contribution-points#contributes.taskDefinitions) |
Expand Down
20 changes: 20 additions & 0 deletions webview-view-sample/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**@type {import('eslint').Linter.Config} */
// eslint-disable-next-line no-undef
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: [
'@typescript-eslint',
],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
],
rules: {
'semi': [2, "always"],
'@typescript-eslint/no-unused-vars': 0,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/explicit-module-boundary-types': 0,
'@typescript-eslint/no-non-null-assertion': 0,
}
};
9 changes: 9 additions & 0 deletions webview-view-sample/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp

// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"dbaeumer.vscode-eslint"
]
}
18 changes: 18 additions & 0 deletions webview-view-sample/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// A launch configuration that compiles the extension and then opens it inside a new window
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}"],
"outFiles": ["${workspaceFolder}/out/**/*.js"],
"preLaunchTask": "npm: watch"
}
]
}
3 changes: 3 additions & 0 deletions webview-view-sample/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"editor.insertSpaces": false
}
20 changes: 20 additions & 0 deletions webview-view-sample/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
24 changes: 24 additions & 0 deletions webview-view-sample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Calico Colors — Webview View API Sample

Demonstrates VS Code's proposed [webview view API](https://github.com/microsoft/vscode/issues/46585). This includes:

- Contributing a webview based view to the explorer.
- Posting messages from an extension to a webview view
- Posting message from a webview to an extension
- Persisting state in the view.

## VS Code API

### `vscode` module

- [`window.createWebviewPanel`](https://code.visualstudio.com/api/references/vscode-api#window.createWebviewPanel)


## Running the example

- Open this example in VS Code 1.49+
- `npm install`
- `npm run watch` or `npm run compile`
- `F5` to start debugging

In the explorer, expand the `Calico Colors` view.
46 changes: 46 additions & 0 deletions webview-view-sample/media/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
body {
background: transparent;
}

.color-list {
list-style: none;
padding: 0;
}

.color-entry {
width: 100%;
display: flex;
margin-bottom: 0.4em;
border: 1px solid var(--vscode-input-border);
}

.color-preview {
width: 2em;
height: 2em;
}

.color-preview:hover {
outline: inset white;
}

.color-input {
display: block;
flex: 1;
width: 100%;
color: var(--vscode-input-foreground);
background-color: var(--vscode-input-background);
border: none;
padding: 0 0.6em;
}

.add-color-button {
display: block;
color: var(--vscode-button-foreground);
background: var(--vscode-button-background);
border: none;
margin: 0 auto;
}

.add-color-button:hover {
background: var(--vscode-button-hoverBackground);
}
90 changes: 90 additions & 0 deletions webview-view-sample/media/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//@ts-check

// This script will be run within the webview itself
// It cannot access the main VS Code APIs directly.
(function () {
const vscode = acquireVsCodeApi();

const oldState = vscode.getState() || { colors: [] };

/** @type {Array<{ value: string }>} */
let colors = oldState.colors;

updateColorList(colors);

document.querySelector('.add-color-button').addEventListener('click', () => {
addColor(colors, getNewCalicoColor, updateColorList);
});

// Handle messages sent from the extension to the webview
window.addEventListener('message', event => {
const message = event.data; // The json data that the extension sent
switch (message.type) {
case 'addColor':
addColor();
break;
}
});

/**
* @param {Array<{ value: string }>} colors
*/
function updateColorList(colors) {
const ul = document.querySelector('.color-list');
ul.textContent = '';
for (const color of colors) {
const li = document.createElement('li');
li.className = 'color-entry';

const colorPreview = document.createElement('div');
colorPreview.className = 'color-preview';
colorPreview.style.backgroundColor = `#${color.value}`;
colorPreview.addEventListener('click', () => {
onColorClicked(color.value);
});
li.appendChild(colorPreview);

const input = document.createElement('input');
input.className = 'color-input';
input.type = 'text';
input.value = color.value;
input.addEventListener('change', (e) => {
const value = e.target.value;
if (!value) {
// Treat empty value as delete
colors.splice(colors.indexOf(color), 1);
} else {
color.value = value;
}
updateColorList(colors);
});
li.appendChild(input);

ul.appendChild(li);
}

// Update the saved state
vscode.setState({ colors: colors });
}

/**
* @param {string} color
*/
function onColorClicked(color) {
vscode.postMessage({ type: 'colorSelected', value: color });
}

/**
* @returns string
*/
function getNewCalicoColor() {
const colors = ['020202', 'f1eeee', 'a85b20', 'daab70', 'efcb99'];
return colors[Math.floor(Math.random() * colors.length)];
}
}());

function addColor(colors, getNewCalicoColor, updateColorList) {
colors.push({ value: getNewCalicoColor() });
updateColorList(colors);
}

0 comments on commit 69409d5

Please sign in to comment.