@@ -5,6 +5,7 @@ import { RuntimeIconSelector } from "../RuntimeIconSelector";
55import { Loader2 , Wand2 } from "lucide-react" ;
66import { cn } from "@/common/lib/utils" ;
77import { Tooltip , TooltipWrapper } from "../Tooltip" ;
8+ import type { WorkspaceNameState } from "@/browser/hooks/useWorkspaceName" ;
89
910interface CreationControlsProps {
1011 branches : string [ ] ;
@@ -13,25 +14,12 @@ interface CreationControlsProps {
1314 runtimeMode : RuntimeMode ;
1415 defaultRuntimeMode : RuntimeMode ;
1516 sshHost : string ;
16- /** Called when user clicks a runtime icon to select it (does not persist) */
1717 onRuntimeModeChange : ( mode : RuntimeMode ) => void ;
18- /** Called when user checks "Default for project" checkbox (persists) */
1918 onSetDefaultRuntime : ( mode : RuntimeMode ) => void ;
20- /** Called when user changes SSH host */
2119 onSshHostChange : ( host : string ) => void ;
2220 disabled : boolean ;
23- /** Workspace name state */
24- workspaceName : string ;
25- /** Whether name is being generated */
26- isGeneratingName : boolean ;
27- /** Whether auto-generation is enabled */
28- autoGenerateName : boolean ;
29- /** Name generation error */
30- nameError : string | null ;
31- /** Called when auto-generate checkbox changes */
32- onAutoGenerateChange : ( enabled : boolean ) => void ;
33- /** Called when user types in the name field */
34- onNameChange : ( name : string ) => void ;
21+ /** Workspace name generation state and actions */
22+ nameState : WorkspaceNameState ;
3523}
3624
3725/**
@@ -45,26 +33,26 @@ export function CreationControls(props: CreationControlsProps) {
4533 const showTrunkBranchSelector =
4634 props . branches . length > 0 && props . runtimeMode !== RUNTIME_MODE . LOCAL ;
4735
48- const { onNameChange , onAutoGenerateChange } = props ;
36+ const { nameState } = props ;
4937
5038 const handleNameChange = useCallback (
5139 ( e : React . ChangeEvent < HTMLInputElement > ) => {
52- onNameChange ( e . target . value ) ;
40+ nameState . setName ( e . target . value ) ;
5341 } ,
54- [ onNameChange ]
42+ [ nameState ]
5543 ) ;
5644
5745 // Clicking into the input disables auto-generation so user can edit
5846 const handleInputFocus = useCallback ( ( ) => {
59- if ( props . autoGenerateName ) {
60- onAutoGenerateChange ( false ) ;
47+ if ( nameState . autoGenerate ) {
48+ nameState . setAutoGenerate ( false ) ;
6149 }
62- } , [ props . autoGenerateName , onAutoGenerateChange ] ) ;
50+ } , [ nameState ] ) ;
6351
6452 // Toggle auto-generation via wand button
6553 const handleWandClick = useCallback ( ( ) => {
66- onAutoGenerateChange ( ! props . autoGenerateName ) ;
67- } , [ props . autoGenerateName , onAutoGenerateChange ] ) ;
54+ nameState . setAutoGenerate ( ! nameState . autoGenerate ) ;
55+ } , [ nameState ] ) ;
6856
6957 return (
7058 < div className = "flex flex-col gap-2" >
@@ -77,19 +65,19 @@ export function CreationControls(props: CreationControlsProps) {
7765 < input
7866 id = "workspace-name"
7967 type = "text"
80- value = { props . workspaceName }
68+ value = { nameState . name }
8169 onChange = { handleNameChange }
8270 onFocus = { handleInputFocus }
83- placeholder = { props . isGeneratingName ? "Generating..." : "workspace-name" }
71+ placeholder = { nameState . isGenerating ? "Generating..." : "workspace-name" }
8472 disabled = { props . disabled }
8573 className = { cn (
8674 "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" ,
87- props . nameError && "border-red-500"
75+ nameState . error && "border-red-500"
8876 ) }
8977 />
9078 { /* Magic wand / loading indicator - vertically centered */ }
9179 < div className = "absolute inset-y-0 right-0 flex items-center pr-1.5" >
92- { props . isGeneratingName ? (
80+ { nameState . isGenerating ? (
9381 < Loader2 className = "text-accent h-3.5 w-3.5 animate-spin" />
9482 ) : (
9583 < TooltipWrapper inline >
@@ -98,26 +86,26 @@ export function CreationControls(props: CreationControlsProps) {
9886 onClick = { handleWandClick }
9987 disabled = { props . disabled }
10088 className = "flex h-full items-center disabled:opacity-50"
101- aria-label = { props . autoGenerateName ? "Disable auto-naming" : "Enable auto-naming" }
89+ aria-label = { nameState . autoGenerate ? "Disable auto-naming" : "Enable auto-naming" }
10290 >
10391 < Wand2
10492 className = { cn (
10593 "h-3.5 w-3.5 transition-colors" ,
106- props . autoGenerateName
94+ nameState . autoGenerate
10795 ? "text-accent"
10896 : "text-muted-foreground opacity-50 hover:opacity-75"
10997 ) }
11098 />
11199 </ button >
112100 < Tooltip className = "tooltip" align = "center" >
113- { props . autoGenerateName ? "Auto-naming enabled" : "Click to enable auto-naming" }
101+ { nameState . autoGenerate ? "Auto-naming enabled" : "Click to enable auto-naming" }
114102 </ Tooltip >
115103 </ TooltipWrapper >
116104 ) }
117105 </ div >
118106 </ div >
119107 { /* Error display - inline */ }
120- { props . nameError && < span className = "text-xs text-red-500" > { props . nameError } </ span > }
108+ { nameState . error && < span className = "text-xs text-red-500" > { nameState . error } </ span > }
121109 </ div >
122110
123111 { /* Second row: Runtime, Branch, SSH */ }
0 commit comments