react-native-enriched-markdown 0.7.0 → 0.7.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 (37) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +215 -0
  3. package/app.plugin.js +2 -1
  4. package/docs/ACCESSIBILITY.md +172 -0
  5. package/docs/API_REFERENCE.md +948 -0
  6. package/docs/COPY_OPTIONS.md +127 -0
  7. package/docs/ELEMENTS_STRUCTURE.md +112 -0
  8. package/docs/IMAGE_CACHING.md +25 -0
  9. package/docs/INPUT.md +233 -0
  10. package/docs/LATEX_MATH.md +136 -0
  11. package/docs/MACOS.md +19 -0
  12. package/docs/MARKDOWN_STREAMING.md +36 -0
  13. package/docs/MENTIONS.md +97 -0
  14. package/docs/RTL.md +82 -0
  15. package/docs/STYLES.md +519 -0
  16. package/docs/TEXT.md +110 -0
  17. package/docs/WEB.md +49 -0
  18. package/package.json +7 -4
  19. package/plugin/build/withAndroidMath.js +19 -0
  20. package/plugin/build/withIosMath.js +28 -0
  21. package/plugin/build/withReactNativeEnrichedMarkdown.js +11 -0
  22. package/plugin/tsconfig.build.json +16 -0
  23. package/lib/module/plugin/withAndroidMath.js +0 -20
  24. package/lib/module/plugin/withAndroidMath.js.map +0 -1
  25. package/lib/module/plugin/withIosMath.js +0 -23
  26. package/lib/module/plugin/withIosMath.js.map +0 -1
  27. package/lib/module/plugin/withReactNativeEnrichedMarkdown.js +0 -16
  28. package/lib/module/plugin/withReactNativeEnrichedMarkdown.js.map +0 -1
  29. package/lib/typescript/src/plugin/withAndroidMath.d.ts +0 -5
  30. package/lib/typescript/src/plugin/withAndroidMath.d.ts.map +0 -1
  31. package/lib/typescript/src/plugin/withIosMath.d.ts +0 -5
  32. package/lib/typescript/src/plugin/withIosMath.d.ts.map +0 -1
  33. package/lib/typescript/src/plugin/withReactNativeEnrichedMarkdown.d.ts +0 -6
  34. package/lib/typescript/src/plugin/withReactNativeEnrichedMarkdown.d.ts.map +0 -1
  35. /package/{src/plugin → plugin/src}/withAndroidMath.ts +0 -0
  36. /package/{src/plugin → plugin/src}/withIosMath.ts +0 -0
  37. /package/{src/plugin → plugin/src}/withReactNativeEnrichedMarkdown.ts +0 -0
package/docs/STYLES.md ADDED
@@ -0,0 +1,519 @@
1
+ # Style Properties Reference
2
+
3
+ This document provides a comprehensive reference for all style properties available in `react-native-enriched-markdown`.
4
+
5
+ ## Platform Defaults
6
+
7
+ The library provides sensible defaults optimized for each platform:
8
+
9
+ | Property | iOS | Android |
10
+ |----------|-----|---------|
11
+ | System Font | SF Pro | Roboto |
12
+ | Monospace Font | Menlo | monospace |
13
+ | Line Height | Tighter (0.75x multiplier) | Standard |
14
+
15
+ ## Style Inheritance
16
+
17
+ `react-native-enriched-markdown` uses a base block style architecture where all block elements (paragraphs, headings, lists, blockquotes, code blocks) share a common set of typography properties. This base block style includes:
18
+
19
+ - `fontSize` - Font size in points
20
+ - `fontFamily` - Font family name
21
+ - `fontWeight` - Font weight
22
+ - `color` - Text color
23
+ - `marginTop` - Top margin
24
+ - `marginBottom` - Bottom margin
25
+ - `lineHeight` - Line height
26
+
27
+ Each block type extends this base style with its own specific properties (e.g., `textAlign` for paragraphs and headings, `borderColor` for blockquotes, `bulletColor` for lists).
28
+
29
+ ### Inline Style Inheritance
30
+
31
+ Inline styles (strong, emphasis, links, inline code, etc.) automatically inherit the base typography properties from their containing block. This means inline elements use the block's `fontSize`, `fontFamily`, `fontWeight`, and `color` as their foundation, then apply their own additional styling on top.
32
+
33
+ **Example:**
34
+
35
+ ```
36
+ Heading (h2: fontSize 24, color blue)
37
+ └── Strong text inherits → fontSize 24, color blue + bold weight
38
+ └── Link inherits → fontSize 24 + link color + underline
39
+
40
+ List item (list: fontSize 16, color gray)
41
+ └── Emphasis inherits → fontSize 16, color gray + italic style
42
+ └── Inline code inherits → fontSize 16 + code background
43
+ ```
44
+
45
+ This inheritance model ensures consistent typography throughout your Markdown content while allowing inline elements to add their own visual emphasis.
46
+
47
+ ### Custom Font Family for Inline Styles
48
+
49
+ Strong, emphasis, and inline code support an optional `fontFamily` property that gives you full control over the font face used for that element.
50
+
51
+ **Default behavior (no `fontFamily` set):**
52
+ - **Strong** — adds the bold trait to the current block font
53
+ - **Emphasis** — adds the italic trait to the current block font
54
+ - **Inline code** — uses the platform's system monospace font (SF Mono on iOS, monospace on Android)
55
+
56
+ **With `fontFamily` set:**
57
+
58
+ By default, bold/italic traits are still applied on top of the custom font family. Use `fontWeight: 'normal'` or `fontStyle: 'normal'` to disable this and use the font face exactly as-is:
59
+
60
+ ```tsx
61
+ markdownStyle={{
62
+ strong: {
63
+ // Bold trait is applied on top of Montserrat-Bold (default: fontWeight 'bold')
64
+ fontFamily: 'Montserrat-Bold',
65
+ },
66
+ strong: {
67
+ // Uses Montserrat-SemiBold as-is, no bold trait added
68
+ fontFamily: 'Montserrat-SemiBold',
69
+ fontWeight: 'normal',
70
+ },
71
+ em: {
72
+ // Italic trait is applied on top of Montserrat-Italic (default: fontStyle 'italic')
73
+ fontFamily: 'Montserrat-Italic',
74
+ },
75
+ em: {
76
+ // Uses Montserrat-Regular as-is, no italic trait added
77
+ fontFamily: 'Montserrat-Regular',
78
+ fontStyle: 'normal',
79
+ },
80
+ code: {
81
+ // Uses CutiveMono-Regular directly, no system monospace applied
82
+ fontFamily: 'CutiveMono-Regular',
83
+ },
84
+ }}
85
+ ```
86
+
87
+ ## Customizing Styles
88
+
89
+ The library provides sensible default styles for all Markdown elements out of the box. You can override any of these defaults using the `markdownStyle` prop — only specify the properties you want to change:
90
+
91
+ ```tsx
92
+ <EnrichedMarkdownText
93
+ markdown={content}
94
+ markdownStyle={{
95
+ paragraph: {
96
+ fontSize: 16,
97
+ color: '#333',
98
+ lineHeight: 24,
99
+ },
100
+ h1: {
101
+ fontSize: 32,
102
+ fontWeight: 'bold',
103
+ color: '#000',
104
+ marginBottom: 16,
105
+ textAlign: 'center',
106
+ },
107
+ h2: {
108
+ fontSize: 24,
109
+ fontWeight: '600',
110
+ marginBottom: 12,
111
+ textAlign: 'left',
112
+ },
113
+ strong: {
114
+ fontFamily: 'Montserrat-Bold',
115
+ color: '#000',
116
+ },
117
+ em: {
118
+ fontFamily: 'Montserrat-Italic',
119
+ color: '#666',
120
+ },
121
+ strikethrough: {
122
+ color: '#999',
123
+ },
124
+ underline: {
125
+ color: '#333',
126
+ },
127
+ link: {
128
+ fontFamily: 'System-Bold',
129
+ color: '#007AFF',
130
+ underline: true,
131
+ },
132
+ code: {
133
+ fontFamily: 'CutiveMono-Regular',
134
+ fontSize: 16,
135
+ color: '#E91E63',
136
+ backgroundColor: '#F5F5F5',
137
+ borderColor: '#E0E0E0',
138
+ },
139
+ codeBlock: {
140
+ fontSize: 14,
141
+ fontFamily: 'monospace',
142
+ backgroundColor: '#1E1E1E',
143
+ color: '#D4D4D4',
144
+ padding: 16,
145
+ borderRadius: 8,
146
+ marginBottom: 16,
147
+ },
148
+ blockquote: {
149
+ borderColor: '#007AFF',
150
+ borderWidth: 3,
151
+ backgroundColor: '#F0F8FF',
152
+ marginBottom: 12,
153
+ },
154
+ list: {
155
+ fontSize: 16,
156
+ bulletColor: '#007AFF',
157
+ bulletSize: 6,
158
+ markerColor: '#007AFF',
159
+ gapWidth: 8,
160
+ marginLeft: 20,
161
+ },
162
+ image: {
163
+ borderRadius: 8,
164
+ marginBottom: 12,
165
+ },
166
+ inlineImage: {
167
+ size: 20,
168
+ },
169
+ taskList: {
170
+ checkedColor: '#2196F3',
171
+ borderColor: '#9E9E9E',
172
+ checkmarkColor: '#FFFFFF',
173
+ checkboxSize: 16,
174
+ },
175
+ math: {
176
+ fontSize: 20,
177
+ color: '#1F2937',
178
+ backgroundColor: '#F3F4F6',
179
+ padding: 12,
180
+ marginBottom: 16,
181
+ textAlign: 'center',
182
+ },
183
+ inlineMath: {
184
+ color: '#1F2937',
185
+ },
186
+ spoiler: {
187
+ color: '#6B7280',
188
+ particles: { density: 10, speed: 25 },
189
+ solid: { borderRadius: 6 },
190
+ },
191
+ superscript: {
192
+ fontScale: 0.75,
193
+ baselineOffsetScale: 0.35,
194
+ },
195
+ subscript: {
196
+ fontScale: 0.75,
197
+ baselineOffsetScale: 0.20,
198
+ },
199
+ highlight: {
200
+ backgroundColor: '#FEF08A',
201
+ },
202
+ }}
203
+ />
204
+ ```
205
+
206
+ > [!NOTE]
207
+ > **Performance:** Memoize the `markdownStyle` prop with `useMemo` to avoid unnecessary re-renders:
208
+ > ```tsx
209
+ > import type { MarkdownStyle } from 'react-native-enriched-markdown';
210
+ >
211
+ > const markdownStyle: MarkdownStyle = useMemo(() => ({
212
+ > paragraph: { fontSize: 16 },
213
+ > h1: { fontSize: 32 },
214
+ > }), []);
215
+ > ```
216
+
217
+ ## Dark Mode
218
+
219
+ The library ships with light-mode color defaults. It does not include a `colorScheme` prop — just like React Native's `Text`, theming is left to the consumer.
220
+
221
+ To support dark mode, create `MarkdownStyle` objects for each color scheme and switch between them using `useColorScheme()`. Your values always win over the defaults — you only need to specify the colors you want to change:
222
+
223
+ ```tsx
224
+ import { useColorScheme } from 'react-native';
225
+ import { EnrichedMarkdownText } from 'react-native-enriched-markdown';
226
+ import type { MarkdownStyle } from 'react-native-enriched-markdown';
227
+
228
+ const lightMarkdownStyle: MarkdownStyle = {
229
+ blockquote: { backgroundColor: '#F9FAFB', borderColor: '#D1D5DB' },
230
+ code: { color: '#E01E5A', backgroundColor: '#FDF2F4' },
231
+ table: {
232
+ headerBackgroundColor: '#F3F4F6',
233
+ rowEvenBackgroundColor: '#FFFFFF',
234
+ rowOddBackgroundColor: '#F9FAFB',
235
+ },
236
+ // ... override any other colors for light mode
237
+ };
238
+
239
+ const darkMarkdownStyle: MarkdownStyle = {
240
+ paragraph: { color: '#E5E7EB' },
241
+ blockquote: { backgroundColor: '#1F2937', borderColor: '#4B5563' },
242
+ code: { color: '#F87171', backgroundColor: '#1F2937' },
243
+ table: {
244
+ headerBackgroundColor: '#1F2937',
245
+ rowEvenBackgroundColor: '#111827',
246
+ rowOddBackgroundColor: '#1A1A2E',
247
+ borderColor: '#374151',
248
+ },
249
+ // ... override any other colors for dark mode
250
+ };
251
+
252
+ function App() {
253
+ const colorScheme = useColorScheme();
254
+
255
+ return (
256
+ <EnrichedMarkdownText
257
+ markdown={content}
258
+ markdownStyle={colorScheme === 'dark' ? darkMarkdownStyle : lightMarkdownStyle}
259
+ />
260
+ );
261
+ }
262
+ ```
263
+
264
+ > [!NOTE]
265
+ > **Performance:** Define style objects outside the component (as shown above) or wrap them in `useMemo` so the same object reference is reused across renders.
266
+
267
+ ## Style Properties Reference
268
+
269
+ ### Block Styles (paragraph, h1-h6, blockquote, list, codeBlock)
270
+
271
+ | Property | Type | Description |
272
+ |----------|------|-------------|
273
+ | `fontSize` | `number` | Font size in points |
274
+ | `fontFamily` | `string` | Font family name |
275
+ | `fontWeight` | `string` | Font weight |
276
+ | `color` | `string` | Text color |
277
+ | `marginTop` | `number` | Top margin |
278
+ | `marginBottom` | `number` | Bottom margin |
279
+ | `lineHeight` | `number` | Line height |
280
+
281
+ ### Paragraph and Heading-specific (paragraph, h1-h6)
282
+
283
+ | Property | Type | Description |
284
+ |----------|------|-------------|
285
+ | `textAlign` | `'auto' \| 'left' \| 'right' \| 'center' \| 'justify'` | Text alignment (default: `'left'`) |
286
+
287
+ ### Blockquote-specific
288
+
289
+ | Property | Type | Description |
290
+ |----------|------|-------------|
291
+ | `borderColor` | `string` | Left border color |
292
+ | `borderWidth` | `number` | Left border width |
293
+ | `gapWidth` | `number` | Gap between border and text |
294
+ | `backgroundColor` | `string` | Background color |
295
+
296
+ ### List-specific
297
+
298
+ | Property | Type | Description |
299
+ |----------|------|-------------|
300
+ | `bulletColor` | `string` | Bullet point color |
301
+ | `bulletSize` | `number` | Bullet point size |
302
+ | `markerMinWidth` | `number` | Minimum reserved marker column width (floors the natural width of every list type) |
303
+ | `markerColor` | `string` | Number marker color |
304
+ | `markerFontWeight` | `string` | Number marker font weight |
305
+ | `gapWidth` | `number` | Gap between marker and text |
306
+ | `marginLeft` | `number` | Left margin for nesting |
307
+
308
+ ### Code Block-specific
309
+
310
+ | Property | Type | Description |
311
+ |----------|------|-------------|
312
+ | `backgroundColor` | `string` | Background color |
313
+ | `borderColor` | `string` | Border color |
314
+ | `borderRadius` | `number` | Corner radius |
315
+ | `borderWidth` | `number` | Border width |
316
+ | `padding` | `number` | Inner padding |
317
+
318
+ ### Inline Code-specific
319
+
320
+ | Property | Type | Description |
321
+ |----------|------|-------------|
322
+ | `fontFamily` | `string` | Font family for inline code. Uses the exact font face as-is. When not set, uses the platform's system monospace font (SF Mono on iOS, monospace on Android) |
323
+ | `fontSize` | `number` | Font size in points. Defaults to the parent block's font size (1em). Set to customize the monospaced font size independently |
324
+ | `color` | `string` | Text color |
325
+ | `backgroundColor` | `string` | Background color |
326
+ | `borderColor` | `string` | Border color |
327
+
328
+ ### Link-specific
329
+
330
+ | Property | Type | Description |
331
+ |----------|------|-------------|
332
+ | `fontFamily` | `string` | Font family for links. Overrides the parent block's font family when set |
333
+ | `color` | `string` | Link text color |
334
+ | `underline` | `boolean` | Show underline |
335
+
336
+ ### Strong-specific
337
+
338
+ | Property | Type | Description |
339
+ |----------|------|-------------|
340
+ | `fontFamily` | `string` | Font family for bold text. When not set, adds the bold trait to the parent block's font |
341
+ | `fontWeight` | `'bold' \| 'normal'` | Controls whether bold is applied on top of the custom `fontFamily`. Defaults to `'bold'`. Set to `'normal'` to use the font face as-is. Only relevant when `fontFamily` is set |
342
+ | `color` | `string` | Bold text color |
343
+
344
+ ### Emphasis-specific
345
+
346
+ | Property | Type | Description |
347
+ |----------|------|-------------|
348
+ | `fontFamily` | `string` | Font family for italic text. When not set, adds the italic trait to the parent block's font |
349
+ | `fontStyle` | `'italic' \| 'normal'` | Controls whether italic is applied on top of the custom `fontFamily`. Defaults to `'italic'`. Set to `'normal'` to use the font face as-is. Only relevant when `fontFamily` is set |
350
+ | `color` | `string` | Italic text color |
351
+
352
+ ### Strikethrough-specific
353
+
354
+ | Property | Type | Description |
355
+ |----------|------|-------------|
356
+ | `color` | `string` | Strikethrough line color (iOS only) |
357
+
358
+ ### Underline-specific
359
+
360
+ | Property | Type | Description |
361
+ |----------|------|-------------|
362
+ | `color` | `string` | Underline color (iOS only) |
363
+
364
+ ### Highlight-specific
365
+
366
+ Styles for highlighted text (`==text==`). Requires `md4cFlags={{ highlight: true }}` to enable the parser. Font size, family, and weight inherit from the surrounding block; only `color` and `backgroundColor` are overridden.
367
+
368
+ | Property | Type | Description |
369
+ |----------|------|-------------|
370
+ | `color` | `string` | Text color inside the highlight. Inherits the block color when omitted |
371
+ | `backgroundColor` | `string` | Background color of the highlight span. Default: `#FEF08A` |
372
+
373
+ ```tsx
374
+ <EnrichedMarkdownText
375
+ markdown="This is ==important== text with ==**bold**== inside."
376
+ md4cFlags={{ highlight: true }}
377
+ markdownStyle={{
378
+ highlight: {
379
+ backgroundColor: '#FEF08A',
380
+ },
381
+ }}
382
+ />
383
+ ```
384
+
385
+ > [!NOTE]
386
+ > When `highlight.color` is omitted, it inherits the surrounding block color. When set explicitly, it applies to the entire `==...==` span, including nested bold or italic text. Nested formatting (bold, italic, links) is preserved.
387
+
388
+ ### Image-specific
389
+
390
+ | Property | Type | Description |
391
+ |----------|------|-------------|
392
+ | `height` | `number` | Image height |
393
+ | `borderRadius` | `number` | Corner radius |
394
+ | `marginTop` | `number` | Top margin |
395
+ | `marginBottom` | `number` | Bottom margin |
396
+
397
+ ### Inline Image-specific
398
+
399
+ | Property | Type | Description |
400
+ |----------|------|-------------|
401
+ | `size` | `number` | Image size (square) |
402
+
403
+ ### Thematic Break (Horizontal Rule)-specific
404
+
405
+ | Property | Type | Description |
406
+ |----------|------|-------------|
407
+ | `color` | `string` | Line color |
408
+ | `height` | `number` | Line thickness |
409
+ | `marginTop` | `number` | Top margin |
410
+ | `marginBottom` | `number` | Bottom margin |
411
+
412
+ ### Table-specific
413
+
414
+ 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:
415
+
416
+ | Property | Type | Description |
417
+ |----------|------|-------------|
418
+ | `headerFontFamily` | `string` | Font family for header cells (falls back to `fontFamily` if not set) |
419
+ | `headerBackgroundColor` | `string` | Background color for the header row |
420
+ | `headerTextColor` | `string` | Text color for the header row |
421
+ | `rowEvenBackgroundColor` | `string` | Background color for even data rows |
422
+ | `rowOddBackgroundColor` | `string` | Background color for odd data rows |
423
+ | `borderColor` | `string` | Color of the table grid lines |
424
+ | `borderWidth` | `number` | Width of the table grid lines |
425
+ | `borderRadius` | `number` | Corner radius of the table container |
426
+ | `cellPaddingHorizontal` | `number` | Horizontal padding inside cells |
427
+ | `cellPaddingVertical` | `number` | Vertical padding inside cells |
428
+
429
+ ### Task List-specific
430
+
431
+ | Property | Type | Description |
432
+ |----------|------|-------------|
433
+ | `checkedColor` | `string` | Background color of checked checkbox |
434
+ | `borderColor` | `string` | Border color of unchecked checkbox |
435
+ | `checkmarkColor` | `string` | Color of the checkmark inside checked checkbox |
436
+ | `checkboxSize` | `number` | Size of the checkbox (defaults to 90% of list font size) |
437
+ | `checkboxBorderRadius` | `number` | Corner radius of the checkbox |
438
+ | `checkedTextColor` | `string` | Text color for checked items |
439
+ | `checkedStrikethrough` | `boolean` | Whether to apply strikethrough to checked items |
440
+
441
+ ### Math Block-specific
442
+
443
+ Styles for block-level LaTeX math (`$$...$$`). Block math is rendered as a standalone display element and only applies when `flavor="github"` is set.
444
+
445
+ | Property | Type | Description |
446
+ |----------|------|-------------|
447
+ | `fontSize` | `number` | Font size used when rendering the equation |
448
+ | `color` | `string` | Equation text color |
449
+ | `backgroundColor` | `string` | Background color of the math block container |
450
+ | `padding` | `number` | Inner padding around the equation |
451
+ | `marginTop` | `number` | Top margin |
452
+ | `marginBottom` | `number` | Bottom margin |
453
+ | `textAlign` | `'left' \| 'center' \| 'right'` | Horizontal alignment of the equation (default: `'center'`) |
454
+
455
+ ### Inline Math-specific
456
+
457
+ Styles for inline LaTeX math (`$...$`). Inline math is rendered within the surrounding text flow.
458
+
459
+ | Property | Type | Description |
460
+ |----------|------|-------------|
461
+ | `color` | `string` | Equation text color |
462
+
463
+ ### Spoiler-specific
464
+
465
+ Styles for spoiler text (`||hidden text||`). Spoiler text is concealed behind an overlay (controlled by the `spoilerOverlay` prop) until the user taps to reveal it.
466
+
467
+ | Property | Type | Description |
468
+ |----------|------|-------------|
469
+ | `color` | `string` | Color used by all presets for the spoiler overlay |
470
+ | `particles.density` | `number` | Density of the particle field (higher = more particles). Default: `8` |
471
+ | `particles.speed` | `number` | Speed of particle movement. Default: `20` |
472
+ | `solid.borderRadius` | `number` | Corner radius of the solid spoiler overlay rectangles. Default: `4` |
473
+
474
+ ### Superscript-specific
475
+
476
+ Styles for superscript text (`^text^`). Requires `md4cFlags={{ superscript: true }}` to enable the parser.
477
+
478
+ | Property | Type | Description |
479
+ |----------|------|-------------|
480
+ | `fontScale` | `number` | Font size as a fraction of the surrounding text size. Default: `0.75` (iOS/macOS/web), `0.65` (Android) |
481
+ | `baselineOffsetScale` | `number` | Vertical shift upward as a fraction of the surrounding text size. Default: `0.35` |
482
+
483
+ ```tsx
484
+ <EnrichedMarkdownText
485
+ markdown="E = mc^2^"
486
+ md4cFlags={{ superscript: true }}
487
+ markdownStyle={{
488
+ superscript: {
489
+ fontScale: 0.75,
490
+ baselineOffsetScale: 0.35,
491
+ },
492
+ }}
493
+ />
494
+ ```
495
+
496
+ ### Subscript-specific
497
+
498
+ Styles for subscript text (`~text~`). Requires `md4cFlags={{ subscript: true }}` to enable the parser. Note: enabling subscript changes the behaviour of single tildes — `~text~` becomes subscript instead of strikethrough.
499
+
500
+ | Property | Type | Description |
501
+ |----------|------|-------------|
502
+ | `fontScale` | `number` | Font size as a fraction of the surrounding text size. Default: `0.75` (iOS/macOS/web), `0.65` (Android) |
503
+ | `baselineOffsetScale` | `number` | Vertical shift downward as a fraction of the surrounding text size. Default: `0.20` |
504
+
505
+ ```tsx
506
+ <EnrichedMarkdownText
507
+ markdown="H~2~O"
508
+ md4cFlags={{ subscript: true }}
509
+ markdownStyle={{
510
+ subscript: {
511
+ fontScale: 0.75,
512
+ baselineOffsetScale: 0.20,
513
+ },
514
+ }}
515
+ />
516
+ ```
517
+
518
+ > [!NOTE]
519
+ > Android uses a slightly smaller default `fontScale` (`0.65`) compared to iOS (`0.75`) because Roboto has a larger x-height than San Francisco, making identically-scaled text appear visually larger on Android.
package/docs/TEXT.md ADDED
@@ -0,0 +1,110 @@
1
+ # EnrichedMarkdownText
2
+
3
+ `EnrichedMarkdownText` renders Markdown content as fully native text — no WebView required.
4
+
5
+ ## Usage
6
+
7
+ ### CommonMark (default)
8
+
9
+ ```tsx
10
+ import { EnrichedMarkdownText } from 'react-native-enriched-markdown';
11
+ import { Linking } from 'react-native';
12
+
13
+ const markdown = `
14
+ # Welcome to Markdown!
15
+
16
+ This is a paragraph with **bold**, *italic*, and [links](https://reactnative.dev).
17
+
18
+ - List item one
19
+ - List item two
20
+ - Nested item
21
+ `;
22
+
23
+ export default function App() {
24
+ return (
25
+ <EnrichedMarkdownText
26
+ markdown={markdown}
27
+ onLinkPress={({ url }) => Linking.openURL(url)}
28
+ />
29
+ );
30
+ }
31
+ ```
32
+
33
+ ### GFM (tables)
34
+
35
+ Set `flavor="github"` to enable GitHub Flavored Markdown features like tables and task lists:
36
+
37
+ ```tsx
38
+ <EnrichedMarkdownText
39
+ flavor="github"
40
+ markdown={markdown}
41
+ onLinkPress={({ url }) => Linking.openURL(url)}
42
+ markdownStyle={{
43
+ table: {
44
+ fontSize: 14,
45
+ borderColor: '#E5E7EB',
46
+ borderRadius: 8,
47
+ headerBackgroundColor: '#F3F4F6',
48
+ headerFontFamily: 'System-Bold',
49
+ cellPaddingHorizontal: 12,
50
+ cellPaddingVertical: 8,
51
+ },
52
+ }}
53
+ />
54
+ ```
55
+
56
+ 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".
57
+
58
+ ### Task Lists
59
+
60
+ Task lists with interactive checkboxes are available when `flavor="github"` is set. Handle checkbox taps with `onTaskListItemPress`:
61
+
62
+ ```tsx
63
+ <EnrichedMarkdownText
64
+ flavor="github"
65
+ markdown={`
66
+ - [x] Completed task
67
+ - [ ] Incomplete task
68
+ - [x] Another completed task
69
+ `}
70
+ onTaskListItemPress={({ index, checked, text }) => {
71
+ console.log(
72
+ `Task ${index}: ${checked ? 'checked' : 'unchecked'} - ${text}`
73
+ );
74
+ // Update your state or data model here
75
+ }}
76
+ />
77
+ ```
78
+
79
+ ### Link Handling
80
+
81
+ Links in Markdown are interactive and can be handled with the `onLinkPress` and `onLinkLongPress` callbacks:
82
+
83
+ - **`onLinkPress`**: Fired when a link is tapped. Use this to open URLs or handle link navigation.
84
+ - **`onLinkLongPress`**: Fired when a link is long-pressed. On iOS, providing this callback automatically disables the system link preview so your handler can fire instead.
85
+
86
+ See the [API Reference](API_REFERENCE.md#onlinkpress) for detailed examples and usage.
87
+
88
+ ## Supported Markdown Elements
89
+
90
+ `react-native-enriched-markdown` supports a comprehensive set of Markdown elements. See [Element Structure](ELEMENTS_STRUCTURE.md) for a detailed overview of all supported elements, their syntax, block vs inline categorization, nesting behavior, and how elements inherit typography from their parent blocks.
91
+
92
+ ## Copy Options
93
+
94
+ When text is selected, `react-native-enriched-markdown` provides enhanced copy functionality through the context menu. See [Copy Options](COPY_OPTIONS.md) for details on smart copy, copy as Markdown, and copy image URL features.
95
+
96
+ ## Accessibility
97
+
98
+ `react-native-enriched-markdown` provides comprehensive accessibility support for screen readers on both platforms. See [Accessibility](ACCESSIBILITY.md) for detailed information about VoiceOver and TalkBack support, custom rotors, semantic traits, and best practices.
99
+
100
+ ## RTL Support
101
+
102
+ `react-native-enriched-markdown` fully supports right-to-left (RTL) languages such as Arabic, Hebrew, and Persian. See [RTL Support](RTL.md) for platform-specific setup instructions and how each element behaves in RTL contexts.
103
+
104
+ ## Customizing Styles
105
+
106
+ `react-native-enriched-markdown` allows customizing styles of all Markdown elements using the `markdownStyle` prop. See the [Style Properties Reference](STYLES.md) for a detailed overview of all available style properties.
107
+
108
+ ### Dark Mode
109
+
110
+ The library uses light-mode defaults. To support dark mode, pass a dark `markdownStyle` object — your values always take priority over the defaults. See the [Dark Mode](STYLES.md#dark-mode) section in the Style Properties Reference for a ready-to-use example with `useColorScheme()`.
package/docs/WEB.md ADDED
@@ -0,0 +1,49 @@
1
+ # Web Support
2
+
3
+ `EnrichedMarkdownText` runs on web using [`react-native-web`](https://necolas.github.io/react-native-web/) for the React Native primitives and [md4c](https://github.com/mity/md4c) compiled to WebAssembly for parsing. The WASM binary is bundled in the npm package — no build step is required by consumers.
4
+
5
+ The web renderer uses semantic HTML elements (`<p>`, `<h1>`–`<h6>`, `<blockquote>`, `<ul>`, `<ol>`, `<table>`, etc.) for improved accessibility.
6
+
7
+ ## Supported features
8
+
9
+ All core `EnrichedMarkdownText` features are supported on web, including:
10
+
11
+ - Full GFM: tables (with horizontal scroll), task lists (with checkbox interaction), strikethrough, links, images (block and inline), code blocks, LaTeX math (block and inline)
12
+ - All `markdownStyle` customisation options
13
+ - `onLinkPress`, `onLinkLongPress` (mapped to `contextmenu` event), `onTaskListItemPress` callbacks
14
+ - `allowTrailingMargin`, `containerStyle`, `selectable`, `selectionColor`, `md4cFlags` (`underline`, `superscript`, `subscript`, `latexMath`)
15
+ - RTL support via the `dir` prop (CSS logical properties automatically flip blockquote borders, list indentation, etc.)
16
+
17
+ ### Accessibility
18
+
19
+ - Semantic HTML elements for all markdown structures
20
+ - Images: `alt` text falls back to `title`, then URL filename, then `"Image"`
21
+ - Code blocks: `aria-label` with language when available (e.g. `"Code block: python"`)
22
+ - Math (KaTeX fallback): `role="math"` and `aria-label` with the expression content
23
+ - Task list checkboxes: `aria-label` with the task text (e.g. `"Task: Buy groceries"`)
24
+
25
+ ### Web-only props
26
+
27
+ | Prop | Description |
28
+ |---|---|
29
+ | `dir` | Sets the text direction on the root container (`'ltr'`, `'rtl'`, or `'auto'`). CSS logical properties in the renderers automatically flip layout for RTL. |
30
+
31
+ The web implementation also exports `WebMarkdownTextProps` which extends `EnrichedMarkdownTextProps` with the web-only props above.
32
+
33
+ ## Ignored props (native-only)
34
+
35
+ | Prop | Reason |
36
+ |---|---|
37
+ | `flavor` | The web renderer always uses full GFM capabilities. On native, `flavor` controls whether a single `TextView` (CommonMark) or container-based renderer (GitHub) is used; the DOM has no such constraint. |
38
+ | `enableLinkPreview` | iOS-only feature (native link preview on long press). |
39
+ | `allowFontScaling` / `maxFontSizeMultiplier` | React Native text scaling props. Browsers handle font scaling natively via OS accessibility settings. |
40
+ | `streamingAnimation` | Native-only tail fade-in animation. Not yet implemented on web. |
41
+ | `streamingConfig` | Native-only streaming table configuration. Not yet implemented on web. |
42
+ | `contextMenuItems` | Not supported — browsers don't allow extending the native context menu. |
43
+ | `selectionMenuConfig` | Not supported — native-only built-in selection menu actions. |
44
+ | `selectionHandleColor` | Android-only — desktop browsers don't render selection handles. |
45
+
46
+ ## Not supported on web
47
+
48
+ - `EnrichedMarkdownTextInput` — native-only
49
+ - Configurable link `target` — all links open in a new tab (`target="_blank"`). Use `onLinkPress` for custom navigation.