Skip to content

Commit 9dfd5c4

Browse files
committed
improvement(action-bar): ui/ux
1 parent 722f35f commit 9dfd5c4

File tree

3 files changed

+59
-21
lines changed

3 files changed

+59
-21
lines changed

apps/sim/app/workspace/[workspaceId]/utils/commands-utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export type CommandId =
1919
| 'clear-terminal-console'
2020
| 'focus-toolbar-search'
2121
| 'clear-notifications'
22+
| 'fit-to-view'
2223

2324
/**
2425
* Static metadata for a global command.
@@ -104,6 +105,11 @@ export const COMMAND_DEFINITIONS: Record<CommandId, CommandDefinition> = {
104105
shortcut: 'Mod+E',
105106
allowInEditable: false,
106107
},
108+
'fit-to-view': {
109+
id: 'fit-to-view',
110+
shortcut: 'Mod+Shift+F',
111+
allowInEditable: false,
112+
},
107113
}
108114

109115
/**

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
'use client'
22

3-
import { useRef, useState } from 'react'
3+
import { useCallback, useRef, useState } from 'react'
44
import { createLogger } from '@sim/logger'
5+
import clsx from 'clsx'
6+
import { Scan } from 'lucide-react'
57
import { useReactFlow } from 'reactflow'
68
import {
79
Button,
810
ChevronDown,
911
Cursor,
10-
Expand,
1112
Hand,
1213
Popover,
1314
PopoverAnchor,
@@ -19,11 +20,14 @@ import {
1920
Undo,
2021
} from '@/components/emcn'
2122
import { useSession } from '@/lib/auth/auth-client'
23+
import { useRegisterGlobalCommands } from '@/app/workspace/[workspaceId]/providers/global-commands-provider'
24+
import { createCommand } from '@/app/workspace/[workspaceId]/utils/commands-utils'
2225
import { useUpdateGeneralSetting } from '@/hooks/queries/general-settings'
2326
import { useCanvasViewport } from '@/hooks/use-canvas-viewport'
2427
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
2528
import { useCanvasModeStore } from '@/stores/canvas-mode'
2629
import { useGeneralStore } from '@/stores/settings/general'
30+
import { useTerminalStore } from '@/stores/terminal'
2731
import { useUndoRedoStore } from '@/stores/undo-redo'
2832
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
2933

@@ -36,6 +40,7 @@ export function ActionBar() {
3640
const { undo, redo } = useCollaborativeWorkflow()
3741
const showActionBar = useGeneralStore((s) => s.showActionBar)
3842
const updateSetting = useUpdateGeneralSetting()
43+
const isTerminalResizing = useTerminalStore((state) => state.isResizing)
3944

4045
const { activeWorkflowId } = useWorkflowRegistry()
4146
const { data: session } = useSession()
@@ -46,6 +51,17 @@ export function ActionBar() {
4651
const canUndo = stack.undo.length > 0
4752
const canRedo = stack.redo.length > 0
4853

54+
const handleFitToView = useCallback(() => {
55+
fitViewToBounds({ padding: 0.1, duration: 300 })
56+
}, [fitViewToBounds])
57+
58+
useRegisterGlobalCommands([
59+
createCommand({
60+
id: 'fit-to-view',
61+
handler: handleFitToView,
62+
}),
63+
])
64+
4965
const [contextMenu, setContextMenu] = useState<{ x: number; y: number } | null>(null)
5066
const [isCanvasModeOpen, setIsCanvasModeOpen] = useState(false)
5167
const menuRef = useRef<HTMLDivElement>(null)
@@ -72,7 +88,14 @@ export function ActionBar() {
7288
return (
7389
<>
7490
<div
75-
className='-translate-x-1/2 fixed bottom-[calc(var(--terminal-height)+16px)] left-[calc((100vw+var(--sidebar-width)-var(--panel-width))/2)] z-10 flex h-[36px] items-center gap-[2px] rounded-[8px] border border-[var(--border)] bg-[var(--surface-1)] p-[4px] shadow-sm transition-[left,bottom] duration-100 ease-out'
91+
className={clsx(
92+
'fixed z-10 flex h-[36px] items-center gap-[2px] rounded-[8px] border border-[var(--border)] bg-[var(--surface-1)] p-[4px]',
93+
!isTerminalResizing && 'transition-[bottom] duration-100 ease-out'
94+
)}
95+
style={{
96+
bottom: 'calc(var(--terminal-height) + 16px)',
97+
left: 'calc(var(--sidebar-width) + 16px)',
98+
}}
7699
onContextMenu={handleContextMenu}
77100
>
78101
{/* Canvas Mode Selector */}
@@ -82,20 +105,27 @@ export function ActionBar() {
82105
variant='secondary'
83106
size='sm'
84107
>
85-
<PopoverTrigger asChild>
86-
<div className='flex cursor-pointer items-center gap-[4px]'>
87-
<Button className='h-[28px] w-[28px] rounded-[6px] p-0' variant='active'>
88-
{mode === 'hand' ? (
89-
<Hand className='h-[14px] w-[14px]' />
90-
) : (
91-
<Cursor className='h-[14px] w-[14px]' />
92-
)}
93-
</Button>
94-
<Button className='!p-[2px] group' variant='ghost'>
95-
<ChevronDown className='h-[8px] w-[10px] text-[var(--text-muted)] group-hover:text-[var(--text-secondary)]' />
96-
</Button>
97-
</div>
98-
</PopoverTrigger>
108+
<Tooltip.Root>
109+
<PopoverTrigger asChild>
110+
<div className='flex cursor-pointer items-center gap-[4px]'>
111+
<Tooltip.Trigger asChild>
112+
<Button className='h-[28px] w-[28px] rounded-[6px] p-0' variant='active'>
113+
{mode === 'hand' ? (
114+
<Hand className='h-[14px] w-[14px]' />
115+
) : (
116+
<Cursor className='h-[14px] w-[14px]' />
117+
)}
118+
</Button>
119+
</Tooltip.Trigger>
120+
<Button className='-m-[4px] !p-[6px] group' variant='ghost'>
121+
<ChevronDown
122+
className={`h-[8px] w-[10px] text-[var(--text-muted)] transition-transform duration-100 group-hover:text-[var(--text-secondary)] ${isCanvasModeOpen ? 'rotate-180' : ''}`}
123+
/>
124+
</Button>
125+
</div>
126+
</PopoverTrigger>
127+
<Tooltip.Content side='top'>{mode === 'hand' ? 'Mover' : 'Pointer'}</Tooltip.Content>
128+
</Tooltip.Root>
99129
<PopoverContent align='center' side='top' sideOffset={8} maxWidth={100} minWidth={100}>
100130
<PopoverItem
101131
onClick={() => {
@@ -159,12 +189,14 @@ export function ActionBar() {
159189
<Button
160190
variant='ghost'
161191
className='h-[28px] w-[28px] rounded-[6px] p-0 hover:bg-[var(--surface-5)]'
162-
onClick={() => fitViewToBounds({ padding: 0.1, duration: 300 })}
192+
onClick={handleFitToView}
163193
>
164-
<Expand className='h-[16px] w-[16px]' />
194+
<Scan className='h-[16px] w-[16px]' />
165195
</Button>
166196
</Tooltip.Trigger>
167-
<Tooltip.Content side='top'>Zoom to fit</Tooltip.Content>
197+
<Tooltip.Content side='top'>
198+
<Tooltip.Shortcut keys='⌘⇧F'>Fit to View</Tooltip.Shortcut>
199+
</Tooltip.Content>
168200
</Tooltip.Root>
169201
</div>
170202

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ export function Sidebar() {
489489
<>
490490
{isCollapsed ? (
491491
/* Floating collapsed header - minimal pill showing workspace name and expand toggle */
492-
<div className='fixed top-[14px] left-[10px] z-10 w-fit rounded-[10px] border border-[var(--border)] bg-[var(--surface-1)] px-[10px] py-[6px]'>
492+
<div className='fixed top-[14px] left-[10px] z-10 w-fit rounded-[8px] border border-[var(--border)] bg-[var(--surface-1)] py-[4px] pr-[10px] pl-[6px]'>
493493
<WorkspaceHeader
494494
activeWorkspace={activeWorkspace}
495495
workspaceId={workspaceId}

0 commit comments

Comments
 (0)