diff --git a/webview-codicons-sample/README.md b/webview-codicons-sample/README.md index e4a552bc3..6ad9d3044 100644 --- a/webview-codicons-sample/README.md +++ b/webview-codicons-sample/README.md @@ -1,4 +1,4 @@ -# Cat Codicons +# Webview with Codicons Demonstrates loading [codicons](https://github.com/microsoft/vscode-codicons) in a [webview](https://code.visualstudio.com/api/extension-guides/webview). @@ -15,4 +15,69 @@ Demonstrates loading [codicons](https://github.com/microsoft/vscode-codicons) in - `npm run watch` or `npm run compile` - `F5` to start debugging -Run the `Cat Codicons: Show Cat Codicons` command to create the webview. +Run the `Webview Codicons: Show Webview Codicons` command to create the webview. + +While similar user experience can be achieved by including image files into your extension and using the `` tag in the Webview HTML, using Codicons provides far simpler way to support themes. While on the _Webview Codicons_ panel, try switching between the light and dark theme. + +![demo](demo.gif) + +## How to use Codicons + +First, include the `vscode-codicons` package into the `dependencies` in `package.json`: + +```json +"dependencies": { +"vscode-codicons": "0.0.12" +} +``` + +Second, refer to the Codicons font and styles from your Webview HTML: + +Get resource paths: + +```typescript +const styleUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, 'media', 'styles.css')); +const codiconsUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, 'node_modules', 'vscode-codicons', 'dist', 'codicon.css')); +const codiconsFontUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, 'node_modules', 'vscode-codicons', 'dist', 'codicon.ttf')); +``` + +Declare the Codicons resources in the Content Security Policy and link the stylesheets into your HTML: + +```html + + + + +``` + +Last, add any Codicon into your HTML: + +```html + +``` + +## Styling and interacting with codicons + +Icons can be styled as any other HTML content: + +```html +
check
+``` + +```css +div.styledIcon .codicon { + font-size: 50px; + color: green; + padding: 3px; +} +``` + +However, it is recommended to use CSS variable to reference a VS Code color token, +rather than hard-coding any concrete color. + +```css + color: var(--vscode-debugIcon-startForeground); +``` + +![demo styling and interacting with codicons](demo_styling.gif) diff --git a/webview-codicons-sample/demo.gif b/webview-codicons-sample/demo.gif index 13b39b44d..3770d1a9a 100644 Binary files a/webview-codicons-sample/demo.gif and b/webview-codicons-sample/demo.gif differ diff --git a/webview-codicons-sample/demo_styling.gif b/webview-codicons-sample/demo_styling.gif new file mode 100644 index 000000000..72cb860ce Binary files /dev/null and b/webview-codicons-sample/demo_styling.gif differ diff --git a/webview-codicons-sample/media/styles.css b/webview-codicons-sample/media/styles.css index 2e2bd44f1..59dfb3768 100644 --- a/webview-codicons-sample/media/styles.css +++ b/webview-codicons-sample/media/styles.css @@ -56,5 +56,40 @@ h1 { #icons .icon .codicon { font-size: 32px; - padding-bottom: 16px; +} + +/* Codicon styling and interaction demo */ + +div.iconBar .codicon { + font-size: 60px; + cursor: pointer; +} + +div.iconBar .disabled { + opacity: 0.3; + cursor: not-allowed; +} + +#play { + /* Use CSS variable to reference a VS Code color token, rather than any concrete color. */ + color: var(--vscode-debugIcon-startForeground); +} + +#stop { + color: var(--vscode-debugIcon-stopForeground); +} + +/* Rotating the 'loading' Codicon to indicate _progress_. +Same implementation as what VS Code is using in the user interface. +https://github.com/microsoft/vscode/blob/master/src/vs/base/browser/ui/codicons/codicon/codicon-animations.css +*/ +@keyframes codicon-spin { + 100% { + transform:rotate(360deg); + } +} + +.codicon-animation-spin { + /* Use steps to throttle FPS to reduce CPU usage */ + animation: codicon-spin 1.5s steps(30) infinite; } \ No newline at end of file diff --git a/webview-codicons-sample/package.json b/webview-codicons-sample/package.json index 7b664665e..6e2d6aef1 100644 --- a/webview-codicons-sample/package.json +++ b/webview-codicons-sample/package.json @@ -1,7 +1,7 @@ { - "name": "cat-codicons", - "description": "Cat Codicons - Using codicons in webviews", - "version": "0.0.1", + "name": "webview-codicons", + "description": "Webview Codicons - Using codicons in webviews", + "version": "0.0.2", "publisher": "vscode-samples", "engines": { "vscode": "^1.47.0" @@ -10,7 +10,7 @@ "Other" ], "activationEvents": [ - "onCommand:catCodicons.show" + "onCommand:webviewCodicons.show" ], "repository": { "type": "git", @@ -20,9 +20,9 @@ "contributes": { "commands": [ { - "command": "catCodicons.show", - "title": "Show Cat Codicons", - "category": "Cat Codicons" + "command": "webviewCodicons.show", + "title": "Show Webview Codicons", + "category": "Webview Codicons" } ] }, @@ -32,14 +32,15 @@ "lint": "eslint . --ext .ts,.tsx", "watch": "tsc -w -p ./" }, - "dependencies": {}, + "dependencies": { + "vscode-codicons": "0.0.14" + }, "devDependencies": { "@types/node": "^12.12.0", "@types/vscode": "^1.47.0", "@typescript-eslint/eslint-plugin": "^4.16.0", "@typescript-eslint/parser": "^4.16.0", "eslint": "^7.21.0", - "typescript": "^4.2.2", - "vscode-codicons": "0.0.7" + "typescript": "^4.2.2" } } \ No newline at end of file diff --git a/webview-codicons-sample/src/extension.ts b/webview-codicons-sample/src/extension.ts index a4a1d66b1..77fb9710c 100644 --- a/webview-codicons-sample/src/extension.ts +++ b/webview-codicons-sample/src/extension.ts @@ -2,16 +2,16 @@ import * as vscode from 'vscode'; export function activate(context: vscode.ExtensionContext) { context.subscriptions.push( - vscode.commands.registerCommand('catCodicons.show', () => { - CatCodiconsPanel.show(context.extensionUri); + vscode.commands.registerCommand('webviewCodicons.show', () => { + WebviewCodiconsPanel.show(context.extensionUri); }) ); } -class CatCodiconsPanel { +class WebviewCodiconsPanel { - public static readonly viewType = 'catCodicons'; + public static readonly viewType = 'webviewCodicons'; public static show(extensionUri: vscode.Uri) { const column = vscode.window.activeTextEditor @@ -19,11 +19,20 @@ class CatCodiconsPanel { : undefined; const panel = vscode.window.createWebviewPanel( - CatCodiconsPanel.viewType, - "Cat Codicons", + WebviewCodiconsPanel.viewType, + "Webview Codicons", column || vscode.ViewColumn.One ); + panel.webview.options = { + // Allow scripts in the webview + enableScripts: true, + + localResourceRoots: [ + extensionUri + ] + } + panel.webview.html = this._getHtmlForWebview(panel.webview, extensionUri); } @@ -34,6 +43,9 @@ class CatCodiconsPanel { const codiconsUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, 'node_modules', 'vscode-codicons', 'dist', 'codicon.css')); const codiconsFontUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, 'node_modules', 'vscode-codicons', 'dist', 'codicon.ttf')); + // Use a nonce to only allow a specific script to be run. + const nonce = getNonce(); + return ` @@ -43,15 +55,16 @@ class CatCodiconsPanel { Use a content security policy to only allow loading images from https or from our extension directory, and only allow scripts that have a specific nonce. --> - + - Cat Coding + Webview Coding +

codicons

account
@@ -380,8 +393,44 @@ class CatCodiconsPanel {
zoom-in
zoom-out
+ +

styling and interacting with codicons

+
+ + + +
+ + `; } } +function getNonce() { + let text = ''; + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (let i = 0; i < 32; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + return text; +}