Explorar o código

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

Rahul A Mistry hai 1 mes
pai
achega
7985c2066a

+ 4 - 0
packages/app/src/components/prompt-input-v2.tsx

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

+ 49 - 39
packages/session-ui/src/v2/components/prompt-input/index.tsx

@@ -39,6 +39,8 @@ export type PromptInputV2Props = {
   borderUnderlay?: boolean
   class?: string
   modelControl?: JSX.Element
+  attachKeybind?: string[]
+  attachShortcut?: string
 }
 
 export function PromptInputV2(props: PromptInputV2Props) {
@@ -197,9 +199,9 @@ export function PromptInputV2(props: PromptInputV2Props) {
             <PromptInputV2AddMenu
               disabled={state.mode === "shell"}
               title="Add images and files"
-              keybind={["Mod", "U"]}
+              keybind={props.attachKeybind ?? ["Mod", "U"]}
               attachLabel="Images and files"
-              attachShortcut="Mod+U"
+              attachShortcut={props.attachShortcut ?? "Mod+U"}
               commandsLabel="Commands"
               contextLabel="Context"
               shellLabel="Shell command"
@@ -233,7 +235,11 @@ export function PromptInputV2(props: PromptInputV2Props) {
             <Show when={view.variant}>
               {(control) => (
                 <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>
@@ -512,7 +518,7 @@ function PromptInputV2ConfiguredSelect(props: {
   return (
     <PromptInputV2Select
       title={props.title}
-      keybind={props.keybind}
+      keybind={props.control.keybind?.() ?? props.keybind}
       options={props.control.options()}
       current={current()}
       currentIcon={
@@ -536,36 +542,45 @@ export function PromptInputV2Select(props: {
   onSelect: (id: string) => void
 }) {
   return (
-    <MenuV2 gutter={6} modal={false} placement="top-start" onOpenChange={props.onOpenChange}>
-      <MenuV2.Trigger
-        as={ButtonV2}
-        variant="ghost-muted"
-        size="normal"
-        class={`max-w-[220px] justify-start ![font-weight:440] ${props.class ?? ""}`}
-        title={keybindTitle(props.title, props.keybind)}
-      >
-        {props.currentIcon}
-        <span class="truncate capitalize leading-5">
-          {props.options.find((option) => option.id === props.current)?.label ?? props.current}
-        </span>
-        <span class="-ml-0.5 -mr-1 flex shrink-0">
-          <IconV2 name="chevron-down" />
-        </span>
-      </MenuV2.Trigger>
-      <MenuV2.Portal>
-        <MenuV2.Content>
-          <MenuV2.RadioGroup value={props.current} onChange={props.onSelect}>
-            <For each={props.options}>
-              {(option) => (
-                <MenuV2.RadioItem value={option.id} class="capitalize" closeOnSelect>
-                  {option.label}
-                </MenuV2.RadioItem>
-              )}
-            </For>
-          </MenuV2.RadioGroup>
-        </MenuV2.Content>
-      </MenuV2.Portal>
-    </MenuV2>
+    <TooltipV2
+      placement="top"
+      value={
+        <>
+          {props.title}
+          <KeybindV2 keys={props.keybind ?? []} variant="neutral" />
+        </>
+      }
+    >
+      <MenuV2 gutter={6} modal={false} placement="top-start" onOpenChange={props.onOpenChange}>
+        <MenuV2.Trigger
+          as={ButtonV2}
+          variant="ghost-muted"
+          size="normal"
+          class={`max-w-[220px] justify-start ![font-weight:440] ${props.class ?? ""}`}
+        >
+          {props.currentIcon}
+          <span class="truncate capitalize leading-5">
+            {props.options.find((option) => option.id === props.current)?.label ?? props.current}
+          </span>
+          <span class="-ml-0.5 -mr-1 flex shrink-0">
+            <IconV2 name="chevron-down" />
+          </span>
+        </MenuV2.Trigger>
+        <MenuV2.Portal>
+          <MenuV2.Content>
+            <MenuV2.RadioGroup value={props.current} onChange={props.onSelect}>
+              <For each={props.options}>
+                {(option) => (
+                  <MenuV2.RadioItem value={option.id} class="capitalize" closeOnSelect>
+                    {option.label}
+                  </MenuV2.RadioItem>
+                )}
+              </For>
+            </MenuV2.RadioGroup>
+          </MenuV2.Content>
+        </MenuV2.Portal>
+      </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("+")})`
-}

+ 1 - 0
packages/session-ui/src/v2/components/prompt-input/interaction.ts

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