affectUI › Components › Inputs

Prompt Library

Saved prompt templates with variables – type straight into the sentence, watch the finished prompt assemble below, and use it once every variable is filled.

Part of affectUI Pro. Install: npx shadcn@latest add https://www.affectui.com/r/prompt-library.json · Import from @/components/ui/prompt-library

When to use

  • AI products where people reuse the same prompts with small changes – summaries, release notes, outreach, debugging
  • Next to a chat composer, as the place to pick a saved prompt, fill in the blanks and send it
  • Team prompt libraries where the template stays fixed and only a few words change per use

When not to use

  • Free writing – a plain composer is faster when nothing repeats
  • Long templates with many variables – past about six fields a form with labels reads better than a sentence
  • Choosing a command or action – use Command Menu

Usage

import { PromptLibrary } from "@/components/ui/prompt-library";

export function Prompts() {
  return (
    <PromptLibrary
      templates={[
        {
          id: "meeting",
          title: "Summarize a meeting",
          category: "Notes",
          body: "Summarize the meeting below for {audience} in under {length}.",
          variables: { length: { default: "150 words" } },
        },
        {
          id: "error",
          title: "Explain an error",
          category: "Debug",
          body: "Explain this {language} error in plain words: {error}.",
        },
      ]}
      onUse={(prompt) => send(prompt)}
    />
  );
}

Props

NameTypeDefaultDescription
templatesPromptTemplate[]{ id, title, category?, tone?, body, variables? } – body holds the variables in curly braces, e.g. {audience}; variables maps a name to { description?, default? }
valuestringId of the chosen template (controlled)
defaultValuestringId chosen at first when uncontrolled – the first template by default
onSelect(id: string) => voidCalled when another template is chosen
onUse(prompt: string, template: PromptTemplate, values: Record<string, string>) => voidCalled with the finished prompt when Use is pressed – only possible once every variable is filled
onCopy(prompt: string) => voidCalled after the prompt was copied to the clipboard
titlestring"Prompts"Heading above the list
useLabelstring"Use prompt"Label of the use button
classNamestringExtra class on the root

Keyboard

  • ↓: From the search field into the list
  • ↑ / ↓ / Home / End: Move through the list – the template opens as you go
  • Esc: Clears the search
  • Tab: Through the variable fields, then Copy and Use
  • Enter: In a variable field: jumps to the next empty one, or uses the prompt once all are filled

Accessibility

  • A group named by the list's title; the templates are a listbox with options and aria-selected, only the chosen one is in the tab order
  • Every variable is a real text field labelled with its name and description
  • Use stays focusable while not ready (aria-disabled) and the tray says how many variables are missing
  • A polite live region announces when all variables are filled, when the prompt was copied and when it was used
  • The outgoing template that fades out during a switch is inert and hidden from screen readers

Responsive

  • Fills its container up to 640px. Below 540px the list moves on top of the template; below 360px Copy keeps only its icon
  • Fields grow with what you type and never get wider than the line
  • Touch screens: taller list rows, fields and buttons
  • Dark mode built in: switches when an ancestor (usually <html>) has the class dark or data-theme="dark"

Requirements

  • React 19

Related

  • Chat Composer – Prompt composer with model picker, voice input, app connections and approval request
  • Command Menu – Search and run anything from one field – tool actions with logos and ⌘1–⌘5, everyday commands with icons
  • Writing Assistant – AI chat card with a soft gradient glow, suggestions, streaming replies and live voice dictation

Guides