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

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 (469) hide show
  1. package/README.md +54 -8
  2. package/ReactNativeEnrichedMarkdown.podspec +82 -73
  3. package/android/build.gradle +186 -1
  4. package/android/consumer-rules.pro +1 -1
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +9 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +3 -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 +9 -0
  10. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +3 -0
  11. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  13. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +35 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +886 -23
  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 +189 -13
  18. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +17 -0
  19. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +50 -0
  20. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -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 +42 -0
  23. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +82 -4
  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/input/EnrichedMarkdownTextInputManager.kt +54 -4
  26. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +901 -462
  27. package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
  28. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
  29. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
  30. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
  31. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
  32. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
  33. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +101 -7
  34. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
  35. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
  36. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
  37. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
  38. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
  39. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
  65. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
  66. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
  68. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
  69. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
  70. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
  71. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
  72. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
  73. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
  74. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
  75. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
  76. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +30 -27
  77. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
  78. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
  79. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +27 -3
  80. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
  81. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  82. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
  83. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
  84. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
  85. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
  86. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
  87. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
  88. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
  89. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
  90. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
  91. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
  93. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
  94. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
  95. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
  96. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
  97. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
  100. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +37 -7
  101. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
  102. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
  103. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
  104. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
  105. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
  106. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
  107. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +20 -0
  108. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
  109. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
  110. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
  111. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
  112. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
  114. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
  115. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
  116. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +49 -15
  117. package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +45 -0
  118. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +396 -0
  119. package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
  120. package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
  121. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +36 -9
  122. package/android/src/main/jni/CMakeLists.txt +53 -0
  123. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
  124. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
  125. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
  126. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
  127. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
  128. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
  129. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
  130. package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
  131. package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +7 -2
  132. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
  133. package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +6 -4
  134. package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
  135. package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
  136. package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
  137. package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
  138. package/cpp/highlight/HighlightGrammars.hpp +28 -0
  139. package/cpp/highlight/code_highlight_podspec.rb +211 -0
  140. package/cpp/highlight/gen-registry.mjs +155 -0
  141. package/cpp/highlight/grammar-versions.json +159 -0
  142. package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
  143. package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
  144. package/cpp/parser/MD4CParser.cpp +173 -61
  145. package/cpp/parser/MD4CParser.hpp +1 -0
  146. package/cpp/parser/MarkdownASTNode.hpp +2 -1
  147. package/cpp/wasm/ASTSerializer.cpp +2 -0
  148. package/cpp/wasm/build.sh +1 -0
  149. package/cpp/wasm/md4c_wasm.cpp +3 -1
  150. package/docs/ACCESSIBILITY.md +14 -2
  151. package/docs/API_REFERENCE.md +234 -12
  152. package/docs/BREAKING_CHANGES.md +129 -0
  153. package/docs/CODE_HIGHLIGHT.md +133 -0
  154. package/docs/COPY_OPTIONS.md +47 -3
  155. package/docs/ELEMENTS_STRUCTURE.md +52 -4
  156. package/docs/IMAGE_CACHING.md +30 -0
  157. package/docs/INPUT.md +108 -11
  158. package/docs/LATEX_MATH.md +87 -45
  159. package/docs/MACOS.md +1 -1
  160. package/docs/MARKDOWN_STREAMING.md +27 -1
  161. package/docs/NATIVE_ASSETS.md +127 -0
  162. package/docs/RTL.md +1 -1
  163. package/docs/STYLES.md +46 -6
  164. package/docs/TESTING.md +112 -0
  165. package/docs/TEXT.md +16 -6
  166. package/docs/WEB.md +3 -1
  167. package/ios/EnrichedMarkdown.h +7 -0
  168. package/ios/EnrichedMarkdown.mm +284 -75
  169. package/ios/EnrichedMarkdownText.h +7 -0
  170. package/ios/EnrichedMarkdownText.mm +101 -73
  171. package/ios/attachments/ENRMImageAttachment.h +9 -0
  172. package/ios/attachments/ENRMImageAttachment.m +143 -40
  173. package/ios/attachments/ENRMMathInlineAttachment.h +2 -0
  174. package/ios/attachments/ENRMMathInlineAttachment.m +48 -81
  175. package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
  176. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  177. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  178. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +35 -0
  179. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +886 -23
  180. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +131 -0
  181. package/ios/input/ENRMAutoLinkDetector.h +2 -1
  182. package/ios/input/ENRMAutoLinkDetector.mm +79 -41
  183. package/ios/input/ENRMBlockEditCoordinator.h +71 -0
  184. package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
  185. package/ios/input/ENRMBlockRange.h +28 -0
  186. package/ios/input/ENRMBlockRange.mm +30 -0
  187. package/ios/input/ENRMBlockStore.h +56 -0
  188. package/ios/input/ENRMBlockStore.mm +275 -0
  189. package/ios/input/ENRMClipboardCoordinator.h +45 -0
  190. package/ios/input/ENRMClipboardCoordinator.mm +120 -0
  191. package/ios/input/ENRMDetectorPipeline.h +2 -1
  192. package/ios/input/ENRMEditPipeline.h +76 -0
  193. package/ios/input/ENRMEditPipeline.mm +228 -0
  194. package/ios/input/ENRMEditSession.h +36 -0
  195. package/ios/input/ENRMEditSession.mm +63 -0
  196. package/ios/input/ENRMFormattingStore.h +17 -0
  197. package/ios/input/ENRMFormattingStore.mm +95 -105
  198. package/ios/input/ENRMInputBlockType.h +91 -0
  199. package/ios/input/ENRMInputBlockType.mm +5 -0
  200. package/ios/input/ENRMInputDecorationDrawer.h +18 -0
  201. package/ios/input/ENRMInputEventEmitter.h +56 -0
  202. package/ios/input/ENRMInputEventEmitter.mm +308 -0
  203. package/ios/input/ENRMInputFormatter.h +29 -69
  204. package/ios/input/ENRMInputFormatter.mm +216 -124
  205. package/ios/input/ENRMInputFormatterStyle.h +99 -0
  206. package/ios/input/ENRMInputFormatterStyle.mm +188 -0
  207. package/ios/input/ENRMInputLayoutManager.h +9 -0
  208. package/ios/input/ENRMInputLayoutManager.mm +30 -0
  209. package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
  210. package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
  211. package/ios/input/ENRMInputParser.h +5 -6
  212. package/ios/input/ENRMInputParser.mm +461 -178
  213. package/ios/input/ENRMInputRemend.mm +2 -2
  214. package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
  215. package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
  216. package/ios/input/ENRMInputTextView.mm +103 -8
  217. package/ios/input/ENRMInputTypingAttributesController.h +42 -0
  218. package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
  219. package/ios/input/ENRMLinkCoordinator.h +41 -0
  220. package/ios/input/ENRMLinkCoordinator.mm +89 -0
  221. package/ios/input/ENRMMarkdownSerializer.h +29 -5
  222. package/ios/input/ENRMMarkdownSerializer.mm +170 -48
  223. package/ios/input/ENRMMathAtom.h +26 -0
  224. package/ios/input/ENRMMathAtom.mm +12 -0
  225. package/ios/input/ENRMMentionCoordinator.h +45 -0
  226. package/ios/input/ENRMMentionCoordinator.mm +167 -0
  227. package/ios/input/ENRMRangeEditAdjustment.h +38 -0
  228. package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
  229. package/ios/input/ENRMRangeStoreUtils.h +39 -0
  230. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
  231. package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
  232. package/ios/input/EnrichedMarkdownTextInput.h +7 -1
  233. package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
  234. package/ios/input/InputStylePropsUtils.h +109 -68
  235. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
  236. package/ios/input/styles/ENRMBlockHandler.h +46 -0
  237. package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
  238. package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
  239. package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
  240. package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
  241. package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
  242. package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
  243. package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
  244. package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
  245. package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
  246. package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
  247. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
  248. package/ios/internals/MeasurementCache.h +33 -7
  249. package/ios/internals/ShadowMeasurementUtils.h +63 -58
  250. package/ios/math/ENRMMathChipController.h +74 -0
  251. package/ios/math/ENRMMathChipController.mm +476 -0
  252. package/ios/math/ENRMRaTeXBridge.swift +4 -1
  253. package/ios/parser/ENRMMarkdownParser.h +1 -8
  254. package/ios/parser/ENRMMarkdownParser.mm +2 -11
  255. package/ios/parser/MarkdownASTNode.h +2 -1
  256. package/ios/parser/MarkdownParserBridge.mm +4 -0
  257. package/ios/renderer/AttributedRenderer.m +20 -2
  258. package/ios/renderer/BaseRenderer.h +17 -2
  259. package/ios/renderer/BaseRenderer.m +30 -0
  260. package/ios/renderer/BlockquoteRenderer.h +1 -1
  261. package/ios/renderer/BlockquoteRenderer.m +144 -35
  262. package/ios/renderer/CodeBlockRenderer.h +1 -1
  263. package/ios/renderer/CodeBlockRenderer.m +27 -23
  264. package/ios/renderer/CodeRenderer.h +1 -1
  265. package/ios/renderer/CodeRenderer.m +3 -1
  266. package/ios/renderer/ENRMImageRenderer.h +1 -1
  267. package/ios/renderer/ENRMImageRenderer.m +5 -1
  268. package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
  269. package/ios/renderer/ENRMMathInlineRenderer.m +5 -1
  270. package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
  271. package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
  272. package/ios/renderer/EmphasisRenderer.h +1 -1
  273. package/ios/renderer/EmphasisRenderer.m +3 -1
  274. package/ios/renderer/HeadingRenderer.h +1 -1
  275. package/ios/renderer/HeadingRenderer.m +13 -6
  276. package/ios/renderer/HighlightRenderer.h +1 -1
  277. package/ios/renderer/HighlightRenderer.m +3 -1
  278. package/ios/renderer/LinkRenderer.h +1 -1
  279. package/ios/renderer/LinkRenderer.m +3 -1
  280. package/ios/renderer/ListItemRenderer.h +13 -1
  281. package/ios/renderer/ListItemRenderer.m +102 -44
  282. package/ios/renderer/ListRenderer.h +2 -2
  283. package/ios/renderer/ListRenderer.m +63 -25
  284. package/ios/renderer/ParagraphRenderer.h +1 -1
  285. package/ios/renderer/ParagraphRenderer.m +16 -8
  286. package/ios/renderer/RenderContext.h +10 -0
  287. package/ios/renderer/RenderContext.m +44 -0
  288. package/ios/renderer/RendererFactory.m +14 -0
  289. package/ios/renderer/StrikethroughRenderer.h +1 -1
  290. package/ios/renderer/StrikethroughRenderer.m +3 -1
  291. package/ios/renderer/StrongRenderer.h +1 -1
  292. package/ios/renderer/StrongRenderer.m +3 -1
  293. package/ios/renderer/SubscriptRenderer.h +1 -1
  294. package/ios/renderer/SubscriptRenderer.m +3 -1
  295. package/ios/renderer/SuperscriptRenderer.h +1 -1
  296. package/ios/renderer/SuperscriptRenderer.m +3 -1
  297. package/ios/renderer/TextRenderer.h +2 -2
  298. package/ios/renderer/TextRenderer.m +3 -1
  299. package/ios/renderer/ThematicBreakRenderer.h +1 -1
  300. package/ios/renderer/ThematicBreakRenderer.m +3 -1
  301. package/ios/renderer/UnderlineRenderer.h +1 -1
  302. package/ios/renderer/UnderlineRenderer.m +3 -1
  303. package/ios/styles/StyleConfig.h +22 -0
  304. package/ios/styles/StyleConfig.mm +132 -0
  305. package/ios/utils/BlockquoteBorder.h +6 -0
  306. package/ios/utils/BlockquoteBorder.m +249 -52
  307. package/ios/utils/CodeBlockBackground.m +16 -2
  308. package/ios/utils/ENRMAtomicSize.h +65 -0
  309. package/ios/utils/ENRMBlockMenu.h +57 -0
  310. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  311. package/ios/utils/ENRMCodeBlockContent.mm +79 -0
  312. package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
  313. package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
  314. package/ios/utils/ENRMFeatureFlags.h +7 -0
  315. package/ios/utils/ENRMImageDownloader.h +11 -1
  316. package/ios/utils/ENRMImageDownloader.m +60 -16
  317. package/ios/utils/ENRMLocalImageLoader.h +31 -0
  318. package/ios/utils/ENRMLocalImageLoader.m +68 -0
  319. package/ios/utils/ENRMMathFallback.h +26 -0
  320. package/ios/utils/ENRMMathFallback.m +18 -0
  321. package/ios/utils/ENRMTextViewSetup.h +35 -17
  322. package/ios/utils/EditMenuUtils.h +22 -5
  323. package/ios/utils/EditMenuUtils.m +53 -9
  324. package/ios/utils/ImageRequestHeaderUtils.h +35 -0
  325. package/ios/utils/LastElementUtils.h +1 -0
  326. package/ios/utils/ListMarkerDrawer.m +29 -42
  327. package/ios/utils/MarkdownASTSerializer.m +4 -0
  328. package/ios/utils/ParagraphStyleUtils.h +5 -0
  329. package/ios/utils/ParagraphStyleUtils.m +77 -17
  330. package/ios/utils/RenderedMarkdownSegment.h +13 -1
  331. package/ios/utils/RenderedMarkdownSegment.m +20 -0
  332. package/ios/utils/SegmentRenderer.m +17 -4
  333. package/ios/utils/StreamingMarkdownFilter.h +11 -1
  334. package/ios/utils/StreamingMarkdownFilter.m +98 -2
  335. package/ios/utils/StylePropsUtils.h +63 -0
  336. package/ios/utils/TaskListTapUtils.m +24 -0
  337. package/ios/views/ENRMCodeBlockContainerView.h +53 -0
  338. package/ios/views/ENRMCodeBlockContainerView.m +559 -0
  339. package/ios/views/ENRMMathContainerView.h +16 -0
  340. package/ios/views/ENRMMathContainerView.m +74 -19
  341. package/ios/views/TableContainerView.h +22 -0
  342. package/ios/views/TableContainerView.m +261 -175
  343. package/jest.d.ts +1 -0
  344. package/jest.js +5 -0
  345. package/lib/module/EnrichedMarkdownNativeComponent.ts +73 -0
  346. package/lib/module/EnrichedMarkdownTextInput.js +84 -5
  347. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
  348. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  349. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +74 -0
  350. package/lib/module/headingDefaults.js +34 -0
  351. package/lib/module/headingDefaults.js.map +1 -0
  352. package/lib/module/index.js.map +1 -1
  353. package/lib/module/jest/index.js +191 -0
  354. package/lib/module/jest/index.js.map +1 -0
  355. package/lib/module/native/EnrichedMarkdownText.js +37 -5
  356. package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
  357. package/lib/module/normalizeMarkdownStyle.js +81 -19
  358. package/lib/module/normalizeMarkdownStyle.js.map +1 -1
  359. package/lib/module/normalizeMarkdownStyle.web.js +56 -18
  360. package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
  361. package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
  362. package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
  363. package/lib/module/normalizeMenuItem.js +1 -1
  364. package/lib/module/utils/textInputState.js +26 -0
  365. package/lib/module/utils/textInputState.js.map +1 -0
  366. package/lib/module/web/EnrichedMarkdownText.js +9 -5
  367. package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
  368. package/lib/module/web/parseMarkdown.js +4 -3
  369. package/lib/module/web/parseMarkdown.js.map +1 -1
  370. package/lib/module/web/renderers/InlineRenderers.js +6 -0
  371. package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
  372. package/lib/module/web/renderers/ListRenderers.js +7 -2
  373. package/lib/module/web/renderers/ListRenderers.js.map +1 -1
  374. package/lib/module/web/renderers/index.js +7 -4
  375. package/lib/module/web/renderers/index.js.map +1 -1
  376. package/lib/module/web/styles.js +83 -6
  377. package/lib/module/web/styles.js.map +1 -1
  378. package/lib/module/web/utils.js +1 -0
  379. package/lib/module/web/utils.js.map +1 -1
  380. package/lib/module/web/wasm/md4c.js +0 -0
  381. package/lib/module/web/wasm/md4c.js.map +1 -1
  382. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +66 -0
  383. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  384. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
  385. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
  386. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
  387. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
  388. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +66 -0
  389. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
  390. package/lib/typescript/src/headingDefaults.d.ts +9 -0
  391. package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
  392. package/lib/typescript/src/index.d.ts +2 -2
  393. package/lib/typescript/src/index.d.ts.map +1 -1
  394. package/lib/typescript/src/index.web.d.ts +1 -1
  395. package/lib/typescript/src/index.web.d.ts.map +1 -1
  396. package/lib/typescript/src/jest/index.d.ts +6 -0
  397. package/lib/typescript/src/jest/index.d.ts.map +1 -0
  398. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +3 -3
  399. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
  400. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
  401. package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
  402. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
  403. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
  404. package/lib/typescript/src/types/MarkdownStyle.d.ts +72 -0
  405. package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
  406. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +27 -0
  407. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
  408. package/lib/typescript/src/types/MarkdownTextProps.d.ts +104 -9
  409. package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
  410. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +19 -0
  411. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
  412. package/lib/typescript/src/types/events.d.ts +19 -0
  413. package/lib/typescript/src/types/events.d.ts.map +1 -1
  414. package/lib/typescript/src/utils/textInputState.d.ts +24 -0
  415. package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
  416. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
  417. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
  418. package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
  419. package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
  420. package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
  421. package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
  422. package/lib/typescript/src/web/renderers/index.d.ts +2 -1
  423. package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
  424. package/lib/typescript/src/web/styles.d.ts +2 -1
  425. package/lib/typescript/src/web/styles.d.ts.map +1 -1
  426. package/lib/typescript/src/web/types.d.ts +6 -2
  427. package/lib/typescript/src/web/types.d.ts.map +1 -1
  428. package/lib/typescript/src/web/utils.d.ts.map +1 -1
  429. package/package.json +36 -9
  430. package/postinstall.mjs +131 -0
  431. package/ratex-version.json +21 -0
  432. package/src/EnrichedMarkdownNativeComponent.ts +73 -0
  433. package/src/EnrichedMarkdownTextInput.tsx +159 -8
  434. package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  435. package/src/EnrichedMarkdownTextNativeComponent.ts +74 -0
  436. package/src/headingDefaults.ts +21 -0
  437. package/src/index.tsx +9 -0
  438. package/src/index.web.tsx +1 -0
  439. package/src/jest/index.tsx +215 -0
  440. package/src/native/EnrichedMarkdownText.tsx +53 -2
  441. package/src/normalizeMarkdownStyle.ts +102 -16
  442. package/src/normalizeMarkdownStyle.web.ts +63 -15
  443. package/src/normalizeMarkdownTextInputStyle.ts +110 -35
  444. package/src/normalizeMenuItem.ts +1 -1
  445. package/src/types/MarkdownStyle.ts +74 -0
  446. package/src/types/MarkdownStyleInternal.ts +39 -0
  447. package/src/types/MarkdownTextProps.ts +101 -9
  448. package/src/types/MarkdownTextProps.web.ts +19 -0
  449. package/src/types/events.ts +21 -0
  450. package/src/utils/textInputState.ts +35 -0
  451. package/src/web/EnrichedMarkdownText.tsx +16 -2
  452. package/src/web/parseMarkdown.ts +6 -2
  453. package/src/web/renderers/InlineRenderers.tsx +5 -0
  454. package/src/web/renderers/ListRenderers.tsx +14 -2
  455. package/src/web/renderers/index.tsx +6 -2
  456. package/src/web/styles.ts +89 -5
  457. package/src/web/types.ts +6 -1
  458. package/src/web/utils.ts +1 -0
  459. package/src/web/wasm/md4c.js +0 -0
  460. package/vendor-grammars.mjs +511 -0
  461. package/vendor-ratex.mjs +173 -0
  462. package/app.plugin.js +0 -2
  463. package/plugin/build/withAndroidMath.js +0 -19
  464. package/plugin/build/withIosMath.js +0 -28
  465. package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
  466. package/plugin/src/withAndroidMath.ts +0 -24
  467. package/plugin/src/withIosMath.ts +0 -35
  468. package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
  469. package/plugin/tsconfig.build.json +0 -16
@@ -0,0 +1,21 @@
1
+ // Single source of truth for default heading appearance, shared by the
2
+ // read-only renderer and the editable input so headings match across views.
3
+
4
+ export type HeadingLevelKey = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
5
+
6
+ export interface HeadingDefault {
7
+ fontSize: number;
8
+ color: string;
9
+ }
10
+
11
+ /** Default font weight applied to every heading level. */
12
+ export const DEFAULT_HEADING_FONT_WEIGHT = 'bold';
13
+
14
+ export const HEADING_DEFAULTS: Record<HeadingLevelKey, HeadingDefault> = {
15
+ h1: { fontSize: 30, color: '#111827' },
16
+ h2: { fontSize: 24, color: '#111827' },
17
+ h3: { fontSize: 20, color: '#111827' },
18
+ h4: { fontSize: 18, color: '#111827' },
19
+ h5: { fontSize: 16, color: '#374151' },
20
+ h6: { fontSize: 14, color: '#4B5563' },
21
+ };
package/src/index.tsx CHANGED
@@ -12,6 +12,8 @@ export type {
12
12
  LinkPressEvent,
13
13
  LinkLongPressEvent,
14
14
  TaskListItemPressEvent,
15
+ CopyPressEvent,
16
+ OnPasteEvent,
15
17
  } from './types/events';
16
18
  export type {
17
19
  AccessibilityLabels,
@@ -31,9 +33,16 @@ export type {
31
33
  ContextMenuItem,
32
34
  InputSelectionMenuConfig,
33
35
  FormatMenuConfig,
36
+ OnKeyPressEvent,
34
37
  OnLinkDetected,
35
38
  OnStartMentionEvent,
36
39
  OnChangeMentionEvent,
37
40
  OnEndMentionEvent,
38
41
  CaretRect,
42
+ HeadingLevel,
43
+ HeadingStyle,
44
+ InputInlineMathStyle,
45
+ InputMathStyle,
46
+ OnMathPressEvent,
47
+ InsertMathOptions,
39
48
  } from './EnrichedMarkdownTextInput';
package/src/index.web.tsx CHANGED
@@ -5,4 +5,5 @@ export type {
5
5
  LinkPressEvent,
6
6
  LinkLongPressEvent,
7
7
  TaskListItemPressEvent,
8
+ CopyPressEvent,
8
9
  } from './types/events';
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Jest mock for `react-native-enriched-markdown-scaffold`, wired up via
3
+ * `jest.mock('react-native-enriched-markdown-scaffold', () => require('react-native-enriched-markdown-scaffold/jest'))`.
4
+ * See docs/TESTING.md for setup and the behavior it mirrors.
5
+ *
6
+ * The two components are Fabric/codegen native views: under Jest there is no
7
+ * native view manager, so rendering them or calling any imperative ref method
8
+ * (each dispatches a native command) throws. These replacements render plain RN
9
+ * primitives and expose every imperative method as a spy.
10
+ *
11
+ * Behavior mirrored from the native component: typing fires `onChangeText` and,
12
+ * when set, `onChangeMarkdown` (the raw text stands in for parsed markdown);
13
+ * `setValue()` updates the rendered text but emits no change events, matching
14
+ * the native suppression of emits for programmatic updates.
15
+ *
16
+ * The mock is typed against the real public types, so `yarn typecheck` fails if
17
+ * the API gains a prop or ref method the mock does not cover -- it cannot
18
+ * silently drift from the real component.
19
+ */
20
+ import { useImperativeHandle, useRef, useState } from 'react';
21
+ import type { ComponentRef } from 'react';
22
+ import { Text, TextInput } from 'react-native';
23
+ import type {
24
+ CaretRect,
25
+ EnrichedMarkdownTextInputInstance,
26
+ EnrichedMarkdownTextInputProps,
27
+ InsertMathOptions,
28
+ } from '../EnrichedMarkdownTextInput';
29
+ import type { EnrichedMarkdownTextProps } from '../native/EnrichedMarkdownText';
30
+
31
+ export {
32
+ DEFAULT_ACCESSIBILITY_LABELS,
33
+ resolveAccessibilityLabels,
34
+ } from '../accessibilityLabelDefaults';
35
+
36
+ type AnyFn = (...args: any[]) => any;
37
+ declare const jest: { fn: <T extends AnyFn>(impl?: T) => T };
38
+
39
+ const spy = <T extends AnyFn>(impl?: T): T => jest.fn(impl);
40
+
41
+ const EMPTY_CARET_RECT: CaretRect = { x: 0, y: 0, width: 0, height: 0 };
42
+
43
+ export const EnrichedMarkdownTextInput = ({
44
+ ref,
45
+ defaultValue,
46
+ onChangeText,
47
+ onChangeMarkdown,
48
+ onFocus,
49
+ onBlur,
50
+ editable = true,
51
+ placeholder,
52
+ placeholderTextColor,
53
+ autoFocus = false,
54
+ multiline = true,
55
+ scrollEnabled = true,
56
+ style,
57
+ testID,
58
+ accessible,
59
+ accessibilityLabel,
60
+ accessibilityHint,
61
+ accessibilityRole,
62
+ accessibilityState,
63
+ nativeID,
64
+ markdownStyle: _markdownStyle,
65
+ cursorColor: _cursorColor,
66
+ selectionColor: _selectionColor,
67
+ autoCapitalize: _autoCapitalize,
68
+ onChangeSelection: _onChangeSelection,
69
+ onChangeState: _onChangeState,
70
+ onKeyPress: _onKeyPress,
71
+ onCaretRectChange: _onCaretRectChange,
72
+ onLinkDetected: _onLinkDetected,
73
+ mentionIndicators: _mentionIndicators,
74
+ onStartMention: _onStartMention,
75
+ onChangeMention: _onChangeMention,
76
+ onEndMention: _onEndMention,
77
+ contextMenuItems: _contextMenuItems,
78
+ selectionMenuConfig: _selectionMenuConfig,
79
+ formatMenuConfig: _formatMenuConfig,
80
+ linkRegex: _linkRegex,
81
+ writingDirection: _writingDirection,
82
+ }: EnrichedMarkdownTextInputProps) => {
83
+ const [text, setText] = useState(defaultValue ?? '');
84
+ const textRef = useRef(text);
85
+ const inputRef = useRef<ComponentRef<typeof TextInput> | null>(null);
86
+
87
+ const applyText = (next: string) => {
88
+ textRef.current = next;
89
+ setText(next);
90
+ };
91
+
92
+ const handleChangeText = (next: string) => {
93
+ applyText(next);
94
+ onChangeText?.(next);
95
+ onChangeMarkdown?.(next);
96
+ };
97
+
98
+ const instanceRef = useRef<EnrichedMarkdownTextInputInstance | null>(null);
99
+ if (instanceRef.current === null) {
100
+ instanceRef.current = {
101
+ focus: spy(() => inputRef.current?.focus()),
102
+ blur: spy(() => inputRef.current?.blur()),
103
+ measure: spy((callback) => callback(0, 0, 0, 0, 0, 0)),
104
+ measureInWindow: spy((callback) => callback(0, 0, 0, 0)),
105
+ measureLayout: spy((_relativeToNativeNode, onSuccess) =>
106
+ onSuccess(0, 0, 0, 0)
107
+ ),
108
+ setValue: spy((markdown: string) => applyText(markdown)),
109
+ setSelection: spy((_start: number, _end: number) => {}),
110
+ toggleBold: spy(() => {}),
111
+ toggleItalic: spy(() => {}),
112
+ toggleUnderline: spy(() => {}),
113
+ toggleStrikethrough: spy(() => {}),
114
+ toggleSpoiler: spy(() => {}),
115
+ toggleHeading: spy((_level) => {}),
116
+ toggleUnorderedList: spy(() => {}),
117
+ toggleOrderedList: spy(() => {}),
118
+ indentList: spy(() => {}),
119
+ outdentList: spy(() => {}),
120
+ setLink: spy((_url: string) => {}),
121
+ insertLink: spy((_text: string, _url: string) => {}),
122
+ insertText: spy((_text: string) => {}),
123
+ insertMention: spy((_displayText: string, _url: string) => {}),
124
+ startMention: spy((_indicator: string) => {}),
125
+ removeLink: spy(() => {}),
126
+ copyToClipboard: spy(() => {}),
127
+ resolvePaste: spy((_text: string, _markdown?: string) => {}),
128
+ // Math chip commands are native-only; the mock records the call so tests can
129
+ // assert the API surface without a native chip implementation.
130
+ insertMath: spy((_latex: string, _options?: InsertMathOptions) => {}),
131
+ updateMath: spy(
132
+ (_start: number, _latex: string, _options?: InsertMathOptions) => {}
133
+ ),
134
+ removeMath: spy((_start: number) => {}),
135
+ getMarkdown: spy(() => Promise.resolve(textRef.current)),
136
+ getCaretRect: spy(() => Promise.resolve(EMPTY_CARET_RECT)),
137
+ };
138
+ }
139
+
140
+ useImperativeHandle(ref, () => instanceRef.current!);
141
+
142
+ return (
143
+ <TextInput
144
+ ref={inputRef}
145
+ value={text}
146
+ onChangeText={handleChangeText}
147
+ onFocus={() => onFocus?.()}
148
+ onBlur={() => onBlur?.()}
149
+ editable={editable}
150
+ placeholder={placeholder}
151
+ placeholderTextColor={placeholderTextColor}
152
+ autoFocus={autoFocus}
153
+ multiline={multiline}
154
+ scrollEnabled={scrollEnabled}
155
+ style={style}
156
+ testID={testID}
157
+ accessible={accessible}
158
+ accessibilityLabel={accessibilityLabel}
159
+ accessibilityHint={accessibilityHint}
160
+ accessibilityRole={accessibilityRole}
161
+ accessibilityState={accessibilityState}
162
+ nativeID={nativeID}
163
+ />
164
+ );
165
+ };
166
+
167
+ export const EnrichedMarkdownText = ({
168
+ markdown,
169
+ containerStyle,
170
+ testID,
171
+ accessible,
172
+ accessibilityLabel,
173
+ accessibilityHint,
174
+ accessibilityRole,
175
+ accessibilityState,
176
+ nativeID,
177
+ markdownStyle: _markdownStyle,
178
+ onLinkPress: _onLinkPress,
179
+ onLinkLongPress: _onLinkLongPress,
180
+ onTaskListItemPress: _onTaskListItemPress,
181
+ enableLinkPreview: _enableLinkPreview,
182
+ selectable: _selectable,
183
+ md4cFlags: _md4cFlags,
184
+ allowFontScaling: _allowFontScaling,
185
+ maxFontSizeMultiplier: _maxFontSizeMultiplier,
186
+ allowTrailingMargin: _allowTrailingMargin,
187
+ flavor: _flavor,
188
+ streamingAnimation: _streamingAnimation,
189
+ streamingConfig: _streamingConfig,
190
+ spoilerOverlay: _spoilerOverlay,
191
+ contextMenuItems: _contextMenuItems,
192
+ imageRequestHeaders: _imageRequestHeaders,
193
+ selectionMenuConfig: _selectionMenuConfig,
194
+ accessibilityLabels: _accessibilityLabels,
195
+ selectionColor: _selectionColor,
196
+ selectionHandleColor: _selectionHandleColor,
197
+ textBreakStrategy: _textBreakStrategy,
198
+ lineBreakStrategyIOS: _lineBreakStrategyIOS,
199
+ writingDirection: _writingDirection,
200
+ }: EnrichedMarkdownTextProps) => {
201
+ return (
202
+ <Text
203
+ style={containerStyle}
204
+ testID={testID}
205
+ accessible={accessible}
206
+ accessibilityLabel={accessibilityLabel}
207
+ accessibilityHint={accessibilityHint}
208
+ accessibilityRole={accessibilityRole}
209
+ accessibilityState={accessibilityState}
210
+ nativeID={nativeID}
211
+ >
212
+ {markdown}
213
+ </Text>
214
+ );
215
+ };
@@ -21,6 +21,7 @@ import type {
21
21
  LinkPressEvent,
22
22
  LinkLongPressEvent,
23
23
  TaskListItemPressEvent,
24
+ CopyPressEvent,
24
25
  OnContextMenuItemPressEvent,
25
26
  } from '../types/events';
26
27
 
@@ -32,7 +33,12 @@ export type {
32
33
  SelectionMenuConfig,
33
34
  SelectionMenuPluralLabels,
34
35
  };
35
- export type { LinkPressEvent, LinkLongPressEvent, TaskListItemPressEvent };
36
+ export type {
37
+ LinkPressEvent,
38
+ LinkLongPressEvent,
39
+ TaskListItemPressEvent,
40
+ CopyPressEvent,
41
+ };
36
42
 
37
43
  // Default English labels for the built-in selection menu actions. Defaults are
38
44
  // resolved here (JS-side) so the native code always receives a concrete string.
@@ -101,6 +107,7 @@ const defaultMd4cFlags: Md4cFlags = {
101
107
  subscript: false,
102
108
  latexMath: true,
103
109
  highlight: false,
110
+ hardSoftBreaks: false,
104
111
  };
105
112
 
106
113
  export const EnrichedMarkdownText = ({
@@ -110,6 +117,8 @@ export const EnrichedMarkdownText = ({
110
117
  onLinkPress,
111
118
  onLinkLongPress,
112
119
  onTaskListItemPress,
120
+ enableTaskListItemToggle = true,
121
+ onCopyPress,
113
122
  enableLinkPreview,
114
123
  selectable = true,
115
124
  md4cFlags = defaultMd4cFlags,
@@ -121,6 +130,8 @@ export const EnrichedMarkdownText = ({
121
130
  streamingConfig,
122
131
  spoilerOverlay = 'particles',
123
132
  contextMenuItems,
133
+ imageRequestHeaders,
134
+ contextMenuHidden = false,
124
135
  selectionMenuConfig,
125
136
  accessibilityLabels,
126
137
  selectionColor,
@@ -146,6 +157,7 @@ export const EnrichedMarkdownText = ({
146
157
  subscript: md4cFlags.subscript ?? false,
147
158
  latexMath: md4cFlags.latexMath ?? true,
148
159
  highlight: md4cFlags.highlight ?? false,
160
+ hardSoftBreaks: md4cFlags.hardSoftBreaks ?? false,
149
161
  }),
150
162
  [md4cFlags]
151
163
  );
@@ -172,6 +184,16 @@ export const EnrichedMarkdownText = ({
172
184
  [contextMenuItems]
173
185
  );
174
186
 
187
+ const nativeImageRequestHeaders = useMemo(
188
+ () =>
189
+ imageRequestHeaders
190
+ ? Object.entries(imageRequestHeaders)
191
+ .map(([name, value]) => ({ name, value }))
192
+ .sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))
193
+ : undefined,
194
+ [imageRequestHeaders]
195
+ );
196
+
175
197
  const handleContextMenuItemPress = useCallback(
176
198
  (e: NativeSyntheticEvent<OnContextMenuItemPressEvent>) => {
177
199
  const { itemText, selectedText, selectionStart, selectionEnd } =
@@ -209,8 +231,20 @@ export const EnrichedMarkdownText = ({
209
231
  [onTaskListItemPress]
210
232
  );
211
233
 
234
+ const handleCopyPress = useCallback(
235
+ (e: NativeSyntheticEvent<CopyPressEvent>) => {
236
+ const { code, language } = e.nativeEvent;
237
+ onCopyPress?.({ code, language });
238
+ },
239
+ [onCopyPress]
240
+ );
241
+
212
242
  const tableMode = streamingConfig?.tableMode ?? 'progressive';
213
- const normalizedStreamingConfig = useMemo(() => ({ tableMode }), [tableMode]);
243
+ const codeBlockMode = streamingConfig?.codeBlockMode ?? 'progressive';
244
+ const normalizedStreamingConfig = useMemo(
245
+ () => ({ tableMode, codeBlockMode }),
246
+ [tableMode, codeBlockMode]
247
+ );
214
248
  const normalizedSelectionMenuConfig = useMemo(() => {
215
249
  // The boolean acceptance is confined to this wrapper boundary via a single
216
250
  // `as unknown` cast; the public type only exposes the object shape.
@@ -219,10 +253,19 @@ export const EnrichedMarkdownText = ({
219
253
  copy?: unknown;
220
254
  copyAsMarkdown?: unknown;
221
255
  copyImageUrl?: unknown;
256
+ systemItems?: unknown;
257
+ codeBlockCopyButton?: unknown;
222
258
  }
223
259
  | undefined;
224
260
 
225
261
  const copy = normalizeMenuItem(config?.copy, true, DEFAULT_COPY_LABEL);
262
+ const copyFormat = (config?.copy as { format?: unknown } | undefined)
263
+ ?.format;
264
+ const codeBlockCopyButton = normalizeMenuItem(
265
+ config?.codeBlockCopyButton,
266
+ true,
267
+ ''
268
+ );
226
269
  const copyAsMarkdown = normalizeLegacyBooleanMenuItem(
227
270
  config?.copyAsMarkdown,
228
271
  'selectionMenuConfig',
@@ -255,6 +298,10 @@ export const EnrichedMarkdownText = ({
255
298
  pluralLabels,
256
299
  copyImageUrl.label
257
300
  ),
301
+ copyEnabled: copy.enabled,
302
+ copyFormatMarkdown: copyFormat === 'markdown',
303
+ systemItemsNone: config?.systemItems === 'none',
304
+ codeBlockCopyButton: codeBlockCopyButton.enabled,
258
305
  };
259
306
  }, [selectionMenuConfig]);
260
307
 
@@ -269,6 +316,8 @@ export const EnrichedMarkdownText = ({
269
316
  onLinkPress: handleLinkPress,
270
317
  onLinkLongPress: handleLinkLongPress,
271
318
  onTaskListItemPress: handleTaskListItemPress,
319
+ enableTaskListItemToggle,
320
+ onCopyPress: handleCopyPress,
272
321
  enableLinkPreview: onLinkLongPress == null && (enableLinkPreview ?? true),
273
322
  selectable,
274
323
  md4cFlags: normalizedMd4cFlags,
@@ -280,6 +329,8 @@ export const EnrichedMarkdownText = ({
280
329
  spoilerOverlay,
281
330
  style: containerStyle,
282
331
  contextMenuItems: nativeContextMenuItems,
332
+ imageRequestHeaders: nativeImageRequestHeaders,
333
+ contextMenuHidden,
283
334
  selectionMenuConfig: normalizedSelectionMenuConfig,
284
335
  accessibilityLabels: resolvedAccessibilityLabels,
285
336
  onContextMenuItemPress: handleContextMenuItemPress,
@@ -8,6 +8,10 @@ import type {
8
8
  } from './types/MarkdownStyleInternal';
9
9
  import { isStyleEqual, normalizeColor, mergeSubStyle } from './styleUtils';
10
10
  import { normalizeLinkVariantEntries } from './linkVariantUtils';
11
+ import {
12
+ DEFAULT_HEADING_FONT_WEIGHT,
13
+ HEADING_DEFAULTS,
14
+ } from './headingDefaults';
11
15
 
12
16
  const getSystemFont = (): string =>
13
17
  Platform.select({
@@ -26,7 +30,43 @@ const getMonospaceFont = (): string =>
26
30
  })!;
27
31
 
28
32
  const defaultTextColor = normalizeColor('#1F2937')!;
29
- const defaultHeadingColor = normalizeColor('#111827')!;
33
+
34
+ const codeBlockTextColor = normalizeColor('#F3F4F6')!;
35
+
36
+ // GitHub-dark syntax palette (Primer prettylights), tuned for the dark code
37
+ // block background (#1F2937). It is the single source of truth for per-token
38
+ // code colors: native reads these resolved values and holds no default of its
39
+ // own. The four inheriting tokens resolve to the code block base color.
40
+ const DEFAULT_CODE_BLOCK_SYNTAX_COLORS = {
41
+ keyword: normalizeColor('#FF7B72')!,
42
+ operatorColor: codeBlockTextColor,
43
+ punctuation: codeBlockTextColor,
44
+ string: normalizeColor('#A5D6FF')!,
45
+ number: normalizeColor('#79C0FF')!,
46
+ constant: normalizeColor('#79C0FF')!,
47
+ comment: normalizeColor('#8B949E')!,
48
+ function: normalizeColor('#D2A8FF')!,
49
+ type: normalizeColor('#FFA657')!,
50
+ variable: codeBlockTextColor,
51
+ property: normalizeColor('#79C0FF')!,
52
+ tag: normalizeColor('#7EE787')!,
53
+ attribute: normalizeColor('#79C0FF')!,
54
+ embedded: codeBlockTextColor,
55
+ };
56
+
57
+ const INHERIT_SYNTAX_TOKENS = new Set([
58
+ 'operatorColor',
59
+ 'punctuation',
60
+ 'variable',
61
+ 'embedded',
62
+ ]);
63
+
64
+ // The public API exposes `operator`, but the internal/native token is named
65
+ // `operatorColor` because `operator` is a reserved word in the generated C++
66
+ // struct. Map the public key onto the internal token when reading user input.
67
+ const PUBLIC_SYNTAX_TOKEN_KEYS: Record<string, string> = {
68
+ operatorColor: 'operator',
69
+ };
30
70
 
31
71
  // Explicit type annotation needed: Object.freeze breaks contextual typing, so
32
72
  // TypeScript widens literal 'auto' to `string` instead of `BlockTextAlign`.
@@ -38,7 +78,7 @@ const baseHeader: {
38
78
  textAlign: BlockTextAlign;
39
79
  } = {
40
80
  fontFamily: getSystemFont(),
41
- fontWeight: '',
81
+ fontWeight: DEFAULT_HEADING_FONT_WEIGHT,
42
82
  marginTop: 0,
43
83
  marginBottom: 8,
44
84
  textAlign: 'auto',
@@ -57,38 +97,38 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
57
97
  },
58
98
  h1: {
59
99
  ...baseHeader,
60
- fontSize: 30,
61
- color: defaultHeadingColor,
100
+ fontSize: HEADING_DEFAULTS.h1.fontSize,
101
+ color: normalizeColor(HEADING_DEFAULTS.h1.color)!,
62
102
  lineHeight: Platform.select({ ios: 36, android: 38, default: 38 })!,
63
103
  },
64
104
  h2: {
65
105
  ...baseHeader,
66
- fontSize: 24,
67
- color: defaultHeadingColor,
106
+ fontSize: HEADING_DEFAULTS.h2.fontSize,
107
+ color: normalizeColor(HEADING_DEFAULTS.h2.color)!,
68
108
  lineHeight: Platform.select({ ios: 30, android: 32, default: 32 })!,
69
109
  },
70
110
  h3: {
71
111
  ...baseHeader,
72
- fontSize: 20,
73
- color: defaultHeadingColor,
112
+ fontSize: HEADING_DEFAULTS.h3.fontSize,
113
+ color: normalizeColor(HEADING_DEFAULTS.h3.color)!,
74
114
  lineHeight: Platform.select({ ios: 26, android: 28, default: 28 })!,
75
115
  },
76
116
  h4: {
77
117
  ...baseHeader,
78
- fontSize: 18,
79
- color: defaultHeadingColor,
118
+ fontSize: HEADING_DEFAULTS.h4.fontSize,
119
+ color: normalizeColor(HEADING_DEFAULTS.h4.color)!,
80
120
  lineHeight: Platform.select({ ios: 24, android: 26, default: 26 })!,
81
121
  },
82
122
  h5: {
83
123
  ...baseHeader,
84
- fontSize: 16,
85
- color: normalizeColor('#374151')!,
124
+ fontSize: HEADING_DEFAULTS.h5.fontSize,
125
+ color: normalizeColor(HEADING_DEFAULTS.h5.color)!,
86
126
  lineHeight: Platform.select({ ios: 22, android: 24, default: 24 })!,
87
127
  },
88
128
  h6: {
89
129
  ...baseHeader,
90
- fontSize: 14,
91
- color: normalizeColor('#4B5563')!,
130
+ fontSize: HEADING_DEFAULTS.h6.fontSize,
131
+ color: normalizeColor(HEADING_DEFAULTS.h6.color)!,
92
132
  lineHeight: Platform.select({ ios: 20, android: 22, default: 22 })!,
93
133
  },
94
134
  blockquote: {
@@ -103,6 +143,8 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
103
143
  borderWidth: 3,
104
144
  gapWidth: 16,
105
145
  backgroundColor: normalizeColor('#F9FAFB')!,
146
+ borderRadius: 0,
147
+ padding: 0,
106
148
  },
107
149
  list: {
108
150
  fontSize: 16,
@@ -119,12 +161,13 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
119
161
  markerFontWeight: '500',
120
162
  gapWidth: 12,
121
163
  marginLeft: 24,
164
+ itemSpacing: 0,
122
165
  },
123
166
  codeBlock: {
124
167
  fontSize: 14,
125
168
  fontFamily: getMonospaceFont(),
126
169
  fontWeight: '',
127
- color: normalizeColor('#F3F4F6')!,
170
+ color: codeBlockTextColor,
128
171
  lineHeight: Platform.select({ ios: 20, android: 22, default: 22 })!,
129
172
  marginTop: 0,
130
173
  marginBottom: 16,
@@ -133,6 +176,7 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
133
176
  borderRadius: 8,
134
177
  borderWidth: 1,
135
178
  padding: 16,
179
+ syntaxColors: { ...DEFAULT_CODE_BLOCK_SYNTAX_COLORS },
136
180
  },
137
181
  link: {
138
182
  fontFamily: '',
@@ -158,7 +202,15 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
158
202
  backgroundColor: normalizeColor('#FDF2F4')!,
159
203
  borderColor: normalizeColor('#F8D7DA')!,
160
204
  },
161
- image: { height: 200, borderRadius: 8, marginTop: 0, marginBottom: 16 },
205
+ image: {
206
+ height: 200,
207
+ maxHeight: 0,
208
+ aspectRatio: 0,
209
+ resizeMode: '' as const,
210
+ borderRadius: 8,
211
+ marginTop: 0,
212
+ marginBottom: 16,
213
+ },
162
214
  inlineImage: { size: 20 },
163
215
  thematicBreak: {
164
216
  color: normalizeColor('#E5E7EB')!,
@@ -184,6 +236,8 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
184
236
  borderRadius: 6,
185
237
  cellPaddingHorizontal: 12,
186
238
  cellPaddingVertical: 8,
239
+ horizontalOverflow: 0,
240
+ align: '' as const,
187
241
  },
188
242
  math: {
189
243
  fontSize: 20,
@@ -298,6 +352,12 @@ export const normalizeMarkdownStyle = (
298
352
  );
299
353
  }
300
354
 
355
+ // maxHeight/aspectRatio sizing is resize-mode driven; default to 'cover'.
356
+ const image = result.image as MarkdownStyleInternal['image'];
357
+ if (!image.resizeMode && (image.maxHeight > 0 || image.aspectRatio > 0)) {
358
+ (result.image as { resizeMode: string }).resizeMode = 'cover';
359
+ }
360
+
301
361
  if (!style.highlight?.color) {
302
362
  const paragraphColor = (
303
363
  result.paragraph as MarkdownStyleInternal['paragraph']
@@ -306,6 +366,32 @@ export const normalizeMarkdownStyle = (
306
366
  paragraphColor;
307
367
  }
308
368
 
369
+ const codeBlock = result.codeBlock as MarkdownStyleInternal['codeBlock'];
370
+ const userSyntaxColors = style.codeBlock?.syntaxColors as
371
+ | Record<string, unknown>
372
+ | undefined;
373
+ const resolvedSyntaxColors: Record<string, unknown> = {};
374
+ for (const token in DEFAULT_CODE_BLOCK_SYNTAX_COLORS) {
375
+ const publicKey = PUBLIC_SYNTAX_TOKEN_KEYS[token] ?? token;
376
+ const userValue = userSyntaxColors?.[publicKey];
377
+ if (typeof userValue === 'string') {
378
+ resolvedSyntaxColors[token] =
379
+ normalizeColor(userValue) ??
380
+ DEFAULT_CODE_BLOCK_SYNTAX_COLORS[
381
+ token as keyof typeof DEFAULT_CODE_BLOCK_SYNTAX_COLORS
382
+ ];
383
+ } else if (INHERIT_SYNTAX_TOKENS.has(token)) {
384
+ resolvedSyntaxColors[token] = codeBlock.color;
385
+ } else {
386
+ resolvedSyntaxColors[token] =
387
+ DEFAULT_CODE_BLOCK_SYNTAX_COLORS[
388
+ token as keyof typeof DEFAULT_CODE_BLOCK_SYNTAX_COLORS
389
+ ];
390
+ }
391
+ }
392
+ (codeBlock as unknown as Record<string, unknown>).syntaxColors =
393
+ resolvedSyntaxColors;
394
+
309
395
  const finalResult = Object.freeze(result) as unknown as MarkdownStyleInternal;
310
396
  refCache.set(style, finalResult);
311
397
  structuralCache.unshift({ style, result: finalResult });