{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"memory-list","type":"registry:ui","title":"Memory List","description":"The memory panel — every fact the assistant has saved about the user, with the ability to add one or make it forget.","author":"Scrim UI (https://scrimui.dev)","categories":["memory"],"docs":"https://scrimui.dev/components/memory-list","dependencies":[],"registryDependencies":[],"files":[{"path":"src/showcase/memory-list/memory-list.tsx","content":"\"use client\";\n\nimport * as React from \"react\";\n\n/* ------------------------------------------------------------------ */\n/* Types                                                               */\n/* ------------------------------------------------------------------ */\n\nexport type MemoryItem = {\n  id: string;\n  text: string;\n  updatedAt?: string;\n};\n\nexport type MemoryListProps = {\n  items: MemoryItem[];\n  title?: string;\n  description?: string;\n  addPlaceholder?: string;\n  emptyText?: string;\n  onAdd?: (text: string) => void;\n  onForget?: (id: string) => void;\n  className?: string;\n};\n\n/* ------------------------------------------------------------------ */\n/* Icons                                                               */\n/* ------------------------------------------------------------------ */\n\nfunction SparkleIcon(props: React.SVGProps<SVGSVGElement>) {\n  return (\n    <svg\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"2\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n      width=\"14\"\n      height=\"14\"\n      {...props}\n    >\n      <path d=\"M12 3l1.9 5.8a2 2 0 0 0 1.3 1.3L21 12l-5.8 1.9a2 2 0 0 0-1.3 1.3L12 21l-1.9-5.8a2 2 0 0 0-1.3-1.3L3 12l5.8-1.9a2 2 0 0 0 1.3-1.3z\" />\n    </svg>\n  );\n}\n\nfunction PlusIcon(props: React.SVGProps<SVGSVGElement>) {\n  return (\n    <svg\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"2.5\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n      width=\"12\"\n      height=\"12\"\n      {...props}\n    >\n      <path d=\"M12 5v14M5 12h14\" />\n    </svg>\n  );\n}\n\nfunction XIcon(props: React.SVGProps<SVGSVGElement>) {\n  return (\n    <svg\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"2.5\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n      width=\"12\"\n      height=\"12\"\n      {...props}\n    >\n      <path d=\"M18 6 6 18M6 6l12 12\" />\n    </svg>\n  );\n}\n\n/* ------------------------------------------------------------------ */\n/* MemoryList                                                          */\n/* ------------------------------------------------------------------ */\n\nexport function MemoryList({\n  items,\n  title = \"Memory\",\n  description = \"Things the assistant remembers about you\",\n  addPlaceholder = \"Add a memory…\",\n  emptyText = \"No memories yet.\",\n  onAdd,\n  onForget,\n  className = \"\",\n}: MemoryListProps) {\n  const [draft, setDraft] = React.useState(\"\");\n\n  function handleSubmit(e: React.FormEvent) {\n    e.preventDefault();\n    const text = draft.trim();\n    if (!text || !onAdd) return;\n    onAdd(text);\n    setDraft(\"\");\n  }\n\n  return (\n    <div className={`rounded-xl border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900 ${className}`}>\n      {/* Header */}\n      <div className=\"flex items-center justify-between border-b border-zinc-100 px-4 py-3 dark:border-zinc-800\">\n        <div>\n          <p className=\"text-sm font-medium text-zinc-900 dark:text-zinc-100\">{title}</p>\n          <p className=\"mt-0.5 text-xs text-zinc-500 dark:text-zinc-400\">{description}</p>\n        </div>\n        <span className=\"rounded-full bg-zinc-100 px-2 py-0.5 text-[11px] font-medium text-zinc-600 dark:bg-zinc-800 dark:text-zinc-400\">\n          {items.length} {items.length === 1 ? \"item\" : \"items\"}\n        </span>\n      </div>\n\n      {/* Items */}\n      {items.length === 0 ? (\n        <p className=\"px-4 py-8 text-center text-xs text-zinc-500 dark:text-zinc-400\">{emptyText}</p>\n      ) : (\n        <ul className=\"max-h-56 divide-y divide-zinc-100 overflow-y-auto dark:divide-zinc-800\">\n          {items.map((item) => (\n            <li key={item.id} className=\"group flex items-center gap-3 px-4 py-2.5\">\n              <span className=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-violet-100 text-violet-600 dark:bg-violet-900/40 dark:text-violet-400\">\n                <SparkleIcon />\n              </span>\n              <p className=\"min-w-0 flex-1 text-[13px] leading-5 text-zinc-700 dark:text-zinc-300\">\n                {item.text}\n              </p>\n              {item.updatedAt && (\n                <span className=\"shrink-0 text-[11px] text-zinc-500 dark:text-zinc-400\">{item.updatedAt}</span>\n              )}\n              {onForget && (\n                <button\n                  type=\"button\"\n                  aria-label={`Forget: ${item.text}`}\n                  onClick={() => onForget(item.id)}\n                  className=\"shrink-0 rounded-md p-1 text-zinc-300 opacity-0 transition-opacity hover:bg-zinc-100 hover:text-zinc-600 group-hover:opacity-100 dark:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300\"\n                >\n                  <XIcon />\n                </button>\n              )}\n            </li>\n          ))}\n        </ul>\n      )}\n\n      {/* Add memory */}\n      {onAdd && (\n        <form\n          onSubmit={handleSubmit}\n          className=\"flex items-center gap-2 border-t border-zinc-100 px-4 py-3 dark:border-zinc-800\"\n        >\n          <input\n            value={draft}\n            onChange={(e) => setDraft(e.target.value)}\n            placeholder={addPlaceholder}\n            aria-label=\"Add a memory\"\n            className=\"min-w-0 flex-1 bg-transparent text-[13px] text-zinc-700 placeholder:text-zinc-400 focus:outline-none dark:text-zinc-300\"\n          />\n          <button\n            type=\"submit\"\n            disabled={!draft.trim()}\n            className=\"inline-flex h-7 shrink-0 items-center gap-1 rounded-lg bg-zinc-900 px-2.5 text-xs font-medium text-white transition-opacity hover:opacity-90 disabled:opacity-40 dark:bg-zinc-100 dark:text-zinc-900\"\n          >\n            <PlusIcon />\n            Add\n          </button>\n        </form>\n      )}\n    </div>\n  );\n}\n","type":"registry:ui","target":"components/ui/memory-list.tsx"}]}