Skip to content

Update IconButton to support multiple keybinding hints#7623

Open
Copilot wants to merge 8 commits intomainfrom
copilot/update-iconbutton-keybindinghint
Open

Update IconButton to support multiple keybinding hints#7623
Copilot wants to merge 8 commits intomainfrom
copilot/update-iconbutton-keybindinghint

Conversation

Copy link
Contributor

Copilot AI commented Mar 4, 2026

Extends IconButton's keybindingHint prop to accept an array of strings in addition to a single string. Multiple keybinding hints are rendered joined with "or" (e.g., ["Mod+B", "Control+B"] renders as ⌘B or ⌃B). An empty array is treated the same as omitting the prop entirely.

Changelog

New

  • IconButton.keybindingHint now accepts string | string[]. When an array is provided, each hint is rendered as a KeybindingHint component with " or " separators between them.
  • The accessible label string joins multiple hints with " or " (e.g., "Bold (command b or control b)").

Changed

  • TooltipProps.keybindingHint widened from string to string | string[] to support the array form (IconButton passes this value through to Tooltip).
  • An empty array passed to keybindingHint produces no hint rendering — keybindingHint defaults to a stable module-level emptyKeybindingHints constant in Tooltip's prop destructuring, and .length checks are used in conditionals throughout.
  • When multiple keybinding hints are shown, extra left margin (var(--base-size-8) vs var(--base-size-6)) is applied between the label text and the hint badges to avoid crowding.
  • keybindingHint type corrected to string | string[] in both Tooltip.docs.json and IconButton.docs.json.

Removed

Rollout strategy

  • Patch release
  • Minor release
  • Major release; if selected, include a written rollout or migration plan
  • None; if selected, include a brief description as to why

Testing & Reviewing

New Storybook story: Components/IconButton/Features — MultipleKeybindingHints demonstrates the array form.

New unit tests cover:

  • Accessible label includes all hints joined by " or "
  • Two KeybindingHint elements are rendered with a " or " separator
  • An empty array produces no keybinding hint output

Merge checklist


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@changeset-bot
Copy link

changeset-bot bot commented Mar 4, 2026

🦋 Changeset detected

Latest commit: c1bcdf4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@primer/react Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Co-authored-by: iansan5653 <2294248+iansan5653@users.noreply.github.com>
Comment on lines +277 to +281
const keybindingHints = keybindingHint
? Array.isArray(keybindingHint)
? keybindingHint
: [keybindingHint]
: undefined
Copy link
Contributor

Choose a reason for hiding this comment

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

@copilot this should be undefined if keybindingHint is an empty array so that it doesn't configure extra properties for an empty hint

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 6818499. An empty array now resolves to undefined, preventing any keybinding hint rendering or extra configuration.

Copilot AI and others added 2 commits March 4, 2026 19:58
Co-authored-by: iansan5653 <2294248+iansan5653@users.noreply.github.com>
Co-authored-by: iansan5653 <2294248+iansan5653@users.noreply.github.com>
Copilot AI changed the title [WIP] Update IconButton to support multiple keybinding hints Update IconButton to support multiple keybinding hints Mar 4, 2026
@github-actions github-actions bot added the integration-tests: recommended This change needs to be tested for breaking changes. See https://arc.net/l/quote/tdmpakpm label Mar 4, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

⚠️ Action required

👋 Hi, this pull request contains changes to the source code that github/github-ui depends on. If you are GitHub staff, test these changes with github/github-ui using the integration workflow. Or, apply the integration-tests: skipped manually label to skip these checks.

@iansan5653 iansan5653 marked this pull request as ready for review March 4, 2026 20:55
@iansan5653 iansan5653 requested a review from a team as a code owner March 4, 2026 20:55
@iansan5653 iansan5653 requested review from TylerJDev and Copilot March 4, 2026 20:55
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Extends IconButton/TooltipV2 keybinding hint support to allow multiple shortcut hints, rendering them as multiple KeybindingHint elements separated by " or ", and updating the accessible label accordingly.

Changes:

  • Widened keybindingHint types to accept string | string[] (and passed through TooltipV2).
  • Updated TooltipV2 rendering + accessible label generation to handle multiple hints with " or " separators, treating [] as no hint.
  • Added Storybook coverage and unit tests for the multiple-hints behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/react/src/TooltipV2/Tooltip.tsx Normalizes keybindingHint into a list, updates visible and VisuallyHidden rendering to support multiple hints.
packages/react/src/TooltipV2/tests/Tooltip.test.tsx Adds tests for multi-hint accessible name, rendering, and empty-array behavior.
packages/react/src/Button/types.ts Updates IconButtonProps.keybindingHint type to `string
packages/react/src/Button/IconButton.features.stories.tsx Adds a Storybook feature story demonstrating multiple keybinding hints.
.changeset/iconbutton-keybinding-hint-array.md Declares a minor release for the new IconButton.keybindingHint array support.

@primer-integration
Copy link

👋 Hi from github/github-ui! Your integration PR is ready: https://github.com/github/github-ui/pull/15156

Copy link
Contributor

@iansan5653 iansan5653 left a comment

Choose a reason for hiding this comment

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

@copilot when there multiple keybinding hints, we need more space between the main label text and the hints or it gets too crowded and confusing

screenshot showing how the hints are too close to the label text

add some more space, but only when there's more than one hint to show

const hasAriaLabel = 'aria-label' in rest

// Normalize keybindingHint to an array for uniform rendering, treating empty arrays as undefined
const keybindingHints = keybindingHint
Copy link
Contributor

Choose a reason for hiding this comment

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

I actually think it would be simpler to allow empty arrays and just check for keybindingHint.length in the later conditionals

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in d0bf446. keybindingHints now normalizes to [] for falsy/empty-array inputs, and the later conditionals use .length === 0 / .length > 0 checks.

@primer-integration
Copy link

Integration test results from github/github-ui:

Failed  CI   Failed
Passed  VRT   Passed
Passed  Projects   Passed

CI check runs linting, type checking, and unit tests. Check the workflow logs for specific failures.

Need help? If you believe this failure is unrelated to your changes, please reach out to the Primer team for assistance.

…iple hints

Co-authored-by: iansan5653 <2294248+iansan5653@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 4, 2026

@copilot when there multiple keybinding hints, we need more space between the main label text and the hints or it gets too crowded and confusing

<img src="https://github.com/user-attachments/assets/...

Added in d0bf446. A HasMultipleHints CSS class applies margin-left: var(--base-size-8) (vs the single-hint var(--base-size-6)) on the hint container when there are 2+ hints, giving more breathing room between the label and the keybinding badges.

tooltipDirection?: TooltipDirection
/** @deprecated Use `keybindingHint` instead. */
keyshortcuts?: string
keybindingHint?: string
Copy link
Member

Choose a reason for hiding this comment

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

correct type in iconbutton.docs.json as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 464c69d. Updated keybindingHint type in IconButton.docs.json from "string" to "string | string[]" and updated the description to mention the array form.

text: string
type?: 'label' | 'description'
keybindingHint?: KeybindingHintProps['keys']
keybindingHint?: KeybindingHintProps['keys'] | Array<KeybindingHintProps['keys']>
Copy link
Member

Choose a reason for hiding this comment

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

correct type on tooltip.docs.json as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 464c69d. Updated keybindingHint type in Tooltip.docs.json from "string" to "string | string[]" and updated the description accordingly.

Comment on lines +276 to +277
// Normalize keybindingHint to an array for uniform rendering
const keybindingHints = keybindingHint ? (Array.isArray(keybindingHint) ? keybindingHint : [keybindingHint]) : []
Copy link
Member

Choose a reason for hiding this comment

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

is it possible to default keyBindingHint to empty array to simplify this and make it more readable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 464c69d. keybindingHint now defaults to [] in the destructuring, so the normalization simplifies to just Array.isArray(keybindingHint) ? keybindingHint : [keybindingHint].

Copy link
Contributor

Choose a reason for hiding this comment

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

@copilot extract the empty array default out to a constant, like:

const emptyArray = []

function Tooltip({keybindingHint = emptyArray}) {...}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in c1bcdf4. Added const emptyKeybindingHints: Array<KeybindingHintProps['keys']> = [] at module level and updated the default to reference it.

@francinelucca
Copy link
Member

@copilot implement requested changes

@github-actions github-actions bot requested a deployment to storybook-preview-7623 March 5, 2026 03:24 Abandoned
…ion with default prop

Co-authored-by: francinelucca <40550942+francinelucca@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 5, 2026

@copilot implement requested changes

All three changes implemented in 464c69d: updated keybindingHint type to string | string[] in both Tooltip.docs.json and IconButton.docs.json, and simplified the normalization by defaulting keybindingHint to [] in the prop destructuring.

@iansan5653
Copy link
Contributor

iansan5653 commented Mar 5, 2026

nice, thanks for catching that! I always forget that the docs aren't powered by TypeScript types

…ble reference

Co-authored-by: iansan5653 <2294248+iansan5653@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

integration-tests: recommended This change needs to be tested for breaking changes. See https://arc.net/l/quote/tdmpakpm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants