The ItemView class extends View and provides a content area and action buttons. This is the base class for most custom views.
Properties
The main content element for this view. Use this to add your view’s content.
Inherited Properties
ItemView inherits all properties from View:
app: App
icon: IconName
navigation: boolean
leaf: WorkspaceLeaf
containerEl: HTMLElement
scope: Scope | null
Constructor
constructor(leaf: WorkspaceLeaf)
The workspace leaf this view will be attached to
Methods
addAction()
Adds an action button to the view’s header.
addAction(
icon: IconName,
title: string,
callback: (evt: MouseEvent) => any
): HTMLElement
The tooltip text for the action button
callback
(evt: MouseEvent) => any
required
Function to call when the action is clicked
The created action button element
Since: 1.1.0
Example
class MyCustomView extends ItemView {
async onOpen() {
const container = this.contentEl;
container.empty();
container.createEl('h4', { text: 'My View' });
// Add action buttons
this.addAction('refresh-cw', 'Refresh', () => {
this.refresh();
});
this.addAction('download', 'Export', () => {
this.exportData();
});
}
refresh() {
console.log('Refreshing view...');
}
exportData() {
console.log('Exporting data...');
}
}
Inherited Methods
ItemView inherits all methods from View:
onOpen(): Called when view is opened
onClose(): Called when view is closed
getViewType(): Returns the view type identifier
getDisplayText(): Returns the display text
getState(): Gets the view state
setState(): Sets the view state
getEphemeralState(): Gets ephemeral state
setEphemeralState(): Sets ephemeral state
getIcon(): Gets the view icon
onResize(): Called when view is resized
onPaneMenu(): Populates the pane menu
Creating a Custom ItemView
Here’s a complete example of creating a custom view with ItemView:
import { ItemView, WorkspaceLeaf } from 'obsidian';
const VIEW_TYPE_EXAMPLE = 'example-view';
class ExampleView extends ItemView {
constructor(leaf: WorkspaceLeaf) {
super(leaf);
}
getViewType() {
return VIEW_TYPE_EXAMPLE;
}
getDisplayText() {
return 'Example view';
}
async onOpen() {
const container = this.contentEl;
container.empty();
container.createEl('h4', { text: 'Example View' });
const listEl = container.createEl('ul');
listEl.createEl('li', { text: 'Item 1' });
listEl.createEl('li', { text: 'Item 2' });
listEl.createEl('li', { text: 'Item 3' });
// Add action buttons
this.addAction('plus', 'Add item', () => {
listEl.createEl('li', { text: `Item ${listEl.children.length + 1}` });
});
this.addAction('trash', 'Clear items', () => {
listEl.empty();
});
}
async onClose() {
// Cleanup
}
}
Registering and Opening the View
import { Plugin } from 'obsidian';
export default class ExamplePlugin extends Plugin {
async onload() {
// Register the view
this.registerView(
VIEW_TYPE_EXAMPLE,
(leaf) => new ExampleView(leaf)
);
// Add ribbon icon to open the view
this.addRibbonIcon('dice', 'Open example view', () => {
this.activateView();
});
// Add command to open the view
this.addCommand({
id: 'open-example-view',
name: 'Open example view',
callback: () => {
this.activateView();
}
});
}
async activateView() {
const { workspace } = this.app;
let leaf = workspace.getLeavesOfType(VIEW_TYPE_EXAMPLE)[0];
if (!leaf) {
leaf = workspace.getRightLeaf(false);
await leaf.setViewState({ type: VIEW_TYPE_EXAMPLE, active: true });
}
workspace.revealLeaf(leaf);
}
async onunload() {
// Detach all leaves of this type
this.app.workspace.detachLeavesOfType(VIEW_TYPE_EXAMPLE);
}
}
Best Practices
1. Always clean up in onClose()
class MyView extends ItemView {
private interval: number;
async onOpen() {
this.interval = window.setInterval(() => {
// Update view
}, 1000);
}
async onClose() {
if (this.interval) {
window.clearInterval(this.interval);
}
}
}
2. Use contentEl for your content
The contentEl is the designated content area. Don’t modify containerEl directly.
async onOpen() {
const container = this.contentEl;
container.empty();
// Add your content to container
}
3. Handle resize events
onResize() {
// Recalculate layout if needed
this.updateLayout();
}
4. Save and restore state
getState() {
return {
selectedTab: this.selectedTab,
scrollPosition: this.scrollPosition
};
}
async setState(state: any, result: ViewStateResult) {
this.selectedTab = state.selectedTab || 0;
this.scrollPosition = state.scrollPosition || 0;
await super.setState(state, result);
}
Common Use Cases
this.addCommand({
id: 'open-sidebar-view',
name: 'Open sidebar view',
callback: async () => {
const leaf = this.app.workspace.getRightLeaf(false);
await leaf.setViewState({
type: VIEW_TYPE,
active: true
});
this.app.workspace.revealLeaf(leaf);
}
});
Creating a main area view
this.addCommand({
id: 'open-main-view',
name: 'Open main view',
callback: async () => {
const leaf = this.app.workspace.getLeaf('tab');
await leaf.setViewState({
type: VIEW_TYPE,
active: true
});
}
});
See Also