{"version":3,"sources":["../../src/components/HeadingAnchor.tsx"],"sourcesContent":["import { ReactNode, use, useCallback } from 'react';\nimport { scrollToId } from '../scrollToId';\nimport { TinkerableContext } from '../TinkerableContext';\nimport { constructOuterUrl } from '../urlUtils';\nimport { FragmentLink } from './Link';\n\n/**\n * Default MDX `HeadingAnchor` component — the render target for the autolink anchor\n * the transpiler's heading-slug plugin (R3-186, `MARKDOWN_SYNTAX_SPEC §15.4`)\n * prepends to every heading. That plugin sets the heading's own `id` (a text slug,\n * or a `sec-…` section id for a numbered heading, R3-211) and emits\n * `<HeadingAnchor id=\"<that id>\" />` as the heading's first child.\n *\n * It is registered in {@link DEFAULT_MDX_COMPONENTS} so a heading anchor renders\n * even in a plain-markdown repo that never calls `boot({ mdxComponents })` — the\n * MDX missing-reference guard never fires (§11.2 phantom defaults). The markup is\n * semantic and accessible — an `aria`-labelled `<a href=\"#id\">` permalink — but\n * **styling is intentionally minimal** (`§15.4` honesty note): an app supplies CSS\n * targeting the `ir-heading-anchor` class to reveal it on hover / add an icon, or\n * overrides this component via `boot({ mdxComponents: { HeadingAnchor } })` to\n * change the icon, position, or behaviour (e.g. copy-permalink-to-clipboard) of\n * every heading anchor in every content file at once (§15.4 late binding).\n *\n * `id` is the *heading's own* id, so the permalink `#id` is the same URL a reader\n * copies and (for a `sec-…` id) an agent computes from a `§`-citation with zero\n * lookup. A missing/empty `id` (defensive — the plugin always supplies one)\n * renders nothing rather than a dead `#` link.\n */\nexport const HeadingAnchor = ({\n  id,\n  ...rest\n}: {\n  id?: string;\n} & Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>): ReactNode => {\n  // ⚠ A BARE `#id` IS THE WRONG HREF INSIDE A SANDBOXED APP, and wrong in a way that only\n  // shows up when someone copies the link. The app runs in an iframe whose document URL is\n  // the SANDBOX's (`https://sandbox.immediately.run/index.html?href=…`), so the browser\n  // resolves `#id` against THAT — \"copy link address\" on a heading yields a\n  // sandbox-internal URL that means nothing to anyone else. Reported from a real wiki\n  // (2026-08-14) as exactly that URL instead of the entry's.\n  //\n  // Both halves have to be right, and they pull in opposite directions:\n  //   • the HREF must be absolute in the HOST's space, so copy-link / middle-click /\n  //     open-in-new-tab all produce a URL that resolves for a reader;\n  //   • the CLICK must NOT navigate to it — that would be a full page load to the page you\n  //     are already on. It scrolls, leaving the sandbox URL the host owns untouched.\n  //\n  // `FragmentLink` is the SDK's existing home for the second half; it runs the caller's\n  // `onClick` first and stands down if it preventDefaults, which is what lets the href be\n  // absolute here while the behaviour stays a scroll.\n  const ctx = use(TinkerableContext);\n  const onAnchorClick = useCallback(\n    (e: React.MouseEvent<HTMLAnchorElement>) => {\n      // Let a modified click through: cmd/ctrl/middle-click means \"open the permalink\",\n      // and that is precisely the case the absolute href exists to serve.\n      if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) return;\n      e.preventDefault();\n      if (id) scrollToId(id);\n    },\n    [id],\n  );\n  if (!id) return null;\n  // No context (a plain-markdown repo that never called `boot()`) → keep the old bare\n  // fragment, which FragmentLink handles on its own.\n  const href = ctx?.navigationState ? constructOuterUrl(ctx.outerHref, `#${id}`, ctx.navigationState) : `#${id}`;\n  return (\n    <FragmentLink\n      className=\"ir-heading-anchor\"\n      href={href}\n      onClick={onAnchorClick}\n      aria-label=\"Permalink to this heading\"\n      {...rest}\n    >\n      <span aria-hidden=\"true\">#</span>\n    </FragmentLink>\n  );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAyEM;AAzEN,mBAA4C;AAC5C,wBAA2B;AAC3B,+BAAkC;AAClC,sBAAkC;AAClC,kBAA6B;AAwBtB,MAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA,GAAG;AACL,MAE+E;AAiB7E,QAAM,UAAM,kBAAI,0CAAiB;AACjC,QAAM,oBAAgB;AAAA,IACpB,CAAC,MAA2C;AAG1C,UAAI,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAG;AACxE,QAAE,eAAe;AACjB,UAAI,GAAI,mCAAW,EAAE;AAAA,IACvB;AAAA,IACA,CAAC,EAAE;AAAA,EACL;AACA,MAAI,CAAC,GAAI,QAAO;AAGhB,QAAM,OAAO,KAAK,sBAAkB,mCAAkB,IAAI,WAAW,IAAI,EAAE,IAAI,IAAI,eAAe,IAAI,IAAI,EAAE;AAC5G,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV;AAAA,MACA,SAAS;AAAA,MACT,cAAW;AAAA,MACV,GAAG;AAAA,MAEJ,sDAAC,UAAK,eAAY,QAAO,eAAC;AAAA;AAAA,EAC5B;AAEJ;","names":[]}