react-native-enriched-markdown 0.2.0 → 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.
- package/README.md +117 -13
- package/android/build.gradle +1 -0
- package/android/consumer-rules.pro +8 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +54 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +26 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +1 -1
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.h +1 -1
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +40 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +31 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +64 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +1813 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.cpp +1 -1
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.h +0 -9
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/States.h +1 -1
- package/android/src/main/baseline-prof.txt +32 -3
- package/android/src/main/cpp/jni-adapter.cpp +12 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +332 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +70 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +189 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +21 -49
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +31 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextPackage.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +136 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/events/TaskListItemPressEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +3 -8
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +82 -14
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +26 -35
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +2 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +4 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +6 -8
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +130 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +6 -11
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeStyle.kt +4 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkStyle.kt +3 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +53 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/TaskListStyle.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/CheckboxTouchHelper.kt +52 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/ContextMenuPopup.kt +214 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/HTMLGenerator.kt +198 -15
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/MarkdownASTSerializer.kt +97 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/MarkdownExtractor.kt +10 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/MarkdownTextViewUtils.kt +43 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/SelectionActionMode.kt +17 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/TaskListTapUtils.kt +82 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/Utils.kt +8 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockSegmentView.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +465 -0
- package/android/src/main/jni/EnrichedMarkdownTextSpec.h +1 -11
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.h +48 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerComponentDescriptor.h +26 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerMeasurementManager.cpp +45 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerMeasurementManager.h +21 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +20 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +34 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +10 -1
- package/cpp/parser/MD4CParser.cpp +71 -2
- package/cpp/parser/MarkdownASTNode.hpp +7 -1
- package/ios/EnrichedMarkdown.h +18 -0
- package/ios/EnrichedMarkdown.mm +623 -0
- package/ios/EnrichedMarkdownText.mm +75 -944
- package/ios/generated/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +1 -1
- package/ios/generated/EnrichedMarkdownTextSpec/ComponentDescriptors.h +1 -1
- package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.cpp +40 -0
- package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.h +31 -0
- package/ios/generated/EnrichedMarkdownTextSpec/Props.cpp +64 -0
- package/ios/generated/EnrichedMarkdownTextSpec/Props.h +1813 -0
- package/ios/generated/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +4 -0
- package/ios/generated/EnrichedMarkdownTextSpec/ShadowNodes.cpp +1 -1
- package/ios/generated/EnrichedMarkdownTextSpec/ShadowNodes.h +0 -9
- package/ios/generated/EnrichedMarkdownTextSpec/States.h +1 -1
- package/ios/internals/EnrichedMarkdownComponentDescriptor.h +18 -0
- package/ios/internals/EnrichedMarkdownShadowNode.h +41 -0
- package/ios/internals/EnrichedMarkdownShadowNode.mm +84 -0
- package/ios/internals/EnrichedMarkdownState.h +23 -0
- package/ios/parser/{MarkdownParser.h → ENRMMarkdownParser.h} +4 -4
- package/ios/parser/{MarkdownParser.mm → ENRMMarkdownParser.mm} +9 -9
- package/ios/parser/MarkdownASTNode.h +7 -1
- package/ios/parser/MarkdownParserBridge.mm +20 -2
- package/ios/renderer/CodeBlockRenderer.m +5 -1
- package/ios/renderer/CodeRenderer.m +2 -1
- package/ios/renderer/LinkRenderer.m +18 -0
- package/ios/renderer/ListItemRenderer.h +4 -1
- package/ios/renderer/ListItemRenderer.m +71 -4
- package/ios/renderer/RenderContext.h +4 -0
- package/ios/renderer/RenderContext.m +14 -0
- package/ios/renderer/RendererFactory.m +7 -0
- package/ios/styles/StyleConfig.h +56 -0
- package/ios/styles/StyleConfig.mm +374 -0
- package/ios/utils/BlockquoteBorder.m +6 -1
- package/ios/utils/FontScaleObserver.h +10 -0
- package/ios/utils/FontScaleObserver.m +47 -0
- package/ios/utils/HTMLGenerator.h +3 -0
- package/ios/utils/HTMLGenerator.m +190 -21
- package/ios/utils/LinkTapUtils.h +21 -0
- package/ios/utils/LinkTapUtils.m +28 -0
- package/ios/utils/ListMarkerDrawer.m +81 -9
- package/ios/utils/MarkdownASTSerializer.h +24 -0
- package/ios/utils/MarkdownASTSerializer.m +96 -0
- package/ios/utils/MarkdownAccessibilityElementBuilder.h +7 -0
- package/ios/utils/MarkdownAccessibilityElementBuilder.m +22 -0
- package/ios/utils/MarkdownExtractor.m +18 -7
- package/ios/utils/ParagraphStyleUtils.h +1 -0
- package/ios/utils/ParagraphStyleUtils.m +16 -6
- package/ios/utils/StylePropsUtils.h +932 -0
- package/ios/utils/TaskListTapUtils.h +31 -0
- package/ios/utils/TaskListTapUtils.m +93 -0
- package/ios/views/EnrichedMarkdownInternalText.h +30 -0
- package/ios/views/EnrichedMarkdownInternalText.m +156 -0
- package/ios/views/TableContainerView.h +31 -0
- package/ios/views/TableContainerView.m +535 -0
- package/lib/module/EnrichedMarkdownNativeComponent.ts +250 -0
- package/lib/module/EnrichedMarkdownText.js +30 -6
- package/lib/module/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +41 -1
- package/lib/module/normalizeMarkdownStyle.js +70 -7
- package/lib/module/normalizeMarkdownStyle.js.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +220 -0
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/EnrichedMarkdownText.d.ts +45 -3
- package/lib/typescript/src/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +35 -0
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
- package/package.json +4 -1
- package/react-native.config.js +4 -1
- package/src/EnrichedMarkdownNativeComponent.ts +250 -0
- package/src/EnrichedMarkdownText.tsx +76 -15
- package/src/EnrichedMarkdownTextNativeComponent.ts +41 -1
- package/src/index.tsx +1 -0
- 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,10 +31,12 @@ 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)
|
|
35
38
|
- [Contributing](#contributing)
|
|
39
|
+
- [Future Plans](#future-plans)
|
|
36
40
|
- [License](#license)
|
|
37
41
|
|
|
38
42
|
## Prerequisites
|
|
@@ -88,7 +92,7 @@ npx expo prebuild
|
|
|
88
92
|
|
|
89
93
|
## Usage
|
|
90
94
|
|
|
91
|
-
|
|
95
|
+
### CommonMark (default)
|
|
92
96
|
|
|
93
97
|
```tsx
|
|
94
98
|
import { EnrichedMarkdownText } from 'react-native-enriched-markdown';
|
|
@@ -102,27 +106,43 @@ This is a paragraph with **bold**, *italic*, and [links](https://reactnative.dev
|
|
|
102
106
|
- List item one
|
|
103
107
|
- List item two
|
|
104
108
|
- Nested item
|
|
105
|
-
|
|
106
|
-
\`\`\`javascript
|
|
107
|
-
const greeting = 'Hello, World!';
|
|
108
|
-
console.log(greeting);
|
|
109
|
-
\`\`\`
|
|
110
109
|
`;
|
|
111
110
|
|
|
112
111
|
export default function App() {
|
|
113
|
-
const handleLinkPress = (event: { nativeEvent: { url: string } }) => {
|
|
114
|
-
Linking.openURL(event.nativeEvent.url);
|
|
115
|
-
};
|
|
116
|
-
|
|
117
112
|
return (
|
|
118
113
|
<EnrichedMarkdownText
|
|
119
114
|
markdown={markdown}
|
|
120
|
-
onLinkPress={
|
|
115
|
+
onLinkPress={({ url }) => Linking.openURL(url)}
|
|
121
116
|
/>
|
|
122
117
|
);
|
|
123
118
|
}
|
|
124
119
|
```
|
|
125
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
|
+
|
|
126
146
|
## Supported Markdown Elements
|
|
127
147
|
|
|
128
148
|
`react-native-enriched-markdown` supports a comprehensive set of Markdown elements:
|
|
@@ -137,8 +157,10 @@ export default function App() {
|
|
|
137
157
|
| Code Blocks | ` ``` code ``` ` | Multi-line code blocks |
|
|
138
158
|
| Unordered Lists | `- Item`, `* Item`, or `+ Item` | Bullet lists with unlimited nesting |
|
|
139
159
|
| Ordered Lists | `1. Item` | Numbered lists with unlimited nesting |
|
|
160
|
+
| Task Lists | `- [x] Done`, `- [ ] Todo` | Interactive checkboxes (requires `flavor="github"`) |
|
|
140
161
|
| Thematic Break | `---`, `***`, or `___` | Visual separator line |
|
|
141
162
|
| Images | `` | Block-level images |
|
|
163
|
+
| Tables | `| col | col |` | GFM tables with alignment support (requires `flavor="github"`) |
|
|
142
164
|
|
|
143
165
|
### Inline Elements
|
|
144
166
|
|
|
@@ -255,6 +277,36 @@ When selecting text that contains images, a **Copy Image URL** option appears to
|
|
|
255
277
|
| **List items** | Position announced (e.g., "bullet point", "list item 1") | Position announced |
|
|
256
278
|
| **Nested lists** | Proper depth handling | "Nested" prefix for deeper items |
|
|
257
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
|
+
|
|
258
310
|
## Styling Architecture
|
|
259
311
|
|
|
260
312
|
Understanding how `react-native-enriched-markdown` handles styling helps you create consistent, well-designed Markdown content.
|
|
@@ -274,6 +326,8 @@ Block elements are structural containers that define the layout. Each block has
|
|
|
274
326
|
| `blockquote` | Quoted content with accent bar |
|
|
275
327
|
| `list` | Ordered and unordered lists |
|
|
276
328
|
| `codeBlock` | Multi-line code containers |
|
|
329
|
+
| `table` | GFM tables (requires `flavor="github"`) |
|
|
330
|
+
| `taskList` | Task list checkboxes |
|
|
277
331
|
|
|
278
332
|
#### Inline Elements
|
|
279
333
|
|
|
@@ -285,8 +339,8 @@ Inline elements modify text within blocks. They inherit the parent block's base
|
|
|
285
339
|
| `em` | Parent block | Italic style, optional color |
|
|
286
340
|
| `strikethrough` | Parent block | Strike line with custom color (iOS only) |
|
|
287
341
|
| `underline` | Parent block | Underline with custom color (iOS only) |
|
|
288
|
-
| `code` | Parent block | Monospace font, background |
|
|
289
|
-
| `link` | Parent block |
|
|
342
|
+
| `code` | Parent block | Monospace font, background, optional fontSize |
|
|
343
|
+
| `link` | Parent block | Optional font family, color, underline |
|
|
290
344
|
|
|
291
345
|
### Style Inheritance
|
|
292
346
|
|
|
@@ -365,10 +419,12 @@ The library provides sensible default styles for all Markdown elements out of th
|
|
|
365
419
|
color: '#333',
|
|
366
420
|
},
|
|
367
421
|
link: {
|
|
422
|
+
fontFamily: 'System-Bold',
|
|
368
423
|
color: '#007AFF',
|
|
369
424
|
underline: true,
|
|
370
425
|
},
|
|
371
426
|
code: {
|
|
427
|
+
fontSize: 16,
|
|
372
428
|
color: '#E91E63',
|
|
373
429
|
backgroundColor: '#F5F5F5',
|
|
374
430
|
borderColor: '#E0E0E0',
|
|
@@ -403,6 +459,12 @@ The library provides sensible default styles for all Markdown elements out of th
|
|
|
403
459
|
inlineImage: {
|
|
404
460
|
size: 20,
|
|
405
461
|
},
|
|
462
|
+
taskList: {
|
|
463
|
+
checkedColor: '#2196F3',
|
|
464
|
+
borderColor: '#9E9E9E',
|
|
465
|
+
checkmarkColor: '#FFFFFF',
|
|
466
|
+
checkboxSize: 16,
|
|
467
|
+
},
|
|
406
468
|
}}
|
|
407
469
|
/>
|
|
408
470
|
```
|
|
@@ -472,6 +534,7 @@ The library provides sensible default styles for all Markdown elements out of th
|
|
|
472
534
|
|
|
473
535
|
| Property | Type | Description |
|
|
474
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 |
|
|
475
538
|
| `color` | `string` | Text color |
|
|
476
539
|
| `backgroundColor` | `string` | Background color |
|
|
477
540
|
| `borderColor` | `string` | Border color |
|
|
@@ -480,6 +543,7 @@ The library provides sensible default styles for all Markdown elements out of th
|
|
|
480
543
|
|
|
481
544
|
| Property | Type | Description |
|
|
482
545
|
|----------|------|-------------|
|
|
546
|
+
| `fontFamily` | `string` | Font family for links. Overrides the parent block's font family when set |
|
|
483
547
|
| `color` | `string` | Link text color |
|
|
484
548
|
| `underline` | `boolean` | Show underline |
|
|
485
549
|
|
|
@@ -519,6 +583,35 @@ The library provides sensible default styles for all Markdown elements out of th
|
|
|
519
583
|
| `marginTop` | `number` | Top margin |
|
|
520
584
|
| `marginBottom` | `number` | Bottom margin |
|
|
521
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
|
+
|
|
522
615
|
## API Reference
|
|
523
616
|
|
|
524
617
|
### Props
|
|
@@ -530,12 +623,23 @@ The library provides sensible default styles for all Markdown elements out of th
|
|
|
530
623
|
| `containerStyle` | `ViewStyle` | - | Style for the container view |
|
|
531
624
|
| `onLinkPress` | `(event: LinkPressEvent) => void` | - | Callback when a link is pressed. Access URL via `event.url` |
|
|
532
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) |
|
|
533
627
|
| `enableLinkPreview` | `boolean` | `true` | Controls the native link preview on long press (iOS only). Automatically set to `false` when `onLinkLongPress` is provided |
|
|
534
628
|
| `selectable` | `boolean` | `true` | Whether text can be selected |
|
|
535
629
|
| `md4cFlags` | `Md4cFlags` | `{ underline: false }` | Configuration for md4c parser extension flags |
|
|
536
630
|
| `allowFontScaling` | `boolean` | `true` | Whether fonts should scale to respect Text Size accessibility settings |
|
|
537
631
|
| `maxFontSizeMultiplier` | `number` | `undefined` | Maximum font scale multiplier when `allowFontScaling` is enabled |
|
|
538
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 |
|
|
634
|
+
|
|
635
|
+
## Future Plans
|
|
636
|
+
|
|
637
|
+
We're actively working on expanding the capabilities of `react-native-enriched-markdown`. Here's what's on the roadmap:
|
|
638
|
+
|
|
639
|
+
- GFM (GitHub Flavored Markdown) Support
|
|
640
|
+
- LaTeX / Math Rendering
|
|
641
|
+
- `EnrichedMarkdownInput`
|
|
642
|
+
- Web Implementation via `react-native-web`
|
|
539
643
|
|
|
540
644
|
## Contributing
|
|
541
645
|
|
package/android/build.gradle
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# ProGuard/R8 consumer rules for react-native-enriched-markdown
|
|
2
|
+
#
|
|
3
|
+
# JNI: Classes accessed from C++ (jni-adapter.cpp) via FindClass/GetFieldID.
|
|
4
|
+
# R8 cannot trace hardcoded string lookups in native code.
|
|
5
|
+
|
|
6
|
+
-keep class com.swmansion.enriched.markdown.parser.MarkdownASTNode { *; }
|
|
7
|
+
-keep class com.swmansion.enriched.markdown.parser.MarkdownASTNode$NodeType { *; }
|
|
8
|
+
-keep class com.swmansion.enriched.markdown.parser.Md4cFlags { *; }
|
package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java
ADDED
|
@@ -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
|
+
}
|
package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java
ADDED
|
@@ -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
|
-
|
|
19
|
+
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
} // namespace facebook::react
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
namespace facebook::react {
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
|
|
21
21
|
void EnrichedMarkdownTextSpec_registerComponentDescriptorsFromCodegen(
|
|
22
22
|
std::shared_ptr<const ComponentDescriptorProviderRegistry> registry);
|
package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp
CHANGED
|
@@ -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
|
package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h
CHANGED
|
@@ -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,
|