Skip to content

Commit 60997f9

Browse files
committed
Errors work, improved the styling
1 parent 33f5b7c commit 60997f9

File tree

2 files changed

+51
-38
lines changed

2 files changed

+51
-38
lines changed

apps/webapp/app/components/primitives/Input.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,27 @@ export type InputProps = React.InputHTMLAttributes<HTMLInputElement> & {
5151
icon?: RenderIcon;
5252
accessory?: React.ReactNode;
5353
fullWidth?: boolean;
54+
containerClassName?: string;
5455
};
5556

5657
const Input = React.forwardRef<HTMLInputElement, InputProps>(
57-
({ className, type, accessory, fullWidth = true, variant = "medium", icon, ...props }, ref) => {
58+
(
59+
{
60+
className,
61+
type,
62+
accessory,
63+
fullWidth = true,
64+
variant = "medium",
65+
icon,
66+
containerClassName,
67+
...props
68+
},
69+
ref
70+
) => {
5871
const innerRef = useRef<HTMLInputElement>(null);
5972
useImperativeHandle(ref, () => innerRef.current as HTMLInputElement);
6073

61-
const containerClassName = variants[variant].container;
74+
const variantContainerClassName = variants[variant].container;
6275
const inputClassName = variants[variant].input;
6376
const iconClassName = variants[variant].iconSize;
6477

@@ -67,6 +80,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
6780
className={cn(
6881
"flex items-center",
6982
containerBase,
83+
variantContainerClassName,
7084
containerClassName,
7185
fullWidth ? "w-full" : "max-w-max"
7286
)}

apps/webapp/app/components/runs/v3/AIFilterInput.tsx

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { useSearchParams } from "~/hooks/useSearchParam";
1212
import { objectToSearchParams } from "~/utils/searchParams";
1313
import { type TaskRunListSearchFilters } from "./RunFilters";
1414
import { cn } from "~/utils/cn";
15-
import { motion } from "framer-motion";
15+
import { motion, AnimatePresence } from "framer-motion";
1616
import { Popover, PopoverContent, PopoverTrigger } from "~/components/primitives/Popover";
1717

1818
type AIFilterResult =
@@ -37,20 +37,6 @@ export function AIFilterInput() {
3737
const inputRef = useRef<HTMLInputElement>(null);
3838
const fetcher = useFetcher<AIFilterResult>();
3939

40-
// Calculate position for error message
41-
const [errorPosition, setErrorPosition] = useState({ top: 0, left: 0, width: 0 });
42-
43-
useEffect(() => {
44-
if (fetcher.data?.success === false && inputRef.current) {
45-
const rect = inputRef.current.getBoundingClientRect();
46-
setErrorPosition({
47-
top: rect.bottom + window.scrollY,
48-
left: rect.left + window.scrollX,
49-
width: rect.width,
50-
});
51-
}
52-
}, [fetcher.data?.success]);
53-
5440
useEffect(() => {
5541
if (fetcher.data?.success && fetcher.state === "loading") {
5642
// Clear the input after successful application
@@ -100,8 +86,19 @@ export function AIFilterInput() {
10086
stiffness: 300,
10187
damping: 30,
10288
}}
103-
className="animated-gradient-glow relative"
89+
className="relative"
10490
>
91+
<AnimatePresence>
92+
{isFocused && (
93+
<motion.div
94+
initial={{ opacity: 0 }}
95+
animate={{ opacity: 1 }}
96+
exit={{ opacity: 0 }}
97+
transition={{ duration: 0.2, ease: "linear" }}
98+
className="animated-gradient-glow pointer-events-none absolute inset-0"
99+
/>
100+
)}
101+
</AnimatePresence>
105102
<Input
106103
type="text"
107104
name="text"
@@ -113,9 +110,10 @@ export function AIFilterInput() {
113110
fullWidth
114111
ref={inputRef}
115112
className={cn(
116-
"placeholder:text-text-bright",
113+
"disabled:text-text-dimmed/50",
117114
isFocused && "placeholder:text-text-dimmed"
118115
)}
116+
containerClassName="has-[:disabled]:opacity-100"
119117
onKeyDown={(e) => {
120118
if (e.key === "Enter" && text.trim() && !isLoading) {
121119
e.preventDefault();
@@ -135,7 +133,13 @@ export function AIFilterInput() {
135133
icon={<AISparkleIcon className="size-4" />}
136134
accessory={
137135
isLoading ? (
138-
<Spinner color="muted" className="size-4" />
136+
<Spinner
137+
color={{
138+
background: "rgba(99, 102, 241, 1)",
139+
foreground: "rgba(217, 70, 239, 1)",
140+
}}
141+
className="size-4"
142+
/>
139143
) : text.length > 0 ? (
140144
<ShortcutKey
141145
shortcut={{ key: "enter" }}
@@ -145,20 +149,6 @@ export function AIFilterInput() {
145149
) : undefined
146150
}
147151
/>
148-
{fetcher.data?.success === false && (
149-
<Portal>
150-
<div
151-
className="fixed z-[9999] rounded-md bg-rose-500 px-3 py-2 text-sm text-white shadow-lg"
152-
style={{
153-
top: `${errorPosition.top + 8}px`,
154-
left: `${errorPosition.left}px`,
155-
width: `${errorPosition.width}px`,
156-
}}
157-
>
158-
{fetcher.data.error}
159-
</div>
160-
</Portal>
161-
)}
162152
</motion.div>
163153
</ErrorPopover>
164154
</fetcher.Form>
@@ -168,7 +158,7 @@ export function AIFilterInput() {
168158
function ErrorPopover({
169159
children,
170160
error,
171-
durationMs = 2_000,
161+
durationMs = 10_000,
172162
}: {
173163
children: React.ReactNode;
174164
error?: string;
@@ -178,11 +168,14 @@ function ErrorPopover({
178168
const timeout = useRef<NodeJS.Timeout | undefined>();
179169

180170
useEffect(() => {
171+
if (error) {
172+
setIsOpen(true);
173+
}
181174
if (timeout.current) {
182175
clearTimeout(timeout.current);
183176
}
184177
timeout.current = setTimeout(() => {
185-
setIsOpen((s) => true);
178+
setIsOpen(false);
186179
}, durationMs);
187180

188181
return () => {
@@ -193,9 +186,15 @@ function ErrorPopover({
193186
}, [error, durationMs]);
194187

195188
return (
196-
<Popover open={isOpen} onOpenChange={setIsOpen}>
189+
<Popover open={isOpen}>
197190
<PopoverTrigger asChild>{children}</PopoverTrigger>
198-
<PopoverContent>{error}</PopoverContent>
191+
<PopoverContent
192+
align="start"
193+
side="bottom"
194+
className="w-[var(--radix-popover-trigger-width)] min-w-[var(--radix-popover-trigger-width)] max-w-[var(--radix-popover-trigger-width)] border border-error/20 bg-[#2F1D24] px-3 py-2 text-xs text-text-dimmed"
195+
>
196+
{error}
197+
</PopoverContent>
199198
</Popover>
200199
);
201200
}

0 commit comments

Comments
 (0)