react-native-enriched-markdown 0.2.1 → 0.3.0-nightly-20260221-b992065d9

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 (135) hide show
  1. package/README.md +107 -13
  2. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +54 -0
  3. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +26 -0
  4. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +1 -1
  5. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.h +1 -1
  6. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +40 -0
  7. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +31 -0
  8. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +64 -0
  9. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +1813 -0
  10. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.cpp +1 -1
  11. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.h +0 -9
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/States.h +1 -1
  13. package/android/src/main/cpp/jni-adapter.cpp +12 -0
  14. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +332 -0
  15. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +70 -0
  16. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +189 -0
  17. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +21 -49
  18. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +31 -2
  19. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextPackage.kt +1 -0
  20. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +136 -1
  21. package/android/src/main/java/com/swmansion/enriched/markdown/events/TaskListItemPressEvent.kt +26 -0
  22. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +6 -0
  23. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +3 -8
  24. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +82 -14
  25. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +5 -0
  26. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +26 -35
  27. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +2 -3
  28. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  29. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +4 -5
  30. package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +8 -1
  31. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +6 -8
  32. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -5
  33. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +130 -0
  34. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +6 -11
  35. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeStyle.kt +4 -1
  36. package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkStyle.kt +3 -1
  37. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +53 -1
  38. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +69 -0
  39. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TaskListStyle.kt +29 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/utils/CheckboxTouchHelper.kt +52 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/utils/ContextMenuPopup.kt +214 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/utils/HTMLGenerator.kt +198 -15
  43. package/android/src/main/java/com/swmansion/enriched/markdown/utils/MarkdownASTSerializer.kt +97 -0
  44. package/android/src/main/java/com/swmansion/enriched/markdown/utils/MarkdownExtractor.kt +10 -3
  45. package/android/src/main/java/com/swmansion/enriched/markdown/utils/MarkdownTextViewUtils.kt +43 -0
  46. package/android/src/main/java/com/swmansion/enriched/markdown/utils/SelectionActionMode.kt +17 -2
  47. package/android/src/main/java/com/swmansion/enriched/markdown/utils/TaskListTapUtils.kt +82 -0
  48. package/android/src/main/java/com/swmansion/enriched/markdown/utils/Utils.kt +8 -0
  49. package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockSegmentView.kt +10 -0
  50. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +465 -0
  51. package/android/src/main/jni/EnrichedMarkdownTextSpec.h +1 -11
  52. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.h +48 -0
  53. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerComponentDescriptor.h +26 -0
  54. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerMeasurementManager.cpp +45 -0
  55. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerMeasurementManager.h +21 -0
  56. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +20 -0
  57. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +34 -0
  58. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +10 -1
  59. package/cpp/parser/MD4CParser.cpp +71 -2
  60. package/cpp/parser/MarkdownASTNode.hpp +7 -1
  61. package/ios/EnrichedMarkdown.h +18 -0
  62. package/ios/EnrichedMarkdown.mm +623 -0
  63. package/ios/EnrichedMarkdownText.mm +75 -944
  64. package/ios/generated/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +1 -1
  65. package/ios/generated/EnrichedMarkdownTextSpec/ComponentDescriptors.h +1 -1
  66. package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.cpp +40 -0
  67. package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.h +31 -0
  68. package/ios/generated/EnrichedMarkdownTextSpec/Props.cpp +64 -0
  69. package/ios/generated/EnrichedMarkdownTextSpec/Props.h +1813 -0
  70. package/ios/generated/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +4 -0
  71. package/ios/generated/EnrichedMarkdownTextSpec/ShadowNodes.cpp +1 -1
  72. package/ios/generated/EnrichedMarkdownTextSpec/ShadowNodes.h +0 -9
  73. package/ios/generated/EnrichedMarkdownTextSpec/States.h +1 -1
  74. package/ios/internals/EnrichedMarkdownComponentDescriptor.h +18 -0
  75. package/ios/internals/EnrichedMarkdownShadowNode.h +41 -0
  76. package/ios/internals/EnrichedMarkdownShadowNode.mm +84 -0
  77. package/ios/internals/EnrichedMarkdownState.h +23 -0
  78. package/ios/parser/{MarkdownParser.h → ENRMMarkdownParser.h} +4 -4
  79. package/ios/parser/{MarkdownParser.mm → ENRMMarkdownParser.mm} +9 -9
  80. package/ios/parser/MarkdownASTNode.h +7 -1
  81. package/ios/parser/MarkdownParserBridge.mm +20 -2
  82. package/ios/renderer/CodeBlockRenderer.m +5 -1
  83. package/ios/renderer/CodeRenderer.m +2 -1
  84. package/ios/renderer/LinkRenderer.m +18 -0
  85. package/ios/renderer/ListItemRenderer.h +4 -1
  86. package/ios/renderer/ListItemRenderer.m +71 -4
  87. package/ios/renderer/RenderContext.h +4 -0
  88. package/ios/renderer/RenderContext.m +14 -0
  89. package/ios/renderer/RendererFactory.m +7 -0
  90. package/ios/styles/StyleConfig.h +56 -0
  91. package/ios/styles/StyleConfig.mm +374 -0
  92. package/ios/utils/BlockquoteBorder.m +6 -1
  93. package/ios/utils/FontScaleObserver.h +10 -0
  94. package/ios/utils/FontScaleObserver.m +47 -0
  95. package/ios/utils/HTMLGenerator.h +3 -0
  96. package/ios/utils/HTMLGenerator.m +190 -21
  97. package/ios/utils/LinkTapUtils.h +21 -0
  98. package/ios/utils/LinkTapUtils.m +28 -0
  99. package/ios/utils/ListMarkerDrawer.m +81 -9
  100. package/ios/utils/MarkdownASTSerializer.h +24 -0
  101. package/ios/utils/MarkdownASTSerializer.m +96 -0
  102. package/ios/utils/MarkdownAccessibilityElementBuilder.h +7 -0
  103. package/ios/utils/MarkdownAccessibilityElementBuilder.m +22 -0
  104. package/ios/utils/MarkdownExtractor.m +18 -7
  105. package/ios/utils/ParagraphStyleUtils.h +1 -0
  106. package/ios/utils/ParagraphStyleUtils.m +16 -6
  107. package/ios/utils/StylePropsUtils.h +932 -0
  108. package/ios/utils/TaskListTapUtils.h +31 -0
  109. package/ios/utils/TaskListTapUtils.m +93 -0
  110. package/ios/views/EnrichedMarkdownInternalText.h +30 -0
  111. package/ios/views/EnrichedMarkdownInternalText.m +156 -0
  112. package/ios/views/TableContainerView.h +31 -0
  113. package/ios/views/TableContainerView.m +535 -0
  114. package/lib/module/EnrichedMarkdownNativeComponent.ts +250 -0
  115. package/lib/module/EnrichedMarkdownText.js +30 -6
  116. package/lib/module/EnrichedMarkdownText.js.map +1 -1
  117. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +41 -1
  118. package/lib/module/normalizeMarkdownStyle.js +70 -7
  119. package/lib/module/normalizeMarkdownStyle.js.map +1 -1
  120. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +220 -0
  121. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -0
  122. package/lib/typescript/src/EnrichedMarkdownText.d.ts +45 -3
  123. package/lib/typescript/src/EnrichedMarkdownText.d.ts.map +1 -1
  124. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +35 -0
  125. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
  126. package/lib/typescript/src/index.d.ts +1 -1
  127. package/lib/typescript/src/index.d.ts.map +1 -1
  128. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
  129. package/package.json +4 -1
  130. package/react-native.config.js +4 -1
  131. package/src/EnrichedMarkdownNativeComponent.ts +250 -0
  132. package/src/EnrichedMarkdownText.tsx +76 -15
  133. package/src/EnrichedMarkdownTextNativeComponent.ts +41 -1
  134. package/src/index.tsx +1 -0
  135. package/src/normalizeMarkdownStyle.ts +101 -7
package/README.md CHANGED
@@ -7,6 +7,7 @@
7
7
  - ⚡ Fully native text rendering (no WebView)
8
8
  - 🎯 High-performance Markdown parsing with [md4c](https://github.com/mity/md4c)
9
9
  - 📐 CommonMark standard compliant
10
+ - 📊 GitHub Flavored Markdown (GFM)
10
11
  - 🎨 Fully customizable styles for all elements
11
12
  - 📱 iOS and Android support
12
13
  - 🏛 Supports only the New Architecture (Fabric)
@@ -15,6 +16,7 @@
15
16
  - 🖼️ Native image interactions (iOS: Copy, Save to Camera Roll)
16
17
  - 🌐 Native platform features (Translate, Look Up, Search Web, Share)
17
18
  - 🗣️ Accessibility support (VoiceOver & TalkBack)
19
+ - 🔄 Full RTL (right-to-left) support including text, lists, blockquotes, tables, and task lists
18
20
 
19
21
  Since 2012 [Software Mansion](https://swmansion.com) is a software agency with experience in building web and mobile apps. We are Core React Native Contributors and experts in dealing with all kinds of React Native issues.
20
22
  We can help you build your next dream product –
@@ -29,6 +31,7 @@ We can help you build your next dream product –
29
31
  - [Link Handling](#link-handling)
30
32
  - [Copy Options](#copy-options)
31
33
  - [Accessibility](#accessibility)
34
+ - [RTL Support](#rtl-support)
32
35
  - [Styling Architecture](#styling-architecture)
33
36
  - [Customizing Styles](#customizing-styles)
34
37
  - [API Reference](#api-reference)
@@ -89,7 +92,7 @@ npx expo prebuild
89
92
 
90
93
  ## Usage
91
94
 
92
- Here's a simple example of rendering Markdown content:
95
+ ### CommonMark (default)
93
96
 
94
97
  ```tsx
95
98
  import { EnrichedMarkdownText } from 'react-native-enriched-markdown';
@@ -103,27 +106,43 @@ This is a paragraph with **bold**, *italic*, and [links](https://reactnative.dev
103
106
  - List item one
104
107
  - List item two
105
108
  - Nested item
106
-
107
- \`\`\`javascript
108
- const greeting = 'Hello, World!';
109
- console.log(greeting);
110
- \`\`\`
111
109
  `;
112
110
 
113
111
  export default function App() {
114
- const handleLinkPress = (event: { nativeEvent: { url: string } }) => {
115
- Linking.openURL(event.nativeEvent.url);
116
- };
117
-
118
112
  return (
119
113
  <EnrichedMarkdownText
120
114
  markdown={markdown}
121
- onLinkPress={handleLinkPress}
115
+ onLinkPress={({ url }) => Linking.openURL(url)}
122
116
  />
123
117
  );
124
118
  }
125
119
  ```
126
120
 
121
+ ### GFM (tables)
122
+
123
+ Set `flavor="github"` to enable GitHub Flavored Markdown features like tables:
124
+
125
+ ```tsx
126
+ <EnrichedMarkdownText
127
+ flavor="github"
128
+ markdown={markdown}
129
+ onLinkPress={({ url }) => Linking.openURL(url)}
130
+ markdownStyle={{
131
+ table: {
132
+ fontSize: 14,
133
+ borderColor: '#E5E7EB',
134
+ borderRadius: 8,
135
+ headerBackgroundColor: '#F3F4F6',
136
+ headerFontFamily: 'System-Bold',
137
+ cellPaddingHorizontal: 12,
138
+ cellPaddingVertical: 8,
139
+ },
140
+ }}
141
+ />
142
+ ```
143
+
144
+ Tables support column alignment, rich text in cells (bold, italic, code, links), horizontal scrolling, header styling, alternating row colors, and a long-press context menu with "Copy" and "Copy as Markdown".
145
+
127
146
  ## Supported Markdown Elements
128
147
 
129
148
  `react-native-enriched-markdown` supports a comprehensive set of Markdown elements:
@@ -138,8 +157,10 @@ export default function App() {
138
157
  | Code Blocks | ` ``` code ``` ` | Multi-line code blocks |
139
158
  | Unordered Lists | `- Item`, `* Item`, or `+ Item` | Bullet lists with unlimited nesting |
140
159
  | Ordered Lists | `1. Item` | Numbered lists with unlimited nesting |
160
+ | Task Lists | `- [x] Done`, `- [ ] Todo` | Interactive checkboxes (requires `flavor="github"`) |
141
161
  | Thematic Break | `---`, `***`, or `___` | Visual separator line |
142
162
  | Images | `![alt](url)` | Block-level images |
163
+ | Tables | `| col | col |` | GFM tables with alignment support (requires `flavor="github"`) |
143
164
 
144
165
  ### Inline Elements
145
166
 
@@ -256,6 +277,36 @@ When selecting text that contains images, a **Copy Image URL** option appears to
256
277
  | **List items** | Position announced (e.g., "bullet point", "list item 1") | Position announced |
257
278
  | **Nested lists** | Proper depth handling | "Nested" prefix for deeper items |
258
279
 
280
+ ## RTL Support
281
+
282
+ `react-native-enriched-markdown` fully supports right-to-left (RTL) languages such as Arabic, Hebrew, and Persian.
283
+
284
+ ### Platform Behavior
285
+
286
+ - **Android** — RTL works automatically. Android's text system detects RTL characters (Arabic, Hebrew, etc.) and renders them right-to-left with no additional configuration.
287
+ - **iOS** — Requires `I18nManager.forceRTL(true)` to enable RTL layout direction. This must be called early in the app lifecycle (before the root component mounts) and requires an app restart to take effect.
288
+
289
+ ```tsx
290
+ import { I18nManager } from 'react-native';
291
+
292
+ // Required for iOS, Android handles RTL automatically
293
+ I18nManager.forceRTL(true);
294
+ ```
295
+
296
+ When RTL content is rendered, the following elements automatically mirror their layout:
297
+
298
+ | Element | RTL Behavior |
299
+ |---------|-------------|
300
+ | **Paragraphs & Headings** | Right-aligned with RTL writing direction |
301
+ | **Unordered lists** | Bullets on the right, text indented from the right |
302
+ | **Ordered lists** | Numbers on the right, text indented from the right |
303
+ | **Task lists** | Checkboxes on the right, tappable in RTL |
304
+ | **Blockquotes** | Border on the right side |
305
+ | **Tables** | Columns ordered right-to-left, scrolls to show first column |
306
+ | **Code blocks** | Always LTR (code is inherently left-to-right) |
307
+ | **Inline code** | Positioned correctly within RTL text flow |
308
+ | **Copy as HTML** | Exported HTML includes `dir="rtl"` for correct rendering in paste targets |
309
+
259
310
  ## Styling Architecture
260
311
 
261
312
  Understanding how `react-native-enriched-markdown` handles styling helps you create consistent, well-designed Markdown content.
@@ -275,6 +326,8 @@ Block elements are structural containers that define the layout. Each block has
275
326
  | `blockquote` | Quoted content with accent bar |
276
327
  | `list` | Ordered and unordered lists |
277
328
  | `codeBlock` | Multi-line code containers |
329
+ | `table` | GFM tables (requires `flavor="github"`) |
330
+ | `taskList` | Task list checkboxes |
278
331
 
279
332
  #### Inline Elements
280
333
 
@@ -286,8 +339,8 @@ Inline elements modify text within blocks. They inherit the parent block's base
286
339
  | `em` | Parent block | Italic style, optional color |
287
340
  | `strikethrough` | Parent block | Strike line with custom color (iOS only) |
288
341
  | `underline` | Parent block | Underline with custom color (iOS only) |
289
- | `code` | Parent block | Monospace font, background |
290
- | `link` | Parent block | Color, underline |
342
+ | `code` | Parent block | Monospace font, background, optional fontSize |
343
+ | `link` | Parent block | Optional font family, color, underline |
291
344
 
292
345
  ### Style Inheritance
293
346
 
@@ -366,10 +419,12 @@ The library provides sensible default styles for all Markdown elements out of th
366
419
  color: '#333',
367
420
  },
368
421
  link: {
422
+ fontFamily: 'System-Bold',
369
423
  color: '#007AFF',
370
424
  underline: true,
371
425
  },
372
426
  code: {
427
+ fontSize: 16,
373
428
  color: '#E91E63',
374
429
  backgroundColor: '#F5F5F5',
375
430
  borderColor: '#E0E0E0',
@@ -404,6 +459,12 @@ The library provides sensible default styles for all Markdown elements out of th
404
459
  inlineImage: {
405
460
  size: 20,
406
461
  },
462
+ taskList: {
463
+ checkedColor: '#2196F3',
464
+ borderColor: '#9E9E9E',
465
+ checkmarkColor: '#FFFFFF',
466
+ checkboxSize: 16,
467
+ },
407
468
  }}
408
469
  />
409
470
  ```
@@ -473,6 +534,7 @@ The library provides sensible default styles for all Markdown elements out of th
473
534
 
474
535
  | Property | Type | Description |
475
536
  |----------|------|-------------|
537
+ | `fontSize` | `number` | Font size in points. Defaults to the parent block's font size (1em). Set to customize the monospaced font size independently |
476
538
  | `color` | `string` | Text color |
477
539
  | `backgroundColor` | `string` | Background color |
478
540
  | `borderColor` | `string` | Border color |
@@ -481,6 +543,7 @@ The library provides sensible default styles for all Markdown elements out of th
481
543
 
482
544
  | Property | Type | Description |
483
545
  |----------|------|-------------|
546
+ | `fontFamily` | `string` | Font family for links. Overrides the parent block's font family when set |
484
547
  | `color` | `string` | Link text color |
485
548
  | `underline` | `boolean` | Show underline |
486
549
 
@@ -520,6 +583,35 @@ The library provides sensible default styles for all Markdown elements out of th
520
583
  | `marginTop` | `number` | Top margin |
521
584
  | `marginBottom` | `number` | Bottom margin |
522
585
 
586
+ #### Table-specific
587
+
588
+ Table styles only apply when `flavor="github"` is set. Tables inherit the base block styles (`fontSize`, `fontFamily`, `fontWeight`, `color`, `marginTop`, `marginBottom`, `lineHeight`) and add the following:
589
+
590
+ | Property | Type | Description |
591
+ |----------|------|-------------|
592
+ | `headerFontFamily` | `string` | Font family for header cells (falls back to `fontFamily` if not set) |
593
+ | `headerBackgroundColor` | `string` | Background color for the header row |
594
+ | `headerTextColor` | `string` | Text color for the header row |
595
+ | `rowEvenBackgroundColor` | `string` | Background color for even data rows |
596
+ | `rowOddBackgroundColor` | `string` | Background color for odd data rows |
597
+ | `borderColor` | `string` | Color of the table grid lines |
598
+ | `borderWidth` | `number` | Width of the table grid lines |
599
+ | `borderRadius` | `number` | Corner radius of the table container |
600
+ | `cellPaddingHorizontal` | `number` | Horizontal padding inside cells |
601
+ | `cellPaddingVertical` | `number` | Vertical padding inside cells |
602
+
603
+ #### Task List-specific
604
+
605
+ | Property | Type | Description |
606
+ |----------|------|-------------|
607
+ | `checkedColor` | `string` | Background color of checked checkbox |
608
+ | `borderColor` | `string` | Border color of unchecked checkbox |
609
+ | `checkmarkColor` | `string` | Color of the checkmark inside checked checkbox |
610
+ | `checkboxSize` | `number` | Size of the checkbox (defaults to 90% of list font size) |
611
+ | `checkboxBorderRadius` | `number` | Corner radius of the checkbox |
612
+ | `checkedTextColor` | `string` | Text color for checked items |
613
+ | `checkedStrikethrough` | `boolean` | Whether to apply strikethrough to checked items |
614
+
523
615
  ## API Reference
524
616
 
525
617
  ### Props
@@ -531,12 +623,14 @@ The library provides sensible default styles for all Markdown elements out of th
531
623
  | `containerStyle` | `ViewStyle` | - | Style for the container view |
532
624
  | `onLinkPress` | `(event: LinkPressEvent) => void` | - | Callback when a link is pressed. Access URL via `event.url` |
533
625
  | `onLinkLongPress` | `(event: LinkLongPressEvent) => void` | - | Callback when a link is long pressed. Access URL via `event.url`. On iOS, automatically disables the system link preview |
626
+ | `onTaskListItemPress` | `(event: TaskListItemPressEvent) => void` | - | Callback when a task list checkbox is tapped. Receives `index` (0-based), `checked` (previous state), and `text` (item text) |
534
627
  | `enableLinkPreview` | `boolean` | `true` | Controls the native link preview on long press (iOS only). Automatically set to `false` when `onLinkLongPress` is provided |
535
628
  | `selectable` | `boolean` | `true` | Whether text can be selected |
536
629
  | `md4cFlags` | `Md4cFlags` | `{ underline: false }` | Configuration for md4c parser extension flags |
537
630
  | `allowFontScaling` | `boolean` | `true` | Whether fonts should scale to respect Text Size accessibility settings |
538
631
  | `maxFontSizeMultiplier` | `number` | `undefined` | Maximum font scale multiplier when `allowFontScaling` is enabled |
539
632
  | `allowTrailingMargin` | `boolean` | `false` | Whether to preserve the bottom margin of the last block element |
633
+ | `flavor` | `'commonmark' \| 'github'` | `'commonmark'` | Markdown flavor. Set to `'github'` to enable GitHub Flavored Markdown table support |
540
634
 
541
635
  ## Future Plans
542
636
 
@@ -0,0 +1,54 @@
1
+ /**
2
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
+ *
4
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
5
+ * once the code is regenerated.
6
+ *
7
+ * @generated by codegen project: GeneratePropsJavaDelegate.js
8
+ */
9
+
10
+ package com.facebook.react.viewmanagers;
11
+
12
+ import android.view.View;
13
+ import androidx.annotation.Nullable;
14
+ import com.facebook.react.bridge.ReadableMap;
15
+ import com.facebook.react.uimanager.BaseViewManager;
16
+ import com.facebook.react.uimanager.BaseViewManagerDelegate;
17
+ import com.facebook.react.uimanager.LayoutShadowNode;
18
+
19
+ public class EnrichedMarkdownManagerDelegate<T extends View, U extends BaseViewManager<T, ? extends LayoutShadowNode> & EnrichedMarkdownManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
20
+ public EnrichedMarkdownManagerDelegate(U viewManager) {
21
+ super(viewManager);
22
+ }
23
+ @Override
24
+ public void setProperty(T view, String propName, @Nullable Object value) {
25
+ switch (propName) {
26
+ case "markdown":
27
+ mViewManager.setMarkdown(view, value == null ? null : (String) value);
28
+ break;
29
+ case "markdownStyle":
30
+ mViewManager.setMarkdownStyle(view, (ReadableMap) value);
31
+ break;
32
+ case "enableLinkPreview":
33
+ mViewManager.setEnableLinkPreview(view, value == null ? true : (boolean) value);
34
+ break;
35
+ case "selectable":
36
+ mViewManager.setSelectable(view, value == null ? false : (boolean) value);
37
+ break;
38
+ case "md4cFlags":
39
+ mViewManager.setMd4cFlags(view, (ReadableMap) value);
40
+ break;
41
+ case "allowFontScaling":
42
+ mViewManager.setAllowFontScaling(view, value == null ? true : (boolean) value);
43
+ break;
44
+ case "maxFontSizeMultiplier":
45
+ mViewManager.setMaxFontSizeMultiplier(view, value == null ? 0f : ((Double) value).floatValue());
46
+ break;
47
+ case "allowTrailingMargin":
48
+ mViewManager.setAllowTrailingMargin(view, value == null ? false : (boolean) value);
49
+ break;
50
+ default:
51
+ super.setProperty(view, propName, value);
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
+ *
4
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
5
+ * once the code is regenerated.
6
+ *
7
+ * @generated by codegen project: GeneratePropsJavaInterface.js
8
+ */
9
+
10
+ package com.facebook.react.viewmanagers;
11
+
12
+ import android.view.View;
13
+ import androidx.annotation.Nullable;
14
+ import com.facebook.react.bridge.ReadableMap;
15
+ import com.facebook.react.uimanager.ViewManagerWithGeneratedInterface;
16
+
17
+ public interface EnrichedMarkdownManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
18
+ void setMarkdown(T view, @Nullable String value);
19
+ void setMarkdownStyle(T view, @Nullable ReadableMap value);
20
+ void setEnableLinkPreview(T view, boolean value);
21
+ void setSelectable(T view, boolean value);
22
+ void setMd4cFlags(T view, @Nullable ReadableMap value);
23
+ void setAllowFontScaling(T view, boolean value);
24
+ void setMaxFontSizeMultiplier(T view, float value);
25
+ void setAllowTrailingMargin(T view, boolean value);
26
+ }
@@ -16,7 +16,7 @@ namespace facebook::react {
16
16
 
17
17
  void EnrichedMarkdownTextSpec_registerComponentDescriptorsFromCodegen(
18
18
  std::shared_ptr<const ComponentDescriptorProviderRegistry> registry) {
19
- registry->add(concreteComponentDescriptorProvider<EnrichedMarkdownTextComponentDescriptor>());
19
+
20
20
  }
21
21
 
22
22
  } // namespace facebook::react
@@ -16,7 +16,7 @@
16
16
 
17
17
  namespace facebook::react {
18
18
 
19
- using EnrichedMarkdownTextComponentDescriptor = ConcreteComponentDescriptor<EnrichedMarkdownTextShadowNode>;
19
+
20
20
 
21
21
  void EnrichedMarkdownTextSpec_registerComponentDescriptorsFromCodegen(
22
22
  std::shared_ptr<const ComponentDescriptorProviderRegistry> registry);
@@ -13,6 +13,35 @@
13
13
 
14
14
  namespace facebook::react {
15
15
 
16
+ void EnrichedMarkdownEventEmitter::onLinkPress(OnLinkPress event) const {
17
+ dispatchEvent("linkPress", [event=std::move(event)](jsi::Runtime &runtime) {
18
+ auto payload = jsi::Object(runtime);
19
+ payload.setProperty(runtime, "url", event.url);
20
+ return payload;
21
+ });
22
+ }
23
+
24
+
25
+ void EnrichedMarkdownEventEmitter::onLinkLongPress(OnLinkLongPress event) const {
26
+ dispatchEvent("linkLongPress", [event=std::move(event)](jsi::Runtime &runtime) {
27
+ auto payload = jsi::Object(runtime);
28
+ payload.setProperty(runtime, "url", event.url);
29
+ return payload;
30
+ });
31
+ }
32
+
33
+
34
+ void EnrichedMarkdownEventEmitter::onTaskListItemPress(OnTaskListItemPress event) const {
35
+ dispatchEvent("taskListItemPress", [event=std::move(event)](jsi::Runtime &runtime) {
36
+ auto payload = jsi::Object(runtime);
37
+ payload.setProperty(runtime, "index", event.index);
38
+ payload.setProperty(runtime, "checked", event.checked);
39
+ payload.setProperty(runtime, "text", event.text);
40
+ return payload;
41
+ });
42
+ }
43
+
44
+
16
45
  void EnrichedMarkdownTextEventEmitter::onLinkPress(OnLinkPress event) const {
17
46
  dispatchEvent("linkPress", [event=std::move(event)](jsi::Runtime &runtime) {
18
47
  auto payload = jsi::Object(runtime);
@@ -30,4 +59,15 @@ void EnrichedMarkdownTextEventEmitter::onLinkLongPress(OnLinkLongPress event) co
30
59
  });
31
60
  }
32
61
 
62
+
63
+ void EnrichedMarkdownTextEventEmitter::onTaskListItemPress(OnTaskListItemPress event) const {
64
+ dispatchEvent("taskListItemPress", [event=std::move(event)](jsi::Runtime &runtime) {
65
+ auto payload = jsi::Object(runtime);
66
+ payload.setProperty(runtime, "index", event.index);
67
+ payload.setProperty(runtime, "checked", event.checked);
68
+ payload.setProperty(runtime, "text", event.text);
69
+ return payload;
70
+ });
71
+ }
72
+
33
73
  } // namespace facebook::react
@@ -13,6 +13,29 @@
13
13
 
14
14
 
15
15
  namespace facebook::react {
16
+ class EnrichedMarkdownEventEmitter : public ViewEventEmitter {
17
+ public:
18
+ using ViewEventEmitter::ViewEventEmitter;
19
+
20
+ struct OnLinkPress {
21
+ std::string url;
22
+ };
23
+
24
+ struct OnLinkLongPress {
25
+ std::string url;
26
+ };
27
+
28
+ struct OnTaskListItemPress {
29
+ int index;
30
+ bool checked;
31
+ std::string text;
32
+ };
33
+ void onLinkPress(OnLinkPress value) const;
34
+
35
+ void onLinkLongPress(OnLinkLongPress value) const;
36
+
37
+ void onTaskListItemPress(OnTaskListItemPress value) const;
38
+ };
16
39
  class EnrichedMarkdownTextEventEmitter : public ViewEventEmitter {
17
40
  public:
18
41
  using ViewEventEmitter::ViewEventEmitter;
@@ -24,8 +47,16 @@ class EnrichedMarkdownTextEventEmitter : public ViewEventEmitter {
24
47
  struct OnLinkLongPress {
25
48
  std::string url;
26
49
  };
50
+
51
+ struct OnTaskListItemPress {
52
+ int index;
53
+ bool checked;
54
+ std::string text;
55
+ };
27
56
  void onLinkPress(OnLinkPress value) const;
28
57
 
29
58
  void onLinkLongPress(OnLinkLongPress value) const;
59
+
60
+ void onTaskListItemPress(OnTaskListItemPress value) const;
30
61
  };
31
62
  } // namespace facebook::react
@@ -14,6 +14,70 @@
14
14
 
15
15
  namespace facebook::react {
16
16
 
17
+ EnrichedMarkdownProps::EnrichedMarkdownProps(
18
+ const PropsParserContext &context,
19
+ const EnrichedMarkdownProps &sourceProps,
20
+ const RawProps &rawProps): ViewProps(context, sourceProps, rawProps),
21
+
22
+ markdown(convertRawProp(context, rawProps, "markdown", sourceProps.markdown, {})),
23
+ markdownStyle(convertRawProp(context, rawProps, "markdownStyle", sourceProps.markdownStyle, {})),
24
+ enableLinkPreview(convertRawProp(context, rawProps, "enableLinkPreview", sourceProps.enableLinkPreview, {true})),
25
+ selectable(convertRawProp(context, rawProps, "selectable", sourceProps.selectable, {false})),
26
+ md4cFlags(convertRawProp(context, rawProps, "md4cFlags", sourceProps.md4cFlags, {})),
27
+ allowFontScaling(convertRawProp(context, rawProps, "allowFontScaling", sourceProps.allowFontScaling, {true})),
28
+ maxFontSizeMultiplier(convertRawProp(context, rawProps, "maxFontSizeMultiplier", sourceProps.maxFontSizeMultiplier, {0.0})),
29
+ allowTrailingMargin(convertRawProp(context, rawProps, "allowTrailingMargin", sourceProps.allowTrailingMargin, {false})) {}
30
+
31
+ #ifdef RN_SERIALIZABLE_STATE
32
+ ComponentName EnrichedMarkdownProps::getDiffPropsImplementationTarget() const {
33
+ return "EnrichedMarkdown";
34
+ }
35
+
36
+ folly::dynamic EnrichedMarkdownProps::getDiffProps(
37
+ const Props* prevProps) const {
38
+ static const auto defaultProps = EnrichedMarkdownProps();
39
+ const EnrichedMarkdownProps* oldProps = prevProps == nullptr
40
+ ? &defaultProps
41
+ : static_cast<const EnrichedMarkdownProps*>(prevProps);
42
+ if (this == oldProps) {
43
+ return folly::dynamic::object();
44
+ }
45
+ folly::dynamic result = HostPlatformViewProps::getDiffProps(prevProps);
46
+
47
+ if (markdown != oldProps->markdown) {
48
+ result["markdown"] = markdown;
49
+ }
50
+
51
+ if (markdownStyle != oldProps->markdownStyle) {
52
+ result["markdownStyle"] = toDynamic(markdownStyle);
53
+ }
54
+
55
+ if (enableLinkPreview != oldProps->enableLinkPreview) {
56
+ result["enableLinkPreview"] = enableLinkPreview;
57
+ }
58
+
59
+ if (selectable != oldProps->selectable) {
60
+ result["selectable"] = selectable;
61
+ }
62
+
63
+ if (md4cFlags != oldProps->md4cFlags) {
64
+ result["md4cFlags"] = toDynamic(md4cFlags);
65
+ }
66
+
67
+ if (allowFontScaling != oldProps->allowFontScaling) {
68
+ result["allowFontScaling"] = allowFontScaling;
69
+ }
70
+
71
+ if ((maxFontSizeMultiplier != oldProps->maxFontSizeMultiplier) && !(std::isnan(maxFontSizeMultiplier) && std::isnan(oldProps->maxFontSizeMultiplier))) {
72
+ result["maxFontSizeMultiplier"] = maxFontSizeMultiplier;
73
+ }
74
+
75
+ if (allowTrailingMargin != oldProps->allowTrailingMargin) {
76
+ result["allowTrailingMargin"] = allowTrailingMargin;
77
+ }
78
+ return result;
79
+ }
80
+ #endif
17
81
  EnrichedMarkdownTextProps::EnrichedMarkdownTextProps(
18
82
  const PropsParserContext &context,
19
83
  const EnrichedMarkdownTextProps &sourceProps,