@epilot/zenith-react 0.1.0-next.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/README.md +95 -15
  2. package/dist/components/appearance-boundary/appearance-boundary.js +32 -34
  3. package/dist/components/appearance-boundary/appearance-boundary.js.map +1 -1
  4. package/dist/components/badge/badge.js +1 -1
  5. package/dist/components/badge/badge.js.map +1 -1
  6. package/dist/components/breadcrumb/breadcrumb.js +10 -10
  7. package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
  8. package/dist/components/button/button.js +28 -28
  9. package/dist/components/button/button.js.map +1 -1
  10. package/dist/components/button-group/button-group.js.map +1 -1
  11. package/dist/components/callout/callout.js +13 -13
  12. package/dist/components/callout/callout.js.map +1 -1
  13. package/dist/components/card/card.js.map +1 -1
  14. package/dist/components/checkbox/checkbox.js +13 -13
  15. package/dist/components/checkbox/checkbox.js.map +1 -1
  16. package/dist/components/code-block/code-block.js +6 -6
  17. package/dist/components/code-block/code-block.js.map +1 -1
  18. package/dist/components/code-editor/code-editor.js +1 -1
  19. package/dist/components/code-editor/code-editor.js.map +1 -1
  20. package/dist/components/code-editor/indent.js.map +1 -1
  21. package/dist/components/command/command.js +7 -13
  22. package/dist/components/command/command.js.map +1 -1
  23. package/dist/components/data-table/data-table-body.js +120 -66
  24. package/dist/components/data-table/data-table-body.js.map +1 -1
  25. package/dist/components/data-table/data-table-column-header.js +7 -7
  26. package/dist/components/data-table/data-table-column-header.js.map +1 -1
  27. package/dist/components/data-table/data-table-column-order.js +277 -0
  28. package/dist/components/data-table/data-table-column-order.js.map +1 -0
  29. package/dist/components/data-table/data-table-content.js +72 -58
  30. package/dist/components/data-table/data-table-content.js.map +1 -1
  31. package/dist/components/data-table/data-table-context.js +8 -4
  32. package/dist/components/data-table/data-table-context.js.map +1 -1
  33. package/dist/components/data-table/data-table-footer.js +31 -0
  34. package/dist/components/data-table/data-table-footer.js.map +1 -0
  35. package/dist/components/data-table/data-table-header-draggable.js +151 -0
  36. package/dist/components/data-table/data-table-header-draggable.js.map +1 -0
  37. package/dist/components/data-table/data-table-header.js +130 -57
  38. package/dist/components/data-table/data-table-header.js.map +1 -1
  39. package/dist/components/data-table/data-table-resize-handle.js +137 -0
  40. package/dist/components/data-table/data-table-resize-handle.js.map +1 -0
  41. package/dist/components/data-table/data-table.js +184 -156
  42. package/dist/components/data-table/data-table.js.map +1 -1
  43. package/dist/components/data-table/hooks/use-data-table-virtualizer.js +9 -0
  44. package/dist/components/data-table/hooks/use-data-table-virtualizer.js.map +1 -0
  45. package/dist/components/date-range-picker/date-range-picker.js +197 -195
  46. package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
  47. package/dist/components/date-time-picker/calendar.js +29 -29
  48. package/dist/components/date-time-picker/calendar.js.map +1 -1
  49. package/dist/components/date-time-picker/time-picker.js +55 -55
  50. package/dist/components/date-time-picker/time-picker.js.map +1 -1
  51. package/dist/components/density-provider/density-provider.js.map +1 -1
  52. package/dist/components/dialog/dialog.js +1 -1
  53. package/dist/components/dialog/dialog.js.map +1 -1
  54. package/dist/components/drawer/drawer.js +5 -5
  55. package/dist/components/drawer/drawer.js.map +1 -1
  56. package/dist/components/dropdown-menu/dropdown-menu.js +36 -36
  57. package/dist/components/dropdown-menu/dropdown-menu.js.map +1 -1
  58. package/dist/components/field/field-combobox.js +4 -4
  59. package/dist/components/field/field-combobox.js.map +1 -1
  60. package/dist/components/field/field.js +40 -40
  61. package/dist/components/field/field.js.map +1 -1
  62. package/dist/components/label/label.js +0 -28
  63. package/dist/components/label/label.js.map +1 -1
  64. package/dist/components/list/list.js +42 -52
  65. package/dist/components/list/list.js.map +1 -1
  66. package/dist/components/option-card/option-card.js +27 -25
  67. package/dist/components/option-card/option-card.js.map +1 -1
  68. package/dist/components/pill/pill.js +9 -9
  69. package/dist/components/pill/pill.js.map +1 -1
  70. package/dist/components/radio/radio.js +14 -14
  71. package/dist/components/radio/radio.js.map +1 -1
  72. package/dist/components/scroll-area/scroll-area.js +9 -9
  73. package/dist/components/scroll-area/scroll-area.js.map +1 -1
  74. package/dist/components/segmented-control/segmented-control.js +1 -1
  75. package/dist/components/segmented-control/segmented-control.js.map +1 -1
  76. package/dist/components/select/select.js +11 -11
  77. package/dist/components/select/select.js.map +1 -1
  78. package/dist/components/separator/separator.js.map +1 -1
  79. package/dist/components/skeleton/skeleton.js.map +1 -1
  80. package/dist/components/slot/compose-as-child.js.map +1 -1
  81. package/dist/components/spinner/spinner.js.map +1 -1
  82. package/dist/components/switch/switch.js +11 -11
  83. package/dist/components/switch/switch.js.map +1 -1
  84. package/dist/components/table/table-pagination.js +1 -1
  85. package/dist/components/table/table-pagination.js.map +1 -1
  86. package/dist/components/table/table.js +15 -15
  87. package/dist/components/table/table.js.map +1 -1
  88. package/dist/components/text/text.js +10 -1
  89. package/dist/components/text/text.js.map +1 -1
  90. package/dist/components/toast/toast.js +30 -32
  91. package/dist/components/toast/toast.js.map +1 -1
  92. package/dist/components/toggle/toggle.js +20 -20
  93. package/dist/components/toggle/toggle.js.map +1 -1
  94. package/dist/delivery/index.d.ts +10 -44
  95. package/dist/delivery/index.js +5 -9
  96. package/dist/index.d.ts +1994 -2272
  97. package/dist/index.js +133 -121
  98. package/dist/index.js.map +1 -1
  99. package/dist/lib/clear-button.js.map +1 -1
  100. package/dist/lib/code-highlight.js.map +1 -1
  101. package/dist/lib/code-tokens.js.map +1 -1
  102. package/dist/lib/pagination.js.map +1 -1
  103. package/dist/packages/tokens/dist/delivery/index.js +18 -48
  104. package/dist/packages/tokens/dist/delivery/index.js.map +1 -1
  105. package/dist/packages/tokens/dist/generated/core.generated.js +18 -0
  106. package/dist/packages/tokens/dist/generated/core.generated.js.map +1 -0
  107. package/dist/packages/tokens/dist/generated/palette.generated.js +5 -5
  108. package/dist/packages/tokens/dist/generated/palette.generated.js.map +1 -1
  109. package/dist/packages/tokens/dist/install.js +9 -9
  110. package/dist/packages/tokens/dist/install.js.map +1 -1
  111. package/dist/styles/document-context.js.map +1 -1
  112. package/dist/styles/make-styles.js.map +1 -1
  113. package/dist/tokens/core.meta.generated.js +2 -2
  114. package/dist/tokens/core.meta.generated.js.map +1 -1
  115. package/dist/tokens/index.d.ts +1029 -1104
  116. package/dist/tokens/index.js +1031 -1106
  117. package/dist/tokens/index.js.map +1 -1
  118. package/dist/tokens/palette.generated.js +2 -2
  119. package/dist/tokens/palette.generated.js.map +1 -1
  120. package/dist/tokens/use-palette-tokens.js.map +1 -1
  121. package/dist/tokens.json +605 -755
  122. package/dist/vendor/.bun/@dnd-kit_core@6.3.1_6f4b9a1cfb20c0ae/vendor/@dnd-kit/core/dist/core.esm.js +385 -340
  123. package/dist/vendor/.bun/@dnd-kit_core@6.3.1_6f4b9a1cfb20c0ae/vendor/@dnd-kit/core/dist/core.esm.js.map +1 -1
  124. package/dist/vendor/.bun/@dnd-kit_sortable@10.0.0_1d291640e1250bbe/vendor/@dnd-kit/sortable/dist/sortable.esm.js +344 -229
  125. package/dist/vendor/.bun/@dnd-kit_sortable@10.0.0_1d291640e1250bbe/vendor/@dnd-kit/sortable/dist/sortable.esm.js.map +1 -1
  126. package/dist/vendor/.bun/@dnd-kit_utilities@3.2.2_62547eec5a2188e3/vendor/@dnd-kit/utilities/dist/utilities.esm.js +1 -1
  127. package/dist/vendor/.bun/@tanstack_react-virtual@3.11.2_6f4b9a1cfb20c0ae/vendor/@tanstack/react-virtual/dist/esm/index.js +36 -0
  128. package/dist/vendor/.bun/@tanstack_react-virtual@3.11.2_6f4b9a1cfb20c0ae/vendor/@tanstack/react-virtual/dist/esm/index.js.map +1 -0
  129. package/dist/vendor/.bun/@tanstack_virtual-core@3.11.2/vendor/@tanstack/virtual-core/dist/esm/index.js +450 -0
  130. package/dist/vendor/.bun/@tanstack_virtual-core@3.11.2/vendor/@tanstack/virtual-core/dist/esm/index.js.map +1 -0
  131. package/dist/vendor/.bun/@tanstack_virtual-core@3.11.2/vendor/@tanstack/virtual-core/dist/esm/utils.js +50 -0
  132. package/dist/vendor/.bun/@tanstack_virtual-core@3.11.2/vendor/@tanstack/virtual-core/dist/esm/utils.js.map +1 -0
  133. package/package.json +5 -4
  134. package/scripts/migration-diagnostics-core.mjs +19 -90
  135. package/scripts/migration-diagnostics.mjs +1 -16
  136. package/scripts/migration-sweep.mjs +2 -12
  137. package/ADOPTING.md +0 -73
  138. package/dist/packages/tokens/dist/delivery/internal.js +0 -181
  139. package/dist/packages/tokens/dist/delivery/internal.js.map +0 -1
  140. package/dist/packages/tokens/dist/generated/core.meta.generated.js +0 -10
  141. package/dist/packages/tokens/dist/generated/core.meta.generated.js.map +0 -1
  142. package/dist/token-assets/core/5cd4072decf5df2a664f0b1d5f2ec250a3309101ded3056c1f87c8bbe3738d50.css +0 -22
@@ -1 +1 @@
1
- {"version":3,"file":"code-block.js","sources":["../../../src/components/code-block/code-block.tsx"],"sourcesContent":["import * as React from \"react\"\n\nimport { mergeClasses, shorthands } from \"@epilot/zenith-runtime/v1\"\n\nimport { SLOT_ATTR } from \"../../renderer/contract\"\nimport { makeZenithStyles } from \"../../styles/make-styles\"\nimport * as tokens from \"../../tokens\"\nimport { Button } from \"../button/button\"\nimport { highlightCode, splitTokenLines } from \"../../lib/code-highlight\"\nimport { useCodeTokenRenderer } from \"../../lib/code-tokens\"\nimport { gutterDigits } from \"../../lib/code-lines\"\n\n/**\n * Read-only highlighted code. Source is rendered as text, and the focusable `<pre>` keeps\n * horizontal overflow keyboard-accessible.\n */\n\nconst COPY_FEEDBACK_MS = 2000\n\n/** Gutter width in monospace glyphs, shared by every numbered row. */\nconst GUTTER = \"--zenith-code-gutter\"\n\nconst useStyles = makeZenithStyles({\n root: {\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n position: \"relative\",\n // The same role recipe Surface's `section` uses, and the same property shapes, so a caller's\n // own border or radius replaces these through `mergeClasses` without a wrapper.\n backgroundColor: tokens.surfaceContainer,\n ...shorthands.borderWidth(tokens.borderWidthContainer),\n ...shorthands.borderStyle(\"solid\"),\n ...shorthands.borderColor(tokens.borderContainer),\n borderRadius: tokens.surfaceRadiusContainer,\n overflowX: \"hidden\",\n overflowY: \"hidden\",\n },\n // Griffel ancestor state selectors must be declared on the ancestor.\n rootCopyReveal: {\n \"&:hover [data-copy-state]\": { opacity: 1 },\n \"&:focus-within [data-copy-state]\": { opacity: 1 },\n },\n header: {\n display: \"flex\",\n alignItems: \"center\",\n ...shorthands.gap(tokens.spacingElement2),\n ...shorthands.paddingBlock(tokens.spacingElement1),\n ...shorthands.paddingInline(tokens.spacingElement2),\n // `borderBottom` expands to the three bottom-edge longhands; there is no per-edge width\n // helper, and a bare `borderBottomWidth: …` alongside a neighbour's `borderWidth` shorthand\n // is exactly the property-shape mismatch AGENTS.md rule 3 warns about.\n ...shorthands.borderBottom(\n tokens.borderWidthContainer,\n \"solid\",\n tokens.surfaceSep\n ),\n },\n // Reserve the overlay button's width when a caption is present.\n headerWithCopy: {\n paddingRight: `calc(1.75rem + ${tokens.spacingElement2} + ${tokens.spacingElement05})`,\n minHeight: `calc(1.75rem + ${tokens.spacingElement05} + ${tokens.spacingElement05})`,\n },\n title: {\n fontSize: tokens.textXs,\n lineHeight: tokens.leadingXs,\n fontWeight: tokens.fontWeightMedium,\n color: tokens.grayA12,\n minWidth: 0,\n overflowX: \"hidden\",\n overflowY: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n },\n language: {\n fontSize: tokens.textXs,\n lineHeight: tokens.leadingXs,\n color: tokens.grayA11,\n // The language label names a machine format, so it stays in the code family rather than\n // inheriting the surrounding UI face.\n fontFamily: tokens.fontMono,\n whiteSpace: \"nowrap\",\n },\n headerSpacer: {\n flexGrow: 1,\n flexShrink: 1,\n flexBasis: \"0%\",\n minWidth: 0,\n },\n // The button stays in the tab order while its paint is hidden.\n copy: {\n position: \"absolute\",\n top: tokens.spacingElement05,\n right: tokens.spacingElement05,\n zIndex: 1,\n backgroundColor: tokens.surfaceContainer,\n opacity: 0,\n transitionProperty: \"opacity\",\n transitionDuration: \"120ms\",\n \"@media (prefers-reduced-motion: reduce)\": {\n transitionDuration: \"0s\",\n },\n \"@media (hover: none)\": {\n opacity: 1,\n },\n // Focus and feedback must override the hidden resting state.\n \"&[data-copy-state='copied']\": { opacity: 1 },\n \"&[data-copy-state='error']\": { opacity: 1 },\n \"&:focus-visible\": { opacity: 1 },\n },\n pre: {\n ...shorthands.margin(0),\n ...shorthands.padding(tokens.spacingElement2),\n overflowX: \"auto\",\n overflowY: \"auto\",\n fontFamily: tokens.fontMono,\n fontSize: tokens.textXs,\n lineHeight: tokens.leadingXs,\n color: tokens.grayA12,\n // `tab-size` is what makes a tab-indented source line up at all; 2 matches the indent the\n // editor inserts by default.\n tabSize: 2,\n outlineStyle: \"none\",\n // Declared after the base so the focus ring wins, per the ordering rule in AGENTS.md.\n \":focus-visible\": {\n outlineWidth: \"2px\",\n outlineStyle: \"solid\",\n outlineOffset: \"-2px\",\n outlineColor: tokens.semFocusRing,\n },\n },\n // Sticky numbers must pin flush to the scrollport.\n preGutter: {\n paddingLeft: 0,\n },\n preNoWrap: {\n whiteSpace: \"pre\",\n },\n preWrap: {\n whiteSpace: \"pre-wrap\",\n overflowWrap: \"break-word\",\n },\n code: {\n // `<code>` is inline by default, which collapses the numbered-line grid to one row.\n display: \"block\",\n fontFamily: \"inherit\",\n fontSize: \"inherit\",\n lineHeight: \"inherit\",\n },\n // Give sticky gutters and row bands the full width of unwrapped code.\n codeNoWrap: {\n width: \"max-content\",\n minWidth: \"100%\",\n },\n line: {\n display: \"flex\",\n width: \"100%\",\n // Avoid sticky touch-hover states; paint both cells because the gutter is opaque.\n \"@media (hover: hover)\": {\n [`&:hover [${SLOT_ATTR}='code-block-line-number'], &:hover [${SLOT_ATTR}='code-block-line-content']`]:\n {\n backgroundImage: `linear-gradient(${tokens.grayA2}, ${tokens.grayA2})`,\n },\n },\n },\n lineNumber: {\n // Not selectable, so dragging a selection across the block copies code and not a column of\n // integers. The copy button never sees these at all — it copies the original `code` string.\n userSelect: \"none\",\n textAlign: \"right\",\n flexGrow: 0,\n flexShrink: 0,\n color: tokens.grayA8,\n boxSizing: \"border-box\",\n width: `calc(var(${GUTTER}) + ${tokens.spacingElement2} + ${tokens.spacingElement3})`,\n paddingLeft: tokens.spacingElement2,\n paddingRight: tokens.spacingElement3,\n // Opaque because horizontally scrolled code passes beneath the sticky gutter.\n position: \"sticky\",\n left: 0,\n backgroundColor: tokens.surfaceContainer,\n },\n lineContent: {\n minWidth: 0,\n flexGrow: 1,\n flexShrink: 1,\n flexBasis: \"auto\",\n },\n lineContentWrap: {\n overflowWrap: \"break-word\",\n },\n srOnly: {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n ...shorthands.padding(0),\n ...shorthands.margin(\"-1px\"),\n overflowX: \"hidden\",\n overflowY: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n },\n})\n\nconst CopyIcon = (props: React.ComponentProps<\"svg\">) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n {...props}\n >\n <rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" />\n <path d=\"M5 15V5a2 2 0 0 1 2-2h10\" />\n </svg>\n)\n\nconst CheckIcon = (props: React.ComponentProps<\"svg\">) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n {...props}\n >\n <path d=\"m4 12.5 5 5 11-11\" />\n </svg>\n)\n\n/** Idle, or the outcome of the last copy attempt. Drives both the icon and the live region. */\ntype CopyState = \"idle\" | \"copied\" | \"error\"\n\nexport type CodeBlockProps = Omit<\n React.ComponentProps<\"div\">,\n \"children\" | \"title\"\n> & {\n /** The source to display. Rendered as text — never as markup, and never evaluated. */\n code: string\n /** Language grammar used for syntax highlighting, also shown in the header. */\n language?: string\n /**\n * Visible caption, typically a file name. Also names the scrollable code region.\n *\n * This replaces the native `title` attribute, which would have rendered a browser tooltip\n * instead of a caption.\n */\n title?: string\n /** Soft-wrap long lines instead of scrolling horizontally. */\n wrap?: boolean\n /**\n * Render a non-selectable line-number gutter, and give each row a hover band.\n *\n * Off by default. Numbers are wayfinding for prose that refers to a line by number; on a\n * four-line snippet they are a column of noise that also costs horizontal space.\n */\n showLineNumbers?: boolean\n /** Show the copy button. */\n copyable?: boolean\n /** Accessible name of the copy button. */\n copyLabel?: string\n /** Announced, and used as the button's name, after a successful copy. */\n copiedLabel?: string\n /** Announced, and used as the button's name, when the clipboard is unavailable or refuses. */\n copyErrorLabel?: string\n /** Called with the exact string written to the clipboard. */\n onCopy?: (code: string) => void\n /** Called when the clipboard write failed or was unavailable. */\n onCopyError?: (error: unknown) => void\n}\n\nexport const CodeBlock = React.forwardRef<HTMLDivElement, CodeBlockProps>(\n function CodeBlock(\n {\n code,\n language,\n title,\n wrap = false,\n showLineNumbers = false,\n copyable = false,\n copyLabel = \"Copy code\",\n copiedLabel = \"Copied\",\n copyErrorLabel = \"Copy failed\",\n onCopy,\n onCopyError,\n className,\n style,\n ...props\n },\n ref\n ) {\n const styles = useStyles()\n const reactId = React.useId()\n const titleId = `${reactId}-title`\n\n const [copyState, setCopyState] = React.useState<CopyState>(\"idle\")\n const resetTimer = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n\n React.useEffect(\n () => () => {\n if (resetTimer.current !== null) clearTimeout(resetTimer.current)\n },\n []\n )\n\n const handleCopy = React.useCallback(async () => {\n // Read the clipboard off `navigator` at click time, never at import or render time: this is\n // the only browser-only access in the component, and an event handler cannot run on a\n // server. A missing or rejecting clipboard is an ordinary outcome here (insecure origin,\n // denied permission, older browser), not an exception to propagate.\n let failure: unknown = null\n try {\n const clipboard =\n typeof navigator === \"undefined\" ? undefined : navigator.clipboard\n if (typeof clipboard?.writeText !== \"function\") {\n failure = new Error(\"Clipboard API unavailable\")\n } else {\n await clipboard.writeText(code)\n }\n } catch (error) {\n failure = error ?? new Error(\"Clipboard write rejected\")\n }\n\n if (failure === null) onCopy?.(code)\n else onCopyError?.(failure)\n\n setCopyState(failure === null ? \"copied\" : \"error\")\n if (resetTimer.current !== null) clearTimeout(resetTimer.current)\n resetTimer.current = setTimeout(() => {\n resetTimer.current = null\n setCopyState(\"idle\")\n }, COPY_FEEDBACK_MS)\n }, [code, onCopy, onCopyError])\n\n // One trailing newline is an artefact of how source files end, not a line the reader should\n // see numbered and empty. The clipboard still gets `code` byte for byte.\n const displayed = code.endsWith(\"\\n\") ? code.slice(0, -1) : code\n const renderTokens = useCodeTokenRenderer()\n\n // Tokenized once per (source, language). Synchronous by construction, so the server render and\n // the first client render produce identical markup and hydration has nothing to reconcile.\n const highlighted = React.useMemo(\n () => highlightCode(displayed, language),\n [displayed, language]\n )\n\n // Two shapes, because the gutter needs rows: a plain string or a token run when there are no\n // line numbers, and one entry per line when there are.\n const plainLines = React.useMemo(\n () => (showLineNumbers ? displayed.split(\"\\n\") : null),\n [displayed, showLineNumbers]\n )\n const tokenLines = React.useMemo(\n () =>\n showLineNumbers && highlighted !== null\n ? splitTokenLines(highlighted)\n : null,\n [highlighted, showLineNumbers]\n )\n\n // An empty string is not a caption. Normalised once, so the header, the caption element and\n // the region's name can never disagree about whether there is one — labelling the region by an\n // empty caption would name it with nothing, which is worse than leaving it unnamed.\n const hasTitle = title !== undefined && title !== \"\"\n const hasLanguage = language !== undefined && language !== \"\"\n\n const ariaLabel = props[\"aria-label\"]\n const ariaLabelledBy = props[\"aria-labelledby\"]\n // A region needs a name. Prefer the caption the reader can see, then whatever the caller\n // supplied; with none of the three, stay focusable but claim no landmark.\n const labelledBy = hasTitle ? titleId : ariaLabelledBy\n const named = labelledBy !== undefined || ariaLabel !== undefined\n\n const copyStatusLabel =\n copyState === \"copied\"\n ? copiedLabel\n : copyState === \"error\"\n ? copyErrorLabel\n : copyLabel\n\n // A header exists for content. A copy button is an overlay and does not summon one — that is\n // what lets `<CodeBlock code copyable />` reserve no vertical space for chrome at all.\n const showHeader = hasTitle || hasLanguage\n\n const gutterStyle =\n plainLines === null\n ? style\n : ({\n [GUTTER]: `${gutterDigits(plainLines.length)}ch`,\n ...style,\n } as React.CSSProperties)\n\n return (\n <div\n ref={ref}\n data-slot=\"code-block\"\n {...{ [SLOT_ATTR]: \"code-block\" }}\n data-language={language}\n className={mergeClasses(\n styles.root,\n copyable ? styles.rootCopyReveal : undefined,\n className\n )}\n style={gutterStyle}\n {...props}\n aria-label={undefined}\n aria-labelledby={undefined}\n >\n {showHeader ? (\n <div\n data-slot=\"code-block-header\"\n {...{ [SLOT_ATTR]: \"code-block-header\" }}\n className={mergeClasses(\n styles.header,\n copyable ? styles.headerWithCopy : undefined\n )}\n >\n {hasTitle ? (\n <span\n id={titleId}\n data-slot=\"code-block-title\"\n {...{ [SLOT_ATTR]: \"code-block-title\" }}\n className={styles.title}\n >\n {title}\n </span>\n ) : null}\n {hasLanguage ? (\n <span\n data-slot=\"code-block-language\"\n {...{ [SLOT_ATTR]: \"code-block-language\" }}\n className={styles.language}\n >\n {language}\n </span>\n ) : null}\n <span className={styles.headerSpacer} />\n </div>\n ) : null}\n\n {copyable ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n // Button keeps its OWN slot markers, the way Callout leaves the ClearButton it\n // composes alone: a Button stays a Button, and a rule written against the button\n // slot must still reach this one. `data-copy-state` is the handle for this\n // button specifically, and it carries the state a caller would want to select on.\n data-copy-state={copyState}\n aria-label={copyStatusLabel}\n className={styles.copy}\n onClick={handleCopy}\n >\n {copyState === \"copied\" ? <CheckIcon /> : <CopyIcon />}\n </Button>\n ) : null}\n\n <pre\n data-slot=\"code-block-content\"\n {...{ [SLOT_ATTR]: \"code-block-content\" }}\n // Always reachable: this is the scroll container, and a pointer must not be the only\n // way to scroll it.\n tabIndex={0}\n role={named ? \"region\" : undefined}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n className={mergeClasses(\n styles.pre,\n plainLines === null ? undefined : styles.preGutter,\n wrap ? styles.preWrap : styles.preNoWrap\n )}\n >\n <code\n data-slot=\"code-block-code\"\n {...{ [SLOT_ATTR]: \"code-block-code\" }}\n className={mergeClasses(\n styles.code,\n plainLines !== null && !wrap ? styles.codeNoWrap : undefined\n )}\n >\n {plainLines === null\n ? // No gutter: one run, highlighted if we have a grammar, otherwise the raw string.\n highlighted === null\n ? displayed\n : renderTokens(highlighted)\n : plainLines.map((line, index) => (\n <span\n // Lines have no identity beyond their position, and the whole block\n // re-renders when `code` changes, so the index is the key.\n key={index}\n data-slot=\"code-block-line\"\n {...{ [SLOT_ATTR]: \"code-block-line\" }}\n data-line={index + 1}\n className={styles.line}\n >\n <span\n aria-hidden=\"true\"\n data-slot=\"code-block-line-number\"\n {...{ [SLOT_ATTR]: \"code-block-line-number\" }}\n className={styles.lineNumber}\n >\n {index + 1}\n </span>\n <span\n data-slot=\"code-block-line-content\"\n {...{ [SLOT_ATTR]: \"code-block-line-content\" }}\n className={mergeClasses(\n styles.lineContent,\n wrap ? styles.lineContentWrap : undefined\n )}\n >\n {/* `tokenLines` is the same text as `plainLines`, split by the same\n newlines — `splitTokenLines` round-trips — so the row count matches and\n the index is safe. Falls back to the plain line when there is no\n grammar. */}\n {tokenLines === null\n ? line\n : renderTokens(tokenLines[index] ?? [])}\n {/* The newline keeps a dragged selection line-separated, exactly as the\n unnumbered rendering is. */}\n {\"\\n\"}\n </span>\n </span>\n ))}\n </code>\n </pre>\n\n {copyable ? (\n <span\n role=\"status\"\n aria-live=\"polite\"\n data-slot=\"code-block-copy-status\"\n {...{ [SLOT_ATTR]: \"code-block-copy-status\" }}\n className={styles.srOnly}\n >\n {copyState === \"idle\" ? \"\" : copyStatusLabel}\n </span>\n ) : null}\n </div>\n )\n }\n)\n"],"names":["COPY_FEEDBACK_MS","GUTTER","useStyles","makeZenithStyles","tokens.surfaceContainer","shorthands","tokens.borderWidthContainer","tokens.borderContainer","tokens.surfaceRadiusContainer","tokens.spacingElement2","tokens.spacingElement1","tokens.surfaceSep","tokens.spacingElement05","tokens.textXs","tokens.leadingXs","tokens.fontWeightMedium","tokens.grayA12","tokens.grayA11","tokens.fontMono","tokens.semFocusRing","SLOT_ATTR","tokens.grayA2","tokens.grayA8","tokens.spacingElement3","CopyIcon","props","jsxs","jsx","CheckIcon","CodeBlock","React","code","language","title","wrap","showLineNumbers","copyable","copyLabel","copiedLabel","copyErrorLabel","onCopy","onCopyError","className","style","ref","styles","titleId","copyState","setCopyState","resetTimer","handleCopy","failure","clipboard","error","displayed","renderTokens","useCodeTokenRenderer","highlighted","highlightCode","plainLines","tokenLines","splitTokenLines","hasTitle","hasLanguage","ariaLabel","ariaLabelledBy","labelledBy","named","copyStatusLabel","showHeader","gutterStyle","gutterDigits","mergeClasses","Button","line","index"],"mappings":"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"}
1
+ {"version":3,"file":"code-block.js","sources":["../../../src/components/code-block/code-block.tsx"],"sourcesContent":["import * as React from \"react\"\n\nimport { mergeClasses, shorthands } from \"@epilot/zenith-runtime/v1\"\n\nimport { SLOT_ATTR } from \"../../renderer/contract\"\nimport { makeZenithStyles } from \"../../styles/make-styles\"\nimport * as tokens from \"../../tokens\"\nimport { Button } from \"../button/button\"\nimport { highlightCode, splitTokenLines } from \"../../lib/code-highlight\"\nimport { useCodeTokenRenderer } from \"../../lib/code-tokens\"\nimport { gutterDigits } from \"../../lib/code-lines\"\n\n/**\n * Read-only highlighted code. Source is rendered as text, and the focusable `<pre>` keeps\n * horizontal overflow keyboard-accessible.\n */\n\nconst COPY_FEEDBACK_MS = 2000\n\n/** Gutter width in monospace glyphs, shared by every numbered row. */\nconst GUTTER = \"--zenith-code-gutter\"\n\nconst useStyles = makeZenithStyles({\n root: {\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n position: \"relative\",\n // The same role recipe Surface's `section` uses, and the same property shapes, so a caller's\n // own border or radius replaces these through `mergeClasses` without a wrapper.\n backgroundColor: tokens.surfaceContainer,\n ...shorthands.borderWidth(tokens.borderWidthContainer),\n ...shorthands.borderStyle(\"solid\"),\n ...shorthands.borderColor(tokens.borderContainer),\n borderRadius: tokens.surfaceRadiusContainer,\n overflowX: \"hidden\",\n overflowY: \"hidden\",\n },\n // Griffel ancestor state selectors must be declared on the ancestor.\n rootCopyReveal: {\n \"&:hover [data-copy-state]\": { opacity: 1 },\n \"&:focus-within [data-copy-state]\": { opacity: 1 },\n },\n header: {\n display: \"flex\",\n alignItems: \"center\",\n ...shorthands.gap(tokens.spacingElement2),\n ...shorthands.paddingBlock(tokens.spacingElement1),\n ...shorthands.paddingInline(tokens.spacingElement2),\n // `borderBottom` expands to the three bottom-edge longhands; there is no per-edge width\n // helper, and a bare `borderBottomWidth: …` alongside a neighbour's `borderWidth` shorthand\n // is exactly the property-shape mismatch AGENTS.md rule 3 warns about.\n ...shorthands.borderBottom(\n tokens.borderWidthContainer,\n \"solid\",\n tokens.surfaceSep\n ),\n },\n // Reserve the overlay button's width when a caption is present.\n headerWithCopy: {\n paddingRight: `calc(1.75rem + ${tokens.spacingElement2} + ${tokens.spacingElement05})`,\n minHeight: `calc(1.75rem + ${tokens.spacingElement05} + ${tokens.spacingElement05})`,\n },\n title: {\n fontSize: tokens.textXs,\n lineHeight: tokens.leadingXs,\n fontWeight: tokens.fontWeightMedium,\n color: tokens.grayA12,\n minWidth: 0,\n overflowX: \"hidden\",\n overflowY: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n },\n language: {\n fontSize: tokens.textXs,\n lineHeight: tokens.leadingXs,\n color: tokens.grayA11,\n // The language label names a machine format, so it stays in the code family rather than\n // inheriting the surrounding UI face.\n fontFamily: tokens.fontMono,\n whiteSpace: \"nowrap\",\n },\n headerSpacer: {\n flexGrow: 1,\n flexShrink: 1,\n flexBasis: \"0%\",\n minWidth: 0,\n },\n // The button stays in the tab order while its paint is hidden.\n copy: {\n position: \"absolute\",\n top: tokens.spacingElement05,\n right: tokens.spacingElement05,\n zIndex: 1,\n backgroundColor: tokens.surfaceContainer,\n opacity: 0,\n transitionProperty: \"opacity\",\n transitionDuration: \"120ms\",\n \"@media (prefers-reduced-motion: reduce)\": {\n transitionDuration: \"0s\",\n },\n \"@media (hover: none)\": {\n opacity: 1,\n },\n // Focus and feedback must override the hidden resting state.\n \"&[data-copy-state='copied']\": { opacity: 1 },\n \"&[data-copy-state='error']\": { opacity: 1 },\n \"&:focus-visible\": { opacity: 1 },\n },\n pre: {\n ...shorthands.margin(0),\n ...shorthands.padding(tokens.spacingElement2),\n overflowX: \"auto\",\n overflowY: \"auto\",\n fontFamily: tokens.fontMono,\n fontSize: tokens.textXs,\n lineHeight: tokens.leadingXs,\n color: tokens.grayA12,\n // `tab-size` is what makes a tab-indented source line up at all; 2 matches the indent the\n // editor inserts by default.\n tabSize: 2,\n outlineStyle: \"none\",\n // Declared after the base so the focus ring wins, per the ordering rule in AGENTS.md.\n \":focus-visible\": {\n outlineWidth: \"2px\",\n outlineStyle: \"solid\",\n outlineOffset: \"-2px\",\n outlineColor: tokens.focusRing,\n },\n },\n // Sticky numbers must pin flush to the scrollport.\n preGutter: {\n paddingLeft: 0,\n },\n preNoWrap: {\n whiteSpace: \"pre\",\n },\n preWrap: {\n whiteSpace: \"pre-wrap\",\n overflowWrap: \"break-word\",\n },\n code: {\n // `<code>` is inline by default, which collapses the numbered-line grid to one row.\n display: \"block\",\n fontFamily: \"inherit\",\n fontSize: \"inherit\",\n lineHeight: \"inherit\",\n },\n // Give sticky gutters and row bands the full width of unwrapped code.\n codeNoWrap: {\n width: \"max-content\",\n minWidth: \"100%\",\n },\n line: {\n display: \"flex\",\n width: \"100%\",\n // Avoid sticky touch-hover states; paint both cells because the gutter is opaque.\n \"@media (hover: hover)\": {\n [`&:hover [${SLOT_ATTR}='code-block-line-number'], &:hover [${SLOT_ATTR}='code-block-line-content']`]:\n {\n backgroundImage: `linear-gradient(${tokens.grayA2}, ${tokens.grayA2})`,\n },\n },\n },\n lineNumber: {\n // Not selectable, so dragging a selection across the block copies code and not a column of\n // integers. The copy button never sees these at all — it copies the original `code` string.\n userSelect: \"none\",\n textAlign: \"right\",\n flexGrow: 0,\n flexShrink: 0,\n color: tokens.grayA8,\n boxSizing: \"border-box\",\n width: `calc(var(${GUTTER}) + ${tokens.spacingElement2} + ${tokens.spacingElement3})`,\n paddingLeft: tokens.spacingElement2,\n paddingRight: tokens.spacingElement3,\n // Opaque because horizontally scrolled code passes beneath the sticky gutter.\n position: \"sticky\",\n left: 0,\n backgroundColor: tokens.surfaceContainer,\n },\n lineContent: {\n minWidth: 0,\n flexGrow: 1,\n flexShrink: 1,\n flexBasis: \"auto\",\n },\n lineContentWrap: {\n overflowWrap: \"break-word\",\n },\n srOnly: {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n ...shorthands.padding(0),\n ...shorthands.margin(\"-1px\"),\n overflowX: \"hidden\",\n overflowY: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n },\n})\n\nconst CopyIcon = (props: React.ComponentProps<\"svg\">) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n {...props}\n >\n <rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" />\n <path d=\"M5 15V5a2 2 0 0 1 2-2h10\" />\n </svg>\n)\n\nconst CheckIcon = (props: React.ComponentProps<\"svg\">) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n {...props}\n >\n <path d=\"m4 12.5 5 5 11-11\" />\n </svg>\n)\n\n/** Idle, or the outcome of the last copy attempt. Drives both the icon and the live region. */\ntype CopyState = \"idle\" | \"copied\" | \"error\"\n\nexport type CodeBlockProps = Omit<\n React.ComponentProps<\"div\">,\n \"children\" | \"title\"\n> & {\n /** The source to display. Rendered as text — never as markup, and never evaluated. */\n code: string\n /** Language grammar used for syntax highlighting, also shown in the header. */\n language?: string\n /**\n * Visible caption, typically a file name. Also names the scrollable code region.\n *\n * This replaces the native `title` attribute, which would have rendered a browser tooltip\n * instead of a caption.\n */\n title?: string\n /** Soft-wrap long lines instead of scrolling horizontally. */\n wrap?: boolean\n /**\n * Render a non-selectable line-number gutter, and give each row a hover band.\n *\n * Off by default. Numbers are wayfinding for prose that refers to a line by number; on a\n * four-line snippet they are a column of noise that also costs horizontal space.\n */\n showLineNumbers?: boolean\n /** Show the copy button. */\n copyable?: boolean\n /** Accessible name of the copy button. */\n copyLabel?: string\n /** Announced, and used as the button's name, after a successful copy. */\n copiedLabel?: string\n /** Announced, and used as the button's name, when the clipboard is unavailable or refuses. */\n copyErrorLabel?: string\n /** Called with the exact string written to the clipboard. */\n onCopy?: (code: string) => void\n /** Called when the clipboard write failed or was unavailable. */\n onCopyError?: (error: unknown) => void\n}\n\nexport const CodeBlock = React.forwardRef<HTMLDivElement, CodeBlockProps>(\n function CodeBlock(\n {\n code,\n language,\n title,\n wrap = false,\n showLineNumbers = false,\n copyable = false,\n copyLabel = \"Copy code\",\n copiedLabel = \"Copied\",\n copyErrorLabel = \"Copy failed\",\n onCopy,\n onCopyError,\n className,\n style,\n ...props\n },\n ref\n ) {\n const styles = useStyles()\n const reactId = React.useId()\n const titleId = `${reactId}-title`\n\n const [copyState, setCopyState] = React.useState<CopyState>(\"idle\")\n const resetTimer = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n React.useEffect(\n () => () => {\n if (resetTimer.current !== null) clearTimeout(resetTimer.current)\n },\n []\n )\n\n const handleCopy = React.useCallback(async () => {\n // Read the clipboard off `navigator` at click time, never at import or render time: this is\n // the only browser-only access in the component, and an event handler cannot run on a\n // server. A missing or rejecting clipboard is an ordinary outcome here (insecure origin,\n // denied permission, older browser), not an exception to propagate.\n let failure: unknown = null\n try {\n const clipboard =\n typeof navigator === \"undefined\" ? undefined : navigator.clipboard\n if (typeof clipboard?.writeText !== \"function\") {\n failure = new Error(\"Clipboard API unavailable\")\n } else {\n await clipboard.writeText(code)\n }\n } catch (error) {\n failure = error ?? new Error(\"Clipboard write rejected\")\n }\n\n if (failure === null) onCopy?.(code)\n else onCopyError?.(failure)\n\n setCopyState(failure === null ? \"copied\" : \"error\")\n if (resetTimer.current !== null) clearTimeout(resetTimer.current)\n resetTimer.current = setTimeout(() => {\n resetTimer.current = null\n setCopyState(\"idle\")\n }, COPY_FEEDBACK_MS)\n }, [code, onCopy, onCopyError])\n\n // One trailing newline is an artefact of how source files end, not a line the reader should\n // see numbered and empty. The clipboard still gets `code` byte for byte.\n const displayed = code.endsWith(\"\\n\") ? code.slice(0, -1) : code\n const renderTokens = useCodeTokenRenderer()\n\n // Tokenized once per (source, language). Synchronous by construction, so the server render and\n // the first client render produce identical markup and hydration has nothing to reconcile.\n const highlighted = React.useMemo(\n () => highlightCode(displayed, language),\n [displayed, language]\n )\n\n // Two shapes, because the gutter needs rows: a plain string or a token run when there are no\n // line numbers, and one entry per line when there are.\n const plainLines = React.useMemo(\n () => (showLineNumbers ? displayed.split(\"\\n\") : null),\n [displayed, showLineNumbers]\n )\n const tokenLines = React.useMemo(\n () =>\n showLineNumbers && highlighted !== null\n ? splitTokenLines(highlighted)\n : null,\n [highlighted, showLineNumbers]\n )\n\n // An empty string is not a caption. Normalised once, so the header, the caption element and\n // the region's name can never disagree about whether there is one — labelling the region by an\n // empty caption would name it with nothing, which is worse than leaving it unnamed.\n const hasTitle = title !== undefined && title !== \"\"\n const hasLanguage = language !== undefined && language !== \"\"\n\n const ariaLabel = props[\"aria-label\"]\n const ariaLabelledBy = props[\"aria-labelledby\"]\n // A region needs a name. Prefer the caption the reader can see, then whatever the caller\n // supplied; with none of the three, stay focusable but claim no landmark.\n const labelledBy = hasTitle ? titleId : ariaLabelledBy\n const named = labelledBy !== undefined || ariaLabel !== undefined\n\n const copyStatusLabel =\n copyState === \"copied\"\n ? copiedLabel\n : copyState === \"error\"\n ? copyErrorLabel\n : copyLabel\n\n // A header exists for content. A copy button is an overlay and does not summon one — that is\n // what lets `<CodeBlock code copyable />` reserve no vertical space for chrome at all.\n const showHeader = hasTitle || hasLanguage\n\n const gutterStyle =\n plainLines === null\n ? style\n : ({\n [GUTTER]: `${gutterDigits(plainLines.length)}ch`,\n ...style,\n } as React.CSSProperties)\n\n return (\n <div\n ref={ref}\n data-slot=\"code-block\"\n {...{ [SLOT_ATTR]: \"code-block\" }}\n data-language={language}\n className={mergeClasses(\n styles.root,\n copyable ? styles.rootCopyReveal : undefined,\n className\n )}\n style={gutterStyle}\n {...props}\n aria-label={undefined}\n aria-labelledby={undefined}\n >\n {showHeader ? (\n <div\n data-slot=\"code-block-header\"\n {...{ [SLOT_ATTR]: \"code-block-header\" }}\n className={mergeClasses(\n styles.header,\n copyable ? styles.headerWithCopy : undefined\n )}\n >\n {hasTitle ? (\n <span\n id={titleId}\n data-slot=\"code-block-title\"\n {...{ [SLOT_ATTR]: \"code-block-title\" }}\n className={styles.title}\n >\n {title}\n </span>\n ) : null}\n {hasLanguage ? (\n <span\n data-slot=\"code-block-language\"\n {...{ [SLOT_ATTR]: \"code-block-language\" }}\n className={styles.language}\n >\n {language}\n </span>\n ) : null}\n <span className={styles.headerSpacer} />\n </div>\n ) : null}\n\n {copyable ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n // Button keeps its OWN slot markers, the way Callout leaves the ClearButton it\n // composes alone: a Button stays a Button, and a rule written against the button\n // slot must still reach this one. `data-copy-state` is the handle for this\n // button specifically, and it carries the state a caller would want to select on.\n data-copy-state={copyState}\n aria-label={copyStatusLabel}\n className={styles.copy}\n onClick={handleCopy}\n >\n {copyState === \"copied\" ? <CheckIcon /> : <CopyIcon />}\n </Button>\n ) : null}\n\n <pre\n data-slot=\"code-block-content\"\n {...{ [SLOT_ATTR]: \"code-block-content\" }}\n // Always reachable: this is the scroll container, and a pointer must not be the only\n // way to scroll it.\n tabIndex={0}\n role={named ? \"region\" : undefined}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n className={mergeClasses(\n styles.pre,\n plainLines === null ? undefined : styles.preGutter,\n wrap ? styles.preWrap : styles.preNoWrap\n )}\n >\n <code\n data-slot=\"code-block-code\"\n {...{ [SLOT_ATTR]: \"code-block-code\" }}\n className={mergeClasses(\n styles.code,\n plainLines !== null && !wrap ? styles.codeNoWrap : undefined\n )}\n >\n {plainLines === null\n ? // No gutter: one run, highlighted if we have a grammar, otherwise the raw string.\n highlighted === null\n ? displayed\n : renderTokens(highlighted)\n : plainLines.map((line, index) => (\n <span\n // Lines have no identity beyond their position, and the whole block\n // re-renders when `code` changes, so the index is the key.\n key={index}\n data-slot=\"code-block-line\"\n {...{ [SLOT_ATTR]: \"code-block-line\" }}\n data-line={index + 1}\n className={styles.line}\n >\n <span\n aria-hidden=\"true\"\n data-slot=\"code-block-line-number\"\n {...{ [SLOT_ATTR]: \"code-block-line-number\" }}\n className={styles.lineNumber}\n >\n {index + 1}\n </span>\n <span\n data-slot=\"code-block-line-content\"\n {...{ [SLOT_ATTR]: \"code-block-line-content\" }}\n className={mergeClasses(\n styles.lineContent,\n wrap ? styles.lineContentWrap : undefined\n )}\n >\n {/* `tokenLines` is the same text as `plainLines`, split by the same\n newlines — `splitTokenLines` round-trips — so the row count matches and\n the index is safe. Falls back to the plain line when there is no\n grammar. */}\n {tokenLines === null\n ? line\n : renderTokens(tokenLines[index] ?? [])}\n {/* The newline keeps a dragged selection line-separated, exactly as the\n unnumbered rendering is. */}\n {\"\\n\"}\n </span>\n </span>\n ))}\n </code>\n </pre>\n\n {copyable ? (\n <span\n role=\"status\"\n aria-live=\"polite\"\n data-slot=\"code-block-copy-status\"\n {...{ [SLOT_ATTR]: \"code-block-copy-status\" }}\n className={styles.srOnly}\n >\n {copyState === \"idle\" ? \"\" : copyStatusLabel}\n </span>\n ) : null}\n </div>\n )\n }\n)\n"],"names":["COPY_FEEDBACK_MS","GUTTER","useStyles","makeZenithStyles","tokens.surfaceContainer","shorthands","tokens.borderWidthContainer","tokens.borderContainer","tokens.surfaceRadiusContainer","tokens.spacingElement2","tokens.spacingElement1","tokens.surfaceSep","tokens.spacingElement05","tokens.textXs","tokens.leadingXs","tokens.fontWeightMedium","tokens.grayA12","tokens.grayA11","tokens.fontMono","tokens.focusRing","SLOT_ATTR","tokens.grayA2","tokens.grayA8","tokens.spacingElement3","CopyIcon","props","jsxs","jsx","CheckIcon","CodeBlock","React","code","language","title","wrap","showLineNumbers","copyable","copyLabel","copiedLabel","copyErrorLabel","onCopy","onCopyError","className","style","ref","styles","titleId","copyState","setCopyState","resetTimer","handleCopy","failure","clipboard","error","displayed","renderTokens","useCodeTokenRenderer","highlighted","highlightCode","plainLines","tokenLines","splitTokenLines","hasTitle","hasLanguage","ariaLabel","ariaLabelledBy","labelledBy","named","copyStatusLabel","showHeader","gutterStyle","gutterDigits","mergeClasses","Button","line","index"],"mappings":";;;;;;;;;AAiBA,MAAMA,KAAmB,KAGnBC,IAAS,wBAETC,KAAYC,GAAiB;AAAA,EACjC,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IACf,UAAU;AAAA,IACV,UAAU;AAAA;AAAA;AAAA,IAGV,iBAAiBC;AAAAA,IACjB,GAAGC,EAAW,YAAYC,CAA2B;AAAA,IACrD,GAAGD,EAAW,YAAY,OAAO;AAAA,IACjC,GAAGA,EAAW,YAAYE,EAAsB;AAAA,IAChD,cAAcC;AAAAA,IACd,WAAW;AAAA,IACX,WAAW;AAAA,EAAA;AAAA;AAAA,EAGb,gBAAgB;AAAA,IACd,6BAA6B,EAAE,SAAS,EAAA;AAAA,IACxC,oCAAoC,EAAE,SAAS,EAAA;AAAA,EAAE;AAAA,EAEnD,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,GAAGH,EAAW,IAAII,CAAsB;AAAA,IACxC,GAAGJ,EAAW,aAAaK,EAAsB;AAAA,IACjD,GAAGL,EAAW,cAAcI,CAAsB;AAAA;AAAA;AAAA;AAAA,IAIlD,GAAGJ,EAAW;AAAA,MACZC;AAAAA,MACA;AAAA,MACAK;AAAAA,IAAO;AAAA,EACT;AAAA;AAAA,EAGF,gBAAgB;AAAA,IACd,cAAc,kBAAkBF,CAAsB,MAAMG,CAAuB;AAAA,IACnF,WAAW,kBAAkBA,CAAuB,MAAMA,CAAuB;AAAA,EAAA;AAAA,EAEnF,OAAO;AAAA,IACL,UAAUC;AAAAA,IACV,YAAYC;AAAAA,IACZ,YAAYC;AAAAA,IACZ,OAAOC;AAAAA,IACP,UAAU;AAAA,IACV,WAAW;AAAA,IACX,WAAW;AAAA,IACX,cAAc;AAAA,IACd,YAAY;AAAA,EAAA;AAAA,EAEd,UAAU;AAAA,IACR,UAAUH;AAAAA,IACV,YAAYC;AAAAA,IACZ,OAAOG;AAAAA;AAAAA;AAAAA,IAGP,YAAYC;AAAAA,IACZ,YAAY;AAAA,EAAA;AAAA,EAEd,cAAc;AAAA,IACZ,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,UAAU;AAAA,EAAA;AAAA;AAAA,EAGZ,MAAM;AAAA,IACJ,UAAU;AAAA,IACV,KAAKN;AAAAA,IACL,OAAOA;AAAAA,IACP,QAAQ;AAAA,IACR,iBAAiBR;AAAAA,IACjB,SAAS;AAAA,IACT,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,2CAA2C;AAAA,MACzC,oBAAoB;AAAA,IAAA;AAAA,IAEtB,wBAAwB;AAAA,MACtB,SAAS;AAAA,IAAA;AAAA;AAAA,IAGX,+BAA+B,EAAE,SAAS,EAAA;AAAA,IAC1C,8BAA8B,EAAE,SAAS,EAAA;AAAA,IACzC,mBAAmB,EAAE,SAAS,EAAA;AAAA,EAAE;AAAA,EAElC,KAAK;AAAA,IACH,GAAGC,EAAW,OAAO,CAAC;AAAA,IACtB,GAAGA,EAAW,QAAQI,CAAsB;AAAA,IAC5C,WAAW;AAAA,IACX,WAAW;AAAA,IACX,YAAYS;AAAAA,IACZ,UAAUL;AAAAA,IACV,YAAYC;AAAAA,IACZ,OAAOE;AAAAA;AAAAA;AAAAA,IAGP,SAAS;AAAA,IACT,cAAc;AAAA;AAAA,IAEd,kBAAkB;AAAA,MAChB,cAAc;AAAA,MACd,cAAc;AAAA,MACd,eAAe;AAAA,MACf,cAAcG;AAAAA,IAAO;AAAA,EACvB;AAAA;AAAA,EAGF,WAAW;AAAA,IACT,aAAa;AAAA,EAAA;AAAA,EAEf,WAAW;AAAA,IACT,YAAY;AAAA,EAAA;AAAA,EAEd,SAAS;AAAA,IACP,YAAY;AAAA,IACZ,cAAc;AAAA,EAAA;AAAA,EAEhB,MAAM;AAAA;AAAA,IAEJ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,YAAY;AAAA,EAAA;AAAA;AAAA,EAGd,YAAY;AAAA,IACV,OAAO;AAAA,IACP,UAAU;AAAA,EAAA;AAAA,EAEZ,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,OAAO;AAAA;AAAA,IAEP,yBAAyB;AAAA,MACvB,CAAC,YAAYC,CAAS,wCAAwCA,CAAS,6BAA6B,GAClG;AAAA,QACE,iBAAiB,mBAAmBC,CAAa,KAAKA,CAAa;AAAA,MAAA;AAAA,IACrE;AAAA,EACJ;AAAA,EAEF,YAAY;AAAA;AAAA;AAAA,IAGV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAOC;AAAAA,IACP,WAAW;AAAA,IACX,OAAO,YAAYrB,CAAM,OAAOQ,CAAsB,MAAMc,CAAsB;AAAA,IAClF,aAAad;AAAAA,IACb,cAAcc;AAAAA;AAAAA,IAEd,UAAU;AAAA,IACV,MAAM;AAAA,IACN,iBAAiBnB;AAAAA,EAAO;AAAA,EAE1B,aAAa;AAAA,IACX,UAAU;AAAA,IACV,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,EAAA;AAAA,EAEb,iBAAiB;AAAA,IACf,cAAc;AAAA,EAAA;AAAA,EAEhB,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,GAAGC,EAAW,QAAQ,CAAC;AAAA,IACvB,GAAGA,EAAW,OAAO,MAAM;AAAA,IAC3B,WAAW;AAAA,IACX,WAAW;AAAA,IACX,MAAM;AAAA,IACN,YAAY;AAAA,EAAA;AAEhB,CAAC,GAEKmB,KAAW,CAACC,MAChB,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAY;AAAA,IACZ,eAAc;AAAA,IACd,gBAAe;AAAA,IACf,eAAY;AAAA,IACZ,WAAU;AAAA,IACT,GAAGD;AAAA,IAEJ,UAAA;AAAA,MAAA,gBAAAE,EAAC,QAAA,EAAK,GAAE,KAAI,GAAE,KAAI,OAAM,MAAK,QAAO,MAAK,IAAG,IAAA,CAAI;AAAA,MAChD,gBAAAA,EAAC,QAAA,EAAK,GAAE,2BAAA,CAA2B;AAAA,IAAA;AAAA,EAAA;AACrC,GAGIC,KAAY,CAACH,MACjB,gBAAAE;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAY;AAAA,IACZ,eAAc;AAAA,IACd,gBAAe;AAAA,IACf,eAAY;AAAA,IACZ,WAAU;AAAA,IACT,GAAGF;AAAA,IAEJ,UAAA,gBAAAE,EAAC,QAAA,EAAK,GAAE,oBAAA,CAAoB;AAAA,EAAA;AAC9B,GA4CWE,KAAYC,EAAM;AAAA,EAC7B,SACE;AAAA,IACE,MAAAC;AAAA,IACA,UAAAC;AAAA,IACA,OAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,iBAAAC,IAAkB;AAAA,IAClB,UAAAC,IAAW;AAAA,IACX,WAAAC,IAAY;AAAA,IACZ,aAAAC,IAAc;AAAA,IACd,gBAAAC,IAAiB;AAAA,IACjB,QAAAC;AAAA,IACA,aAAAC;AAAA,IACA,WAAAC;AAAA,IACA,OAAAC;AAAA,IACA,GAAGlB;AAAA,EAAA,GAELmB,GACA;AACA,UAAMC,IAAS3C,GAAA,GAET4C,IAAU,GADAhB,EAAM,MAAA,CACI,UAEpB,CAACiB,GAAWC,CAAY,IAAIlB,EAAM,SAAoB,MAAM,GAC5DmB,IAAanB,EAAM,OAA6C,IAAI;AAC1E,IAAAA,EAAM;AAAA,MACJ,MAAM,MAAM;AACV,QAAImB,EAAW,YAAY,QAAM,aAAaA,EAAW,OAAO;AAAA,MAClE;AAAA,MACA,CAAA;AAAA,IAAC;AAGH,UAAMC,IAAapB,EAAM,YAAY,YAAY;AAK/C,UAAIqB,IAAmB;AACvB,UAAI;AACF,cAAMC,IACJ,OAAO,YAAc,MAAc,SAAY,UAAU;AAC3D,QAAI,QAAOA,KAAA,gBAAAA,EAAW,cAAc,aAClCD,IAAU,IAAI,MAAM,2BAA2B,IAE/C,MAAMC,EAAU,UAAUrB,CAAI;AAAA,MAElC,SAASsB,GAAO;AACd,QAAAF,IAAUE,KAAS,IAAI,MAAM,0BAA0B;AAAA,MACzD;AAEA,MAAIF,MAAY,OAAMX,KAAA,QAAAA,EAAST,oBACZoB,IAEnBH,EAAaG,MAAY,OAAO,WAAW,OAAO,GAC9CF,EAAW,YAAY,QAAM,aAAaA,EAAW,OAAO,GAChEA,EAAW,UAAU,WAAW,MAAM;AACpC,QAAAA,EAAW,UAAU,MACrBD,EAAa,MAAM;AAAA,MACrB,GAAGhD,EAAgB;AAAA,IACrB,GAAG,CAAC+B,GAAMS,GAAQC,CAAW,CAAC,GAIxBa,IAAYvB,EAAK,SAAS;AAAA,CAAI,IAAIA,EAAK,MAAM,GAAG,EAAE,IAAIA,GACtDwB,IAAeC,GAAA,GAIfC,IAAc3B,EAAM;AAAA,MACxB,MAAM4B,GAAcJ,GAAWtB,CAAQ;AAAA,MACvC,CAACsB,GAAWtB,CAAQ;AAAA,IAAA,GAKhB2B,IAAa7B,EAAM;AAAA,MACvB,MAAOK,IAAkBmB,EAAU,MAAM;AAAA,CAAI,IAAI;AAAA,MACjD,CAACA,GAAWnB,CAAe;AAAA,IAAA,GAEvByB,IAAa9B,EAAM;AAAA,MACvB,MACEK,KAAmBsB,MAAgB,OAC/BI,GAAgBJ,CAAW,IAC3B;AAAA,MACN,CAACA,GAAatB,CAAe;AAAA,IAAA,GAMzB2B,IAAW7B,MAAU,UAAaA,MAAU,IAC5C8B,IAAc/B,MAAa,UAAaA,MAAa,IAErDgC,IAAYvC,EAAM,YAAY,GAC9BwC,IAAiBxC,EAAM,iBAAiB,GAGxCyC,IAAaJ,IAAWhB,IAAUmB,GAClCE,IAAQD,MAAe,UAAaF,MAAc,QAElDI,IACJrB,MAAc,WACVT,IACAS,MAAc,UACZR,IACAF,GAIFgC,IAAaP,KAAYC,GAEzBO,KACJX,MAAe,OACXhB,IACC;AAAA,MACC,CAAC1C,CAAM,GAAG,GAAGsE,GAAaZ,EAAW,MAAM,CAAC;AAAA,MAC5C,GAAGhB;AAAA,IAAA;AAGX,WACE,gBAAAjB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAAkB;AAAA,QACA,aAAU;AAAA,QACJ,CAACxB,CAAS,GAAG;AAAA,QACnB,iBAAeY;AAAA,QACf,WAAWwC;AAAA,UACT3B,EAAO;AAAA,UACPT,IAAWS,EAAO,iBAAiB;AAAA,UACnCH;AAAA,QAAA;AAAA,QAEF,OAAO4B;AAAA,QACN,GAAG7C;AAAA,QACJ,cAAY;AAAA,QACZ,mBAAiB;AAAA,QAEhB,UAAA;AAAA,UAAA4C,IACC,gBAAA3C;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,aAAU;AAAA,cACJ,CAACN,CAAS,GAAG;AAAA,cACnB,WAAWoD;AAAA,gBACT3B,EAAO;AAAA,gBACPT,IAAWS,EAAO,iBAAiB;AAAA,cAAA;AAAA,cAGpC,UAAA;AAAA,gBAAAiB,IACC,gBAAAnC;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,IAAImB;AAAA,oBACJ,aAAU;AAAA,oBACJ,CAAC1B,CAAS,GAAG;AAAA,oBACnB,WAAWyB,EAAO;AAAA,oBAEjB,UAAAZ;AAAA,kBAAA;AAAA,gBAAA,IAED;AAAA,gBACH8B,IACC,gBAAApC;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,aAAU;AAAA,oBACJ,CAACP,CAAS,GAAG;AAAA,oBACnB,WAAWyB,EAAO;AAAA,oBAEjB,UAAAb;AAAA,kBAAA;AAAA,gBAAA,IAED;AAAA,gBACJ,gBAAAL,EAAC,QAAA,EAAK,WAAWkB,EAAO,aAAA,CAAc;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA,IAEtC;AAAA,UAEHT,IACC,gBAAAT;AAAA,YAAC8C;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cAKL,mBAAiB1B;AAAA,cACjB,cAAYqB;AAAA,cACZ,WAAWvB,EAAO;AAAA,cAClB,SAASK;AAAA,cAER,gBAAc,WAAW,gBAAAvB,EAACC,IAAA,EAAU,sBAAMJ,IAAA,CAAA,CAAS;AAAA,YAAA;AAAA,UAAA,IAEpD;AAAA,UAEJ,gBAAAG;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,aAAU;AAAA,cACJ,CAACP,CAAS,GAAG;AAAA,cAGnB,UAAU;AAAA,cACV,MAAM+C,IAAQ,WAAW;AAAA,cACzB,cAAYH;AAAA,cACZ,mBAAiBE;AAAA,cACjB,WAAWM;AAAA,gBACT3B,EAAO;AAAA,gBACPc,MAAe,OAAO,SAAYd,EAAO;AAAA,gBACzCX,IAAOW,EAAO,UAAUA,EAAO;AAAA,cAAA;AAAA,cAGjC,UAAA,gBAAAlB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,aAAU;AAAA,kBACJ,CAACP,CAAS,GAAG;AAAA,kBACnB,WAAWoD;AAAA,oBACT3B,EAAO;AAAA,oBACPc,MAAe,QAAQ,CAACzB,IAAOW,EAAO,aAAa;AAAA,kBAAA;AAAA,kBAGpD,UAAAc,MAAe;AAAA;AAAA,oBAEZF,MAAgB,OACdH,IACAC,EAAaE,CAAW;AAAA,sBAC1BE,EAAW,IAAI,CAACe,GAAMC,MACpB,gBAAAjD;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBAIC,aAAU;AAAA,sBACJ,CAACN,CAAS,GAAG;AAAA,sBACnB,aAAWuD,IAAQ;AAAA,sBACnB,WAAW9B,EAAO;AAAA,sBAElB,UAAA;AAAA,wBAAA,gBAAAlB;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,eAAY;AAAA,4BACZ,aAAU;AAAA,4BACJ,CAACP,CAAS,GAAG;AAAA,4BACnB,WAAWyB,EAAO;AAAA,4BAEjB,UAAA8B,IAAQ;AAAA,0BAAA;AAAA,wBAAA;AAAA,wBAEX,gBAAAjD;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,aAAU;AAAA,4BACJ,CAACN,CAAS,GAAG;AAAA,4BACnB,WAAWoD;AAAA,8BACT3B,EAAO;AAAA,8BACPX,IAAOW,EAAO,kBAAkB;AAAA,4BAAA;AAAA,4BAOjC,UAAA;AAAA,8BAAAe,MAAe,OACZc,IACAnB,EAAaK,EAAWe,CAAK,KAAK,EAAE;AAAA,8BAGvC;AAAA;AAAA,4BAAA;AAAA,0BAAA;AAAA,wBAAA;AAAA,sBACH;AAAA,oBAAA;AAAA,oBAhCKA;AAAA,kBAAA,CAkCR;AAAA,gBAAA;AAAA,cAAA;AAAA,YACP;AAAA,UAAA;AAAA,UAGDvC,IACC,gBAAAT;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,aAAU;AAAA,cACV,aAAU;AAAA,cACJ,CAACP,CAAS,GAAG;AAAA,cACnB,WAAWyB,EAAO;AAAA,cAEjB,UAAAE,MAAc,SAAS,KAAKqB;AAAA,YAAA;AAAA,UAAA,IAE7B;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGV;AACF;"}
@@ -2,7 +2,7 @@ import { jsxs as j, jsx as n } from "react/jsx-runtime";
2
2
  import * as t from "react";
3
3
  import { mergeClasses as m, SLOT_ATTR as c, shorthands as l } from "@epilot/zenith-runtime/v1";
4
4
  import { makeZenithStyles as it } from "../../styles/make-styles.js";
5
- import { leadingXs as le, spacingElement2 as k, surfaceField as oe, spacingElement05 as ze, info11 as nt, warning11 as lt, error11 as at, semInfoUi as st, semWarningUi as ct, semErrorUi as De, grayA12 as _, spacingElement3 as ie, grayA8 as ne, grayA2 as We, accentA5 as dt, fontWeightNormal as ut, trackingNormal as ft, textXs as ht, fontMono as gt, grayA3 as Re, semFocusRing as mt, surfaceRadiusField as pt, borderField as vt, borderWidthField as bt } from "../../tokens/index.js";
5
+ import { leadingXs as le, spacingElement2 as k, surfaceField as oe, spacingElement05 as ze, info11 as nt, warning11 as lt, error11 as at, infoUi as st, warningUi as ct, errorUi as De, grayA12 as _, spacingElement3 as ie, grayA8 as ne, grayA2 as We, accentA5 as dt, fontWeightNormal as ut, trackingNormal as ft, textXs as ht, fontMono as gt, grayA3 as Re, focusRing as mt, surfaceRadiusField as pt, borderField as vt, borderWidthField as bt } from "../../tokens/index.js";
6
6
  import { Button as yt } from "../button/button.js";
7
7
  import { applyIndent as kt } from "./indent.js";
8
8
  import { highlightCode as xt, splitTokenLines as St } from "../../lib/code-highlight.js";
@@ -1 +1 @@
1
- {"version":3,"file":"code-editor.js","sources":["../../../src/components/code-editor/code-editor.tsx"],"sourcesContent":["import * as React from \"react\"\n\nimport { mergeClasses, shorthands } from \"@epilot/zenith-runtime/v1\"\n\nimport { SLOT_ATTR } from \"../../renderer/contract\"\nimport { makeZenithStyles } from \"../../styles/make-styles\"\nimport * as tokens from \"../../tokens\"\nimport { Button } from \"../button/button\"\nimport { applyIndent } from \"./indent\"\nimport { highlightCode, splitTokenLines } from \"../../lib/code-highlight\"\nimport { useCodeTokenRenderer } from \"../../lib/code-tokens\"\nimport {\n caretAfterRewrite,\n gutterDigits,\n lineIndexAt,\n severityByLine,\n visibleDiagnostics,\n type CodeDiagnostic,\n type CodeDiagnosticSeverity,\n} from \"../../lib/code-lines\"\n\n/**\n * Compact code editing on a native textarea. Highlighting is decorative; the textarea remains the\n * only focusable, labelled, form-participating control. Formatting and diagnostics are supplied by\n * the caller rather than computed here.\n */\n\n/** How long a formatting outcome stays in the live region. */\nconst FORMAT_FEEDBACK_MS = 2000\n\n/** Shared gutter width for the number cells and textarea padding. */\nconst GUTTER = \"--zenith-code-gutter\"\n\n/**\n * Metrics shared by the textarea and highlight layer. `tabSize` varies per instance and gutter\n * padding intentionally differs between layers.\n */\nconst CODE_METRICS = {\n ...shorthands.margin(0),\n ...shorthands.borderWidth(0),\n ...shorthands.borderStyle(\"none\"),\n ...shorthands.padding(tokens.spacingElement2),\n fontFamily: tokens.fontMono,\n fontSize: tokens.textXs,\n lineHeight: tokens.leadingXs,\n letterSpacing: tokens.trackingNormal,\n fontWeight: tokens.fontWeightNormal,\n textIndent: 0,\n boxSizing: \"border-box\",\n // A classic, space-consuming scrollbar narrows the textarea's content box but not the layer's,\n // which moves where wrapped lines break. Reserving the gutter on both keeps one content width.\n // Platforms with overlay scrollbars never had the problem.\n scrollbarGutter: \"stable\",\n} as const\n\n/** Core-sheet colours used by diagnostic rules and numbers. */\nconst SEVERITY_TOKENS: Record<\n CodeDiagnosticSeverity,\n { rule: string; number: string }\n> = {\n error: { rule: tokens.semErrorUi, number: tokens.error11 },\n warning: { rule: tokens.semWarningUi, number: tokens.warning11 },\n info: { rule: tokens.semInfoUi, number: tokens.info11 },\n}\n\nconst useStyles = makeZenithStyles({\n root: {\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n position: \"relative\",\n backgroundColor: tokens.surfaceField,\n ...shorthands.borderWidth(tokens.borderWidthField),\n ...shorthands.borderStyle(\"solid\"),\n ...shorthands.borderColor(tokens.borderField),\n borderRadius: tokens.surfaceRadiusField,\n // Declared before the state rules below so those win by source order, per AGENTS.md rule 2.\n \"&:focus-within\": {\n outlineWidth: \"2px\",\n outlineStyle: \"solid\",\n outlineOffset: \"-1px\",\n outlineColor: tokens.semFocusRing,\n },\n \"&[data-invalid]\": {\n ...shorthands.borderColor(tokens.semErrorUi),\n },\n \"&[data-disabled]\": {\n backgroundColor: tokens.grayA3,\n },\n },\n // Repaint the opaque gutter when the surrounding field is disabled.\n rootDisabledGutter: {\n [`&[data-disabled] [${SLOT_ATTR}='code-editor-line-number']`]: {\n backgroundColor: tokens.grayA3,\n },\n },\n // focus-within would keep the overlay visible throughout the editing session.\n rootFormatReveal: {\n \"&:hover [data-format-state]\": { opacity: 1 },\n },\n // The textarea defines the box; this decorative layer stretches without measurement.\n highlight: {\n ...CODE_METRICS,\n position: \"absolute\",\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n overflowX: \"hidden\",\n overflowY: \"hidden\",\n // Paint only: it must never take a click, a caret or a selection away from the control.\n pointerEvents: \"none\",\n userSelect: \"none\",\n color: tokens.grayA12,\n \"&[data-composing]\": {\n // Provisional IME text lives in the textarea, so the layer would be showing stale colours\n // over it. Declared after the base so it wins by source order.\n opacity: 0,\n },\n },\n /** With a gutter, the left padding moves into the number cell so the cell can pin flush. */\n highlightGutter: {\n paddingLeft: 0,\n },\n textarea: {\n ...CODE_METRICS,\n position: \"relative\",\n width: \"100%\",\n minWidth: 0,\n backgroundColor: \"transparent\",\n // The glyphs come from the layer beneath; only the caret is painted here.\n color: \"transparent\",\n caretColor: tokens.grayA12,\n overflowX: \"auto\",\n overflowY: \"auto\",\n // The root paints the ring for the whole surface; a second one on the control would double it.\n outlineStyle: \"none\",\n \"::placeholder\": {\n color: tokens.grayA8,\n // Placeholders are the textarea's own paint, so they need a real colour despite the above.\n WebkitTextFillColor: tokens.grayA8,\n },\n \"::selection\": {\n // An alpha tint, so highlighted glyphs stay legible through the selection band instead of\n // being covered by it — transparent text under an opaque selection is invisible text.\n backgroundColor: tokens.accentA5,\n },\n \":disabled\": {\n cursor: \"not-allowed\",\n },\n \"&[data-composing]\": {\n // Reveal what the IME is composing. Without this the author types blind through a CJK\n // composition, which is the one way this technique can fail outright.\n color: tokens.grayA12,\n },\n },\n // Keep textarea glyphs aligned with the highlighted rows.\n textareaGutter: {\n paddingLeft: `calc(${tokens.spacingElement2} + var(${GUTTER}) + ${tokens.spacingElement3})`,\n },\n // Unsupported browsers fall back to the native rows height.\n autoSize: {\n fieldSizing: \"content\",\n },\n resizeNone: {\n resize: \"none\",\n },\n resizeVertical: {\n resize: \"vertical\",\n },\n resizeHorizontal: {\n resize: \"horizontal\",\n },\n resizeBoth: {\n resize: \"both\",\n },\n noWrap: {\n whiteSpace: \"pre\",\n overflowWrap: \"normal\",\n },\n wrap: {\n whiteSpace: \"pre-wrap\",\n overflowWrap: \"break-word\",\n },\n // Width constraints below require a block formatting context.\n codeRows: {\n display: \"block\",\n },\n // Give the sticky gutter and active-line band the full width of unwrapped code.\n codeNoWrap: {\n width: \"max-content\",\n minWidth: \"100%\",\n },\n line: {\n display: \"flex\",\n width: \"100%\",\n },\n /** The band under the caret's line. See `caretLine` in the component for when it is on. */\n lineActive: {\n backgroundImage: `linear-gradient(${tokens.grayA2}, ${tokens.grayA2})`,\n },\n lineNumber: {\n userSelect: \"none\",\n textAlign: \"right\",\n flexGrow: 0,\n flexShrink: 0,\n color: tokens.grayA8,\n boxSizing: \"border-box\",\n width: `calc(var(${GUTTER}) + ${tokens.spacingElement2} + ${tokens.spacingElement3})`,\n paddingLeft: tokens.spacingElement2,\n paddingRight: tokens.spacingElement3,\n // Pinned, so a long line scrolled sideways does not take the numbers with it. Opaque, because\n // scrolled code passes underneath.\n position: \"sticky\",\n left: 0,\n backgroundColor: tokens.surfaceField,\n },\n /** The caret's line number, lifted out of the gutter's grey. */\n lineNumberActive: {\n color: tokens.grayA12,\n },\n lineContent: {\n minWidth: 0,\n flexGrow: 1,\n flexShrink: 1,\n flexBasis: \"auto\",\n },\n lineContentWrap: {\n overflowWrap: \"break-word\",\n },\n // Underline only the text; a line fill would compete with selection and active-line paint.\n diagnosticError: {\n textDecorationLine: \"underline\",\n textDecorationStyle: \"wavy\",\n textDecorationColor: SEVERITY_TOKENS.error.rule,\n textDecorationSkipInk: \"none\",\n textUnderlineOffset: \"0.2em\",\n },\n diagnosticWarning: {\n textDecorationLine: \"underline\",\n textDecorationStyle: \"wavy\",\n textDecorationColor: SEVERITY_TOKENS.warning.rule,\n textDecorationSkipInk: \"none\",\n textUnderlineOffset: \"0.2em\",\n },\n diagnosticInfo: {\n textDecorationLine: \"underline\",\n textDecorationStyle: \"wavy\",\n textDecorationColor: SEVERITY_TOKENS.info.rule,\n textDecorationSkipInk: \"none\",\n textUnderlineOffset: \"0.2em\",\n },\n numberError: { color: SEVERITY_TOKENS.error.number },\n numberWarning: { color: SEVERITY_TOKENS.warning.number },\n numberInfo: { color: SEVERITY_TOKENS.info.number },\n format: {\n position: \"absolute\",\n top: tokens.spacingElement05,\n right: tokens.spacingElement05,\n zIndex: 1,\n backgroundColor: tokens.surfaceField,\n opacity: 0,\n transitionProperty: \"opacity\",\n transitionDuration: \"120ms\",\n \"@media (prefers-reduced-motion: reduce)\": {\n transitionDuration: \"0s\",\n },\n \"@media (hover: none)\": {\n opacity: 1,\n },\n // After the base, so they win by source order (AGENTS.md rule 2).\n \"&:focus-visible\": { opacity: 1 },\n \"&[data-format-state='pending']\": { opacity: 1 },\n },\n srOnly: {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n ...shorthands.padding(0),\n ...shorthands.margin(\"-1px\"),\n overflowX: \"hidden\",\n overflowY: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n },\n})\n\nconst FormatIcon = (props: React.ComponentProps<\"svg\">) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n {...props}\n >\n <path d=\"M4 5h16\" />\n <path d=\"M9 10h11\" />\n <path d=\"M9 15h7\" />\n <path d=\"M4 20h16\" />\n </svg>\n)\n\nexport type CodeEditorResize = \"none\" | \"vertical\" | \"horizontal\" | \"both\"\n\nexport type CodeEditorProps = Omit<\n React.ComponentProps<\"textarea\">,\n \"value\" | \"defaultValue\" | \"wrap\" | \"children\"\n> & {\n /** Controlled source text. Omit for an uncontrolled editor. */\n value?: string\n /** Initial source text for an uncontrolled editor. Ignored when `value` is passed. */\n defaultValue?: string\n /** The next source text, after any edit — typing, paste, Tab indentation, or a format. */\n onValueChange?: (value: string) => void\n /** Language grammar used for syntax highlighting. Unknown values fall back to plain text. */\n language?: string\n /**\n * Soft-wrap long lines. Off by default, so a long line scrolls rather than silently folding.\n *\n * This replaces the native `wrap` attribute's `\"off\" | \"soft\" | \"hard\"`, whose `\"hard\"` value\n * rewrites the submitted value with real newlines — never what a code buffer wants.\n */\n wrap?: boolean\n /** Which directions the caller may drag to resize. Defaults to `none` under `autoSize`. */\n resize?: CodeEditorResize\n /**\n * Let Tab and Shift+Tab indent instead of moving focus.\n *\n * Off by default, because a textarea that swallows Tab is a keyboard trap. When on, Escape\n * releases the next Tab to focus movement — the escape hatch every code editor that takes Tab\n * has to provide — and the release lasts until the next keystroke or refocus.\n */\n indentWithTab?: boolean\n /** Spaces inserted per indent level, and the rendered width of a literal tab. */\n indentSize?: number\n /** Marks the control invalid: sets `aria-invalid` and the invalid styling. */\n invalid?: boolean\n /**\n * Render a line-number gutter, and mark the line the caret is on.\n *\n * Off by default: on the four-line snippets this component is for, numbers are a column of noise\n * that also costs horizontal space. One property rather than two, because a gutter that does not\n * say where you are and a band with nothing to count against are each half an affordance — this\n * is `lineNumbers()`, `highlightActiveLine()` and `highlightActiveLineGutter()` as CodeMirror's\n * own default setup bundles them.\n */\n showLineNumbers?: boolean\n /**\n * Problems the CALLER found, one per line. Nothing here computes them.\n *\n * Rendered as a wavy rule under the line and a coloured gutter number, and enumerated in a\n * visually hidden list that is added to the control's `aria-describedby` — so a screen reader\n * gets the text on focus rather than a colour it cannot see. Deliberately NOT announced live:\n * diagnostics normally change on every keystroke, and a live region that fires on every keystroke\n * is noise. A caller who wants an announcement owns the timing, and owns the data already.\n */\n diagnostics?: readonly CodeDiagnostic[]\n /**\n * Reformat the buffer. The caller supplies the formatter; this component supplies the keystroke,\n * the caret, and the announcement.\n *\n * Bound to **Shift+Alt+F**, VS Code's \"Format Document\", and to a quiet button revealed on hover.\n * May be synchronous or async. While one call is in flight another is dropped rather than queued,\n * a result whose request has been superseded is discarded, and a result that arrives after the\n * author has typed is discarded too and reported through `onFormatError` — applying it would\n * silently delete what they typed. Never runs on a `readOnly` or `disabled` editor.\n *\n * The returned string is committed exactly like a keystroke, through `onValueChange`: a\n * controlled editor that does not accept it does not change, which is the same contract typing\n * already has.\n */\n onFormat?: (value: string) => string | Promise<string>\n /** Called when the formatter threw, rejected, or its result had to be discarded. */\n onFormatError?: (error: unknown) => void\n /** Accessible name of the format button. */\n formatLabel?: string\n /** Announced after the formatter ran. */\n formattedLabel?: string\n /** Announced when the formatter failed or its result was discarded. */\n formatErrorLabel?: string\n /**\n * Grow with the content instead of reserving a fixed height.\n *\n * `rows` becomes the minimum and `maxRows` the maximum, past which the editor scrolls. Off by\n * default, and progressive: browsers without CSS `field-sizing` fall back to `rows`, which is\n * what this component did before the property existed.\n */\n autoSize?: boolean\n /** With `autoSize`, the height past which the editor scrolls instead of growing. */\n maxRows?: number\n}\n\nexport const CodeEditor = React.forwardRef<\n HTMLTextAreaElement,\n CodeEditorProps\n>(function CodeEditor(\n {\n value,\n defaultValue,\n onValueChange,\n onChange,\n onKeyDown,\n onBlur,\n onFocus,\n onSelect,\n onScroll,\n onCompositionStart,\n onCompositionEnd,\n language,\n wrap = false,\n resize,\n indentWithTab = false,\n indentSize = 2,\n invalid = false,\n readOnly = false,\n disabled = false,\n showLineNumbers = false,\n diagnostics,\n onFormat,\n onFormatError,\n formatLabel = \"Format code\",\n formattedLabel = \"Formatted\",\n formatErrorLabel = \"Formatting failed\",\n autoSize = false,\n maxRows,\n rows,\n className,\n style,\n spellCheck = false,\n autoComplete = \"off\",\n autoCorrect = \"off\",\n autoCapitalize = \"off\",\n dir = \"ltr\",\n ...props\n },\n forwardedRef\n) {\n const styles = useStyles()\n const reactId = React.useId()\n const diagnosticsId = `${reactId}-diagnostics`\n\n const isControlled = value !== undefined\n const [uncontrolled, setUncontrolled] = React.useState(defaultValue ?? \"\")\n const current = isControlled ? value : uncontrolled\n\n const renderTokens = useCodeTokenRenderer()\n const highlightRef = React.useRef<HTMLPreElement | null>(null)\n\n const [composing, setComposing] = React.useState(false)\n\n const innerRef = React.useRef<HTMLTextAreaElement | null>(null)\n const setRefs = React.useCallback(\n (el: HTMLTextAreaElement | null) => {\n innerRef.current = el\n if (typeof forwardedRef === \"function\") forwardedRef(el)\n else if (forwardedRef) forwardedRef.current = el\n },\n [forwardedRef]\n )\n\n // Escape releases the next Tab without triggering a render.\n const tabReleased = React.useRef(false)\n\n const commit = React.useCallback(\n (next: string) => {\n if (!isControlled) setUncontrolled(next)\n onValueChange?.(next)\n },\n [isControlled, onValueChange]\n )\n\n const lineCount = React.useMemo(() => current.split(\"\\n\").length, [current])\n const severities = React.useMemo(\n () => severityByLine(diagnostics, lineCount),\n [diagnostics, lineCount]\n )\n const listed = React.useMemo(\n () => visibleDiagnostics(diagnostics, lineCount),\n [diagnostics, lineCount]\n )\n const rowMode = showLineNumbers || severities.size > 0\n\n // Null while blurred or range-selected, when an active-line band would be misleading.\n const [caretLine, setCaretLine] = React.useState<number | null>(null)\n\n const syncCaretLine = React.useCallback(() => {\n // Avoid caret state and rerenders when no row affordance is enabled.\n if (!rowMode) return\n const el = innerRef.current\n if (el === null) return\n if (el.selectionStart !== el.selectionEnd) {\n setCaretLine(null)\n return\n }\n setCaretLine(lineIndexAt(el.value, el.selectionStart ?? 0))\n }, [rowMode])\n\n const handleChange = React.useCallback(\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n commit(event.target.value)\n onChange?.(event)\n },\n [commit, onChange]\n )\n\n const handleSelect = React.useCallback(\n (event: React.SyntheticEvent<HTMLTextAreaElement>) => {\n syncCaretLine()\n onSelect?.(event)\n },\n [onSelect, syncCaretLine]\n )\n\n const handleFocus = React.useCallback(\n (event: React.FocusEvent<HTMLTextAreaElement>) => {\n syncCaretLine()\n onFocus?.(event)\n },\n [onFocus, syncCaretLine]\n )\n\n // The ref gates calls synchronously; state paints the pending affordance.\n const formatPending = React.useRef(false)\n const [formatting, setFormatting] = React.useState(false)\n const [formatStatus, setFormatStatus] = React.useState(\"\")\n const formatTimer = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n\n React.useEffect(\n () => () => {\n if (formatTimer.current !== null) clearTimeout(formatTimer.current)\n },\n []\n )\n\n const announceFormat = React.useCallback((message: string) => {\n setFormatStatus(message)\n if (formatTimer.current !== null) clearTimeout(formatTimer.current)\n // Clearing lets a repeated identical outcome be announced again.\n formatTimer.current = setTimeout(() => {\n formatTimer.current = null\n setFormatStatus(\"\")\n }, FORMAT_FEEDBACK_MS)\n }, [])\n\n const runFormat = React.useCallback(async () => {\n if (onFormat === undefined || readOnly || disabled) return\n const el = innerRef.current\n if (el === null) return\n // Do not queue stale work behind an in-flight formatter.\n if (formatPending.current) return\n\n const source = el.value\n formatPending.current = true\n setFormatting(true)\n\n let next: string\n try {\n next = await onFormat(source)\n } catch (error) {\n formatPending.current = false\n setFormatting(false)\n announceFormat(formatErrorLabel)\n onFormatError?.(error ?? new Error(\"Formatting failed\"))\n return\n }\n\n formatPending.current = false\n setFormatting(false)\n\n const live = innerRef.current\n if (live === null) return\n if (live.value !== source) {\n // Never overwrite edits made while the formatter was running.\n announceFormat(formatErrorLabel)\n onFormatError?.(\n new Error(\"Formatting discarded: the value changed while formatting\")\n )\n return\n }\n\n if (next !== source) {\n const caret = caretAfterRewrite(source, next, live.selectionStart ?? 0)\n // Place the caret before React reconciles the controlled value.\n live.value = next\n live.setSelectionRange(caret, caret)\n commit(next)\n }\n announceFormat(formattedLabel)\n }, [\n announceFormat,\n commit,\n disabled,\n formatErrorLabel,\n formattedLabel,\n onFormat,\n onFormatError,\n readOnly,\n ])\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n onKeyDown?.(event)\n if (event.defaultPrevented) return\n if (readOnly || disabled) return\n\n // Shift+Alt+F, matched on `code` rather than `key`: Alt rewrites `key` on macOS layouts, so\n // the physical key is the only stable identity this chord has.\n if (\n onFormat !== undefined &&\n event.altKey &&\n event.shiftKey &&\n !event.ctrlKey &&\n !event.metaKey &&\n (event.code === \"KeyF\" || event.key.toLowerCase() === \"f\")\n ) {\n event.preventDefault()\n tabReleased.current = false\n void runFormat()\n return\n }\n\n if (!indentWithTab) return\n\n if (event.key === \"Escape\") {\n // Deliberately NOT prevented: an editor inside a Dialog must still let Escape close it.\n // The latch is the whole effect.\n tabReleased.current = true\n return\n }\n\n if (event.key !== \"Tab\") {\n tabReleased.current = false\n return\n }\n // A released Tab, or any modified Tab, is focus movement. Shift is the one modifier that\n // still means indentation, because Shift+Tab is outdent.\n if (tabReleased.current || event.ctrlKey || event.metaKey || event.altKey)\n return\n\n const el = event.currentTarget\n const next = applyIndent(\n {\n value: el.value,\n selectionStart: el.selectionStart ?? 0,\n selectionEnd: el.selectionEnd ?? 0,\n },\n { outdent: event.shiftKey, indentSize }\n )\n if (\n next.value === el.value &&\n next.selectionStart === el.selectionStart &&\n next.selectionEnd === el.selectionEnd\n ) {\n // Shift+Tab on an already-flush line changes nothing; let it move focus rather than\n // silently eating the key.\n return\n }\n\n event.preventDefault()\n // Write the DOM before the state update so the caret lands where the transform said. React\n // then renders the same string, sees the node already holds it, and leaves the selection\n // alone — restoring it from an effect would fight the browser for a frame first.\n el.value = next.value\n el.setSelectionRange(next.selectionStart, next.selectionEnd)\n commit(next.value)\n },\n [\n commit,\n disabled,\n indentSize,\n indentWithTab,\n onFormat,\n onKeyDown,\n readOnly,\n runFormat,\n ]\n )\n\n const handleBlur = React.useCallback(\n (event: React.FocusEvent<HTMLTextAreaElement>) => {\n tabReleased.current = false\n setCaretLine(null)\n onBlur?.(event)\n },\n [onBlur]\n )\n\n const handleScroll = React.useCallback(\n (event: React.UIEvent<HTMLTextAreaElement>) => {\n const layer = highlightRef.current\n if (layer !== null) {\n // Synchronous, deliberately. `scroll` is not cancelable and fires at a high rate, and the\n // usual advice is to throttle it — but deferring to a frame puts the colours behind the\n // text for that frame, which is exactly the artefact this sync exists to prevent. Two\n // property writes are cheaper than the reflow a throttle would be saving.\n layer.scrollTop = event.currentTarget.scrollTop\n layer.scrollLeft = event.currentTarget.scrollLeft\n }\n onScroll?.(event)\n },\n [onScroll]\n )\n\n const handleCompositionStart = React.useCallback(\n (event: React.CompositionEvent<HTMLTextAreaElement>) => {\n setComposing(true)\n onCompositionStart?.(event)\n },\n [onCompositionStart]\n )\n\n const handleCompositionEnd = React.useCallback(\n (event: React.CompositionEvent<HTMLTextAreaElement>) => {\n setComposing(false)\n onCompositionEnd?.(event)\n },\n [onCompositionEnd]\n )\n\n /**\n * A `<pre>` does not render a final empty line, so a value ending in a newline would leave the\n * layer one line short of the textarea and everything below the fold misaligned. The extra space\n * gives that last line something to occupy. It exists only in the decoration — `value`, and every\n * callback, selection and form submission reading it, is untouched.\n *\n * Row mode has no such problem: `\"a\\n\".split(\"\\n\")` is two entries, so the empty last line is a\n * row like any other, and each row carries its own newline for height.\n */\n const highlightSource = rowMode\n ? current\n : current.endsWith(\"\\n\")\n ? `${current} `\n : current\n\n // Synchronous tokenization: the server render and the first client render produce the same\n // markup, so there is nothing for hydration to reconcile.\n const highlighted = React.useMemo(\n () => highlightCode(highlightSource, language),\n [highlightSource, language]\n )\n\n const plainLines = React.useMemo(\n () => (rowMode ? current.split(\"\\n\") : null),\n [current, rowMode]\n )\n const tokenLines = React.useMemo(\n () =>\n rowMode && highlighted !== null ? splitTokenLines(highlighted) : null,\n [highlighted, rowMode]\n )\n\n const wrapStyle = wrap ? styles.wrap : styles.noWrap\n\n const effectiveResize = resize ?? (autoSize ? \"none\" : \"vertical\")\n const resizeStyle =\n effectiveResize === \"vertical\"\n ? styles.resizeVertical\n : effectiveResize === \"horizontal\"\n ? styles.resizeHorizontal\n : effectiveResize === \"both\"\n ? styles.resizeBoth\n : styles.resizeNone\n\n /**\n * `rows` is ignored under `field-sizing: content`, so it is translated into the floor it means.\n * The terms are the ones `CODE_METRICS` sets: N line boxes plus the block padding, with the\n * control's border already at zero and `box-sizing: border-box`.\n */\n const autoSizeStyle = autoSize\n ? {\n minHeight: `calc(${rows ?? 3} * ${tokens.leadingXs} + ${tokens.spacingElement2} * 2)`,\n maxHeight:\n maxRows === undefined\n ? undefined\n : `calc(${maxRows} * ${tokens.leadingXs} + ${tokens.spacingElement2} * 2)`,\n }\n : undefined\n\n const rootStyle = showLineNumbers\n ? ({\n [GUTTER]: `${gutterDigits(lineCount)}ch`,\n ...style,\n } as React.CSSProperties)\n : style\n\n const describedBy =\n listed.length === 0\n ? props[\"aria-describedby\"]\n : [props[\"aria-describedby\"], diagnosticsId].filter(Boolean).join(\" \")\n\n const severityClass = {\n error: styles.diagnosticError,\n warning: styles.diagnosticWarning,\n info: styles.diagnosticInfo,\n } as const\n const numberClass = {\n error: styles.numberError,\n warning: styles.numberWarning,\n info: styles.numberInfo,\n } as const\n\n return (\n <div\n data-slot=\"code-editor\"\n {...{ [SLOT_ATTR]: \"code-editor\" }}\n data-language={language}\n // Value-less boolean attributes, so `&[data-invalid]` and `&[data-disabled]` match the way\n // Field's do rather than matching the string \"false\".\n data-invalid={invalid || undefined}\n data-disabled={disabled || undefined}\n data-readonly={readOnly || undefined}\n data-formatting={formatting || undefined}\n // `className` and `style` address the component, which is this element — the same contract\n // every other component in the package offers. Everything else in `...props` is a textarea\n // attribute and lands on the control below.\n className={mergeClasses(\n styles.root,\n showLineNumbers ? styles.rootDisabledGutter : undefined,\n onFormat === undefined ? undefined : styles.rootFormatReveal,\n className\n )}\n style={rootStyle}\n >\n {/*\n Decoration, and nothing else. `aria-hidden` because it is a duplicate of the textarea's own\n text and contains nothing focusable — the one case MDN names for it — so a screen reader\n reads the control once, not twice. `pointer-events: none` keeps clicks, the caret and\n selection on the control beneath it. CodeMirror marks its own gutter `aria-hidden` for the\n same reason: a line number is a position, and the position is already in the control.\n */}\n <pre\n ref={highlightRef}\n aria-hidden=\"true\"\n data-slot=\"code-editor-highlight\"\n {...{ [SLOT_ATTR]: \"code-editor-highlight\" }}\n data-composing={composing || undefined}\n className={mergeClasses(\n styles.highlight,\n showLineNumbers ? styles.highlightGutter : undefined,\n wrapStyle\n )}\n style={{ tabSize: indentSize }}\n >\n <code\n className={mergeClasses(\n plainLines === null ? undefined : styles.codeRows,\n plainLines !== null && !wrap ? styles.codeNoWrap : undefined\n )}\n >\n {plainLines === null\n ? highlighted === null\n ? highlightSource\n : renderTokens(highlighted)\n : plainLines.map((line, index) => {\n const severity = severities.get(index + 1)\n const active = caretLine === index\n return (\n <span\n key={index}\n data-slot=\"code-editor-line\"\n {...{ [SLOT_ATTR]: \"code-editor-line\" }}\n data-line={index + 1}\n data-active={active || undefined}\n data-severity={severity}\n className={mergeClasses(\n styles.line,\n active ? styles.lineActive : undefined\n )}\n >\n {showLineNumbers ? (\n <span\n data-slot=\"code-editor-line-number\"\n {...{ [SLOT_ATTR]: \"code-editor-line-number\" }}\n className={mergeClasses(\n styles.lineNumber,\n active ? styles.lineNumberActive : undefined,\n severity === undefined\n ? undefined\n : numberClass[severity]\n )}\n >\n {index + 1}\n </span>\n ) : null}\n <span\n data-slot=\"code-editor-line-content\"\n {...{ [SLOT_ATTR]: \"code-editor-line-content\" }}\n className={mergeClasses(\n styles.lineContent,\n wrap ? styles.lineContentWrap : undefined\n )}\n >\n {/* The rule goes on this inner span so it ends with the text rather than\n running out to the fold; the newline stays outside it. */}\n <span\n className={\n severity === undefined\n ? undefined\n : severityClass[severity]\n }\n >\n {tokenLines === null\n ? line\n : renderTokens(tokenLines[index] ?? [])}\n </span>\n {\"\\n\"}\n </span>\n </span>\n )\n })}\n </code>\n </pre>\n\n <textarea\n {...props}\n ref={setRefs}\n data-slot=\"code-editor-input\"\n {...{ [SLOT_ATTR]: \"code-editor-input\" }}\n value={current}\n rows={rows}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onSelect={handleSelect}\n onScroll={handleScroll}\n onCompositionStart={handleCompositionStart}\n onCompositionEnd={handleCompositionEnd}\n data-composing={composing || undefined}\n readOnly={readOnly}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n aria-busy={formatting || undefined}\n // Code is not prose: a squiggle under every identifier is noise, and an editor that\n // capitalises `const` or \"corrects\" `-->` corrupts the buffer.\n spellCheck={spellCheck}\n autoComplete={autoComplete}\n autoCorrect={autoCorrect}\n autoCapitalize={autoCapitalize}\n // Source is left-to-right even on a right-to-left page; `auto` would flip a buffer that\n // happens to start with an RTL character in a string literal.\n dir={dir}\n wrap={wrap ? \"soft\" : \"off\"}\n // One indent level, one tab stop: a literal tab in the buffer renders exactly as wide as\n // the spaces Tab inserts. Dynamic, so it is an inline declaration rather than an atom.\n style={{ tabSize: indentSize, ...autoSizeStyle }}\n className={mergeClasses(\n styles.textarea,\n showLineNumbers ? styles.textareaGutter : undefined,\n autoSize ? styles.autoSize : undefined,\n wrapStyle,\n resizeStyle\n )}\n />\n\n {onFormat === undefined ? null : (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n data-format-state={formatting ? \"pending\" : \"idle\"}\n aria-label={formatLabel}\n disabled={disabled || readOnly || formatting}\n className={styles.format}\n // Keeps the caret where it is: without this the button takes focus on press and the\n // editor's selection — which the format is about to restore — is gone before it runs.\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n void runFormat()\n }}\n >\n <FormatIcon />\n </Button>\n )}\n\n {listed.length === 0 ? null : (\n <ul\n id={diagnosticsId}\n data-slot=\"code-editor-diagnostics\"\n {...{ [SLOT_ATTR]: \"code-editor-diagnostics\" }}\n className={styles.srOnly}\n >\n {listed.map((diagnostic, index) => (\n <li key={index}>\n {`${diagnostic.severity ?? \"error\"}, line ${diagnostic.line}${\n diagnostic.column === undefined\n ? \"\"\n : `, column ${diagnostic.column}`\n }: ${diagnostic.message}`}\n </li>\n ))}\n </ul>\n )}\n\n {onFormat === undefined ? null : (\n <span\n role=\"status\"\n aria-live=\"polite\"\n data-slot=\"code-editor-format-status\"\n {...{ [SLOT_ATTR]: \"code-editor-format-status\" }}\n className={styles.srOnly}\n >\n {formatStatus}\n </span>\n )}\n </div>\n )\n})\n"],"names":["FORMAT_FEEDBACK_MS","GUTTER","CODE_METRICS","shorthands","tokens.spacingElement2","tokens.fontMono","tokens.textXs","tokens.leadingXs","tokens.trackingNormal","tokens.fontWeightNormal","SEVERITY_TOKENS","tokens.semErrorUi","tokens.error11","tokens.semWarningUi","tokens.warning11","tokens.semInfoUi","tokens.info11","useStyles","makeZenithStyles","tokens.surfaceField","tokens.borderWidthField","tokens.borderField","tokens.surfaceRadiusField","tokens.semFocusRing","tokens.grayA3","SLOT_ATTR","tokens.grayA12","tokens.grayA8","tokens.accentA5","tokens.spacingElement3","tokens.grayA2","tokens.spacingElement05","FormatIcon","props","jsxs","jsx","CodeEditor","React","value","defaultValue","onValueChange","onChange","onKeyDown","onBlur","onFocus","onSelect","onScroll","onCompositionStart","onCompositionEnd","language","wrap","resize","indentWithTab","indentSize","invalid","readOnly","disabled","showLineNumbers","diagnostics","onFormat","onFormatError","formatLabel","formattedLabel","formatErrorLabel","autoSize","maxRows","rows","className","style","spellCheck","autoComplete","autoCorrect","autoCapitalize","dir","forwardedRef","styles","diagnosticsId","isControlled","uncontrolled","setUncontrolled","current","renderTokens","useCodeTokenRenderer","highlightRef","composing","setComposing","innerRef","setRefs","el","tabReleased","commit","next","lineCount","severities","severityByLine","listed","visibleDiagnostics","rowMode","caretLine","setCaretLine","syncCaretLine","lineIndexAt","handleChange","event","handleSelect","handleFocus","formatPending","formatting","setFormatting","formatStatus","setFormatStatus","formatTimer","announceFormat","message","runFormat","source","error","live","caret","caretAfterRewrite","handleKeyDown","applyIndent","handleBlur","handleScroll","layer","handleCompositionStart","handleCompositionEnd","highlightSource","highlighted","highlightCode","plainLines","tokenLines","splitTokenLines","wrapStyle","effectiveResize","resizeStyle","autoSizeStyle","rootStyle","gutterDigits","describedBy","severityClass","numberClass","mergeClasses","line","index","severity","active","Button","diagnostic"],"mappings":"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"}
1
+ {"version":3,"file":"code-editor.js","sources":["../../../src/components/code-editor/code-editor.tsx"],"sourcesContent":["import * as React from \"react\"\n\nimport { mergeClasses, shorthands } from \"@epilot/zenith-runtime/v1\"\n\nimport { SLOT_ATTR } from \"../../renderer/contract\"\nimport { makeZenithStyles } from \"../../styles/make-styles\"\nimport * as tokens from \"../../tokens\"\nimport { Button } from \"../button/button\"\nimport { applyIndent } from \"./indent\"\nimport { highlightCode, splitTokenLines } from \"../../lib/code-highlight\"\nimport { useCodeTokenRenderer } from \"../../lib/code-tokens\"\nimport {\n caretAfterRewrite,\n gutterDigits,\n lineIndexAt,\n severityByLine,\n visibleDiagnostics,\n type CodeDiagnostic,\n type CodeDiagnosticSeverity,\n} from \"../../lib/code-lines\"\n\n/**\n * Compact code editing on a native textarea. Highlighting is decorative; the textarea remains the\n * only focusable, labelled, form-participating control. Formatting and diagnostics are supplied by\n * the caller rather than computed here.\n */\n\n/** How long a formatting outcome stays in the live region. */\nconst FORMAT_FEEDBACK_MS = 2000\n\n/** Shared gutter width for the number cells and textarea padding. */\nconst GUTTER = \"--zenith-code-gutter\"\n\n/**\n * Metrics shared by the textarea and highlight layer. `tabSize` varies per instance and gutter\n * padding intentionally differs between layers.\n */\nconst CODE_METRICS = {\n ...shorthands.margin(0),\n ...shorthands.borderWidth(0),\n ...shorthands.borderStyle(\"none\"),\n ...shorthands.padding(tokens.spacingElement2),\n fontFamily: tokens.fontMono,\n fontSize: tokens.textXs,\n lineHeight: tokens.leadingXs,\n letterSpacing: tokens.trackingNormal,\n fontWeight: tokens.fontWeightNormal,\n textIndent: 0,\n boxSizing: \"border-box\",\n // A classic, space-consuming scrollbar narrows the textarea's content box but not the layer's,\n // which moves where wrapped lines break. Reserving the gutter on both keeps one content width.\n // Platforms with overlay scrollbars never had the problem.\n scrollbarGutter: \"stable\",\n} as const\n\n/** Core-sheet colours used by diagnostic rules and numbers. */\nconst SEVERITY_TOKENS: Record<\n CodeDiagnosticSeverity,\n { rule: string; number: string }\n> = {\n error: { rule: tokens.errorUi, number: tokens.error11 },\n warning: { rule: tokens.warningUi, number: tokens.warning11 },\n info: { rule: tokens.infoUi, number: tokens.info11 },\n}\n\nconst useStyles = makeZenithStyles({\n root: {\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n position: \"relative\",\n backgroundColor: tokens.surfaceField,\n ...shorthands.borderWidth(tokens.borderWidthField),\n ...shorthands.borderStyle(\"solid\"),\n ...shorthands.borderColor(tokens.borderField),\n borderRadius: tokens.surfaceRadiusField,\n // Declared before the state rules below so those win by source order, per AGENTS.md rule 2.\n \"&:focus-within\": {\n outlineWidth: \"2px\",\n outlineStyle: \"solid\",\n outlineOffset: \"-1px\",\n outlineColor: tokens.focusRing,\n },\n \"&[data-invalid]\": {\n ...shorthands.borderColor(tokens.errorUi),\n },\n \"&[data-disabled]\": {\n backgroundColor: tokens.grayA3,\n },\n },\n // Repaint the opaque gutter when the surrounding field is disabled.\n rootDisabledGutter: {\n [`&[data-disabled] [${SLOT_ATTR}='code-editor-line-number']`]: {\n backgroundColor: tokens.grayA3,\n },\n },\n // focus-within would keep the overlay visible throughout the editing session.\n rootFormatReveal: {\n \"&:hover [data-format-state]\": { opacity: 1 },\n },\n // The textarea defines the box; this decorative layer stretches without measurement.\n highlight: {\n ...CODE_METRICS,\n position: \"absolute\",\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n overflowX: \"hidden\",\n overflowY: \"hidden\",\n // Paint only: it must never take a click, a caret or a selection away from the control.\n pointerEvents: \"none\",\n userSelect: \"none\",\n color: tokens.grayA12,\n \"&[data-composing]\": {\n // Provisional IME text lives in the textarea, so the layer would be showing stale colours\n // over it. Declared after the base so it wins by source order.\n opacity: 0,\n },\n },\n /** With a gutter, the left padding moves into the number cell so the cell can pin flush. */\n highlightGutter: {\n paddingLeft: 0,\n },\n textarea: {\n ...CODE_METRICS,\n position: \"relative\",\n width: \"100%\",\n minWidth: 0,\n backgroundColor: \"transparent\",\n // The glyphs come from the layer beneath; only the caret is painted here.\n color: \"transparent\",\n caretColor: tokens.grayA12,\n overflowX: \"auto\",\n overflowY: \"auto\",\n // The root paints the ring for the whole surface; a second one on the control would double it.\n outlineStyle: \"none\",\n \"::placeholder\": {\n color: tokens.grayA8,\n // Placeholders are the textarea's own paint, so they need a real colour despite the above.\n WebkitTextFillColor: tokens.grayA8,\n },\n \"::selection\": {\n // An alpha tint, so highlighted glyphs stay legible through the selection band instead of\n // being covered by it — transparent text under an opaque selection is invisible text.\n backgroundColor: tokens.accentA5,\n },\n \":disabled\": {\n cursor: \"not-allowed\",\n },\n \"&[data-composing]\": {\n // Reveal what the IME is composing. Without this the author types blind through a CJK\n // composition, which is the one way this technique can fail outright.\n color: tokens.grayA12,\n },\n },\n // Keep textarea glyphs aligned with the highlighted rows.\n textareaGutter: {\n paddingLeft: `calc(${tokens.spacingElement2} + var(${GUTTER}) + ${tokens.spacingElement3})`,\n },\n // Unsupported browsers fall back to the native rows height.\n autoSize: {\n fieldSizing: \"content\",\n },\n resizeNone: {\n resize: \"none\",\n },\n resizeVertical: {\n resize: \"vertical\",\n },\n resizeHorizontal: {\n resize: \"horizontal\",\n },\n resizeBoth: {\n resize: \"both\",\n },\n noWrap: {\n whiteSpace: \"pre\",\n overflowWrap: \"normal\",\n },\n wrap: {\n whiteSpace: \"pre-wrap\",\n overflowWrap: \"break-word\",\n },\n // Width constraints below require a block formatting context.\n codeRows: {\n display: \"block\",\n },\n // Give the sticky gutter and active-line band the full width of unwrapped code.\n codeNoWrap: {\n width: \"max-content\",\n minWidth: \"100%\",\n },\n line: {\n display: \"flex\",\n width: \"100%\",\n },\n /** The band under the caret's line. See `caretLine` in the component for when it is on. */\n lineActive: {\n backgroundImage: `linear-gradient(${tokens.grayA2}, ${tokens.grayA2})`,\n },\n lineNumber: {\n userSelect: \"none\",\n textAlign: \"right\",\n flexGrow: 0,\n flexShrink: 0,\n color: tokens.grayA8,\n boxSizing: \"border-box\",\n width: `calc(var(${GUTTER}) + ${tokens.spacingElement2} + ${tokens.spacingElement3})`,\n paddingLeft: tokens.spacingElement2,\n paddingRight: tokens.spacingElement3,\n // Pinned, so a long line scrolled sideways does not take the numbers with it. Opaque, because\n // scrolled code passes underneath.\n position: \"sticky\",\n left: 0,\n backgroundColor: tokens.surfaceField,\n },\n /** The caret's line number, lifted out of the gutter's grey. */\n lineNumberActive: {\n color: tokens.grayA12,\n },\n lineContent: {\n minWidth: 0,\n flexGrow: 1,\n flexShrink: 1,\n flexBasis: \"auto\",\n },\n lineContentWrap: {\n overflowWrap: \"break-word\",\n },\n // Underline only the text; a line fill would compete with selection and active-line paint.\n diagnosticError: {\n textDecorationLine: \"underline\",\n textDecorationStyle: \"wavy\",\n textDecorationColor: SEVERITY_TOKENS.error.rule,\n textDecorationSkipInk: \"none\",\n textUnderlineOffset: \"0.2em\",\n },\n diagnosticWarning: {\n textDecorationLine: \"underline\",\n textDecorationStyle: \"wavy\",\n textDecorationColor: SEVERITY_TOKENS.warning.rule,\n textDecorationSkipInk: \"none\",\n textUnderlineOffset: \"0.2em\",\n },\n diagnosticInfo: {\n textDecorationLine: \"underline\",\n textDecorationStyle: \"wavy\",\n textDecorationColor: SEVERITY_TOKENS.info.rule,\n textDecorationSkipInk: \"none\",\n textUnderlineOffset: \"0.2em\",\n },\n numberError: { color: SEVERITY_TOKENS.error.number },\n numberWarning: { color: SEVERITY_TOKENS.warning.number },\n numberInfo: { color: SEVERITY_TOKENS.info.number },\n format: {\n position: \"absolute\",\n top: tokens.spacingElement05,\n right: tokens.spacingElement05,\n zIndex: 1,\n backgroundColor: tokens.surfaceField,\n opacity: 0,\n transitionProperty: \"opacity\",\n transitionDuration: \"120ms\",\n \"@media (prefers-reduced-motion: reduce)\": {\n transitionDuration: \"0s\",\n },\n \"@media (hover: none)\": {\n opacity: 1,\n },\n // After the base, so they win by source order (AGENTS.md rule 2).\n \"&:focus-visible\": { opacity: 1 },\n \"&[data-format-state='pending']\": { opacity: 1 },\n },\n srOnly: {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n ...shorthands.padding(0),\n ...shorthands.margin(\"-1px\"),\n overflowX: \"hidden\",\n overflowY: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n },\n})\n\nconst FormatIcon = (props: React.ComponentProps<\"svg\">) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n {...props}\n >\n <path d=\"M4 5h16\" />\n <path d=\"M9 10h11\" />\n <path d=\"M9 15h7\" />\n <path d=\"M4 20h16\" />\n </svg>\n)\n\nexport type CodeEditorResize = \"none\" | \"vertical\" | \"horizontal\" | \"both\"\n\nexport type CodeEditorProps = Omit<\n React.ComponentProps<\"textarea\">,\n \"value\" | \"defaultValue\" | \"wrap\" | \"children\"\n> & {\n /** Controlled source text. Omit for an uncontrolled editor. */\n value?: string\n /** Initial source text for an uncontrolled editor. Ignored when `value` is passed. */\n defaultValue?: string\n /** The next source text, after any edit — typing, paste, Tab indentation, or a format. */\n onValueChange?: (value: string) => void\n /** Language grammar used for syntax highlighting. Unknown values fall back to plain text. */\n language?: string\n /**\n * Soft-wrap long lines. Off by default, so a long line scrolls rather than silently folding.\n *\n * This replaces the native `wrap` attribute's `\"off\" | \"soft\" | \"hard\"`, whose `\"hard\"` value\n * rewrites the submitted value with real newlines — never what a code buffer wants.\n */\n wrap?: boolean\n /** Which directions the caller may drag to resize. Defaults to `none` under `autoSize`. */\n resize?: CodeEditorResize\n /**\n * Let Tab and Shift+Tab indent instead of moving focus.\n *\n * Off by default, because a textarea that swallows Tab is a keyboard trap. When on, Escape\n * releases the next Tab to focus movement — the escape hatch every code editor that takes Tab\n * has to provide — and the release lasts until the next keystroke or refocus.\n */\n indentWithTab?: boolean\n /** Spaces inserted per indent level, and the rendered width of a literal tab. */\n indentSize?: number\n /** Marks the control invalid: sets `aria-invalid` and the invalid styling. */\n invalid?: boolean\n /**\n * Render a line-number gutter, and mark the line the caret is on. Off by default: on the four-\n * line snippets this component is for, numbers are a column of noise that also costs horizontal\n * space.\n */\n showLineNumbers?: boolean\n /**\n * Problems the CALLER found, one per line. Nothing here computes them. Rendered as a wavy rule\n * under the line and a coloured gutter number, and enumerated in a visually hidden list that is\n * added to the control's `aria-describedby` — so a screen reader gets the text on focus rather\n * than a colour it cannot see.\n */\n diagnostics?: readonly CodeDiagnostic[]\n /**\n * Reformat the buffer. The caller supplies the formatter; this component supplies the keystroke,\n * the caret, and the announcement. Bound to **Shift+Alt+F**, VS Code's \"Format Document\", and to\n * a quiet button revealed on hover.\n */\n onFormat?: (value: string) => string | Promise<string>\n /** Called when the formatter threw, rejected, or its result had to be discarded. */\n onFormatError?: (error: unknown) => void\n /** Accessible name of the format button. */\n formatLabel?: string\n /** Announced after the formatter ran. */\n formattedLabel?: string\n /** Announced when the formatter failed or its result was discarded. */\n formatErrorLabel?: string\n /**\n * Grow with the content instead of reserving a fixed height.\n *\n * `rows` becomes the minimum and `maxRows` the maximum, past which the editor scrolls. Off by\n * default, and progressive: browsers without CSS `field-sizing` fall back to `rows`, which is\n * what this component did before the property existed.\n */\n autoSize?: boolean\n /** With `autoSize`, the height past which the editor scrolls instead of growing. */\n maxRows?: number\n}\n\nexport const CodeEditor = React.forwardRef<\n HTMLTextAreaElement,\n CodeEditorProps\n>(function CodeEditor(\n {\n value,\n defaultValue,\n onValueChange,\n onChange,\n onKeyDown,\n onBlur,\n onFocus,\n onSelect,\n onScroll,\n onCompositionStart,\n onCompositionEnd,\n language,\n wrap = false,\n resize,\n indentWithTab = false,\n indentSize = 2,\n invalid = false,\n readOnly = false,\n disabled = false,\n showLineNumbers = false,\n diagnostics,\n onFormat,\n onFormatError,\n formatLabel = \"Format code\",\n formattedLabel = \"Formatted\",\n formatErrorLabel = \"Formatting failed\",\n autoSize = false,\n maxRows,\n rows,\n className,\n style,\n spellCheck = false,\n autoComplete = \"off\",\n autoCorrect = \"off\",\n autoCapitalize = \"off\",\n dir = \"ltr\",\n ...props\n },\n forwardedRef\n) {\n const styles = useStyles()\n const reactId = React.useId()\n const diagnosticsId = `${reactId}-diagnostics`\n\n const isControlled = value !== undefined\n const [uncontrolled, setUncontrolled] = React.useState(defaultValue ?? \"\")\n const current = isControlled ? value : uncontrolled\n\n const renderTokens = useCodeTokenRenderer()\n const highlightRef = React.useRef<HTMLPreElement | null>(null)\n\n const [composing, setComposing] = React.useState(false)\n\n const innerRef = React.useRef<HTMLTextAreaElement | null>(null)\n const setRefs = React.useCallback(\n (el: HTMLTextAreaElement | null) => {\n innerRef.current = el\n if (typeof forwardedRef === \"function\") forwardedRef(el)\n else if (forwardedRef) forwardedRef.current = el\n },\n [forwardedRef]\n )\n\n // Escape releases the next Tab without triggering a render.\n const tabReleased = React.useRef(false)\n\n const commit = React.useCallback(\n (next: string) => {\n if (!isControlled) setUncontrolled(next)\n onValueChange?.(next)\n },\n [isControlled, onValueChange]\n )\n\n const lineCount = React.useMemo(() => current.split(\"\\n\").length, [current])\n const severities = React.useMemo(\n () => severityByLine(diagnostics, lineCount),\n [diagnostics, lineCount]\n )\n const listed = React.useMemo(\n () => visibleDiagnostics(diagnostics, lineCount),\n [diagnostics, lineCount]\n )\n const rowMode = showLineNumbers || severities.size > 0\n\n // Null while blurred or range-selected, when an active-line band would be misleading.\n const [caretLine, setCaretLine] = React.useState<number | null>(null)\n\n const syncCaretLine = React.useCallback(() => {\n // Avoid caret state and rerenders when no row affordance is enabled.\n if (!rowMode) return\n const el = innerRef.current\n if (el === null) return\n if (el.selectionStart !== el.selectionEnd) {\n setCaretLine(null)\n return\n }\n setCaretLine(lineIndexAt(el.value, el.selectionStart ?? 0))\n }, [rowMode])\n\n const handleChange = React.useCallback(\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n commit(event.target.value)\n onChange?.(event)\n },\n [commit, onChange]\n )\n\n const handleSelect = React.useCallback(\n (event: React.SyntheticEvent<HTMLTextAreaElement>) => {\n syncCaretLine()\n onSelect?.(event)\n },\n [onSelect, syncCaretLine]\n )\n\n const handleFocus = React.useCallback(\n (event: React.FocusEvent<HTMLTextAreaElement>) => {\n syncCaretLine()\n onFocus?.(event)\n },\n [onFocus, syncCaretLine]\n )\n\n // The ref gates calls synchronously; state paints the pending affordance.\n const formatPending = React.useRef(false)\n const [formatting, setFormatting] = React.useState(false)\n const [formatStatus, setFormatStatus] = React.useState(\"\")\n const formatTimer = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n React.useEffect(\n () => () => {\n if (formatTimer.current !== null) clearTimeout(formatTimer.current)\n },\n []\n )\n\n const announceFormat = React.useCallback((message: string) => {\n setFormatStatus(message)\n if (formatTimer.current !== null) clearTimeout(formatTimer.current)\n // Clearing lets a repeated identical outcome be announced again.\n formatTimer.current = setTimeout(() => {\n formatTimer.current = null\n setFormatStatus(\"\")\n }, FORMAT_FEEDBACK_MS)\n }, [])\n\n const runFormat = React.useCallback(async () => {\n if (onFormat === undefined || readOnly || disabled) return\n const el = innerRef.current\n if (el === null) return\n // Do not queue stale work behind an in-flight formatter.\n if (formatPending.current) return\n\n const source = el.value\n formatPending.current = true\n setFormatting(true)\n\n let next: string\n try {\n next = await onFormat(source)\n } catch (error) {\n formatPending.current = false\n setFormatting(false)\n announceFormat(formatErrorLabel)\n onFormatError?.(error ?? new Error(\"Formatting failed\"))\n return\n }\n\n formatPending.current = false\n setFormatting(false)\n\n const live = innerRef.current\n if (live === null) return\n if (live.value !== source) {\n // Never overwrite edits made while the formatter was running.\n announceFormat(formatErrorLabel)\n onFormatError?.(\n new Error(\"Formatting discarded: the value changed while formatting\")\n )\n return\n }\n\n if (next !== source) {\n const caret = caretAfterRewrite(source, next, live.selectionStart ?? 0)\n // Place the caret before React reconciles the controlled value.\n live.value = next\n live.setSelectionRange(caret, caret)\n commit(next)\n }\n announceFormat(formattedLabel)\n }, [\n announceFormat,\n commit,\n disabled,\n formatErrorLabel,\n formattedLabel,\n onFormat,\n onFormatError,\n readOnly,\n ])\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n onKeyDown?.(event)\n if (event.defaultPrevented) return\n if (readOnly || disabled) return\n\n // Shift+Alt+F, matched on `code` rather than `key`: Alt rewrites `key` on macOS layouts, so\n // the physical key is the only stable identity this chord has.\n if (\n onFormat !== undefined &&\n event.altKey &&\n event.shiftKey &&\n !event.ctrlKey &&\n !event.metaKey &&\n (event.code === \"KeyF\" || event.key.toLowerCase() === \"f\")\n ) {\n event.preventDefault()\n tabReleased.current = false\n void runFormat()\n return\n }\n\n if (!indentWithTab) return\n\n if (event.key === \"Escape\") {\n // Deliberately NOT prevented: an editor inside a Dialog must still let Escape close it.\n // The latch is the whole effect.\n tabReleased.current = true\n return\n }\n\n if (event.key !== \"Tab\") {\n tabReleased.current = false\n return\n }\n // A released Tab, or any modified Tab, is focus movement. Shift is the one modifier that\n // still means indentation, because Shift+Tab is outdent.\n if (tabReleased.current || event.ctrlKey || event.metaKey || event.altKey)\n return\n\n const el = event.currentTarget\n const next = applyIndent(\n {\n value: el.value,\n selectionStart: el.selectionStart ?? 0,\n selectionEnd: el.selectionEnd ?? 0,\n },\n { outdent: event.shiftKey, indentSize }\n )\n if (\n next.value === el.value &&\n next.selectionStart === el.selectionStart &&\n next.selectionEnd === el.selectionEnd\n ) {\n // Shift+Tab on an already-flush line changes nothing; let it move focus rather than\n // silently eating the key.\n return\n }\n\n event.preventDefault()\n // Write the DOM before the state update so the caret lands where the transform said. React\n // then renders the same string, sees the node already holds it, and leaves the selection\n // alone — restoring it from an effect would fight the browser for a frame first.\n el.value = next.value\n el.setSelectionRange(next.selectionStart, next.selectionEnd)\n commit(next.value)\n },\n [\n commit,\n disabled,\n indentSize,\n indentWithTab,\n onFormat,\n onKeyDown,\n readOnly,\n runFormat,\n ]\n )\n\n const handleBlur = React.useCallback(\n (event: React.FocusEvent<HTMLTextAreaElement>) => {\n tabReleased.current = false\n setCaretLine(null)\n onBlur?.(event)\n },\n [onBlur]\n )\n\n const handleScroll = React.useCallback(\n (event: React.UIEvent<HTMLTextAreaElement>) => {\n const layer = highlightRef.current\n if (layer !== null) {\n // Synchronous, deliberately. `scroll` is not cancelable and fires at a high rate, and the\n // usual advice is to throttle it — but deferring to a frame puts the colours behind the\n // text for that frame, which is exactly the artefact this sync exists to prevent. Two\n // property writes are cheaper than the reflow a throttle would be saving.\n layer.scrollTop = event.currentTarget.scrollTop\n layer.scrollLeft = event.currentTarget.scrollLeft\n }\n onScroll?.(event)\n },\n [onScroll]\n )\n\n const handleCompositionStart = React.useCallback(\n (event: React.CompositionEvent<HTMLTextAreaElement>) => {\n setComposing(true)\n onCompositionStart?.(event)\n },\n [onCompositionStart]\n )\n\n const handleCompositionEnd = React.useCallback(\n (event: React.CompositionEvent<HTMLTextAreaElement>) => {\n setComposing(false)\n onCompositionEnd?.(event)\n },\n [onCompositionEnd]\n )\n\n /**\n * A `<pre>` does not render a final empty line, so a value ending in a newline would leave the\n * layer one line short of the textarea and everything below the fold misaligned. The extra space\n * gives that last line something to occupy.\n */\n const highlightSource = rowMode\n ? current\n : current.endsWith(\"\\n\")\n ? `${current} `\n : current\n\n // Synchronous tokenization: the server render and the first client render produce the same\n // markup, so there is nothing for hydration to reconcile.\n const highlighted = React.useMemo(\n () => highlightCode(highlightSource, language),\n [highlightSource, language]\n )\n\n const plainLines = React.useMemo(\n () => (rowMode ? current.split(\"\\n\") : null),\n [current, rowMode]\n )\n const tokenLines = React.useMemo(\n () =>\n rowMode && highlighted !== null ? splitTokenLines(highlighted) : null,\n [highlighted, rowMode]\n )\n\n const wrapStyle = wrap ? styles.wrap : styles.noWrap\n\n const effectiveResize = resize ?? (autoSize ? \"none\" : \"vertical\")\n const resizeStyle =\n effectiveResize === \"vertical\"\n ? styles.resizeVertical\n : effectiveResize === \"horizontal\"\n ? styles.resizeHorizontal\n : effectiveResize === \"both\"\n ? styles.resizeBoth\n : styles.resizeNone\n\n /**\n * `rows` is ignored under `field-sizing: content`, so it is translated into the floor it means.\n * The terms are the ones `CODE_METRICS` sets: N line boxes plus the block padding, with the\n * control's border already at zero and `box-sizing: border-box`.\n */\n const autoSizeStyle = autoSize\n ? {\n minHeight: `calc(${rows ?? 3} * ${tokens.leadingXs} + ${tokens.spacingElement2} * 2)`,\n maxHeight:\n maxRows === undefined\n ? undefined\n : `calc(${maxRows} * ${tokens.leadingXs} + ${tokens.spacingElement2} * 2)`,\n }\n : undefined\n\n const rootStyle = showLineNumbers\n ? ({\n [GUTTER]: `${gutterDigits(lineCount)}ch`,\n ...style,\n } as React.CSSProperties)\n : style\n\n const describedBy =\n listed.length === 0\n ? props[\"aria-describedby\"]\n : [props[\"aria-describedby\"], diagnosticsId].filter(Boolean).join(\" \")\n\n const severityClass = {\n error: styles.diagnosticError,\n warning: styles.diagnosticWarning,\n info: styles.diagnosticInfo,\n } as const\n const numberClass = {\n error: styles.numberError,\n warning: styles.numberWarning,\n info: styles.numberInfo,\n } as const\n\n return (\n <div\n data-slot=\"code-editor\"\n {...{ [SLOT_ATTR]: \"code-editor\" }}\n data-language={language}\n // Value-less boolean attributes, so `&[data-invalid]` and `&[data-disabled]` match the way\n // Field's do rather than matching the string \"false\".\n data-invalid={invalid || undefined}\n data-disabled={disabled || undefined}\n data-readonly={readOnly || undefined}\n data-formatting={formatting || undefined}\n // `className` and `style` address the component, which is this element — the same contract\n // every other component in the package offers. Everything else in `...props` is a textarea\n // attribute and lands on the control below.\n className={mergeClasses(\n styles.root,\n showLineNumbers ? styles.rootDisabledGutter : undefined,\n onFormat === undefined ? undefined : styles.rootFormatReveal,\n className\n )}\n style={rootStyle}\n >\n {/*\n Decoration, and nothing else. `aria-hidden` because it is a duplicate of the textarea's own\n text and contains nothing focusable — the one case MDN names for it — so a screen reader\n reads the control once, not twice. `pointer-events: none` keeps clicks, the caret and\n selection on the control beneath it. CodeMirror marks its own gutter `aria-hidden` for the\n same reason: a line number is a position, and the position is already in the control.\n */}\n <pre\n ref={highlightRef}\n aria-hidden=\"true\"\n data-slot=\"code-editor-highlight\"\n {...{ [SLOT_ATTR]: \"code-editor-highlight\" }}\n data-composing={composing || undefined}\n className={mergeClasses(\n styles.highlight,\n showLineNumbers ? styles.highlightGutter : undefined,\n wrapStyle\n )}\n style={{ tabSize: indentSize }}\n >\n <code\n className={mergeClasses(\n plainLines === null ? undefined : styles.codeRows,\n plainLines !== null && !wrap ? styles.codeNoWrap : undefined\n )}\n >\n {plainLines === null\n ? highlighted === null\n ? highlightSource\n : renderTokens(highlighted)\n : plainLines.map((line, index) => {\n const severity = severities.get(index + 1)\n const active = caretLine === index\n return (\n <span\n key={index}\n data-slot=\"code-editor-line\"\n {...{ [SLOT_ATTR]: \"code-editor-line\" }}\n data-line={index + 1}\n data-active={active || undefined}\n data-severity={severity}\n className={mergeClasses(\n styles.line,\n active ? styles.lineActive : undefined\n )}\n >\n {showLineNumbers ? (\n <span\n data-slot=\"code-editor-line-number\"\n {...{ [SLOT_ATTR]: \"code-editor-line-number\" }}\n className={mergeClasses(\n styles.lineNumber,\n active ? styles.lineNumberActive : undefined,\n severity === undefined\n ? undefined\n : numberClass[severity]\n )}\n >\n {index + 1}\n </span>\n ) : null}\n <span\n data-slot=\"code-editor-line-content\"\n {...{ [SLOT_ATTR]: \"code-editor-line-content\" }}\n className={mergeClasses(\n styles.lineContent,\n wrap ? styles.lineContentWrap : undefined\n )}\n >\n {/* The rule goes on this inner span so it ends with the text rather than\n running out to the fold; the newline stays outside it. */}\n <span\n className={\n severity === undefined\n ? undefined\n : severityClass[severity]\n }\n >\n {tokenLines === null\n ? line\n : renderTokens(tokenLines[index] ?? [])}\n </span>\n {\"\\n\"}\n </span>\n </span>\n )\n })}\n </code>\n </pre>\n\n <textarea\n {...props}\n ref={setRefs}\n data-slot=\"code-editor-input\"\n {...{ [SLOT_ATTR]: \"code-editor-input\" }}\n value={current}\n rows={rows}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onSelect={handleSelect}\n onScroll={handleScroll}\n onCompositionStart={handleCompositionStart}\n onCompositionEnd={handleCompositionEnd}\n data-composing={composing || undefined}\n readOnly={readOnly}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n aria-busy={formatting || undefined}\n // Code is not prose: a squiggle under every identifier is noise, and an editor that\n // capitalises `const` or \"corrects\" `-->` corrupts the buffer.\n spellCheck={spellCheck}\n autoComplete={autoComplete}\n autoCorrect={autoCorrect}\n autoCapitalize={autoCapitalize}\n // Source is left-to-right even on a right-to-left page; `auto` would flip a buffer that\n // happens to start with an RTL character in a string literal.\n dir={dir}\n wrap={wrap ? \"soft\" : \"off\"}\n // One indent level, one tab stop: a literal tab in the buffer renders exactly as wide as\n // the spaces Tab inserts. Dynamic, so it is an inline declaration rather than an atom.\n style={{ tabSize: indentSize, ...autoSizeStyle }}\n className={mergeClasses(\n styles.textarea,\n showLineNumbers ? styles.textareaGutter : undefined,\n autoSize ? styles.autoSize : undefined,\n wrapStyle,\n resizeStyle\n )}\n />\n\n {onFormat === undefined ? null : (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n data-format-state={formatting ? \"pending\" : \"idle\"}\n aria-label={formatLabel}\n disabled={disabled || readOnly || formatting}\n className={styles.format}\n // Keeps the caret where it is: without this the button takes focus on press and the\n // editor's selection — which the format is about to restore — is gone before it runs.\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n void runFormat()\n }}\n >\n <FormatIcon />\n </Button>\n )}\n\n {listed.length === 0 ? null : (\n <ul\n id={diagnosticsId}\n data-slot=\"code-editor-diagnostics\"\n {...{ [SLOT_ATTR]: \"code-editor-diagnostics\" }}\n className={styles.srOnly}\n >\n {listed.map((diagnostic, index) => (\n <li key={index}>\n {`${diagnostic.severity ?? \"error\"}, line ${diagnostic.line}${\n diagnostic.column === undefined\n ? \"\"\n : `, column ${diagnostic.column}`\n }: ${diagnostic.message}`}\n </li>\n ))}\n </ul>\n )}\n\n {onFormat === undefined ? null : (\n <span\n role=\"status\"\n aria-live=\"polite\"\n data-slot=\"code-editor-format-status\"\n {...{ [SLOT_ATTR]: \"code-editor-format-status\" }}\n className={styles.srOnly}\n >\n {formatStatus}\n </span>\n )}\n </div>\n )\n})\n"],"names":["FORMAT_FEEDBACK_MS","GUTTER","CODE_METRICS","shorthands","tokens.spacingElement2","tokens.fontMono","tokens.textXs","tokens.leadingXs","tokens.trackingNormal","tokens.fontWeightNormal","SEVERITY_TOKENS","tokens.errorUi","tokens.error11","tokens.warningUi","tokens.warning11","tokens.infoUi","tokens.info11","useStyles","makeZenithStyles","tokens.surfaceField","tokens.borderWidthField","tokens.borderField","tokens.surfaceRadiusField","tokens.focusRing","tokens.grayA3","SLOT_ATTR","tokens.grayA12","tokens.grayA8","tokens.accentA5","tokens.spacingElement3","tokens.grayA2","tokens.spacingElement05","FormatIcon","props","jsxs","jsx","CodeEditor","React","value","defaultValue","onValueChange","onChange","onKeyDown","onBlur","onFocus","onSelect","onScroll","onCompositionStart","onCompositionEnd","language","wrap","resize","indentWithTab","indentSize","invalid","readOnly","disabled","showLineNumbers","diagnostics","onFormat","onFormatError","formatLabel","formattedLabel","formatErrorLabel","autoSize","maxRows","rows","className","style","spellCheck","autoComplete","autoCorrect","autoCapitalize","dir","forwardedRef","styles","diagnosticsId","isControlled","uncontrolled","setUncontrolled","current","renderTokens","useCodeTokenRenderer","highlightRef","composing","setComposing","innerRef","setRefs","el","tabReleased","commit","next","lineCount","severities","severityByLine","listed","visibleDiagnostics","rowMode","caretLine","setCaretLine","syncCaretLine","lineIndexAt","handleChange","event","handleSelect","handleFocus","formatPending","formatting","setFormatting","formatStatus","setFormatStatus","formatTimer","announceFormat","message","runFormat","source","error","live","caret","caretAfterRewrite","handleKeyDown","applyIndent","handleBlur","handleScroll","layer","handleCompositionStart","handleCompositionEnd","highlightSource","highlighted","highlightCode","plainLines","tokenLines","splitTokenLines","wrapStyle","effectiveResize","resizeStyle","autoSizeStyle","rootStyle","gutterDigits","describedBy","severityClass","numberClass","mergeClasses","line","index","severity","active","Button","diagnostic"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"indent.js","sources":["../../../src/components/code-editor/indent.ts"],"sourcesContent":["/**\n * The text transform behind CodeEditor's Tab and Shift+Tab, kept separate from the component\n * because it is the only part with interesting edge cases and the only part worth testing without\n * a DOM: selection arithmetic is where this class of feature actually goes wrong, and a\n * `<textarea>` render adds nothing to that.\n *\n * Pure: takes a value and a selection, returns a value and a selection. It never touches the DOM.\n */\n\nexport type IndentSelection = {\n value: string\n selectionStart: number\n selectionEnd: number\n}\n\nexport type IndentOptions = {\n /** Shift+Tab: remove one level of leading indentation instead of adding one. */\n outdent: boolean\n /** Spaces per level. */\n indentSize: number\n}\n\n/** The line-start offset of the line containing `index`. */\nconst lineStartAt = (value: string, index: number): number =>\n value.lastIndexOf(\"\\n\", index - 1) + 1\n\n/** How many characters of leading indentation this line loses when outdented one level. */\nconst outdentWidth = (line: string, indentSize: number): number => {\n // A tab is one level however wide it renders, which is the only sane reading when the same\n // buffer mixes tabs and spaces.\n if (line.startsWith(\"\\t\")) return 1\n let spaces = 0\n while (spaces < indentSize && line[spaces] === \" \") spaces++\n return spaces\n}\n\n/**\n * Apply one level of indentation to `value` at the given selection.\n *\n * Three cases, matching what a code editor does:\n *\n * - **outdent** always works on whole lines, including a collapsed caret — Shift+Tab with no\n * selection is how you dedent the line you are on;\n * - **indent across a line break** works on whole lines, so indenting a block keeps it a block;\n * - **indent within one line** replaces the selection with one indent, which is what a plain\n * caret Tab has to mean.\n *\n * A selection that ends exactly at a line start does not reach into that line — dragging down to\n * the next line should not indent a line you cannot see selected. Blank lines are left alone when\n * indenting, so a block indent introduces no trailing whitespace.\n */\nexport function applyIndent(\n { value, selectionStart, selectionEnd }: IndentSelection,\n { outdent, indentSize }: IndentOptions\n): IndentSelection {\n const unit = \" \".repeat(Math.max(0, indentSize))\n const spansLines = value.slice(selectionStart, selectionEnd).includes(\"\\n\")\n\n if (!outdent && !spansLines) {\n return {\n value: value.slice(0, selectionStart) + unit + value.slice(selectionEnd),\n selectionStart: selectionStart + unit.length,\n selectionEnd: selectionStart + unit.length,\n }\n }\n\n const blockStart = lineStartAt(value, selectionStart)\n const effectiveEnd =\n selectionEnd > selectionStart && value[selectionEnd - 1] === \"\\n\"\n ? selectionEnd - 1\n : selectionEnd\n const nextBreak = value.indexOf(\"\\n\", effectiveEnd)\n const blockEnd = nextBreak === -1 ? value.length : nextBreak\n\n const lines = value.slice(blockStart, blockEnd).split(\"\\n\")\n\n let firstLineDelta = 0\n let totalDelta = 0\n const rewritten = lines.map((line, index) => {\n if (outdent) {\n const removed = outdentWidth(line, indentSize)\n if (index === 0) firstLineDelta = -removed\n totalDelta -= removed\n return line.slice(removed)\n }\n if (line.length === 0) return line\n if (index === 0) firstLineDelta = unit.length\n totalDelta += unit.length\n return unit + line\n })\n\n const nextValue =\n value.slice(0, blockStart) + rewritten.join(\"\\n\") + value.slice(blockEnd)\n\n // A selection that already started at column 0 stays at column 0, so indenting a block keeps\n // the whole block selected rather than dropping the indent it just added. A caret anywhere else\n // keeps its position *within* its line, moving by whatever that line gained or lost and never\n // past the line start.\n const nextStart =\n selectionStart === blockStart\n ? blockStart\n : Math.max(blockStart, selectionStart + firstLineDelta)\n const nextEnd = Math.max(nextStart, selectionEnd + totalDelta)\n\n return { value: nextValue, selectionStart: nextStart, selectionEnd: nextEnd }\n}\n"],"names":["lineStartAt","value","index","outdentWidth","line","indentSize","spaces","applyIndent","selectionStart","selectionEnd","outdent","unit","spansLines","blockStart","effectiveEnd","nextBreak","blockEnd","lines","firstLineDelta","totalDelta","rewritten","removed","nextValue","nextStart","nextEnd"],"mappings":"AAuBA,MAAMA,IAAc,CAACC,GAAeC,MAClCD,EAAM,YAAY;AAAA,GAAMC,IAAQ,CAAC,IAAI,GAGjCC,IAAe,CAACC,GAAcC,MAA+B;AAGjE,MAAID,EAAK,WAAW,GAAI,EAAG,QAAO;AAClC,MAAIE,IAAS;AACb,SAAOA,IAASD,KAAcD,EAAKE,CAAM,MAAM,MAAK,CAAAA;AACpD,SAAOA;AACT;AAiBO,SAASC,EACd,EAAE,OAAAN,GAAO,gBAAAO,GAAgB,cAAAC,KACzB,EAAE,SAAAC,GAAS,YAAAL,KACM;AACjB,QAAMM,IAAO,IAAI,OAAO,KAAK,IAAI,GAAGN,CAAU,CAAC,GACzCO,IAAaX,EAAM,MAAMO,GAAgBC,CAAY,EAAE,SAAS;AAAA,CAAI;AAE1E,MAAI,CAACC,KAAW,CAACE;AACf,WAAO;AAAA,MACL,OAAOX,EAAM,MAAM,GAAGO,CAAc,IAAIG,IAAOV,EAAM,MAAMQ,CAAY;AAAA,MACvE,gBAAgBD,IAAiBG,EAAK;AAAA,MACtC,cAAcH,IAAiBG,EAAK;AAAA,IAAA;AAIxC,QAAME,IAAab,EAAYC,GAAOO,CAAc,GAC9CM,IACJL,IAAeD,KAAkBP,EAAMQ,IAAe,CAAC,MAAM;AAAA,IACzDA,IAAe,IACfA,GACAM,IAAYd,EAAM,QAAQ;AAAA,GAAMa,CAAY,GAC5CE,IAAWD,MAAc,KAAKd,EAAM,SAASc,GAE7CE,IAAQhB,EAAM,MAAMY,GAAYG,CAAQ,EAAE,MAAM;AAAA,CAAI;AAE1D,MAAIE,IAAiB,GACjBC,IAAa;AACjB,QAAMC,IAAYH,EAAM,IAAI,CAACb,GAAMF,MAAU;AAC3C,QAAIQ,GAAS;AACX,YAAMW,IAAUlB,EAAaC,GAAMC,CAAU;AAC7C,aAAIH,MAAU,MAAGgB,IAAiB,CAACG,IACnCF,KAAcE,GACPjB,EAAK,MAAMiB,CAAO;AAAA,IAC3B;AACA,WAAIjB,EAAK,WAAW,IAAUA,KAC1BF,MAAU,MAAGgB,IAAiBP,EAAK,SACvCQ,KAAcR,EAAK,QACZA,IAAOP;AAAA,EAChB,CAAC,GAEKkB,IACJrB,EAAM,MAAM,GAAGY,CAAU,IAAIO,EAAU,KAAK;AAAA,CAAI,IAAInB,EAAM,MAAMe,CAAQ,GAMpEO,IACJf,MAAmBK,IACfA,IACA,KAAK,IAAIA,GAAYL,IAAiBU,CAAc,GACpDM,IAAU,KAAK,IAAID,GAAWd,IAAeU,CAAU;AAE7D,SAAO,EAAE,OAAOG,GAAW,gBAAgBC,GAAW,cAAcC,EAAA;AACtE;"}
1
+ {"version":3,"file":"indent.js","sources":["../../../src/components/code-editor/indent.ts"],"sourcesContent":["/**\n * The text transform behind CodeEditor's Tab and Shift+Tab, kept separate from the component\n * because it is the only part with interesting edge cases and the only part worth testing without\n * a DOM: selection arithmetic is where this class of feature actually goes wrong, and a\n * `<textarea>` render adds nothing to that.\n */\n\nexport type IndentSelection = {\n value: string\n selectionStart: number\n selectionEnd: number\n}\n\nexport type IndentOptions = {\n /** Shift+Tab: remove one level of leading indentation instead of adding one. */\n outdent: boolean\n /** Spaces per level. */\n indentSize: number\n}\n\n/** The line-start offset of the line containing `index`. */\nconst lineStartAt = (value: string, index: number): number =>\n value.lastIndexOf(\"\\n\", index - 1) + 1\n\n/** How many characters of leading indentation this line loses when outdented one level. */\nconst outdentWidth = (line: string, indentSize: number): number => {\n // A tab is one level however wide it renders, which is the only sane reading when the same\n // buffer mixes tabs and spaces.\n if (line.startsWith(\"\\t\")) return 1\n let spaces = 0\n while (spaces < indentSize && line[spaces] === \" \") spaces++\n return spaces\n}\n\n/** Apply one level of indentation to `value` at the given selection. */\nexport function applyIndent(\n { value, selectionStart, selectionEnd }: IndentSelection,\n { outdent, indentSize }: IndentOptions\n): IndentSelection {\n const unit = \" \".repeat(Math.max(0, indentSize))\n const spansLines = value.slice(selectionStart, selectionEnd).includes(\"\\n\")\n\n if (!outdent && !spansLines) {\n return {\n value: value.slice(0, selectionStart) + unit + value.slice(selectionEnd),\n selectionStart: selectionStart + unit.length,\n selectionEnd: selectionStart + unit.length,\n }\n }\n\n const blockStart = lineStartAt(value, selectionStart)\n const effectiveEnd =\n selectionEnd > selectionStart && value[selectionEnd - 1] === \"\\n\"\n ? selectionEnd - 1\n : selectionEnd\n const nextBreak = value.indexOf(\"\\n\", effectiveEnd)\n const blockEnd = nextBreak === -1 ? value.length : nextBreak\n\n const lines = value.slice(blockStart, blockEnd).split(\"\\n\")\n\n let firstLineDelta = 0\n let totalDelta = 0\n const rewritten = lines.map((line, index) => {\n if (outdent) {\n const removed = outdentWidth(line, indentSize)\n if (index === 0) firstLineDelta = -removed\n totalDelta -= removed\n return line.slice(removed)\n }\n if (line.length === 0) return line\n if (index === 0) firstLineDelta = unit.length\n totalDelta += unit.length\n return unit + line\n })\n\n const nextValue =\n value.slice(0, blockStart) + rewritten.join(\"\\n\") + value.slice(blockEnd)\n\n // A selection that already started at column 0 stays at column 0, so indenting a block keeps\n // the whole block selected rather than dropping the indent it just added. A caret anywhere else\n // keeps its position *within* its line, moving by whatever that line gained or lost and never\n // past the line start.\n const nextStart =\n selectionStart === blockStart\n ? blockStart\n : Math.max(blockStart, selectionStart + firstLineDelta)\n const nextEnd = Math.max(nextStart, selectionEnd + totalDelta)\n\n return { value: nextValue, selectionStart: nextStart, selectionEnd: nextEnd }\n}\n"],"names":["lineStartAt","value","index","outdentWidth","line","indentSize","spaces","applyIndent","selectionStart","selectionEnd","outdent","unit","spansLines","blockStart","effectiveEnd","nextBreak","blockEnd","lines","firstLineDelta","totalDelta","rewritten","removed","nextValue","nextStart","nextEnd"],"mappings":"AAqBA,MAAMA,IAAc,CAACC,GAAeC,MAClCD,EAAM,YAAY;AAAA,GAAMC,IAAQ,CAAC,IAAI,GAGjCC,IAAe,CAACC,GAAcC,MAA+B;AAGjE,MAAID,EAAK,WAAW,GAAI,EAAG,QAAO;AAClC,MAAIE,IAAS;AACb,SAAOA,IAASD,KAAcD,EAAKE,CAAM,MAAM,MAAK,CAAAA;AACpD,SAAOA;AACT;AAGO,SAASC,EACd,EAAE,OAAAN,GAAO,gBAAAO,GAAgB,cAAAC,KACzB,EAAE,SAAAC,GAAS,YAAAL,KACM;AACjB,QAAMM,IAAO,IAAI,OAAO,KAAK,IAAI,GAAGN,CAAU,CAAC,GACzCO,IAAaX,EAAM,MAAMO,GAAgBC,CAAY,EAAE,SAAS;AAAA,CAAI;AAE1E,MAAI,CAACC,KAAW,CAACE;AACf,WAAO;AAAA,MACL,OAAOX,EAAM,MAAM,GAAGO,CAAc,IAAIG,IAAOV,EAAM,MAAMQ,CAAY;AAAA,MACvE,gBAAgBD,IAAiBG,EAAK;AAAA,MACtC,cAAcH,IAAiBG,EAAK;AAAA,IAAA;AAIxC,QAAME,IAAab,EAAYC,GAAOO,CAAc,GAC9CM,IACJL,IAAeD,KAAkBP,EAAMQ,IAAe,CAAC,MAAM;AAAA,IACzDA,IAAe,IACfA,GACAM,IAAYd,EAAM,QAAQ;AAAA,GAAMa,CAAY,GAC5CE,IAAWD,MAAc,KAAKd,EAAM,SAASc,GAE7CE,IAAQhB,EAAM,MAAMY,GAAYG,CAAQ,EAAE,MAAM;AAAA,CAAI;AAE1D,MAAIE,IAAiB,GACjBC,IAAa;AACjB,QAAMC,IAAYH,EAAM,IAAI,CAACb,GAAMF,MAAU;AAC3C,QAAIQ,GAAS;AACX,YAAMW,IAAUlB,EAAaC,GAAMC,CAAU;AAC7C,aAAIH,MAAU,MAAGgB,IAAiB,CAACG,IACnCF,KAAcE,GACPjB,EAAK,MAAMiB,CAAO;AAAA,IAC3B;AACA,WAAIjB,EAAK,WAAW,IAAUA,KAC1BF,MAAU,MAAGgB,IAAiBP,EAAK,SACvCQ,KAAcR,EAAK,QACZA,IAAOP;AAAA,EAChB,CAAC,GAEKkB,IACJrB,EAAM,MAAM,GAAGY,CAAU,IAAIO,EAAU,KAAK;AAAA,CAAI,IAAInB,EAAM,MAAMe,CAAQ,GAMpEO,IACJf,MAAmBK,IACfA,IACA,KAAK,IAAIA,GAAYL,IAAiBU,CAAc,GACpDM,IAAU,KAAK,IAAID,GAAWd,IAAeU,CAAU;AAE7D,SAAO,EAAE,OAAOG,GAAW,gBAAgBC,GAAW,cAAcC,EAAA;AACtE;"}
@@ -3,7 +3,7 @@ import * as s from "react";
3
3
  import { Command as p } from "../../vendor/.bun/cmdk@1.1.1_2b23df507bdda662/vendor/cmdk/dist/index.js";
4
4
  import { mergeClasses as i, SLOT_ATTR as m, shorthands as c } from "@epilot/zenith-runtime/v1";
5
5
  import { makeZenithStyles as N } from "../../styles/make-styles.js";
6
- import { spacingElement3 as u, spacingElement2 as r, fontWeightMedium as S, grayA11 as h, leadingXs as v, textXs as T, accentA3 as L, grayA12 as y, leadingSm as C, textSm as x, spacingElement1 as f, semGraySoft as q, semFocusRing as I, body as B, radiusSm as D, radiusMd as b, grayA3 as E } from "../../tokens/index.js";
6
+ import { spacingElement3 as u, spacingElement2 as r, fontWeightMedium as S, grayA11 as h, leadingXs as v, textXs as T, accentA3 as L, grayA12 as y, leadingSm as C, textSm as x, spacingElement1 as f, graySoft as q, focusRing as I, body as B, radiusSm as D, radiusMd as b, grayA3 as E } from "../../tokens/index.js";
7
7
  import { Dialog as W, DialogHeader as X, DialogTitle as A, DialogDescription as H, DialogContent as z } from "../dialog/dialog.js";
8
8
  const Y = (d) => /* @__PURE__ */ a(
9
9
  "svg",
@@ -58,13 +58,7 @@ const Y = (d) => /* @__PURE__ */ a(
58
58
  outlineStyle: "solid",
59
59
  // Inset (negative), not the outward +2px every other audited control uses: this input sits
60
60
  // flush against the top edge of the Command root, which clips overflow for its rounded
61
- // corners. An outward ring's top 4px (width + offset) render outside that clip box and are
62
- // cut off — confirmed by measuring the rendered outline rect against the clipping ancestor's
63
- // rect (second a11y review, §2). Insetting keeps the ring's outer edge at the input's own
64
- // border edge, so it doesn't extend past this ancestor's clip box in this layout (it is not
65
- // a universal guarantee against every possible ancestor — an ancestor that clips the input's
66
- // OWN box, not just what extends beyond it, would still hide it). No layout change either
67
- // way: outline never affects box model regardless of sign.
61
+ // corners.
68
62
  outlineOffset: "-2px",
69
63
  outlineColor: I
70
64
  },
@@ -213,7 +207,7 @@ const Y = (d) => /* @__PURE__ */ a(
213
207
  whiteSpace: "nowrap",
214
208
  ...c.borderWidth(0)
215
209
  }
216
- }), G = s.forwardRef(function({ className: t, "data-slot": o = "command", ...e }, n) {
210
+ }), O = s.forwardRef(function({ className: t, "data-slot": o = "command", ...e }, n) {
217
211
  const g = l();
218
212
  return /* @__PURE__ */ a(
219
213
  p,
@@ -234,7 +228,7 @@ s.forwardRef(
234
228
  className: n,
235
229
  showCloseButton: g = !0,
236
230
  ...k
237
- }, O) {
231
+ }, G) {
238
232
  const w = l();
239
233
  return /* @__PURE__ */ R(W, { ...k, children: [
240
234
  /* @__PURE__ */ R(X, { className: w.srOnly, children: [
@@ -246,7 +240,7 @@ s.forwardRef(
246
240
  {
247
241
  className: i(w.dialogContent, n),
248
242
  showCloseButton: g,
249
- children: /* @__PURE__ */ a(G, { className: w.dialogCommand, children: e })
243
+ children: /* @__PURE__ */ a(O, { className: w.dialogCommand, children: e })
250
244
  }
251
245
  )
252
246
  ] });
@@ -363,14 +357,14 @@ const oo = s.forwardRef(function({ className: t, ...o }, e) {
363
357
  );
364
358
  });
365
359
  export {
366
- G as Command,
360
+ O as Command,
367
361
  K as CommandEmpty,
368
362
  Q as CommandGroup,
369
363
  F as CommandInput,
370
364
  V as CommandItem,
371
365
  J as CommandList,
372
366
  oo as CommandLoading,
373
- G as CommandRoot,
367
+ O as CommandRoot,
374
368
  U as CommandSeparator
375
369
  };
376
370
  //# sourceMappingURL=command.js.map