@neeleshyadav/react-native-html-renderer 1.1.0

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 (155) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +407 -0
  3. package/lib/module/HtmlRenderer.js +183 -0
  4. package/lib/module/HtmlRenderer.js.map +1 -0
  5. package/lib/module/context/index.js +32 -0
  6. package/lib/module/context/index.js.map +1 -0
  7. package/lib/module/hooks/index.js +6 -0
  8. package/lib/module/hooks/index.js.map +1 -0
  9. package/lib/module/hooks/useContentWidth.js +12 -0
  10. package/lib/module/hooks/useContentWidth.js.map +1 -0
  11. package/lib/module/hooks/useHtmlParser.js +16 -0
  12. package/lib/module/hooks/useHtmlParser.js.map +1 -0
  13. package/lib/module/hooks/useTagStyle.js +26 -0
  14. package/lib/module/hooks/useTagStyle.js.map +1 -0
  15. package/lib/module/index.js +23 -0
  16. package/lib/module/index.js.map +1 -0
  17. package/lib/module/package.json +1 -0
  18. package/lib/module/parser/index.js +62 -0
  19. package/lib/module/parser/index.js.map +1 -0
  20. package/lib/module/renderer/ErrorBoundary.js +66 -0
  21. package/lib/module/renderer/ErrorBoundary.js.map +1 -0
  22. package/lib/module/renderer/NodeRenderer.js +279 -0
  23. package/lib/module/renderer/NodeRenderer.js.map +1 -0
  24. package/lib/module/renderer/index.js +5 -0
  25. package/lib/module/renderer/index.js.map +1 -0
  26. package/lib/module/renderer/tags/BlockTags.js +28 -0
  27. package/lib/module/renderer/tags/BlockTags.js.map +1 -0
  28. package/lib/module/renderer/tags/FormTags.js +129 -0
  29. package/lib/module/renderer/tags/FormTags.js.map +1 -0
  30. package/lib/module/renderer/tags/ImageTag.js +163 -0
  31. package/lib/module/renderer/tags/ImageTag.js.map +1 -0
  32. package/lib/module/renderer/tags/LinkTag.js +50 -0
  33. package/lib/module/renderer/tags/LinkTag.js.map +1 -0
  34. package/lib/module/renderer/tags/ListTags.js +96 -0
  35. package/lib/module/renderer/tags/ListTags.js.map +1 -0
  36. package/lib/module/renderer/tags/MediaTags.js +69 -0
  37. package/lib/module/renderer/tags/MediaTags.js.map +1 -0
  38. package/lib/module/renderer/tags/TableTags.js +48 -0
  39. package/lib/module/renderer/tags/TableTags.js.map +1 -0
  40. package/lib/module/renderer/tags/TextTags.js +87 -0
  41. package/lib/module/renderer/tags/TextTags.js.map +1 -0
  42. package/lib/module/renderer/tags/index.js +11 -0
  43. package/lib/module/renderer/tags/index.js.map +1 -0
  44. package/lib/module/styles/cssToRn.js +34 -0
  45. package/lib/module/styles/cssToRn.js.map +1 -0
  46. package/lib/module/styles/darkModeStyles.js +81 -0
  47. package/lib/module/styles/darkModeStyles.js.map +1 -0
  48. package/lib/module/styles/defaultStyles.js +218 -0
  49. package/lib/module/styles/defaultStyles.js.map +1 -0
  50. package/lib/module/styles/index.js +7 -0
  51. package/lib/module/styles/index.js.map +1 -0
  52. package/lib/module/styles/mergeStyles.js +47 -0
  53. package/lib/module/styles/mergeStyles.js.map +1 -0
  54. package/lib/module/types/index.js +4 -0
  55. package/lib/module/types/index.js.map +1 -0
  56. package/lib/module/utils/accessibility.js +108 -0
  57. package/lib/module/utils/accessibility.js.map +1 -0
  58. package/lib/module/utils/cache.js +69 -0
  59. package/lib/module/utils/cache.js.map +1 -0
  60. package/lib/module/utils/index.js +95 -0
  61. package/lib/module/utils/index.js.map +1 -0
  62. package/lib/module/utils/sanitize.js +102 -0
  63. package/lib/module/utils/sanitize.js.map +1 -0
  64. package/lib/typescript/package.json +1 -0
  65. package/lib/typescript/src/HtmlRenderer.d.ts +15 -0
  66. package/lib/typescript/src/HtmlRenderer.d.ts.map +1 -0
  67. package/lib/typescript/src/context/index.d.ts +5 -0
  68. package/lib/typescript/src/context/index.d.ts.map +1 -0
  69. package/lib/typescript/src/hooks/index.d.ts +4 -0
  70. package/lib/typescript/src/hooks/index.d.ts.map +1 -0
  71. package/lib/typescript/src/hooks/useContentWidth.d.ts +6 -0
  72. package/lib/typescript/src/hooks/useContentWidth.d.ts.map +1 -0
  73. package/lib/typescript/src/hooks/useHtmlParser.d.ts +11 -0
  74. package/lib/typescript/src/hooks/useHtmlParser.d.ts.map +1 -0
  75. package/lib/typescript/src/hooks/useTagStyle.d.ts +11 -0
  76. package/lib/typescript/src/hooks/useTagStyle.d.ts.map +1 -0
  77. package/lib/typescript/src/index.d.ts +9 -0
  78. package/lib/typescript/src/index.d.ts.map +1 -0
  79. package/lib/typescript/src/parser/index.d.ts +10 -0
  80. package/lib/typescript/src/parser/index.d.ts.map +1 -0
  81. package/lib/typescript/src/renderer/ErrorBoundary.d.ts +22 -0
  82. package/lib/typescript/src/renderer/ErrorBoundary.d.ts.map +1 -0
  83. package/lib/typescript/src/renderer/NodeRenderer.d.ts +7 -0
  84. package/lib/typescript/src/renderer/NodeRenderer.d.ts.map +1 -0
  85. package/lib/typescript/src/renderer/index.d.ts +3 -0
  86. package/lib/typescript/src/renderer/index.d.ts.map +1 -0
  87. package/lib/typescript/src/renderer/tags/BlockTags.d.ts +18 -0
  88. package/lib/typescript/src/renderer/tags/BlockTags.d.ts.map +1 -0
  89. package/lib/typescript/src/renderer/tags/FormTags.d.ts +16 -0
  90. package/lib/typescript/src/renderer/tags/FormTags.d.ts.map +1 -0
  91. package/lib/typescript/src/renderer/tags/ImageTag.d.ts +18 -0
  92. package/lib/typescript/src/renderer/tags/ImageTag.d.ts.map +1 -0
  93. package/lib/typescript/src/renderer/tags/LinkTag.d.ts +19 -0
  94. package/lib/typescript/src/renderer/tags/LinkTag.d.ts.map +1 -0
  95. package/lib/typescript/src/renderer/tags/ListTags.d.ts +15 -0
  96. package/lib/typescript/src/renderer/tags/ListTags.d.ts.map +1 -0
  97. package/lib/typescript/src/renderer/tags/MediaTags.d.ts +14 -0
  98. package/lib/typescript/src/renderer/tags/MediaTags.d.ts.map +1 -0
  99. package/lib/typescript/src/renderer/tags/TableTags.d.ts +15 -0
  100. package/lib/typescript/src/renderer/tags/TableTags.d.ts.map +1 -0
  101. package/lib/typescript/src/renderer/tags/TextTags.d.ts +22 -0
  102. package/lib/typescript/src/renderer/tags/TextTags.d.ts.map +1 -0
  103. package/lib/typescript/src/renderer/tags/index.d.ts +9 -0
  104. package/lib/typescript/src/renderer/tags/index.d.ts.map +1 -0
  105. package/lib/typescript/src/styles/cssToRn.d.ts +11 -0
  106. package/lib/typescript/src/styles/cssToRn.d.ts.map +1 -0
  107. package/lib/typescript/src/styles/darkModeStyles.d.ts +7 -0
  108. package/lib/typescript/src/styles/darkModeStyles.d.ts.map +1 -0
  109. package/lib/typescript/src/styles/defaultStyles.d.ts +8 -0
  110. package/lib/typescript/src/styles/defaultStyles.d.ts.map +1 -0
  111. package/lib/typescript/src/styles/index.d.ts +5 -0
  112. package/lib/typescript/src/styles/index.d.ts.map +1 -0
  113. package/lib/typescript/src/styles/mergeStyles.d.ts +10 -0
  114. package/lib/typescript/src/styles/mergeStyles.d.ts.map +1 -0
  115. package/lib/typescript/src/types/index.d.ts +158 -0
  116. package/lib/typescript/src/types/index.d.ts.map +1 -0
  117. package/lib/typescript/src/utils/accessibility.d.ts +32 -0
  118. package/lib/typescript/src/utils/accessibility.d.ts.map +1 -0
  119. package/lib/typescript/src/utils/cache.d.ts +24 -0
  120. package/lib/typescript/src/utils/cache.d.ts.map +1 -0
  121. package/lib/typescript/src/utils/index.d.ts +33 -0
  122. package/lib/typescript/src/utils/index.d.ts.map +1 -0
  123. package/lib/typescript/src/utils/sanitize.d.ts +11 -0
  124. package/lib/typescript/src/utils/sanitize.d.ts.map +1 -0
  125. package/package.json +171 -0
  126. package/src/HtmlRenderer.tsx +216 -0
  127. package/src/context/index.tsx +30 -0
  128. package/src/hooks/index.ts +3 -0
  129. package/src/hooks/useContentWidth.ts +9 -0
  130. package/src/hooks/useHtmlParser.ts +18 -0
  131. package/src/hooks/useTagStyle.ts +23 -0
  132. package/src/index.tsx +39 -0
  133. package/src/parser/index.ts +80 -0
  134. package/src/renderer/ErrorBoundary.tsx +80 -0
  135. package/src/renderer/NodeRenderer.tsx +345 -0
  136. package/src/renderer/index.tsx +2 -0
  137. package/src/renderer/tags/BlockTags.tsx +49 -0
  138. package/src/renderer/tags/FormTags.tsx +169 -0
  139. package/src/renderer/tags/ImageTag.tsx +215 -0
  140. package/src/renderer/tags/LinkTag.tsx +76 -0
  141. package/src/renderer/tags/ListTags.tsx +148 -0
  142. package/src/renderer/tags/MediaTags.tsx +81 -0
  143. package/src/renderer/tags/TableTags.tsx +94 -0
  144. package/src/renderer/tags/TextTags.tsx +139 -0
  145. package/src/renderer/tags/index.ts +8 -0
  146. package/src/styles/cssToRn.ts +45 -0
  147. package/src/styles/darkModeStyles.ts +80 -0
  148. package/src/styles/defaultStyles.ts +176 -0
  149. package/src/styles/index.ts +4 -0
  150. package/src/styles/mergeStyles.ts +59 -0
  151. package/src/types/index.ts +229 -0
  152. package/src/utils/accessibility.ts +132 -0
  153. package/src/utils/cache.ts +83 -0
  154. package/src/utils/index.ts +151 -0
  155. package/src/utils/sanitize.ts +149 -0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Neelesh Yadav
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,407 @@
1
+ # react-native-html-renderer
2
+
3
+ [![npm version](https://img.shields.io/npm/v/react-native-html-renderer.svg)](https://www.npmjs.com/package/react-native-html-renderer)
4
+ [![license](https://img.shields.io/npm/l/react-native-html-renderer.svg)](https://github.com/Neelesh-FS-Dev/react-native-html-renderer/blob/main/LICENSE)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue.svg)](https://www.typescriptlang.org/)
6
+ [![CI](https://github.com/Neelesh-FS-Dev/react-native-html-renderer/actions/workflows/ci.yml/badge.svg)](https://github.com/Neelesh-FS-Dev/react-native-html-renderer/actions/workflows/ci.yml)
7
+
8
+ Renders HTML into 100% native React Native views — actively maintained, TypeScript-first, and lightweight.
9
+
10
+ A modern replacement for the abandoned `react-native-render-html`.
11
+
12
+ ## Table of Contents
13
+
14
+ - [Requirements](#requirements)
15
+ - [Installation](#installation)
16
+ - [Basic Usage](#basic-usage)
17
+ - [Props API](#props-api)
18
+ - [Security](#security)
19
+ - [Dark Mode](#dark-mode)
20
+ - [Accessibility](#accessibility)
21
+ - [Font Scaling](#font-scaling)
22
+ - [Supported HTML Tags](#supported-html-tags)
23
+ - [Custom Renderers](#custom-renderers)
24
+ - [Tag & Class Styles](#tag--class-styles)
25
+ - [Hooks](#hooks)
26
+ - [Utility Exports](#utility-exports)
27
+ - [Image Handling](#image-handling)
28
+ - [Debug Mode](#debug-mode)
29
+ - [Limitations](#limitations)
30
+ - [Migration from react-native-render-html v6](#migration-from-react-native-render-html-v6)
31
+ - [Contributing](#contributing)
32
+ - [License](#license)
33
+
34
+ ## Requirements
35
+
36
+ | Dependency | Version |
37
+ | ------------- | --------- |
38
+ | React | >= 18.0.0 |
39
+ | React Native | >= 0.71.0 |
40
+ | Node.js | >= 20 |
41
+
42
+ ## Installation
43
+
44
+ ```sh
45
+ npm install react-native-html-renderer
46
+ ```
47
+
48
+ or
49
+
50
+ ```sh
51
+ yarn add react-native-html-renderer
52
+ ```
53
+
54
+ All other dependencies (`htmlparser2`, `css-to-react-native`) are bundled — no extra installs needed.
55
+
56
+ ## Basic Usage
57
+
58
+ ```tsx
59
+ import { HtmlRenderer } from 'react-native-html-renderer';
60
+ import { useWindowDimensions, Linking } from 'react-native';
61
+
62
+ function MyComponent() {
63
+ const { width } = useWindowDimensions();
64
+
65
+ return (
66
+ <HtmlRenderer
67
+ html="<h1>Hello</h1><p>This is <strong>bold</strong> and <em>italic</em>.</p>"
68
+ contentWidth={width - 32}
69
+ onLinkPress={(href) => Linking.openURL(href)}
70
+ />
71
+ );
72
+ }
73
+ ```
74
+
75
+ ## Props API
76
+
77
+ | Prop | Type | Default | Description |
78
+ | ---- | ---- | ------- | ----------- |
79
+ | `html` | `string` | *required* | Raw HTML string to render |
80
+ | `contentWidth` | `number` | *required* | Available width for layout and image scaling |
81
+ | `baseStyle` | `ViewStyle` | `undefined` | Style applied to the root container |
82
+ | `tagsStyles` | `Record<string, RNStyle>` | `undefined` | Per-tag style overrides |
83
+ | `classesStyles` | `Record<string, RNStyle>` | `undefined` | Styles applied by HTML class name |
84
+ | `idsStyles` | `Record<string, RNStyle>` | `undefined` | Styles applied by HTML element id |
85
+ | `customRenderers` | `Record<string, CustomRenderer>` | `undefined` | Override rendering for specific tags |
86
+ | `onLinkPress` | `(href, attrs) => void` | `undefined` | Callback for `<a>` tag taps |
87
+ | `onImagePress` | `(src, attrs) => void` | `undefined` | Callback for image taps |
88
+ | `onError` | `(error: Error) => void` | `undefined` | Called on parse or render errors |
89
+ | `fallback` | `ReactNode` | default message | Custom UI to show when an error occurs |
90
+ | `ignoredTags` | `string[]` | `undefined` | Tags to completely skip (including children) |
91
+ | `ignoredStyles` | `string[]` | `undefined` | CSS property names to ignore |
92
+ | `allowedStyles` | `string[]` | `undefined` | Whitelist of CSS properties to allow |
93
+ | `defaultTextProps` | `TextProps` | `undefined` | Default props for all `<Text>` components |
94
+ | `defaultViewProps` | `ViewProps` | `undefined` | Default props for all `<View>` components |
95
+ | `renderersProps` | `Record<string, object>` | `undefined` | Extra props for specific tag renderers |
96
+ | `maxImagesWidth` | `number` | `undefined` | Maximum image width cap |
97
+ | `imagesInitialDimensions` | `{ width, height }` | `{100, 100}` | Placeholder size before image loads |
98
+ | `listsPrefixesRenderers` | `ListsPrefixesRenderers` | `undefined` | Custom bullet/number components |
99
+ | `emSize` | `number` | `14` | Base em unit in pixels |
100
+ | `systemFonts` | `string[]` | `undefined` | Available system fonts |
101
+ | `fallbackFonts` | `Record<string, string>` | `undefined` | Map unsupported fonts to fallbacks |
102
+ | `debug` | `boolean` | `false` | Log DOM, styles, and show red debug borders |
103
+ | `allowDangerousHtml` | `boolean` | `false` | When false, strips dangerous tags and attributes |
104
+ | `darkModeStyles` | `Record<string, RNStyle>` | `undefined` | Per-tag overrides applied in dark mode |
105
+ | `colorScheme` | `'light' \| 'dark'` | system | Override color scheme detection |
106
+ | `allowFontScaling` | `boolean` | `true` | Allow system font-size accessibility scaling |
107
+ | `maxFontSizeMultiplier` | `number` | `undefined` | Cap the font-size multiplier |
108
+
109
+ ## Security
110
+
111
+ By default (when `allowDangerousHtml` is `false`), the renderer automatically:
112
+
113
+ - Strips `<script>`, `<iframe>`, `<object>`, `<embed>`, `<form>`, `<svg>`, `<math>` tags
114
+ - Neutralizes `javascript:`, `vbscript:`, and `data:text/html` URLs
115
+ - Removes all event handler attributes (`onclick`, `onerror`, `onload`, etc.)
116
+ - Guards against prototype pollution and deeply nested DOM attacks
117
+
118
+ Set `allowDangerousHtml={true}` to opt out of sanitization. See [SECURITY.md](SECURITY.md) for details.
119
+
120
+ ## Dark Mode
121
+
122
+ The renderer automatically detects the system color scheme and applies dark-mode-aware default styles. You can add per-tag overrides:
123
+
124
+ ```tsx
125
+ <HtmlRenderer
126
+ html={html}
127
+ contentWidth={width}
128
+ darkModeStyles={{
129
+ p: { color: '#ddd' },
130
+ pre: { backgroundColor: '#1a1a2e', color: '#eee' },
131
+ }}
132
+ />
133
+ ```
134
+
135
+ Override detection with the `colorScheme` prop: `colorScheme="dark"` or `colorScheme="light"`.
136
+
137
+ Use `getDefaultDarkModeStyles()` to inspect the built-in dark mode defaults.
138
+
139
+ ## Accessibility
140
+
141
+ All interactive elements include proper accessibility attributes:
142
+
143
+ - `<a>` → `accessibilityRole="link"`, `accessibilityHint="Opens {href}"`
144
+ - `<img>` → `accessibilityRole="image"`, `accessibilityLabel` from `alt`
145
+ - `<button>` → `accessibilityRole="button"`
146
+ - `<h1>`–`<h6>` → `accessibilityRole="header"`
147
+ - `<ul>`/`<ol>` → `accessibilityRole="list"`
148
+ - `<input type="checkbox">` → `accessibilityRole="checkbox"`, `accessibilityState.checked`
149
+
150
+ HTML `aria-*` attributes are mapped to React Native equivalents:
151
+
152
+ ```html
153
+ <p aria-label="Custom label">Accessible paragraph</p>
154
+ <span aria-hidden="true">Hidden from screen readers</span>
155
+ <button aria-disabled="true">Disabled button</button>
156
+ ```
157
+
158
+ | HTML attribute | React Native equivalent |
159
+ | -------------- | ---------------------- |
160
+ | `aria-label` | `accessibilityLabel` |
161
+ | `aria-hidden="true"` | `accessible={false}` |
162
+ | `aria-disabled` | `accessibilityState.disabled` |
163
+ | `aria-checked` | `accessibilityState.checked` |
164
+ | `aria-expanded` | `accessibilityState.expanded` |
165
+ | `aria-busy` | `accessibilityState.busy` |
166
+ | `aria-role` / `role` | `accessibilityRole` |
167
+
168
+ ## Font Scaling
169
+
170
+ Respects system accessibility font-size settings:
171
+
172
+ ```tsx
173
+ <HtmlRenderer
174
+ html={html}
175
+ contentWidth={width}
176
+ allowFontScaling={true}
177
+ maxFontSizeMultiplier={1.5}
178
+ />
179
+ ```
180
+
181
+ ## Supported HTML Tags
182
+
183
+ ### Block Elements
184
+
185
+ `<div>`, `<section>`, `<article>`, `<header>`, `<footer>`, `<main>`, `<nav>`, `<aside>`, `<blockquote>`, `<pre>`, `<figure>`
186
+
187
+ ### Text Elements
188
+
189
+ `<p>`, `<h1>`-`<h6>`, `<span>`, `<strong>`, `<b>`, `<em>`, `<i>`, `<u>`, `<s>`, `<strike>`, `<del>`, `<ins>`, `<mark>`, `<small>`, `<sub>`, `<sup>`, `<code>`, `<label>`
190
+
191
+ ### Media
192
+
193
+ `<img>` (with auto-sizing, caching, loading state, error fallback), `<video>` and `<audio>` (placeholder views)
194
+
195
+ ### Lists
196
+
197
+ `<ul>`, `<ol>`, `<li>` with proper bullets/numbers and nested list support
198
+
199
+ ### Tables
200
+
201
+ `<table>`, `<thead>`, `<tbody>`, `<tfoot>`, `<tr>`, `<th>`, `<td>` wrapped in horizontal ScrollView
202
+
203
+ ### Links
204
+
205
+ `<a>` with `onLinkPress` callback
206
+
207
+ ### Forms (read-only)
208
+
209
+ `<input>`, `<textarea>`, `<button>`, `<select>` rendered as visual read-only elements
210
+
211
+ ### Self-closing
212
+
213
+ `<br>`, `<hr>`
214
+
215
+ ### Silently Ignored
216
+
217
+ `<script>`, `<style>`, `<head>`, `<meta>`, `<link>`, `<title>`, `<noscript>`
218
+
219
+ ### Unknown Tags
220
+
221
+ Unknown tags render their children without crashing. In `debug` mode, a warning is logged.
222
+
223
+ ## Custom Renderers
224
+
225
+ Override how any tag renders:
226
+
227
+ ```tsx
228
+ import { HtmlRenderer } from 'react-native-html-renderer';
229
+ import type { CustomRendererProps } from 'react-native-html-renderer';
230
+ import { View } from 'react-native';
231
+
232
+ function myBlockquote({ children, style }: CustomRendererProps) {
233
+ return (
234
+ <View style={{ borderLeftWidth: 4, borderLeftColor: '#3498db', paddingLeft: 12 }}>
235
+ {children}
236
+ </View>
237
+ );
238
+ }
239
+
240
+ <HtmlRenderer
241
+ html="<blockquote><p>Quoted text</p></blockquote>"
242
+ contentWidth={350}
243
+ customRenderers={{ blockquote: myBlockquote }}
244
+ />
245
+ ```
246
+
247
+ The `CustomRendererProps` object includes:
248
+
249
+ | Property | Type | Description |
250
+ | -------- | ---- | ----------- |
251
+ | `node` | `DOMElement` | The parsed DOM element |
252
+ | `children` | `ReactNode[]` | Pre-rendered child nodes |
253
+ | `style` | `RNStyle` | Merged style for the element |
254
+ | `attributes` | `Record<string, string>` | HTML attributes |
255
+ | `passProps` | `Record<string, unknown>` | Extra props from `renderersProps` |
256
+ | `renderChildren` | `(nodes: DOMNode[]) => ReactNode[]` | Helper to render child DOM nodes |
257
+ | `contentWidth` | `number` | Available content width |
258
+
259
+ ## Tag & Class Styles
260
+
261
+ ```tsx
262
+ <HtmlRenderer
263
+ html='<p class="intro">Hello</p><p id="note">Note</p>'
264
+ contentWidth={350}
265
+ tagsStyles={{
266
+ p: { fontSize: 16, lineHeight: 24 },
267
+ h1: { color: '#2c3e50' },
268
+ }}
269
+ classesStyles={{
270
+ intro: { backgroundColor: '#f0f0f0', padding: 8 },
271
+ }}
272
+ idsStyles={{
273
+ note: { fontStyle: 'italic', color: '#999' },
274
+ }}
275
+ />
276
+ ```
277
+
278
+ Style cascade order: **default tag style** → **tagsStyles** → **classesStyles** → **idsStyles** → **inline style**
279
+
280
+ In dark mode: **default dark styles** and **darkModeStyles** are merged into the tag styles layer.
281
+
282
+ ## Hooks
283
+
284
+ Three reusable hooks exported for use inside custom renderers or elsewhere:
285
+
286
+ ```tsx
287
+ import { useHtmlParser, useContentWidth, useTagStyle } from 'react-native-html-renderer';
288
+
289
+ // Parse HTML into a DOM tree
290
+ const nodes = useHtmlParser('<p>Hello</p>');
291
+
292
+ // Get contentWidth from the nearest HtmlRenderer context
293
+ const width = useContentWidth();
294
+
295
+ // Get the resolved style for a tag from context
296
+ const pStyle = useTagStyle('p');
297
+ ```
298
+
299
+ ## Utility Exports
300
+
301
+ ```tsx
302
+ import {
303
+ parseHTML,
304
+ parseInlineStyle,
305
+ getDefaultTagStyles,
306
+ getDefaultDarkModeStyles,
307
+ sanitizeDOM,
308
+ clearDOMCache,
309
+ clearImageDimensionCache,
310
+ } from 'react-native-html-renderer';
311
+ ```
312
+
313
+ | Export | Description |
314
+ | ------ | ----------- |
315
+ | `parseHTML(html, ignoredTags?)` | Parse an HTML string into a `DOMNode[]` tree |
316
+ | `parseInlineStyle(css, ignored?, allowed?)` | Convert a CSS string to a React Native style object |
317
+ | `getDefaultTagStyles(emSize)` | Get the default styles for all supported tags |
318
+ | `getDefaultDarkModeStyles()` | Get the built-in dark mode style overrides |
319
+ | `sanitizeDOM(nodes)` | Strip dangerous tags, attributes, and URLs from a DOM tree |
320
+ | `clearDOMCache()` | Clear the parsed DOM LRU cache (max 50 entries) |
321
+ | `clearImageDimensionCache()` | Clear the image dimension LRU cache (max 200 entries) |
322
+
323
+ ## Image Handling
324
+
325
+ Images automatically:
326
+
327
+ - Fetch dimensions via `Image.getSize()` for remote URLs
328
+ - **Cache dimensions** after first fetch to avoid repeated network calls
329
+ - Scale proportionally to fit `contentWidth`
330
+ - Respect `maxImagesWidth` cap
331
+ - Show a loading indicator while fetching
332
+ - Show an error fallback if loading fails
333
+ - Support `onImagePress` callback
334
+ - Support `data:` base64 URIs
335
+
336
+ ## Error Handling
337
+
338
+ The renderer handles errors at multiple levels to ensure it never crashes your app:
339
+
340
+ - **Parse errors** — malformed HTML is caught during parsing; returns empty output and calls `onError`
341
+ - **Render errors** — if a node fails to render, it is skipped (other nodes continue rendering)
342
+ - **Custom renderer errors** — exceptions in user-provided `customRenderers` are caught per-node; the failing tag is skipped with a debug-mode console error
343
+ - **Style errors** — invalid inline CSS is silently ignored
344
+ - **Image errors** — failed image loads show a fallback placeholder
345
+ - **React ErrorBoundary** — wraps the entire tree as a final safety net
346
+
347
+ ```tsx
348
+ <HtmlRenderer
349
+ html={html}
350
+ contentWidth={width}
351
+ onError={(error) => {
352
+ // Log to your error tracking service
353
+ Sentry.captureException(error);
354
+ }}
355
+ fallback={<Text>Something went wrong.</Text>}
356
+ />
357
+ ```
358
+
359
+ In `debug` mode, all caught errors are logged to the console with the tag name and stack trace.
360
+
361
+ ## Debug Mode
362
+
363
+ Set `debug={true}` to enable:
364
+
365
+ - Parsed DOM tree logged to console
366
+ - Computed styles per node logged to console
367
+ - Unknown/skipped tags logged as warnings
368
+ - Red border drawn around every rendered node
369
+ - Color scheme logged to console
370
+
371
+ ## Limitations
372
+
373
+ - **Form elements are read-only** — `<input>`, `<textarea>`, `<select>`, `<button>` render as visual representations but are not interactive
374
+ - **Video and audio are placeholders** — `<video>` and `<audio>` render placeholder views, not playable media (use custom renderers to integrate a media player)
375
+ - **No CSS cascade beyond inline** — only inline `style` attributes, tag/class/id overrides, and default styles are supported (no external stylesheets, no `<style>` blocks)
376
+ - **Limited CSS properties** — only properties supported by React Native's style system are converted (see `css-to-react-native` for the full list)
377
+ - **No CSS animations or transitions**
378
+ - **No web component support** (`<slot>`, `<template>`, shadow DOM)
379
+ - **Tables may overflow** — wide tables are wrapped in a horizontal `ScrollView`
380
+
381
+ ## Migration from [react-native-render-html](https://github.com/meliorence/react-native-render-html) v6
382
+
383
+ | react-native-render-html | react-native-html-renderer |
384
+ | ------------------------ | -------------------------- |
385
+ | `<RenderHtml source={{ html }} />` | `<HtmlRenderer html={html} contentWidth={width} />` |
386
+ | `renderers={{ p: PRenderer }}` | `customRenderers={{ p: myPRenderer }}` |
387
+ | `tagsStyles={{ p: { ... } }}` | `tagsStyles={{ p: { ... } }}` (same API) |
388
+ | `classesStyles={{ ... }}` | `classesStyles={{ ... }}` (same API) |
389
+ | `ignoredDomTags={[...]}` | `ignoredTags={[...]}` |
390
+ | `renderersProps={{ a: { ... } }}` | `renderersProps={{ a: { ... } }}` (same API) |
391
+ | `systemFonts={[...]}` | `systemFonts={[...]}` (same API) |
392
+ | `defaultTextProps={{ ... }}` | `defaultTextProps={{ ... }}` (same API) |
393
+ | *(no equivalent)* | `allowDangerousHtml` — built-in XSS sanitization |
394
+ | *(no equivalent)* | `darkModeStyles` — automatic dark mode support |
395
+ | *(no equivalent)* | `allowFontScaling` / `maxFontSizeMultiplier` |
396
+
397
+ ## Contributing
398
+
399
+ See the [contributing guide](CONTRIBUTING.md) for development workflow and pull request instructions.
400
+
401
+ ## License
402
+
403
+ MIT
404
+
405
+ ---
406
+
407
+ Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+
3
+ import { useMemo } from 'react';
4
+ import { View, useColorScheme } from 'react-native';
5
+ import { HtmlRendererContext } from "./context/index.js";
6
+ import { parseHTML } from "./parser/index.js";
7
+ import { getDefaultDarkModeStyles } from "./styles/darkModeStyles.js";
8
+ import { renderNodes } from "./renderer/index.js";
9
+ import { ErrorBoundary } from "./renderer/ErrorBoundary.js";
10
+ import { sanitizeDOM } from "./utils/sanitize.js";
11
+ import { getCachedDOM, setCachedDOM, buildDOMCacheKey } from "./utils/cache.js";
12
+
13
+ /**
14
+ * Renders an HTML string into native React Native components.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * <HtmlRenderer
19
+ * html="<h1>Hello</h1><p>World</p>"
20
+ * contentWidth={350}
21
+ * onLinkPress={(href) => Linking.openURL(href)}
22
+ * />
23
+ * ```
24
+ */
25
+ import { jsx as _jsx } from "react/jsx-runtime";
26
+ export function HtmlRenderer({
27
+ html,
28
+ contentWidth,
29
+ baseStyle,
30
+ tagsStyles,
31
+ classesStyles,
32
+ idsStyles,
33
+ customRenderers,
34
+ onLinkPress,
35
+ onImagePress,
36
+ onError,
37
+ fallback,
38
+ ignoredTags,
39
+ ignoredStyles,
40
+ allowedStyles,
41
+ defaultTextProps,
42
+ defaultViewProps,
43
+ renderersProps,
44
+ maxImagesWidth,
45
+ imagesInitialDimensions,
46
+ listsPrefixesRenderers,
47
+ emSize = 14,
48
+ systemFonts,
49
+ fallbackFonts,
50
+ debug = false,
51
+ allowDangerousHtml = false,
52
+ darkModeStyles,
53
+ colorScheme: colorSchemeProp,
54
+ allowFontScaling = true,
55
+ maxFontSizeMultiplier
56
+ }) {
57
+ // --- Color scheme ---
58
+ const systemScheme = useColorScheme();
59
+ const resolvedScheme = colorSchemeProp ?? systemScheme;
60
+ const isDark = resolvedScheme === 'dark';
61
+
62
+ // --- Memoize set conversions ---
63
+ const ignoredTagsSet = useMemo(() => new Set(ignoredTags ?? []), [ignoredTags]);
64
+ const ignoredStylesSet = useMemo(() => new Set(ignoredStyles ?? []), [ignoredStyles]);
65
+ const allowedStylesSet = useMemo(() => allowedStyles ? new Set(allowedStyles) : null, [allowedStyles]);
66
+
67
+ // --- Parse DOM (with cache, key includes sanitization params to prevent poisoning) ---
68
+ const nodes = useMemo(() => {
69
+ try {
70
+ const cacheKey = buildDOMCacheKey(html, allowDangerousHtml, ignoredTagsSet);
71
+ const cached = getCachedDOM(cacheKey);
72
+ if (cached) return cached;
73
+ let parsed = parseHTML(html, ignoredTagsSet);
74
+
75
+ // Sanitize if not explicitly opted out
76
+ if (!allowDangerousHtml) {
77
+ parsed = sanitizeDOM(parsed);
78
+ }
79
+ setCachedDOM(cacheKey, parsed);
80
+ return parsed;
81
+ } catch (e) {
82
+ const error = e instanceof Error ? e : new Error('Failed to parse HTML');
83
+ if (debug) {
84
+ console.error('[HtmlRenderer] Parse error:', error);
85
+ }
86
+ onError?.(error);
87
+ return [];
88
+ }
89
+ }, [html, ignoredTagsSet, allowDangerousHtml, debug, onError]);
90
+
91
+ // --- Merge dark mode styles ---
92
+ const effectiveTagsStyles = useMemo(() => {
93
+ const base = tagsStyles ?? {};
94
+ if (!isDark) return base;
95
+ const defaultDark = getDefaultDarkModeStyles();
96
+ const userDark = darkModeStyles ?? {};
97
+
98
+ // Merge: base tagsStyles + default dark overrides + user dark overrides
99
+ const merged = {
100
+ ...base
101
+ };
102
+ for (const tag of Object.keys(defaultDark)) {
103
+ merged[tag] = {
104
+ ...(merged[tag] ?? {}),
105
+ ...defaultDark[tag]
106
+ };
107
+ }
108
+ for (const tag of Object.keys(userDark)) {
109
+ merged[tag] = {
110
+ ...(merged[tag] ?? {}),
111
+ ...userDark[tag]
112
+ };
113
+ }
114
+ return merged;
115
+ }, [tagsStyles, isDark, darkModeStyles]);
116
+
117
+ // --- Build context value ---
118
+ const ctx = useMemo(() => ({
119
+ contentWidth,
120
+ tagsStyles: effectiveTagsStyles,
121
+ classesStyles: classesStyles ?? {},
122
+ idsStyles: idsStyles ?? {},
123
+ customRenderers: customRenderers ?? {},
124
+ onLinkPress,
125
+ onImagePress,
126
+ renderersProps: renderersProps ?? {},
127
+ emSize,
128
+ debug,
129
+ ignoredTags: ignoredTagsSet,
130
+ ignoredStyles: ignoredStylesSet,
131
+ allowedStyles: allowedStylesSet,
132
+ defaultTextProps,
133
+ defaultViewProps,
134
+ maxImagesWidth,
135
+ imagesInitialDimensions: imagesInitialDimensions ?? {
136
+ width: 100,
137
+ height: 100
138
+ },
139
+ listsPrefixesRenderers,
140
+ systemFonts,
141
+ fallbackFonts,
142
+ nestLevel: 0,
143
+ colorScheme: resolvedScheme,
144
+ darkModeStyles: darkModeStyles ?? {},
145
+ allowFontScaling,
146
+ maxFontSizeMultiplier
147
+ }), [contentWidth, effectiveTagsStyles, classesStyles, idsStyles, customRenderers, onLinkPress, onImagePress, renderersProps, emSize, debug, ignoredTagsSet, ignoredStylesSet, allowedStylesSet, defaultTextProps, defaultViewProps, maxImagesWidth, imagesInitialDimensions, listsPrefixesRenderers, systemFonts, fallbackFonts, resolvedScheme, darkModeStyles, allowFontScaling, maxFontSizeMultiplier]);
148
+
149
+ // --- Debug log ---
150
+ if (debug) {
151
+ console.log('[HtmlRenderer] Parsed DOM:', JSON.stringify(nodes, null, 2));
152
+ console.log('[HtmlRenderer] Color scheme:', resolvedScheme);
153
+ }
154
+
155
+ // --- Render ---
156
+ const rendered = useMemo(() => {
157
+ try {
158
+ return renderNodes(nodes, ctx, 'rn');
159
+ } catch (e) {
160
+ const error = e instanceof Error ? e : new Error('Failed to render HTML');
161
+ if (debug) {
162
+ console.error('[HtmlRenderer] Render error:', error);
163
+ }
164
+ onError?.(error);
165
+ return [];
166
+ }
167
+ }, [nodes, ctx, debug, onError]);
168
+ return /*#__PURE__*/_jsx(ErrorBoundary, {
169
+ onError: onError,
170
+ fallback: fallback,
171
+ children: /*#__PURE__*/_jsx(HtmlRendererContext.Provider, {
172
+ value: ctx,
173
+ children: /*#__PURE__*/_jsx(View, {
174
+ style: [containerStyle, baseStyle],
175
+ children: rendered
176
+ })
177
+ })
178
+ });
179
+ }
180
+ const containerStyle = {
181
+ flexShrink: 1
182
+ };
183
+ //# sourceMappingURL=HtmlRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useMemo","View","useColorScheme","HtmlRendererContext","parseHTML","getDefaultDarkModeStyles","renderNodes","ErrorBoundary","sanitizeDOM","getCachedDOM","setCachedDOM","buildDOMCacheKey","jsx","_jsx","HtmlRenderer","html","contentWidth","baseStyle","tagsStyles","classesStyles","idsStyles","customRenderers","onLinkPress","onImagePress","onError","fallback","ignoredTags","ignoredStyles","allowedStyles","defaultTextProps","defaultViewProps","renderersProps","maxImagesWidth","imagesInitialDimensions","listsPrefixesRenderers","emSize","systemFonts","fallbackFonts","debug","allowDangerousHtml","darkModeStyles","colorScheme","colorSchemeProp","allowFontScaling","maxFontSizeMultiplier","systemScheme","resolvedScheme","isDark","ignoredTagsSet","Set","ignoredStylesSet","allowedStylesSet","nodes","cacheKey","cached","parsed","e","error","Error","console","effectiveTagsStyles","base","defaultDark","userDark","merged","tag","Object","keys","ctx","width","height","nestLevel","log","JSON","stringify","rendered","children","Provider","value","style","containerStyle","flexShrink"],"sourceRoot":"../../src","sources":["HtmlRenderer.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ import { createContext, useContext } from 'react';
4
+ const DEFAULT_CONTEXT = {
5
+ contentWidth: 300,
6
+ tagsStyles: {},
7
+ classesStyles: {},
8
+ idsStyles: {},
9
+ customRenderers: {},
10
+ renderersProps: {},
11
+ emSize: 14,
12
+ debug: false,
13
+ ignoredTags: new Set(),
14
+ ignoredStyles: new Set(),
15
+ allowedStyles: null,
16
+ imagesInitialDimensions: {
17
+ width: 100,
18
+ height: 100
19
+ },
20
+ nestLevel: 0,
21
+ colorScheme: 'light',
22
+ darkModeStyles: {},
23
+ allowFontScaling: true,
24
+ maxFontSizeMultiplier: undefined
25
+ };
26
+ export const HtmlRendererContext = /*#__PURE__*/createContext(DEFAULT_CONTEXT);
27
+
28
+ /** Access the HtmlRenderer context from inside the render tree. */
29
+ export function useHtmlRendererContext() {
30
+ return useContext(HtmlRendererContext);
31
+ }
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createContext","useContext","DEFAULT_CONTEXT","contentWidth","tagsStyles","classesStyles","idsStyles","customRenderers","renderersProps","emSize","debug","ignoredTags","Set","ignoredStyles","allowedStyles","imagesInitialDimensions","width","height","nestLevel","colorScheme","darkModeStyles","allowFontScaling","maxFontSizeMultiplier","undefined","HtmlRendererContext","useHtmlRendererContext"],"sourceRoot":"../../../src","sources":["context/index.tsx"],"mappings":";;AAAA,SAASA,aAAa,EAAEC,UAAU,QAAQ,OAAO;AAGjD,MAAMC,eAAyC,GAAG;EAChDC,YAAY,EAAE,GAAG;EACjBC,UAAU,EAAE,CAAC,CAAC;EACdC,aAAa,EAAE,CAAC,CAAC;EACjBC,SAAS,EAAE,CAAC,CAAC;EACbC,eAAe,EAAE,CAAC,CAAC;EACnBC,cAAc,EAAE,CAAC,CAAC;EAClBC,MAAM,EAAE,EAAE;EACVC,KAAK,EAAE,KAAK;EACZC,WAAW,EAAE,IAAIC,GAAG,CAAC,CAAC;EACtBC,aAAa,EAAE,IAAID,GAAG,CAAC,CAAC;EACxBE,aAAa,EAAE,IAAI;EACnBC,uBAAuB,EAAE;IAAEC,KAAK,EAAE,GAAG;IAAEC,MAAM,EAAE;EAAI,CAAC;EACpDC,SAAS,EAAE,CAAC;EACZC,WAAW,EAAE,OAAO;EACpBC,cAAc,EAAE,CAAC,CAAC;EAClBC,gBAAgB,EAAE,IAAI;EACtBC,qBAAqB,EAAEC;AACzB,CAAC;AAED,OAAO,MAAMC,mBAAmB,gBAC9BxB,aAAa,CAA2BE,eAAe,CAAC;;AAE1D;AACA,OAAO,SAASuB,sBAAsBA,CAAA,EAA6B;EACjE,OAAOxB,UAAU,CAACuB,mBAAmB,CAAC;AACxC","ignoreList":[]}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ export { useHtmlParser } from "./useHtmlParser.js";
4
+ export { useContentWidth } from "./useContentWidth.js";
5
+ export { useTagStyle } from "./useTagStyle.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useHtmlParser","useContentWidth","useTagStyle"],"sourceRoot":"../../../src","sources":["hooks/index.ts"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,oBAAiB;AAC/C,SAASC,eAAe,QAAQ,sBAAmB;AACnD,SAASC,WAAW,QAAQ,kBAAe","ignoreList":[]}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ import { useHtmlRendererContext } from "../context/index.js";
4
+
5
+ /**
6
+ * Returns the current `contentWidth` from the HtmlRenderer context.
7
+ * Useful inside custom renderers that need to know the available layout width.
8
+ */
9
+ export function useContentWidth() {
10
+ return useHtmlRendererContext().contentWidth;
11
+ }
12
+ //# sourceMappingURL=useContentWidth.js.map