{
  "name": "Coachmark",
  "source": "src/components/Coachmark.tsx",
  "propsType": "CoachmarkProps",
  "description": "Coachmark — a callout pointing at one thing on the page, to say what it is\nor what changed. Anchored to its target, which is ringed while it shows.\nSeveral in a row are a Tour.\n\nONLY WHEN ASKED\n\nIt takes focus when it appears, so it must appear because someone asked:\na \"Take the tour\" button, a \"What's new?\" link. Opened on page load, it\nwould pull a keyboard or screen-reader user out of whatever they came to\ndo. To tell people something changed without being asked, use a Banner.\n\nNOT MODAL\n\nThe page behind stays usable and is not hidden from assistive tech: this\npoints at the page, and the page is the point. Focus is not trapped; it\ngoes back where it was when the coachmark closes, and Escape closes it.",
  "import": "import { Coachmark } from 'ionbase-ui';",
  "status": "stable",
  "summary": "A callout pointing at one thing on the page, to say what it is or what changed — anchored to its target by id or ref, which is ringed while it shows. Several in a row are a Tour.",
  "useWhen": [
    "someone asked what a control does, or what changed — a \"What's new?\" link beside a feature that moved",
    "the explanation is about one place on the page and reads best beside it",
    "it is one of several: then it is a Tour, which sequences them"
  ],
  "useInstead": [
    {
      "when": "telling people something changed without their asking",
      "use": "Banner",
      "why": "a coachmark takes focus; opened on page load, it pulls a keyboard or screen-reader user out of what they came to do"
    },
    {
      "when": "several places in order — a first look round a page",
      "use": "Tour",
      "why": "Tour gives the count, Back and Next, and one focus hand-back at the end; a row of separate coachmarks gives none of them"
    },
    {
      "when": "a short hint on a control, on hover or focus",
      "use": "Tooltip",
      "why": "a tooltip holds no controls and never takes focus; a coachmark is for what needs reading"
    },
    {
      "when": "more detail the reader opens themselves from a control",
      "use": "Toggletip",
      "why": "a toggletip is the control's own explanation; a coachmark points at the page from outside it"
    }
  ],
  "composition": {
    "order": [
      "Coachmark"
    ],
    "note": "`target` is an element id, or a ref. Render it when a person asks — `isOpen` from a button's press — with `onClose`, which gives it a close button and Escape. `footer` holds its actions and `progress` a count, which is how Tour builds its steps.",
    "example": "<Coachmark target=\"export-runs\" title=\"Export is here now\" isOpen={open} onClose={() => setOpen(false)}>Runs export as CSV from this button, filtered as the table is.</Coachmark>"
  },
  "slots": {
    "children": {
      "accepts": "text",
      "note": "what to know about the target; linked as the dialog's description, so keep it to a sentence or two"
    },
    "footer": {
      "accepts": "Button",
      "note": "actions, end-aligned; one primary at most"
    }
  },
  "a11y": {
    "requires": [
      "a `title` — it names the dialog",
      "open it from a person's action, never on page load: it takes focus"
    ],
    "guarantees": [
      "a dialog named by `title` and described by the body, focused when it appears so it is read out",
      "not modal: the rest of the page is neither hidden from assistive tech nor inert, and focus is not trapped",
      "Escape and the close button call `onClose`; focus goes back to where it was when it opened",
      "its target is scrolled into view and ringed in border/primary-strong while it shows, and the ring goes when it closes",
      "`placement` is logical: `start` is the right in a right-to-left page; React Aria flips it when there is no room, and the arrow follows the side it resolved to",
      "a target that is not on the page shows nothing, rather than a callout pointing at nothing",
      "a target drawn in the same commit as the coachmark — a section one press reveals and points at — is looked for again once it is on the page, and the coachmark still appears focused",
      "in forced colours the target's ring is Highlight and the panel keeps a CanvasText edge"
    ],
    "notes": [
      "No `onClose`, no close button, and Escape does nothing: give one unless something else closes it.",
      "The close button is named by `closeLabel`, \"Close\" by default."
    ]
  },
  "antiPatterns": [
    {
      "dont": "a Coachmark with `isOpen` true on page load",
      "do": "a \"What's new?\" button that opens it, or a Banner",
      "why": "it takes focus when it appears; unasked, it moves a keyboard user away from what they came to do"
    },
    {
      "dont": "three Coachmarks opened one after another from your own state",
      "do": "<Tour steps={…} />",
      "why": "the count, Back, Next, the skipping of missing targets and the single focus hand-back are Tour's"
    },
    {
      "dont": "a coachmark holding a form",
      "do": "a SidePanel or a Modal",
      "why": "a coachmark points at the page; a task needs its own surface"
    }
  ],
  "stylesheet": "src/styles/coachmark.css",
  "tokens": [
    "--border-primary-strong",
    "--border-subtle",
    "--border-width-default",
    "--border-width-thick",
    "--font-family-sans",
    "--font-weight-medium",
    "--icon-secondary",
    "--icon-size-md",
    "--ion-coachmark-width",
    "--ion-duration-base",
    "--ion-ease-out",
    "--ion-shadow-shadow-lg",
    "--radius-md",
    "--radius-sm",
    "--ring-focus",
    "--spacing-12",
    "--spacing-16",
    "--spacing-32",
    "--spacing-4",
    "--spacing-6",
    "--spacing-8",
    "--surface-hover",
    "--surface-raised",
    "--text-default",
    "--text-secondary",
    "--text-tertiary",
    "--type-body",
    "--type-body-line-height",
    "--type-body-sm",
    "--type-body-sm-line-height"
  ],
  "props": {
    "target": {
      "type": "string | React.RefObject<HTMLElement | null>",
      "required": true,
      "origin": "own",
      "description": "What the coachmark points at: an element's `id`, or a ref to it. Ids let\na tour be written as data, with no refs threaded through the page."
    },
    "title": {
      "type": "string",
      "required": true,
      "origin": "own",
      "description": "Names the coachmark — it is a dialog, and this is its label."
    },
    "children": {
      "type": "React.ReactNode",
      "required": false,
      "origin": "own",
      "description": "What to know about the target. Linked as the dialog's description."
    },
    "placement": {
      "type": "CoachmarkPlacement | undefined",
      "required": false,
      "origin": "own",
      "description": "Which side of the target it sits on. Logical: `start` is the left in a\nleft-to-right page and the right in a right-to-left one. React Aria\nflips it when there is no room.",
      "values": [
        "top",
        "bottom",
        "start",
        "end"
      ]
    },
    "isOpen": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "own",
      "description": "Shown or not. Defaults to shown: render it when a person asks for it."
    },
    "onClose": {
      "type": "(() => void) | undefined",
      "required": false,
      "origin": "own",
      "description": "The close button and Escape. Without it there is no close button."
    },
    "footer": {
      "type": "React.ReactNode",
      "required": false,
      "origin": "own",
      "description": "Actions under the body, end-aligned: a tour's Back and Next."
    },
    "progress": {
      "type": "string | undefined",
      "required": false,
      "origin": "own",
      "description": "Where this is in a sequence — \"2 of 4\" — at the start of the footer."
    },
    "closeLabel": {
      "type": "string | undefined",
      "required": false,
      "origin": "own",
      "description": "The close button's name. Default \"Close\"."
    },
    "className": {
      "type": "string | undefined",
      "required": false,
      "origin": "own"
    }
  },
  "propCounts": {
    "own": 10,
    "aria": 0,
    "dom": 0,
    "other": 0
  }
}
