Editor windowPro
A code editor frame with a file tree slot, file tabs, breadcrumbs, change bars, an inline suggestion and a status bar.
On this page
Installation
Usage
import { EditorCode, EditorStatusBar, EditorWindow } from "@/components/ui/chatcn/pro/editor-window"
<EditorWindow
title="runs-pagination"
sidebar={<FileTree nodes={tree} />}
tabs={[{ id: "page", path: "src/app/runs/page.tsx", dirty: true, content: <EditorCode code={code} language="tsx" /> }]}
statusBar={<EditorStatusBar branch="runs-pagination" position={{ line: 12, column: 30 }} />}
/>The window shares its surface with the app, browser and terminal windows. One chrome tone runs through the title bar, the tree, the tab strip and the status bar; the code sits on the page background. The sidebar is a slot (the free FileTree fits it) and hides when the window is narrower than 560 px.
EditorCode highlights with the kit's lazy Shiki and draws what editors draw: change bars against the base in the gutter, indent guides, the cursor line, squiggles under diagnostics with the message at the line end, and an agent's inline suggestion as ghost text with the key that accepts it. Lines sit on a 20 px grid in 13 px mono. Code stays left to right in right to left pages.
Examples
States
An error while an agent fixes it, a file opening, no file open, and a dark right to left window with a long path: the breadcrumbs keep the first folder and the last two segments.
Props
EditorWindow
| Prop | Type | Notes |
|---|---|---|
title | ReactNode | Centered in the title bar |
tabs | EditorTab[] | id, path, dirty, status (added, modified, deleted), content |
activeTab | string | Controlled. defaultActiveTab, onActiveTabChange |
onCloseTab | (id) => void | Shows close buttons; Delete closes the focused tab |
sidebar | ReactNode | The file tree slot. sidebarWidth (232), sidebarTitle |
breadcrumbs | boolean | Default true |
statusBar | ReactNode | Usually EditorStatusBar |
empty | ReactNode | Shown when no file is open |
tone | "auto" | "dark" | dark keeps the window dark on a light page |
height / width | number | string | Default 520 and 100% |
EditorCode
| Prop | Type | Notes |
|---|---|---|
code | string | |
language | string | A Shiki id or alias, loaded lazily |
cursor | { line, column } | 1 based |
changes | { added?, modified?, deleted? } | Line numbers for the gutter bars |
diagnostics | EditorDiagnostic[] | line, start, end, severity, message |
suggestion | { line, text, hint? } | Ghost text after a line; more lines become ghost rows |
highlightLines | number[] | Marked lines |
loading | boolean | Skeleton lines while the file opens |
indentGuides / tabSize | boolean / number | Default true and 2 |
EditorStatusBar
| Prop | Type | Notes |
|---|---|---|
branch | string | |
errors / warnings | number | Red and amber when above zero, with icons and counts |
activity | ReactNode | A running task with a spinner, for example Agent fixing runs.ts |
position | { line, column } | Tabular figures |
language / encoding / indent | string | Encoding and indent hide in narrow windows |
Keyboard
| Key | Action |
|---|---|
| Arrow keys on a tab | Move between tabs |
Delete / Backspace on a tab | Close it, when onCloseTab is set |
Tab into the code | Focuses the scrollable code so it scrolls from the keyboard |
Accessibility
- Tabs are real tabs (Base UI Tabs); a tab's name adds its change and unsaved state in words.
- The code is read as one block, followed by its problems and the suggestion in words; line numbers and guides are hidden.
- Problem counts in the status bar are one image with a full label.
Motion
- The cursor blinks once a second and holds steady under reduced motion.
- Hover colors change in 150 ms. Nothing else moves.