@bikdotai/bik-component-library 0.0.840 → 0.0.841-beta.1

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 (241) hide show
  1. package/dist/cjs/components/agent-builder/AgentBuilder.js +1 -1
  2. package/dist/cjs/components/agent-builder/AgentBuilder.js.map +1 -1
  3. package/dist/cjs/components/agent-builder/AgentBuilder.styled.js +51 -39
  4. package/dist/cjs/components/agent-builder/AgentBuilder.styled.js.map +1 -1
  5. package/dist/cjs/components/agent-builder/components/AgentBuilderFooter.js +1 -1
  6. package/dist/cjs/components/agent-builder/components/AgentBuilderFooter.js.map +1 -1
  7. package/dist/cjs/components/agent-builder/components/AgentBuilderTopBar.js +1 -1
  8. package/dist/cjs/components/agent-builder/components/AgentBuilderTopBar.js.map +1 -1
  9. package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js +2 -2
  10. package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
  11. package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +1 -1
  12. package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
  13. package/dist/cjs/components/agent-builder/components/DiscardModal.js +1 -1
  14. package/dist/cjs/components/agent-builder/components/DiscardModal.js.map +1 -1
  15. package/dist/cjs/components/agent-builder/components/GoLiveModal.js +1 -1
  16. package/dist/cjs/components/agent-builder/components/GoLiveModal.js.map +1 -1
  17. package/dist/cjs/components/agent-builder/components/MentionEditor.js +1 -1
  18. package/dist/cjs/components/agent-builder/components/MentionEditor.js.map +1 -1
  19. package/dist/cjs/components/agent-builder/components/MentionPicker.js +28 -22
  20. package/dist/cjs/components/agent-builder/components/MentionPicker.js.map +1 -1
  21. package/dist/cjs/components/agent-builder/components/RequireVerificationModal.js +2 -0
  22. package/dist/cjs/components/agent-builder/components/RequireVerificationModal.js.map +1 -0
  23. package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js +4 -4
  24. package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
  25. package/dist/cjs/components/agent-builder/components/SelectableListSection.js +6 -6
  26. package/dist/cjs/components/agent-builder/components/SelectableListSection.js.map +1 -1
  27. package/dist/cjs/components/agent-builder/components/StepSectionHeader.js +1 -1
  28. package/dist/cjs/components/agent-builder/components/StepSectionHeader.js.map +1 -1
  29. package/dist/cjs/components/agent-builder/constants/tools.js +1 -1
  30. package/dist/cjs/components/agent-builder/constants/tools.js.map +1 -1
  31. package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js +1 -1
  32. package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
  33. package/dist/cjs/components/agent-builder/steps/Step2WhenItStepsIn.js +3 -1
  34. package/dist/cjs/components/agent-builder/steps/Step2WhenItStepsIn.js.map +1 -1
  35. package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js +1 -1
  36. package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
  37. package/dist/cjs/components/agent-builder/steps/Step4HandoverRules.js +1 -1
  38. package/dist/cjs/components/agent-builder/steps/Step4HandoverRules.js.map +1 -1
  39. package/dist/cjs/components/agent-builder/utils/mentionSerialization.js +5 -3
  40. package/dist/cjs/components/agent-builder/utils/mentionSerialization.js.map +1 -1
  41. package/dist/cjs/components/agent-listing/AgentListing.js +1 -1
  42. package/dist/cjs/components/agent-listing/AgentListing.js.map +1 -1
  43. package/dist/cjs/components/agent-listing/AgentTable.js +1 -1
  44. package/dist/cjs/components/agent-listing/AgentTable.js.map +1 -1
  45. package/dist/cjs/components/agent-listing/AgentTableRow.js +1 -1
  46. package/dist/cjs/components/agent-listing/AgentTableRow.js.map +1 -1
  47. package/dist/cjs/components/agent-listing/AgentTableShimmer.js +2 -0
  48. package/dist/cjs/components/agent-listing/AgentTableShimmer.js.map +1 -0
  49. package/dist/cjs/components/agent-listing/DeleteAgentModal.js +1 -1
  50. package/dist/cjs/components/agent-listing/DeleteAgentModal.js.map +1 -1
  51. package/dist/cjs/components/button/Button.styled.js +1 -0
  52. package/dist/cjs/components/button/Button.styled.js.map +1 -1
  53. package/dist/cjs/components/card-selector/CardSelector.js +1 -1
  54. package/dist/cjs/components/card-selector/CardSelector.js.map +1 -1
  55. package/dist/cjs/components/card-selector/CardSelectorGroup.js +1 -1
  56. package/dist/cjs/components/card-selector/CardSelectorGroup.js.map +1 -1
  57. package/dist/cjs/components/carousel/carousel.js +2 -2
  58. package/dist/cjs/components/carousel/carousel.js.map +1 -1
  59. package/dist/cjs/components/checkBox/CheckBox.js +1 -1
  60. package/dist/cjs/components/checkBox/CheckBox.js.map +1 -1
  61. package/dist/cjs/components/code-block/CodeBlock.js +2 -2
  62. package/dist/cjs/components/code-block/CodeBlock.js.map +1 -1
  63. package/dist/cjs/components/colourInput/ColourInput.js +1 -1
  64. package/dist/cjs/components/colourInput/ColourInput.js.map +1 -1
  65. package/dist/cjs/components/dot-pulse/DotPulse.js +3 -3
  66. package/dist/cjs/components/dot-pulse/DotPulse.js.map +1 -1
  67. package/dist/cjs/components/dropShadow/DropShadow.js +1 -1
  68. package/dist/cjs/components/dropShadow/DropShadow.js.map +1 -1
  69. package/dist/cjs/components/dropdown/ChipInput.js +1 -1
  70. package/dist/cjs/components/dropdown/ChipInput.js.map +1 -1
  71. package/dist/cjs/components/dropdown/Dropdown.js +1 -1
  72. package/dist/cjs/components/dropdown/Dropdown.js.map +1 -1
  73. package/dist/cjs/components/dropdown/DropdownPopover/index.js +1 -1
  74. package/dist/cjs/components/dropdown/DropdownPopover/index.js.map +1 -1
  75. package/dist/cjs/components/floater/floater.js +1 -1
  76. package/dist/cjs/components/floater/floater.js.map +1 -1
  77. package/dist/cjs/components/modals/styledModal.js +2 -2
  78. package/dist/cjs/components/modals/styledModal.js.map +1 -1
  79. package/dist/cjs/components/pagination/Pagination.js +1 -1
  80. package/dist/cjs/components/pagination/Pagination.js.map +1 -1
  81. package/dist/cjs/components/progress-bar/CircularProgressBar.js +1 -1
  82. package/dist/cjs/components/progress-bar/CircularProgressBar.js.map +1 -1
  83. package/dist/cjs/components/progress-bar/ProgressBarComponent.js +2 -2
  84. package/dist/cjs/components/progress-bar/ProgressBarComponent.js.map +1 -1
  85. package/dist/cjs/components/progress-bar-v2/ProgressBarV2.js +17 -17
  86. package/dist/cjs/components/progress-bar-v2/ProgressBarV2.js.map +1 -1
  87. package/dist/cjs/components/shimmer-image/ShimmerImage.js +1 -1
  88. package/dist/cjs/components/shimmer-image/ShimmerImage.js.map +1 -1
  89. package/dist/cjs/components/spinner/Spinner.js +3 -3
  90. package/dist/cjs/components/spinner/Spinner.js.map +1 -1
  91. package/dist/cjs/components/states/StateComponent.js +1 -1
  92. package/dist/cjs/components/states/StateComponent.js.map +1 -1
  93. package/dist/cjs/components/stepper/Stepper.js +1 -1
  94. package/dist/cjs/components/stepper/Stepper.js.map +1 -1
  95. package/dist/cjs/components/testimonial-card/TestimonialCard.js +1 -1
  96. package/dist/cjs/components/testimonial-card/TestimonialCard.js.map +1 -1
  97. package/dist/cjs/components/unsatisfactory-response-list/UnsatisfactoryResponseList.js +1 -1
  98. package/dist/cjs/components/unsatisfactory-response-list/UnsatisfactoryResponseList.js.map +1 -1
  99. package/dist/cjs/editor/BikEditor.js +1 -1
  100. package/dist/cjs/editor/BikEditor.js.map +1 -1
  101. package/dist/cjs/editor/BikEditor.styles.js +97 -54
  102. package/dist/cjs/editor/BikEditor.styles.js.map +1 -1
  103. package/dist/cjs/editor/extensions/jsonHighlight/JsonHighlightExtension.js +3 -3
  104. package/dist/cjs/editor/extensions/jsonHighlight/JsonHighlightExtension.js.map +1 -1
  105. package/dist/cjs/icons/Informational/Common UI/Shield.js +2 -0
  106. package/dist/cjs/icons/Informational/Common UI/Shield.js.map +1 -0
  107. package/dist/cjs/icons/index.js +1 -1
  108. package/dist/esm/components/agent-builder/AgentBuilder.js +106 -102
  109. package/dist/esm/components/agent-builder/AgentBuilder.js.map +1 -1
  110. package/dist/esm/components/agent-builder/AgentBuilder.model.d.ts +31 -1
  111. package/dist/esm/components/agent-builder/AgentBuilder.styled.d.ts +3 -6
  112. package/dist/esm/components/agent-builder/AgentBuilder.styled.js +118 -106
  113. package/dist/esm/components/agent-builder/AgentBuilder.styled.js.map +1 -1
  114. package/dist/esm/components/agent-builder/__fixtures__/agentValue.d.ts +11 -0
  115. package/dist/esm/components/agent-builder/components/AgentBuilderFooter.js +29 -21
  116. package/dist/esm/components/agent-builder/components/AgentBuilderFooter.js.map +1 -1
  117. package/dist/esm/components/agent-builder/components/AgentBuilderTopBar.js +27 -26
  118. package/dist/esm/components/agent-builder/components/AgentBuilderTopBar.js.map +1 -1
  119. package/dist/esm/components/agent-builder/components/ConfigToolPanel.js +25 -25
  120. package/dist/esm/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
  121. package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +24 -23
  122. package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
  123. package/dist/esm/components/agent-builder/components/DiscardModal.d.ts +3 -1
  124. package/dist/esm/components/agent-builder/components/DiscardModal.js +33 -24
  125. package/dist/esm/components/agent-builder/components/DiscardModal.js.map +1 -1
  126. package/dist/esm/components/agent-builder/components/GoLiveModal.js +23 -21
  127. package/dist/esm/components/agent-builder/components/GoLiveModal.js.map +1 -1
  128. package/dist/esm/components/agent-builder/components/MentionEditor.js +19 -19
  129. package/dist/esm/components/agent-builder/components/MentionEditor.js.map +1 -1
  130. package/dist/esm/components/agent-builder/components/MentionPicker.js +205 -154
  131. package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
  132. package/dist/esm/components/agent-builder/components/RequireVerificationModal.d.ts +18 -0
  133. package/dist/esm/components/agent-builder/components/RequireVerificationModal.js +74 -0
  134. package/dist/esm/components/agent-builder/components/RequireVerificationModal.js.map +1 -0
  135. package/dist/esm/components/agent-builder/components/RestApiToolPanel.d.ts +2 -0
  136. package/dist/esm/components/agent-builder/components/RestApiToolPanel.js +111 -105
  137. package/dist/esm/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
  138. package/dist/esm/components/agent-builder/components/SelectableListSection.d.ts +18 -4
  139. package/dist/esm/components/agent-builder/components/SelectableListSection.js +174 -138
  140. package/dist/esm/components/agent-builder/components/SelectableListSection.js.map +1 -1
  141. package/dist/esm/components/agent-builder/components/StepSectionHeader.js +7 -7
  142. package/dist/esm/components/agent-builder/components/StepSectionHeader.js.map +1 -1
  143. package/dist/esm/components/agent-builder/constants/tools.js +6 -6
  144. package/dist/esm/components/agent-builder/constants/tools.js.map +1 -1
  145. package/dist/esm/components/agent-builder/context/AgentBuilderContext.js +104 -103
  146. package/dist/esm/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
  147. package/dist/esm/components/agent-builder/steps/Step2WhenItStepsIn.js +101 -102
  148. package/dist/esm/components/agent-builder/steps/Step2WhenItStepsIn.js.map +1 -1
  149. package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +289 -205
  150. package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
  151. package/dist/esm/components/agent-builder/steps/Step4HandoverRules.js +23 -79
  152. package/dist/esm/components/agent-builder/steps/Step4HandoverRules.js.map +1 -1
  153. package/dist/esm/components/agent-builder/utils/mentionSerialization.d.ts +2 -0
  154. package/dist/esm/components/agent-builder/utils/mentionSerialization.js +59 -46
  155. package/dist/esm/components/agent-builder/utils/mentionSerialization.js.map +1 -1
  156. package/dist/esm/components/agent-listing/AgentListing.js +70 -65
  157. package/dist/esm/components/agent-listing/AgentListing.js.map +1 -1
  158. package/dist/esm/components/agent-listing/AgentTable.d.ts +2 -0
  159. package/dist/esm/components/agent-listing/AgentTable.js +16 -15
  160. package/dist/esm/components/agent-listing/AgentTable.js.map +1 -1
  161. package/dist/esm/components/agent-listing/AgentTableRow.js +11 -11
  162. package/dist/esm/components/agent-listing/AgentTableRow.js.map +1 -1
  163. package/dist/esm/components/agent-listing/AgentTableShimmer.d.ts +12 -0
  164. package/dist/esm/components/agent-listing/AgentTableShimmer.js +20 -0
  165. package/dist/esm/components/agent-listing/AgentTableShimmer.js.map +1 -0
  166. package/dist/esm/components/agent-listing/DeleteAgentModal.js +8 -8
  167. package/dist/esm/components/agent-listing/DeleteAgentModal.js.map +1 -1
  168. package/dist/esm/components/agent-listing/__fixtures__/agents.d.ts +3 -0
  169. package/dist/esm/components/button/Button.styled.js +25 -19
  170. package/dist/esm/components/button/Button.styled.js.map +1 -1
  171. package/dist/esm/components/card-selector/CardSelector.js +11 -9
  172. package/dist/esm/components/card-selector/CardSelector.js.map +1 -1
  173. package/dist/esm/components/card-selector/CardSelectorGroup.js +1 -0
  174. package/dist/esm/components/card-selector/CardSelectorGroup.js.map +1 -1
  175. package/dist/esm/components/carousel/carousel.js +8 -8
  176. package/dist/esm/components/carousel/carousel.js.map +1 -1
  177. package/dist/esm/components/checkBox/CheckBox.js +8 -5
  178. package/dist/esm/components/checkBox/CheckBox.js.map +1 -1
  179. package/dist/esm/components/code-block/CodeBlock.js +14 -14
  180. package/dist/esm/components/code-block/CodeBlock.js.map +1 -1
  181. package/dist/esm/components/colourInput/ColourInput.js +11 -10
  182. package/dist/esm/components/colourInput/ColourInput.js.map +1 -1
  183. package/dist/esm/components/dot-pulse/DotPulse.js +15 -15
  184. package/dist/esm/components/dot-pulse/DotPulse.js.map +1 -1
  185. package/dist/esm/components/dropShadow/DropShadow.js +6 -6
  186. package/dist/esm/components/dropShadow/DropShadow.js.map +1 -1
  187. package/dist/esm/components/dropdown/ChipInput.js +10 -9
  188. package/dist/esm/components/dropdown/ChipInput.js.map +1 -1
  189. package/dist/esm/components/dropdown/Dropdown.js +18 -13
  190. package/dist/esm/components/dropdown/Dropdown.js.map +1 -1
  191. package/dist/esm/components/dropdown/DropdownPopover/index.js +26 -25
  192. package/dist/esm/components/dropdown/DropdownPopover/index.js.map +1 -1
  193. package/dist/esm/components/floater/floater.js +14 -13
  194. package/dist/esm/components/floater/floater.js.map +1 -1
  195. package/dist/esm/components/modals/styledModal.js +6 -5
  196. package/dist/esm/components/modals/styledModal.js.map +1 -1
  197. package/dist/esm/components/pagination/Pagination.js +7 -7
  198. package/dist/esm/components/pagination/Pagination.js.map +1 -1
  199. package/dist/esm/components/progress-bar/CircularProgressBar.js +61 -50
  200. package/dist/esm/components/progress-bar/CircularProgressBar.js.map +1 -1
  201. package/dist/esm/components/progress-bar/ProgressBarComponent.js +14 -13
  202. package/dist/esm/components/progress-bar/ProgressBarComponent.js.map +1 -1
  203. package/dist/esm/components/progress-bar-v2/ProgressBarV2.js +57 -39
  204. package/dist/esm/components/progress-bar-v2/ProgressBarV2.js.map +1 -1
  205. package/dist/esm/components/shimmer-image/ShimmerImage.js +19 -18
  206. package/dist/esm/components/shimmer-image/ShimmerImage.js.map +1 -1
  207. package/dist/esm/components/spinner/Spinner.js +19 -11
  208. package/dist/esm/components/spinner/Spinner.js.map +1 -1
  209. package/dist/esm/components/states/StateComponent.js +47 -30
  210. package/dist/esm/components/states/StateComponent.js.map +1 -1
  211. package/dist/esm/components/stepper/Stepper.js +24 -16
  212. package/dist/esm/components/stepper/Stepper.js.map +1 -1
  213. package/dist/esm/components/testimonial-card/TestimonialCard.js +5 -4
  214. package/dist/esm/components/testimonial-card/TestimonialCard.js.map +1 -1
  215. package/dist/esm/components/unsatisfactory-response-list/UnsatisfactoryResponseList.js +19 -18
  216. package/dist/esm/components/unsatisfactory-response-list/UnsatisfactoryResponseList.js.map +1 -1
  217. package/dist/esm/editor/BikEditor.js +173 -160
  218. package/dist/esm/editor/BikEditor.js.map +1 -1
  219. package/dist/esm/editor/BikEditor.styles.d.ts +20 -3
  220. package/dist/esm/editor/BikEditor.styles.js +102 -57
  221. package/dist/esm/editor/BikEditor.styles.js.map +1 -1
  222. package/dist/esm/editor/extensions/jsonHighlight/JsonHighlightExtension.d.ts +5 -8
  223. package/dist/esm/editor/extensions/jsonHighlight/JsonHighlightExtension.js +87 -68
  224. package/dist/esm/editor/extensions/jsonHighlight/JsonHighlightExtension.js.map +1 -1
  225. package/dist/esm/icons/Informational/Common UI/Shield.d.ts +6 -0
  226. package/dist/esm/icons/Informational/Common UI/Shield.js +33 -0
  227. package/dist/esm/icons/Informational/Common UI/Shield.js.map +1 -0
  228. package/dist/esm/icons/Informational/Common UI/index.d.ts +1 -0
  229. package/dist/esm/icons/Media/Visual/index.d.ts +0 -2
  230. package/dist/esm/icons/index.d.ts +25 -25
  231. package/dist/esm/icons/index.js +418 -420
  232. package/dist/esm/icons/index.js.map +1 -1
  233. package/package.json +1 -1
  234. package/dist/cjs/icons/Media/Visual/FormkitNeutral.js +0 -2
  235. package/dist/cjs/icons/Media/Visual/FormkitNeutral.js.map +0 -1
  236. package/dist/cjs/icons/Media/Visual/FormkitSad.js +0 -2
  237. package/dist/cjs/icons/Media/Visual/FormkitSad.js.map +0 -1
  238. package/dist/esm/icons/Media/Visual/FormkitNeutral.js +0 -58
  239. package/dist/esm/icons/Media/Visual/FormkitNeutral.js.map +0 -1
  240. package/dist/esm/icons/Media/Visual/FormkitSad.js +0 -61
  241. package/dist/esm/icons/Media/Visual/FormkitSad.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport { BodyCaption } from '@src/components/TypographyStyle';\nimport { Copy, WandSparkles } from '../icons';\nimport {\n\tBikEditorShell,\n\tBikJsonError,\n\tBikJsonHeader,\n} from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n\tJsonParseResult,\n} from './BikEditor.types';\nimport {\n\tbuildJsonCodeBlockHtml,\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tgetCodeBlockText,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tparseJson,\n\tsetCodeBlockText,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tcharacterLimit,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t\trenderJsonError,\n\t} = props;\n\n\tconst isJsonMode = !!features?.jsonMode;\n\n\t// Live JSON parse error, shown inside the editor when jsonMode is on.\n\t// null = valid (or not applicable) → nothing rendered.\n\tconst [jsonError, setJsonError] = useState<JsonParseResult | null>(null);\n\t// Transient \"Copied\" state for the jsonMode copy button.\n\tconst [jsonCopied, setJsonCopied] = useState(false);\n\n\t// JSON body mode: treat initialContent as raw JSON text and wrap it in a code\n\t// block. Skips section/HTML normalisation entirely.\n\tconst initialEditorContent = isJsonMode\n\t\t? buildJsonCodeBlockHtml(initialContent ?? '')\n\t\t: sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst prevFormatsRef = useRef<FormatState>(DEFAULT_FORMAT_STATE);\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\tcharacterLimit,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\tremoveMentionTriggerOnDismiss: mentions?.removeTriggerOnDismiss,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t\tif (isJsonMode) {\n\t\t\t\tconst result = parseJson(getCodeBlockText(e));\n\t\t\t\tsetJsonError(result.valid ? null : result);\n\t\t\t}\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tconst next = extractActiveFormats(e);\n\t\t\tconst prev = prevFormatsRef.current;\n\t\t\tconst changed =\n\t\t\t\tprev.bold !== next.bold ||\n\t\t\t\tprev.italic !== next.italic ||\n\t\t\t\tprev.underline !== next.underline ||\n\t\t\t\tprev.strike !== next.strike ||\n\t\t\t\tprev.bulletList !== next.bulletList ||\n\t\t\t\tprev.orderedList !== next.orderedList ||\n\t\t\t\tprev.blockquote !== next.blockquote ||\n\t\t\t\tprev.codeBlock !== next.codeBlock ||\n\t\t\t\tprev.superscript !== next.superscript ||\n\t\t\t\tprev.subscript !== next.subscript ||\n\t\t\t\tprev.textAlign !== next.textAlign ||\n\t\t\t\tprev.fontFamily !== next.fontFamily ||\n\t\t\t\tprev.fontSize !== next.fontSize ||\n\t\t\t\tprev.color !== next.color ||\n\t\t\t\tprev.highlight !== next.highlight ||\n\t\t\t\tprev.link?.href !== next.link?.href;\n\t\t\tif (changed) {\n\t\t\t\tprevFormatsRef.current = next;\n\t\t\t\tonSelectionChangeRef.current?.(next);\n\t\t\t}\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t\t// Surface an error for invalid initialContent immediately on mount.\n\t\tif (isJsonMode) {\n\t\t\tconst result = parseJson(getCodeBlockText(editor));\n\t\t\tsetJsonError(result.valid ? null : result);\n\t\t}\n\t}, [editor, isJsonMode]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1)\n\t\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\n\t\t\t// ── JSON body ─────────────────────────────────────────────────────\n\t\t\tjson: features?.jsonMode\n\t\t\t\t? {\n\t\t\t\t\t\tgetText: () => (editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tsetText: (raw) => enqueue((e) => setCodeBlockText(e, raw)),\n\t\t\t\t\t\tparse: () => parseJson(editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tisValid: () =>\n\t\t\t\t\t\t\tparseJson(editor ? getCodeBlockText(editor) : '').valid,\n\t\t\t\t\t\tformat: (indent = 2) =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value, null, indent));\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tminify: () =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value));\n\t\t\t\t\t\t\t}),\n\t\t\t\t }\n\t\t\t\t: undefined,\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\t// ── jsonMode floating actions ────────────────────────────────────────────\n\t// Beautify pretty-prints in place (no-op / disabled while the JSON is broken);\n\t// Copy writes the raw text to the clipboard with transient feedback.\n\tconst handleJsonBeautify = () => {\n\t\tif (!editor) return;\n\t\tconst { valid, value } = parseJson(getCodeBlockText(editor));\n\t\tif (!valid || value === null) return;\n\t\tsetCodeBlockText(editor, JSON.stringify(value, null, 2));\n\t};\n\tconst handleJsonCopy = () => {\n\t\tif (!editor) return;\n\t\tvoid navigator.clipboard?.writeText(getCodeBlockText(editor));\n\t\tsetJsonCopied(true);\n\t\tsetTimeout(() => setJsonCopied(false), 1500);\n\t};\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tjsonMode={isJsonMode}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t{isJsonMode && (\n\t\t\t\t<BikJsonHeader>\n\t\t\t\t\t<span className=\"bik-json-header-label\">JSON</span>\n\t\t\t\t\t<div className=\"bik-json-header-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={handleJsonBeautify}\n\t\t\t\t\t\t\tdisabled={!!jsonError}\n\t\t\t\t\t\t\ttitle=\"Format JSON\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<WandSparkles size={16} />\n\t\t\t\t\t\t\t<BodyCaption>Beautify</BodyCaption>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button type=\"button\" onClick={handleJsonCopy} title=\"Copy JSON\">\n\t\t\t\t\t\t\t<Copy size={16} />\n\t\t\t\t\t\t\t{jsonCopied && <BodyCaption>Copied</BodyCaption>}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</BikJsonHeader>\n\t\t\t)}\n\t\t\t<EditorContent editor={editor} />\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t\t{isJsonMode && jsonError ? (\n\t\t\t\trenderJsonError ? (\n\t\t\t\t\trenderJsonError(jsonError)\n\t\t\t\t) : (\n\t\t\t\t\t<BikJsonError>\n\t\t\t\t\t\t{jsonError.line != null && (\n\t\t\t\t\t\t\t<strong>\n\t\t\t\t\t\t\t\tLine {jsonError.line}\n\t\t\t\t\t\t\t\t{jsonError.column != null ? `, column ${jsonError.column}` : ''}\n\t\t\t\t\t\t\t\t:{' '}\n\t\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{jsonError.error}\n\t\t\t\t\t</BikJsonError>\n\t\t\t\t)\n\t\t\t) : null}\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","k","v","c","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","characterLimit","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","renderJsonError","isJsonMode","jsonError","setJsonError","useState","jsonCopied","setJsonCopied","initialEditorContent","buildJsonCodeBlockHtml","buildSectionedContent","normalizeHtml","s","pendingQueue","useRef","hasCalledOnReady","onReadyRef","onChangeRef","onSelectionChangeRef","prevFormatsRef","DEFAULT_FORMAT_STATE","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","teamMentionsRef","slashCommandsRef","editor","useEditor","buildExtensions","snapshot","extractContent","result","parseJson","getCodeBlockText","next","extractActiveFormats","prev","enqueue","op","useEffect","useImperativeHandle","position","e","html","normalised","insertInlineHtml","agentIds","teamIds","node","from","to","pos","state","empty","linkMarkType","range","getMarkRange","sectionId","extractSectionContent","setSectionContentInEditor","endOfBody","targetPos","extractBodyContent","body","boundaryPos","findSectionEndPos","findSectionStartPos","align","font","size","color","href","text","tr","linkNode","space","emoji","variableName","src","raw","setCodeBlockText","indent","valid","value","handleJsonBeautify","handleJsonCopy","jsxs","BikEditorShell","BikJsonHeader","jsx","WandSparkles","BodyCaption","Copy","EditorContent","LinkBubbleMenu","BikJsonError","BikEditor","forwardRef"],"mappings":"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"}
1
+ {"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport { BodyCaption } from '@src/components/TypographyStyle';\nimport { Code, Copy, Info, WandSparkles } from '../icons';\nimport {\n\tBikEditorShell,\n\tBikJsonBody,\n\tBikJsonEmptyState,\n\tBikJsonError,\n\tBikJsonHeader,\n} from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n\tJsonParseResult,\n} from './BikEditor.types';\nimport {\n\tbuildJsonCodeBlockHtml,\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tgetCodeBlockText,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tparseJson,\n\tsetCodeBlockText,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tcharacterLimit,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t\trenderJsonError,\n\t} = props;\n\n\tconst isJsonMode = !!features?.jsonMode;\n\n\t// Live JSON parse error, shown inside the editor when jsonMode is on.\n\t// null = valid (or not applicable) → nothing rendered.\n\tconst [jsonError, setJsonError] = useState<JsonParseResult | null>(null);\n\t// Transient \"Copied\" state for the jsonMode copy button.\n\tconst [jsonCopied, setJsonCopied] = useState(false);\n\t// jsonMode: no content yet → centered code-glyph + placeholder overlay.\n\tconst [jsonEmpty, setJsonEmpty] = useState(\n\t\tisJsonMode && !(initialContent ?? '').trim(),\n\t);\n\n\t// JSON body mode: treat initialContent as raw JSON text and wrap it in a code\n\t// block. Skips section/HTML normalisation entirely.\n\tconst initialEditorContent = isJsonMode\n\t\t? buildJsonCodeBlockHtml(initialContent ?? '')\n\t\t: sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst prevFormatsRef = useRef<FormatState>(DEFAULT_FORMAT_STATE);\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\tcharacterLimit,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\tremoveMentionTriggerOnDismiss: mentions?.removeTriggerOnDismiss,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t\tif (isJsonMode) {\n\t\t\t\tconst text = getCodeBlockText(e);\n\t\t\t\tconst result = parseJson(text);\n\t\t\t\tsetJsonError(result.valid ? null : result);\n\t\t\t\tsetJsonEmpty(!text.trim());\n\t\t\t}\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tconst next = extractActiveFormats(e);\n\t\t\tconst prev = prevFormatsRef.current;\n\t\t\tconst changed =\n\t\t\t\tprev.bold !== next.bold ||\n\t\t\t\tprev.italic !== next.italic ||\n\t\t\t\tprev.underline !== next.underline ||\n\t\t\t\tprev.strike !== next.strike ||\n\t\t\t\tprev.bulletList !== next.bulletList ||\n\t\t\t\tprev.orderedList !== next.orderedList ||\n\t\t\t\tprev.blockquote !== next.blockquote ||\n\t\t\t\tprev.codeBlock !== next.codeBlock ||\n\t\t\t\tprev.superscript !== next.superscript ||\n\t\t\t\tprev.subscript !== next.subscript ||\n\t\t\t\tprev.textAlign !== next.textAlign ||\n\t\t\t\tprev.fontFamily !== next.fontFamily ||\n\t\t\t\tprev.fontSize !== next.fontSize ||\n\t\t\t\tprev.color !== next.color ||\n\t\t\t\tprev.highlight !== next.highlight ||\n\t\t\t\tprev.link?.href !== next.link?.href;\n\t\t\tif (changed) {\n\t\t\t\tprevFormatsRef.current = next;\n\t\t\t\tonSelectionChangeRef.current?.(next);\n\t\t\t}\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t\t// Surface an error for invalid initialContent immediately on mount.\n\t\tif (isJsonMode) {\n\t\t\tconst text = getCodeBlockText(editor);\n\t\t\tconst result = parseJson(text);\n\t\t\tsetJsonError(result.valid ? null : result);\n\t\t\tsetJsonEmpty(!text.trim());\n\t\t}\n\t}, [editor, isJsonMode]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1)\n\t\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised, {\n\t\t\t\t\t\tparseOptions: { preserveWhitespace: true },\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\n\t\t\t// ── JSON body ─────────────────────────────────────────────────────\n\t\t\tjson: features?.jsonMode\n\t\t\t\t? {\n\t\t\t\t\t\tgetText: () => (editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tsetText: (raw) => enqueue((e) => setCodeBlockText(e, raw)),\n\t\t\t\t\t\tparse: () => parseJson(editor ? getCodeBlockText(editor) : ''),\n\t\t\t\t\t\tisValid: () =>\n\t\t\t\t\t\t\tparseJson(editor ? getCodeBlockText(editor) : '').valid,\n\t\t\t\t\t\tformat: (indent = 2) =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value, null, indent));\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\tminify: () =>\n\t\t\t\t\t\t\tenqueue((e) => {\n\t\t\t\t\t\t\t\tconst { valid, value } = parseJson(getCodeBlockText(e));\n\t\t\t\t\t\t\t\tif (!valid || value === null) return;\n\t\t\t\t\t\t\t\tsetCodeBlockText(e, JSON.stringify(value));\n\t\t\t\t\t\t\t}),\n\t\t\t\t }\n\t\t\t\t: undefined,\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\t// ── jsonMode floating actions ────────────────────────────────────────────\n\t// Beautify pretty-prints in place (no-op / disabled while the JSON is broken);\n\t// Copy writes the raw text to the clipboard with transient feedback.\n\tconst handleJsonBeautify = () => {\n\t\tif (!editor) return;\n\t\tconst { valid, value } = parseJson(getCodeBlockText(editor));\n\t\tif (!valid || value === null) return;\n\t\tsetCodeBlockText(editor, JSON.stringify(value, null, 2));\n\t};\n\tconst handleJsonCopy = () => {\n\t\tif (!editor) return;\n\t\tvoid navigator.clipboard?.writeText(getCodeBlockText(editor));\n\t\tsetJsonCopied(true);\n\t\tsetTimeout(() => setJsonCopied(false), 1500);\n\t};\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tjsonMode={isJsonMode}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t{isJsonMode && (\n\t\t\t\t<BikJsonHeader>\n\t\t\t\t\t<span className=\"bik-json-header-label\">JSON</span>\n\t\t\t\t\t<div className=\"bik-json-header-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={handleJsonBeautify}\n\t\t\t\t\t\t\tdisabled={!!jsonError}\n\t\t\t\t\t\t\ttitle=\"Format JSON\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<WandSparkles size={16} />\n\t\t\t\t\t\t\t<BodyCaption>Beautify</BodyCaption>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button type=\"button\" onClick={handleJsonCopy} title=\"Copy JSON\">\n\t\t\t\t\t\t\t<Copy size={16} />\n\t\t\t\t\t\t\t{jsonCopied && <BodyCaption>Copied</BodyCaption>}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</BikJsonHeader>\n\t\t\t)}\n\t\t\t{isJsonMode ? (\n\t\t\t\t<BikJsonBody $error={!!jsonError}>\n\t\t\t\t\t<EditorContent editor={editor} />\n\t\t\t\t\t{jsonEmpty && (\n\t\t\t\t\t\t<BikJsonEmptyState aria-hidden>\n\t\t\t\t\t\t\t<Code size={20} />\n\t\t\t\t\t\t\t<span>{props.placeholder ?? 'Type or paste JSON here'}</span>\n\t\t\t\t\t\t</BikJsonEmptyState>\n\t\t\t\t\t)}\n\t\t\t\t</BikJsonBody>\n\t\t\t) : (\n\t\t\t\t<EditorContent editor={editor} />\n\t\t\t)}\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t\t{isJsonMode && jsonError ? (\n\t\t\t\trenderJsonError ? (\n\t\t\t\t\trenderJsonError(jsonError)\n\t\t\t\t) : (\n\t\t\t\t\t<BikJsonError>\n\t\t\t\t\t\t<Info size={16} />\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t{jsonError.line != null && (\n\t\t\t\t\t\t\t\t<strong>\n\t\t\t\t\t\t\t\t\tLine {jsonError.line}\n\t\t\t\t\t\t\t\t\t{jsonError.column != null\n\t\t\t\t\t\t\t\t\t\t? `, column ${jsonError.column}`\n\t\t\t\t\t\t\t\t\t\t: ''}\n\t\t\t\t\t\t\t\t\t:{' '}\n\t\t\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{jsonError.error}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</BikJsonError>\n\t\t\t\t)\n\t\t\t) : null}\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","k","v","c","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","characterLimit","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","renderJsonError","isJsonMode","jsonError","setJsonError","useState","jsonCopied","setJsonCopied","jsonEmpty","setJsonEmpty","initialEditorContent","buildJsonCodeBlockHtml","buildSectionedContent","normalizeHtml","s","pendingQueue","useRef","hasCalledOnReady","onReadyRef","onChangeRef","onSelectionChangeRef","prevFormatsRef","DEFAULT_FORMAT_STATE","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","teamMentionsRef","slashCommandsRef","editor","useEditor","buildExtensions","snapshot","extractContent","text","getCodeBlockText","result","parseJson","next","extractActiveFormats","prev","enqueue","op","useEffect","useImperativeHandle","position","e","html","normalised","insertInlineHtml","agentIds","teamIds","node","from","to","pos","state","empty","linkMarkType","range","getMarkRange","sectionId","extractSectionContent","setSectionContentInEditor","endOfBody","targetPos","extractBodyContent","body","boundaryPos","findSectionEndPos","findSectionStartPos","align","font","size","color","href","tr","linkNode","space","emoji","variableName","src","raw","setCodeBlockText","indent","valid","value","handleJsonBeautify","handleJsonCopy","jsxs","BikEditorShell","BikJsonHeader","jsx","WandSparkles","BodyCaption","Copy","BikJsonBody","EditorContent","BikJsonEmptyState","Code","LinkBubbleMenu","BikJsonError","Info","BikEditor","forwardRef"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("styled-components"),o=require("../constants/Theme.js"),i=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},r=i(t),n=r.default.div`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("styled-components"),e=require("../constants/Theme.js"),i=o=>o&&typeof o=="object"&&"default"in o?o:{default:o},t=i(r),n=t.default.div`
2
2
  position: relative;
3
3
  width: 100%;
4
4
 
5
5
  .ProseMirror {
6
- min-height: ${({minHeight:e})=>e??"60px"};
7
- max-height: ${({maxHeight:e})=>e??"none"};
6
+ min-height: ${({minHeight:o})=>o??"60px"};
7
+ max-height: ${({maxHeight:o})=>o??"none"};
8
8
  overflow-y: auto;
9
9
  outline: none;
10
10
  font-size: 14px;
@@ -21,7 +21,7 @@
21
21
  no paragraph-gap concept — paragraphs are tight (margin:0) regardless of
22
22
  typed vs pasted. (A margin:0 attr still overrides to tight either way.) */
23
23
  p {
24
- margin: ${({tightParagraphs:e})=>e?"0":"1em 0"};
24
+ margin: ${({tightParagraphs:o})=>o?"0":"1em 0"};
25
25
  padding: 0;
26
26
  }
27
27
 
@@ -65,16 +65,16 @@
65
65
  /* Characters pasted beyond the soft character limit — rendered grey so the
66
66
  overflow is visible but clearly marked (see CharacterLimitExtension). */
67
67
  .bik-editor-overflow {
68
- color: ${o.COLORS.content.placeholder};
68
+ color: ${e.COLORS.content.placeholder};
69
69
  }
70
70
  }
71
71
 
72
72
  .bik-mention {
73
- color: ${o.COLORS.content.brand};
73
+ color: ${e.COLORS.content.brand};
74
74
  padding: 1px 4px;
75
75
  }
76
76
  .bik-mention--team {
77
- color: ${o.COLORS.content.brand};
77
+ color: ${e.COLORS.content.brand};
78
78
  }
79
79
  /* Typed mention chips (agent-builder): distinct colour per reference kind. */
80
80
  .bik-mention[data-kind='tool'] {
@@ -93,21 +93,17 @@
93
93
  }
94
94
 
95
95
  /* JSON body mode — scoped so normal-mode code blocks keep their default look
96
- (no reserved gutter, no monospace override). */
97
- ${({jsonMode:e})=>e&&t.css`
98
- /* Self-framed card: the header bar and the code area share one rounded
99
- border, so the component renders as a complete panel without the
100
- consumer having to wrap it. */
101
- border: 1px solid #e1e4e8;
102
- border-radius: 8px;
103
- overflow: hidden;
104
-
96
+ (no reserved gutter, no monospace override). The frame is split: the header
97
+ bar owns the top rounded border, the code area (BikJsonBody) owns its own
98
+ full border so it can recolour on focus / error without touching the
99
+ header. */
100
+ ${({jsonMode:o})=>o&&r.css`
105
101
  /* The code block IS the editor surface, sitting below the header bar.
106
102
  White fills the scroller down to the min-height (no blank strip below
107
103
  short JSON); the header owns the grey. */
108
104
  .ProseMirror {
109
105
  padding: 0;
110
- background: #ffffff;
106
+ background: ${e.COLORS.surface.standard};
111
107
  }
112
108
  /* ProseMirror appends an empty trailing paragraph AFTER the code block
113
109
  (a <p><br class="ProseMirror-trailingBreak"></p> caret-escape node).
@@ -121,8 +117,9 @@
121
117
  margin: 0;
122
118
  background: transparent;
123
119
  /* Left padding reserves the line-number gutter; each .bik-json-lineno
124
- widget hangs back into it with a matching negative margin. */
125
- padding: 12px 12px 12px 3.5em;
120
+ widget hangs back into it with a matching negative margin. Wide
121
+ enough for a 3-digit line number (up to 999). */
122
+ padding: 12px 12px 12px 4.2em;
126
123
  font-family: 'SFMono-Regular', ui-monospace, 'JetBrains Mono', Menlo,
127
124
  Consolas, 'Liberation Mono', monospace;
128
125
  font-size: 13px;
@@ -137,22 +134,32 @@
137
134
  font-size: inherit;
138
135
  color: #1f2328;
139
136
  }
140
- /* Line-number gutter. Numbers hang into the code block's left padding via
141
- a negative margin (width + margin-right == the reserved padding, so the
142
- code text still starts at the padding edge). Stacked right borders form
143
- one continuous divider line. */
137
+ /* Line-number gutter a contenteditable=false sibling of <code> rendered
138
+ by the code-block node view (JsonCodeBlockView), absolutely positioned
139
+ into the reserved left padding. It scrolls with <pre> as one block, so
140
+ numbers stay aligned with their lines. Stacked right borders form one
141
+ continuous divider. */
142
+ .bik-json-gutter {
143
+ position: absolute;
144
+ left: 0;
145
+ top: 12px; /* == the code block's padding-top */
146
+ width: 3.5em; /* within the 4.2em reserved left padding */
147
+ display: flex;
148
+ flex-direction: column;
149
+ user-select: none;
150
+ -webkit-user-select: none;
151
+ pointer-events: none;
152
+ }
144
153
  .bik-json-lineno {
145
- display: inline-block;
146
154
  box-sizing: border-box;
147
- width: 2.5em;
148
- margin-left: -3.5em;
149
- margin-right: 1em;
155
+ height: 1.6em; /* == code line-height (13px × 1.6) so rows align */
156
+ line-height: 1.6;
150
157
  padding-right: 0.7em;
151
158
  text-align: right;
152
- color: #8c959f;
153
- border-right: 1px solid #e1e4e8;
154
- user-select: none;
155
- -webkit-user-select: none;
159
+ /* Never let a 3-digit number (e.g. 210) break across two lines. */
160
+ white-space: nowrap;
161
+ color: ${e.COLORS.content.placeholder};
162
+ border-right: 1px solid ${e.COLORS.stroke.primary};
156
163
  }
157
164
  .bik-json-key {
158
165
  color: #0550ae;
@@ -185,62 +192,98 @@
185
192
  text-decoration-color: #6366f1;
186
193
  }
187
194
  }
188
- `,a=r.default.div`
195
+ `,a=t.default.div`
189
196
  display: flex;
190
197
  align-items: center;
191
198
  justify-content: space-between;
192
199
  gap: 8px;
193
200
  padding: 8px 12px;
194
- background: #f6f8fa;
195
- border-bottom: 1px solid #e1e4e8;
201
+ background: ${e.COLORS.surface.subdued};
202
+ border: 1px solid ${e.COLORS.stroke.primary};
203
+ border-bottom: none;
204
+ border-radius: 4px 4px 0 0;
196
205
 
197
206
  .bik-json-header-label {
198
207
  font-family: inherit;
199
208
  font-size: 14px;
200
- font-weight: 500;
201
- color: #3c4149;
209
+ line-height: 20px;
210
+ font-weight: 400;
211
+ color: ${e.COLORS.content.secondary};
202
212
  user-select: none;
203
213
  }
204
214
 
205
215
  .bik-json-header-actions {
206
216
  display: flex;
207
- gap: 6px;
217
+ gap: 8px;
208
218
  }
209
219
 
210
220
  button {
211
221
  display: inline-flex;
212
222
  align-items: center;
213
- gap: 6px;
214
- padding: 6px 10px;
223
+ gap: 4px;
224
+ height: 28px;
225
+ padding: 0 8px;
215
226
  font-family: inherit;
216
- font-size: 13px;
217
- line-height: 1.4;
218
- color: #3c4149;
219
- background: #ffffff;
220
- border: 1px solid #d0d7de;
221
- border-radius: 6px;
227
+ font-size: 12px;
228
+ line-height: 16px;
229
+ color: ${e.COLORS.content.secondary};
230
+ background: ${e.COLORS.surface.standard};
231
+ border: 1px solid ${e.COLORS.stroke.primary};
232
+ border-radius: 4px;
222
233
  cursor: pointer;
223
234
 
224
235
  &:hover:not(:disabled) {
225
- background: #f3f4f6;
226
- border-color: #adb5bd;
236
+ background: ${e.COLORS.surface.subdued};
227
237
  }
228
238
  &:disabled {
229
239
  opacity: 0.5;
230
240
  cursor: not-allowed;
231
241
  }
232
242
  }
233
- `,d=r.default.div`
234
- padding: 6px 12px;
243
+ `,s=t.default.div`
244
+ position: relative;
245
+ overflow: hidden;
246
+ background: ${e.COLORS.surface.standard};
247
+ border: 1px solid
248
+ ${({$error:o})=>o?e.COLORS.content.negative:e.COLORS.stroke.primary};
249
+ border-radius: 0 0 4px 4px;
250
+
251
+ &:focus-within {
252
+ border-color: ${({$error:o})=>o?e.COLORS.content.negative:e.BASE_COLORS.brand[800]};
253
+ }
254
+ `,d=t.default.div`
255
+ position: absolute;
256
+ inset: 0;
257
+ display: flex;
258
+ flex-direction: column;
259
+ align-items: center;
260
+ justify-content: center;
261
+ gap: 8px;
262
+ color: ${e.COLORS.content.placeholder};
263
+ font-size: 14px;
264
+ line-height: 20px;
265
+ pointer-events: none;
266
+ user-select: none;
267
+ `,l=t.default.div`
268
+ display: flex;
269
+ align-items: flex-start;
270
+ gap: 8px;
271
+ margin-top: 8px;
272
+ padding: 12px;
235
273
  font-size: 12px;
236
- line-height: 1.5;
237
- color: #d1242f;
238
- background: #fff0f0;
239
- border-top: 1px solid #ffd7d5;
274
+ line-height: 16px;
275
+ color: ${e.COLORS.content.negative};
276
+ background: ${e.COLORS.background.negative.light};
277
+ border: 1px solid ${e.COLORS.stroke.negative.lightAlt};
278
+ border-radius: 4px;
240
279
  word-break: break-word;
241
280
 
281
+ svg {
282
+ flex-shrink: 0;
283
+ }
284
+
242
285
  strong {
243
286
  font-weight: 600;
244
287
  }
245
- `;exports.BikEditorShell=n;exports.BikJsonError=d;exports.BikJsonHeader=a;
288
+ `;exports.BikEditorShell=n;exports.BikJsonBody=s;exports.BikJsonEmptyState=d;exports.BikJsonError=l;exports.BikJsonHeader=a;
246
289
  //# sourceMappingURL=BikEditor.styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BikEditor.styles.js","sources":["../../../src/editor/BikEditor.styles.ts"],"sourcesContent":["import styled, { css } from 'styled-components';\nimport { COLORS } from '../constants/Theme';\n\nexport const BikEditorShell = styled.div<{\n\tminHeight?: string;\n\tmaxHeight?: string;\n\ttightParagraphs?: boolean;\n\tjsonMode?: boolean;\n}>`\n\tposition: relative;\n\twidth: 100%;\n\n\t.ProseMirror {\n\t\tmin-height: ${({ minHeight }) => minHeight ?? '60px'};\n\t\tmax-height: ${({ maxHeight }) => maxHeight ?? 'none'};\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t\tfont-size: 14px;\n\t\tline-height: 1.5;\n\t\tword-break: break-word;\n\n\t\t/* Paragraph spacing.\n\t\t Email/signature (rich): paragraphs carry the browser-default 1em block\n\t\t margin — the SAME spacing the sent HTML gets (we emit plain <p>, which\n\t\t renders against the default <p> margin in Gmail and our email viewer),\n\t\t so editor view == emitted HTML == Gmail. A single Enter = a new\n\t\t paragraph with a visible gap, like pasted Gmail/ChatGPT/Docs content.\n\t\t Other channels (WhatsApp/IG/FB/comments) are plain-text messaging, with\n\t\t no paragraph-gap concept — paragraphs are tight (margin:0) regardless of\n\t\t typed vs pasted. (A margin:0 attr still overrides to tight either way.) */\n\t\tp {\n\t\t\tmargin: ${({ tightParagraphs }) => (tightParagraphs ? '0' : '1em 0')};\n\t\t\tpadding: 0;\n\t\t}\n\n\t\tul,\n\t\tol {\n\t\t\tmargin: 0;\n\t\t\tpadding-left: 1.5em;\n\t\t}\n\n\t\tli + li {\n\t\t\tmargin-top: 2px;\n\t\t}\n\n\t\t/* The empty placeholder paragraph shouldn't inherit the rich-mode 1em\n\t\t block margin (email/SMTP/signature) — otherwise the placeholder text\n\t\t is pushed down. Real (non-empty) paragraphs keep their spacing. */\n\t\tp.is-editor-empty:first-child {\n\t\t\tmargin: 0;\n\t\t}\n\n\t\tp.is-editor-empty:first-child::before {\n\t\t\tcontent: attr(data-placeholder);\n\t\t\tfloat: left;\n\t\t\tcolor: #adb5bd;\n\t\t\tpointer-events: none;\n\t\t\theight: 0;\n\t\t}\n\n\t\t/* hidden in-flow copy of the placeholder so a multi-line\n\t\t placeholder grows the editor instead of showing a scrollbar (the\n\t\t zero-height float above adds no height). -1lh cancels the caret line. */\n\t\tp.is-editor-empty:first-child::after {\n\t\t\tcontent: attr(data-placeholder);\n\t\t\tdisplay: block;\n\t\t\tvisibility: hidden;\n\t\t\tpointer-events: none;\n\t\t\tmargin-top: -1.5em; /* one line at the editor's line-height: 1.5 */\n\t\t\tmargin-top: -1lh;\n\t\t}\n\n\t\t/* Characters pasted beyond the soft character limit — rendered grey so the\n\t\t overflow is visible but clearly marked (see CharacterLimitExtension). */\n\t\t.bik-editor-overflow {\n\t\t\tcolor: ${COLORS.content.placeholder};\n\t\t}\n\t}\n\n\t.bik-mention {\n\t\tcolor: ${COLORS.content.brand};\n\t\tpadding: 1px 4px;\n\t}\n\t.bik-mention--team {\n\t\tcolor: ${COLORS.content.brand};\n\t}\n\t/* Typed mention chips (agent-builder): distinct colour per reference kind. */\n\t.bik-mention[data-kind='tool'] {\n\t\tcolor: #1570ef;\n\t\tbackground: #eff8ff;\n\t\tborder-radius: 4px;\n\t\tfont-weight: 500;\n\t}\n\t.bik-mention[data-kind='subagent'] {\n\t\tcolor: #6938ef;\n\t\tbackground: #f4f3ff;\n\t\tborder-radius: 4px;\n\t\tfont-weight: 500;\n\t}\n\t.bik-variable {\n\t}\n\n\t/* JSON body mode — scoped so normal-mode code blocks keep their default look\n\t (no reserved gutter, no monospace override). */\n\t${({ jsonMode }) =>\n\t\tjsonMode &&\n\t\tcss`\n\t\t\t/* Self-framed card: the header bar and the code area share one rounded\n\t\t\t border, so the component renders as a complete panel without the\n\t\t\t consumer having to wrap it. */\n\t\t\tborder: 1px solid #e1e4e8;\n\t\t\tborder-radius: 8px;\n\t\t\toverflow: hidden;\n\n\t\t\t/* The code block IS the editor surface, sitting below the header bar.\n\t\t\t White fills the scroller down to the min-height (no blank strip below\n\t\t\t short JSON); the header owns the grey. */\n\t\t\t.ProseMirror {\n\t\t\t\tpadding: 0;\n\t\t\t\tbackground: #ffffff;\n\t\t\t}\n\t\t\t/* ProseMirror appends an empty trailing paragraph AFTER the code block\n\t\t\t (a <p><br class=\"ProseMirror-trailingBreak\"></p> caret-escape node).\n\t\t\t In JSON mode there's nothing to escape to — it only renders as a blank\n\t\t\t line under the JSON, which is the \"extra space at the bottom\". Hide it. */\n\t\t\t.ProseMirror pre + p {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t\t.ProseMirror pre {\n\t\t\t\tposition: relative;\n\t\t\t\tmargin: 0;\n\t\t\t\tbackground: transparent;\n\t\t\t\t/* Left padding reserves the line-number gutter; each .bik-json-lineno\n\t\t\t\t widget hangs back into it with a matching negative margin. */\n\t\t\t\tpadding: 12px 12px 12px 3.5em;\n\t\t\t\tfont-family: 'SFMono-Regular', ui-monospace, 'JetBrains Mono', Menlo,\n\t\t\t\t\tConsolas, 'Liberation Mono', monospace;\n\t\t\t\tfont-size: 13px;\n\t\t\t\tline-height: 1.6;\n\t\t\t\twhite-space: pre;\n\t\t\t\toverflow-x: auto;\n\t\t\t\ttab-size: 2;\n\t\t\t}\n\t\t\t.ProseMirror pre code {\n\t\t\t\tbackground: none;\n\t\t\t\tpadding: 0;\n\t\t\t\tfont-size: inherit;\n\t\t\t\tcolor: #1f2328;\n\t\t\t}\n\t\t\t/* Line-number gutter. Numbers hang into the code block's left padding via\n\t\t\t a negative margin (width + margin-right == the reserved padding, so the\n\t\t\t code text still starts at the padding edge). Stacked right borders form\n\t\t\t one continuous divider line. */\n\t\t\t.bik-json-lineno {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tbox-sizing: border-box;\n\t\t\t\twidth: 2.5em;\n\t\t\t\tmargin-left: -3.5em;\n\t\t\t\tmargin-right: 1em;\n\t\t\t\tpadding-right: 0.7em;\n\t\t\t\ttext-align: right;\n\t\t\t\tcolor: #8c959f;\n\t\t\t\tborder-right: 1px solid #e1e4e8;\n\t\t\t\tuser-select: none;\n\t\t\t\t-webkit-user-select: none;\n\t\t\t}\n\t\t\t.bik-json-key {\n\t\t\t\tcolor: #0550ae;\n\t\t\t}\n\t\t\t.bik-json-string {\n\t\t\t\tcolor: #0a7d33;\n\t\t\t}\n\t\t\t.bik-json-number {\n\t\t\t\tcolor: #b5590a;\n\t\t\t}\n\t\t\t.bik-json-boolean,\n\t\t\t.bik-json-null {\n\t\t\t\tcolor: #8250df;\n\t\t\t\tfont-weight: 500;\n\t\t\t}\n\t\t\t.bik-json-punct {\n\t\t\t\tcolor: #57606a;\n\t\t\t}\n\t\t`}\n\n\ta,\n\t.bik-link {\n\t\tcolor: #4f46e5;\n\t\ttext-decoration: underline;\n\t\ttext-decoration-color: #a5b4fc;\n\t\ttext-underline-offset: 2px;\n\t\tcursor: pointer;\n\t\t&:hover {\n\t\t\tcolor: #3730a3;\n\t\t\ttext-decoration-color: #6366f1;\n\t\t}\n\t}\n`;\n\n/**\n * jsonMode header bar: a \"JSON\" label on the left and the Beautify / Copy actions\n * on the right, sitting above the code area with a bottom divider. Grey fill sets\n * it apart from the white code surface below (see the jsonMode block above).\n */\nexport const BikJsonHeader = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 8px;\n\tpadding: 8px 12px;\n\tbackground: #f6f8fa;\n\tborder-bottom: 1px solid #e1e4e8;\n\n\t.bik-json-header-label {\n\t\tfont-family: inherit;\n\t\tfont-size: 14px;\n\t\tfont-weight: 500;\n\t\tcolor: #3c4149;\n\t\tuser-select: none;\n\t}\n\n\t.bik-json-header-actions {\n\t\tdisplay: flex;\n\t\tgap: 6px;\n\t}\n\n\tbutton {\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tgap: 6px;\n\t\tpadding: 6px 10px;\n\t\tfont-family: inherit;\n\t\tfont-size: 13px;\n\t\tline-height: 1.4;\n\t\tcolor: #3c4149;\n\t\tbackground: #ffffff;\n\t\tborder: 1px solid #d0d7de;\n\t\tborder-radius: 6px;\n\t\tcursor: pointer;\n\n\t\t&:hover:not(:disabled) {\n\t\t\tbackground: #f3f4f6;\n\t\t\tborder-color: #adb5bd;\n\t\t}\n\t\t&:disabled {\n\t\t\topacity: 0.5;\n\t\t\tcursor: not-allowed;\n\t\t}\n\t}\n`;\n\n/** Inline JSON parse-error banner rendered by BikEditor in jsonMode. */\nexport const BikJsonError = styled.div`\n\tpadding: 6px 12px;\n\tfont-size: 12px;\n\tline-height: 1.5;\n\tcolor: #d1242f;\n\tbackground: #fff0f0;\n\tborder-top: 1px solid #ffd7d5;\n\tword-break: break-word;\n\n\tstrong {\n\t\tfont-weight: 600;\n\t}\n`;\n"],"names":["BikEditorShell","styled","minHeight","maxHeight","tightParagraphs","COLORS","jsonMode","css","BikJsonHeader","BikJsonError"],"mappings":"uNAGaA,EAAiBC,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,gBAUrB,CAAC,CAAE,UAAAC,KAAgBA,GAAa,MAAM;AAAA,gBACtC,CAAC,CAAE,UAAAC,KAAgBA,GAAa,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAiBzC,CAAC,CAAE,gBAAAC,CAAA,IAAuBA,EAAkB,IAAM,OAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YA4C3DC,EAAAA,OAAO,QAAQ,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,WAK3BA,EAAAA,OAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA,WAIpBA,EAAAA,OAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAoB5B,CAAC,CAAE,SAAAC,KACJA,GACAC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,GA6EC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBUC,EAAgBP,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgDvBQ,EAAeR,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA"}
1
+ {"version":3,"file":"BikEditor.styles.js","sources":["../../../src/editor/BikEditor.styles.ts"],"sourcesContent":["import styled, { css } from 'styled-components';\nimport { BASE_COLORS, COLORS } from '../constants/Theme';\n\nexport const BikEditorShell = styled.div<{\n\tminHeight?: string;\n\tmaxHeight?: string;\n\ttightParagraphs?: boolean;\n\tjsonMode?: boolean;\n}>`\n\tposition: relative;\n\twidth: 100%;\n\n\t.ProseMirror {\n\t\tmin-height: ${({ minHeight }) => minHeight ?? '60px'};\n\t\tmax-height: ${({ maxHeight }) => maxHeight ?? 'none'};\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t\tfont-size: 14px;\n\t\tline-height: 1.5;\n\t\tword-break: break-word;\n\n\t\t/* Paragraph spacing.\n\t\t Email/signature (rich): paragraphs carry the browser-default 1em block\n\t\t margin — the SAME spacing the sent HTML gets (we emit plain <p>, which\n\t\t renders against the default <p> margin in Gmail and our email viewer),\n\t\t so editor view == emitted HTML == Gmail. A single Enter = a new\n\t\t paragraph with a visible gap, like pasted Gmail/ChatGPT/Docs content.\n\t\t Other channels (WhatsApp/IG/FB/comments) are plain-text messaging, with\n\t\t no paragraph-gap concept — paragraphs are tight (margin:0) regardless of\n\t\t typed vs pasted. (A margin:0 attr still overrides to tight either way.) */\n\t\tp {\n\t\t\tmargin: ${({ tightParagraphs }) => (tightParagraphs ? '0' : '1em 0')};\n\t\t\tpadding: 0;\n\t\t}\n\n\t\tul,\n\t\tol {\n\t\t\tmargin: 0;\n\t\t\tpadding-left: 1.5em;\n\t\t}\n\n\t\tli + li {\n\t\t\tmargin-top: 2px;\n\t\t}\n\n\t\t/* The empty placeholder paragraph shouldn't inherit the rich-mode 1em\n\t\t block margin (email/SMTP/signature) — otherwise the placeholder text\n\t\t is pushed down. Real (non-empty) paragraphs keep their spacing. */\n\t\tp.is-editor-empty:first-child {\n\t\t\tmargin: 0;\n\t\t}\n\n\t\tp.is-editor-empty:first-child::before {\n\t\t\tcontent: attr(data-placeholder);\n\t\t\tfloat: left;\n\t\t\tcolor: #adb5bd;\n\t\t\tpointer-events: none;\n\t\t\theight: 0;\n\t\t}\n\n\t\t/* hidden in-flow copy of the placeholder so a multi-line\n\t\t placeholder grows the editor instead of showing a scrollbar (the\n\t\t zero-height float above adds no height). -1lh cancels the caret line. */\n\t\tp.is-editor-empty:first-child::after {\n\t\t\tcontent: attr(data-placeholder);\n\t\t\tdisplay: block;\n\t\t\tvisibility: hidden;\n\t\t\tpointer-events: none;\n\t\t\tmargin-top: -1.5em; /* one line at the editor's line-height: 1.5 */\n\t\t\tmargin-top: -1lh;\n\t\t}\n\n\t\t/* Characters pasted beyond the soft character limit — rendered grey so the\n\t\t overflow is visible but clearly marked (see CharacterLimitExtension). */\n\t\t.bik-editor-overflow {\n\t\t\tcolor: ${COLORS.content.placeholder};\n\t\t}\n\t}\n\n\t.bik-mention {\n\t\tcolor: ${COLORS.content.brand};\n\t\tpadding: 1px 4px;\n\t}\n\t.bik-mention--team {\n\t\tcolor: ${COLORS.content.brand};\n\t}\n\t/* Typed mention chips (agent-builder): distinct colour per reference kind. */\n\t.bik-mention[data-kind='tool'] {\n\t\tcolor: #1570ef;\n\t\tbackground: #eff8ff;\n\t\tborder-radius: 4px;\n\t\tfont-weight: 500;\n\t}\n\t.bik-mention[data-kind='subagent'] {\n\t\tcolor: #6938ef;\n\t\tbackground: #f4f3ff;\n\t\tborder-radius: 4px;\n\t\tfont-weight: 500;\n\t}\n\t.bik-variable {\n\t}\n\n\t/* JSON body mode — scoped so normal-mode code blocks keep their default look\n\t (no reserved gutter, no monospace override). The frame is split: the header\n\t bar owns the top rounded border, the code area (BikJsonBody) owns its own\n\t full border so it can recolour on focus / error without touching the\n\t header. */\n\t${({ jsonMode }) =>\n\t\tjsonMode &&\n\t\tcss`\n\t\t\t/* The code block IS the editor surface, sitting below the header bar.\n\t\t\t White fills the scroller down to the min-height (no blank strip below\n\t\t\t short JSON); the header owns the grey. */\n\t\t\t.ProseMirror {\n\t\t\t\tpadding: 0;\n\t\t\t\tbackground: ${COLORS.surface.standard};\n\t\t\t}\n\t\t\t/* ProseMirror appends an empty trailing paragraph AFTER the code block\n\t\t\t (a <p><br class=\"ProseMirror-trailingBreak\"></p> caret-escape node).\n\t\t\t In JSON mode there's nothing to escape to — it only renders as a blank\n\t\t\t line under the JSON, which is the \"extra space at the bottom\". Hide it. */\n\t\t\t.ProseMirror pre + p {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t\t.ProseMirror pre {\n\t\t\t\tposition: relative;\n\t\t\t\tmargin: 0;\n\t\t\t\tbackground: transparent;\n\t\t\t\t/* Left padding reserves the line-number gutter; each .bik-json-lineno\n\t\t\t\t widget hangs back into it with a matching negative margin. Wide\n\t\t\t\t enough for a 3-digit line number (up to 999). */\n\t\t\t\tpadding: 12px 12px 12px 4.2em;\n\t\t\t\tfont-family: 'SFMono-Regular', ui-monospace, 'JetBrains Mono', Menlo,\n\t\t\t\t\tConsolas, 'Liberation Mono', monospace;\n\t\t\t\tfont-size: 13px;\n\t\t\t\tline-height: 1.6;\n\t\t\t\twhite-space: pre;\n\t\t\t\toverflow-x: auto;\n\t\t\t\ttab-size: 2;\n\t\t\t}\n\t\t\t.ProseMirror pre code {\n\t\t\t\tbackground: none;\n\t\t\t\tpadding: 0;\n\t\t\t\tfont-size: inherit;\n\t\t\t\tcolor: #1f2328;\n\t\t\t}\n\t\t\t/* Line-number gutter — a contenteditable=false sibling of <code> rendered\n\t\t\t by the code-block node view (JsonCodeBlockView), absolutely positioned\n\t\t\t into the reserved left padding. It scrolls with <pre> as one block, so\n\t\t\t numbers stay aligned with their lines. Stacked right borders form one\n\t\t\t continuous divider. */\n\t\t\t.bik-json-gutter {\n\t\t\t\tposition: absolute;\n\t\t\t\tleft: 0;\n\t\t\t\ttop: 12px; /* == the code block's padding-top */\n\t\t\t\twidth: 3.5em; /* within the 4.2em reserved left padding */\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-direction: column;\n\t\t\t\tuser-select: none;\n\t\t\t\t-webkit-user-select: none;\n\t\t\t\tpointer-events: none;\n\t\t\t}\n\t\t\t.bik-json-lineno {\n\t\t\t\tbox-sizing: border-box;\n\t\t\t\theight: 1.6em; /* == code line-height (13px × 1.6) so rows align */\n\t\t\t\tline-height: 1.6;\n\t\t\t\tpadding-right: 0.7em;\n\t\t\t\ttext-align: right;\n\t\t\t\t/* Never let a 3-digit number (e.g. 210) break across two lines. */\n\t\t\t\twhite-space: nowrap;\n\t\t\t\tcolor: ${COLORS.content.placeholder};\n\t\t\t\tborder-right: 1px solid ${COLORS.stroke.primary};\n\t\t\t}\n\t\t\t.bik-json-key {\n\t\t\t\tcolor: #0550ae;\n\t\t\t}\n\t\t\t.bik-json-string {\n\t\t\t\tcolor: #0a7d33;\n\t\t\t}\n\t\t\t.bik-json-number {\n\t\t\t\tcolor: #b5590a;\n\t\t\t}\n\t\t\t.bik-json-boolean,\n\t\t\t.bik-json-null {\n\t\t\t\tcolor: #8250df;\n\t\t\t\tfont-weight: 500;\n\t\t\t}\n\t\t\t.bik-json-punct {\n\t\t\t\tcolor: #57606a;\n\t\t\t}\n\t\t`}\n\n\ta,\n\t.bik-link {\n\t\tcolor: #4f46e5;\n\t\ttext-decoration: underline;\n\t\ttext-decoration-color: #a5b4fc;\n\t\ttext-underline-offset: 2px;\n\t\tcursor: pointer;\n\t\t&:hover {\n\t\t\tcolor: #3730a3;\n\t\t\ttext-decoration-color: #6366f1;\n\t\t}\n\t}\n`;\n\n/**\n * jsonMode header bar: a \"JSON\" label on the left and the Beautify / Copy actions\n * on the right. Owns the frame's top rounded border (no bottom edge — the code\n * area below draws its own top border, so the seam stays a single line even when\n * it recolours on focus/error). Grey fill sets it apart from the white code\n * surface below.\n */\nexport const BikJsonHeader = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 8px;\n\tpadding: 8px 12px;\n\tbackground: ${COLORS.surface.subdued};\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-bottom: none;\n\tborder-radius: 4px 4px 0 0;\n\n\t.bik-json-header-label {\n\t\tfont-family: inherit;\n\t\tfont-size: 14px;\n\t\tline-height: 20px;\n\t\tfont-weight: 400;\n\t\tcolor: ${COLORS.content.secondary};\n\t\tuser-select: none;\n\t}\n\n\t.bik-json-header-actions {\n\t\tdisplay: flex;\n\t\tgap: 8px;\n\t}\n\n\tbutton {\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\t\tgap: 4px;\n\t\theight: 28px;\n\t\tpadding: 0 8px;\n\t\tfont-family: inherit;\n\t\tfont-size: 12px;\n\t\tline-height: 16px;\n\t\tcolor: ${COLORS.content.secondary};\n\t\tbackground: ${COLORS.surface.standard};\n\t\tborder: 1px solid ${COLORS.stroke.primary};\n\t\tborder-radius: 4px;\n\t\tcursor: pointer;\n\n\t\t&:hover:not(:disabled) {\n\t\t\tbackground: ${COLORS.surface.subdued};\n\t\t}\n\t\t&:disabled {\n\t\t\topacity: 0.5;\n\t\t\tcursor: not-allowed;\n\t\t}\n\t}\n`;\n\n/**\n * jsonMode code surface below the header. Owns the recolourable border: brand on\n * focus, negative when the JSON is invalid (error wins over focus).\n */\nexport const BikJsonBody = styled.div<{ $error?: boolean }>`\n\tposition: relative;\n\toverflow: hidden;\n\tbackground: ${COLORS.surface.standard};\n\tborder: 1px solid\n\t\t${({ $error }) =>\n\t\t\t$error ? COLORS.content.negative : COLORS.stroke.primary};\n\tborder-radius: 0 0 4px 4px;\n\n\t&:focus-within {\n\t\tborder-color: ${({ $error }) =>\n\t\t\t$error ? COLORS.content.negative : BASE_COLORS.brand['800']};\n\t}\n`;\n\n/**\n * jsonMode empty state: a centered code glyph + placeholder line over the code\n * area. Pointer-events off so clicks focus the editor.\n */\nexport const BikJsonEmptyState = styled.div`\n\tposition: absolute;\n\tinset: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: 8px;\n\tcolor: ${COLORS.content.placeholder};\n\tfont-size: 14px;\n\tline-height: 20px;\n\tpointer-events: none;\n\tuser-select: none;\n`;\n\n/**\n * JSON parse-error alert rendered by BikEditor in jsonMode: a standalone rounded\n * card below the code area.\n */\nexport const BikJsonError = styled.div`\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 8px;\n\tmargin-top: 8px;\n\tpadding: 12px;\n\tfont-size: 12px;\n\tline-height: 16px;\n\tcolor: ${COLORS.content.negative};\n\tbackground: ${COLORS.background.negative.light};\n\tborder: 1px solid ${COLORS.stroke.negative.lightAlt};\n\tborder-radius: 4px;\n\tword-break: break-word;\n\n\tsvg {\n\t\tflex-shrink: 0;\n\t}\n\n\tstrong {\n\t\tfont-weight: 600;\n\t}\n`;\n"],"names":["BikEditorShell","styled","minHeight","maxHeight","tightParagraphs","COLORS","jsonMode","css","BikJsonHeader","BikJsonBody","$error","BASE_COLORS","BikJsonEmptyState","BikJsonError"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("../../../node_modules/@tiptap/core/dist/index.js"),a=require("@tiptap/pm/state"),u=require("@tiptap/pm/view"),f=require("./tokenizeJson.js"),h={key:"bik-json-key",string:"bik-json-string",number:"bik-json-number",boolean:"bik-json-boolean",null:"bik-json-null",punctuation:"bik-json-punct"};function p(i){const e=document.createElement("span");return e.className="bik-json-lineno",e.textContent=String(i),e.setAttribute("contenteditable","false"),e}const k=g.Extension.create({name:"jsonHighlight",priority:1e3,addKeyboardShortcuts(){return{Backspace:()=>{const{selection:i}=this.editor.state,{empty:e,$from:t}=i;return e&&t.parent.type.name==="codeBlock"&&t.parentOffset===0}}},addProseMirrorPlugins(){return[new a.Plugin({key:new a.PluginKey("jsonHighlightGuard"),appendTransaction(i,e,t){if(!i.some(d=>d.docChanged))return null;const{doc:r,schema:s}=t,o=s.nodes.codeBlock;if(!o||r.childCount===1&&r.firstChild?.type===o)return null;let l=!1;if(r.forEach(d=>{d.type===o&&(l=!0)}),l)return null;const n=r.textBetween(0,r.content.size,`
2
- `),c=t.tr;return c.replaceWith(0,r.content.size,o.create(null,n?s.text(n):null)),c.setSelection(a.TextSelection.create(c.doc,1)),c}}),new a.Plugin({key:new a.PluginKey("jsonHighlight"),props:{handlePaste(i,e){const t=e.clipboardData?.getData("text/plain");if(!t||!t.trim())return!1;let r;try{r=JSON.parse(t)}catch{return!1}const s=JSON.stringify(r,null,2);if(s===t)return!1;const{state:o,dispatch:l}=i,{from:n,to:c}=o.selection;return l(o.tr.insertText(s,n,c).scrollIntoView()),!0},decorations(i){const e=[];return i.doc.descendants((t,r)=>{if(t.type.name!=="codeBlock")return;const s=t.textContent,o=r+1;for(const n of f.tokenizeJson(s))e.push(u.Decoration.inline(o+n.start,o+n.end,{class:h[n.type]}));let l=1;e.push(u.Decoration.widget(o,()=>p(1),{side:-1,key:"ln-1"}));for(let n=0;n<s.length;n++){if(s[n]!==`
3
- `)continue;l+=1;const c=l;e.push(u.Decoration.widget(o+n+1,()=>p(c),{side:-1,key:`ln-${c}`}))}}),u.DecorationSet.create(i.doc,e)}}})]}});exports.JsonHighlightExtension=k;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("../../../node_modules/@tiptap/core/dist/index.js"),l=require("@tiptap/pm/state"),d=require("@tiptap/pm/view"),g=require("./tokenizeJson.js"),p={key:"bik-json-key",string:"bik-json-string",number:"bik-json-number",boolean:"bik-json-boolean",null:"bik-json-null",punctuation:"bik-json-punct"};function f(r){return r.trim().length===0?0:r.split(`
2
+ `).length}class m{dom;contentDOM;gutter;constructor(n){const t=document.createElement("pre"),e=document.createElement("div");e.className="bik-json-gutter",e.contentEditable="false";const o=document.createElement("code");t.appendChild(e),t.appendChild(o),this.dom=t,this.contentDOM=o,this.gutter=e,this.renderGutter(n)}renderGutter(n){const t=f(n.textContent);if(this.gutter.childElementCount===t)return;const e=[];for(let o=1;o<=t;o++){const s=document.createElement("span");s.className="bik-json-lineno",s.textContent=String(o),e.push(s)}this.gutter.replaceChildren(...e)}update(n){return n.type.name!=="codeBlock"?!1:(this.renderGutter(n),!0)}ignoreMutation(n){return this.gutter===n.target||this.gutter.contains(n.target)}}const k=h.Extension.create({name:"jsonHighlight",priority:1e3,addKeyboardShortcuts(){return{Backspace:()=>{const{selection:r}=this.editor.state,{empty:n,$from:t}=r;return n&&t.parent.type.name==="codeBlock"&&t.parentOffset===0}}},addProseMirrorPlugins(){return[new l.Plugin({key:new l.PluginKey("jsonHighlightGuard"),appendTransaction(r,n,t){if(!r.some(u=>u.docChanged))return null;const{doc:e,schema:o}=t,s=o.nodes.codeBlock;if(!s||e.childCount===1&&e.firstChild?.type===s)return null;let i=!1;if(e.forEach(u=>{u.type===s&&(i=!0)}),i)return null;const a=e.textBetween(0,e.content.size,`
3
+ `),c=t.tr;return c.replaceWith(0,e.content.size,s.create(null,a?o.text(a):null)),c.setSelection(l.TextSelection.create(c.doc,1)),c}}),new l.Plugin({key:new l.PluginKey("jsonHighlight"),props:{nodeViews:{codeBlock:r=>new m(r)},handlePaste(r,n){const t=n.clipboardData?.getData("text/plain");if(!t||!t.trim())return!1;let e;try{e=JSON.parse(t)}catch{return!1}const o=JSON.stringify(e,null,2);if(o===t)return!1;const{state:s,dispatch:i}=r,{from:a,to:c}=s.selection;return i(s.tr.insertText(o,a,c).scrollIntoView()),!0},decorations(r){const n=[];return r.doc.descendants((t,e)=>{if(t.type.name!=="codeBlock")return;const o=t.textContent;if(o.length===0)return;const s=e+1;for(const i of g.tokenizeJson(o))n.push(d.Decoration.inline(s+i.start,s+i.end,{class:p[i.type]}))}),d.DecorationSet.create(r.doc,n)}}})]}});exports.JsonHighlightExtension=k;
4
4
  //# sourceMappingURL=JsonHighlightExtension.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JsonHighlightExtension.js","sources":["../../../../../src/editor/extensions/jsonHighlight/JsonHighlightExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { Plugin, PluginKey, TextSelection } from '@tiptap/pm/state';\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\nimport { JsonTokenType, tokenizeJson } from './tokenizeJson';\n\nconst CLASS_BY_TYPE: Record<JsonTokenType, string> = {\n\tkey: 'bik-json-key',\n\tstring: 'bik-json-string',\n\tnumber: 'bik-json-number',\n\tboolean: 'bik-json-boolean',\n\tnull: 'bik-json-null',\n\tpunctuation: 'bik-json-punct',\n};\n\n/** Line-number widget rendered in the hanging gutter at each line start. */\nfunction lineNumberWidget(n: number): HTMLElement {\n\tconst span = document.createElement('span');\n\tspan.className = 'bik-json-lineno';\n\tspan.textContent = String(n);\n\tspan.setAttribute('contenteditable', 'false');\n\treturn span;\n}\n\n/**\n * Colours JSON tokens inside `codeBlock` nodes and renders a line-number gutter.\n * A code block stores its whole multi-line body in a single text node, so token\n * offsets map 1:1 onto document positions (`nodeStart + offset`) — no cross-node\n * bookkeeping needed, and lines are just the `\\n`-separated runs of that text.\n *\n * Purely decorative: the document text is never rewritten, so undo/redo,\n * character count and the cursor all behave exactly as with plain text. The\n * gutter numbers are `side: -1` widgets that hang into the code block's left\n * padding (see `.bik-json-lineno` in BikEditor.styles.ts), so they never enter\n * the document text or shift character offsets.\n */\nexport const JsonHighlightExtension = Extension.create({\n\tname: 'jsonHighlight',\n\t// Above CodeBlock (default 100) so our Backspace handler runs first and can\n\t// veto CodeBlock's own \"clearNodes at start\" shortcut (which would lift the\n\t// block to a paragraph).\n\tpriority: 1000,\n\taddKeyboardShortcuts() {\n\t\treturn {\n\t\t\t// In JSON mode the document is a single code block. A Backspace at its very\n\t\t\t// start would lift it to a plain paragraph (killing the highlight, the\n\t\t\t// line-number gutter and the monospace font). There's nothing to delete\n\t\t\t// before the caret there anyway, so swallow it. Mid-text Backspace (and\n\t\t\t// deleting a leading `\\n` from line 2+) still works — those have\n\t\t\t// parentOffset > 0.\n\t\t\tBackspace: () => {\n\t\t\t\tconst { selection } = this.editor.state;\n\t\t\t\tconst { empty, $from } = selection;\n\t\t\t\treturn (\n\t\t\t\t\tempty &&\n\t\t\t\t\t$from.parent.type.name === 'codeBlock' &&\n\t\t\t\t\t$from.parentOffset === 0\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t},\n\taddProseMirrorPlugins() {\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tkey: new PluginKey('jsonHighlightGuard'),\n\t\t\t\t// jsonMode invariant: the whole document is ONE codeBlock. Several\n\t\t\t\t// default Backspace paths can lift it to a plain paragraph — and one\n\t\t\t\t// of them, TipTap core's `clearDocument` appendTransaction (fired when\n\t\t\t\t// the whole doc is selected then deleted, e.g. Cmd-A → Backspace),\n\t\t\t\t// runs AFTER our Backspace shortcut, so a keymap veto can't stop it.\n\t\t\t\t// A paragraph has no gutter and no monospace rule, so the line numbers\n\t\t\t\t// and font vanish. Re-wrap the content back into a codeBlock whenever\n\t\t\t\t// something lifts it, restoring the invariant.\n\t\t\t\tappendTransaction(transactions, _oldState, newState) {\n\t\t\t\t\tif (!transactions.some((tr) => tr.docChanged)) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tconst { doc, schema } = newState;\n\t\t\t\t\tconst codeBlock = schema.nodes['codeBlock'];\n\t\t\t\t\tif (!codeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// Common case: already a single codeBlock → nothing to do.\n\t\t\t\t\tif (doc.childCount === 1 && doc.firstChild?.type === codeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// If a codeBlock survives anywhere, leave it alone (don't fight\n\t\t\t\t\t// legitimate multi-node edits that shouldn't happen in jsonMode).\n\t\t\t\t\tlet hasCodeBlock = false;\n\t\t\t\t\tdoc.forEach((node) => {\n\t\t\t\t\t\tif (node.type === codeBlock) {\n\t\t\t\t\t\t\thasCodeBlock = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (hasCodeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// A lift happened: rebuild a single codeBlock from the text\n\t\t\t\t\t// (block boundaries preserved as newlines, matching JSON lines).\n\t\t\t\t\tconst text = doc.textBetween(0, doc.content.size, '\\n');\n\t\t\t\t\tconst tr = newState.tr;\n\t\t\t\t\ttr.replaceWith(\n\t\t\t\t\t\t0,\n\t\t\t\t\t\tdoc.content.size,\n\t\t\t\t\t\tcodeBlock.create(null, text ? schema.text(text) : null),\n\t\t\t\t\t);\n\t\t\t\t\ttr.setSelection(TextSelection.create(tr.doc, 1));\n\t\t\t\t\treturn tr;\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew Plugin({\n\t\t\t\tkey: new PluginKey('jsonHighlight'),\n\t\t\t\tprops: {\n\t\t\t\t\t// Paste beautify: if the clipboard text is valid JSON, drop in a\n\t\t\t\t\t// pretty-printed version (2-space indent, matching the Beautify\n\t\t\t\t\t// button) instead of the raw blob. Non-JSON pastes fall through to\n\t\t\t\t\t// the default handler untouched.\n\t\t\t\t\thandlePaste(view, event) {\n\t\t\t\t\t\tconst raw = event.clipboardData?.getData('text/plain');\n\t\t\t\t\t\tif (!raw || !raw.trim()) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet value: unknown;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tvalue = JSON.parse(raw);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst pretty = JSON.stringify(value, null, 2);\n\t\t\t\t\t\t// No-op if it was already beautified (avoids a redundant tx).\n\t\t\t\t\t\tif (pretty === raw) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst { state, dispatch } = view;\n\t\t\t\t\t\tconst { from, to } = state.selection;\n\t\t\t\t\t\tdispatch(state.tr.insertText(pretty, from, to).scrollIntoView());\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\tdecorations(state) {\n\t\t\t\t\t\tconst decorations: Decoration[] = [];\n\t\t\t\t\t\tstate.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (node.type.name !== 'codeBlock') return;\n\t\t\t\t\t\t\tconst text = node.textContent;\n\t\t\t\t\t\t\t// +1: step past the code-block node boundary into its text.\n\t\t\t\t\t\t\tconst base = pos + 1;\n\n\t\t\t\t\t\t\tfor (const tok of tokenizeJson(text)) {\n\t\t\t\t\t\t\t\tdecorations.push(\n\t\t\t\t\t\t\t\t\tDecoration.inline(base + tok.start, base + tok.end, {\n\t\t\t\t\t\t\t\t\t\tclass: CLASS_BY_TYPE[tok.type],\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// One line number per `\\n`-separated line (line 1 at offset 0,\n\t\t\t\t\t\t\t// then one after every newline). `white-space: pre` on the block\n\t\t\t\t\t\t\t// disables wrapping, so logical lines == visual lines.\n\t\t\t\t\t\t\tlet line = 1;\n\t\t\t\t\t\t\tdecorations.push(\n\t\t\t\t\t\t\t\tDecoration.widget(base, () => lineNumberWidget(1), {\n\t\t\t\t\t\t\t\t\tside: -1,\n\t\t\t\t\t\t\t\t\tkey: 'ln-1',\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tfor (let i = 0; i < text.length; i++) {\n\t\t\t\t\t\t\t\tif (text[i] !== '\\n') continue;\n\t\t\t\t\t\t\t\tline += 1;\n\t\t\t\t\t\t\t\tconst n = line;\n\t\t\t\t\t\t\t\tdecorations.push(\n\t\t\t\t\t\t\t\t\tDecoration.widget(base + i + 1, () => lineNumberWidget(n), {\n\t\t\t\t\t\t\t\t\t\tside: -1,\n\t\t\t\t\t\t\t\t\t\tkey: `ln-${n}`,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn DecorationSet.create(state.doc, decorations);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["CLASS_BY_TYPE","lineNumberWidget","n","span","JsonHighlightExtension","Extension","selection","empty","$from","Plugin","PluginKey","transactions","_oldState","newState","tr","doc","schema","codeBlock","hasCodeBlock","node","text","TextSelection","view","event","raw","value","pretty","state","dispatch","from","to","decorations","pos","base","tok","tokenizeJson","Decoration","line","i","DecorationSet"],"mappings":"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"}
1
+ {"version":3,"file":"JsonHighlightExtension.js","sources":["../../../../../src/editor/extensions/jsonHighlight/JsonHighlightExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model';\nimport { Plugin, PluginKey, TextSelection } from '@tiptap/pm/state';\nimport type { NodeView } from '@tiptap/pm/view';\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\nimport { JsonTokenType, tokenizeJson } from './tokenizeJson';\n\nconst CLASS_BY_TYPE: Record<JsonTokenType, string> = {\n\tkey: 'bik-json-key',\n\tstring: 'bik-json-string',\n\tnumber: 'bik-json-number',\n\tboolean: 'bik-json-boolean',\n\tnull: 'bik-json-null',\n\tpunctuation: 'bik-json-punct',\n};\n\n/**\n * Visual line count of a code block's text (0 → no gutter). Whitespace-only\n * content counts as 0: that's exactly when BikEditor shows the placeholder\n * overlay (`jsonEmpty = !text.trim()`), so the gutter must be empty too —\n * otherwise a blank field shows a stray \"1\" behind the placeholder.\n */\nfunction lineCount(text: string): number {\n\treturn text.trim().length === 0 ? 0 : text.split('\\n').length;\n}\n\n/**\n * Node view for the JSON `codeBlock` that renders the line-number gutter as a\n * `contenteditable=false` sibling of the editable `<code>` — NOT as ProseMirror\n * widget decorations.\n *\n * Why: widget decorations are re-inserted into the content flow on every\n * decoration recompute (i.e. every keystroke). Re-inserting a node next to the\n * caret reset the contenteditable selection to the line start, so typing a JSON\n * key and then its `:` dropped the caret to the start of the line (MAP-7286).\n * A node view lets us update the gutter DOM independently of `contentDOM`, so\n * the caret is never touched — and we only rebuild it when the line count\n * actually changes.\n */\nclass JsonCodeBlockView implements NodeView {\n\tdom: HTMLPreElement;\n\tcontentDOM: HTMLElement;\n\tprivate gutter: HTMLElement;\n\n\tconstructor(node: ProseMirrorNode) {\n\t\tconst pre = document.createElement('pre');\n\t\tconst gutter = document.createElement('div');\n\t\tgutter.className = 'bik-json-gutter';\n\t\tgutter.contentEditable = 'false';\n\t\tconst code = document.createElement('code');\n\t\t// Gutter is absolutely positioned into the reserved left padding, so its\n\t\t// order relative to <code> doesn't affect the code layout.\n\t\tpre.appendChild(gutter);\n\t\tpre.appendChild(code);\n\n\t\tthis.dom = pre;\n\t\tthis.contentDOM = code;\n\t\tthis.gutter = gutter;\n\t\tthis.renderGutter(node);\n\t}\n\n\tprivate renderGutter(node: ProseMirrorNode): void {\n\t\tconst count = lineCount(node.textContent);\n\t\t// Nothing to do while the line count is unchanged — this is the common case\n\t\t// (typing within a line) and skipping it avoids touching the gutter DOM.\n\t\tif (this.gutter.childElementCount === count) {\n\t\t\treturn;\n\t\t}\n\t\tconst numbers: HTMLElement[] = [];\n\t\tfor (let n = 1; n <= count; n++) {\n\t\t\tconst span = document.createElement('span');\n\t\t\tspan.className = 'bik-json-lineno';\n\t\t\tspan.textContent = String(n);\n\t\t\tnumbers.push(span);\n\t\t}\n\t\tthis.gutter.replaceChildren(...numbers);\n\t}\n\n\tupdate(node: ProseMirrorNode): boolean {\n\t\tif (node.type.name !== 'codeBlock') {\n\t\t\treturn false;\n\t\t}\n\t\tthis.renderGutter(node);\n\t\treturn true;\n\t}\n\n\t// The gutter is ours to manage — never let ProseMirror parse it as content.\n\tignoreMutation(mutation: MutationRecord | { target: Node }): boolean {\n\t\treturn (\n\t\t\tthis.gutter === mutation.target || this.gutter.contains(mutation.target)\n\t\t);\n\t}\n}\n\n/**\n * Colours JSON tokens inside `codeBlock` nodes and renders a line-number gutter\n * (via {@link JsonCodeBlockView}). A code block stores its whole multi-line body\n * in a single text node, so token offsets map 1:1 onto document positions\n * (`nodeStart + offset`) — no cross-node bookkeeping needed.\n *\n * Purely decorative: the document text is never rewritten, so undo/redo,\n * character count and the cursor all behave exactly as with plain text.\n */\nexport const JsonHighlightExtension = Extension.create({\n\tname: 'jsonHighlight',\n\t// Above CodeBlock (default 100) so our Backspace handler runs first and can\n\t// veto CodeBlock's own \"clearNodes at start\" shortcut (which would lift the\n\t// block to a paragraph).\n\tpriority: 1000,\n\taddKeyboardShortcuts() {\n\t\treturn {\n\t\t\t// In JSON mode the document is a single code block. A Backspace at its very\n\t\t\t// start would lift it to a plain paragraph (killing the highlight, the\n\t\t\t// line-number gutter and the monospace font). There's nothing to delete\n\t\t\t// before the caret there anyway, so swallow it. Mid-text Backspace (and\n\t\t\t// deleting a leading `\\n` from line 2+) still works — those have\n\t\t\t// parentOffset > 0.\n\t\t\tBackspace: () => {\n\t\t\t\tconst { selection } = this.editor.state;\n\t\t\t\tconst { empty, $from } = selection;\n\t\t\t\treturn (\n\t\t\t\t\tempty &&\n\t\t\t\t\t$from.parent.type.name === 'codeBlock' &&\n\t\t\t\t\t$from.parentOffset === 0\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t},\n\taddProseMirrorPlugins() {\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tkey: new PluginKey('jsonHighlightGuard'),\n\t\t\t\t// jsonMode invariant: the whole document is ONE codeBlock. Several\n\t\t\t\t// default Backspace paths can lift it to a plain paragraph — and one\n\t\t\t\t// of them, TipTap core's `clearDocument` appendTransaction (fired when\n\t\t\t\t// the whole doc is selected then deleted, e.g. Cmd-A → Backspace),\n\t\t\t\t// runs AFTER our Backspace shortcut, so a keymap veto can't stop it.\n\t\t\t\t// A paragraph has no gutter and no monospace rule, so the line numbers\n\t\t\t\t// and font vanish. Re-wrap the content back into a codeBlock whenever\n\t\t\t\t// something lifts it, restoring the invariant.\n\t\t\t\tappendTransaction(transactions, _oldState, newState) {\n\t\t\t\t\tif (!transactions.some((tr) => tr.docChanged)) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tconst { doc, schema } = newState;\n\t\t\t\t\tconst codeBlock = schema.nodes['codeBlock'];\n\t\t\t\t\tif (!codeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// Common case: already a single codeBlock → nothing to do.\n\t\t\t\t\tif (doc.childCount === 1 && doc.firstChild?.type === codeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// If a codeBlock survives anywhere, leave it alone (don't fight\n\t\t\t\t\t// legitimate multi-node edits that shouldn't happen in jsonMode).\n\t\t\t\t\tlet hasCodeBlock = false;\n\t\t\t\t\tdoc.forEach((node) => {\n\t\t\t\t\t\tif (node.type === codeBlock) {\n\t\t\t\t\t\t\thasCodeBlock = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (hasCodeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// A lift happened: rebuild a single codeBlock from the text\n\t\t\t\t\t// (block boundaries preserved as newlines, matching JSON lines).\n\t\t\t\t\tconst text = doc.textBetween(0, doc.content.size, '\\n');\n\t\t\t\t\tconst tr = newState.tr;\n\t\t\t\t\ttr.replaceWith(\n\t\t\t\t\t\t0,\n\t\t\t\t\t\tdoc.content.size,\n\t\t\t\t\t\tcodeBlock.create(null, text ? schema.text(text) : null),\n\t\t\t\t\t);\n\t\t\t\t\ttr.setSelection(TextSelection.create(tr.doc, 1));\n\t\t\t\t\treturn tr;\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew Plugin({\n\t\t\t\tkey: new PluginKey('jsonHighlight'),\n\t\t\t\tprops: {\n\t\t\t\t\t// The gutter is a node view, not a widget decoration — see\n\t\t\t\t\t// JsonCodeBlockView for why (MAP-7286).\n\t\t\t\t\tnodeViews: {\n\t\t\t\t\t\tcodeBlock: (node) => new JsonCodeBlockView(node),\n\t\t\t\t\t},\n\t\t\t\t\t// Paste beautify: if the clipboard text is valid JSON, drop in a\n\t\t\t\t\t// pretty-printed version (2-space indent, matching the Beautify\n\t\t\t\t\t// button) instead of the raw blob. Non-JSON pastes fall through to\n\t\t\t\t\t// the default handler untouched.\n\t\t\t\t\thandlePaste(view, event) {\n\t\t\t\t\t\tconst raw = event.clipboardData?.getData('text/plain');\n\t\t\t\t\t\tif (!raw || !raw.trim()) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet value: unknown;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tvalue = JSON.parse(raw);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst pretty = JSON.stringify(value, null, 2);\n\t\t\t\t\t\t// No-op if it was already beautified (avoids a redundant tx).\n\t\t\t\t\t\tif (pretty === raw) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst { state, dispatch } = view;\n\t\t\t\t\t\tconst { from, to } = state.selection;\n\t\t\t\t\t\tdispatch(state.tr.insertText(pretty, from, to).scrollIntoView());\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\t// Inline token colours only. Recolouring an inline span does not\n\t\t\t\t\t// disturb the caret (unlike the old gutter widgets).\n\t\t\t\t\tdecorations(state) {\n\t\t\t\t\t\tconst decorations: Decoration[] = [];\n\t\t\t\t\t\tstate.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (node.type.name !== 'codeBlock') return;\n\t\t\t\t\t\t\tconst text = node.textContent;\n\t\t\t\t\t\t\tif (text.length === 0) return;\n\t\t\t\t\t\t\t// +1: step past the code-block node boundary into its text.\n\t\t\t\t\t\t\tconst base = pos + 1;\n\t\t\t\t\t\t\tfor (const tok of tokenizeJson(text)) {\n\t\t\t\t\t\t\t\tdecorations.push(\n\t\t\t\t\t\t\t\t\tDecoration.inline(base + tok.start, base + tok.end, {\n\t\t\t\t\t\t\t\t\t\tclass: CLASS_BY_TYPE[tok.type],\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn DecorationSet.create(state.doc, decorations);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["CLASS_BY_TYPE","lineCount","text","JsonCodeBlockView","node","pre","gutter","code","count","numbers","n","span","mutation","JsonHighlightExtension","Extension","selection","empty","$from","Plugin","PluginKey","transactions","_oldState","newState","tr","doc","schema","codeBlock","hasCodeBlock","TextSelection","view","event","raw","value","pretty","state","dispatch","from","to","decorations","pos","base","tok","tokenizeJson","Decoration","DecorationSet"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const C=require("react/jsx-runtime"),i=({size:e=20,...t})=>{const l={width:e,height:e,...t};return C.jsxs("svg",{viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",...l,children:[C.jsx("rect",{width:e,height:e,rx:4,fill:"#EFE6F9"}),C.jsx("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M10.2048 3.62015C10.0728 3.57063 9.92724 3.57063 9.79518 3.62015L5.12851 5.37015C4.90083 5.45553 4.75 5.67318 4.75 5.91634V9.99967C4.75 12.0101 6.08102 13.6165 7.28254 14.6678C7.89555 15.2042 8.50582 15.6235 8.96167 15.9084C9.1902 16.0512 9.38148 16.1613 9.51696 16.2363C9.58474 16.2738 9.63867 16.3026 9.67644 16.3224C9.69533 16.3323 9.71018 16.34 9.72073 16.3454L9.73327 16.3518L9.73704 16.3537L9.73877 16.3546C9.90299 16.4367 10.0966 16.4369 10.2609 16.3548L10 15.833C10.2609 16.3548 10.2609 16.3548 10.2609 16.3548L10.263 16.3537L10.2667 16.3518L10.2793 16.3454C10.2898 16.34 10.3047 16.3323 10.3236 16.3224C10.3613 16.3026 10.4153 16.2738 10.483 16.2363C10.6185 16.1613 10.8098 16.0512 11.0383 15.9084C11.4942 15.6235 12.1044 15.2042 12.7175 14.6678C13.919 13.6165 15.25 12.0101 15.25 9.99967V5.91634C15.25 5.67318 15.0992 5.45553 14.8715 5.37015L10.2048 3.62015ZM10 15.833L9.73877 16.3546C9.73877 16.3546 9.73913 16.3548 10 15.833ZM10.42 14.9191C10.2547 15.0224 10.1118 15.1063 10 15.1696C9.88821 15.1063 9.74526 15.0224 9.58 14.9191C9.16085 14.6571 8.60445 14.2743 8.05079 13.7898C6.91898 12.7995 5.91667 11.4893 5.91667 9.99967V6.32059L10 4.78934L14.0833 6.32059V9.99967C14.0833 11.4893 13.081 12.7995 11.9492 13.7898C11.3956 14.2743 10.8391 14.6571 10.42 14.9191Z",fill:"#4B1583"})]})};exports.default=i;
2
+ //# sourceMappingURL=Shield.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Shield.js","sources":["../../../../../src/icons/Informational/Common UI/Shield.tsx"],"sourcesContent":["import type { SVGProps } from 'react';\n\ninterface Props extends SVGProps<SVGSVGElement> {\n\tsize?: number | string;\n}\nconst SvgShield = ({ size = 20, ...rest }: Props) => {\n\tconst props = {\n\t\twidth: size,\n\t\theight: size,\n\t\t...rest,\n\t};\n\treturn (\n\t\t<svg\n\t\t\tviewBox=\"0 0 20 20\"\n\t\t\tfill=\"none\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<rect width={size} height={size} rx={4} fill=\"#EFE6F9\" />\n\t\t\t<path\n\t\t\t\tfillRule=\"evenodd\"\n\t\t\t\tclipRule=\"evenodd\"\n\t\t\t\td=\"M10.2048 3.62015C10.0728 3.57063 9.92724 3.57063 9.79518 3.62015L5.12851 5.37015C4.90083 5.45553 4.75 5.67318 4.75 5.91634V9.99967C4.75 12.0101 6.08102 13.6165 7.28254 14.6678C7.89555 15.2042 8.50582 15.6235 8.96167 15.9084C9.1902 16.0512 9.38148 16.1613 9.51696 16.2363C9.58474 16.2738 9.63867 16.3026 9.67644 16.3224C9.69533 16.3323 9.71018 16.34 9.72073 16.3454L9.73327 16.3518L9.73704 16.3537L9.73877 16.3546C9.90299 16.4367 10.0966 16.4369 10.2609 16.3548L10 15.833C10.2609 16.3548 10.2609 16.3548 10.2609 16.3548L10.263 16.3537L10.2667 16.3518L10.2793 16.3454C10.2898 16.34 10.3047 16.3323 10.3236 16.3224C10.3613 16.3026 10.4153 16.2738 10.483 16.2363C10.6185 16.1613 10.8098 16.0512 11.0383 15.9084C11.4942 15.6235 12.1044 15.2042 12.7175 14.6678C13.919 13.6165 15.25 12.0101 15.25 9.99967V5.91634C15.25 5.67318 15.0992 5.45553 14.8715 5.37015L10.2048 3.62015ZM10 15.833L9.73877 16.3546C9.73877 16.3546 9.73913 16.3548 10 15.833ZM10.42 14.9191C10.2547 15.0224 10.1118 15.1063 10 15.1696C9.88821 15.1063 9.74526 15.0224 9.58 14.9191C9.16085 14.6571 8.60445 14.2743 8.05079 13.7898C6.91898 12.7995 5.91667 11.4893 5.91667 9.99967V6.32059L10 4.78934L14.0833 6.32059V9.99967C14.0833 11.4893 13.081 12.7995 11.9492 13.7898C11.3956 14.2743 10.8391 14.6571 10.42 14.9191Z\"\n\t\t\t\tfill=\"#4B1583\"\n\t\t\t/>\n\t\t</svg>\n\t);\n};\nexport default SvgShield;\n"],"names":["SvgShield","size","rest","props","jsxs","jsx"],"mappings":"iJAKMA,EAAY,CAAC,CAAE,KAAAC,EAAO,GAAI,GAAGC,KAAkB,CACpD,MAAMC,EAAQ,CACb,MAAOF,EACP,OAAQA,EACR,GAAGC,CAAA,EAEJ,OACCE,EAAAA,KAAC,MAAA,CACA,QAAQ,YACR,KAAK,OACL,MAAM,6BACL,GAAGD,EAEJ,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,MAAOJ,EAAM,OAAQA,EAAM,GAAI,EAAG,KAAK,SAAA,CAAU,EACvDI,EAAAA,IAAC,OAAA,CACA,SAAS,UACT,SAAS,UACT,EAAE,2vCACF,KAAK,SAAA,CAAA,CACN,CAAA,CAAA,CAGH"}