> ## Documentation Index
> Fetch the complete documentation index at: https://artifactuse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ArtifactusePanel

> Side panel for artifact preview and code view

The side panel component that displays artifact previews, code, and interactive editors. Supports preview mode, code mode, split view, fullscreen, and resizing.

## Import

<Tabs>
  <Tab title="Vue 3">
    ```js theme={null}
    import { ArtifactusePanel } from 'artifactuse/vue'
    ```
  </Tab>

  <Tab title="Vue 2">
    ```js theme={null}
    import { ArtifactusePanel } from 'artifactuse/vue2'
    ```
  </Tab>

  <Tab title="React">
    ```js theme={null}
    import { ArtifactusePanel } from 'artifactuse/react'
    ```
  </Tab>

  <Tab title="Svelte">
    ```js theme={null}
    import { ArtifactusePanel } from 'artifactuse/svelte'
    ```
  </Tab>
</Tabs>

## Usage

<Tabs>
  <Tab title="Vue">
    ```vue theme={null}
    <template>
      <div class="app-container">
        <div class="chat">
          <!-- Your chat messages -->
        </div>
        
        <ArtifactusePanel 
          @ai-request="handleAIRequest"
          @save="handleSave"
          @export="handleExport"
          @form-submit="handleFormSubmit"
        />
      </div>
    </template>
    ```
  </Tab>

  <Tab title="React">
    ```jsx theme={null}
    <div className="app-container">
      <div className="chat">
        {/* Your chat messages */}
      </div>
      
      <ArtifactusePanel 
        onAIRequest={handleAIRequest}
        onSave={handleSave}
        onExport={handleExport}
        onFormSubmit={handleFormSubmit}
      />
    </div>
    ```
  </Tab>

  <Tab title="Svelte">
    ```svelte theme={null}
    <div class="app-container">
      <div class="chat">
        <!-- Your chat messages -->
      </div>
      
      <ArtifactusePanel 
        on:aiRequest={handleAIRequest}
        on:save={handleSave}
        on:export={handleExport}
        on:formSubmit={handleFormSubmit}
      />
    </div>
    ```
  </Tab>
</Tabs>

## Layout

The panel should be a sibling to your chat container in a flex layout:

```css theme={null}
.app-container {
  display: flex;
  height: 100%;
  overflow: hidden;
}

.chat {
  flex: 1;
  min-width: 0;
  overflow-y: auto;
}
```

The panel automatically positions itself on the right side and is resizable.

## Props

| Prop              | Type      | Default | Description                                                                            |
| ----------------- | --------- | ------- | -------------------------------------------------------------------------------------- |
| `panelWidth`      | `Number`  | `65`    | Initial panel width as a percentage (25–75). Users can still drag to resize.           |
| `splitPosition`   | `Number`  | `50`    | Initial split view position as a percentage (20–80). Users can still drag to resize.   |
| `externalPreview` | `Boolean` | `false` | Show "Open in new tab" button in panel header. Only visible when a preview URL exists. |

<Tabs>
  <Tab title="Vue">
    ```vue theme={null}
    <ArtifactusePanel
      :panel-width="50"
      :split-position="60"
      @ai-request="handleAIRequest"
    />
    ```
  </Tab>

  <Tab title="React">
    ```jsx theme={null}
    <ArtifactusePanel
      panelWidth={50}
      splitPosition={60}
      onAIRequest={handleAIRequest}
    />
    ```
  </Tab>

  <Tab title="Svelte">
    ```svelte theme={null}
    <ArtifactusePanel
      initialPanelWidth={50}
      initialSplitPosition={60}
      on:aiRequest={handleAIRequest}
    />
    ```
  </Tab>
</Tabs>

<Note>
  These values set the **initial** position only. Users can still drag the panel edge or split divider to resize. Values outside the valid range are clamped automatically. Props override the global config values (`panelWidth` and `splitPosition` in `provideArtifactuse`).
</Note>

## Events

| Event         | Payload                          | Description                                                |
| ------------- | -------------------------------- | ---------------------------------------------------------- |
| `ai-request`  | `{ prompt, context, requestId }` | AI assistance requested from panel (e.g., "Fix this code") |
| `save`        | `{ artifactId, data }`           | Save requested for current artifact                        |
| `export`      | `{ artifactId, blob, filename }` | Export completed                                           |
| `form-submit` | `{ formId, action, values }`     | Panel form submitted                                       |
| `edit:save`   | `{ artifactId, artifact, code }` | Code saved from edit tab                                   |

## Handling AI Requests

When users request AI assistance from the panel (e.g., clicking "Fix", "Improve", or using the AI input), handle it like this:

<Tabs>
  <Tab title="Vue">
    ```vue theme={null}
    <script setup>
    async function handleAIRequest({ prompt, context, requestId }) {
      // context contains the current artifact code/content
      const response = await openai.chat.completions.create({
        model: 'gpt-4',
        messages: [
          { role: 'system', content: 'You are a helpful coding assistant.' },
          { role: 'user', content: `${prompt}\n\nContext:\n${context}` }
        ]
      })
      
      // The response will be processed and update the artifact
    }
    </script>

    <template>
      <ArtifactusePanel @ai-request="handleAIRequest" />
    </template>
    ```
  </Tab>

  <Tab title="React">
    ```jsx theme={null}
    const handleAIRequest = async ({ prompt, context, requestId }) => {
      const response = await openai.chat.completions.create({
        model: 'gpt-4',
        messages: [
          { role: 'system', content: 'You are a helpful coding assistant.' },
          { role: 'user', content: `${prompt}\n\nContext:\n${context}` }
        ]
      })
    }

    <ArtifactusePanel onAIRequest={handleAIRequest} />
    ```
  </Tab>
</Tabs>

## View Modes

The panel supports four view modes:

| Mode      | Description                                                    |
| --------- | -------------------------------------------------------------- |
| `preview` | Live preview of the artifact (default for HTML, React, Vue)    |
| `code`    | Syntax-highlighted code view (read-only, uses Prism.js)        |
| `split`   | Side-by-side preview and code                                  |
| `edit`    | Editable code editor (requires CodeMirror via `editor` config) |

Control view mode programmatically:

```js theme={null}
const { setViewMode } = useArtifactuse()

setViewMode('preview')
setViewMode('code')
setViewMode('split')
setViewMode('edit')
```

### Tab Filtering

Control which tabs are visible when opening artifacts programmatically:

```js theme={null}
const { openFile } = useArtifactuse()

// Only show code and edit tabs
openFile('app.js', code, { tabs: ['code', 'edit'] })

// Only show preview and code (no split)
openFile('page.html', code, { tabs: ['preview', 'code'] })

// Update an existing artifact (no duplicate tab)
updateFile(artifact, newCode)
```

<Note>
  The `edit` tab only appears when CodeMirror modules are provided via the `editor` config option. See [Code Artifacts](/docs/artifacts/code#edit-tab) for setup instructions.
</Note>

## Fullscreen

Toggle fullscreen mode:

```js theme={null}
const { toggleFullscreen } = useArtifactuse()

toggleFullscreen()
```

## Panel Controls

The panel header includes:

* **View mode tabs** - Switch between preview/code/split/edit
* **Save button** - Appears when the edit tab is active (emits `edit:save` event)
* **Open in new tab button** - Opens the artifact preview URL in a new browser tab (requires `externalPreview` enabled and a preview URL)
* **Fullscreen button** - Expand to full screen
* **Close button** - Close the panel

The panel footer includes:

* **Branding** - "Powered by Artifactuse" (can be hidden with license)
* **Navigation** - Previous/next artifact buttons
* **Actions** - Copy, download, export buttons

## Panel Methods

Control the panel programmatically:

```js theme={null}
const { openPanel, closePanel, togglePanel } = useArtifactuse()

openPanel()       // Open panel in empty "viewer" state
closePanel()      // Close panel
togglePanel()     // Toggle panel open/closed
```

### openPanel()

Opens the panel in an empty viewer state with no artifact selected. The panel displays an "Artifact Viewer" header and a prompt to open an artifact. When an artifact is subsequently opened (via `openArtifact()`, `openFile()`, or `openCode()`), the empty state is automatically cleared.

This is useful for showing the panel before any artifact content is ready — for example, while waiting for an AI response.

### Panel Events

Listen for panel lifecycle events:

```js theme={null}
const { on } = useArtifactuse()

on('panel:opened', () => {
  console.log('Panel opened')
})

on('panel:closed', () => {
  console.log('Panel closed')
})

on('panel:toggled', ({ isOpen }) => {
  console.log('Panel toggled:', isOpen)
})
```

| Event           | Payload      | Description                                                          |
| --------------- | ------------ | -------------------------------------------------------------------- |
| `panel:opened`  | —            | Emitted when `openPanel()` is called                                 |
| `panel:closed`  | —            | Emitted when `closePanel()` is called or the close button is clicked |
| `panel:toggled` | `{ isOpen }` | Emitted when `togglePanel()` is called                               |

## Artifact Navigation

When multiple artifacts exist, users can navigate between them using the footer controls or programmatically:

```js theme={null}
const { openArtifact, state } = useArtifactuse()

// Open specific artifact
openArtifact(artifact)

// Access all artifacts
const allArtifacts = state.artifacts
```

## Multi-Tab

Enable multi-tab mode to open multiple artifacts as tabs, similar to a code editor:

```js theme={null}
provideArtifactuse({
  multiTab: true,
})
```

When enabled:

* Clicking an artifact card or calling `openFile()` / `openCode()` opens it in a new tab (or focuses it if already open)
* Each tab preserves its own view mode (preview, code, split, edit)
* Closing the active tab switches to the adjacent tab
* The prev/next navigation is replaced by the tab bar
* Artifacts from streamed messages do **not** auto-open as tabs

### Tab Methods

```js theme={null}
const { closeTab, closeOtherTabs, closeAllTabs } = useArtifactuse()

// Close a specific tab
closeTab(artifactId)

// Close all tabs except one
closeOtherTabs(artifactId)

// Close all open tabs
closeAllTabs()
```

### State

When multi-tab is active, two additional state fields are available:

| Field                | Type       | Description                             |
| -------------------- | ---------- | --------------------------------------- |
| `state.openTabs`     | `string[]` | Ordered array of open artifact IDs      |
| `state.tabViewModes` | `object`   | Map of artifact ID to view mode per tab |

<Note>
  Multi-tab is opt-in and disabled by default. When `multiTab: false` (default), the panel behaves exactly as before with single-artifact navigation.
</Note>

## Mobile Behavior

On mobile devices (\< 768px), the panel:

* Opens as a full-screen overlay
* Hides the resize handle
* Shows a backdrop behind the panel
* Uses vertical split in split mode

## Vue 2 Portal

For Vue 2, the panel uses `portal-vue` for fullscreen/mobile rendering. Add the portal target:

```vue theme={null}
<template>
  <div class="app-container">
    <div class="chat">...</div>
    <ArtifactusePanel />
    
    <!-- Required for Vue 2 -->
    <portal-target name="artifactuse" />
  </div>
</template>
```
