diff --git a/apps/sim/app/workspace/[workspaceId]/utils/commands-utils.ts b/apps/sim/app/workspace/[workspaceId]/utils/commands-utils.ts index 24a6eead3ad..d227b6d9026 100644 --- a/apps/sim/app/workspace/[workspaceId]/utils/commands-utils.ts +++ b/apps/sim/app/workspace/[workspaceId]/utils/commands-utils.ts @@ -10,6 +10,7 @@ export type CommandId = | 'accept-diff-changes' | 'add-agent' | 'add-workflow' + | 'collapse-sidebar' | 'goto-logs' | 'open-search' | 'open-workflow-search-replace' @@ -57,6 +58,11 @@ export const COMMAND_DEFINITIONS: Record = { shortcut: 'Mod+Shift+P', allowInEditable: false, }, + 'collapse-sidebar': { + id: 'collapse-sidebar', + shortcut: 'Mod+B', + allowInEditable: false, + }, 'goto-logs': { id: 'goto-logs', shortcut: 'Mod+L', @@ -144,3 +150,33 @@ export function createCommand(input: CreateCommandInput): GlobalCommand { export function createCommands(inputs: CreateCommandInput[]): GlobalCommand[] { return inputs.map((input) => createCommand(input)) } + +/** Display symbols for shortcut modifiers on macOS. */ +const MAC_MODIFIER_SYMBOLS: Record = { + Mod: '⌘', + Shift: '⇧', + Alt: '⌥', +} + +/** Display labels for shortcut modifiers on Windows/Linux. */ +const NON_MAC_MODIFIER_LABELS: Record = { + Mod: 'Ctrl', + Shift: 'Shift', + Alt: 'Alt', +} + +/** + * Formats a command's shortcut for display, deriving the keys from + * {@link COMMAND_DEFINITIONS} so tooltips never drift from the registered + * binding. macOS renders compact symbols (`⌘⇧P`); other platforms render + * `+`-joined labels (`Ctrl+Shift+P`). + * + * @param id - Command whose shortcut to format. + * @param isMac - Whether to render macOS symbols instead of Windows/Linux labels. + */ +export function formatCommandShortcut(id: CommandId, isMac: boolean): string { + const tokens = COMMAND_DEFINITIONS[id].shortcut.split('+') + return isMac + ? tokens.map((token) => MAC_MODIFIER_SYMBOLS[token] ?? token).join('') + : tokens.map((token) => NON_MAC_MODIFIER_LABELS[token] ?? token).join('+') +} diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workspace-header/workspace-header.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workspace-header/workspace-header.tsx index 499f79b91b2..c6f10ebdb29 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workspace-header/workspace-header.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workspace-header/workspace-header.tsx @@ -15,6 +15,7 @@ import { Plus, Send, Skeleton, + Tooltip, } from '@/components/emcn' import { ManageWorkspace, PanelLeft } from '@/components/emcn/icons' import { cn } from '@/lib/core/utils/cn' @@ -68,6 +69,8 @@ interface WorkspaceHeaderProps { isCollapsed?: boolean /** Callback to expand the sidebar from collapsed state */ onExpandSidebar?: () => void + /** Formatted keyboard shortcut shown in the expand affordance tooltip */ + expandShortcut?: string } /** @@ -93,6 +96,7 @@ function WorkspaceHeaderImpl({ sessionUserId, isCollapsed = false, onExpandSidebar, + expandShortcut, }: WorkspaceHeaderProps) { const [isCreateModalOpen, setIsCreateModalOpen] = useState(false) const [isInviteModalOpen, setIsInviteModalOpen] = useState(false) @@ -270,41 +274,52 @@ function WorkspaceHeaderImpl({ return (
{isMounted && isCollapsed ? ( - + + + {expandShortcut ? ( + Expand sidebar + ) : ( +

Expand sidebar

)} -
- + + ) : isMounted && isWorkspaceReady ? ( {children} -

{label}

+ {shortcut ? {label} :

{label}

}
) @@ -388,6 +393,7 @@ export const Sidebar = memo(function Sidebar() { }, [isCollapsed]) const isMac = isMacPlatform() + const collapseShortcut = formatCommandShortcut('collapse-sidebar', isMac) const [showCollapsedTooltips, setShowCollapsedTooltips] = useState(isCollapsed) @@ -1218,6 +1224,12 @@ export const Sidebar = memo(function Sidebar() { handleCreateWorkflow() }, }, + { + id: 'collapse-sidebar', + handler: () => { + toggleCollapsed() + }, + }, ]) ) @@ -1267,8 +1279,14 @@ export const Sidebar = memo(function Sidebar() { sessionUserId={sessionData?.user?.id} isCollapsed={isCollapsed} onExpandSidebar={toggleCollapsed} + expandShortcut={collapseShortcut} /> - +