Skip to content

Conversation

angelplusultra
Copy link
Contributor

@angelplusultra angelplusultra commented Sep 18, 2025

Pull Request Type

  • ✨ feat
  • πŸ› fix
  • ♻️ refactor
  • πŸ’„ style
  • πŸ”¨ chore
  • πŸ“ docs

Relevant Issues

resolves #2019

What is in this change?

This PR introduces keyboard navigation for the slash command selection popup.

Users can now:

  • Navigate options using the Up and Down arrow keys.
  • Select a command by pressing Enter.
  • Close the popup by pressing Escape.

Additional Information

Developer Validations

  • I ran yarn lint from the root of the repo & committed changes
  • Relevant documentation has been updated
  • I have tested my code functionality
  • Docker build succeeds locally

@angelplusultra angelplusultra linked an issue Sep 18, 2025 that may be closed by this pull request
@angelplusultra angelplusultra changed the title 2019 slash command keyboard selection Introduce keyboard (Up/Down/Enter) selection for slash commands Sep 18, 2025
@angelplusultra angelplusultra changed the title Introduce keyboard (Up/Down/Enter) selection for slash commands Introduce keyboard (Up/Down/Enter/Escape) selection for slash commands Sep 18, 2025
@timothycarambat timothycarambat self-assigned this Sep 19, 2025
@timothycarambat timothycarambat added the PR:needs review Needs review by core team label Sep 19, 2025
Copy link
Member

@timothycarambat timothycarambat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a heavy code review atm, but current feedback:

  • If i click on the slash command button [/] in the prompt box, keyboard nav does not work
  • Keyboard nav does work if I type /
  • If I type / nav down one or more, click "Add new preset" and add it. Then i type / again, my new preset is unreachable via keyboard nav (because qty state is out of sync probably). Does work on page reload.

Ideally, either way the modal pops up, this functionality for navigation becomes usable and is cleaned up and unmounted when the modal is dismissed.

Instead of using JS state, you could probably more easily do this with DOM manipulation while still using events. This would make counting results on the fly easy, work on all cases, and when pressing enter all the logic we have around clicking the item would take over - simplifying things a lot (maybe?) ;)

return (
<>
{presets.map((preset) => (
{presets.map((preset, index) => (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not do highlight operation with preset.id?

<button
onClick={onUse}
className="border-none w-full hover:cursor-pointer hover:bg-theme-action-menu-item-hover px-2 py-2 rounded-xl flex flex-row justify-start items-center relative"
className={`border-none w-full hover:cursor-pointer hover:bg-theme-action-menu-item-hover px-2 py-2 rounded-xl flex flex-row justify-start items-center relative ${highlighted ? "bg-theme-action-menu-item-hover" : ""}`}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ‘

Comment on lines 40 to 41
highlightedSlashCommand,
setHighlightedSlashCommand,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are passing the state getter and setter, it could be scoped too high and might make more sense inside of this component.

export default function ResetCommand({
setShowing,
sendCommand,
highlightedSlashCommand,
Copy link
Member

@timothycarambat timothycarambat Sep 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would make more sense as a prop like isHighlighted, no?

Comment on lines 23 to 26
window.addEventListener(
"selectHighlightedSlashCommand",
handleSelectHighlighted
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For events, we often export them as consts so we can update the string of an event name without a lot of LOC. example with attachment event handling

const [highlightedSlashCommand, setHighlightedSlashCommand] = useState(1);
const formRef = useRef(null);
const textareaRef = useRef(null);
const [_, setFocused] = useState(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed?

if (input === "/") setShowSlashCommand(true);
if (input === "/") {
setShowSlashCommand(true);
setHighlightedSlashCommand(0); // Start with reset command highlighted
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this state was managed at the component level for slash commands - you would not need to do this and it would be handled on mount of SlashCommand modal

if (event.keyCode === 13 && !event.shiftKey) {
event.preventDefault();
// Don't submit if slash commands are showing - let the slash command handler take care of it
if (showSlashCommand) return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch

handlePasteEvent(e);
}}
required={true}
onFocus={() => setFocused(true)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed?

…Fix bug where slash command navigation wasn't working when triggered with slash command button | Fix bug with overflowed slash commands not being scrolled into view on navigation | Refactored slash command selection logic from custom event emission to direct handling in handleKeyDown fn.
@angelplusultra
Copy link
Contributor Author

Not a heavy code review atm, but current feedback:

* If i click on the slash command button `[/]` in the prompt box, keyboard nav does not work

* Keyboard nav does work if I type `/`

* If I type `/` nav down one or more, click "Add new preset" and add it. Then i type `/` again, my new preset is unreachable via keyboard nav (because qty state is out of sync probably). Does work on page reload.

Ideally, either way the modal pops up, this functionality for navigation becomes usable and is cleaned up and unmounted when the modal is dismissed.

Instead of using JS state, you could probably more easily do this with DOM manipulation while still using events. This would make counting results on the fly easy, work on all cases, and when pressing enter all the logic we have around clicking the item would take over - simplifying things a lot (maybe?) ;)

Fixes in 3e85053

  1. I abstracted most of the logic related to slash commands into the custom hook useSlashCommands to keep the PromptInput comp as light as possible.
  2. I fixed the bug when the slash command popup would be triggered via the slash command button and wouldn't respond keyboard navigation/selection
  3. I also found a bug in the process where if a user had enough slash commands to cause vertical overflow, out of view slash commands would be highlighted but not visible, I added scroll-into-view logic when a slash command is highlighted.
  4. The bug where newly created slash commands would not be highlightable/selectable is now fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR:needs review Needs review by core team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT]: Enhanced Keyboard Navigation for Preset Prompts Menu

2 participants