Skip to content

feat(query-bar): add resize handle and update execution key binding#7787

Open
bsradcliffe wants to merge 4 commits intomainfrom
feat/query-bar-resize-handle
Open

feat(query-bar): add resize handle and update execution key binding#7787
bsradcliffe wants to merge 4 commits intomainfrom
feat/query-bar-resize-handle

Conversation

@bsradcliffe
Copy link
Copy Markdown
Collaborator

Description

I inlined a resize handler to the query bar that CodeMirror does not natively support. It can be made DRY in the future if we need to extend resizing to other fields, but this is the only surface that needs to ingest it right now, so inlining made sense.

Additionally, we did not follow the standard key combination for executing a query. Most IDEs/editors use "Ctrl/Cmd+Enter" to fire a query. Instead, we used "Enter", which is typically reserved for creating new lines and is likely to help discoverability of the auto-growing "Find" input. This changes CodeMirror on the documents tab to match this industry paradigm.

CleanShot 2026-02-12 at 08 24 58@2x

Checklist

  • New tests and/or benchmarks are included
  • Documentation is changed or added
  • If this change updates the UI, screenshots/videos are added and a design review is requested
  • If this change could impact the load on the MongoDB cluster, please describe the expected and worst case impact
  • I have signed the MongoDB Contributor License Agreement (https://www.mongodb.com/legal/contributor-agreement)

Motivation and Context

https://mongodb.slack.com/archives/GDTJXPHD0/p1770825572519319

  • Bugfix
  • New feature
  • Dependency update
  • Misc

Open Questions

Dependents

Types of changes

  • Backport Needed
  • Patch (non-breaking change which fixes an issue)
  • Minor (non-breaking change which adds functionality)
  • Major (fix or feature that would cause existing functionality to change)

bsradcliffe and others added 2 commits February 11, 2026 11:58
…keybinding

Add a textarea-style resize grip to the filter field so users can
manually expand the editor beyond the 10-line auto-grow limit. The grip
uses role="separator" with ARIA value attributes for accessibility and
supports keyboard resizing (Arrow keys, Home/End).

Change the execute keybinding from Enter to Mod-Enter (Cmd+Enter on
macOS, Ctrl+Enter on Windows/Linux) so bare Enter inserts a newline,
aligning with the multiline editor model and the convention used by
other database query tools.

Co-authored-by: Cursor <cursoragent@cursor.com>
…y resized

Remove the maxLines cap that was incorrectly added to the editor when
the user has not resized. The original InlineEditor had no maxLines
prop and grew with content indefinitely — passing maxLines=10 broke
this by capping the editor at 10 lines with a scrollbar.

Co-authored-by: Cursor <cursoragent@cursor.com>
@bsradcliffe bsradcliffe requested a review from a team as a code owner February 12, 2026 16:29
@bsradcliffe bsradcliffe requested a review from lerouxb February 12, 2026 16:29
@bsradcliffe bsradcliffe changed the title fix/query bar resize handle fix(query-bar): add resize handle and update execution key binding Feb 12, 2026
@github-actions github-actions bot added the fix label Feb 12, 2026
@bsradcliffe bsradcliffe added no-title-validation Skips validation of PR titles (conventional commit adherence + JIRA ticket inclusion) no release notes Fix or feature not for release notes labels Feb 12, 2026
The separator role is treated as non-interactive by eslint-plugin-jsx-a11y,
causing no-noninteractive-element-interactions and no-noninteractive-tabindex
errors. Switch to slider role which is interactive and semantically fits
the resize handle with aria-valuenow/min/max. Also corrects orientation
to vertical to match the up/down resize behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
@bsradcliffe
Copy link
Copy Markdown
Collaborator Author

Me approving my own design review:
image

return [
{
key: 'Enter',
key: 'Mod-Enter',
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we have feedback from the Compass users that they are not happy with the current hotkey? Enter is a hotkey in compass for a long time (also why Shift+Enter is a new line and not just Enter), changing it as a drive-by if we don't have indicators that people are asking for this should probably be avoided

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It runs counter to what other tools do; Jakob's law. If users are used to Mod-Enter being the norm in their other tools, it's weird that we fight that. DataGrip, Databricks, Snowflake, Studio 3T, etc. eschew toward Mod-Enter. In any multi-line text area, I'd say most users expect Enter to create a newline. If Enter suddenly “runs” something, it’s easy to fire half-written queries by accident. Mod+Enter preserves the mental model: Enter edits, Mod+Enter executes.

This just maps to the user immediately saying "hey, I expect this input to act more like a multi-line input".

I understand this is changing something that has been in production for years, but I'd argue this is more a correcting alignment than a regression.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm sure I'm not the only person that doesn't like when apps change established patterns as a minor, drive-by, change for no apparent reason. It's ultimately a product / design decision, but "someone else dose it that way" doesn't sound like a solid decision making strategy if no-one asked us to change that or complained abut Enter not being an expected combination

const handleGripMouseDown = useCallback(() => {
const handleMouseMove = (event: MouseEvent) => {
setUserHeight((prev) =>
clampHeight((prev ?? MIN_EDITOR_HEIGHT) + event.movementY)
Copy link
Copy Markdown
Collaborator

@gribnoysup gribnoysup Feb 16, 2026

Choose a reason for hiding this comment

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

Style updates like that shouldn't go through React state (there are cases where it might be needed, but that's not one of them): this is firing too often and causing the whole React rendering cycle to kick off every time. Instead you should update the container element styles directly

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Understood, so just targeting inline styles? I definitely don't want to trigger re-renders because I've notice how laggy/degraded behavior becomes when that happens.

});

// Matches BaseEditor's default lineHeight prop value.
const EDITOR_LINE_HEIGHT = 16;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's avoid random magic numbers. You can define these in compass-edtor and re-export them from the package. That way the values are located in their logial place and will stay up to date if changed

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I'll take a look at that package and see the convention we currently follow. Thanks!


// Matches BaseEditor's default lineHeight prop value.
const EDITOR_LINE_HEIGHT = 16;
const MAX_EDITOR_LINES = 50;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Don't mind this being bigger than it is right now, but the current value is 10 and it was chosen as a good compromise between allowing more lines to show vs taking too much space on the screen. 50 allows you to do silly stuff like this (this is just one field):

Image

... and scrolling doesn't work when this happens

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I think 20 is as high as I'd want to go. This is a good edge case to consider, and I definitely don't want the input's growth making scrolling impossible to render.

ref={editorContainerRef}
style={
userHeight !== null
? { height: userHeight, minHeight: MIN_EDITOR_HEIGHT }
Copy link
Copy Markdown
Collaborator

@gribnoysup gribnoysup Feb 16, 2026

Choose a reason for hiding this comment

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

The way you implemented the resizing, it completely breaks the existing editor behavor that auto expands the editor when new lines are added

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Eh? Let me look again. I had noticed this myself but I was pretty sure I went back and fixed it. Checking it out again.

/>
{!disabled && optionName === 'filter' && (
<div
role="slider"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Slider usually support left and right in addition to up and down as a way to increase / decrease the value (it doesn't depend oon the orientation attr). I recommend reading through the documentation for the role where it's called out

onBlur={onBlur}
maxLines={maxLines}
/>
{!disabled && optionName === 'filter' && (
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why wouldn't you want to change the size if the editor is disabled for some reason?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

You mean if the primary filter input is disabled, why wouldn't you want to resize it? We typically disable all interactions with a field if that's the case.

Comment on lines +93 to +94
// Matches the LeafyGreen "Resize" glyph — two diagonal lines in the corner.
const resizeGripSvg = encodeURIComponent(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If this is for a real element we are rendering on the screen why are we inline hardcoding the icon instead of using leafygreen icon component? There doesn't seem to be a reason to set it as a background image compared to just using Icon component inside your slider container

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Wasn't sure what the convention was for slotting things within. Can definitely refactor to import the Resize icon here.

@bsradcliffe
Copy link
Copy Markdown
Collaborator Author

@gribnoysup will follow up with you here, but thanks for the guidance! This is exactly the type of feedback I'm looking for. I think design is going to be looking for more established touchpoints with engineering for stuff like this.

@gribnoysup gribnoysup added release notes and removed no release notes Fix or feature not for release notes labels Feb 18, 2026
@gribnoysup gribnoysup changed the title fix(query-bar): add resize handle and update execution key binding feat(query-bar): add resize handle and update execution key binding Feb 18, 2026
@gribnoysup gribnoysup added feat and removed fix labels Feb 18, 2026
@lerouxb lerouxb removed their request for review March 9, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat no-title-validation Skips validation of PR titles (conventional commit adherence + JIRA ticket inclusion) release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants