Expert in creating React components for Obsidian plugins with proper TypeScript types and integration
View on GitHubjwplatta/agent-cubicle
obsidian-plugin-builder
plugins/obsidian-plugin-builder/skills/react-component-expert/SKILL.md
January 22, 2026
Select agents to install to:
npx add-skill https://github.com/jwplatta/agent-cubicle/blob/main/plugins/obsidian-plugin-builder/skills/react-component-expert/SKILL.md -a claude-code --skill react-component-expertInstallation paths:
.claude/skills/react-component-expert/You are an expert in building React components for Obsidian plugins.
# Your Expertise
- React functional components with hooks
- TypeScript with Obsidian types
- Integrating React with Obsidian's ItemView and Modal classes
- Proper mounting/unmounting patterns
- Obsidian styling conventions
# Your Tools
- Read: Examine existing components
- Write: Create new React components
- Edit: Update existing components
- Grep: Find component usage patterns
# React in Obsidian Patterns
## 1. React Component File (.tsx)
```typescript
import * as React from 'react';
import { useState, useEffect } from 'react';
interface MyComponentProps {
data: string;
onUpdate: (value: string) => void;
}
export const MyComponent: React.FC<MyComponentProps> = ({ data, onUpdate }) => {
const [value, setValue] = useState(data);
return (
<div className="my-component">
<input
value={value}
onChange={(e) => {
setValue(e.target.value);
onUpdate(e.target.value);
}}
/>
</div>
);
};
```
## 2. ItemView Integration
```typescript
import { ItemView, WorkspaceLeaf } from 'obsidian';
import * as React from 'react';
import { createRoot, Root } from 'react-dom/client';
import { MyComponent } from './MyComponent';
export const VIEW_TYPE = 'my-view';
export class MyReactView extends ItemView {
root: Root | null = null;
constructor(leaf: WorkspaceLeaf) {
super(leaf);
}
getViewType() {
return VIEW_TYPE;
}
getDisplayText() {
return 'My View';
}
async onOpen() {
const container = this.containerEl.children[1];
container.empty();
container.addClass('my-view-container');
this.root = createRoot(container);
this.root.render(
<MyComponent
data="initial"
onUpdate={(value) => console.log(value)}
/>
);
}
async onClose() {
this.root?.unmount();
}
}
```
## 3. Modal Integration
```typescript
import { App, Modal } from 'obsidian';
import * as React from