summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'packages/app/src/components')
-rw-r--r--packages/app/src/components/prompt-input.tsx80
1 files changed, 63 insertions, 17 deletions
diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx
index ba5a33a47..89169af0d 100644
--- a/packages/app/src/components/prompt-input.tsx
+++ b/packages/app/src/components/prompt-input.tsx
@@ -1,4 +1,5 @@
import { useFilteredList } from "@opencode-ai/ui/hooks"
+import { useSpring } from "@opencode-ai/ui/motion-spring"
import { createEffect, on, Component, Show, onCleanup, Switch, Match, createMemo, createSignal } from "solid-js"
import { createStore } from "solid-js/store"
import { createFocusSignal } from "@solid-primitives/active-element"
@@ -255,6 +256,11 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
pendingAutoAccept: false,
})
+ const buttonsSpring = useSpring(
+ () => (store.mode === "normal" ? 1 : 0),
+ { visualDuration: 0.2, bounce: 0 },
+ )
+
const commentCount = createMemo(() => {
if (store.mode === "shell") return 0
return prompt.context.items().filter((item) => !!item.comment?.trim()).length
@@ -1250,10 +1256,9 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
<div
aria-hidden={store.mode !== "normal"}
- class="flex items-center gap-1 transition-all duration-200 ease-out"
- classList={{
- "opacity-100 translate-y-0 scale-100 pointer-events-auto": store.mode === "normal",
- "opacity-0 translate-y-2 scale-95 pointer-events-none": store.mode !== "normal",
+ class="flex items-center gap-1"
+ style={{
+ "pointer-events": buttonsSpring() > 0.5 ? "auto" : "none",
}}
>
<TooltipKeybind
@@ -1266,6 +1271,11 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
type="button"
variant="ghost"
class="size-8 p-0"
+ style={{
+ opacity: buttonsSpring(),
+ transform: `scale(${0.95 + buttonsSpring() * 0.05})`,
+ filter: `blur(${(1 - buttonsSpring()) * 2}px)`,
+ }}
onClick={pick}
disabled={store.mode !== "normal"}
tabIndex={store.mode === "normal" ? undefined : -1}
@@ -1303,6 +1313,11 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
icon={working() ? "stop" : "arrow-up"}
variant="primary"
class="size-8"
+ style={{
+ opacity: buttonsSpring(),
+ transform: `scale(${0.95 + buttonsSpring() * 0.05})`,
+ filter: `blur(${(1 - buttonsSpring()) * 2}px)`,
+ }}
aria-label={working() ? language.t("prompt.action.stop") : language.t("prompt.action.send")}
/>
</Tooltip>
@@ -1355,14 +1370,21 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
<Show when={store.mode === "normal" || store.mode === "shell"}>
<DockTray attach="top">
<div class="px-1.75 pt-5.5 pb-2 flex items-center gap-2 min-w-0">
- <div class="flex items-center gap-1.5 min-w-0 flex-1">
- <Show when={store.mode === "shell"}>
- <div class="h-7 flex items-center gap-1.5 max-w-[160px] min-w-0" style={{ padding: "0 4px 0 8px" }}>
- <span class="truncate text-13-medium text-text-strong">{language.t("prompt.mode.shell")}</span>
- <div class="size-4 shrink-0" />
- </div>
- </Show>
- <Show when={store.mode === "normal"}>
+ <div class="flex items-center gap-1.5 min-w-0 flex-1 relative">
+ <div
+ class="h-7 flex items-center gap-1.5 max-w-[160px] min-w-0 absolute inset-y-0 left-0"
+ style={{
+ padding: "0 4px 0 8px",
+ opacity: 1 - buttonsSpring(),
+ transform: `scale(${0.95 + (1 - buttonsSpring()) * 0.05})`,
+ filter: `blur(${buttonsSpring() * 2}px)`,
+ "pointer-events": buttonsSpring() < 0.5 ? "auto" : "none",
+ }}
+ >
+ <span class="truncate text-13-medium text-text-strong">{language.t("prompt.mode.shell")}</span>
+ <div class="size-4 shrink-0" />
+ </div>
+ <div class="flex items-center gap-1.5 min-w-0 flex-1">
<TooltipKeybind
placement="top"
gutter={4}
@@ -1376,7 +1398,13 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
onSelect={local.agent.set}
class="capitalize max-w-[160px]"
valueClass="truncate text-13-regular"
- triggerStyle={{ height: "28px" }}
+ triggerStyle={{
+ height: "28px",
+ opacity: buttonsSpring(),
+ transform: `scale(${0.95 + buttonsSpring() * 0.05})`,
+ filter: `blur(${(1 - buttonsSpring()) * 2}px)`,
+ "pointer-events": buttonsSpring() > 0.5 ? "auto" : "none",
+ }}
variant="ghost"
/>
</TooltipKeybind>
@@ -1394,7 +1422,13 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
variant="ghost"
size="normal"
class="min-w-0 max-w-[320px] text-13-regular group"
- style={{ height: "28px" }}
+ style={{
+ height: "28px",
+ opacity: buttonsSpring(),
+ transform: `scale(${0.95 + buttonsSpring() * 0.05})`,
+ filter: `blur(${(1 - buttonsSpring()) * 2}px)`,
+ "pointer-events": buttonsSpring() > 0.5 ? "auto" : "none",
+ }}
onClick={() => dialog.show(() => <DialogSelectModelUnpaid />)}
>
<Show when={local.model.current()?.provider?.id}>
@@ -1423,7 +1457,13 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
triggerProps={{
variant: "ghost",
size: "normal",
- style: { height: "28px" },
+ style: {
+ height: "28px",
+ opacity: buttonsSpring(),
+ transform: `scale(${0.95 + buttonsSpring() * 0.05})`,
+ filter: `blur(${(1 - buttonsSpring()) * 2}px)`,
+ "pointer-events": buttonsSpring() > 0.5 ? "auto" : "none",
+ },
class: "min-w-0 max-w-[320px] text-13-regular group",
}}
>
@@ -1455,11 +1495,17 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
onSelect={(x) => local.model.variant.set(x === "default" ? undefined : x)}
class="capitalize max-w-[160px]"
valueClass="truncate text-13-regular"
- triggerStyle={{ height: "28px" }}
+ triggerStyle={{
+ height: "28px",
+ opacity: buttonsSpring(),
+ transform: `scale(${0.95 + buttonsSpring() * 0.05})`,
+ filter: `blur(${(1 - buttonsSpring()) * 2}px)`,
+ "pointer-events": buttonsSpring() > 0.5 ? "auto" : "none",
+ }}
variant="ghost"
/>
</TooltipKeybind>
- </Show>
+ </div>
</div>
<div class="shrink-0">
<RadioGroup