VibeCoderzVibeCoderz
Telegram
All Prompts
Radiant Prompt Input UI Preview
ui componentinput

Radiant Prompt Input

UI компонент: анимированный ввод текста с градиентной обводкой. Идеален для чат-ботов, командных строк и поиска с футуристичным дизайном.

by Zhou JasonLive Preview

Prompt

# Radiant Prompt Input

You are given a task to integrate an existing React component in the codebase

~~~/README.md
# Radiant Prompt Input

A high-fidelity, kinetic input interface featuring a mesmerizing, continuously rotating conic gradient border. Designed for next-generation AI interactions, this component elevates simple text entry into a focal point of engagement.

## Features

- **Kinetic Gradient Border**: Custom CSS `@property` animation creates a smooth, rotating multi-color gradient.
- **Backdrop Blur**: Organic glassmorphism effect that blends with any background.
- **Fluid Interactions**: Micro-interactions on hover, focus, and submission.
- **Responsive**: Adapts gracefully to mobile and desktop viewports.
- **Production Ready**: Fully typed, accessible, and theme-aware (works in Light/Dark modes).

## Usage

```tsx
import { RadiantPromptInput } from '@/sd-components/d2a7422b-1c93-41e6-a000-e313c7ad67f9';

function MyChatInterface() {
  const handleAsk = (query: string) => {
    console.log("User asked:", query);
  };

  return (
    <div className="w-full max-w-2xl mx-auto mt-20">
      <RadiantPromptInput 
        onSubmit={handleAsk}
        placeholder="Ask Gemini..."
      />
    </div>
  );
}
```

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `placeholder` | `string` | "Ask anything..." | Text to display when empty |
| `value` | `string` | undefined | Controlled value of the input |
| `onChange` | `(value: string) => void` | undefined | Callback when input changes |
| `onSubmit` | `(value: string) => void` | undefined | Callback when Enter is pressed or arrow clicked |
| `disabled` | `boolean` | false | Disables interactions |
| `className` | `string` | undefined | Additional CSS classes for the wrapper |

## Browser Support

Requires a browser that supports CSS `@property` (Modern Chrome, Edge, Safari, Firefox) for the rotation animation. Fallbacks gracefully to a static gradient in older browsers.
~~~

~~~/src/App.tsx
import React, { useState } from 'react';
import { RadiantPromptInput } from './Component';

export default function App() {
  const [lastSubmitted, setLastSubmitted] = useState<string | null>(null);

  const handleSubmit = (value: string) => {
    setLastSubmitted(value);
    console.log("Submitted:", value);
  };

  return (
    <div className="min-h-screen w-full flex flex-col items-center justify-center bg-background p-4 md:p-8 font-sans transition-colors duration-300">
      
      {/* Background decoration to show off the component's backdrop blur */}
      <div className="absolute inset-0 overflow-hidden pointer-events-none">
        <div className="absolute top-0 left-1/4 w-96 h-96 bg-primary/5 rounded-full blur-[100px]" />
        <div className="absolute bottom-0 right-1/4 w-[500px] h-[500px] bg-accent/5 rounded-full blur-[120px]" />
      </div>

      <div className="relative z-10 w-full max-w-4xl flex flex-col items-center gap-12">
        
        {/* Header Text */}
        <div className="text-center space-y-4">
          <h1 className="text-4xl md:text-6xl font-bold tracking-tight text-transparent bg-clip-text bg-gradient-to-br from-foreground to-muted-foreground/50 pb-2">
            How can I help?
          </h1>
          <p className="text-muted-foreground text-lg md:text-xl font-light max-w-lg mx-auto">
            Experience the fluid interface designed for the next generation of AI.
          </p>
        </div>

        {/* The Component */}
        <div className="w-full px-4">
          <RadiantPromptInput 
            onSubmit={handleSubmit} 
            placeholder="Ask anything..."
          />
        </div>

        {/* Feedback / State Display */}
        <div className="h-12 flex items-center justify-center">
          {lastSubmitted && (
            <div className="animate-in fade-in slide-in-from-bottom-4 duration-500">
              <span className="px-4 py-2 rounded-full bg-muted/50 text-sm text-muted-foreground border border-border/50">
                You asked: <span className="text-foreground font-medium">{lastSubmitted}</span>
              </span>
            </div>
          )}
        </div>

        {/* Capabilities Grid (Visual Filler) */}
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4 w-full max-w-3xl opacity-60">
          {[
            { icon: "✨", title: "Creative Writing", desc: "Stories, poems, scripts" },
            { icon: "💻", title: "Code Analysis", desc: "Debug, refactor, optimize" },
            { icon: "🎨", title: "Image Gen", desc: "Logos, art, diagrams" },
          ].map((item, i) => (
            <div key={i} className="p-4 rounded-xl border border-border/40 bg-card/30 hover:bg-card/50 transition-colors text-center">
              <div className="text-2xl mb-2">{item.icon}</div>
              <h3 className="font-medium text-foreground">{item.title}</h3>
              <p className="text-xs text-muted-foreground">{item.desc}</p>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
~~~

~~~/package.json
{
  "name": "radiant-prompt-input",
  "version": "1.0.0",
  "description": "A high-fidelity, kinetic input interface featuring a mesmerizing, continuously rotating conic gradient border.",
  "dependencies": {
    "lucide-react": "^0.300.0",
    "clsx": "^2.0.0",
    "tailwind-merge": "^2.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  }
}
~~~

~~~/src/Component.tsx
import React, { useState } from 'react';
import { Plus, Mic, ArrowUp } from 'lucide-react';
import { cn } from './utils'; // We'll implement utility inline or helper
import clsx from 'clsx';
import { twMerge } from 'tailwind-merge';

function cn(...inputs: (string | undefined | null | false)[]) {
  return twMerge(clsx(inputs));
}

export interface RadiantPromptInputProps {
  placeholder?: string;
  value?: string;
  onChange?: (value: string) => void;
  onSubmit?: (value: string) => void;
  className?: string;
  disabled?: boolean;
}

export function RadiantPromptInput({
  placeholder = "Ask anything...",
  value: propValue,
  onChange: propOnChange,
  onSubmit,
  className,
  disabled
}: RadiantPromptInputProps) {
  const [internalValue, setInternalValue] = useState("");
  const isControlled = propValue !== undefined;
  const value = isControlled ? propValue : internalValue;

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (!isControlled) {
      setInternalValue(e.target.value);
    }
    propOnChange?.(e.target.value);
  };

  const handleSubmit = () => {
    if (value && !disabled) {
      onSubmit?.(value);
      if (!isControlled) setInternalValue("");
    }
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSubmit();
    }
  };

  return (
    <div className={cn("relative w-full max-w-2xl mx-auto", className)}>
      {/* 
        Custom CSS for the gradient animation using @property which Tailwind doesn't fully support inline yet.
        We use a unique class scope 'radiant-input-wrapper' to avoid conflicts.
      */}
      <style>{`
        @property --rotation {
          syntax: '<angle>';
          inherits: false;
          initial-value: 0deg;
        }
        
        @keyframes rotate-gradient {
          to {
            --rotation: 360deg;
          }
        }

        .radiant-input-wrapper {
          --border-size: 3px;
          --gradient: conic-gradient(
            from var(--rotation) 
            at 50% 50% in oklab, 
            oklch(0.63 0.2 251.22) 27%, 
            oklch(0.67 0.21 25.81) 33%, 
            oklch(0.9 0.19 93.93) 41%, 
            oklch(0.79 0.25 150.49) 49%, 
            oklch(0.63 0.2 251.22) 65%, 
            oklch(0.72 0.21 150.89) 93%, 
            oklch(0.63 0.2 251.22)
          );
          animation: rotate-gradient 5s infinite linear;
        }

        /* The glowing border effect */
        .radiant-input-wrapper::before {
          content: '';
          position: absolute;
          inset: calc(var(--border-size) * -1);
          border-radius: inherit;
          background: var(--gradient);
          z-index: -1;
          filter: blur(8px);
          opacity: 0.6;
        }

        /* The sharp border mask */
        .radiant-input-border {
          position: absolute;
          inset: 0;
          border-radius: inherit;
          padding: var(--border-size);
          background: var(--gradient);
          -webkit-mask: 
            linear-gradient(#fff 0 0) content-box, 
            linear-gradient(#fff 0 0);
          -webkit-mask-composite: xor;
          mask-composite: exclude;
          pointer-events: none;
        }
      `}</style>

      <div className="radiant-input-wrapper relative rounded-full bg-white dark:bg-zinc-900 group transition-all duration-300 hover:shadow-lg hover:shadow-primary/5">
        
        {/* Animated Gradient Border */}
        <div className="radiant-input-border rounded-full" />
        
        {/* Inner Content */}
        <div className="relative z-10 flex items-center gap-2 p-1.5 pl-4 pr-1.5 h-14 md:h-16">
          
          {/* Add Button */}
          <button 
            type="button"
            className="flex items-center justify-center w-8 h-8 md:w-10 md:h-10 rounded-full text-muted-foreground hover:bg-muted/50 hover:text-foreground transition-colors"
            aria-label="Add attachment"
          >
            <Plus size={20} strokeWidth={2} />
          </button>

          {/* Text Input */}
          <input
            type="text"
            value={value}
            onChange={handleChange}
            onKeyDown={handleKeyDown}
            placeholder={placeholder}
            disabled={disabled}
            className="flex-1 bg-transparent border-none outline-none text-foreground placeholder:text-muted-foreground/70 text-base md:text-lg font-light tracking-wide h-full w-full min-w-0"
          />

          {/* Right Actions */}
          <div className="flex items-center gap-1 md:gap-2">
            
            {/* Mic Button */}
            <button 
              type="button"
              className="flex items-center justify-center w-8 h-8 md:w-10 md:h-10 rounded-full text-muted-foreground hover:bg-muted/50 hover:text-foreground transition-colors"
              aria-label="Use microphone"
            >
              <Mic size={20} strokeWidth={2} />
            </button>

            {/* Submit Button */}
            <button
              type="button"
              onClick={handleSubmit}
              disabled={!value || disabled}
              className={cn(
                "flex items-center justify-center w-10 h-10 md:w-12 md:h-12 rounded-full transition-all duration-300",
                value 
                  ? "bg-foreground text-background hover:scale-105 active:scale-95 shadow-md" 
                  : "bg-muted text-muted-foreground cursor-not-allowed opacity-50"
              )}
              aria-label="Send message"
            >
              <ArrowUp size={22} strokeWidth={2.5} />
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

export default RadiantPromptInput;
~~~

Implementation Guidelines

1. Analyze the component structure, styling, animation implementations
2. Review the component's arguments and state
3. Think through what is the best place to adopt this component/style into the design we are doing
4. Then adopt the component/design to our current system

Help me integrate this into my design
All Prompts