Generate and render a pixel-precise ASCII TUI Input component with complete output blocks (TUI_RENDER, COMPONENT_SPEC, PENCIL_SPEC, PENCIL_BATCH_DESIGN) for Pencil MCP drawing workflows. Use when the user asks to create an input in a terminal UI, text-based interface, or Pencil MCP project.
batch_design plan (≤25 operations per call).{
"widthCols": 70,
"grid": { "cellWidthPx": 8, "cellHeightPx": 16 },
"props": {},
"modelValue": null,
"state": { "focused": false, "disabled": false, "loading": false, "error": null },
"style": {
"fillColor": "#ffffff",
"textColor": "#111111",
"strokeColor": "#e5e7eb",
"strokeThickness": 1,
"cornerRadius": 12
},
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 400, "lineHeight": 20 },
"layout": { "paddingPx": 16, "gapPx": 8 },
"hotkeys": []
}
...monospace-only text...
{
"id": "tui-input_1",
"name": "Input",
"type": "tui-input",
"bbox": { "topPx": 0, "leftPx": 0, "widthPx": 0, "heightPx": 0 },
"zIndex": 1,
"layout": { "paddingPx": 16, "gapPx": 8, "align": "left", "valign": "top" },
"style": {
"fillColor": "#ffffff",
"textColor": "#111111",
"strokeColor": "#e5e7eb",
"strokeThickness": 1,
"cornerRadius": 12,
"opacity": 1
},
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 400, "lineHeight": 20 },
"overflow": { "mode": "truncate", "ellipsis": "…", "maxLines": 1 },
"state": { "focused": false, "disabled": false, "loading": false, "error": null },
"hotkeys": []
}
{
"canvas": { "widthPx": 390, "heightPx": 844, "backgroundColor": "#ffffff" },
"grid": { "cellWidthPx": 8, "cellHeightPx": 16 },
"nodes": [],
"components": []
}
CALL 1:
root=G()
screen=I(root,{type:"frame",name:"Screen"})
U(screen,{width:390,height:844,x:0,y:0})
CALL 2:
cmpBg=I(screen,{type:"rect",name:"Input/Background"})
U(cmpBg,{x:24,y:24,width:342,height:96,fillColor:"#ffffff",strokeColor:"#e5e7eb",strokeThickness:1,cornerRadius:12})
cmpText=I(screen,{type:"text",name:"Input/Text",content:"Input"})
U(cmpText,{x:40,y:56,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:600})
Follow the shared rules from tui-front-ui:
widthCols.disabled=true must suppress interaction hints.loading=true must show a stable placeholder.error!=null must be printed in a single line footer (truncated to width).Canonical props for a text input:
label?: stringplaceholder?: stringvalue: string (or use modelValue)required?: booleanmaxLength?: numberprefix?: string, suffix?: string (render as inline tokens)clearable?: boolean (render [x] when focused and non-empty)keyboard?: "text" | "number" | "password" (affects masking)State rules:
| inside the field at the end position (or selection if provided).• with same length as value.Interaction hints:
<tab> next field, <enter> commit, <esc> back.┌──────────────────────────────────────────────────────────────┐
│ [Input] │
├──────────────────────────────────────────────────────────────┤
│ (default state) │
└──────────────────────────────────────────────────────────────┘
{
"id": "tui-input_ex1",
"name": "Input",
"type": "tui-input",
"bbox": { "topPx": 24, "leftPx": 24, "widthPx": 342, "heightPx": 96 },
"zIndex": 1,
"layout": { "paddingPx": 16, "gapPx": 8, "align": "left", "valign": "top" },
"style": { "fillColor": "#ffffff", "textColor": "#111111", "strokeColor": "#e5e7eb", "strokeThickness": 1, "cornerRadius": 12, "opacity": 1 },
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 400, "lineHeight": 20 },
"overflow": { "mode": "truncate", "ellipsis": "…", "maxLines": 1 },
"state": { "focused": false, "disabled": false, "loading": false, "error": null },
"hotkeys": []
}
{
"canvas": { "widthPx": 390, "heightPx": 844, "backgroundColor": "#ffffff" },
"grid": { "cellWidthPx": 8, "cellHeightPx": 16 },
"nodes": [],
"components": [
{ "id": "tui-input_ex1", "name": "Input", "bbox": { "topPx": 24, "leftPx": 24, "widthPx": 342, "heightPx": 96 }, "zIndex": 1 }
]
}
CALL 1:
root=G()
screen=I(root,{type:"frame",name:"Screen"})
U(screen,{width:390,height:844,x:0,y:0})
CALL 2:
cmpBg=I(screen,{type:"rect",name:"Input/Background"})
U(cmpBg,{x:24,y:24,width:342,height:96,fillColor:"#ffffff",strokeColor:"#e5e7eb",strokeThickness:1,cornerRadius:12})
cmpText=I(screen,{type:"text",name:"Input/Text",content:"Input"})
U(cmpText,{x:40,y:56,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:600})
┌──────────────────────────────────────────────────────────────┐
│ [Input] │
├──────────────────────────────────────────────────────────────┤
│ (custom style: strong border, increased padding) │
└──────────────────────────────────────────────────────────────┘
{
"id": "tui-input_ex2",
"name": "Input",
"type": "tui-input",
"bbox": { "topPx": 24, "leftPx": 24, "widthPx": 342, "heightPx": 104 },
"zIndex": 1,
"layout": { "paddingPx": 20, "gapPx": 10, "align": "left", "valign": "top" },
"style": { "fillColor": "#ffffff", "textColor": "#111111", "strokeColor": "#111111", "strokeThickness": 2, "cornerRadius": 12, "opacity": 1 },
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 600, "lineHeight": 20 },
"overflow": { "mode": "truncate", "ellipsis": "…", "maxLines": 1 },
"state": { "focused": false, "disabled": false, "loading": false, "error": null },
"hotkeys": []
}
{
"canvas": { "widthPx": 390, "heightPx": 844, "backgroundColor": "#ffffff" },
"grid": { "cellWidthPx": 8, "cellHeightPx": 16 },
"nodes": [],
"components": [
{ "id": "tui-input_ex2", "name": "Input", "bbox": { "topPx": 24, "leftPx": 24, "widthPx": 342, "heightPx": 104 }, "zIndex": 1 }
]
}
CALL 1:
root=G()
screen=I(root,{type:"frame",name:"Screen"})
U(screen,{width:390,height:844,x:0,y:0})
CALL 2:
cmpBg=I(screen,{type:"rect",name:"Input/Background"})
U(cmpBg,{x:24,y:24,width:342,height:104,fillColor:"#ffffff",strokeColor:"#111111",strokeThickness:2,cornerRadius:12})
cmpText=I(screen,{type:"text",name:"Input/Text",content:"Input"})
U(cmpText,{x:40,y:60,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:600})
┌──────────────────────────────────────────────────────────────┐
│ [Input] Disabled │
├──────────────────────────────────────────────────────────────┤
│ Error: Something went wrong… │
└──────────────────────────────────────────────────────────────┘
{
"id": "tui-input_ex3",
"name": "Input",
"type": "tui-input",
"bbox": { "topPx": 24, "leftPx": 24, "widthPx": 342, "heightPx": 112 },
"zIndex": 1,
"layout": { "paddingPx": 16, "gapPx": 8, "align": "left", "valign": "top" },
"style": { "fillColor": "#ffffff", "textColor": "#6b7280", "strokeColor": "#e5e7eb", "strokeThickness": 1, "cornerRadius": 12, "opacity": 1 },
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 400, "lineHeight": 20 },
"overflow": { "mode": "truncate", "ellipsis": "…", "maxLines": 1 },
"state": { "focused": false, "disabled": true, "loading": false, "error": "Something went wrong" },
"hotkeys": []
}
{
"canvas": { "widthPx": 390, "heightPx": 844, "backgroundColor": "#ffffff" },
"grid": { "cellWidthPx": 8, "cellHeightPx": 16 },
"nodes": [],
"components": [
{ "id": "tui-input_ex3", "name": "Input", "bbox": { "topPx": 24, "leftPx": 24, "widthPx": 342, "heightPx": 112 }, "zIndex": 1 }
]
}
CALL 1:
root=G()
screen=I(root,{type:"frame",name:"Screen"})
U(screen,{width:390,height:844,x:0,y:0})
CALL 2:
cmpBg=I(screen,{type:"rect",name:"Input/Background"})
U(cmpBg,{x:24,y:24,width:342,height:112,fillColor:"#ffffff",strokeColor:"#e5e7eb",strokeThickness:1,cornerRadius:12,opacity:1})
cmpText=I(screen,{type:"text",name:"Input/Error",content:"Error: Something went wrong…"})
U(cmpText,{x:40,y:60,width:310,height:20,textColor:"#6b7280",fontFamily:"Inter",fontSize:14,fontWeight:400})
┌──────────────────────────────────────────────────────────────┐
│ [Input] │
├──────────────────────────────────────────────────────────────┤
│ Email │
│ [ [email protected]|___________________________ ] [x] │
├──────────────────────────────────────────────────────────────┤
│ Keys: <tab> next <enter> commit <esc> back │
└──────────────────────────────────────────────────────────────┘
{
"id": "tui-input_ex4",
"name": "Input",
"type": "tui-input",
"bbox": { "topPx": 24, "leftPx": 24, "widthPx": 342, "heightPx": 120 },
"zIndex": 1,
"layout": { "paddingPx": 16, "gapPx": 8, "align": "left", "valign": "top" },
"style": { "fillColor": "#ffffff", "textColor": "#111111", "strokeColor": "#111111", "strokeThickness": 1, "cornerRadius": 12, "opacity": 1 },
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 400, "lineHeight": 20 },
"overflow": { "mode": "truncate", "ellipsis": "…", "maxLines": 1 },
"state": { "focused": true, "disabled": false, "loading": false, "error": null },
"hotkeys": ["<tab>", "<enter>", "<esc>"]
}
{
"canvas": { "widthPx": 390, "heightPx": 844, "backgroundColor": "#ffffff" },
"grid": { "cellWidthPx": 8, "cellHeightPx": 16 },
"nodes": [],
"components": [
{ "id": "tui-input_ex4", "name": "Input", "bbox": { "topPx": 24, "leftPx": 24, "widthPx": 342, "heightPx": 120 }, "zIndex": 1 }
]
}
CALL 1:
root=G()
screen=I(root,{type:"frame",name:"Screen"})
U(screen,{width:390,height:844,x:0,y:0})
CALL 2:
field=I(screen,{type:"rect",name:"Input/Field"})
U(field,{x:24,y:24,width:342,height:72,fillColor:"#ffffff",strokeColor:"#111111",strokeThickness:1,cornerRadius:12})
label=I(screen,{type:"text",name:"Input/Label",content:"Email"})
U(label,{x:40,y:40,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:600})
value=I(screen,{type:"text",name:"Input/Value",content:"[email protected]|"})
U(value,{x:40,y:64,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:400})
clear=I(screen,{type:"text",name:"Input/Clear",content:"[x]"})
U(clear,{x:340,y:64,width:26,height:20,textColor:"#6b7280",fontFamily:"Inter",fontSize:12,fontWeight:400})
┌──────────────────────────────────────────────────────────────┐
│ [Input] │
├──────────────────────────────────────────────────────────────┤
│ Password │
│ [ ••••••••••_______________________________ ] │
├──────────────────────────────────────────────────────────────┤
│ Keys: <tab> next <enter> commit <esc> back │
└──────────────────────────────────────────────────────────────┘
{
"id": "tui-input_ex5",
"name": "Input",
"type": "tui-input",
"bbox": { "topPx": 24, "leftPx": 24, "widthPx": 342, "heightPx": 120 },
"zIndex": 1,
"layout": { "paddingPx": 16, "gapPx": 8, "align": "left", "valign": "top" },
"style": { "fillColor": "#ffffff", "textColor": "#111111", "strokeColor": "#e5e7eb", "strokeThickness": 1, "cornerRadius": 12, "opacity": 1 },
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 400, "lineHeight": 20 },
"overflow": { "mode": "truncate", "ellipsis": "…", "maxLines": 1 },
"state": { "focused": true, "disabled": false, "loading": false, "error": null },
"hotkeys": ["<tab>", "<enter>", "<esc>"]
}
{
"canvas": { "widthPx": 390, "heightPx": 844, "backgroundColor": "#ffffff" },
"grid": { "cellWidthPx": 8, "cellHeightPx": 16 },
"nodes": [],
"components": [
{ "id": "tui-input_ex5", "name": "Input", "bbox": { "topPx": 24, "leftPx": 24, "widthPx": 342, "heightPx": 120 }, "zIndex": 1 }
]
}
CALL 1:
root=G()
screen=I(root,{type:"frame",name:"Screen"})
U(screen,{width:390,height:844,x:0,y:0})
CALL 2:
field=I(screen,{type:"rect",name:"Input/Field"})
U(field,{x:24,y:24,width:342,height:72,fillColor:"#ffffff",strokeColor:"#e5e7eb",strokeThickness:1,cornerRadius:12})
label=I(screen,{type:"text",name:"Input/Label",content:"Password"})
U(label,{x:40,y:40,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:600})
value=I(screen,{type:"text",name:"Input/Value",content:"••••••••••"})
U(value,{x:40,y:64,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:400})
| id | name | top | left | width | height | z | keyProps | state | hotkeys |
| tui-input | Input | 0 | 0 | 0 | 0 | 0 | keyProps=... | state=... | hotkeys=... |