feat: ai's attempt

This commit is contained in:
2026-02-28 16:28:07 +08:00
parent 6da2284ead
commit a4023c994f
7 changed files with 632 additions and 0 deletions
@@ -0,0 +1,78 @@
import { type Component, Show } from "solid-js";
import type { CompletionItem } from "./types";
export interface CommanderInputProps {
placeholder?: string;
inputValue: () => string;
onInput: (e: Event) => void;
onKeyDown: (e: KeyboardEvent) => void;
onFocus: () => void;
onBlur: () => void;
onSubmit: () => void;
showCompletions: () => boolean;
completions: () => CompletionItem[];
selectedCompletion: () => number;
onSelectCompletion: (idx: number) => void;
onAcceptCompletion: () => void;
}
export const CommanderInput: Component<CommanderInputProps> = (props) => {
return (
<div class="flex items-center border-b border-gray-300 bg-gray-50 px-3 py-2">
<span class="text-gray-500 mr-2">❯</span>
<input
type="text"
value={props.inputValue()}
onInput={props.onInput}
onKeyDown={props.onKeyDown}
onFocus={props.onFocus}
onBlur={props.onBlur}
placeholder={props.placeholder || "输入命令..."}
class="flex-1 bg-transparent outline-none text-gray-800"
/>
<button
onClick={props.onSubmit}
class="ml-2 px-3 py-1 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors"
>
执行
</button>
{/* 自动补全下拉框 */}
<Show when={props.showCompletions() && props.completions().length > 0}>
<div class="absolute z-10 w-full bg-white border border-gray-300 shadow-lg max-h-48 overflow-auto mt-1">
{props.completions().map((comp, idx) => (
<div
class={`px-3 py-2 cursor-pointer flex justify-between items-center ${
idx === props.selectedCompletion()
? "bg-blue-100"
: "hover:bg-gray-100"
}`}
onClick={() => {
props.onSelectCompletion(idx);
props.onAcceptCompletion();
}}
>
<div class="flex items-center gap-2">
<span
class={`text-xs px-1 rounded ${
comp.type === "command"
? "bg-purple-100 text-purple-700"
: comp.type === "option"
? "bg-green-100 text-green-700"
: "bg-gray-100 text-gray-700"
}`}
>
{comp.type}
</span>
<span class="font-mono text-sm">{comp.label}</span>
</div>
<Show when={comp.description}>
<span class="text-xs text-gray-500">{comp.description}</span>
</Show>
</div>
))}
</div>
</Show>
</div>
);
};