Views
Views are an important part of a VSCode extension. There are two types of views in VSCode: Tree View and Webview. Please read the official UX guidelines for a basic understanding.
Define in Manifest Non-Proprietary
As described in the official documentation, first, you need view containers to be defined in the contributes.viewsContainers.[viewContainerType]
section in the package.json
. Then you can define your views in the contributes.views.[viewContainerId]
section.
{
"contributes": {
"viewsContainers": {
"activitybar": [
{
"id": "package-explorer",
"title": "Package Explorer",
"icon": "resources/package-explorer.svg"
}
]
},
"views": {
"package-explorer": [
{
"id": "package-dependencies",
"name": "Dependencies"
},
{
"id": "package-outline",
"name": "Outline"
}
]
}
}
}
Register Tree View
Tree views are used to display hierarchical data. You can define a tree view by using the useTreeView function.
Here is an example of a tree view:
import type { TreeViewNode } from 'reactive-vscode'
import { computed, createSingletonComposable, useTreeView } from 'reactive-vscode'
import { TreeItemCollapsibleState } from 'vscode'
export const useDemoTreeView = createSingletonComposable(() => {
function getRootNode(index: number) {
return {
children: [
getChildNode(index * 10 + 1),
getChildNode(index * 10 + 2),
],
treeItem: {
label: `Root ${index}`,
collapsibleState: TreeItemCollapsibleState.Expanded,
},
}
}
function getChildNode(index: number) {
return {
treeItem: {
label: `Child ${index}`,
collapsibleState: TreeItemCollapsibleState.None,
},
}
}
const treeData = computed(() => {
const roots: TreeViewNode[] = []
for (let i = 1; i < 5; i++)
roots.push(getRootNode(i))
return roots
})
const view = useTreeView(
'reactive-tree-view',
treeData,
{
title: () => `Tree with ${treeData.value.length} roots`,
},
)
// return anything you want to expose
return view
})
Then you can call the useDemoTreeView
function every where to register the tree view and get the returned value:
import { defineExtension } from 'reactive-vscode'
import { useDemoTreeView } from './treeView'
export = defineExtension(() => {
const demoTreeView = useDemoTreeView()
// ...
})
The children
property in nodes is used to define the children of the node. The treeItem
property is required and is used to define the tree item of the node. It should be a TreeItem object, or a promise that resolves to a TreeItem object.
If you want to trigger an update based on some reactive values that aren't tracked in treeData
, you can pass them to the watchSource
option.
About createSingletonComposable
createSingletonComposable is a helper function to create a singleton composable. It will only create the composable once and return the same instance every time it is called.WARNING
For the above example, useDemoTreeView
should not be called at the top-level in the module, because the extension context is not available at that time. Instead, you should always call it in the setup
function.
Register Webview
Webviews are used to display web content in the editor. You can define a webview by using the useWebviewView function.
Here is an example of a webview:
import { computed, createSingletonComposable, ref, useWebviewView } from 'reactive-vscode'
export const useDemoWebviewView = createSingletonComposable(() => {
const message = ref('')
const html = computed(() => `
<script>
vscode = acquireVsCodeApi()
function updateMessage() {
vscode.postMessage({
type: 'updateMessage',
message: document.querySelector('input').value,
})
}
</script>
<p>${message.value}</p>
<div style="display:flex; flex-wrap:wrap;">
<input type="text" placeholder="Input Message" />
<button onclick="updateMessage()">Update Message</button>
</div>
`)
const { postMessage } = useWebviewView(
'reactive-webview-view',
html,
{
webviewOptions: {
enableScripts: true,
enableCommandUris: true,
},
onDidReceiveMessage(ev) {
if (ev.type === 'updateMessage')
message.value = ev.message
},
},
)
return { message, postMessage }
})
The time to call useDemoWebviewView
is the same as the tree view in the previous section.
There is also useWebviewPanel composable to create a webview panel. The usage is similar to useWebviewView.