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
vsceasy components addWrites 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 onClick={save}>Save</Button><Button variant="secondary">Cancel</Button><Button disabled>Saving…</Button>| Prop | Type | Notes |
|---|---|---|
variant | 'primary' | 'secondary' | Default primary. |
| …rest | ButtonHTMLAttributes | onClick, disabled, type, … |
Input
A theme-aware text input. Forwards its ref and all native <input> props.
<Input value={name} onChange={(e) => setName(e.target.value)} placeholder="Jane Doe" />| Prop | Type | Notes |
|---|---|---|
| …rest | InputHTMLAttributes | value, onChange, type, placeholder, … |
Field
A labeled wrapper for a control, with optional hint or error text below it.
<Field label="Email" htmlFor="email" error={invalid ? 'Enter a valid email.' : undefined}> <Input id="email" value={email} onChange={(e) => setEmail(e.target.value)} /></Field>| Prop | Type | Notes |
|---|---|---|
label | string | Required. |
htmlFor | string | Ties the label to the control. |
hint | string | Shown when there’s no error. |
error | string | Replaces the hint, styled as an error. |
Card
A bordered surface for grouping content, with an optional title and an actions row in the header.
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>| Prop | Type | Notes |
|---|---|---|
title | string | Optional header title. |
actions | ReactNode | Optional header actions (right-aligned). |
children | ReactNode | Card body. |
List
A selectable list. Rows highlight on hover and call onSelect when clicked.
Renders an empty state when there are no items.
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."/>| Prop | Type | Notes |
|---|---|---|
items | T[] | The rows. |
getKey | (item, i) => string | number | Stable React key. |
renderItem | (item, i) => ReactNode | Row content. |
onSelect | (item, i) => void | Optional; makes rows clickable. |
empty | ReactNode | Shown when items is empty. |
All together
Composed into a small CRUD-style screen — the shape a generated panel takes.
New user
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.
vsceasy panel add --name signup --template formvsceasy panel add --name items --template listvsceasy panel add --name stats --template dashboard| Template | UI | RPC added |
|---|---|---|
form | inputs + Save | save(input) |
list | list + Refresh | list() |
dashboard | stat cards | stats() |
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.