Skip to content

feat(cmdk): Show hotkey label in search button tooltip for command palette#113382

Merged
JonasBa merged 5 commits into
masterfrom
jb/ref/cmdk-hotkey-label
Apr 20, 2026
Merged

feat(cmdk): Show hotkey label in search button tooltip for command palette#113382
JonasBa merged 5 commits into
masterfrom
jb/ref/cmdk-hotkey-label

Conversation

@JonasBa

@JonasBa JonasBa commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

Update CMDK tooltip when feature is released
CleanShot 2026-04-18 at 05 54 18@2x

…lette

When an org has the cmd-k-supercharged feature, replace the generic
"Search support, docs and more" tooltip on the primary nav search button
with "Open command palette" and an inline ⌘K / Ctrl+K hotkey badge.

Adds a tooltipTitle prop (ReactNode) to PrimaryNavigationButton so the
tooltip content can differ from the aria-label without changing the
button's accessible name.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Apr 18, 2026
@JonasBa
JonasBa marked this pull request as ready for review April 20, 2026 16:05
@JonasBa
JonasBa requested a review from a team as a code owner April 20, 2026 16:05
{hasPageFrame ? (
<PrimaryNavigation.Button
label={t('Search support, docs and more')}
tooltipTitle={

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@cursoragent update this to instead override the label prop and remove tooltipTitle prop from the PrimaryNavigationButton component

@cursor cursor Bot Apr 20, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Perfect! The changes look good. Let me create a summary of what was accomplished:

Summary

I've successfully refactored the command palette search button to use the label prop instead of tooltipTitle as requested. Here's what changed:

Changes Made:

  1. Removed tooltipTitle prop from PrimaryNavigationButton component:

    • Deleted the tooltipTitle prop from the interface
    • Updated the Tooltip to use props.label directly
  2. Changed label prop type from string to React.ReactNode:

    • This allows passing JSX (like the hotkey label with Flex and Hotkey components)
    • Maintains backward compatibility with string labels
  3. Updated the search button in navigation.tsx:

    • Now conditionally passes the hotkey label directly to the label prop when the feature is enabled
    • Falls back to the simple string label when the feature is disabled
  4. Fixed aria-label handling:

    • Added logic to only set aria-label when the label is a string
    • This prevents invalid aria-label values when label contains JSX

Testing:

  • ✅ ESLint passes
  • ✅ TypeScript type checking passes
  • ✅ All pre-commit hooks pass
  • ✅ Changes committed and pushed to the branch

The implementation is cleaner now, with the tooltip content directly controlled by the label prop rather than having a separate tooltipTitle override prop.

Open in Web Open in Cursor 

Comment thread static/app/views/navigation/navigation.tsx Outdated
- Remove tooltipTitle prop from PrimaryNavigationButton component
- Change label prop type from string to React.ReactNode
- Update search button to pass hotkey label directly to label prop
- Handle aria-label when label is not a string

Co-authored-by: Jonas <JonasBa@users.noreply.github.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 024a379. Configure here.

? undefined
: typeof props.label === 'string'
? props.label
: undefined;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Missing aria-label when label is JSX element

Medium Severity

When cmd-k-supercharged is enabled, label is a Flex JSX element (not a string), so ariaLabel resolves to undefined on desktop. The button loses its accessible name entirely — screen readers won't be able to identify the search button. Previously, label was always a string so aria-label was always set. Since buttonProps explicitly omits aria-label, there's no alternative way to provide one.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 024a379. Configure here.

Comment on lines +270 to +275
const ariaLabel =
layout === 'mobile'
? undefined
: typeof props.label === 'string'
? props.label
: undefined;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bug: When cmd-k-supercharged feature is enabled, ariaLabel resolves to undefined on desktop, leaving the search button with no accessible name.
Severity: MEDIUM

Suggested Fix

Instead of returning undefined when the label is not a string, derive a plain-text fallback. For example: const ariaLabel = layout === 'mobile' ? undefined : typeof props.label === 'string' ? props.label : t('Open command palette');. Alternatively, accept a separate ariaLabel prop so callers can supply a string accessible name independent of the rich-content label.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: static/app/views/navigation/primary/components.tsx#L270-L275

Potential issue: In `PrimaryNavigationButton`, `ariaLabel` is computed as `undefined`
when `props.label` is not a string. When the `cmd-k-supercharged` feature flag is
active, `props.label` is a JSX `<Flex>` element (not a string), so `typeof props.label
=== 'string'` is `false` and `ariaLabel` becomes `undefined`. On desktop (`layout !==
'mobile'`), the button's `aria-label` attribute is therefore `undefined`. Since the
tooltip is also `disabled` on mobile, and the button has no visible text child on
desktop, this leaves the search/command-palette button with **no accessible name** at
all for screen-reader users on desktop when the feature is enabled — a regression from
the previous behavior where the string label was always passed as `aria-label`.

Did we get this right? 👍 / 👎 to inform future reviews.

Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
@JonasBa
JonasBa merged commit 46a8c02 into master Apr 20, 2026
64 checks passed
@JonasBa
JonasBa deleted the jb/ref/cmdk-hotkey-label branch April 20, 2026 22:26
@github-actions github-actions Bot locked and limited conversation to collaborators May 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants