Beste UI Pieces
componentai1source: ok · refreshed
Prompt Input
Chat prompt card with a sparkle glyph, multi-line value, attach button, and a smart send arrow.
npx shadcn add "https://ui.beste.co/piece/r/ai1.json"free
No selection tags yet — empty means no evidence, not lack of support.
Dependencies
Bundle weight · lightclsxtailwind-mergelucide-react
Files1 · source cached 10/8/2026, 10:10:30 AM
registry-pieces/ai1/ai1.tsx
"use client";
import { ArrowUp, Paperclip } from "lucide-react";
import { cn } from "@/lib/utils";
type Surface = "card" | "glass";
interface Ai1Props {
placeholder?: string;
value?: string;
surface?: Surface;
bordered?: boolean;
inverted?: boolean;
className?: string;
}
/* The card sets the colour and everything inside it is drawn in `current`, so
inverting is two classes rather than a condition on every element.
`glass` is a deliberate exception to the solid-surface rule: these pieces sit
over section background images, and a frosted panel is the point of it. */
const surfaceClasses: Record<Surface, { plain: string; inverted: string }> = {
card: {
plain: "bg-card text-card-foreground",
inverted: "bg-foreground text-background",
},
glass: {
plain: "bg-card/60 text-card-foreground backdrop-blur-md",
inverted: "bg-foreground/60 text-background backdrop-blur-md",
},
};
export const ai1Demo: Ai1Props = {
surface: "card",
bordered: false,
inverted: false,
placeholder: "Ask anything...",
value: "Write a landing page hero for a coffee roaster",
};
export function Ai1({
placeholder = "Ask",
value = "",
surface = "card",
bordered = false,
inverted = false,
className,
}: Ai1Props) {
const hasValue = value.length > 0;
const surfaceTone = surfaceClasses[surface][inverted ? "inverted" : "plain"];
return (
<div
className={cn(
"relative flex size-full items-center justify-center p-4",
className
)}
>
<div
className={cn(
"flex w-full max-w-80 flex-col gap-2 rounded-2xl p-3 shadow-sm",
surfaceTone,
bordered && "border border-current/15"
)}
>
<p
className={cn(
"text-sm leading-snug",
hasValue ? "" : "text-current/60"
)}
>
{hasValue ? value : placeholder}
</p>
<div className="flex items-center justify-between">
<button
type="button"
aria-label="Attach"
className="flex size-7 items-center justify-center rounded-full text-current/60 transition-colors hover:bg-current/10 hover:text-current"
>
<Paperclip className="size-3.5" aria-hidden="true" />
</button>
<button
type="button"
aria-label="Send"
disabled={!hasValue}
className={cn(
"flex size-7 items-center justify-center rounded-full transition-colors",
hasValue
? "bg-foreground text-background hover:bg-current/90"
: "bg-current/10 text-current/60"
)}
>
<ArrowUp className="size-3.5" aria-hidden="true" />
</button>
</div>
</div>
</div>
);
}