| author | |
| committer | |
| log | a38cac81d82b82a6967eaf8cb90ed2770c514f3c |
| tree | ff88fecf0cb1c1fce8fadc4f5384894ec889d35a |
| parent | 3bc4fdf05b6b748a7b506c81dc125f3504f35278 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Sy-D <8460326+Sy-D@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: codex <codex@users.noreply.github.com>3 files changed, 51 insertions(+), 4 deletions(-)
apps/web/src/components/CommandPalette.logic.test.ts+30| ... | @@ -2,6 +2,7 @@ import { describe, expect, it, vi } from "vite-plus/test"; | ... | @@ -2,6 +2,7 @@ import { describe, expect, it, vi } from "vite-plus/test"; |
| 2 | import { EnvironmentId, ProjectId, ProviderInstanceId, ThreadId } from "@t3tools/contracts"; | 2 | import { EnvironmentId, ProjectId, ProviderInstanceId, ThreadId } from "@t3tools/contracts"; |
| 3 | import type { Thread } from "../types"; | 3 | import type { Thread } from "../types"; |
| 4 | import { | 4 | import { |
| 5 | browseInputEndPaddingClass, | ||
| 5 | buildBrowseGroups, | 6 | buildBrowseGroups, |
| 6 | buildThreadActionItems, | 7 | buildThreadActionItems, |
| 7 | enumerateCommandPaletteItems, | 8 | enumerateCommandPaletteItems, |
| ... | @@ -10,6 +11,35 @@ import { | ... | @@ -10,6 +11,35 @@ import { |
| 10 | type CommandPaletteGroup, | 11 | type CommandPaletteGroup, |
| 11 | } from "./CommandPalette.logic"; | 12 | } from "./CommandPalette.logic"; |
| 12 | 13 | ||
| 14 | describe("browseInputEndPaddingClass", () => { | ||
| 15 | it("reserves the widest space for the create action", () => { | ||
| 16 | expect( | ||
| 17 | browseInputEndPaddingClass({ | ||
| 18 | willCreateProjectPath: true, | ||
| 19 | hasHighlightedBrowseItem: false, | ||
| 20 | }), | ||
| 21 | ).toContain("pe-38"); | ||
| 22 | }); | ||
| 23 | |||
| 24 | it("reserves space for the wider highlighted-item shortcut", () => { | ||
| 25 | expect( | ||
| 26 | browseInputEndPaddingClass({ | ||
| 27 | willCreateProjectPath: false, | ||
| 28 | hasHighlightedBrowseItem: true, | ||
| 29 | }), | ||
| 30 | ).toContain("pe-30"); | ||
| 31 | }); | ||
| 32 | |||
| 33 | it("keeps the compact reserve for the normal add action", () => { | ||
| 34 | expect( | ||
| 35 | browseInputEndPaddingClass({ | ||
| 36 | willCreateProjectPath: false, | ||
| 37 | hasHighlightedBrowseItem: false, | ||
| 38 | }), | ||
| 39 | ).toContain("pe-24"); | ||
| 40 | }); | ||
| 41 | }); | ||
| 42 | |||
| 13 | describe("reduceCommandPaletteUiState", () => { | 43 | describe("reduceCommandPaletteUiState", () => { |
| 14 | const closedState = { open: false, mode: "command", openIntent: null } as const; | 44 | const closedState = { open: false, mode: "command", openIntent: null } as const; |
| 15 | 45 |
apps/web/src/components/CommandPalette.logic.ts+13| ... | @@ -15,6 +15,19 @@ export const RECENT_THREAD_LIMIT = 12; | ... | @@ -15,6 +15,19 @@ export const RECENT_THREAD_LIMIT = 12; |
| 15 | export const ITEM_ICON_CLASS = "size-4 text-icon-muted"; | 15 | export const ITEM_ICON_CLASS = "size-4 text-icon-muted"; |
| 16 | export const ADDON_ICON_CLASS = "size-4"; | 16 | export const ADDON_ICON_CLASS = "size-4"; |
| 17 | 17 | ||
| 18 | export function browseInputEndPaddingClass(input: { | ||
| 19 | readonly willCreateProjectPath: boolean; | ||
| 20 | readonly hasHighlightedBrowseItem: boolean; | ||
| 21 | }): string { | ||
| 22 | if (input.willCreateProjectPath) { | ||
| 23 | return "*:data-[slot=autocomplete-input]:pe-38!"; | ||
| 24 | } | ||
| 25 | if (input.hasHighlightedBrowseItem) { | ||
| 26 | return "*:data-[slot=autocomplete-input]:pe-30!"; | ||
| 27 | } | ||
| 28 | return "*:data-[slot=autocomplete-input]:pe-24!"; | ||
| 29 | } | ||
| 30 | |||
| 18 | /** | 31 | /** |
| 19 | * The global search overlay hosts three mutually exclusive surfaces: the | 32 | * The global search overlay hosts three mutually exclusive surfaces: the |
| 20 | * command palette (⌘K), the project file picker (⌘P), and project content | 33 | * command palette (⌘K), the project file picker (⌘P), and project content |
apps/web/src/components/CommandPalette.tsx+8-4| ... | @@ -98,6 +98,7 @@ import { | ... | @@ -98,6 +98,7 @@ import { |
| 98 | } from "../wslPaths"; | 98 | } from "../wslPaths"; |
| 99 | import { | 99 | import { |
| 100 | ADDON_ICON_CLASS, | 100 | ADDON_ICON_CLASS, |
| 101 | browseInputEndPaddingClass, | ||
| 101 | buildBrowseGroups, | 102 | buildBrowseGroups, |
| 102 | buildProjectActionItems, | 103 | buildProjectActionItems, |
| 103 | buildRootGroups, | 104 | buildRootGroups, |
| ... | @@ -2345,13 +2346,16 @@ function OpenCommandPaletteDialog(props: { | ... | @@ -2345,13 +2346,16 @@ function OpenCommandPaletteDialog(props: { |
| 2345 | footerTrailing={footerTrailing} | 2346 | footerTrailing={footerTrailing} |
| 2346 | inputAccessory={inputAccessory} | 2347 | inputAccessory={inputAccessory} |
| 2347 | inputProps={{ | 2348 | inputProps={{ |
| 2349 | // The submit button is absolutely positioned over the field, so the | ||
| 2350 | // inner input must reserve enough room for the full action label. | ||
| 2348 | className: | 2351 | className: |
| 2349 | addProjectCloneFlow?.step === "repository" | 2352 | addProjectCloneFlow?.step === "repository" |
| 2350 | ? "pe-32" | 2353 | ? "*:data-[slot=autocomplete-input]:pe-32!" |
| 2351 | : isBrowsing | 2354 | : isBrowsing |
| 2352 | ? willCreateProjectPath | 2355 | ? browseInputEndPaddingClass({ |
| 2353 | ? "pe-36" | 2356 | willCreateProjectPath, |
| 2354 | : "pe-16" | 2357 | hasHighlightedBrowseItem, |
| 2358 | }) | ||
| 2355 | : undefined, | 2359 | : undefined, |
| 2356 | placeholder: inputPlaceholder, | 2360 | placeholder: inputPlaceholder, |
| 2357 | wrapperClassName: isSubmenu | 2361 | wrapperClassName: isSubmenu |