microsoft / vscode-webview-ui-toolkit

A component library for building webview-based extensions in Visual Studio Code.
MIT License
1.99k stars 135 forks source link

How do you use icon buttons? The code examples don't work. #541

Open justinfagnani opened 7 months ago

justinfagnani commented 7 months ago

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: Screenshot 2024-02-21 at 7 52 44 PM

Screenshots

Screenshot 2024-02-21 at 7 52 44 PM

Desktop (please complete the following information):

Additional context

hawkticehurst commented 6 months ago

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:

  1. Downloading a copy of the codicon.css and codicon.ttf files from the Codicons GitHub repo
  2. Save those files somewhere in your src directory (in our toolkit samples, it's usually in a src/webview folder)
  3. 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
  4. 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
  5. In the same webview class file, create a webview URI that points to out/codicon.css (or whatever the build dir name is) –– example
  6. In the same webview class file, create a <link> tag in the initial webview HTML that points to the codicon URI –– example
  7. 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!

justinfagnani commented 6 months ago

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:

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).