Skip to content
Notra logoNotra UI
Esc
↑↓navigate↵open⌘Jpreview
On this page

Prompt

The input between two rules, with the permission mode, PR link and effort below.

"use client";

import { useState } from "react";
import type { KeyboardEvent } from "react";

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";

import { ClaudeCodePrompt } from "../components/claude-code-prompt";
import { ClaudeCodeTerminal } from "../components/claude-code-terminal";
import {
  CLAUDE_CODE_EFFORT_ORDER,
  CLAUDE_CODE_MODE_ORDER,
} from "../constants/claude-code";
import type { ClaudeCodeEffort, ClaudeCodeMode } from "../types/claude-code";

const nextMode = (current: ClaudeCodeMode) => {
  const index = CLAUDE_CODE_MODE_ORDER.indexOf(current);
  return CLAUDE_CODE_MODE_ORDER[(index + 1) % CLAUDE_CODE_MODE_ORDER.length];
};

export default function ClaudeCodePromptExample() {
  const [mode, setMode] = useState<ClaudeCodeMode>("bypass");
  const [effort, setEffort] = useState<ClaudeCodeEffort>("high");

  const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
    if (event.key === "Tab" && event.shiftKey) {
      event.preventDefault();
      setMode(nextMode);
    }
  };

  return (
    <div className="flex w-full flex-col gap-3">
      <ClaudeCodeTerminal title="claude — prompt">
        <ClaudeCodePrompt
          effort={effort}
          mode={mode}
          onKeyDown={handleKeyDown}
          placeholder="Type here · Shift+Tab cycles the mode"
          pullRequest={{ number: 1317 }}
        />
      </ClaudeCodeTerminal>
      <ToggleGroup
        aria-label="Permission mode"
        className="flex-wrap"
        onValueChange={(next) => {
          const [picked] = next as ClaudeCodeMode[];
          if (picked) {
            setMode(picked);
          }
        }}
        size="sm"
        value={[mode]}
        variant="outline"
      >
        {CLAUDE_CODE_MODE_ORDER.map((item) => (
          <ToggleGroupItem key={item} value={item}>
            {item}
          </ToggleGroupItem>
        ))}
      </ToggleGroup>
      <ToggleGroup
        aria-label="Effort"
        className="flex-wrap"
        onValueChange={(next) => {
          const [picked] = next as ClaudeCodeEffort[];
          if (picked) {
            setEffort(picked);
          }
        }}
        size="sm"
        value={[effort]}
        variant="outline"
      >
        {CLAUDE_CODE_EFFORT_ORDER.map((item) => (
          <ToggleGroupItem key={item} value={item}>
            {item}
          </ToggleGroupItem>
        ))}
      </ToggleGroup>
    </div>
  );
}
$ bunx --bun shadcn@latest add @notra/claude-code-prompt

ClaudeCodePrompt is a shadcn InputGroup restyled as Claude Code’s input: the ❯ sits in an InputGroupAddon and the InputGroupInput runs between two thin gray rules, with a block cursor while it is empty. The line below shows the permission mode in its color with the (shift+tab to cycle) hint, the key in a shadcn Kbd, an optional link to the branch’s pull request and the effort level on the right. The example cycles modes on Shift+Tab like Claude Code and picks mode and effort with a shadcn ToggleGroup.

Prop Default Description
mode manual manual, accept-edits, plan, auto or bypass. manual shows ? for shortcuts.
effort false low, medium, high, xhigh, max, ultracode, or false to hide it.
pullRequest { number, href? }. Adds · PR #1317 as an underlined yellow link.
onSend Called with the trimmed text on Enter. An uncontrolled prompt clears afterwards. With value, clear it yourself in onSend.
busy false A turn is running. Enter does not send and Escape calls onStop.
onStop Called on Escape while busy.
value, defaultValue, onChange Input state, controlled or uncontrolled.
onKeyDown, placeholder Passed to the input.
inputRef, inputClassName Ref and classes for the input.

The rest of the props go to the root form. CLAUDE_CODE_MODE_ORDER lists the modes in Shift+Tab order and CLAUDE_CODE_EFFORT_ORDER the efforts from low to ultracode.

Used in

Claude Code

A Claude Code terminal session with the compact header, tool calls, a running turn and the prompt.