react-native-enriched-markdown-scaffold 0.7.4-scaffold.9 → 1.0.2-scaffold.10

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 (505) hide show
  1. package/README.md +54 -8
  2. package/ReactNativeEnrichedMarkdown.podspec +82 -73
  3. package/android/build.gradle +188 -1
  4. package/android/consumer-rules.pro +1 -1
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +27 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +7 -0
  7. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +24 -0
  8. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +8 -0
  9. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +27 -0
  10. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +7 -0
  11. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +223 -0
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +183 -0
  13. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +65 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +1086 -61
  15. package/android/src/main/baseline-prof.txt +1 -1
  16. package/android/src/main/cpp/jni-adapter.cpp +74 -0
  17. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +351 -13
  18. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +62 -0
  19. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +85 -0
  20. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +160 -1
  21. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +10 -1
  22. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +76 -0
  23. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +126 -10
  24. package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyPressEvent.kt +24 -0
  25. package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyRequestEvent.kt +28 -0
  26. package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkLayoutEvent.kt +36 -0
  27. package/android/src/main/java/com/swmansion/enriched/markdown/events/SelectionChangeEvent.kt +43 -0
  28. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +54 -4
  29. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +923 -462
  30. package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
  31. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
  32. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
  33. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
  34. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
  35. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
  36. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +108 -7
  37. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
  38. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
  39. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
  65. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
  66. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
  68. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
  69. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
  70. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
  71. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
  72. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
  73. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
  74. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +37 -7
  75. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
  76. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
  77. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
  78. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
  79. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
  80. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +35 -28
  81. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
  82. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
  83. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +20 -82
  84. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
  85. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  86. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
  87. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
  88. package/android/src/main/java/com/swmansion/enriched/markdown/spans/InlineChipPainter.kt +140 -0
  89. package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkChipSpans.kt +177 -0
  90. package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +1 -6
  91. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
  93. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
  94. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
  95. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
  96. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
  97. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
  100. package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineMathStyle.kt +16 -1
  101. package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkStyle.kt +36 -1
  102. package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt +7 -3
  103. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
  104. package/android/src/main/java/com/swmansion/enriched/markdown/styles/MathStyle.kt +3 -0
  105. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
  106. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
  107. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
  108. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
  109. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
  110. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
  111. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +84 -7
  112. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
  114. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
  115. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
  116. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
  117. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
  118. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +52 -0
  119. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
  120. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
  121. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
  122. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/HTMLGenerator.kt +2 -1
  123. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt +6 -0
  124. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
  125. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
  126. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
  127. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
  128. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/HeadlessActionMode.kt +88 -0
  129. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLayoutCollector.kt +100 -0
  130. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
  131. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +72 -16
  132. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionChangeReporter.kt +232 -0
  133. package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +64 -0
  134. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +414 -0
  135. package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
  136. package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
  137. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +61 -11
  138. package/android/src/main/jni/CMakeLists.txt +53 -0
  139. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
  140. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
  141. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
  142. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
  143. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
  144. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
  145. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
  146. package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
  147. package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +8 -2
  148. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
  149. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathInlineSpan.kt +13 -6
  150. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathMeasureHelper.kt +2 -1
  151. package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +26 -8
  152. package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
  153. package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
  154. package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
  155. package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
  156. package/cpp/highlight/HighlightGrammars.hpp +28 -0
  157. package/cpp/highlight/code_highlight_podspec.rb +211 -0
  158. package/cpp/highlight/gen-registry.mjs +155 -0
  159. package/cpp/highlight/grammar-versions.json +159 -0
  160. package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
  161. package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
  162. package/cpp/parser/MD4CParser.cpp +173 -61
  163. package/cpp/parser/MD4CParser.hpp +1 -0
  164. package/cpp/parser/MarkdownASTNode.hpp +2 -1
  165. package/cpp/wasm/ASTSerializer.cpp +2 -0
  166. package/cpp/wasm/build.sh +1 -0
  167. package/cpp/wasm/md4c_wasm.cpp +3 -1
  168. package/docs/ACCESSIBILITY.md +14 -2
  169. package/docs/API_REFERENCE.md +405 -12
  170. package/docs/BREAKING_CHANGES.md +129 -0
  171. package/docs/CODE_HIGHLIGHT.md +133 -0
  172. package/docs/COPY_OPTIONS.md +61 -3
  173. package/docs/ELEMENTS_STRUCTURE.md +52 -4
  174. package/docs/IMAGE_CACHING.md +30 -0
  175. package/docs/INPUT.md +110 -11
  176. package/docs/LATEX_MATH.md +87 -45
  177. package/docs/MACOS.md +1 -1
  178. package/docs/MARKDOWN_STREAMING.md +27 -1
  179. package/docs/MENTIONS.md +8 -1
  180. package/docs/NATIVE_ASSETS.md +127 -0
  181. package/docs/RTL.md +1 -1
  182. package/docs/STYLES.md +73 -6
  183. package/docs/TESTING.md +112 -0
  184. package/docs/TEXT.md +18 -6
  185. package/docs/WEB.md +4 -1
  186. package/ios/EnrichedMarkdown.h +7 -0
  187. package/ios/EnrichedMarkdown.mm +583 -76
  188. package/ios/EnrichedMarkdownText.h +7 -0
  189. package/ios/EnrichedMarkdownText.mm +299 -73
  190. package/ios/attachments/ENRMImageAttachment.h +9 -0
  191. package/ios/attachments/ENRMImageAttachment.m +143 -40
  192. package/ios/attachments/ENRMMathInlineAttachment+macOS.m +2 -1
  193. package/ios/attachments/ENRMMathInlineAttachment.h +5 -0
  194. package/ios/attachments/ENRMMathInlineAttachment.m +50 -82
  195. package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
  196. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +223 -0
  197. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +183 -0
  198. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +65 -0
  199. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +1086 -61
  200. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +181 -2
  201. package/ios/input/ENRMAutoLinkDetector.h +2 -1
  202. package/ios/input/ENRMAutoLinkDetector.mm +79 -41
  203. package/ios/input/ENRMBlockEditCoordinator.h +71 -0
  204. package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
  205. package/ios/input/ENRMBlockRange.h +28 -0
  206. package/ios/input/ENRMBlockRange.mm +30 -0
  207. package/ios/input/ENRMBlockStore.h +56 -0
  208. package/ios/input/ENRMBlockStore.mm +275 -0
  209. package/ios/input/ENRMClipboardCoordinator.h +45 -0
  210. package/ios/input/ENRMClipboardCoordinator.mm +120 -0
  211. package/ios/input/ENRMDetectorPipeline.h +2 -1
  212. package/ios/input/ENRMEditPipeline.h +76 -0
  213. package/ios/input/ENRMEditPipeline.mm +228 -0
  214. package/ios/input/ENRMEditSession.h +36 -0
  215. package/ios/input/ENRMEditSession.mm +63 -0
  216. package/ios/input/ENRMFormattingStore.h +17 -0
  217. package/ios/input/ENRMFormattingStore.mm +95 -105
  218. package/ios/input/ENRMInputBlockType.h +91 -0
  219. package/ios/input/ENRMInputBlockType.mm +5 -0
  220. package/ios/input/ENRMInputDecorationDrawer.h +18 -0
  221. package/ios/input/ENRMInputEventEmitter.h +56 -0
  222. package/ios/input/ENRMInputEventEmitter.mm +308 -0
  223. package/ios/input/ENRMInputFormatter.h +29 -69
  224. package/ios/input/ENRMInputFormatter.mm +216 -124
  225. package/ios/input/ENRMInputFormatterStyle.h +99 -0
  226. package/ios/input/ENRMInputFormatterStyle.mm +188 -0
  227. package/ios/input/ENRMInputLayoutManager.h +9 -0
  228. package/ios/input/ENRMInputLayoutManager.mm +30 -0
  229. package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
  230. package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
  231. package/ios/input/ENRMInputParser.h +5 -6
  232. package/ios/input/ENRMInputParser.mm +461 -178
  233. package/ios/input/ENRMInputRemend.mm +2 -2
  234. package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
  235. package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
  236. package/ios/input/ENRMInputTextView.mm +103 -8
  237. package/ios/input/ENRMInputTypingAttributesController.h +42 -0
  238. package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
  239. package/ios/input/ENRMLinkCoordinator.h +41 -0
  240. package/ios/input/ENRMLinkCoordinator.mm +89 -0
  241. package/ios/input/ENRMMarkdownSerializer.h +29 -5
  242. package/ios/input/ENRMMarkdownSerializer.mm +170 -48
  243. package/ios/input/ENRMMathAtom.h +26 -0
  244. package/ios/input/ENRMMathAtom.mm +12 -0
  245. package/ios/input/ENRMMentionCoordinator.h +45 -0
  246. package/ios/input/ENRMMentionCoordinator.mm +167 -0
  247. package/ios/input/ENRMRangeEditAdjustment.h +38 -0
  248. package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
  249. package/ios/input/ENRMRangeStoreUtils.h +39 -0
  250. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
  251. package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
  252. package/ios/input/EnrichedMarkdownTextInput.h +7 -1
  253. package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
  254. package/ios/input/InputStylePropsUtils.h +109 -68
  255. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
  256. package/ios/input/styles/ENRMBlockHandler.h +46 -0
  257. package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
  258. package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
  259. package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
  260. package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
  261. package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
  262. package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
  263. package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
  264. package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
  265. package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
  266. package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
  267. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
  268. package/ios/internals/MeasurementCache.h +41 -9
  269. package/ios/internals/ShadowMeasurementUtils.h +63 -58
  270. package/ios/math/ENRMMathChipController.h +74 -0
  271. package/ios/math/ENRMMathChipController.mm +476 -0
  272. package/ios/math/ENRMRaTeXBridge.swift +27 -6
  273. package/ios/parser/ENRMMarkdownParser.h +1 -8
  274. package/ios/parser/ENRMMarkdownParser.mm +2 -11
  275. package/ios/parser/MarkdownASTNode.h +2 -1
  276. package/ios/parser/MarkdownParserBridge.mm +4 -0
  277. package/ios/renderer/AttributedRenderer.m +20 -2
  278. package/ios/renderer/BaseRenderer.h +17 -2
  279. package/ios/renderer/BaseRenderer.m +30 -0
  280. package/ios/renderer/BlockquoteRenderer.h +1 -1
  281. package/ios/renderer/BlockquoteRenderer.m +144 -35
  282. package/ios/renderer/CodeBlockRenderer.h +1 -1
  283. package/ios/renderer/CodeBlockRenderer.m +27 -23
  284. package/ios/renderer/CodeRenderer.h +1 -1
  285. package/ios/renderer/CodeRenderer.m +3 -1
  286. package/ios/renderer/ENRMImageRenderer.h +1 -1
  287. package/ios/renderer/ENRMImageRenderer.m +5 -1
  288. package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
  289. package/ios/renderer/ENRMMathInlineRenderer.m +6 -1
  290. package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
  291. package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
  292. package/ios/renderer/EmphasisRenderer.h +1 -1
  293. package/ios/renderer/EmphasisRenderer.m +3 -1
  294. package/ios/renderer/HeadingRenderer.h +1 -1
  295. package/ios/renderer/HeadingRenderer.m +13 -6
  296. package/ios/renderer/HighlightRenderer.h +1 -1
  297. package/ios/renderer/HighlightRenderer.m +3 -1
  298. package/ios/renderer/LinkRenderer.h +1 -1
  299. package/ios/renderer/LinkRenderer.m +50 -16
  300. package/ios/renderer/ListItemRenderer.h +13 -1
  301. package/ios/renderer/ListItemRenderer.m +102 -44
  302. package/ios/renderer/ListRenderer.h +2 -2
  303. package/ios/renderer/ListRenderer.m +63 -25
  304. package/ios/renderer/ParagraphRenderer.h +1 -1
  305. package/ios/renderer/ParagraphRenderer.m +16 -8
  306. package/ios/renderer/RenderContext.h +10 -0
  307. package/ios/renderer/RenderContext.m +44 -0
  308. package/ios/renderer/RendererFactory.m +14 -0
  309. package/ios/renderer/StrikethroughRenderer.h +1 -1
  310. package/ios/renderer/StrikethroughRenderer.m +3 -1
  311. package/ios/renderer/StrongRenderer.h +1 -1
  312. package/ios/renderer/StrongRenderer.m +3 -1
  313. package/ios/renderer/SubscriptRenderer.h +1 -1
  314. package/ios/renderer/SubscriptRenderer.m +3 -1
  315. package/ios/renderer/SuperscriptRenderer.h +1 -1
  316. package/ios/renderer/SuperscriptRenderer.m +3 -1
  317. package/ios/renderer/TextRenderer.h +2 -2
  318. package/ios/renderer/TextRenderer.m +3 -1
  319. package/ios/renderer/ThematicBreakRenderer.h +1 -1
  320. package/ios/renderer/ThematicBreakRenderer.m +3 -1
  321. package/ios/renderer/UnderlineRenderer.h +1 -1
  322. package/ios/renderer/UnderlineRenderer.m +3 -1
  323. package/ios/styles/StyleConfig.h +42 -0
  324. package/ios/styles/StyleConfig.mm +216 -0
  325. package/ios/utils/BlockquoteBorder.h +6 -0
  326. package/ios/utils/BlockquoteBorder.m +249 -52
  327. package/ios/utils/CodeBackground.m +3 -65
  328. package/ios/utils/CodeBlockBackground.m +16 -2
  329. package/ios/utils/ENRMAtomicSize.h +65 -0
  330. package/ios/utils/ENRMBlockMenu.h +66 -0
  331. package/ios/utils/ENRMChipDrawing.h +24 -0
  332. package/ios/utils/ENRMChipDrawing.m +83 -0
  333. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  334. package/ios/utils/ENRMCodeBlockContent.mm +79 -0
  335. package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
  336. package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
  337. package/ios/utils/ENRMFeatureFlags.h +7 -0
  338. package/ios/utils/ENRMImageDownloader.h +11 -1
  339. package/ios/utils/ENRMImageDownloader.m +60 -16
  340. package/ios/utils/ENRMLinkChip.h +70 -0
  341. package/ios/utils/ENRMLinkChip.m +213 -0
  342. package/ios/utils/ENRMLinkLayout.h +50 -0
  343. package/ios/utils/ENRMLinkLayout.m +45 -0
  344. package/ios/utils/ENRMLocalImageLoader.h +31 -0
  345. package/ios/utils/ENRMLocalImageLoader.m +68 -0
  346. package/ios/utils/ENRMMathFallback.h +26 -0
  347. package/ios/utils/ENRMMathFallback.m +18 -0
  348. package/ios/utils/ENRMSelectionChange.h +120 -0
  349. package/ios/utils/ENRMSelectionChange.m +282 -0
  350. package/ios/utils/ENRMTextViewSetup.h +35 -17
  351. package/ios/utils/EditMenuUtils+macOS.m +4 -1
  352. package/ios/utils/EditMenuUtils.h +35 -6
  353. package/ios/utils/EditMenuUtils.m +188 -11
  354. package/ios/utils/HTMLGenerator.m +2 -1
  355. package/ios/utils/ImageRequestHeaderUtils.h +35 -0
  356. package/ios/utils/LastElementUtils.h +1 -0
  357. package/ios/utils/ListMarkerDrawer.m +29 -42
  358. package/ios/utils/MarkdownASTSerializer.m +4 -0
  359. package/ios/utils/MarkdownAccessibilityElementBuilder.m +3 -1
  360. package/ios/utils/MarkdownExtractor.m +2 -1
  361. package/ios/utils/ParagraphStyleUtils.h +5 -0
  362. package/ios/utils/ParagraphStyleUtils.m +77 -17
  363. package/ios/utils/RTFExportUtils.m +2 -0
  364. package/ios/utils/RenderedMarkdownSegment.h +13 -1
  365. package/ios/utils/RenderedMarkdownSegment.m +20 -0
  366. package/ios/utils/SegmentRenderer.m +17 -4
  367. package/ios/utils/StreamingMarkdownFilter.h +11 -1
  368. package/ios/utils/StreamingMarkdownFilter.m +98 -2
  369. package/ios/utils/StylePropsUtils.h +110 -1
  370. package/ios/utils/TaskListTapUtils.m +24 -0
  371. package/ios/utils/TextViewLayoutManager.mm +3 -0
  372. package/ios/views/ENRMCodeBlockContainerView.h +60 -0
  373. package/ios/views/ENRMCodeBlockContainerView.m +569 -0
  374. package/ios/views/ENRMMathContainerView.h +23 -0
  375. package/ios/views/ENRMMathContainerView.m +87 -20
  376. package/ios/views/TableContainerView.h +32 -0
  377. package/ios/views/TableContainerView.m +291 -175
  378. package/jest.d.ts +1 -0
  379. package/jest.js +5 -0
  380. package/lib/module/EnrichedMarkdownNativeComponent.ts +203 -1
  381. package/lib/module/EnrichedMarkdownTextInput.js +84 -5
  382. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
  383. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  384. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +204 -1
  385. package/lib/module/headingDefaults.js +34 -0
  386. package/lib/module/headingDefaults.js.map +1 -0
  387. package/lib/module/index.js.map +1 -1
  388. package/lib/module/jest/index.js +205 -0
  389. package/lib/module/jest/index.js.map +1 -0
  390. package/lib/module/native/EnrichedMarkdownText.js +199 -15
  391. package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
  392. package/lib/module/normalizeMarkdownStyle.js +98 -23
  393. package/lib/module/normalizeMarkdownStyle.js.map +1 -1
  394. package/lib/module/normalizeMarkdownStyle.web.js +73 -22
  395. package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
  396. package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
  397. package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
  398. package/lib/module/normalizeMenuItem.js +1 -1
  399. package/lib/module/utils/textInputState.js +26 -0
  400. package/lib/module/utils/textInputState.js.map +1 -0
  401. package/lib/module/web/EnrichedMarkdownText.js +15 -8
  402. package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
  403. package/lib/module/web/parseMarkdown.js +4 -3
  404. package/lib/module/web/parseMarkdown.js.map +1 -1
  405. package/lib/module/web/renderers/InlineRenderers.js +102 -3
  406. package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
  407. package/lib/module/web/renderers/ListRenderers.js +7 -2
  408. package/lib/module/web/renderers/ListRenderers.js.map +1 -1
  409. package/lib/module/web/renderers/index.js +7 -4
  410. package/lib/module/web/renderers/index.js.map +1 -1
  411. package/lib/module/web/styles.js +101 -6
  412. package/lib/module/web/styles.js.map +1 -1
  413. package/lib/module/web/utils.js +14 -0
  414. package/lib/module/web/utils.js.map +1 -1
  415. package/lib/module/web/wasm/md4c.js +0 -0
  416. package/lib/module/web/wasm/md4c.js.map +1 -1
  417. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +185 -2
  418. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  419. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
  420. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
  421. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
  422. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
  423. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +185 -2
  424. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
  425. package/lib/typescript/src/headingDefaults.d.ts +9 -0
  426. package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
  427. package/lib/typescript/src/index.d.ts +3 -3
  428. package/lib/typescript/src/index.d.ts.map +1 -1
  429. package/lib/typescript/src/index.web.d.ts +2 -2
  430. package/lib/typescript/src/index.web.d.ts.map +1 -1
  431. package/lib/typescript/src/jest/index.d.ts +6 -0
  432. package/lib/typescript/src/jest/index.d.ts.map +1 -0
  433. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +5 -5
  434. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
  435. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
  436. package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
  437. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
  438. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
  439. package/lib/typescript/src/types/MarkdownStyle.d.ts +122 -5
  440. package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
  441. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +39 -0
  442. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
  443. package/lib/typescript/src/types/MarkdownTextProps.d.ts +207 -10
  444. package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
  445. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +60 -1
  446. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
  447. package/lib/typescript/src/types/events.d.ts +85 -0
  448. package/lib/typescript/src/types/events.d.ts.map +1 -1
  449. package/lib/typescript/src/utils/textInputState.d.ts +24 -0
  450. package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
  451. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
  452. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
  453. package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
  454. package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
  455. package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
  456. package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
  457. package/lib/typescript/src/web/renderers/index.d.ts +2 -1
  458. package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
  459. package/lib/typescript/src/web/styles.d.ts +2 -1
  460. package/lib/typescript/src/web/styles.d.ts.map +1 -1
  461. package/lib/typescript/src/web/types.d.ts +10 -2
  462. package/lib/typescript/src/web/types.d.ts.map +1 -1
  463. package/lib/typescript/src/web/utils.d.ts +4 -0
  464. package/lib/typescript/src/web/utils.d.ts.map +1 -1
  465. package/package.json +36 -9
  466. package/postinstall.mjs +131 -0
  467. package/ratex-version.json +21 -0
  468. package/src/EnrichedMarkdownNativeComponent.ts +203 -1
  469. package/src/EnrichedMarkdownTextInput.tsx +159 -8
  470. package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  471. package/src/EnrichedMarkdownTextNativeComponent.ts +204 -1
  472. package/src/headingDefaults.ts +21 -0
  473. package/src/index.tsx +15 -0
  474. package/src/index.web.tsx +6 -1
  475. package/src/jest/index.tsx +236 -0
  476. package/src/native/EnrichedMarkdownText.tsx +260 -11
  477. package/src/normalizeMarkdownStyle.ts +117 -16
  478. package/src/normalizeMarkdownStyle.web.ts +76 -15
  479. package/src/normalizeMarkdownTextInputStyle.ts +110 -35
  480. package/src/normalizeMenuItem.ts +1 -1
  481. package/src/types/MarkdownStyle.ts +125 -5
  482. package/src/types/MarkdownStyleInternal.ts +51 -0
  483. package/src/types/MarkdownTextProps.ts +215 -10
  484. package/src/types/MarkdownTextProps.web.ts +62 -1
  485. package/src/types/events.ts +90 -0
  486. package/src/utils/textInputState.ts +35 -0
  487. package/src/web/EnrichedMarkdownText.tsx +26 -5
  488. package/src/web/parseMarkdown.ts +6 -2
  489. package/src/web/renderers/InlineRenderers.tsx +116 -3
  490. package/src/web/renderers/ListRenderers.tsx +14 -2
  491. package/src/web/renderers/index.tsx +6 -2
  492. package/src/web/styles.ts +114 -5
  493. package/src/web/types.ts +10 -1
  494. package/src/web/utils.ts +9 -0
  495. package/src/web/wasm/md4c.js +0 -0
  496. package/vendor-grammars.mjs +511 -0
  497. package/vendor-ratex.mjs +173 -0
  498. package/app.plugin.js +0 -2
  499. package/plugin/build/withAndroidMath.js +0 -19
  500. package/plugin/build/withIosMath.js +0 -28
  501. package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
  502. package/plugin/src/withAndroidMath.ts +0 -24
  503. package/plugin/src/withIosMath.ts +0 -35
  504. package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
  505. package/plugin/tsconfig.build.json +0 -16
@@ -69,6 +69,59 @@ Callback when a link is long pressed. Access URL via `event.url`. On iOS, automa
69
69
  />
70
70
  ```
71
71
 
72
+ ### `renderLinkDecoration`
73
+
74
+ Renders a React Native view on top of each link — for example a badge or sparkle on a [link chip](STYLES.md#link-chips). Return `null` to leave a link undecorated.
75
+
76
+ | Type | Default Value | Platform |
77
+ | ------------------------------------------------------ | ------------- | -------- |
78
+ | `(info: LinkDecorationInfo) => ReactNode \| null` | - | Both |
79
+
80
+ `LinkDecorationInfo`:
81
+
82
+ | Field | Type | Description |
83
+ | ------- | ------------ | ----------- |
84
+ | `index` | `number` | Position of the link in the document (0-based). Stable key for the link |
85
+ | `url` | `string` | Link URL |
86
+ | `text` | `string` | Visible link text |
87
+ | `rect` | `LinkRect` | Anchor rect: the drawn chip (glyphs + horizontal/vertical padding) of the link's **last** line fragment |
88
+ | `rects` | `LinkRect[]` | Every line fragment, in order (several when the link wraps) |
89
+
90
+ `LinkRect` is `{ x, y, width, height }` in dp, relative to the component's content box (inside `containerStyle` padding).
91
+
92
+ The returned node is placed inside an absolutely positioned box matching `rect`, with `pointerEvents="box-none"`, so position it relative to that box. Negative offsets let it overflow the chip:
93
+
94
+ ```tsx
95
+ <EnrichedMarkdownText
96
+ markdown="Read the [guide](https://example.com/guide) first."
97
+ markdownStyle={{
98
+ link: {
99
+ backgroundColor: '#DCE2FF',
100
+ borderRadius: 5,
101
+ paddingHorizontal: 7,
102
+ underline: false,
103
+ },
104
+ }}
105
+ renderLinkDecoration={({ url }) =>
106
+ url.startsWith('https://') ? (
107
+ <View style={{ position: 'absolute', top: -8, right: -8 }}>
108
+ <SparkleIcon />
109
+ </View>
110
+ ) : null
111
+ }
112
+ />
113
+ ```
114
+
115
+ Notes and limitations:
116
+
117
+ - When this prop is not set the component renders exactly as before: no wrapper view and no layout events.
118
+ - Setting it wraps the native view in a `View` (which takes `containerStyle`). Switching between set and unset remounts the native view.
119
+ - Rects are measured natively after layout and sent to JS, so decorations appear one frame after the text. Updates are deduplicated — streaming does not re-render decorations unless a link actually moves.
120
+ - Links inside tables (`flavor="github"`) are not reported.
121
+ - On Android, parts of a decoration that overflow the component's bounds do not receive touches.
122
+ - Web: `rect` is the link's whole inline box and `rects` is `[rect]`; for a wrapping link the decoration anchors to that box rather than the last line.
123
+ - Not supported by `EnrichedMarkdownTextInput`.
124
+
72
125
  ### `onTaskListItemPress`
73
126
 
74
127
  Callback when a task list checkbox is tapped. Receives `index` (0-based), `checked` (new state after toggling), and `text` (item text).
@@ -77,6 +130,157 @@ Callback when a task list checkbox is tapped. Receives `index` (0-based), `check
77
130
  | ----------------------------------------------- | ------------- | -------- |
78
131
  | `(event: TaskListItemPressEvent) => void` | - | Both |
79
132
 
133
+ ### `enableTaskListItemToggle`
134
+
135
+ Controls whether tapping a task list checkbox toggles its checked state.
136
+
137
+ When `false`, the checkbox renders its markdown state read-only and the tap is **fully inert** — there is no visual toggle and `onTaskListItemPress` does not fire. Text selection and links in the same row are unaffected.
138
+
139
+ | Type | Default Value | Platform |
140
+ | --------- | ------------- | ----------------- |
141
+ | `boolean` | `true` | Both, Web |
142
+
143
+ **Example:**
144
+
145
+ ```tsx
146
+ // Render checkboxes that reflect the markdown but cannot be toggled by the user
147
+ <EnrichedMarkdownText
148
+ markdown={content}
149
+ flavor="github"
150
+ enableTaskListItemToggle={false}
151
+ />
152
+ ```
153
+
154
+ > **Note:** On web the checkbox keeps its normal appearance and is marked `readOnly` / `aria-disabled` rather than `disabled`, so it stays visually consistent with iOS and Android. It is also made pointer-inert (`pointer-events: none`), so the browser paints no hover or active state on a checkbox that cannot be toggled.
155
+
156
+ ### `onCopyPress`
157
+
158
+ Callback when code is copied from a fenced code block, via the header copy button, the long-press context-menu **Copy** action, or the VoiceOver copy action. Receives `code` (the copied code) and `language` (the fence language, or `""` if none). Does not fire for **Copy as Markdown**.
159
+
160
+ Only fires when `flavor="github"` — the copy button is part of the GitHub flavor's code block renderer.
161
+
162
+ | Type | Default Value | Platform |
163
+ | ------------------------------------- | ------------- | ---------------- |
164
+ | `(event: CopyPressEvent) => void` | - | Both, macOS |
165
+
166
+ **Example:**
167
+
168
+ ```tsx
169
+ <EnrichedMarkdownText
170
+ flavor="github"
171
+ markdown={"```ts\nconst x = 1;\n```"}
172
+ onCopyPress={({ code, language }) => {
173
+ console.log(`Copied ${language} code:`, code);
174
+ }}
175
+ />
176
+ ```
177
+
178
+ ### `onCopy`
179
+
180
+ Takes over the **Copy** item of the text selection menu and of the table, math and code block menus. When set, native does **not** write the clipboard: it calls `onCopy` with the copied content and your handler writes whatever it wants — for example with [`expo-clipboard`](https://docs.expo.dev/versions/latest/sdk/clipboard/). Use it to post-process what users copy (strip formatting, drop link targets…) without a native change.
181
+
182
+ | Type | Default Value | Platform |
183
+ | ----------------------------- | ------------- | -------- |
184
+ | `(event: CopyEvent) => void` | - | Both |
185
+
186
+ ```ts
187
+ interface CopyEvent {
188
+ /** Which menu the Copy item belongs to. */
189
+ source: 'selection' | 'math' | 'table' | 'code';
190
+ /** What `copy.format: 'markdown'` would write. */
191
+ markdown: string;
192
+ /** Rendered text of the selection, or the block's raw content. */
193
+ text: string;
194
+ /** The selection spans the whole component (`markdown` is the source). Always true for blocks. */
195
+ whole: boolean;
196
+ }
197
+ ```
198
+
199
+ | `source` | `markdown` | `text` |
200
+ | ----------- | -------------------------------------------------------------------------- | ----------------------------- |
201
+ | `selection` | Original source when `whole`, otherwise rebuilt from the rendered styles | Selected text as rendered |
202
+ | `math` | `$$…$$` | LaTeX |
203
+ | `table` | The table as Markdown | Tab-separated cells |
204
+ | `code` | Fenced code block | Raw code |
205
+
206
+ - `onCopy` overrides `selectionMenuConfig.copy.format`; `copy.enabled: false` still hides the item, so no event fires.
207
+ - **Copy as Markdown**, the code block header copy button and the VoiceOver copy action are unaffected. `onCopyPress` does not fire for an intercepted Copy.
208
+ - With `flavor="github"` the text is split into segments around blocks, so a selection is `whole` only when the markdown renders as a single text segment.
209
+ - A rebuilt `markdown` wraps each styled run separately (`**a *****b***** c**`) and does not escape literal `*` / `_`.
210
+ - Copying with a hardware keyboard (Cmd+C / Ctrl+C) does not go through the menu and is not intercepted.
211
+ - Ignored on macOS. On web the prop is not this API: it reaches the container `div` as the DOM `onCopy` clipboard event.
212
+
213
+ **Example:**
214
+
215
+ ```tsx
216
+ import * as Clipboard from 'expo-clipboard';
217
+
218
+ <EnrichedMarkdownText
219
+ markdown={content}
220
+ onCopy={({ source, markdown }) => {
221
+ Clipboard.setStringAsync(source === 'selection' ? stripFormatting(markdown) : markdown);
222
+ }}
223
+ />
224
+ ```
225
+
226
+ ### `onSelectionChange`
227
+
228
+ Reports the text selection so the app can draw its own selection menu. Pair it with [`contextMenuHidden`](#contextmenuhidden) to replace the native menu entirely.
229
+
230
+ | Type | Default Value | Platform |
231
+ | ---------------------------------------- | ------------- | -------- |
232
+ | `(event: SelectionChangeEvent) => void` | - | Both |
233
+
234
+ ```ts
235
+ interface SelectionRect { x: number; y: number; width: number; height: number }
236
+
237
+ interface SelectionChangeEvent {
238
+ /** `false` once the selection is gone; every other field is then empty / zero. */
239
+ active: boolean;
240
+ /** `'selection'` for text, or the kind of a long-pressed block. */
241
+ source: 'selection' | 'math' | 'table' | 'code';
242
+ /** Same as `CopyEvent.text` / `CopyEvent.markdown` / `CopyEvent.whole`. */
243
+ text: string;
244
+ markdown: string;
245
+ whole: boolean;
246
+ /** Bounding box (full content width when it spans several lines). */
247
+ rect: SelectionRect;
248
+ /** Selected part of the first / last line — anchor a menu above the start or below the end. */
249
+ startRect: SelectionRect;
250
+ endRect: SelectionRect;
251
+ /** `true` while a selection handle is dragged (iOS; always `false` on Android). */
252
+ adjusting: boolean;
253
+ }
254
+ ```
255
+
256
+ - Fires at most once per frame while the selection changes (payloads are deduplicated), and with `active: false` right away once it is gone — including when new `markdown` replaces the text.
257
+ - Rects are in dp, relative to the component's native view: add the origin from `ref.current.measureInWindow` to get window coordinates. Re-measure after scrolling instead of waiting for a new event.
258
+ - With `contextMenuHidden`, a long press on a table, math or code block (`flavor="github"`) fires the event with `source` set to the block kind, `whole: true` and every rect set to the block's frame. These blocks have no text selection, so without this they would offer no way to copy. Without `contextMenuHidden` the block menu shows as usual and no event fires.
259
+ - On iOS the selection isn't reported while a handle is dragged: the event fires with `adjusting: true` (and the selection as it was) when the drag begins, and with `adjusting: false` and the new selection when the finger lifts. Hide your menu while `adjusting` is `true`. Android has no such flag (`adjusting` is always `false`) but reports every step of the drag, so debounce before showing the menu there too.
260
+ - Within one component only one part holds a selection at a time: selecting in another text segment clears the previous one. To keep a single selection across several components, call `clearSelection()` on the previous one.
261
+ - Ignored on macOS and web.
262
+
263
+ **Imperative handle.** `ref` exposes `clearSelection()`, which clears the selection (and any long-pressed block) and fires `active: false`. It also forwards `measure`, `measureInWindow` and `measureLayout`.
264
+
265
+ ```tsx
266
+ const ref = useRef<EnrichedMarkdownTextInstance>(null);
267
+
268
+ <EnrichedMarkdownText
269
+ ref={ref}
270
+ markdown={content}
271
+ contextMenuHidden
272
+ onSelectionChange={(e) => {
273
+ if (!e.active || e.adjusting) return hideMenu();
274
+ ref.current?.measureInWindow((x, y) =>
275
+ showMenuDebounced({ x: x + e.startRect.x, y: y + e.startRect.y }, e.markdown)
276
+ );
277
+ }}
278
+ />;
279
+
280
+ // After the menu action:
281
+ ref.current?.clearSelection();
282
+ ```
283
+
80
284
  ### `enableLinkPreview`
81
285
 
82
286
  Controls the native link preview on long press (iOS only). Automatically set to `false` when `onLinkLongPress` is provided.
@@ -97,6 +301,16 @@ You can also control this behavior explicitly without providing a handler:
97
301
  />
98
302
  ```
99
303
 
304
+ ### `linkLongPressSelects`
305
+
306
+ Long-pressing a link selects its label and shows the selection edit menu (the same one a manual selection gets), instead of the system link preview (iOS only). Takes precedence over `enableLinkPreview` and `onLinkLongPress`.
307
+
308
+ | Type | Default Value | Platform |
309
+ | --------- | ------------- | -------- |
310
+ | `boolean` | `false` | iOS |
311
+
312
+ Only the link label is selected, not the chip padding; the selection handles can be dragged to extend it. Long-pressing inline math always behaves this way, without the prop.
313
+
100
314
  ### `selectable`
101
315
 
102
316
  Whether text can be selected.
@@ -105,6 +319,39 @@ Whether text can be selected.
105
319
  | --------- | ------------- | -------- |
106
320
  | `boolean` | `true` | Both |
107
321
 
322
+ ### `contextMenuHidden`
323
+
324
+ Hides the text selection context menu. Text stays selectable — only the menu is
325
+ suppressed. This is deliberately different from `selectable={false}`, which
326
+ disables selection altogether and, on Android, also removes the text from the
327
+ TalkBack focus order.
328
+
329
+ | Type | Default Value | Platform |
330
+ | --------- | ------------- | ----------- |
331
+ | `boolean` | `false` | Both, macOS |
332
+
333
+ ```tsx
334
+ // Text can still be selected, but long-press shows no menu
335
+ <EnrichedMarkdownText markdown={content} contextMenuHidden />
336
+ ```
337
+
338
+ Notes:
339
+
340
+ - It hides the **whole** menu. The custom items from `contextMenuItems` and the
341
+ built-in items from `selectionMenuConfig` share that same menu, so they are
342
+ hidden too. To drop individual items instead, use `selectionMenuConfig`.
343
+ - It also covers the separate copy menus on table, code and math blocks (which
344
+ appear with `flavor="github"`), not just the text selection menu. The copy
345
+ button in a code block's header is a visible control, not a menu, and stays.
346
+ - It does **not** suppress the system "Save to Camera Roll / Copy" sheet that
347
+ UIKit shows when long-pressing an image — that sheet is owned by UIKit.
348
+ - On macOS the menu opens on click-with-selection rather than long-press; the
349
+ prop suppresses it the same way.
350
+ - Applies to `EnrichedMarkdownText` only — it does not affect
351
+ `EnrichedMarkdownTextInput`.
352
+ - To show your own menu instead, use [`onSelectionChange`](#onselectionchange);
353
+ with this prop on, block long-presses are reported through it as well.
354
+
108
355
  ### `selectionColor`
109
356
 
110
357
  Color of the text selection highlight. On iOS, this also affects the caret and selection handle colors (they share a single tint). On macOS, only the selection background is affected. On Android, use `selectionHandleColor` to override the handle color independently.
@@ -127,7 +374,7 @@ Configuration for md4c parser extension flags.
127
374
 
128
375
  | Type | Default Value | Platform |
129
376
  | ------------- | ------------------------ | -------- |
130
- | `Md4cFlags` | `{ underline: false, superscript: false, subscript: false, highlight: false, latexMath: true }` | Both |
377
+ | `Md4cFlags` | `{ underline: false, superscript: false, subscript: false, highlight: false, latexMath: true, hardSoftBreaks: false }` | Both |
131
378
 
132
379
  **Properties:**
133
380
 
@@ -136,6 +383,7 @@ Configuration for md4c parser extension flags.
136
383
  - **`subscript`**: When `true`, parses `~text~` as subscript. When disabled, single and double tildes remain strikethrough markers. Visual appearance can be tuned with the `subscript` style prop — see [Subscript-specific](./STYLES.md#subscript-specific).
137
384
  - **`highlight`**: When `true`, parses `==text==` as highlighted spans. When disabled, double equals signs are treated as plain text. Visual appearance can be tuned with the `highlight` style prop — see [Highlight-specific](./STYLES.md#highlight-specific).
138
385
  - **`latexMath`**: When `true`, parses `$...$` and `$$...$$` as LaTeX math spans.
386
+ - **`hardSoftBreaks`**: When `true`, treats single newlines (soft breaks) as hard breaks, rendering them as visible line breaks instead of collapsing them to spaces. Useful when displaying content authored in `EnrichedMarkdownTextInput`, where pressing Enter produces a single newline. See [Line Breaks](./ELEMENTS_STRUCTURE.md#line-breaks) for details.
139
387
 
140
388
  **Example:**
141
389
 
@@ -150,6 +398,12 @@ Configuration for md4c parser extension flags.
150
398
  markdown="This is _underlined_ and *italic* text"
151
399
  md4cFlags={{ underline: true }}
152
400
  />
401
+
402
+ // Preserve single newlines as visible line breaks
403
+ <EnrichedMarkdownText
404
+ markdown={markdownFromInput}
405
+ md4cFlags={{ hardSoftBreaks: true }}
406
+ />
153
407
  ```
154
408
 
155
409
  ### `allowFontScaling`
@@ -233,7 +487,7 @@ Code blocks are always rendered left-to-right regardless of this prop. Per-parag
233
487
 
234
488
  ### `flavor`
235
489
 
236
- Markdown flavor. Set to `'github'` to enable GitHub Flavored Markdown table support.
490
+ Markdown flavor. Set to `'github'` to enable GitHub Flavored Markdown features: tables and block-style code blocks.
237
491
 
238
492
  | Type | Default Value | Platform |
239
493
  | --------------------------------- | --------------- | -------- |
@@ -241,7 +495,9 @@ Markdown flavor. Set to `'github'` to enable GitHub Flavored Markdown table supp
241
495
 
242
496
  > **Note:**
243
497
  > - **`'commonmark'`**: All Markdown content is rendered as a single TextView. Selecting text will select all content in the view.
244
- > - **`'github'`**: The Markdown AST is split into segments. Consecutive text blocks (paragraphs, headings, lists, etc.) are grouped into separate TextView segments, while tables are rendered as separate table views. This allows for granular text selection within each segment and enables interactive table features (horizontal scrolling, context menus). Text selection cannot span across segments.
498
+ > - **`'github'`**: The Markdown AST is split into segments. Consecutive text blocks (paragraphs, headings, lists, etc.) are grouped into separate TextView segments, while tables, fenced code blocks, and math blocks are rendered as separate block views. This allows for granular text selection within each segment and enables interactive block features (horizontal table scrolling, context menus, the code block header). Text selection cannot span across segments.
499
+ >
500
+ > With `'github'`, a fenced code block renders as a dedicated component: a header bar with the language display name (` ```python ` shows "Python") and a copy-code button, a divider, and the code below. Long lines do not wrap — the code pane scrolls horizontally while the header stays fixed. Long-pressing the block opens the Copy / Copy as Markdown menu. With `'commonmark'`, code blocks stay inside the single TextView, styled via spans, and long lines wrap.
245
501
 
246
502
  ### `streamingAnimation`
247
503
 
@@ -253,11 +509,11 @@ When `true`, newly appended content fades in during streaming updates. Only the
253
509
 
254
510
  ### `streamingConfig`
255
511
 
256
- Configuration for streaming behavior. Currently controls how incomplete tables are handled during streaming with `flavor="github"`.
512
+ Configuration for streaming behavior. Controls how incomplete tables and fenced code blocks are handled during streaming with `flavor="github"`.
257
513
 
258
- | Type | Default Value | Platform |
259
- | ----------------------- | ------------------------ | -------- |
260
- | `{ tableMode: string }` | `{ tableMode: 'progressive' }` | Both |
514
+ | Type | Default Value | Platform |
515
+ | ------------------------------------------- | ------------------------------------------------------ | -------- |
516
+ | `{ tableMode?: string, codeBlockMode?: string }` | `{ tableMode: 'progressive', codeBlockMode: 'progressive' }` | Both |
261
517
 
262
518
  #### `tableMode`
263
519
 
@@ -275,6 +531,15 @@ Controls how incomplete (still-streaming) tables are rendered:
275
531
  />
276
532
  ```
277
533
 
534
+ #### `codeBlockMode`
535
+
536
+ Controls how a fenced code block whose closing fence has not arrived yet is rendered:
537
+
538
+ - **`'progressive'`** (default): The code streams in line-by-line with its header (language label + copy button) visible but non-interactive — copying is disabled until the block completes. Syntax highlighting is deferred until the closing fence arrives, so it applies once instead of flickering on every token.
539
+ - **`'hidden'`**: The entire code block is hidden until its closing fence arrives, then it appears complete (the same all-or-nothing behavior block math uses).
540
+
541
+ Both modes only take effect when `streamingAnimation` is `true`.
542
+
278
543
  ### `spoilerOverlay`
279
544
 
280
545
  Controls how spoiler text (`||hidden text||`) is displayed before being revealed.
@@ -288,6 +553,29 @@ Controls how spoiler text (`||hidden text||`) is displayed before being revealed
288
553
 
289
554
  Both modes support tap-to-reveal.
290
555
 
556
+ ### `imageRequestHeaders`
557
+
558
+ HTTP headers attached to remote image requests, e.g. a `Referer` required by CDN hotlink protection or an `Authorization` token.
559
+
560
+ | Type | Default Value | Platform |
561
+ | ------------------------ | ------------- | -------- |
562
+ | `Record<string, string>` | - | Both |
563
+
564
+ Headers participate in image cache identity, so the same URL requested with different headers is fetched and cached separately — see [Image Caching](./IMAGE_CACHING.md).
565
+
566
+ > **Web**: Not supported — browsers don't allow custom headers on `<img>` requests.
567
+
568
+ **Example:**
569
+
570
+ ```tsx
571
+ <EnrichedMarkdownText
572
+ markdown={markdown}
573
+ imageRequestHeaders={{
574
+ Referer: 'https://example.com',
575
+ }}
576
+ />
577
+ ```
578
+
291
579
  ### `contextMenuItems`
292
580
 
293
581
  Custom items to add to the text selection context menu. Items appear before the system actions (Copy, etc.). Items with `visible: false` are hidden from the menu.
@@ -352,7 +640,7 @@ Controls built-in actions added to the native text selection menu. Custom app-pr
352
640
  | -------------------- | ---------------------------------------------- | -------- |
353
641
  | `SelectionMenuConfig` | `{}` (see shape below for per-field defaults) | iOS, Android, macOS |
354
642
 
355
- Each item takes an object: `{ enabled }` toggles visibility (the system `copy` item can't be hidden — only relabeled) and `label` overrides the English default. The labels apply to the main text selection menu as well as the table and math block copy menus.
643
+ Each item takes an object: `{ enabled }` toggles visibility and `label` overrides the English default. Items and labels apply to the main text selection menu as well as the table, math and code block copy menus. `copy.enabled`, `copy.format` and `systemItems` are ignored on macOS.
356
644
 
357
645
  > **Deprecation:** the previous boolean shape (`copyAsMarkdown: false`) is still accepted at runtime for backward compatibility but logs a one-time warning. It will be removed in 0.8 — migrate to `{ enabled: false }`.
358
646
 
@@ -360,9 +648,13 @@ Each item takes an object: `{ enabled }` toggles visibility (the system `copy` i
360
648
 
361
649
  ```ts
362
650
  interface SelectionMenuConfig {
363
- /** System "Copy" item — can't be hidden, only relabeled. @default { label: "Copy" } */
364
- copy?: { label?: string };
365
- /** "Copy as Markdown" action. @default { enabled: true, label: "Copy as Markdown" } */
651
+ /**
652
+ * "Copy" item. `format: 'markdown'` copies Markdown as plain text instead of
653
+ * rich text (text selections) or the raw content (blocks).
654
+ * @default { enabled: true, label: "Copy", format: "rich" }
655
+ */
656
+ copy?: { enabled?: boolean; label?: string; format?: 'rich' | 'markdown' };
657
+ /** "Copy as Markdown" action, in the text and block menus. @default { enabled: true, label: "Copy as Markdown" } */
366
658
  copyAsMarkdown?: { enabled?: boolean; label?: string };
367
659
  /** "Copy Image URL" action, shown when the selection contains images. */
368
660
  copyImageUrl?: {
@@ -372,6 +664,10 @@ interface SelectionMenuConfig {
372
664
  /** Forms for multiple images, chosen with Intl.PluralRules. @default { other: "Copy {count} Image URLs" } */
373
665
  pluralLabels?: SelectionMenuPluralLabels;
374
666
  };
667
+ /** `'none'` drops every system item (Select All, Look Up, Share, Translate…). @default 'default' */
668
+ systemItems?: 'default' | 'none';
669
+ /** Copy button in the code block header. @default { enabled: true } */
670
+ codeBlockCopyButton?: { enabled?: boolean };
375
671
  }
376
672
 
377
673
  interface SelectionMenuPluralLabels {
@@ -532,6 +828,18 @@ Auto-capitalization behavior.
532
828
  | -------- | -------------- | -------- |
533
829
  | `string` | `'sentences'` | Both |
534
830
 
831
+ ### `interceptPaste`
832
+
833
+ Reports pastes through [`onPaste`](#onpaste) instead of inserting them. Only takes effect when `onPaste` is also set — otherwise native would swallow every paste with nobody left to resolve it, so the library keeps the prop off.
834
+
835
+ See [Intercepting paste](./INPUT.md#intercepting-paste).
836
+
837
+ | Type | Default Value | Platform |
838
+ | --------- | ------------- | ------------- |
839
+ | `boolean` | `false` | iOS, Android |
840
+
841
+ macOS ignores this prop and always pastes inline.
842
+
535
843
  ### `multiline`
536
844
 
537
845
  Whether the input supports multiple lines.
@@ -574,6 +882,8 @@ Style configuration for formatted text in the input.
574
882
  - `linkVariants` — per-URL-pattern style overrides. Each key is a regex tested against the link URL. See [Mentions — Link Variants](MENTIONS.md#link-variants-mention-styling).
575
883
  - `spoiler.color` — text color for spoiler text.
576
884
  - `spoiler.backgroundColor` — background color for spoiler text.
885
+ - `h1`–`h6` — per-level heading styling, each accepting `fontSize`, `fontWeight`, and `color`. Defaults match the read-only renderer (sizes `30/24/20/18/16/14`, bold).
886
+ - `list.itemSpacing` — vertical spacing (points) added above each list item (bullet and numbered alike) so items read as separate rows; defaults to `0`. iOS applies it via `paragraphSpacingBefore`; Android via a `LineHeightSpan`.
577
887
 
578
888
  ### `mentionIndicators`
579
889
 
@@ -601,6 +911,15 @@ Fires when the plain text content changes. Returns the text without Markdown syn
601
911
  | ------------------------------- | ------------- | -------- |
602
912
  | `(text: string) => void` | - | Both |
603
913
 
914
+ > [!NOTE]
915
+ > A LaTeX formula appears in this string as a single `U+FFFC` (object replacement
916
+ > character), not as its source. That keeps the string index-compatible with
917
+ > [`onChangeSelection`](#onchangeselection), [`onCaretRectChange`](#oncaretrectchange)
918
+ > and the `insertMath` / `updateMath` / `removeMath` methods, which all address the
919
+ > buffer by offset and count a formula as one character. Use
920
+ > [`onChangeMarkdown`](#onchangemarkdown) when you need the `$...$` source.
921
+ > See [LaTeX math](LATEX_MATH.md).
922
+
604
923
  ### `onChangeMarkdown`
605
924
 
606
925
  Fires when the Markdown representation changes. Returns the full Markdown string. Only active when the callback is provided — omitting it skips the serialization for better performance.
@@ -619,7 +938,7 @@ Fires when the text selection changes.
619
938
 
620
939
  ### `onChangeState`
621
940
 
622
- Fires when the active style state changes. The payload provides a nested object for each style with an `isActive` property.
941
+ Fires when the active style state changes. The payload provides a nested object for each style with an `isActive` property; `heading` additionally carries the cursor paragraph's `level` (`0` when it is not a heading) and `unorderedList` / `orderedList` their 0-based nesting `depth`.
623
942
 
624
943
  | Type | Default Value | Platform |
625
944
  | --------------------------------- | ------------- | -------- |
@@ -635,9 +954,35 @@ interface StyleState {
635
954
  strikethrough: { isActive: boolean };
636
955
  spoiler: { isActive: boolean };
637
956
  link: { isActive: boolean };
957
+ // Heading level of the cursor's paragraph: 0 = none, 1-6 = H1-H6.
958
+ heading: { isActive: boolean; level: number };
959
+ // `depth` is the 0-based nesting level while `isActive` is true, and is
960
+ // always `0` when `isActive` is false (i.e. the cursor is not in a list).
961
+ // This differs from `heading.level`, where `0` is itself a meaningful value
962
+ // (no heading); read `depth` only when `isActive` is true.
963
+ unorderedList: { isActive: boolean; depth: number };
964
+ orderedList: { isActive: boolean; depth: number };
638
965
  }
639
966
  ```
640
967
 
968
+ ### `onKeyPress`
969
+
970
+ Fires on every keystroke, before the change is applied to the input content — mirroring React Native TextInput's `onKeyPress`. `nativeEvent.key` is the pressed character, or a named key: `Backspace`, `Enter`, `Tab` (iOS additionally reports `Escape`). On Android the key reported for soft keyboard input may lag actual typing when autocomplete suggestions are involved. Paste operations do not fire the event.
971
+
972
+ | Type | Default Value | Platform |
973
+ | ------------------------------------------------------------- | ------------- | -------- |
974
+ | `(e: NativeSyntheticEvent<{ key: string }>) => void` | - | Both |
975
+
976
+ **Example:**
977
+
978
+ ```tsx
979
+ <EnrichedMarkdownTextInput
980
+ onKeyPress={({ nativeEvent: { key } }) => {
981
+ console.log('Pressed key:', key);
982
+ }}
983
+ />
984
+ ```
985
+
641
986
  ### `onCaretRectChange`
642
987
 
643
988
  Fires when the caret's pixel position changes (typing, selection change, content reflow). The rect is relative to the input's top-left corner, in density-independent pixels. The native side diffs the rect before emitting, so redundant events are suppressed.
@@ -686,6 +1031,8 @@ Fires when the input loses focus.
686
1031
  | -------------- | ------------- | -------- |
687
1032
  | `() => void` | - | Both |
688
1033
 
1034
+ The input participates in React Native's text-input focus tracking (`TextInput.State`), so blur also happens through the platform's standard keyboard-dismiss paths: taps outside the input inside a `ScrollView` (per its `keyboardShouldPersistTaps` setting) and `Keyboard.dismiss()`. See [Keyboard Dismissal](INPUT.md#keyboard-dismissal).
1035
+
689
1036
  ### `onStartMention`
690
1037
 
691
1038
  Fires when a new mention flow starts. See [Mentions](MENTIONS.md#events).
@@ -710,6 +1057,18 @@ Fires when the active mention flow ends.
710
1057
  | ---- | ------------- | -------- |
711
1058
  | `(event: { indicator: string }) => void` | - | Both |
712
1059
 
1060
+ ### `onPaste`
1061
+
1062
+ Fires instead of the insert when [`interceptPaste`](#interceptpaste) is on. Native reads the clipboard and leaves the buffer untouched, so the handler owns the paste from that point: it must call [`resolvePaste`](#resolvepastetext-string-markdown-string) exactly once, on every path including failures, or the paste is silently dropped.
1063
+
1064
+ | Type | Default Value | Platform |
1065
+ | ---- | ------------- | -------- |
1066
+ | `(event: { text: string; markdown: string }) => void` | - | iOS, Android |
1067
+
1068
+ `markdown` is non-empty only on iOS, when the copy source was an `EnrichedMarkdownTextInput`. Android always reports `''` and `resolvePaste` there inserts `text` verbatim.
1069
+
1070
+ See [Intercepting paste](./INPUT.md#intercepting-paste).
1071
+
713
1072
  ### `writingDirection`
714
1073
 
715
1074
  Paragraph writing direction in the input. iOS only — Android's `EditText` already resolves direction per paragraph via `TEXT_DIRECTION_FIRST_STRONG` and is unaffected by this prop.
@@ -924,6 +1283,26 @@ Toggles strikethrough on the current selection or cursor.
924
1283
 
925
1284
  Toggles spoiler on the current selection or cursor.
926
1285
 
1286
+ ### `toggleHeading(level: number)`
1287
+
1288
+ Toggles a heading of the given level (`1`–`6`) on the cursor's paragraph. Calling it with the level already applied turns the paragraph back into regular text. Unlike the inline `toggle*` methods, this operates on the whole paragraph, not a character range.
1289
+
1290
+ ### `toggleUnorderedList()`
1291
+
1292
+ Turns the cursor's paragraph(s) into bullet list items, or back into regular paragraphs if they already are. Operates on the whole paragraph. List items are single-line — each item is exactly one paragraph, and Markdown imported with multi-paragraph (loose) items keeps only each item's first line as a list item.
1293
+
1294
+ ### `toggleOrderedList()`
1295
+
1296
+ Turns the cursor's paragraph(s) into numbered list items, or back into regular paragraphs if they already are. Numbering derives from an item's position among its adjacent same-depth siblings. Toggling one list type on a line carrying the other replaces it, keeping the item's nesting depth.
1297
+
1298
+ ### `indentList()`
1299
+
1300
+ Nests the current list item one level deeper (up to a maximum depth). Called on a non-list paragraph, it starts a bullet list at depth 0. Equivalent to pressing **Tab** with a hardware keyboard.
1301
+
1302
+ ### `outdentList()`
1303
+
1304
+ Lifts the current list item out one nesting level. Outdenting a depth-0 item removes the bullet, turning it back into a regular paragraph. Equivalent to **Shift+Tab**.
1305
+
927
1306
  ### `setLink(url: string)`
928
1307
 
929
1308
  Applies a link URL to the currently selected text.
@@ -936,12 +1315,26 @@ Inserts a link with the given text and URL at the current cursor position. Usefu
936
1315
 
937
1316
  Removes the link from the current selection.
938
1317
 
1318
+ ### `insertText(text: string)`
1319
+
1320
+ Parses the given string as Markdown and inserts it literally at the current cursor position, replacing the selection if there is one. Leading and trailing newlines are preserved, so wrap block content (lists, headings) in newlines to keep it on its own lines when inserting mid-paragraph — `insertText('\n- item\n')` in the middle of `test` yields `te`, a `- item` bullet, and `st` on separate lines. Calling it with an empty string is a no-op.
1321
+
939
1322
  ### `copyToClipboard()`
940
1323
 
941
1324
  Copies the input's full content to the system clipboard, matching the result of selecting all text and pressing the context menu's copy action. The selection is left unchanged, and calling it on an empty input is a no-op.
942
1325
 
943
1326
  On iOS and macOS the clipboard receives both plain text and a private Markdown pasteboard type, so pasting back into an `EnrichedMarkdownTextInput` restores the formatting; external apps receive plain text only. On Android the clipboard receives plain text only — inline styles are not preserved for any paste target.
944
1327
 
1328
+ ### `resolvePaste(text: string, markdown?: string)`
1329
+
1330
+ Completes a paste reported through [`onPaste`](#onpaste). Call it exactly once per event:
1331
+
1332
+ - `resolvePaste(text, markdown)` — inserts, restoring the copied formatting when `markdown` is non-empty.
1333
+ - `resolvePaste(text)` — inserts `text` verbatim.
1334
+ - `resolvePaste('', '')` — drops the clipboard content, replacing the current selection. With an empty selection this is a no-op that still emits `onChangeText` with unchanged content.
1335
+
1336
+ Anything that replaces a selection replaces it here too, so a paste over selected text behaves the same on every branch.
1337
+
945
1338
  ### `startMention(indicator: string)`
946
1339
 
947
1340
  Programmatically triggers a mention flow by inserting the indicator character at the current cursor position. The indicator must be listed in the `mentionIndicators` prop. Useful for toolbar buttons.