fix(app): show keybind tooltips on prompt input controls (#37824)

This commit is contained in:
Rahul A Mistry 2026-07-20 05:52:38 +05:30 committed by GitHub
parent 67caf894e0
commit 7985c2066a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 54 additions and 39 deletions

View file

@ -60,6 +60,8 @@ export function PromptInputV2Composer(props: PromptInputV2ComposerProps) {
controller={props.controller} controller={props.controller}
borderUnderlay={props.borderUnderlay} borderUnderlay={props.borderUnderlay}
class={props.class} class={props.class}
attachKeybind={command.keybindParts("file.attach")}
attachShortcut={command.keybind("file.attach")}
modelControl={ modelControl={
<PromptInputV2ModelControl <PromptInputV2ModelControl
loading={props.controller.model.loading} loading={props.controller.model.loading}
@ -451,12 +453,14 @@ export function usePromptInputV2Controller(props: PromptInputV2ControllerProps):
options: () => props.controls.agents.options.map((name) => ({ id: name, label: name })), options: () => props.controls.agents.options.map((name) => ({ id: name, label: name })),
current: () => props.controls.agents.current, current: () => props.controls.agents.current,
onSelect: props.controls.agents.select, onSelect: props.controls.agents.select,
keybind: () => command.keybindParts("agent.cycle"),
} }
: undefined, : undefined,
variant: { variant: {
options: () => variants().map((value) => ({ id: value, label: value })), options: () => variants().map((value) => ({ id: value, label: value })),
current: () => props.controls.model.selection.variant.current() ?? "default", current: () => props.controls.model.selection.variant.current() ?? "default",
onSelect: (value) => props.controls.model.selection.variant.set(value === "default" ? undefined : value), onSelect: (value) => props.controls.model.selection.variant.set(value === "default" ? undefined : value),
keybind: () => command.keybindParts("model.variant.cycle"),
}, },
submit: { submit: {
stopping, stopping,

View file

@ -39,6 +39,8 @@ export type PromptInputV2Props = {
borderUnderlay?: boolean borderUnderlay?: boolean
class?: string class?: string
modelControl?: JSX.Element modelControl?: JSX.Element
attachKeybind?: string[]
attachShortcut?: string
} }
export function PromptInputV2(props: PromptInputV2Props) { export function PromptInputV2(props: PromptInputV2Props) {
@ -197,9 +199,9 @@ export function PromptInputV2(props: PromptInputV2Props) {
<PromptInputV2AddMenu <PromptInputV2AddMenu
disabled={state.mode === "shell"} disabled={state.mode === "shell"}
title="Add images and files" title="Add images and files"
keybind={["Mod", "U"]} keybind={props.attachKeybind ?? ["Mod", "U"]}
attachLabel="Images and files" attachLabel="Images and files"
attachShortcut="Mod+U" attachShortcut={props.attachShortcut ?? "Mod+U"}
commandsLabel="Commands" commandsLabel="Commands"
contextLabel="Context" contextLabel="Context"
shellLabel="Shell command" shellLabel="Shell command"
@ -233,7 +235,11 @@ export function PromptInputV2(props: PromptInputV2Props) {
<Show when={view.variant}> <Show when={view.variant}>
{(control) => ( {(control) => (
<Show when={control().options().length > 1}> <Show when={control().options().length > 1}>
<PromptInputV2ConfiguredSelect title="Choose model variant" control={control()} /> <PromptInputV2ConfiguredSelect
title="Choose model variant"
keybind={["Shift", "Mod", "D"]}
control={control()}
/>
</Show> </Show>
)} )}
</Show> </Show>
@ -512,7 +518,7 @@ function PromptInputV2ConfiguredSelect(props: {
return ( return (
<PromptInputV2Select <PromptInputV2Select
title={props.title} title={props.title}
keybind={props.keybind} keybind={props.control.keybind?.() ?? props.keybind}
options={props.control.options()} options={props.control.options()}
current={current()} current={current()}
currentIcon={ currentIcon={
@ -536,13 +542,21 @@ export function PromptInputV2Select(props: {
onSelect: (id: string) => void onSelect: (id: string) => void
}) { }) {
return ( return (
<TooltipV2
placement="top"
value={
<>
{props.title}
<KeybindV2 keys={props.keybind ?? []} variant="neutral" />
</>
}
>
<MenuV2 gutter={6} modal={false} placement="top-start" onOpenChange={props.onOpenChange}> <MenuV2 gutter={6} modal={false} placement="top-start" onOpenChange={props.onOpenChange}>
<MenuV2.Trigger <MenuV2.Trigger
as={ButtonV2} as={ButtonV2}
variant="ghost-muted" variant="ghost-muted"
size="normal" size="normal"
class={`max-w-[220px] justify-start ![font-weight:440] ${props.class ?? ""}`} class={`max-w-[220px] justify-start ![font-weight:440] ${props.class ?? ""}`}
title={keybindTitle(props.title, props.keybind)}
> >
{props.currentIcon} {props.currentIcon}
<span class="truncate capitalize leading-5"> <span class="truncate capitalize leading-5">
@ -566,6 +580,7 @@ export function PromptInputV2Select(props: {
</MenuV2.Content> </MenuV2.Content>
</MenuV2.Portal> </MenuV2.Portal>
</MenuV2> </MenuV2>
</TooltipV2>
) )
} }
@ -688,8 +703,3 @@ function PromptInputV2SuggestionIcon(props: { item: PromptInputV2Suggestion }) {
/> />
) )
} }
function keybindTitle(label: string, keybind?: string[]) {
if (!keybind?.length) return label
return `${label} (${keybind.join("+")})`
}

View file

@ -23,6 +23,7 @@ export type PromptInputV2SelectControl = {
options: Accessor<PromptInputV2Option[]> options: Accessor<PromptInputV2Option[]>
current: Accessor<string> current: Accessor<string>
onSelect: (id: string) => void onSelect: (id: string) => void
keybind?: Accessor<string[]>
} }
export type PromptInputV2ViewConfig = { export type PromptInputV2ViewConfig = {