nteract elements

Cell Components

Composable components for building notebook cell interfaces

print("Hello, World!")

The cell components create notebook cell interfaces with a classic [n]: execution count. Click to run, hover to see controls.

Paper Margins Layout

CellContainer uses a paper margins design with symmetric gutters:

┌──────────────────────────────────────────────────────────┐
│ Left    │                                    │   Right   │
│ Margin  │         Content Area               │   Margin  │
├─────────┼────────────────────────────────────┼───────────┤
│[▶]:│▮│  │ Source code                        │     [⋮]   │
│    │▮│  │ print("Hello")                     │           │
│    │▮│  │                                    │           │
│    │▮│  ├────────────────────────────────────┤           │
│    │▮│  │ Output: Hello                      │           │
└────┴─┴──┴────────────────────────────────────┴───────────┘
  ^    ^                                            ^
  │    └── ribbon (colored by cell type)            │
  │                                                 └── controls (hover/focus)
  └── [n]: execution count (click to run)
  • Left margin: [n]: execution count with integrated play button, colored ribbon
  • Content: Clean "paper" with source and output
  • Right margin: Cell controls (visible on hover/focus)

Usage

Use CompactExecutionButton for the classic Jupyter [n]: style:

import { CellContainer } from "@/components/cell/CellContainer";
import { CompactExecutionButton } from "@/components/cell/CompactExecutionButton";
import { Button } from "@/components/ui/button";
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from "@/components/ui/dropdown-menu";
import { MoreVertical } from "lucide-react";

function NotebookCell({ cell, isFocused, onFocus }) {
  return (
    <CellContainer
      id={cell.id}
      cellType={cell.type}
      isFocused={isFocused}
      onFocus={onFocus}
      gutterContent={
        cell.type === "code" ? (
          <CompactExecutionButton
            count={cell.executionCount}
            isExecuting={cell.executionState === "running"}
            onExecute={() => executeCell(cell.id)}
            onInterrupt={() => interruptCell(cell.id)}
          />
        ) : undefined
      }
      rightGutterContent={
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant="ghost" size="sm" className="h-7 w-7 p-0">
              <MoreVertical className="h-3 w-3" />
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end">
            <DropdownMenuItem onClick={() => deleteCell(cell.id)}>Delete cell</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      }
    >
      <CodeEditor value={cell.source} />
      {cell.outputs.map(output => <OutputRenderer output={output} />)}
    </CellContainer>
  );
}

The CompactExecutionButton shows:

  • [▶]: before first run - click to execute
  • [■]: while running (pulsing) - click to stop
  • [1]: after execution - hover shows play, click to re-run

Multiple Cells

Click different cells to see focus behavior:

x = 1
y = 2
print(x + y)

Ribbon Colors

Cell TypeRibbon Color (focused)
codeSky blue
markdownEmerald
sqlBlue
aiPurple
rawRose

Custom colors can be provided via customGutterColors prop.

Segmented Ribbon Layout

For cells with separate code and output sections, use codeContent and outputContent props instead of children. This creates a segmented ribbon with distinct colors for each section:

┌─────────────────────────────────────────┐
│ [gutter] │ code ribbon   │ codeContent  │
│          │───────────────│──────────────│
│          │ output ribbon │ outputContent│
└─────────────────────────────────────────┘
  • Code ribbon: Cell type color (e.g., sky blue for code)
  • Output ribbon: Gradient variation of cell type color
  • Output opacity: 70% when cell is unfocused
print("Hello, world!")
Hello, world!
<CellContainer
  cellType="code"
  isFocused={isFocused}
  codeContent={<CodeEditor value={source} />}
  outputContent={<OutputArea outputs={outputs} />}
/>

Hide Output

Use hideOutput to invisibly hide the output section (useful for preloading iframes):

<CellContainer
  cellType="code"
  codeContent={<CodeEditor value={source} />}
  outputContent={<OutputArea outputs={outputs} preloadIframe />}
  hideOutput={outputs.length === 0}  // Hide until outputs arrive
/>

Installation

npx shadcn@latest add @nteract/cell-container
npx shadcn@latest add @nteract/compact-execution-button
npx shadcn@latest add @nteract/play-button
npx shadcn@latest add @nteract/execution-count

New to @nteract? pnpm dlx shadcn@latest registry add @nteract

Copy from nteract/elements.


Component Reference

CellContainer

The outer wrapper with gutter ribbon and focus styling.

Unfocused code cell
Focused code cell
Focused markdown cell (emerald ribbon)
PropTypeDefaultDescription
idstringCell identifier for data-cell-id
cellTypestringrequiredCell type for ribbon coloring
isFocusedbooleanfalseShows focus styling when true
onFocus() => voidCalled on mousedown
childrenReactNodeCell content (legacy, use codeContent/outputContent for segmented ribbon)
codeContentReactNodeCode/editor section content (enables segmented ribbon)
outputContentReactNodeOutput section content (renders with different ribbon color)
hideOutputbooleanfalseHide output section (useful for preloading)
gutterContentReactNodeLeft margin content (e.g., CompactExecutionButton)
rightGutterContentReactNodeRight margin content (e.g., controls, kebab menu)
customGutterColorsRecord<string, GutterColorConfig>Custom ribbon colors
onDragStart(e: DragEvent) => voidEnables dragging when provided
onDragOver(e: DragEvent) => voidDrag over handler
onDrop(e: DragEvent) => voidDrop handler
classNamestringAdditional classes

CompactExecutionButton

Combines play button + execution count into one [n]: element.

PropTypeDefaultDescription
countnumber | nullExecution count (null = never executed)
isExecutingbooleanfalseShows stop icon with pulse when true
onExecute() => voidRun callback
onInterrupt() => voidStop callback
classNamestringAdditional classes

PlayButton

Execute/interrupt button with state-based icons. Use gutterMode when placing in the gutter.

Idle
Running
PropTypeDescription
executionState"idle" | "queued" | "running" | "completed" | "error"Current state
cellTypestringFor tooltip text
isFocusedbooleanHighlight when focused
onExecute() => voidRun callback
onInterrupt() => voidStop callback
gutterModebooleanSmart visibility for gutter (hidden unfocused, visible on focus/hover)

ExecutionCount

Displays [n]: execution count badge.

PropTypeDescription
countnumber | nullExecution count (null shows empty brackets)
isExecutingbooleanShows [*]: when true
classNamestringAdditional classes

CellTypeButton

Color-coded button showing cell type.

PropTypeDefaultDescription
cellType"code" | "markdown" | "sql" | "ai"Cell type
showIconbooleantrueShow type icon
showPlusbooleanfalseShow + icon (for add buttons)
labelstringCustom label

On this page