Skip to content

Commit ac6d325

Browse files
committed
🤖 refactor: put runtime selector and name on same row in create workspace
- Move RuntimeIconSelector and Name input to first row - Use flex-wrap for responsive layout on smaller screens - Conditionally render second row only when branch/SSH controls needed
1 parent cbb29fa commit ac6d325

File tree

1 file changed

+87
-82
lines changed

1 file changed

+87
-82
lines changed

‎src/browser/components/ChatInput/CreationControls.tsx‎

Lines changed: 87 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -56,59 +56,7 @@ export function CreationControls(props: CreationControlsProps) {
5656

5757
return (
5858
<div className="flex flex-col gap-2">
59-
{/* First row: Workspace name with magic wand toggle */}
60-
<div className="flex items-center gap-2" data-component="WorkspaceNameGroup">
61-
<label htmlFor="workspace-name" className="text-muted text-xs whitespace-nowrap">
62-
Name:
63-
</label>
64-
<div className="relative max-w-xs flex-1">
65-
<input
66-
id="workspace-name"
67-
type="text"
68-
value={nameState.name}
69-
onChange={handleNameChange}
70-
onFocus={handleInputFocus}
71-
placeholder={nameState.isGenerating ? "Generating..." : "workspace-name"}
72-
disabled={props.disabled}
73-
className={cn(
74-
"bg-separator text-foreground border-border-medium focus:border-accent h-6 w-full rounded border px-2 pr-6 text-xs focus:outline-none disabled:opacity-50",
75-
nameState.error && "border-red-500"
76-
)}
77-
/>
78-
{/* Magic wand / loading indicator - vertically centered */}
79-
<div className="absolute inset-y-0 right-0 flex items-center pr-1.5">
80-
{nameState.isGenerating ? (
81-
<Loader2 className="text-accent h-3.5 w-3.5 animate-spin" />
82-
) : (
83-
<TooltipWrapper inline>
84-
<button
85-
type="button"
86-
onClick={handleWandClick}
87-
disabled={props.disabled}
88-
className="flex h-full items-center disabled:opacity-50"
89-
aria-label={nameState.autoGenerate ? "Disable auto-naming" : "Enable auto-naming"}
90-
>
91-
<Wand2
92-
className={cn(
93-
"h-3.5 w-3.5 transition-colors",
94-
nameState.autoGenerate
95-
? "text-accent"
96-
: "text-muted-foreground opacity-50 hover:opacity-75"
97-
)}
98-
/>
99-
</button>
100-
<Tooltip className="tooltip" align="center">
101-
{nameState.autoGenerate ? "Auto-naming enabled" : "Click to enable auto-naming"}
102-
</Tooltip>
103-
</TooltipWrapper>
104-
)}
105-
</div>
106-
</div>
107-
{/* Error display - inline */}
108-
{nameState.error && <span className="text-xs text-red-500">{nameState.error}</span>}
109-
</div>
110-
111-
{/* Second row: Runtime, Branch, SSH */}
59+
{/* First row: Runtime selector (left) + Workspace name (right), wraps on small screens */}
11260
<div className="flex flex-wrap items-center gap-x-3 gap-y-2">
11361
{/* Runtime Selector - icon-based with tooltips */}
11462
<RuntimeIconSelector
@@ -119,39 +67,96 @@ export function CreationControls(props: CreationControlsProps) {
11967
disabled={props.disabled}
12068
/>
12169

122-
{/* Trunk Branch Selector - hidden for Local runtime */}
123-
{showTrunkBranchSelector && (
124-
<div
125-
className="flex h-6 items-center gap-1"
126-
data-component="TrunkBranchGroup"
127-
data-tutorial="trunk-branch"
128-
>
129-
<label htmlFor="trunk-branch" className="text-muted text-xs">
130-
From:
131-
</label>
132-
<Select
133-
id="trunk-branch"
134-
value={props.trunkBranch}
135-
options={props.branches}
136-
onChange={props.onTrunkBranchChange}
70+
{/* Workspace name with magic wand toggle */}
71+
<div className="flex items-center gap-2" data-component="WorkspaceNameGroup">
72+
<label htmlFor="workspace-name" className="text-muted text-xs whitespace-nowrap">
73+
Name:
74+
</label>
75+
<div className="relative w-48">
76+
<input
77+
id="workspace-name"
78+
type="text"
79+
value={nameState.name}
80+
onChange={handleNameChange}
81+
onFocus={handleInputFocus}
82+
placeholder={nameState.isGenerating ? "Generating..." : "workspace-name"}
13783
disabled={props.disabled}
138-
className="h-6 max-w-[120px]"
84+
className={cn(
85+
"bg-separator text-foreground border-border-medium focus:border-accent h-6 w-full rounded border px-2 pr-6 text-xs focus:outline-none disabled:opacity-50",
86+
nameState.error && "border-red-500"
87+
)}
13988
/>
89+
{/* Magic wand / loading indicator - vertically centered */}
90+
<div className="absolute inset-y-0 right-0 flex items-center pr-1.5">
91+
{nameState.isGenerating ? (
92+
<Loader2 className="text-accent h-3.5 w-3.5 animate-spin" />
93+
) : (
94+
<TooltipWrapper inline>
95+
<button
96+
type="button"
97+
onClick={handleWandClick}
98+
disabled={props.disabled}
99+
className="flex h-full items-center disabled:opacity-50"
100+
aria-label={nameState.autoGenerate ? "Disable auto-naming" : "Enable auto-naming"}
101+
>
102+
<Wand2
103+
className={cn(
104+
"h-3.5 w-3.5 transition-colors",
105+
nameState.autoGenerate
106+
? "text-accent"
107+
: "text-muted-foreground opacity-50 hover:opacity-75"
108+
)}
109+
/>
110+
</button>
111+
<Tooltip className="tooltip" align="center">
112+
{nameState.autoGenerate ? "Auto-naming enabled" : "Click to enable auto-naming"}
113+
</Tooltip>
114+
</TooltipWrapper>
115+
)}
116+
</div>
140117
</div>
141-
)}
142-
143-
{/* SSH Host Input - after From selector */}
144-
{props.runtimeMode === RUNTIME_MODE.SSH && (
145-
<input
146-
type="text"
147-
value={props.sshHost}
148-
onChange={(e) => props.onSshHostChange(e.target.value)}
149-
placeholder="user@host"
150-
disabled={props.disabled}
151-
className="bg-separator text-foreground border-border-medium focus:border-accent h-6 w-32 rounded border px-1 text-xs focus:outline-none disabled:opacity-50"
152-
/>
153-
)}
118+
{/* Error display - inline */}
119+
{nameState.error && <span className="text-xs text-red-500">{nameState.error}</span>}
120+
</div>
154121
</div>
122+
123+
{/* Second row: Branch, SSH - only shown when there's content */}
124+
{(showTrunkBranchSelector || props.runtimeMode === RUNTIME_MODE.SSH) && (
125+
<div className="flex flex-wrap items-center gap-x-3 gap-y-2">
126+
{/* Trunk Branch Selector - hidden for Local runtime */}
127+
{showTrunkBranchSelector && (
128+
<div
129+
className="flex h-6 items-center gap-1"
130+
data-component="TrunkBranchGroup"
131+
data-tutorial="trunk-branch"
132+
>
133+
<label htmlFor="trunk-branch" className="text-muted text-xs">
134+
From:
135+
</label>
136+
<Select
137+
id="trunk-branch"
138+
value={props.trunkBranch}
139+
options={props.branches}
140+
onChange={props.onTrunkBranchChange}
141+
disabled={props.disabled}
142+
className="h-6 max-w-[120px]"
143+
/>
144+
</div>
145+
)}
146+
147+
{/* SSH Host Input - after From selector */}
148+
{props.runtimeMode === RUNTIME_MODE.SSH && (
149+
<input
150+
type="text"
151+
value={props.sshHost}
152+
onChange={(e) => props.onSshHostChange(e.target.value)}
153+
placeholder="user@host"
154+
disabled={props.disabled}
155+
className="bg-separator text-foreground border-border-medium focus:border-accent h-6 w-32 rounded border px-1 text-xs focus:outline-none disabled:opacity-50"
156+
/>
157+
)}
158+
</div>
159+
)}
155160
</div>
156161
);
157162
}

0 commit comments

Comments
 (0)