Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 39 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ A simple blur view in react native based in [`@react-native-community/blur`](htt
</p>
</div>

> [!WARNING]
> This package supports **only** [new architecture](https://reactnative.dev/blog/2024/10/23/the-new-architecture-is-here).
> [!NOTE]
> This package supports **both** React Native architectures:
> - ✅ **New Architecture** (Fabric) - React Native 0.68+
> - ✅ **Old Architecture** (Paper) - React Native 0.60+
>
> The library automatically detects and adapts to your project's architecture. No configuration needed!

<p align="center">
<img
Expand Down Expand Up @@ -40,6 +44,7 @@ A simple blur view in react native based in [`@react-native-community/blur`](htt
- [Platform Differences](#platform-differences)
- [Android](#android)
- [iOS](#ios)
- [Architecture Compatibility](#architecture-compatibility)
- [Expo](#expo)
- [TypeScript Support](#typescript-support)
- [Contributing](#contributing)
Expand Down Expand Up @@ -235,9 +240,40 @@ Support the animation transitions with [react-native-screens](https://github.com

On iOS all types are supported by default. However, on Android they are RGBA colors to simulate the same blur color.

## Architecture Compatibility

This library works with **both** old and new React Native architectures out of the box!

### Automatic Detection

The library automatically detects your app's architecture:
- Uses **Fabric** components when new architecture is enabled
- Falls back to **Paper** (old architecture) components otherwise
- No configuration or code changes required!

### Migration Guide

When migrating between architectures, your code stays the same:

```tsx
// This code works in BOTH architectures! ✨
<BlurView targetId="target" style={styles.blurView}>
<Text>BlurView</Text>
</BlurView>
```

For detailed information about architecture compatibility, see [ARCHITECTURE_COMPATIBILITY.md](./ARCHITECTURE_COMPATIBILITY.md).

### Supported Versions

| Architecture | React Native Version | Status |
|--------------|---------------------|--------|
| Old (Paper) | 0.60 - 0.75+ | ✅ Supported |
| New (Fabric) | 0.68 - 0.79+ | ✅ Supported |

## Expo

In Expo, you need to convert to a [custom development build](https://docs.expo.dev/develop/development-builds/introduction/) or use [prebuild](https://docs.expo.dev/workflow/continuous-native-generation/). You can use also React Native without Expo.
In Expo, you need to convert to a [custom development build](https://docs.expo.dev/develop/development-builds/introduction/) or use [prebuild](https://docs.expo.dev/workflow/continuous-native-generation/). Works with both old and new architecture. You can also use React Native without Expo.

## TypeScript Support

Expand Down
22 changes: 5 additions & 17 deletions android/src/main/java/com/blurview/BlurViewManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,10 @@ package com.blurview
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.ViewGroupManager
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.viewmanagers.BlurViewManagerInterface
import com.facebook.react.viewmanagers.BlurViewManagerDelegate

@ReactModule(name = BlurViewManager.NAME)
class BlurViewManager : ViewGroupManager<BlurView>(),
BlurViewManagerInterface<BlurView> {
private val mDelegate: ViewManagerDelegate<BlurView> = BlurViewManagerDelegate(this)

override fun getDelegate(): ViewManagerDelegate<BlurView> {
return mDelegate
}
class BlurViewManager : ViewGroupManager<BlurView>() {

override fun getName(): String {
return NAME
Expand All @@ -29,21 +20,18 @@ class BlurViewManager : ViewGroupManager<BlurView>(),
const val NAME = "BlurView"
}

@Override
@ReactProp(name = "overlayColor")
override fun setOverlayColor(view: BlurView?, overlarColor: String?) {
view?.setOverlayColor(overlarColor ?: "light")
fun setOverlayColor(view: BlurView?, overlayColor: String?) {
view?.setOverlayColor(overlayColor ?: "light")
}

@Override
@ReactProp(name = "blurRadius", defaultFloat = 10f)
override fun setBlurRadius(view: BlurView?, radius: Float) {
fun setBlurRadius(view: BlurView?, radius: Float) {
view?.setRadius(radius)
}

@Override
@ReactProp(name = "targetId")
override fun setTargetId(view: BlurView?, targetId: String?) {
fun setTargetId(view: BlurView?, targetId: String?) {
view?.setTargetId(targetId)
}
}
Expand Down
12 changes: 12 additions & 0 deletions android/src/main/java/com/blurview/BlurViewManagerInterface.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.blurview

/**
* Interface for backward compatibility with old architecture.
* This provides the same contract as the Fabric-generated interface.
*/
interface BlurViewManagerInterface<T> {
fun setOverlayColor(view: T?, overlayColor: String?)
fun setBlurRadius(view: T?, radius: Float)
fun setTargetId(view: T?, targetId: String?)
}

14 changes: 2 additions & 12 deletions android/src/main/java/com/blurview/TargetViewManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,10 @@ package com.blurview
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.ViewGroupManager
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.viewmanagers.TargetViewManagerInterface
import com.facebook.react.viewmanagers.TargetViewManagerDelegate

@ReactModule(name = TargetViewManager.NAME)
class TargetViewManager : ViewGroupManager<TargetView>(),
TargetViewManagerInterface<TargetView> {
private val mDelegate: ViewManagerDelegate<TargetView> = TargetViewManagerDelegate(this)

override fun getDelegate(): ViewManagerDelegate<TargetView> {
return mDelegate
}
class TargetViewManager : ViewGroupManager<TargetView>() {

public override fun createViewInstance(context: ThemedReactContext): TargetView {
return TargetView(context)
Expand All @@ -29,9 +20,8 @@ class TargetViewManager : ViewGroupManager<TargetView>(),
const val NAME = "TargetView"
}

@Override
@ReactProp(name = "id")
override fun setId(view: TargetView?, id: String?) {
fun setId(view: TargetView?, id: String?) {
view?.setId(id)
}
}
10 changes: 10 additions & 0 deletions android/src/main/java/com/blurview/TargetViewManagerInterface.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.blurview

/**
* Interface for backward compatibility with old architecture.
* This provides the same contract as the Fabric-generated interface.
*/
interface TargetViewManagerInterface<T> {
fun setId(view: T?, id: String?)
}

27 changes: 27 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,33 @@ This is a new [**React Native**](https://reactnative.dev) project, bootstrapped

> **Note**: Make sure you have completed the [Set Up Your Environment](https://reactnative.dev/docs/set-up-your-environment) guide before proceeding.

## Architecture Support

This example app demonstrates the blur view library working with **React Native's New Architecture (Fabric)** enabled.

The library also supports the **Old Architecture (Paper)**. To test with old architecture:

**iOS**: In `ios/Podfile`, change:
```ruby
ENV['RCT_NEW_ARCH_ENABLED'] = '0' # or comment out the line
```

**Android**: In `android/gradle.properties`, change:
```properties
newArchEnabled=false # or remove the line
```

Then clean and rebuild:
```bash
# iOS
cd ios && rm -rf Pods Podfile.lock build && bundle exec pod install && cd ..

# Android
cd android && ./gradlew clean && cd ..
```

The app will work identically with both architectures! 🎉

## Step 1: Start Metro

First, you will need to run **Metro**, the JavaScript build tool for React Native.
Expand Down
5 changes: 4 additions & 1 deletion example/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# your application. You should enable this flag either if you want
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=true
#
# The blur view library supports BOTH old and new architecture.
# Set to true for new architecture, false for old architecture.
newArchEnabled=false

# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
Expand Down
5 changes: 4 additions & 1 deletion example/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
ENV['RCT_NEW_ARCH_ENABLED'] = '1'
# Enable or disable React Native's New Architecture (Fabric)
# The blur view library supports BOTH old and new architecture
# Set to '1' for new architecture, '0' or comment out for old architecture
# ENV['RCT_NEW_ARCH_ENABLED'] = '1' # Disabled - using old architecture

# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
Expand Down
61 changes: 55 additions & 6 deletions example/metro.config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,65 @@
const path = require('path');
const { getDefaultConfig } = require('@react-native/metro-config');
const { getConfig } = require('react-native-builder-bob/metro-config');
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');

const root = path.resolve(__dirname, '..');
const pak = require('../package.json');

/**
* Metro configuration
* https://facebook.github.io/metro/docs/configuration
*
* @type {import('metro-config').MetroConfig}
*/
module.exports = getConfig(getDefaultConfig(__dirname), {
root,
project: __dirname,
});
const config = {
projectRoot: __dirname,
watchFolders: [root],

// We need to make sure that only one version is loaded for peerDependencies
// So we block them at the root, and alias them to the versions in example's node_modules
resolver: {
blacklistRE: new RegExp(
`^${escape(path.join(root, 'node_modules'))}\\/.*$`
),

extraNodeModules: {
// Redirect the library package to the parent source
[pak.name]: path.join(root, 'src'),
// Redirect react-native from parent to example
'react-native': path.resolve(__dirname, 'node_modules/react-native'),
'react': path.resolve(__dirname, 'node_modules/react'),
},

// Tell Metro to resolve the library package from the parent directory
nodeModulesPaths: [
path.resolve(__dirname, 'node_modules'),
path.resolve(root, 'node_modules'),
],

// Resolve source files instead of built files
resolveRequest: (context, moduleName, platform) => {
if (moduleName === pak.name) {
return {
filePath: path.join(root, 'src', 'index.ts'),
type: 'sourceFile',
};
}
// Fallback to default resolution
return context.resolveRequest(context, moduleName, platform);
},
},

transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
};

function escape(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

module.exports = mergeConfig(getDefaultConfig(__dirname), config);
15 changes: 13 additions & 2 deletions ios/BlurView.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
#import <React/RCTViewComponentView.h>
#import <UIKit/UIKit.h>

#import "BlurViewEffect.h"

// Check if Fabric (new architecture) is available
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTViewComponentView.h>
#else
#import <React/RCTView.h>
#endif

#ifndef BlurViewNativeComponent_h
#define BlurViewNativeComponent_h

NS_ASSUME_NONNULL_BEGIN

#ifdef RCT_NEW_ARCH_ENABLED
// New architecture: inherit from RCTViewComponentView
@interface BlurView : RCTViewComponentView
#else
// Old architecture: inherit from UIView
@interface BlurView : UIView
#endif

@property(nonatomic, copy, nullable) NSString *overlayColor;
@property(nonatomic, copy, nullable) NSNumber *blurRadius;
Expand Down
Loading
Loading