Sandbox

A collapsible container for displaying AI-generated code and output in chat interfaces.

The Sandbox component provides a structured way to display AI-generated code alongside its execution output in chat conversations. It features a collapsible container with status indicators and tabbed navigation between code and output views. It's designed to be used with CodeBlock for displaying code and StackTrace for displaying errors.

Install using CLI

AI Elements Vue
shadcn-vue CLI
npx ai-elements-vue@latest add sandbox

Install Manually

Copy and paste the following files into the same folder.

Sandbox.vue
SandboxHeader.vue
SandboxContent.vue
SandboxTabs.vue
SandboxTabsBar.vue
SandboxTabsList.vue
SandboxTabsTrigger.vue
SandboxTabContent.vue
index.ts
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { Collapsible } from '@repo/shadcn-vue/components/ui/collapsible'
import { cn } from '@repo/shadcn-vue/lib/utils'

type CollapsibleProps = InstanceType<typeof Collapsible>['$props']

interface Props extends /* @vue-ignore */ CollapsibleProps {
  class?: HTMLAttributes['class']
}

const props = defineProps<Props>()
</script>

<template>
  <Collapsible
    :class="cn(
      'not-prose group mb-4 w-full overflow-hidden rounded-md border',
      props.class,
    )"
    :default-open="true"
    v-bind="$attrs"
  >
    <slot />
  </Collapsible>
</template>

Features

  • Collapsible container with smooth animations
  • Status badges showing execution state (Pending, Running, Completed, Error)
  • Tabs for Code and Output views
  • Syntax-highlighted code display
  • Copy button for easy code sharing
  • Works with AI SDK tool state patterns

Usage with AI SDK

The Sandbox component integrates with the AI SDK's tool state to show code generation progress:

<script setup lang="ts">
import type { ToolUIPart } from 'ai'
import { CodeBlock } from '@repo/elements/code-block'
import {
  Sandbox,
  SandboxContent,
  SandboxHeader,
  SandboxTabContent,
  SandboxTabs,
  SandboxTabsBar,
  SandboxTabsList,
  SandboxTabsTrigger,
} from '@repo/elements/sandbox'

const props = defineProps<{
  toolPart: ToolUIPart
}>()

const code = props.toolPart.input?.code ?? ''
const output = props.toolPart.output?.logs ?? ''
</script>

<template>
  <Sandbox>
    <SandboxHeader
      :state="props.toolPart.state"
      :title="props.toolPart.input?.filename ?? 'code.tsx'"
    />
    <SandboxContent>
      <SandboxTabs default-value="code">
        <SandboxTabsBar>
          <SandboxTabsList>
            <SandboxTabsTrigger value="code">
              Code
            </SandboxTabsTrigger>
            <SandboxTabsTrigger value="output">
              Output
            </SandboxTabsTrigger>
          </SandboxTabsList>
        </SandboxTabsBar>
        <SandboxTabContent value="code">
          <CodeBlock :code="code" language="tsx" />
        </SandboxTabContent>
        <SandboxTabContent value="output">
          <CodeBlock :code="output" language="log" />
        </SandboxTabContent>
      </SandboxTabs>
    </SandboxContent>
  </Sandbox>
</template>

Props

<Sandbox />

...propsCollapsibleProps
Spread to the Collapsible component.

<SandboxHeader />

titlestring
The title displayed in the header (e.g., filename).
staterequiredToolUIPart["state"]
The current execution state, used to display the appropriate status badge.
classstring
Additional CSS classes for the header.

<SandboxContent />

...propsCollapsibleContentProps
Spread to the CollapsibleContent.

<SandboxTabs />

...propsTabsProps
Spread to the underlying Tabs component.

<SandboxTabsBar />

...propsHTMLAttributes
Spread to the container div.

<SandboxTabsList />

...propsTabsListProps
Spread to the underlying TabsList component.

<SandboxTabsTrigger />

...propsTabsTriggerProps
Spread to the underlying TabsTrigger component.

<SandboxTabContent />

...propsTabsContentProps
Spread to the underlying TabsContent component.