From e97473cda25169805b1230659764f494de4403bc Mon Sep 17 00:00:00 2001 From: richardkeep Date: Sat, 31 Oct 2026 22:43:04 +0300 Subject: [PATCH 1/2] fix layout --- .../components/keyboard-shortcuts-dialog.tsx | 185 ++++++++++++------ 1 file changed, 122 insertions(+), 63 deletions(-) diff --git a/resources/js/components/keyboard-shortcuts-dialog.tsx b/resources/js/components/keyboard-shortcuts-dialog.tsx index 1cd6e556b..f9fd47c5b 100644 --- a/resources/js/components/keyboard-shortcuts-dialog.tsx +++ b/resources/js/components/keyboard-shortcuts-dialog.tsx @@ -1,3 +1,4 @@ +import { Fragment } from 'react'; import { Dialog, DialogContent, @@ -7,59 +8,117 @@ import { import type { KeyLabels } from '@/lib/keyboard'; import { useKeyLabels } from '@/lib/keyboard'; -type Shortcut = { keys: string[]; label: string }; +// Each entry in `keys` is one way to press it: most have one, search has two. +type Shortcut = { keys: string[][]; label: string }; +type Group = { title: string; shortcuts: Shortcut[] }; -const shortcuts = (keys: KeyLabels, hasRemotes: boolean): Shortcut[] => [ - { keys: ['j'], label: 'Next commit' }, - { keys: ['k'], label: 'Previous commit' }, - { keys: ['y'], label: 'Copy link to the focused commit' }, - { keys: ['↵'], label: 'Open the focused commit' }, - { keys: ['r'], label: 'Reply to commit' }, - { keys: ['q'], label: 'Quote commit' }, - { keys: ['s'], label: 'Star or unstar commit' }, - { keys: ['o'], label: 'Show or hide replies' }, - { keys: ['c'], label: 'Write a commit' }, - { keys: [keys.mod, 'K'], label: 'Search developers and commits' }, - { keys: ['/'], label: 'Search developers and commits' }, - { keys: [keys.mod, '↵'], label: 'Commit (in the composer)' }, - { keys: [keys.mod, keys.shift, 'P'], label: 'Preview (in the composer)' }, - { keys: ['g', 'l'], label: 'Go to your log' }, - { keys: ['g', 'e'], label: 'Go to trending' }, - { keys: ['g', 'p'], label: 'Go to your profile' }, - { keys: ['g', 's'], label: 'Go to settings' }, - { keys: ['g', 'n'], label: 'Go to notifications' }, - ...(hasRemotes ? [{ keys: ['g', 'm'], label: 'Go to remotes' }] : []), - { keys: ['g', '*'], label: 'Go to starred' }, - { keys: ['?'], label: 'Show this list' }, +const groups = ( + keys: KeyLabels, + hasRemotes: boolean, + canModerate: boolean, +): Group[][] => [ + [ + { + title: 'Commits', + shortcuts: [ + { keys: [['j']], label: 'Next' }, + { keys: [['k']], label: 'Previous' }, + { keys: [['↵']], label: 'Open' }, + { keys: [['r']], label: 'Reply' }, + { keys: [['q']], label: 'Quote' }, + { keys: [['s']], label: 'Star or unstar' }, + { keys: [['o']], label: 'Show or hide replies' }, + { keys: [['y']], label: 'Copy link' }, + ], + }, + ], + [ + { + title: 'Go to', + shortcuts: [ + { keys: [['g', 'l']], label: 'Your log' }, + { keys: [['g', 'e']], label: 'Trending' }, + { keys: [['g', 'p']], label: 'Your profile' }, + { keys: [['g', 'n']], label: 'Notifications' }, + ...(hasRemotes + ? [{ keys: [['g', 'm']], label: 'Remotes' }] + : []), + { keys: [['g', '*']], label: 'Starred' }, + { keys: [['g', 's']], label: 'Settings' }, + ], + }, + ], + [ + { + title: 'Write', + shortcuts: [ + { keys: [['c']], label: 'New commit' }, + { keys: [[keys.mod, '↵']], label: 'Commit' }, + { keys: [[keys.mod, keys.shift, 'P']], label: 'Preview' }, + ], + }, + { + title: 'Anywhere', + shortcuts: [ + { keys: [[keys.mod, 'K'], ['/']], label: 'Search' }, + { keys: [['?']], label: 'Show this list' }, + ], + }, + ...(canModerate + ? [ + { + title: 'Moderation queue', + shortcuts: [ + { keys: [['a']], label: 'Approve commit' }, + { keys: [['x']], label: 'Reject commit' }, + ], + }, + ] + : []), + ], ]; -const moderationShortcuts: Shortcut[] = [ - { keys: ['a'], label: 'Approve commit (in the queue)' }, - { keys: ['x'], label: 'Reject commit (in the queue)' }, -]; +function ShortcutGroup({ group }: { group: Group }) { + const id = `shortcuts-${group.title.toLowerCase().replaceAll(' ', '-')}`; -function ShortcutList({ shortcuts }: { shortcuts: Shortcut[] }) { return ( -
- {shortcuts.map((shortcut) => ( -
-
{shortcut.label}
-
- {shortcut.keys.map((key) => ( - - {key} - - ))} -
-
- ))} -
+
+

+ {group.title} +

+
+ {group.shortcuts.map((shortcut) => ( +
+
{shortcut.label}
+
+ {shortcut.keys.map((combo, index) => ( + + {index > 0 && ( + + or + + )} + {combo.map((key) => ( + + {key} + + ))} + + ))} +
+
+ ))} +
+
); } @@ -78,25 +137,25 @@ export function KeyboardShortcutsDialog({ return ( - + Keyboard shortcuts - They work anywhere except while you're typing. + They work anywhere except while you're typing. Commit and + preview work in the composer. - - - {canModerate && ( -
-

- Moderation -

- -
- )} +
+ {groups(keys, hasRemotes, canModerate).map((column) => ( +
+ {column.map((group) => ( + + ))} +
+ ))} +
); From 61e06ef71a771273cf0a634af2e8a206c59bd23d Mon Sep 17 00:00:00 2001 From: richardkeep Date: Sat, 31 Oct 2026 22:56:46 +0300 Subject: [PATCH 2/2] fix: preserve visual viewport height cap in keyboard shortcuts dialog --- resources/js/components/keyboard-shortcuts-dialog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/js/components/keyboard-shortcuts-dialog.tsx b/resources/js/components/keyboard-shortcuts-dialog.tsx index f9fd47c5b..c4fb9ec01 100644 --- a/resources/js/components/keyboard-shortcuts-dialog.tsx +++ b/resources/js/components/keyboard-shortcuts-dialog.tsx @@ -137,7 +137,7 @@ export function KeyboardShortcutsDialog({ return ( - + Keyboard shortcuts They work anywhere except while you're typing. Commit and