Component

Editor Tabs

An IDE-style open-file tab bar with active highlighting, dirty-state indicators, close buttons, and full keyboard navigation โ€” built for mock-interview and code-editor surfaces.

Basic

A minimal tab bar with icons and labels. Click a tab to activate it.

Active tab: solution

With dirty indicator and close button

Set dirty to show an amber dot for unsaved changes. Set closable to show a close button that calls onClose.

The amber dot signals unsaved changes. Click ร— to close a tab.

Keyboard navigation

The tab bar uses roving tabindex. Once focused, use arrow keys to move between tabs โ€” wrapping at the ends โ€” and Home/End to jump to the first/last tab.

Focus a tab and use โ† โ†’ to move between tabs โ€” wrapping at the ends.Home End jump to the first/last tab.

Active tab: solution

Installation

$pnpm add @refraction-ui/react

Usage

tsx
import { EditorTabs } from '@refraction-ui/react'
import type { EditorTabData } from '@refraction-ui/react'

const tabs: EditorTabData[] = [
  { id: 'solution', label: 'solution.py', icon: '๐Ÿ', dirty: true, closable: true },
  { id: 'tests',    label: 'tests.py',    icon: '๐Ÿงช', closable: true },
  { id: 'notes',    label: 'notes.md',    icon: '๐Ÿ“', closable: true },
]

export function IDE() {
  const [activeId, setActiveId] = React.useState('solution')
  const [openTabs, setOpenTabs] = React.useState(tabs)

  const handleClose = (id: string) => {
    const remaining = openTabs.filter((t) => t.id !== id)
    setOpenTabs(remaining)
    if (activeId === id && remaining.length > 0) setActiveId(remaining[0].id)
  }

  return (
    <EditorTabs
      tabs={openTabs}
      activeId={activeId}
      onSelect={setActiveId}
      onClose={handleClose}
    />
  )
}

Props

PropTypeDefaultDescription
tabsEditorTabData[]--The list of tab entries. Each entry: `{ id, label, icon?, dirty?, closable? }`.
activeIdstring--The id of the currently active tab (controlled).
onSelect(id: string) => void--Called when the user clicks or navigates to a tab.
onClose(id: string) => void--Called when the user clicks the close button on a closable tab.
classNamestring--Additional CSS classes to apply to the tab bar container.