Skip to content

Commit f12e269

Browse files
committed
Introduce auto-sizing WebView and update package naming
Added SizedWebView component with automatic content height measurement using a custom bridge and hook. Updated package and example names to 'react-native-sized-webview', improved documentation, added tests and utility scripts, and refactored exports. Also updated dependencies and configuration for consistency with the new naming and features.
1 parent 1978896 commit f12e269

File tree

18 files changed

+15143
-63
lines changed

18 files changed

+15143
-63
lines changed

.github/FUNDING.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# These are supported funding model platforms
2+
3+
github: [mcodex]
4+
patreon: # Replace with a single Patreon username
5+
open_collective: # Replace with a single Open Collective username
6+
ko_fi: # Replace with a single Ko-fi username
7+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9+
liberapay: # Replace with a single Liberapay username
10+
issuehunt: # Replace with a single IssueHunt username
11+
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12+
polar: # Replace with a single Polar username
13+
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14+
thanks_dev: # Replace with a single thanks.dev username
15+
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
blank_issues_enabled: false
22
contact_links:
33
- name: Feature Request 💡
4-
url: https://github.com/mCodex/react-native-webview-sized/discussions/new?category=ideas
4+
url: https://github.com/mCodex/react-native-sized-webview/discussions/new?category=ideas
55
about: If you have a feature request, please create a new discussion on GitHub.
66
- name: Discussions on GitHub 💬
7-
url: https://github.com/mCodex/react-native-webview-sized/discussions
7+
url: https://github.com/mCodex/react-native-sized-webview/discussions
88
about: If this library works as promised but you need help, please ask questions there.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,6 @@ android/generated
8484

8585
# React Native Nitro Modules
8686
nitrogen/
87+
88+
# Test coverage
89+
coverage/

README.md

Lines changed: 108 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,131 @@
1-
# react-native-webview-sized
1+
# react-native-sized-webview 📏
22

3-
...
3+
[![npm version](https://img.shields.io/npm/v/react-native-sized-webview.svg?style=flat-square)](https://www.npmjs.com/package/react-native-sized-webview)
4+
[![npm downloads](https://img.shields.io/npm/dm/react-native-sized-webview.svg?style=flat-square&logo=npm)](https://www.npmjs.com/package/react-native-sized-webview)
5+
[![coverage](https://img.shields.io/badge/coverage-100%25-22c55e?style=flat-square&logo=jest&logoColor=white)](#-testing)
46

5-
## Installation
7+
React Native WebView that auto-sizes to match its HTML content—whether you load local HTML or full external websites—without manual measurements, timers, or layout flicker.
68

9+
> [!IMPORTANT]
10+
> ⚡️ `SizedWebView` keeps the parent scroll view in charge by disabling the inner WebView scroll and syncing height changes via a lightweight bridge.
11+
12+
> [!TIP]
13+
> 💡 Works out-of-the-box with dynamic CMS pages, FAQs, marketing landers, local HTML snippets, or full external sites.
14+
15+
## ✨ Highlights
16+
17+
- 📐 Auto-measures rendered HTML height on every DOM mutation or resize.
18+
- 🚀 Modern pipeline powered by `ResizeObserver`, `MutationObserver`, `visualViewport`, and font-load events with graceful fallbacks.
19+
- 🧵 Keeps the WebView scroll-disabled so outer `ScrollView`s and gesture handlers stay silky smooth.
20+
- 🎨 Transparent background by default; style the container however you like.
21+
- ⚙️ Friendly API with `minHeight`, `containerStyle`, and `onHeightChange` callbacks.
22+
- 🌲 ESM-first build, fully typed, `sideEffects: false` for optimal tree shaking.
23+
- 📱 Verified on iOS, Android, and Expo Go out of the box.
24+
25+
## 📦 Installation
26+
27+
```sh
28+
yarn add react-native-sized-webview react-native-webview
29+
# or
30+
npm install react-native-sized-webview react-native-webview
31+
```
32+
33+
No native steps are needed beyond the upstream `react-native-webview` dependency.
34+
35+
## 🚀 Quick Start
36+
37+
```tsx
38+
import { SizedWebView } from 'react-native-sized-webview';
39+
40+
const Article = () => (
41+
<SizedWebView
42+
minHeight={180}
43+
source={{
44+
html: `
45+
<html>
46+
<body>
47+
<h1>Privacy policy</h1>
48+
<p>Generated by your CMS and sized automatically ✨</p>
49+
</body>
50+
</html>
51+
`,
52+
}}
53+
containerStyle={{ borderRadius: 12, overflow: 'hidden' }}
54+
onHeightChange={(height) => console.log('content height', height)}
55+
/>
56+
);
57+
```
58+
59+
## 🧪 Example App
760

861
```sh
9-
npm install react-native-webview-sized
62+
yarn
63+
yarn example ios # or yarn example android
1064
```
1165

66+
The example showcases:
1267

13-
## Usage
68+
- Auto-sizing dynamic HTML with toggled sections.
69+
- Live external sites (Marvel, NFL, Google, Wikipedia, The Verge) embedded without layout thrash.
70+
- Real-time height readouts so you can verify your own endpoints quickly.
1471

72+
> [!NOTE]
73+
> 🧪 The demo is built with Expo; swap the `uri` to test your own pages instantly.
1574
16-
```js
17-
import { multiply } from 'react-native-webview-sized';
75+
## ⚙️ API
1876

19-
// ...
77+
| Prop | Type | Default | Description |
78+
| --- | --- | --- | --- |
79+
| `minHeight` | `number` | `0` | Minimum height (dp) applied to the container to avoid layout jumps before content loads. |
80+
| `containerStyle` | `StyleProp<ViewStyle>` || Styles applied to the wrapping `View`. Use it for padding, borders, or shadows. |
81+
| `onHeightChange` | `(height: number) => void` || Callback fired whenever a new height is committed. Great for analytics or debugging. |
82+
| `...WebViewProps` ||| All remaining props are forwarded to the underlying `react-native-webview`. |
2083

21-
const result = await multiply(3, 7);
84+
> [!NOTE]
85+
> 🧩 `scrollEnabled` defaults to `false` so sizing remains deterministic. Only enable it if the WebView should manage its own scroll.
86+
87+
## 🧠 How It Works
88+
89+
- Injected bridge observes DOM mutations, layout changes, font loads, and viewport shifts.
90+
- Height calculations are debounced via `requestAnimationFrame` and a short idle timer to prevent resize storms.
91+
- Measurements arrive through `postMessage`, then `useAutoHeight` coalesces them into a single render per frame.
92+
- Package exports the bridge, hook, and helpers individually, making it easy to build bespoke wrappers when needed.
93+
94+
## ⚖️ Performance Snapshot
95+
96+
| Scenario | Plain `react-native-webview` | `react-native-sized-webview` |
97+
| --- | --- | --- |
98+
| Initial render layout shifts | Requires timers / manual height guesswork | Zero shifts; height resolved before paint |
99+
| React state updates on content change | Manual `postMessage` plumbing | Automatic bridge with RAF + debounce guard |
100+
| Scrolling in parent `ScrollView` | Nested scroll can fight gestures | Parent retains full momentum and gesture priority |
101+
102+
Benchmarks were captured on CMS articles up to 3k words in a 60 fps RN dev build. The bridge batches DOM mutations so even long documents resize without thrashing the JS thread.
103+
104+
## 🛠️ Local Development
105+
106+
```sh
107+
yarn
108+
yarn lint
109+
yarn typecheck
110+
yarn test --watch=false
111+
yarn example ios # or yarn example android
22112
```
23113

114+
This project uses [react-native-builder-bob](https://github.com/callstack/react-native-builder-bob) for packaging and [release-it](https://github.com/release-it/release-it) for publishing.
24115

25-
## Contributing
116+
## 🤝 Contributing
26117

27118
- [Development workflow](CONTRIBUTING.md#development-workflow)
28119
- [Sending a pull request](CONTRIBUTING.md#sending-a-pull-request)
29120
- [Code of conduct](CODE_OF_CONDUCT.md)
30121

31-
## License
122+
> [!CAUTION]
123+
> 🔬 Before submitting PRs that touch the bridge script, please test the example app on both iOS and Android to catch edge cases with interactive embeds.
124+
125+
## 🧑‍💻 Maintainer
32126

33-
MIT
127+
- Mateus Andrade ([@mCodex](https://github.com/mCodex))
34128

35-
---
129+
## 📄 License
36130

37-
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
131+
MIT © [Mateus Andrade](https://github.com/mCodex)

babel.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module.exports = {
2+
plugins: ['babel-plugin-react-compiler'],
23
overrides: [
34
{
45
exclude: /\/node_modules\//,

example/package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "react-native-webview-sized-example",
2+
"name": "react-native-sized-webview-example",
33
"version": "1.0.0",
44
"main": "index.js",
55
"scripts": {
@@ -10,16 +10,17 @@
1010
},
1111
"dependencies": {
1212
"@expo/metro-runtime": "~6.1.2",
13-
"expo": "~54.0.20",
13+
"expo": "~54.0.21",
1414
"expo-status-bar": "~3.0.8",
1515
"react": "19.1.0",
1616
"react-dom": "19.1.0",
1717
"react-native": "0.81.5",
18-
"react-native-web": "~0.21.0"
18+
"react-native-web": "~0.21.2",
19+
"react-native-webview": "^13.16.0"
1920
},
2021
"private": true,
2122
"devDependencies": {
22-
"react-native-builder-bob": "^0.40.13",
23-
"react-native-monorepo-config": "^0.1.9"
23+
"react-native-builder-bob": "^0.40.14",
24+
"react-native-monorepo-config": "^0.3.0"
2425
}
2526
}

0 commit comments

Comments
 (0)