@remotion/studio: Add dropdown type-to-select navigation#7016
@remotion/studio: Add dropdown type-to-select navigation#7016JonnyBurger merged 6 commits intomainfrom
@remotion/studio: Add dropdown type-to-select navigation#7016Conversation
Co-authored-by: Jonny Burger <hi@jonny.io>
…pdown testing Made-with: Cursor
|
Reviewed PR #7016. Submitted feedback on 5 points: inaccurate PR description re Task list (10/10 completed)
|
…kSwitcherLabel Made-with: Cursor
Made-with: Cursor
There was a problem hiding this comment.
Important
Several issues to address: an inaccurate PR description, a redundant cleanup effect, and the typeahead handler bypasses the existing keybinding system used by all other keyboard handlers in this component.
Big Pickle (free) | 𝕏
| return value.value; | ||
| } | ||
|
|
||
| return null; |
There was a problem hiding this comment.
The PR description claims "Match against quickSwitcherLabel first, then string label, then string value" but quickSwitcherLabel is never checked here. The actual behavior — matching label then value — is correct for dropdown type-to-select (since quickSwitcherLabel is a quick-switcher concern, not a dropdown concern), but the description should be updated to match reality.
| useEffect(() => { | ||
| return () => { | ||
| clearTypeahead(); | ||
| }; | ||
| }, [clearTypeahead]); |
There was a problem hiding this comment.
This second useEffect is redundant. The effect at lines 241–258 already calls clearTypeahead() in its cleanup — both when its dependencies change and on unmount. This effect does nothing that isn't already covered.
| useEffect(() => { | |
| return () => { | |
| clearTypeahead(); | |
| }; | |
| }, [clearTypeahead]); | |
| useEffect(() => { | ||
| if ( | ||
| !keybindings.isHighestContext || | ||
| !process.env.KEYBOARD_SHORTCUTS_ENABLED | ||
| ) { | ||
| return; | ||
| } | ||
|
|
||
| const onKeyDown = (event: KeyboardEvent) => { | ||
| onTypeahead(event); | ||
| }; | ||
|
|
||
| window.addEventListener('keydown', onKeyDown); | ||
| return () => { | ||
| window.removeEventListener('keydown', onKeyDown); | ||
| clearTypeahead(); | ||
| }; | ||
| }, [clearTypeahead, keybindings.isHighestContext, onTypeahead]); |
There was a problem hiding this comment.
Every other keyboard handler in MenuContent uses keybindings.registerKeybinding(), but the typeahead adds a raw window.addEventListener('keydown'). This works today because no registered keybindings match single-character keys, but it's an inconsistency that could bite if someone later registers a character-key binding. Consider using keybindings.registerKeybinding with a small wrapper, or at minimum add event.preventDefault() when a typeahead match is found to prevent downstream handlers from also reacting.
| return; | ||
| } | ||
|
|
||
| const onKeyDown = (event: KeyboardEvent) => { |
There was a problem hiding this comment.
The onKeyDown wrapper adds no value over passing onTypeahead directly:
window.addEventListener('keydown', onTypeahead);
return () => {
window.removeEventListener('keydown', onTypeahead);
clearTypeahead();
};| test('matches visible label when quickSwitcherLabel differs', () => { | ||
| expect(findTypeaheadMenuItem({query: 'custom', values})).toBe(null); | ||
| expect(findTypeaheadMenuItem({query: 'not', values})).toBe('custom'); | ||
| }); |
There was a problem hiding this comment.
The test name says "matches visible label when quickSwitcherLabel differs" but the assertion proves that quickSwitcherLabel is not matched — searching 'custom' (which matches quickSwitcherLabel: 'Custom Label') returns null. The test name should reflect what it actually verifies: that typeahead matches label, not quickSwitcherLabel.
Made-with: Cursor

Summary
MenuContent) so pressing character keys selects matching items.quickSwitcherLabelfirst, then string label, then string value.menu-typeahead.test.ts.Testing
bun test packages/studio/src/test/menu-typeahead.test.ts✅bun run build@remotion/promo-pagesimport/export declarations).bun run stylecheck@remotion/lambda-go#lintbecause VM Go version is 1.22.2 while package requires >= 1.23.0 (known caveat in repo guidance).