33import { memo , useCallback , useRef , useState } from 'react'
44import {
55 Button ,
6- ChevronDown ,
6+ ChipSwitch ,
77 Cursor ,
88 Hand ,
99 Popover ,
1010 PopoverAnchor ,
1111 PopoverContent ,
1212 PopoverItem ,
13- PopoverTrigger ,
1413 Redo ,
1514 Tooltip ,
1615 Undo ,
@@ -31,6 +30,19 @@ import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
3130
3231const logger = createLogger ( 'WorkflowControls' )
3332
33+ const CANVAS_MODE_OPTIONS = [
34+ {
35+ value : 'cursor' ,
36+ label : < span className = 'sr-only' > Pointer</ span > ,
37+ icon : Cursor ,
38+ } ,
39+ {
40+ value : 'hand' ,
41+ label : < span className = 'sr-only' > Hand</ span > ,
42+ icon : Hand ,
43+ } ,
44+ ] as const
45+
3446/**
3547 * Header controls for navigating workflow history.
3648 */
@@ -111,7 +123,6 @@ export const WorkflowControls = memo(function WorkflowControls() {
111123 ] )
112124
113125 const [ contextMenu , setContextMenu ] = useState < { x : number ; y : number } | null > ( null )
114- const [ isCanvasModeOpen , setIsCanvasModeOpen ] = useState ( false )
115126 const menuRef = useRef < HTMLDivElement > ( null )
116127
117128 const handleContextMenu = ( e : React . MouseEvent ) => {
@@ -135,61 +146,13 @@ export const WorkflowControls = memo(function WorkflowControls() {
135146
136147 return (
137148 < >
138- < div
139- className = 'flex h-[36px] flex-shrink-0 items-center gap-0.5 rounded-lg border border-[var(--border)] bg-[var(--surface-1)] p-1'
140- onContextMenu = { handleContextMenu }
141- >
142- { /* Canvas Mode Selector */ }
143- < Popover
144- open = { isCanvasModeOpen }
145- onOpenChange = { setIsCanvasModeOpen }
146- variant = 'secondary'
147- size = 'sm'
148- >
149- < Tooltip . Root >
150- < PopoverTrigger asChild >
151- < div className = 'flex cursor-pointer items-center gap-1' >
152- < Tooltip . Trigger asChild >
153- < Button className = 'size-[28px] rounded-md p-0' variant = 'active' >
154- { mode === 'hand' ? (
155- < Hand className = 'size-[14px]' />
156- ) : (
157- < Cursor className = 'size-[14px]' />
158- ) }
159- </ Button >
160- </ Tooltip . Trigger >
161- < Button className = '-m-1 !p-1.5 group' variant = 'ghost' >
162- < ChevronDown
163- className = { `size-[14px] text-[var(--text-muted)] transition-transform duration-100 group-hover:text-[var(--text-secondary)] ${ isCanvasModeOpen ? 'rotate-180' : '' } ` }
164- />
165- </ Button >
166- </ div >
167- </ PopoverTrigger >
168- < Tooltip . Content side = 'top' > { mode === 'hand' ? 'Mover' : 'Pointer' } </ Tooltip . Content >
169- </ Tooltip . Root >
170- < PopoverContent side = 'top' sideOffset = { 8 } maxWidth = { 100 } minWidth = { 100 } >
171- < PopoverItem
172- onClick = { ( ) => {
173- setMode ( 'hand' )
174- setIsCanvasModeOpen ( false )
175- } }
176- >
177- < Hand className = 'size-3' />
178- < span > Mover</ span >
179- </ PopoverItem >
180- < PopoverItem
181- onClick = { ( ) => {
182- setMode ( 'cursor' )
183- setIsCanvasModeOpen ( false )
184- } }
185- >
186- < Cursor className = 'size-3' />
187- < span > Pointer</ span >
188- </ PopoverItem >
189- </ PopoverContent >
190- </ Popover >
191-
192- < div className = 'mx-1 h-[20px] w-px bg-[var(--border)]' />
149+ < div className = 'flex flex-shrink-0 items-center gap-0.5' onContextMenu = { handleContextMenu } >
150+ < ChipSwitch
151+ options = { CANVAS_MODE_OPTIONS }
152+ value = { mode }
153+ onChange = { setMode }
154+ aria-label = 'Canvas interaction mode'
155+ />
193156
194157 < Tooltip . Root >
195158 < Tooltip . Trigger asChild >
0 commit comments