npm package: @slotkitjs/react
Description: React bindings for SlotKit plugin system
Author: liusnew
Latest version: 0.3.0

# @slotkitjs/react

[English](#english) | [中文](#中文)

---

## English

### React Bindings for SlotKit

`@slotkitjs/react` provides React components and hooks for the SlotKit plugin system, making it easy to integrate plugins into React applications.

### Features

- **React Components**: `<Slot>` component for rendering plugins
- **React Hooks**: Custom hooks for plugin management
- **Error Boundaries**: Built-in error isolation for plugins
- **TypeScript Support**: Full type definitions
- **Reactive Updates**: Automatic updates when plugins change

### Installation

```bash
npm install @slotkitjs/react @slotkitjs/core
# or
yarn add @slotkitjs/react @slotkitjs/core
# or
pnpm add @slotkitjs/react @slotkitjs/core
```

**Note**: `@slotkitjs/core` is a peer dependency and must be installed separately.

### Quick Start

```tsx
import React from 'react'
import { Slot } from '@slotkitjs/react'
import { pluginLoader, pluginRegistry } from '@slotkitjs/core'

// Load and register plugins
const loadPlugins = async () => {
  const plugins = await pluginLoader.loadAllPlugins()
  plugins.forEach(plugin => pluginRegistry.register(plugin))
}

function App() {
  React.useEffect(() => {
    loadPlugins()
  }, [])

  return (
    <div>
      <header>
        <Slot name="header" />
      </header>
      <main>
        <Slot name="content" />
      </main>
      <aside>
        <Slot name="sidebar" />
      </aside>
    </div>
  )
}
```

### Components

#### `<Slot>`

Renders plugins for a specific slot position.

**Props:**

- `name: string` - The slot name (required)
- `children?: React.ReactNode` - Fallback content when no plugins are available
- `...props` - Additional props passed to plugin components

**Example:**

```tsx
<Slot name="content">
  <p>No plugins available</p>
</Slot>
```

#### `<PluginErrorBoundary>`

Isolates plugin errors to prevent them from crashing the entire application.

**Props:**

- `pluginId: string` - The plugin ID (required)
- `children: React.ReactNode` - The plugin component to render

**Example:**

```tsx
<PluginErrorBoundary pluginId="my-plugin">
  <PluginComponent />
</PluginErrorBoundary>
```

### Hooks

#### `usePlugin(pluginId: string)`

Get a plugin by ID with reactive updates.

```tsx
import { usePlugin } from '@slotkitjs/react'

function MyComponent() {
  const plugin = usePlugin('my-plugin')
  
  if (!plugin) {
    return <div>Plugin not found</div>
  }
  
  return <div>Plugin: {plugin.name}</div>
}
```

#### `usePluginState(pluginId: string)`

Get the current state of a plugin.

```tsx
import { usePluginState } from '@slotkitjs/react'
import { PluginState } from '@slotkitjs/core'

function PluginStatus({ pluginId }) {
  const state = usePluginState(pluginId)
  
  return (
    <div>
      {state === PluginState.LOADING && <span>Loading...</span>}
      {state === PluginState.LOADED && <span>Loaded</span>}
      {state === PluginState.ERROR && <span>Error</span>}
    </div>
  )
}
```

#### `usePluginsForSlot(slotName: string)`

Get all plugins for a specific slot.

```tsx
import { usePluginsForSlot } from '@slotkitjs/react'

function SlotInfo({ slotName }) {
  const plugins = usePluginsForSlot(slotName)
  
  return (
    <div>
      <h3>Plugins in {slotName}:</h3>
      {plugins.map(plugin => (
        <div key={plugin.id}>{plugin.name}</div>
      ))}
    </div>
  )
}
```

#### `useAllPlugins()`

Get all registered plugins.

```tsx
import { useAllPlugins } from '@slotkitjs/react'

function PluginList() {
  const plugins = useAllPlugins()
  
  return (
    <ul>
      {plugins.map(plugin => (
        <li key={plugin.id}>{plugin.name}</li>
      ))}
    </ul>
  )
}
```

### Complete Example

```tsx
import React, { useEffect } from 'react'
import { Slot, usePlugin } from '@slotkitjs/react'
import { pluginLoader, pluginRegistry } from '@slotkitjs/core'

function App() {
  useEffect(() => {
    const loadPlugins = async () => {
      const plugins = await pluginLoader.loadAllPlugins()
      plugins.forEach(plugin => {
        pluginRegistry.register(plugin)
      })
    }
    loadPlugins()
  }, [])

  return (
    <div className="app">
      <header>
        <h1>My App</h1>
        <Slot name="header" />
      </header>
      
      <main>
        <aside>
          <Slot name="sidebar" />
        </aside>
        
        <section>
          <Slot name="content">
            <p>Default content</p>
          </Slot>
        </section>
      </main>
      
      <footer>
        <Slot name="footer" />
      </footer>
    </div>
  )
}

export default App
```

### Development

```bash
# Clone the repository
git clone <repository-url>
cd slotkitjs-react

# Install dependencies
pnpm install

# Build
pnpm build

# Development mode (watch)
pnpm dev
```

### License

MIT

---

## 中文

### SlotKit 的 React 绑定

`@slotkitjs/react` 为 SlotKit 插件系统提供 React 组件和 Hooks，使插件易于集成到 React 应用中。

### 特性

- **React 组件**：`<Slot>` 组件用于渲染插件
- **React Hooks**：用于插件管理的自定义 Hooks
- **错误边界**：内置的插件错误隔离
- **TypeScript 支持**：完整的类型定义
- **响应式更新**：插件变化时自动更新

### 安装

```bash
npm install @slotkitjs/react @slotkitjs/core
# 或
yarn add @slotkitjs/react @slotkitjs/core
# 或
pnpm add @slotkitjs/react @slotkitjs/core
```

**注意**：`@slotkitjs/core` 是 peer dependency，必须单独安装。

### 快速开始

```tsx
import React from 'react'
import { Slot } from '@slotkitjs/react'
import { pluginLoader, pluginRegistry } from '@slotkitjs/core'

// 加载并注册插件
const loadPlugins = async () => {
  const plugins = await pluginLoader.loadAllPlugins()
  plugins.forEach(plugin => pluginRegistry.register(plugin))
}

function App() {
  React.useEffect(() => {
    loadPlugins()
  }, [])

  return (
    <div>
      <header>
        <Slot name="header" />
      </header>
      <main>
        <Slot name="content" />
      </main>
      <aside>
        <Slot name="sidebar" />
      </aside>
    </div>
  )
}
```

### 组件

#### `<Slot>`

在特定插槽位置渲染插件。

**Props:**

- `name: string` - 插槽名称（必需）
- `children?: React.ReactNode` - 没有可用插件时的后备内容
- `...props` - 传递给插件组件的额外属性

**示例:**

```tsx
<Slot name="content">
  <p>没有可用插件</p>
</Slot>
```

#### `<PluginErrorBoundary>`

隔离插件错误，防止它们导致整个应用崩溃。

**Props:**

- `pluginId: string` - 插件 ID（必需）
- `children: React.ReactNode` - 要渲染的插件组件

**示例:**

```tsx
<PluginErrorBoundary pluginId="my-plugin">
  <PluginComponent />
</PluginErrorBoundary>
```

### Hooks

#### `usePlugin(pluginId: string)`

通过 ID 获取插件，支持响应式更新。

```tsx
import { usePlugin } from '@slotkitjs/react'

function MyComponent() {
  const plugin = usePlugin('my-plugin')
  
  if (!plugin) {
    return <div>插件未找到</div>
  }
  
  return <div>插件: {plugin.name}</div>
}
```

#### `usePluginState(pluginId: string)`

获取插件的当前状态。

```tsx
import { usePluginState } from '@slotkitjs/react'
import { PluginState } from '@slotkitjs/core'

function PluginStatus({ pluginId }) {
  const state = usePluginState(pluginId)
  
  return (
    <div>
      {state === PluginState.LOADING && <span>加载中...</span>}
      {state === PluginState.LOADED && <span>已加载</span>}
      {state === PluginState.ERROR && <span>错误</span>}
    </div>
  )
}
```

#### `usePluginsForSlot(slotName: string)`

获取特定插槽的所有插件。

```tsx
import { usePluginsForSlot } from '@slotkitjs/react'

function SlotInfo({ slotName }) {
  const plugins = usePluginsForSlot(slotName)
  
  return (
    <div>
      <h3>{slotName} 中的插件:</h3>
      {plugins.map(plugin => (
        <div key={plugin.id}>{plugin.name}</div>
      ))}
    </div>
  )
}
```

#### `useAllPlugins()`

获取所有已注册的插件。

```tsx
import { useAllPlugins } from '@slotkitjs/react'

function PluginList() {
  const plugins = useAllPlugins()
  
  return (
    <ul>
      {plugins.map(plugin => (
        <li key={plugin.id}>{plugin.name}</li>
      ))}
    </ul>
  )
}
```

### 完整示例

```tsx
import React, { useEffect } from 'react'
import { Slot, usePlugin } from '@slotkitjs/react'
import { pluginLoader, pluginRegistry } from '@slotkitjs/core'

function App() {
  useEffect(() => {
    const loadPlugins = async () => {
      const plugins = await pluginLoader.loadAllPlugins()
      plugins.forEach(plugin => {
        pluginRegistry.register(plugin)
      })
    }
    loadPlugins()
  }, [])

  return (
    <div className="app">
      <header>
        <h1>我的应用</h1>
        <Slot name="header" />
      </header>
      
      <main>
        <aside>
          <Slot name="sidebar" />
        </aside>
        
        <section>
          <Slot name="content">
            <p>默认内容</p>
          </Slot>
        </section>
      </main>
      
      <footer>
        <Slot name="footer" />
      </footer>
    </div>
  )
}

export default App
```

### 开发

```bash
# 克隆仓库
git clone <repository-url>
cd slotkitjs-react

# 安装依赖
pnpm install

# 构建
pnpm build

# 开发模式（监听）
pnpm dev
```

### 许可证

MIT