Xzero UI
Pro library

Starter promptsPro

A greeting and a grid of starter cards for the empty state of an AI app. The cards are grouped into Write, Code, Analyze and Plan tabs, and a shuffle swaps them with a short staggered crossfade. Picking a card fills the composer, and cards that use a connected app show its mark (Gmail, GitHub, Notion, Linear, Google Calendar).

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/starter-prompts
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/starter-prompts

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { StarterPrompts } from "@/components/xzero/starter-prompts/starter-prompts";

export function NewChat() {
  return (
    <StarterPrompts
      greeting="Good morning, Maya"
      onSelect={prompt => track("starter_picked", { id: prompt.id })}
      onSubmit={async (message, { signal }) => {
        const res = await fetch("/api/chat", { method: "POST", body: JSON.stringify({ message }), signal });
        if (!res.ok) throw new Error("Couldn't send. Try again.");
      }}
    />
  );
}

Examples

Your own starters and tabs

<StarterPrompts
  categories={[{ id: "support", label: "Support" }, { id: "sales", label: "Sales" }]}
  prompts={[
    { id: "refund", category: "support", app: "gmail", title: "Answer refund requests", description: "Draft replies for the 6 open threads", prompt: "Draft replies to the 6 open refund threads in Gmail..." },
    { id: "pipeline", category: "sales", title: "Review the pipeline", description: "Deals that slipped this month", prompt: "List the deals that slipped in October and why..." },
  ]}
  model={{ name: "GPT-6.1 Sol", mark: <OpenAIMark width={14} height={14} /> }}
/>

API reference

StarterPrompts

The empty state of an AI app: a greeting, starter cards filtered by category tabs, a shuffle that swaps cards with a short staggered crossfade, and a composer the cards fill. With no props it shows 24 sample starters and simulates the send.

PropTypeDefaultDescription
greetingReactNode"What are we working on, Maya?"The heading.
descriptionReactNodesample lineOne quiet line under the heading. Pass null to hide it.
promptsStarterPrompt[]starterPromptSamplesThe starters: { id, category, title, description?, prompt, app? }. prompt is the full text placed in the composer; app is "gmail" | "github" | "notion" | "linear" | "calendar" and shows that app's mark.
categoriesStarterPromptCategory[]Write, Code, Analyze, PlanThe filter tabs in order, each { id, label, icon? }. All is added in front, and tabs with no starters are hidden.
defaultCategorystring"all"The tab selected first.
countnumber4Cards on screen at once. The grid reserves this many slots so nothing jumps.
loadingbooleanfalseShows placeholder cards with the same size and rhythm while starters load.
valuestring–The composer text, controlled. Pair with onValueChange.
defaultValuestring""The composer text on first render when uncontrolled.
onValueChange(value: string) => void–Called when the composer text changes, from typing or a picked card.
onSelect(prompt: StarterPrompt) => void–Called when a card is picked, after its prompt fills the composer.
onSubmit(message: string, context: { prompt: StarterPrompt | null; signal: AbortSignal }) => Promise<void> | void–Sends the message. Throw to show the error state with Retry. The signal aborts when the person presses Stop or the component unmounts. Without it the send is simulated.
model{ name: string; mark?: ReactNode }{ name: "Claude Sonnet 5.5" }The model named in the composer footer. The mark defaults to the Claude mark.
placeholderstring"Ask anything, or pick a starter above"Composer placeholder.
classNamestring–Extra class on the root section.

Keyboard interactions

KeysAction
TabMoves through the tabs, Shuffle, each card and the composer.
Arrow keysMove between category tabs.
Enter or SpaceOn a card, fills the composer with its prompt and focuses it.
EnterIn the composer, sends the message.
Shift EnterIn the composer, adds a new line.
EscapeWhile sending, stops the send and keeps the text.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in ai

Guidance for AI tools

Starter prompts: A greeting and a grid of starter cards for the empty state of an AI app. The cards are grouped into Write, Code, Analyze and Plan tabs, and a shuffle swaps them with a short staggered crossfade. Picking a card fills the composer, and cards that use a connected app show its mark (Gmail, GitHub, Notion, Linear, Google Calendar). Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components