{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "prompt-suggestions",
  "type": "registry:ui",
  "title": "Prompt Suggestions",
  "description": "Starter prompts for empty chat states — chips, cards or a list that rise in with a short stagger and fill the composer when clicked.",
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://kuro.abstergo.fyi/r/kura-theme.json",
    "https://kuro.abstergo.fyi/r/kura-motion.json",
    "https://kuro.abstergo.fyi/r/use-reduced-motion.json",
    "utils"
  ],
  "files": [
    {
      "path": "registry/kura/prompt-suggestions/index.ts",
      "type": "registry:ui",
      "target": "components/kura/prompt-suggestions/index.ts",
      "content": "export {\n  type PromptSuggestion,\n  PromptSuggestions,\n  type PromptSuggestionsProps,\n} from \"./prompt-suggestions\";\n"
    },
    {
      "path": "registry/kura/prompt-suggestions/prompt-suggestions.tsx",
      "type": "registry:ui",
      "target": "components/kura/prompt-suggestions/prompt-suggestions.tsx",
      "content": "\"use client\";\n\nimport { ArrowUpRight } from \"lucide-react\";\nimport { AnimatePresence, motion, type Variants } from \"motion/react\";\nimport type * as React from \"react\";\nimport { useReducedMotion } from \"@/hooks/kura/use-reduced-motion\";\nimport { cn } from \"@/lib/utils\";\nimport { springs } from \"@/lib/kura/motion\";\n\nexport interface PromptSuggestion {\n  /** Stable id; defaults to the title. Changing ids re-runs the enter animation for that item. */\n  id?: string;\n  /** Short label, e.g. \"Plan a trip\". */\n  title: string;\n  /** Secondary line (cards and list only), e.g. \"to Kyoto in April\". */\n  description?: string;\n  /** 16px icon. */\n  icon?: React.ReactNode;\n  /** Text passed to `onSelect`. Defaults to title + \" \" + description. */\n  prompt?: string;\n}\n\nexport interface PromptSuggestionsProps\n  extends Omit<React.ComponentProps<\"ul\">, \"children\" | \"onSelect\"> {\n  suggestions: readonly PromptSuggestion[];\n  /** Called with the prompt text when a suggestion is clicked. */\n  onSelect?: (prompt: string, suggestion: PromptSuggestion) => void;\n  /** `chips` = pills in a wrapping row, `cards` = two-column tiles, `list` = rows. Default \"cards\". */\n  variant?: \"chips\" | \"cards\" | \"list\";\n  /** Seconds between items entering. Default 0.04. Capped after 8 items. */\n  stagger?: number;\n  /** Accessible name. Default \"Suggestions\". */\n  label?: string;\n  disabled?: boolean;\n}\n\nconst promptOf = (s: PromptSuggestion) =>\n  s.prompt ?? [s.title, s.description].filter(Boolean).join(\" \");\n\n/**\n * Starter prompts for an empty chat: chips, cards or a list that rise in with a short stagger\n * and hand their prompt to `onSelect` (e.g. to fill a composer).\n */\nexport function PromptSuggestions({\n  suggestions,\n  onSelect,\n  variant = \"cards\",\n  stagger = 0.04,\n  label = \"Suggestions\",\n  disabled = false,\n  className,\n  ...props\n}: PromptSuggestionsProps) {\n  const reduced = useReducedMotion();\n\n  const item: Variants = reduced\n    ? { hidden: { opacity: 0 }, shown: { opacity: 1, transition: { duration: 0.2 } } }\n    : {\n        hidden: { opacity: 0, y: 6, filter: \"blur(2px)\" },\n        shown: (i: number) => ({\n          opacity: 1,\n          y: 0,\n          filter: \"blur(0px)\",\n          transition: { ...springs.smooth, delay: Math.min(i, 8) * stagger },\n        }),\n      };\n\n  return (\n    <ul\n      data-slot=\"prompt-suggestions\"\n      data-variant={variant}\n      aria-label={label}\n      className={cn(\n        \"font-kura-sans\",\n        variant === \"chips\" && \"flex flex-wrap justify-center gap-2\",\n        variant === \"cards\" && \"grid grid-cols-1 gap-2 sm:grid-cols-2\",\n        variant === \"list\" && \"flex flex-col\",\n        className,\n      )}\n      {...props}\n    >\n      <AnimatePresence initial mode=\"popLayout\">\n        {suggestions.map((s, i) => {\n          const key = s.id ?? s.title;\n          return (\n            <motion.li\n              key={key}\n              custom={i}\n              variants={item}\n              initial=\"hidden\"\n              animate=\"shown\"\n              exit={{ opacity: 0, transition: { duration: 0.09 } }}\n              className={cn(\n                \"flex\",\n                variant === \"list\" && \"not-last:shadow-[0_1px_0_var(--kura-border-subtle)]\",\n              )}\n            >\n              <button\n                type=\"button\"\n                data-slot=\"prompt-suggestions-item\"\n                disabled={disabled}\n                onClick={() => onSelect?.(promptOf(s), s)}\n                className={cn(\n                  \"group/suggestion relative flex w-full min-w-0 cursor-pointer items-center text-left outline-none\",\n                  \"transition-[background-color,color,box-shadow,transform] duration-(--kura-duration-fast) ease-kura-out\",\n                  \"focus-visible:shadow-kura-focus disabled:cursor-not-allowed disabled:opacity-50 motion-reduce:transform-none\",\n                  variant === \"chips\" &&\n                    \"h-8 gap-1.5 rounded-full bg-kura-surface px-3 text-[13px] text-kura-fg-muted shadow-kura-xs hover:not-disabled:bg-kura-surface-sunken hover:not-disabled:text-kura-fg active:not-disabled:scale-[0.97] [&_[data-slot=prompt-suggestions-icon]_svg]:size-3.5\",\n                  variant === \"cards\" &&\n                    \"flex-col items-start gap-2.5 rounded-kura-xl bg-kura-surface p-3.5 shadow-kura-sm hover:not-disabled:shadow-kura-md active:not-disabled:scale-[0.985]\",\n                  variant === \"list\" &&\n                    \"gap-3 rounded-kura-md px-2 py-2.5 text-kura-fg-muted text-sm hover:not-disabled:bg-kura-hover hover:not-disabled:text-kura-fg\",\n                )}\n              >\n                {s.icon && (\n                  <span\n                    data-slot=\"prompt-suggestions-icon\"\n                    aria-hidden\n                    className={cn(\n                      \"flex shrink-0 items-center justify-center text-kura-fg-subtle transition-colors duration-(--kura-duration-fast) group-hover/suggestion:text-kura-fg-muted\",\n                      variant === \"cards\" &&\n                        \"size-7 rounded-kura-md bg-kura-hover shadow-[inset_0_0_0_1px_var(--kura-border-subtle)] [&_svg]:size-3.5\",\n                      variant === \"list\" && \"[&_svg]:size-4\",\n                    )}\n                  >\n                    {s.icon}\n                  </span>\n                )}\n                {variant === \"chips\" ? (\n                  <span className=\"truncate\">{s.title}</span>\n                ) : (\n                  <span className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n                    <span\n                      className={cn(\n                        \"truncate font-medium\",\n                        variant === \"cards\" ? \"text-kura-fg text-sm\" : \"text-inherit\",\n                      )}\n                    >\n                      {s.title}\n                    </span>\n                    {s.description && (\n                      <span\n                        className={cn(\n                          \"text-kura-fg-subtle\",\n                          variant === \"cards\"\n                            ? \"line-clamp-2 text-xs leading-4\"\n                            : \"truncate text-xs\",\n                        )}\n                      >\n                        {s.description}\n                      </span>\n                    )}\n                  </span>\n                )}\n                {variant !== \"chips\" && (\n                  <ArrowUpRight\n                    aria-hidden\n                    className={cn(\n                      \"size-3.5 shrink-0 text-kura-fg-subtle opacity-0 transition-[opacity,transform] duration-(--kura-duration-base) ease-kura-out\",\n                      \"-translate-x-0.5 translate-y-0.5 group-hover/suggestion:translate-x-0 group-hover/suggestion:translate-y-0 group-hover/suggestion:opacity-100 group-focus-visible/suggestion:opacity-100\",\n                      \"motion-reduce:translate-x-0 motion-reduce:translate-y-0\",\n                      variant === \"cards\" && \"absolute top-3.5 right-3.5\",\n                    )}\n                  />\n                )}\n              </button>\n            </motion.li>\n          );\n        })}\n      </AnimatePresence>\n    </ul>\n  );\n}\n"
    }
  ],
  "categories": [
    "input",
    "suggestions",
    "starters",
    "empty-state",
    "prompts"
  ],
  "docs": "Docs: https://kuro.abstergo.fyi/components/prompt-suggestions · Markdown for agents: https://kuro.abstergo.fyi/components/prompt-suggestions.md",
  "meta": {
    "kura": {
      "status": "beta",
      "whenToUse": [
        "The empty state of a chat or agent: show 3–6 example prompts the user can start from.",
        "Follow-up suggestions under an answer (“Make it shorter”, “Add sources”) using the chips variant.",
        "Onboarding that teaches what the assistant can do, with icons and one-line descriptions."
      ],
      "whenNotToUse": [
        "Commands typed inline in the prompt — use slash-command-menu.",
        "Global actions and navigation — use command-palette.",
        "More than ~8 items or anything that needs search — use command-palette or a list."
      ]
    }
  }
}
