Tdd Component
Generate and iteratively improve TDD React components until all tests pass
Claude CodeGeneric
---
description: Generate and iteratively improve TDD React components until all tests pass
argument-hint: <component-name> [continue]
allowed-tools: Read, Write, Edit, Glob, Grep, Bash, TodoWrite
---
<context>
<opentui_core>
## OpenTUI React Primitives
### Core Components
- `<box>` - Layout container with flexbox: `<box style={{ flexDirection: "column", padding: 1 }}>`
- `<text>` - Text display: `<text style={{ color: "#FFFFFF" }}>Content</text>` or `<text content="Content" />`
- Child elements: `<span>`, `<strong>`, `<em>`, `<u>`, `<b>`, `<i>`
- `<input>` - Text input: `<input value={value} onInput={onChange} focused={isFocused} />`
- `<scrollbox>` - Scrollable container with customizable scrollbar
- `<ascii-font>` - ASCII art text: `<ascii-font font="Slant" text="Title" />`
- `<select>` - Dropdown selection: `<select options={[]} onChange={handler} focused />`
### Box Properties
```typescript
<box
style={{
// Layout
flexDirection: "row" | "column",
justifyContent: "flex-start" | "center" | "flex-end" | "space-between",
alignItems: "flex-start" | "center" | "flex-end",
// Spacing
padding: number | { top?, right?, bottom?, left? },
margin: number | { top?, right?, bottom?, left? },
// Appearance
border: boolean,
borderStyle: "single" | "double" | "rounded" | "heavy",
borderColor: string,
backgroundColor: string,
width: number | "100%",
height: number,
}}
title="Optional Title"
>
Text Properties
import { TextAttributes } from "@opentui/core";
<text
content="Text content"
style={{
fg: "#FFFFFF", // foreground color
bg: "#000000", // background color
attributes: TextAttributes.BOLD | TextAttributes.ITALIC,
}}
/>
// Available TextAttributes:
// TextAttributes.BOLD
// TextAttributes.ITALIC
// TextAttributes.DIM
// TextAttributes.UNDERLINE
// TextAttributes.BLINK
// TextAttributes.REVERSE
// TextAttributes.HIDDEN
// TextAttributes.STRIKETHROUGH
Input Properties
<input
value={value}
onInput={(value: string) => void}
onSubmit={() => void}
placeholder="Enter text..."
focused={boolean}
style={{
focusedBackgroundColor: "#000000",
fg: "#FFFFFF",
}}
/>
Text Child Elements
<text>
Regular text
<span fg="red" bg="blue">Colored span</span>
<strong>Bold text</strong> or <b>Bold shorthand</b>
<em>Italic text</em> or <i>Italic shorthand</i>
<u>Underlined text</u>
<span fg="brightRed">Bright colors available</span>
</text>
Select Properties
<select
focused={boolean}
onChange={(value, option) => void}
options={[
{ name: "Display", description: "Details", value: "val" }
]}
showScrollIndicator={boolean}
style={{ flexGrow: 1 }}
/>
Scrollbox Structure
<scrollbox
focused
style={{
rootOptions: { backgroundColor: "#24283b" },
wrapperOptions: { backgroundColor: "#1f2335" },
viewportOptions: { backgroundColor: "#1a1b26" },
contentOptions: { backgroundColor: "#16161e" },
scrollbarOptions: {
showArrows: true,
trackOptions: {
foregroundColor: "#7aa2f7",
backgroundColor: "#414868",
},
},
}}
>
OpenTUI Hooks
useKeyboard((key) => {})- Handle keyboard inputuseRenderer()- Access renderer for debug overlay, consoleuseTimeline({ duration, loop })- Animation timeline
OpenTUI extend() Pattern
When creating complex custom components, use the extend pattern:
import { BoxRenderable, OptimizedBuffer, RGBA, type BoxOptions, type RenderContext } from "@opentui/core"
import { extend, render } from "@opentui/react"
class CustomComponent extends BoxRenderable {
public label: string = "Component"
constructor(ctx: RenderContext, options: BoxOptions & { label: string }) {
super(ctx, options)
this.height = 3
this.width = 24
}
protected renderSelf(buffer: OptimizedBuffer): void {
super.renderSelf(buffer)
const centerX = this.x + Math.floor(this.width / 2 - this.label.length / 2)
const centerY = this.y + Math.floor(this.height / 2)
buffer.drawText(this.label, centerX, centerY, RGBA.fromInts(255, 255, 255, 255))
}
}
// TypeScript module augmentation for type safety
declare module "@opentui/react" {
interface OpenTUIComponents {
customComponent: typeof CustomComponent
}
}
// Register the component
extend({ customComponent: CustomComponent })
// Use in JSX
function App() {
return <customComponent label="Hello!" />
}
When to Use extend()
Use extend when:
- Need custom OpenTUI rendering behavior
- Creating reusable components with complex internal logic
- Implementing custom drawing (borders, decorations)
- Need direct buffer access for performance
Use composition when:
- Simple combination of existing primitives
- No custom rendering needed
- One-off layouts
Setup File Structure
Every component needs a .setup.ts file:
export type ComponentScenario = {
scenarioName: string; // Unique identifier
description: string; // Human-readable summary
expectation: string; // AI evaluation criteria (CRITICAL!)
params: ComponentProps; // Props to pass to component
};
export default {
scenarios: [
// Minimum 3 scenarios covering main states
]
} as const;
Writing Effective Expectations
The 3 Elements: What + Where + How = Good Expectation
Specificity Examples:
// ❌ Too vague - AI confidence ~60%
expectation: "Shows input field"
// ⚠️ Better - AI confidence ~75%
expectation: "Shows input field with placeholder"
// ✅ Best - AI confidence >90%
expectation: "Displays input field with gray '#999999' placeholder text 'Enter command...' surrounded by horizontal borders using '━' top and '─' bottom"
Spec File Pattern
import { renderComponent } from "@/testing/captu
Maintain Tdd Component?
Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.
[Tdd Component on getagentictools](https://getagentictools.com/loops/daoresearch-run-tests-for-a-specific-component?ref=badge) npx agentictools info loops/daoresearch-run-tests-for-a-specific-component The second line is the CLI lookup for this page — handy in READMEs and docs.