From e2094eb4cb3a8593d03e6964346c3025ef37b06f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 03:11:19 +0000 Subject: [PATCH] Palette: Add clear button to URL input & remove unused component --- .Jules/palette.md | 10 ++ components/url-input-with-branding.tsx | 145 ------------------------- components/url-input.tsx | 23 +++- 3 files changed, 31 insertions(+), 147 deletions(-) create mode 100644 .Jules/palette.md delete mode 100644 components/url-input-with-branding.tsx diff --git a/.Jules/palette.md b/.Jules/palette.md new file mode 100644 index 0000000..a515161 --- /dev/null +++ b/.Jules/palette.md @@ -0,0 +1,10 @@ +## 2025-05-23 - [Input Clear Button Pattern] +**Learning:** Users often struggle to clear long inputs like URLs. Adding a conditional "Clear" button (X icon) that appears when text is present significantly improves usability on both desktop and mobile. +**Action:** When creating primary text inputs (search, URL), always implement a clear button that: +1. Only appears when input has value +2. Clears the state +3. Returns focus to the input element + +## 2025-05-23 - [Component Cleanup] +**Learning:** Found an unused component `UrlInputWithBranding` that was a near-duplicate of `UrlInput`. +**Action:** Before modifying a component, check for duplicates or "with branding" variants that might be unused. remove them to keep the codebase clean. diff --git a/components/url-input-with-branding.tsx b/components/url-input-with-branding.tsx deleted file mode 100644 index 73e89a8..0000000 --- a/components/url-input-with-branding.tsx +++ /dev/null @@ -1,145 +0,0 @@ -"use client"; - -import { useEffect, useState } from "react"; -import { Loader2, ArrowUp, Link as LinkIcon } from "lucide-react"; -import Image from "next/image"; -import Link from "next/link"; -import { extractVideoId } from "@/lib/utils"; -import { cn } from "@/lib/utils"; -import { Button } from "@/components/ui/button"; -import { Card } from "@/components/ui/card"; -import { ModeSelector } from "@/components/mode-selector"; -import { isGrokProviderOnClient } from "@/lib/ai-providers/client-config"; -import type { TopicGenerationMode } from "@/lib/types"; - -interface UrlInputWithBrandingProps { - onSubmit: (url: string) => void; - isLoading?: boolean; - initialUrl?: string; - mode?: TopicGenerationMode; - onModeChange?: (mode: TopicGenerationMode) => void; -} - -export function UrlInputWithBranding({ onSubmit, isLoading = false, initialUrl, mode, onModeChange }: UrlInputWithBrandingProps) { - const [url, setUrl] = useState(() => initialUrl ?? ""); - const [error, setError] = useState(""); - const [isFocused, setIsFocused] = useState(false); - const forceSmartMode = isGrokProviderOnClient(); - const showModeSelector = - !forceSmartMode && typeof onModeChange === "function"; - const modeValue: TopicGenerationMode = forceSmartMode - ? "smart" - : mode ?? "fast"; - - useEffect(() => { - if (initialUrl === undefined) return; - setUrl((current) => (current === initialUrl ? current : initialUrl)); - }, [initialUrl]); - - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - setError(""); - - if (!url.trim()) { - setError("Please enter a YouTube URL"); - return; - } - - const videoId = extractVideoId(url); - if (!videoId) { - setError("Please enter a valid YouTube URL"); - return; - } - - onSubmit(url); - }; - - return ( -
{error}
- )} -