Skip to content

Webview components

Webviews start blank, but you don’t have to. vsceasy ships a themed component library and panel UI templates that use it.

Every preview below is the real component, synced verbatim from the generator templates and rendered with representative VS Code theme tokens. Toggle Dark/Light to see it adapt the way it does inside the editor.

The component library

Terminal window
vsceasy components add

Writes Button, Input, Field, Card, List (+ components.css) into src/webview/components/, all styled with var(--vscode-*) tokens so they match the user’s theme in light and dark mode.

import { Button, Input, Field, Card, List } from '../../components';
import '../../components/components.css';

Components

Button

A theme-aware button with primary (default) and secondary variants. Passes through all native <button> props.

Button — primary + secondary variants
clicked 0×
<Button onClick={save}>Save</Button>
<Button variant="secondary">Cancel</Button>
<Button disabled>Saving…</Button>
PropTypeNotes
variant'primary' | 'secondary'Default primary.
…restButtonHTMLAttributesonClick, disabled, type, …

Input

A theme-aware text input. Forwards its ref and all native <input> props.

Input — themed text field
<Input value={name} onChange={(e) => setName(e.target.value)} placeholder="Jane Doe" />
PropTypeNotes
…restInputHTMLAttributesvalue, onChange, type, placeholder, …

Field

A labeled wrapper for a control, with optional hint or error text below it.

Field — label + hint + error
Lowercase, no spaces.
Enter a valid email.
<Field label="Email" htmlFor="email" error={invalid ? 'Enter a valid email.' : undefined}>
<Input id="email" value={email} onChange={(e) => setEmail(e.target.value)} />
</Field>
PropTypeNotes
labelstringRequired.
htmlForstringTies the label to the control.
hintstringShown when there’s no error.
errorstringReplaces the hint, styled as an error.

Card

A bordered surface for grouping content, with an optional title and an actions row in the header.

Card — titled surface with actions

Settings

A bordered surface for grouping content, with an optional title and an actions row in the header.

<Card title="Settings" actions={<Button variant="secondary">Edit</Button>}>
…content…
</Card>
PropTypeNotes
titlestringOptional header title.
actionsReactNodeOptional header actions (right-aligned).
childrenReactNodeCard body.

List

A selectable list. Rows highlight on hover and call onSelect when clicked. Renders an empty state when there are no items.

List — selectable, hover-highlighted rows

Users

  • Ada Lovelace
  • Alan Turing · selected
  • Grace Hopper
<List
items={users}
getKey={(u) => u.id}
onSelect={(u) => setSelected(u.id)}
renderItem={(u) => u.name}
empty="No users yet."
/>
PropTypeNotes
itemsT[]The rows.
getKey(item, i) => string | numberStable React key.
renderItem(item, i) => ReactNodeRow content.
onSelect(item, i) => voidOptional; makes rows clickable.
emptyReactNodeShown when items is empty.

All together

Composed into a small CRUD-style screen — the shape a generated panel takes.

Live preview · the whole library together

New user

Shown in the list.

Users

  • Ada Lovelace
  • Alan Turing · selected
  • Grace Hopper

Panel templates

panel add --template starts a panel from a working screen built on these components, with the matching RPC method already wired.

Terminal window
vsceasy panel add --name signup --template form
vsceasy panel add --name items --template list
vsceasy panel add --name stats --template dashboard
TemplateUIRPC added
forminputs + Savesave(input)
listlist + Refreshlist()
dashboardstat cardsstats()

Non-blank templates auto-generate the component library on first use and force the typed API on. Fill in the handler in the panel and you have a working screen.