{
  "name": "MemoryProfileWidget",
  "type": "pattern",
  "description": "A floating launcher that opens a drawer of memory-profile summaries, observations and traits",
  "export": "MemoryProfileWidget",
  "path": "@gtmi/strix-react/organisms/memory-profile-widget",
  "props": [
    {
      "name": "profileId",
      "type": "string | null",
      "description": "Opaque id shown in the drawer header, with a copy-to-clipboard affordance"
    },
    {
      "name": "summaries",
      "type": "string[]",
      "default": "[]",
      "description": "Free-text summaries, most recent first. Capped at maxSummaries"
    },
    {
      "name": "observations",
      "type": "string[]",
      "default": "[]",
      "description": "Short standalone facts. Capped at maxObservations"
    },
    {
      "name": "traits",
      "type": "MemoryProfileTrait[]",
      "default": "[]",
      "description": "Key/value/group triples, each rendered as a row with a group badge. Capped at maxTraits"
    },
    { "name": "maxSummaries", "type": "number", "default": "2" },
    { "name": "maxObservations", "type": "number", "default": "3" },
    { "name": "maxTraits", "type": "number", "default": "3" },
    { "name": "open", "type": "boolean", "description": "Controlled drawer state. Pair with onOpenChange" },
    {
      "name": "defaultOpen",
      "type": "boolean",
      "default": "false",
      "description": "Initial drawer state when uncontrolled"
    },
    {
      "name": "onOpenChange",
      "type": "(open: boolean) => void",
      "description": "Called with the next drawer state on every toggle, controlled or not"
    },
    {
      "name": "position",
      "type": "'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'",
      "default": "'bottom-right'",
      "description": "Corner the bubble launcher docks to"
    },
    {
      "name": "drawerSide",
      "type": "'left' | 'right'",
      "default": "'right'",
      "description": "Edge the drawer slides in from"
    },
    { "name": "title", "type": "string", "default": "'Memory Profile'" },
    { "name": "bubbleIcon", "type": "ReactNode", "description": "Bubble launcher icon" },
    { "name": "bubbleSize", "type": "IconButtonSize", "default": "'xl'" },
    { "name": "bubbleClassName", "type": "string", "description": "Applied to the bubble IconButton" }
  ],
  "parts": [
    { "name": "memory-profile-widget", "description": "Root wrapper, via data-slot" },
    { "name": "memory-profile-widget-launcher", "description": "The floating IconButton that opens the drawer" }
  ],
  "ai_tags": ["widget", "bubble", "drawer", "memory", "profile", "launcher", "pattern"],
  "since": "0.5.0",
  "source": "cr-web-demo WidgetBubble",
  "tokens_used": [
    "--spacing-gap-050",
    "--spacing-gap-100",
    "--spacing-gap-200",
    "--spacing-gap-300",
    "--spacing-padding-horizontal-lg",
    "--text-size-body-medium",
    "--font-weight-body-medium-semibold"
  ],
  "notes": "The source dispatched and listened for a `memory-profile:found` CustomEvent on `window`, and accumulated every event it ever received into unbounded arrays for the life of the page. Neither survived the port: no other pattern in this library reaches for ambient global state — CollapsiblePanel and InfoSection both take their data as props — and an accumulating internal array is exactly the kind of state a caller cannot reset or cap from outside. MemoryProfileWidget is controlled: `summaries`, `observations` and `traits` render exactly what is passed, in the order given, and a host that wants to append across multiple findings owns that array itself. All colour, spacing and typography is inherited from Badge, IconButton, InfoRow, InfoSection, SideModal and Typography, so this pattern's own tokens are limited to the layout gaps and the sheet header's type role."
}
