Обзор
Компоненты
- Accordion
- Alert
- Alert Dialog
- Autocomplete
- Auth Surface
- Avatar
- Badge
- Browse Catalog Dialog
- Button
- Card
- Checkbox
- Checkbox Group
- Collapsible
- Combobox
- Command
- Connector Setup Dialog
- Cookie Banner
- Dialog
- Directory Card
- Directory Detail
- Directory Skeleton
- DrawerНовое
- Token Parts Input
- Empty
- Field
- Fieldset
- File Preview Modal
- File Preview Skeleton
- Form
- Frame
- Group
- Icon
- Input
- Input Group
- Kbd
- Label
- Legal Shell
- Menu
- Mermaid Diagram
- Mind Map Diagram
- Not Found Screen
- Onboarding Frame
- Popover
- PDF Thumbnail
- Personalization Landing
- Preview Card
- Pricing Page
- Progress
- Radio Group
- Ring Spinner
- Scroll Area
- Select
- Separator
- Settings Page
- Settings Skills
- Settings Connectors
- Settings Capabilities
- Settings Usage
- Settings Account
- Settings Billing
- Sheet
- Sidebar
- Skeleton
- Skill Create Dialog
- Slider
- Spinner
- Stat
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Tooltip
AI-компоненты
- Компоненты AI
- Chat Conversation
- Chat Message
- Chat Response
- Chat Suggestion
- Chat Prompt Input
- Slash Highlighted Textarea
- Chat Search Dialog
- Chat Skill Doc
- Chat Connector Detail
- Chat Attachments
- Chat File Card
- Chat Token Chip
- Chat Code Block
- Chat Image
- Chat Inline Citation
- Chat Sources
- Chat Web Search
- Chat Research
- Chat Source
- Chat Actions
- Chat Context
- Chat Loader
- Chat Compaction
- Chat Timeline
- Chat Snippet
- Chat Terminal
- Chat Stack Trace
- Chat Test Results
- Chat File Tree
- Chat Environment Variables
- Chat Audio Player
- Chat Transcription
- Chat Speech Input
- Chat Mic Selector
- Chat Voice Selector
- Chat Agent
- Chat Persona
- Chat Connection
- Chat Connector Suggestion
- Chat Queue
- Chat Checkpoint
- Chat Confirmation
- Chat Artifact
- Chat JSX Preview
- Chat Schema Display
- Chat Package Info
- Chat Commit
- Chat Plan
- Chat Open In Chat
- Chat Sandbox
- Chat Model Selector
- Chat Canvas
- Chat Node
- Chat Edge
Ресурсы
Chat Sandbox
Сворачиваемый блок для AI-генерируемого кода с tab-ами Code / Preview и iframe-выводом.
import {
ChatCodeBlock,
ChatCodeBlockActions,
ChatCodeBlockCopyButton,
ChatCodeBlockFilename,
ChatCodeBlockHeader,
} from "@/components/ui/chat-code-block";
import {
ChatSandbox,
ChatSandboxContent,
ChatSandboxFrame,
ChatSandboxHeader,
ChatSandboxTab,
ChatSandboxTabPanel,
ChatSandboxTabs,
ChatSandboxTabsBar,
ChatSandboxTabsList,
} from "@/components/ui/chat-sandbox";
import { ChatTerminal } from "@/components/ui/chat-terminal";
const code = `export default function App() {
return (
<main className="grid min-h-svh place-items-center bg-zinc-950 text-zinc-50">
<h1 className="text-3xl font-semibold">Привет из песочницы</h1>
</main>
);
}`;
const consoleLog = [
"\x1b[2m> \x1b[0mvite dev",
" \x1b[32m✓\x1b[0m Local: http://localhost:5173/",
" \x1b[32m✓\x1b[0m ready in 248ms",
"",
"\x1b[33m! \x1b[0mHMR connected",
].join("\n");
export default function Particle() {
return (
<div className="w-full max-w-3xl p-4">
<ChatSandbox defaultOpen>
<ChatSandboxHeader status="completed" title="Превью Hello World" />
<ChatSandboxContent>
<ChatSandboxTabs defaultValue="preview">
<ChatSandboxTabsBar>
<ChatSandboxTabsList>
<ChatSandboxTab value="preview">Превью</ChatSandboxTab>
<ChatSandboxTab value="code">Код</ChatSandboxTab>
<ChatSandboxTab value="console">Консоль</ChatSandboxTab>
</ChatSandboxTabsList>
</ChatSandboxTabsBar>
<ChatSandboxTabPanel value="preview">
<ChatSandboxFrame
className="min-h-70"
src="data:text/html;charset=utf-8,%3Cstyle%3Ebody%7Bmargin%3A0%3Bdisplay%3Agrid%3Bplace-items%3Acenter%3Bmin-height%3A100vh%3Bbackground%3A%2309090b%3Bcolor%3A%23fafafa%3Bfont-family%3Asystem-ui%7Dh1%7Bfont-size%3A2rem%3Bfont-weight%3A600%7D%3C%2Fstyle%3E%3Ch1%3E%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%B8%D0%B7%20%D0%BF%D0%B5%D1%81%D0%BE%D1%87%D0%BD%D0%B8%D1%86%D1%8B%3C%2Fh1%3E"
/>
</ChatSandboxTabPanel>
<ChatSandboxTabPanel value="code">
<div className="p-3">
<ChatCodeBlock code={code} language="tsx" showLineNumbers>
<ChatCodeBlockHeader>
<ChatCodeBlockFilename>App.tsx</ChatCodeBlockFilename>
<ChatCodeBlockActions>
<ChatCodeBlockCopyButton />
</ChatCodeBlockActions>
</ChatCodeBlockHeader>
</ChatCodeBlock>
</div>
</ChatSandboxTabPanel>
<ChatSandboxTabPanel value="console">
<div className="p-3">
<ChatTerminal output={consoleLog} />
</div>
</ChatSandboxTabPanel>
</ChatSandboxTabs>
</ChatSandboxContent>
</ChatSandbox>
</div>
);
}
Установка
pnpm dlx shadcn@latest add @oracul/chat-sandbox
Использование
import {
ChatSandbox,
ChatSandboxContent,
ChatSandboxFrame,
ChatSandboxHeader,
ChatSandboxTab,
ChatSandboxTabPanel,
ChatSandboxTabs,
ChatSandboxTabsBar,
ChatSandboxTabsList,
} from "@/components/ui/chat-sandbox";
<ChatSandbox defaultOpen>
<ChatSandboxHeader status="completed" title="Hello World preview" />
<ChatSandboxContent>
<ChatSandboxTabs defaultValue="preview">
<ChatSandboxTabsBar>
<ChatSandboxTabsList>
<ChatSandboxTab value="preview">Preview</ChatSandboxTab>
<ChatSandboxTab value="code">Code</ChatSandboxTab>
<ChatSandboxTab value="console">Console</ChatSandboxTab>
</ChatSandboxTabsList>
</ChatSandboxTabsBar>
<ChatSandboxTabPanel value="preview">
<ChatSandboxFrame src={sandboxUrl} />
</ChatSandboxTabPanel>
<ChatSandboxTabPanel value="code">
<ChatCodeBlock code={code} language="tsx" />
</ChatSandboxTabPanel>
<ChatSandboxTabPanel value="console">
<ChatTerminal output={consoleLog} />
</ChatSandboxTabPanel>
</ChatSandboxTabs>
</ChatSandboxContent>
</ChatSandbox>API
| Компонент | Описание |
|---|---|
ChatSandbox | Корневой Collapsible. |
ChatSandboxHeader | Заголовок-триггер. title, опциональный status. |
ChatSandboxContent | Сворачиваемое тело. |
ChatSandboxTabs / ChatSandboxTabsBar / ChatSandboxTabsList / ChatSandboxTab / ChatSandboxTabPanel | Стилизованные обёртки над Oracul Tabs. |
ChatSandboxFrame | <iframe> с разумным атрибутом sandbox (allow-scripts allow-same-origin allow-forms). Переопредели sandbox, если нужны другие права. |
Безопасность iframe
sandbox по умолчанию допускает скрипты и same-origin, но не allow-top-navigation и не allow-popups. Для встраивания StackBlitz / CodeSandbox этого достаточно. Для своего бэкенда с большей изоляцией — передай sandbox="" (полная изоляция).
На этой странице