Empty state

What a new chat shows before the first message: a greeting, a centred prompt, a project's home with its files and recent chats, a gallery of task templates, a return screen with unfinished work, an agent's own landing page, and a blank image studio.

Loading preview…

Install

  1. 1

    Run this command in your Tailwind CSS project. It adds components/ai/empty-state-greeting.tsx and installs its dependencies.

    $ npx shadcn@latest add https://gradientdeck.com/ai-components/r/empty-state-greeting.json

Usage & API

Example

empty-state-greeting.tsx
import { EmptyStateGreeting } from "@/components/ai/empty-state-greeting"

<EmptyStateGreeting
  greeting="…"
  place="…"
  lead="…"
  starters={[]}
  onPick={() => {}}
/>

Props EmptyStateGreeting

PropType & descriptionRequired
greetingstringe.g. "Tuesday evening, Maya"Required
placestringe.g. "18:42 in Lisbon · 16° and clearing"Required
leadstringRequired
startersStarter[]Required
onPick(starter: Starter) => voidRequired
sceneReactNodeOptional

Dependencies

  • React
  • Tailwind CSS
  • motion
  • lucide-react
Implementation notes

Greeting exports EmptyStateGreeting and CyclingPlaceholder. The heading is greeting, the line above it is place, and lead sits underneath. starters render as buttons with a visual, a title, and a detail. onPick receives the whole starter, so you can drop starter.prompt into the composer. The optional scene is a node on the right, hidden below the md breakpoint. The preview's scene is DuskScene. CyclingPlaceholder takes items and paused, and swaps the visible suggestion every 3200ms unless paused or reduced motion is on. The preview's items include Ask about the board memo and What should I cook with leeks and feta? The other starters are a Saturday run from Graça, a reply to Tom about Porto, and three receipts of about £86.

Choosing a layout

Use Greeting when the product knows who is sitting down and can suggest a next task from their own work. The preview says Tuesday evening, Maya, 18:42 in Lisbon, 16° and clearing, and offers Finish the Q3 board memo because they stopped at Risks yesterday, 1,240 words in. Use the centred composer when the first choice is the kind of task, ask, research, or create, not a personal history. Use Project home when the chat belongs to a project that already has files and instructions. Use templates when people should start from a shape, Write, Analyse, Plan, or Code, instead of a blank box. Use the return screen when they were away and a task finished or an approval is waiting. Use agent landing when the empty thread is one agent's front door. Use the studio when the empty screen is for pictures, not paragraphs.

Do not leave an empty state up after the first message. Greeting's onPick hands you the starter, including its prompt, and the centred composer's compact flag is how that layout gets out of the way. Do not use these screens to show a reply in progress. A wait with no tokens is Loader. A thread that should follow new text is Conversation. A list of old chats is Thread list. The studio's Generate button and the greeting's send button belong to the preview shells around the exported pieces. Wire them to your own send.

The return screen mentions Saturday and a draft PR. Can I change that copy?

Not through props. AwaySummary builds the task title, the repo, the file counts, and took from task. The line Waiting for you, since Saturday is fixed, and so is Draft PR #418 opened on GitHub under the file list. The approved state ignores approval.detail and shows 4 emails sent from [email protected]. The declined state shows Nothing was sent. You can still pass approval.detail for the waiting state, and you can pass the real paths in task.files. If that fixed copy is wrong for the product, this variant is the wrong screen.

What happens to the centred composer after the first message?

Set compact. The title, the mode tabs, and the starter suggestions unmount, and the placeholder becomes Reply. mode is still ask, research, or create, so the chips stay: Search the web, Web and Drive, or Doc, Slides, and Email. value and onChange still drive the textarea. disabled blocks Send. Enter without Shift calls onSend. The component does not clear value for you. Greeting has no compact flag. You replace it when onPick fires, using the starter's prompt, title, and detail.