Skip to content

Commit edc5023

Browse files
authored
improvement(sidebar): expand sidebar by hovering and clicking the edge (#3830)
* improvement(sidebar): expand sidebar by hovering and clicking the edge * improvement(sidebar): add keyboard shortcuts for new workflow/task, center search modal, fix edge ARIA * improvement(sidebar): use Tooltip.Shortcut for inline shortcut display * fix(sidebar): change new workflow shortcut from Mod+Shift+W to Mod+Shift+P to avoid browser close-window conflict * fix(hotkeys): fall back to event.code for international keyboard layout compatibility * fix(sidebar): guard add-workflow shortcut with canEdit and isCreatingWorkflow checks
1 parent e2be992 commit edc5023

File tree

4 files changed

+558
-491
lines changed

4 files changed

+558
-491
lines changed

apps/sim/app/workspace/[workspaceId]/providers/global-commands-provider.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,26 @@ function parseShortcut(shortcut: string): ParsedShortcut {
5757
}
5858
}
5959

60+
/**
61+
* Maps a KeyboardEvent.code value to the logical key name used in shortcut definitions.
62+
* Needed for international keyboard layouts where e.key may produce unexpected characters
63+
* (e.g. macOS Option+letter yields 'å' instead of 'a', dead keys yield 'Dead').
64+
*/
65+
function codeToKey(code: string): string | undefined {
66+
if (code.startsWith('Key')) return code.slice(3).toLowerCase()
67+
if (code.startsWith('Digit')) return code.slice(5)
68+
return undefined
69+
}
70+
6071
function matchesShortcut(e: KeyboardEvent, parsed: ParsedShortcut): boolean {
6172
const isMac = isMacPlatform()
6273
const expectedCtrl = parsed.ctrl || (parsed.mod ? !isMac : false)
6374
const expectedMeta = parsed.meta || (parsed.mod ? isMac : false)
6475
const eventKey = e.key.length === 1 ? e.key.toLowerCase() : e.key
76+
const keyMatches = eventKey === parsed.key || codeToKey(e.code) === parsed.key
6577

6678
return (
67-
eventKey === parsed.key &&
79+
keyMatches &&
6880
!!e.ctrlKey === !!expectedCtrl &&
6981
!!e.metaKey === !!expectedMeta &&
7082
!!e.shiftKey === !!parsed.shift &&

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import type { GlobalCommand } from '@/app/workspace/[workspaceId]/providers/glob
99
export type CommandId =
1010
| 'accept-diff-changes'
1111
| 'add-agent'
12+
| 'add-workflow'
13+
| 'add-task'
1214
// | 'goto-templates'
1315
| 'goto-logs'
1416
| 'open-search'
@@ -52,6 +54,16 @@ export const COMMAND_DEFINITIONS: Record<CommandId, CommandDefinition> = {
5254
shortcut: 'Mod+Shift+A',
5355
allowInEditable: true,
5456
},
57+
'add-workflow': {
58+
id: 'add-workflow',
59+
shortcut: 'Mod+Shift+P',
60+
allowInEditable: false,
61+
},
62+
'add-task': {
63+
id: 'add-task',
64+
shortcut: 'Mod+Shift+K',
65+
allowInEditable: false,
66+
},
5567
// 'goto-templates': {
5668
// id: 'goto-templates',
5769
// shortcut: 'Mod+Y',

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ export function SearchModal({
343343
'-translate-x-1/2 fixed top-[15%] z-50 w-[500px] rounded-xl border-[4px] border-black/[0.06] bg-[var(--bg)] shadow-[0_24px_80px_-16px_rgba(0,0,0,0.15)] dark:border-white/[0.06] dark:shadow-[0_24px_80px_-16px_rgba(0,0,0,0.4)]',
344344
open ? 'visible opacity-100' : 'invisible opacity-0'
345345
)}
346-
style={{ left: '50%' }}
346+
style={{ left: 'calc(var(--sidebar-width) / 2 + 50%)' }}
347347
>
348348
<Command label='Search' shouldFilter={false}>
349349
<div className='mx-2 mt-2 mb-1 flex items-center gap-1.5 rounded-lg border border-[var(--border-1)] bg-[var(--surface-5)] px-2 dark:bg-[var(--surface-4)]'>

0 commit comments

Comments
 (0)