{
  "name": "AILabel",
  "source": "src/components/AILabel.tsx",
  "propsType": "AILabelProps",
  "description": "AILabel — marks content as generated by AI, and opens what that means.\n\nIt is a Toggletip whose button is the mark: opened on purpose, it stays\nopen, it is part of the page, and it never traps focus. The explanation is\na required prop for the same reason ConfidenceIndicator's `basis` is — a\nmark with nothing behind it is a claim the system cannot back.\n\nIt labels; it does not detect. Whether content is generated is the\ncaller's knowledge, and so is whether a person has edited it since.",
  "import": "import { AILabel } from 'ionbase-ui';",
  "status": "stable",
  "summary": "Marks content as generated by AI, and opens what that means — what was generated, from what, and what to check. The explanation is required.",
  "useWhen": [
    "content a model wrote is shown as part of the product — a summary, a drafted reply, a suggested field value, a generated description",
    "a person has edited generated content, and it should still say where it came from"
  ],
  "useInstead": [
    {
      "when": "the content is an answer to a question someone asked, with sources",
      "use": "Citation",
      "why": "in the AssistantAnswer pattern the answer already says it is generated — its Citations and ConfidenceIndicator carry what to trust; add an AILabel only where the answer leaves the conversation and is shown elsewhere"
    },
    {
      "when": "the reader needs to know how far to trust it",
      "use": "ConfidenceIndicator",
      "why": "AILabel says who made it, not how good it is; pair them when both matter, and never let the mark stand in for a trust level"
    },
    {
      "when": "an agent is doing something now",
      "use": "AgentActivity",
      "why": "that is a run in progress; AILabel marks finished content"
    },
    {
      "when": "the explanation has nothing to do with AI",
      "use": "Toggletip",
      "why": "AILabel is a Toggletip whose button is the AI mark; for any other explanation use the ⓘ"
    }
  ],
  "composition": {
    "order": [
      "AILabel",
      "Link"
    ],
    "note": "Place it right after the heading or label of the generated content, not inside the content. Name it for the content — `aria-label=\"About this summary\"` — and the button reads \"AI: About this summary\". The children say what was generated, from what — the model, the inputs — and what to check before relying on it; at most one Link, to how it is made. Set `isEdited` once a person has changed the content; clear it only if the content is generated again.",
    "example": "<h3>Summary <AILabel aria-label=\"About this summary\">Written by atlas-m from the last 20 runs. Check the failure counts against the Runs tab before sharing. <Link href=\"/docs/summaries\">How summaries are made</Link></AILabel></h3>"
  },
  "variants": {
    "size": {
      "sm": {
        "use": "beside body-sm text — table cells, field labels, card titles; drawn 20px, a 24px target"
      },
      "md": {
        "use": "beside body text and headings — the default"
      }
    },
    "placement": {
      "top": {
        "use": "the default — above the mark, clear of the content below"
      },
      "bottom": {
        "use": "near the top of the viewport; it also flips here on its own"
      },
      "left": {
        "use": "beside a label at the end of a row"
      },
      "right": {
        "use": "beside a label at the start of a row"
      }
    }
  },
  "slots": {
    "children": {
      "accepts": "text, Link",
      "note": "the explanation, under a heading — \"Generated by AI\", or \"Generated by AI, edited by a person\" when edited; read out on open"
    },
    "labels": {
      "accepts": "text",
      "note": "mark, edited, title and editedTitle, for translation; the button's name follows the translated mark"
    }
  },
  "a11y": {
    "role": "button (a disclosure) that opens a status region",
    "guarantees": [
      "the button's name starts with the visible mark — \"AI: About this summary\", or \"AI, Edited: …\" — so what is seen is what is heard (WCAG 2.5.3)",
      "the explanation behaves as Toggletip's: opened by a press, not hover; read out on open while focus stays on the mark; Tab reaches a link inside; Escape closes it and returns focus",
      "it is not modal: it never traps focus or hides the page",
      "a 24px target at both sizes (WCAG 2.5.8)",
      "the mark uses the primary colour role, not a status colour: it says who made the content, not that something is wrong or new"
    ],
    "requires": [
      "`aria-label` naming the content it marks — \"About this summary\", not \"AI info\"",
      "children that say what was generated and from what"
    ],
    "notes": [
      "It labels; it does not detect. Whether content is generated, and whether a person has edited it since, is the caller's knowledge — pass it, never guess it."
    ]
  },
  "antiPatterns": [
    {
      "dont": "an explanation that says only \"This was generated by AI\"",
      "do": "the model, what it read, and what to check",
      "why": "the mark already says that; an explanation with nothing behind it is a claim the system cannot back"
    },
    {
      "dont": "leaving the mark unchanged after a person edits the content",
      "do": "`isEdited`",
      "why": "the reader is told the model wrote words a person chose, and blames or trusts the wrong author"
    },
    {
      "dont": "one AILabel for a whole page of mixed content",
      "why": "the reader cannot tell which parts were generated; mark each generated piece where it starts"
    },
    {
      "dont": "a mark on every row of a list that is all generated",
      "do": "one AILabel on the list's heading",
      "why": "twenty identical marks are noise, and twenty tab stops in the way of the rows"
    },
    {
      "dont": "using the mark as a badge for an AI feature — a button, a menu item, a nav link",
      "why": "it marks content a model produced; on a feature it says nothing about any content, and teaches readers to ignore it"
    }
  ],
  "stylesheet": null,
  "tokens": [],
  "props": {
    "aria-label": {
      "type": "string",
      "required": true,
      "origin": "own",
      "description": "What the label is for — \"About this summary\", \"About this reply\". The\nbutton is named with the mark first, so it reads \"AI: About this\nsummary\", and what is seen is what is heard (WCAG 2.5.3)."
    },
    "children": {
      "type": "React.ReactNode",
      "required": true,
      "origin": "own",
      "description": "The explanation, and required: what was generated, from what, and what\nto check before relying on it. A label that says only \"this is AI\"\ntells the reader nothing they can act on."
    },
    "isEdited": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "own",
      "description": "A person has changed the content since it was generated. The mark then\nsays so, and so does the explanation: the content is no longer only\nthe model's, and it is no longer only the person's either."
    },
    "placement": {
      "type": "ToggletipPlacement | undefined",
      "required": false,
      "origin": "own",
      "description": "Where the explanation sits. Flips when there is no room.",
      "values": [
        "top",
        "bottom",
        "left",
        "right"
      ]
    },
    "size": {
      "type": "ToggletipSize | undefined",
      "required": false,
      "origin": "own",
      "description": "`sm` beside body-sm text and in a table; `md` beside body text.",
      "values": [
        "sm",
        "md"
      ]
    },
    "labels": {
      "type": "AILabelLabels | undefined",
      "required": false,
      "origin": "own",
      "description": "Every string the label renders, for translation. English by default."
    },
    "isOpen": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "own"
    },
    "defaultOpen": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "own"
    },
    "onOpenChange": {
      "type": "((isOpen: boolean) => void) | undefined",
      "required": false,
      "origin": "own"
    },
    "className": {
      "type": "string | undefined",
      "required": false,
      "origin": "own"
    }
  },
  "propCounts": {
    "own": 10,
    "aria": 0,
    "dom": 0,
    "other": 0
  }
}
