vscode-webview-ui-toolkit
vscode-webview-ui-toolkit copied to clipboard
How do you use icon buttons? The code examples don't work.
Describe the bug
Icons do not show up for appearance="icon"
buttons with the examples given on the button component docs:
<vscode-button appearance="icon">
<span class="codicon codicon-check"></span>
</vscode-button>
There appears to be no instructions on getting the <span class="codicon codicon-check"></span>
bit to work.
To reproduce
Paste the example snippet into a webview where <vscode-button>
is defined.
Expected behavior
The button shows an icon.
Current behavior
The button doesn't show an icon:
Screenshots
Desktop (please complete the following information):
- OS Version:
macOS 14.3.1
- Toolkit Version:
v1.4.0
Additional context
Thanks for calling this out, this is definitely long overdue for some more extensive documentation π
To give some context, the doc code snippets demonstrate usage of the Codicons icon library (a library that is created/managed independently of this one). We historically didn't document how to install/setup Codicons because it has it's own documentation/samples for configuring the icons within a webview and is one of any number of icon libraries that can be used in a webview extension.
Generally using an icon library in a webview falls under the umbrella of loading local content into a webview which is also documented separately in the VS Code API docs. But like I said, we're long overdue for offering a bit more guidance/direction to folks in our docs.
I'll take this issue as a task to update our docs, but to immediately unblock you, you can configure Codicons by:
- Downloading a copy of the
codicon.css
andcodicon.ttf
files from the Codicons GitHub repo - Save those files somewhere in your
src
directory (in our toolkit samples, it's usually in asrc/webview
folder) - Update your build pipeline so that these two files get copied into your build directory (in our samples the build directory is named
out
) ββ here's an example of that configuration using esbuild - Now in the file where you've configured your webview class you'll want to make sure that local resources from your build directory are allowed in the webview ββ again here's an example
- In the same webview class file, create a webview URI that points to
out/codicon.css
(or whatever the build dir name is) ββ example - In the same webview class file, create a
<link>
tag in the initial webview HTML that points to the codicon URIΒ ββ example - With that done, the Codicon icons should now be accessible within your webview and the original icon button code snippets should work!
I hope that all makes sense (tried my best to be succinct and clear), but if you have any questions or run into issues let me know and I'm happy to clarify!
Thanks for those steps!
I did get things working in a pretty acceptable way, but I hit some other speed bumps that might be good to document:
- I use the
@vscode/codicons
npm package. From webview code, especially in a monorepo, it was a bit tricky to figure out the path where this is actually located on disk. - It seems like I needed to set up CSP? Though it took a bit to get that not to interfere with my other resources.
- Things still didn't work because I'm writing components using shadow DOM and the stylesheet defines selectors which need to run in my element's scope.
- I eventually settled on using native CSS modules, because I could just import the CSS and let Web Dev Server handle the node resolution, and then easily add the stylesheet to my shadow root's
adoptedStyleSheets
- This still didn't work because in Chrome (as of VS Code's latest version)
@font-face
doesn't work in shadow roots, so you also need to load the stylesheet in the main document to define the font-face.
In the end my code looked like this:
// The Chromium version in VS Code does not support the `with` keyword yet
import codiconStyles from '@vscode/codicons/dist/codicon.css' assert {type: 'css'};
// @font-face doesn't work in shadow roots! So we have to inject the styles into
// the main document.
document.adoptedStyleSheets.push(codiconStyles);
@customElement('x-foo')
export class XFoo extends LitElement {
static styles = [
codiconStyles,
css`...`
];
And I needed to mark @vscode/codicons
as external in an esbuild config, then let WDS handle the specifier resolution (which means I'm using a local web server to serve the webview UI).