@sbaiahmed1/react-native-blur 0.1.2 → 0.2.1
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 +174 -1
- package/android/app/build/generated/source/codegen/java/com/facebook/react/viewmanagers/ReactNativeGlassViewManagerDelegate.java +38 -0
- package/android/app/build/generated/source/codegen/java/com/facebook/react/viewmanagers/ReactNativeGlassViewManagerInterface.java +20 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/ReactNativeBlurViewSpec/ComponentDescriptors.cpp +1 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/ReactNativeBlurViewSpec/ComponentDescriptors.h +1 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/ReactNativeBlurViewSpec/EventEmitters.cpp +1 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/ReactNativeBlurViewSpec/EventEmitters.h +7 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/ReactNativeBlurViewSpec/Props.cpp +9 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/ReactNativeBlurViewSpec/Props.h +28 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/ReactNativeBlurViewSpec/ShadowNodes.cpp +1 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/ReactNativeBlurViewSpec/ShadowNodes.h +11 -0
- package/android/app/build/generated/source/codegen/jni/react/renderer/components/ReactNativeBlurViewSpec/States.h +12 -0
- package/android/src/main/java/com/sbaiahmed1/reactnativeblur/ReactNativeBlurView.kt +51 -28
- package/lib/module/BlurView.js +44 -9
- package/lib/module/BlurView.js.map +1 -1
- package/lib/typescript/src/BlurView.d.ts +6 -1
- package/lib/typescript/src/BlurView.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/BlurView.tsx +39 -10
package/README.md
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
# @sbaiahmed1/react-native-blur
|
|
2
2
|
|
|
3
3
|
A modern React Native blur view component that provides native blur effects for both iOS and Android platforms.
|
|
4
|
-
|
|
4
|
+
<div align="center">
|
|
5
|
+
<p>
|
|
6
|
+
<img src="https://img.shields.io/npm/v/@sbaiahmed1/react-native-blur?style=for-the-badge&color=blue" alt="npm version" />
|
|
7
|
+
<img src="https://img.shields.io/npm/dm/@sbaiahmed1/react-native-blur?style=for-the-badge&color=green" alt="downloads" />
|
|
8
|
+
<img src="https://img.shields.io/github/license/sbaiahmed1/react-native-blur?style=for-the-badge&color=orange" alt="license" />
|
|
9
|
+
<img src="https://img.shields.io/github/stars/sbaiahmed1/react-native-blur?style=for-the-badge&color=yellow" alt="stars" />
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p>
|
|
13
|
+
<img src="https://img.shields.io/badge/New%20Architecture-Ready-purple?style=for-the-badge" alt="New Architecture" />
|
|
14
|
+
</p>
|
|
15
|
+
</div>
|
|
5
16
|
## Demo
|
|
6
17
|
|
|
7
18
|
<div align="center">
|
|
@@ -23,6 +34,137 @@ A modern React Native blur view component that provides native blur effects for
|
|
|
23
34
|
- 🛠️ **Easy to Use**: Simple API for quick integration into your React Native projects
|
|
24
35
|
- 📦 **Modern**: Uses Kotlin for Android implementation and *will* use Swift for iOS, ensuring modern development practices
|
|
25
36
|
|
|
37
|
+
## 📊 Library Comparison
|
|
38
|
+
|
|
39
|
+
This section provides a detailed comparison between `@sbaiahmed1/react-native-blur` and other popular blur libraries in the React Native ecosystem.
|
|
40
|
+
|
|
41
|
+
### vs. [@react-native-community/blur](https://www.npmjs.com/package/@react-native-community/blur)
|
|
42
|
+
|
|
43
|
+
| Feature | @sbaiahmed1/react-native-blur | @react-native-community/blur |
|
|
44
|
+
|------------------------------|-------------------------------------|---------------------------------------|
|
|
45
|
+
| **New Architecture Support** | ✅ Full Fabric/Turbo Module support | ❌ Limited support (crashes on android |
|
|
46
|
+
| **Android Real Blur** | ✅ Hardware-accelerated real blur | ✅ Hardware-accelerated real blur |
|
|
47
|
+
| **iOS Blur Quality** | ✅ Native UIVisualEffectView | ✅ Native UIVisualEffectView |
|
|
48
|
+
| **TypeScript Support** | ✅ Full TypeScript definitions | ⚠️ Basic TypeScript support |
|
|
49
|
+
| **Maintenance Status** | ✅ Actively maintained | ⚠️ Community-maintained |
|
|
50
|
+
| **Bundle Size** | 🟡 Moderate (includes BlurView lib) | 🟡 Moderate (includes BlurView lib) |
|
|
51
|
+
| **API Complexity** | ✅ Simple, intuitive API | ✅ Simple API |
|
|
52
|
+
| **Performance** | ✅ Hardware-accelerated | 🟡 iOS: Good, Android: Limited |
|
|
53
|
+
| **Accessibility** | ✅ Full reduced transparency support | ✅ Reduced transparency support |
|
|
54
|
+
| **Documentation** | ✅ Comprehensive with examples | 🟡 Basic documentation |
|
|
55
|
+
|
|
56
|
+
**Advantages of @sbaiahmed1/react-native-blur:**
|
|
57
|
+
- **True Android Blur**: Unlike the community version which only provides semi-transparent overlays on Android, our library delivers real hardware-accelerated blur effects on both platforms
|
|
58
|
+
- **Future-Ready**: Built from the ground up with React Native's new architecture (Fabric) in mind
|
|
59
|
+
- **Modern Codebase**: Uses the latest development practices with Kotlin for Android
|
|
60
|
+
- ** Uses Swift**: Use of Swift for iOS, ensuring modern and efficient native code
|
|
61
|
+
- **Better Performance**: Hardware acceleration on both platforms ensures smooth rendering
|
|
62
|
+
- **Active Development**: Regular updates and feature additions
|
|
63
|
+
|
|
64
|
+
**When to choose @react-native-community/blur:**
|
|
65
|
+
- If you need a battle-tested library with extensive community usage
|
|
66
|
+
- If bundle size is a critical concern
|
|
67
|
+
- If you're working with older React Native versions
|
|
68
|
+
|
|
69
|
+
### vs. [expo-blur](https://www.npmjs.com/package/expo-blur)
|
|
70
|
+
|
|
71
|
+
| Feature | @sbaiahmed1/react-native-blur | expo-blur |
|
|
72
|
+
|---------|------------------------------|----------|
|
|
73
|
+
| **Expo Dependency** | ✅ No Expo required | ❌ Requires Expo SDK |
|
|
74
|
+
| **Bare React Native** | ✅ Works with any RN project | ⚠️ Requires Expo configuration |
|
|
75
|
+
| **Android Support** | ✅ Real blur effects | ❌ Semi-transparent view only |
|
|
76
|
+
| **iOS Support** | ✅ Full native blur support | ✅ Full native blur support |
|
|
77
|
+
| **Bundle Size** | 🟡 Moderate | ✅ Lightweight (when using Expo) |
|
|
78
|
+
| **Setup Complexity** | ✅ Simple npm install | 🟡 Requires Expo setup |
|
|
79
|
+
| **Customization** | ✅ Extensive blur type options | 🟡 Limited blur types |
|
|
80
|
+
| **New Architecture** | ✅ Full Fabric support | ✅ Expo handles compatibility |
|
|
81
|
+
| **Development Experience** | ✅ Standard RN development | ✅ Excellent with Expo tools |
|
|
82
|
+
| **Production Flexibility** | ✅ Any deployment method | 🟡 Expo-specific deployment |
|
|
83
|
+
|
|
84
|
+
**Advantages of @sbaiahmed1/react-native-blur:**
|
|
85
|
+
- **No Vendor Lock-in**: Works with any React Native project without requiring Expo ecosystem
|
|
86
|
+
- **Real Android Blur**: Provides actual blur effects on Android, not just transparency
|
|
87
|
+
- **Flexibility**: Can be used in brownfield apps, custom native modules, and any deployment scenario
|
|
88
|
+
- **More Blur Types**: Extensive support for iOS system materials and custom blur types
|
|
89
|
+
- **Direct Control**: Full control over native implementation without abstraction layers
|
|
90
|
+
|
|
91
|
+
**When to choose expo-blur:**
|
|
92
|
+
- If you're already using Expo and want ecosystem consistency
|
|
93
|
+
- If you prefer Expo's managed workflow and tooling
|
|
94
|
+
- If you only need basic blur effects and iOS-focused functionality
|
|
95
|
+
- If you want the simplicity of Expo's managed dependencies
|
|
96
|
+
|
|
97
|
+
### Performance Comparison
|
|
98
|
+
|
|
99
|
+
| Metric | @sbaiahmed1/react-native-blur | @react-native-community/blur | expo-blur |
|
|
100
|
+
|--------|------------------------------|------------------------------|----------|
|
|
101
|
+
| **iOS Rendering** | Hardware-accelerated | Hardware-accelerated | Hardware-accelerated |
|
|
102
|
+
| **Android Rendering** | Hardware-accelerated real blur | Software overlay | Software overlay |
|
|
103
|
+
| **Memory Usage** | Optimized with BlurView | Low | Low |
|
|
104
|
+
| **CPU Impact** | Low (GPU-based) | iOS: Low, Android: Minimal | iOS: Low, Android: Minimal |
|
|
105
|
+
| **Frame Rate Impact** | Minimal on both platforms | iOS: Minimal, Android: None | iOS: Minimal, Android: None |
|
|
106
|
+
|
|
107
|
+
### Community & Support
|
|
108
|
+
|
|
109
|
+
| Aspect | @sbaiahmed1/react-native-blur | @react-native-community/blur | expo-blur |
|
|
110
|
+
|--------|------------------------------|------------------------------|----------|
|
|
111
|
+
| **GitHub Stars** | 🆕 Growing | 🌟 Established (3.8k+) | 🌟 Part of Expo ecosystem |
|
|
112
|
+
| **Issue Response** | ✅ Active maintainer | 🟡 Community-driven | ✅ Expo team support |
|
|
113
|
+
| **Documentation Quality** | ✅ Comprehensive | 🟡 Basic | ✅ Excellent (Expo docs) |
|
|
114
|
+
| **Update Frequency** | ✅ Regular updates | 🟡 Sporadic | ✅ Regular (with Expo releases) |
|
|
115
|
+
| **Breaking Changes** | ✅ Semantic versioning | ⚠️ Occasional | ✅ Managed by Expo |
|
|
116
|
+
|
|
117
|
+
### Migration Guide
|
|
118
|
+
|
|
119
|
+
#### From @react-native-community/blur
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
// Before
|
|
123
|
+
import { BlurView } from '@react-native-community/blur';
|
|
124
|
+
|
|
125
|
+
// After
|
|
126
|
+
import { BlurView } from '@sbaiahmed1/react-native-blur';
|
|
127
|
+
|
|
128
|
+
// API is largely compatible, main differences:
|
|
129
|
+
// - Better Android blur quality
|
|
130
|
+
// - Additional iOS system material types
|
|
131
|
+
// - Improved TypeScript support
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### From expo-blur
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
// Before
|
|
138
|
+
import { BlurView } from 'expo-blur';
|
|
139
|
+
|
|
140
|
+
// After
|
|
141
|
+
import { BlurView } from '@sbaiahmed1/react-native-blur';
|
|
142
|
+
|
|
143
|
+
// Key differences:
|
|
144
|
+
// - More blur type options available
|
|
145
|
+
// - Real Android blur instead of transparency
|
|
146
|
+
// - No Expo dependency required
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Recommendation
|
|
150
|
+
|
|
151
|
+
**Choose @sbaiahmed1/react-native-blur if:**
|
|
152
|
+
- You want real blur effects on Android
|
|
153
|
+
- You're building for the new React Native architecture
|
|
154
|
+
- You need maximum flexibility and don't want vendor lock-in
|
|
155
|
+
- You want the latest performance optimizations
|
|
156
|
+
- You're starting a new project or can afford migration time
|
|
157
|
+
|
|
158
|
+
**Choose @react-native-community/blur if:**
|
|
159
|
+
- You have an existing project that works well with it
|
|
160
|
+
- Bundle size is critical and Android blur quality is not important
|
|
161
|
+
- You need maximum stability and community testing
|
|
162
|
+
|
|
163
|
+
**Choose expo-blur if:**
|
|
164
|
+
- You're already committed to the Expo ecosystem
|
|
165
|
+
- You only need iOS blur effects
|
|
166
|
+
- You prefer managed dependencies and simplified setup
|
|
167
|
+
|
|
26
168
|
## Architecture Compatibility
|
|
27
169
|
|
|
28
170
|
This library is fully compatible with both React Native architectures:
|
|
@@ -73,6 +215,26 @@ The Android implementation leverages the BlurView library to provide real blur e
|
|
|
73
215
|
- **Fallback Handling:** Gracefully handles devices with limited graphics capabilities
|
|
74
216
|
- **No Extra Permissions:** Does not require additional Android permissions
|
|
75
217
|
|
|
218
|
+
### Android Version Compatibility
|
|
219
|
+
|
|
220
|
+
This library automatically handles Android version compatibility to prevent `NoClassDefFoundError` issues:
|
|
221
|
+
|
|
222
|
+
- **Android 12+ (API 31+):** Uses `RenderEffectBlur` for optimal performance and modern blur effects
|
|
223
|
+
- **Android 10-11 (API 29-30):** Automatically falls back to `RenderScriptBlur` for compatibility
|
|
224
|
+
- **Older Android versions:** Graceful fallback to semi-transparent overlay when blur is not supported
|
|
225
|
+
|
|
226
|
+
**Note:** The library includes automatic API level detection and will choose the appropriate blur algorithm based on the device's Android version. This ensures compatibility across all supported Android versions without requiring any additional configuration.
|
|
227
|
+
|
|
228
|
+
#### Troubleshooting Android Issues
|
|
229
|
+
|
|
230
|
+
If you encounter `java.lang.NoClassDefFoundError: Failed resolution of: Landroid/graphics/RenderEffect;` on Android 10 or 11:
|
|
231
|
+
|
|
232
|
+
1. **This is automatically handled** - The library now includes fallback mechanisms
|
|
233
|
+
2. **Update to latest version** - Ensure you're using the latest version of this library
|
|
234
|
+
3. **Clean and rebuild** - Run `cd android && ./gradlew clean` then rebuild your project
|
|
235
|
+
|
|
236
|
+
The error occurs because `RenderEffect` was introduced in Android 12 (API 31), but the library now automatically detects the API level and uses compatible alternatives on older versions.
|
|
237
|
+
|
|
76
238
|
## Usage
|
|
77
239
|
|
|
78
240
|
### Basic Usage
|
|
@@ -217,6 +379,17 @@ See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the
|
|
|
217
379
|
|
|
218
380
|
MIT
|
|
219
381
|
|
|
382
|
+
## 📊 Stats
|
|
383
|
+
|
|
384
|
+
<div align="center">
|
|
385
|
+
<img src="https://img.shields.io/github/contributors/sbaiahmed1/react-native-blur?style=for-the-badge" alt="contributors" />
|
|
386
|
+
<img src="https://img.shields.io/github/last-commit/sbaiahmed1/react-native-blur?style=for-the-badge" alt="last commit" />
|
|
387
|
+
<img src="https://img.shields.io/github/issues/sbaiahmed1/react-native-blur?style=for-the-badge" alt="issues" />
|
|
388
|
+
<img src="https://img.shields.io/github/issues-pr/sbaiahmed1/react-native-blur?style=for-the-badge" alt="pull requests" />
|
|
389
|
+
</div>
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
220
393
|
## Credits
|
|
221
394
|
|
|
222
395
|
Built with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
|
|
@@ -0,0 +1,38 @@
|
|
|
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.uimanager.BaseViewManager;
|
|
15
|
+
import com.facebook.react.uimanager.BaseViewManagerDelegate;
|
|
16
|
+
import com.facebook.react.uimanager.LayoutShadowNode;
|
|
17
|
+
|
|
18
|
+
public class ReactNativeGlassViewManagerDelegate<T extends View, U extends BaseViewManager<T, ? extends LayoutShadowNode> & ReactNativeGlassViewManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
|
|
19
|
+
public ReactNativeGlassViewManagerDelegate(U viewManager) {
|
|
20
|
+
super(viewManager);
|
|
21
|
+
}
|
|
22
|
+
@Override
|
|
23
|
+
public void setProperty(T view, String propName, @Nullable Object value) {
|
|
24
|
+
switch (propName) {
|
|
25
|
+
case "glassType":
|
|
26
|
+
mViewManager.setGlassType(view, (String) value);
|
|
27
|
+
break;
|
|
28
|
+
case "glassAmount":
|
|
29
|
+
mViewManager.setGlassAmount(view, value == null ? 50f : ((Double) value).doubleValue());
|
|
30
|
+
break;
|
|
31
|
+
case "reducedTransparencyFallbackColor":
|
|
32
|
+
mViewManager.setReducedTransparencyFallbackColor(view, value == null ? null : (String) value);
|
|
33
|
+
break;
|
|
34
|
+
default:
|
|
35
|
+
super.setProperty(view, propName, value);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
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.uimanager.ViewManagerWithGeneratedInterface;
|
|
15
|
+
|
|
16
|
+
public interface ReactNativeGlassViewManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
|
|
17
|
+
void setGlassType(T view, @Nullable String value);
|
|
18
|
+
void setGlassAmount(T view, double value);
|
|
19
|
+
void setReducedTransparencyFallbackColor(T view, @Nullable String value);
|
|
20
|
+
}
|
|
@@ -17,6 +17,7 @@ namespace facebook::react {
|
|
|
17
17
|
void ReactNativeBlurViewSpec_registerComponentDescriptorsFromCodegen(
|
|
18
18
|
std::shared_ptr<const ComponentDescriptorProviderRegistry> registry) {
|
|
19
19
|
registry->add(concreteComponentDescriptorProvider<ReactNativeBlurViewComponentDescriptor>());
|
|
20
|
+
registry->add(concreteComponentDescriptorProvider<ReactNativeGlassViewComponentDescriptor>());
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
} // namespace facebook::react
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
namespace facebook::react {
|
|
18
18
|
|
|
19
19
|
using ReactNativeBlurViewComponentDescriptor = ConcreteComponentDescriptor<ReactNativeBlurViewShadowNode>;
|
|
20
|
+
using ReactNativeGlassViewComponentDescriptor = ConcreteComponentDescriptor<ReactNativeGlassViewShadowNode>;
|
|
20
21
|
|
|
21
22
|
void ReactNativeBlurViewSpec_registerComponentDescriptorsFromCodegen(
|
|
22
23
|
std::shared_ptr<const ComponentDescriptorProviderRegistry> registry);
|
|
@@ -19,5 +19,12 @@ class ReactNativeBlurViewEventEmitter : public ViewEventEmitter {
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
};
|
|
23
|
+
class ReactNativeGlassViewEventEmitter : public ViewEventEmitter {
|
|
24
|
+
public:
|
|
25
|
+
using ViewEventEmitter::ViewEventEmitter;
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
22
29
|
};
|
|
23
30
|
} // namespace facebook::react
|
|
@@ -23,5 +23,14 @@ ReactNativeBlurViewProps::ReactNativeBlurViewProps(
|
|
|
23
23
|
blurAmount(convertRawProp(context, rawProps, "blurAmount", sourceProps.blurAmount, {10.0})),
|
|
24
24
|
reducedTransparencyFallbackColor(convertRawProp(context, rawProps, "reducedTransparencyFallbackColor", sourceProps.reducedTransparencyFallbackColor, {}))
|
|
25
25
|
{}
|
|
26
|
+
ReactNativeGlassViewProps::ReactNativeGlassViewProps(
|
|
27
|
+
const PropsParserContext &context,
|
|
28
|
+
const ReactNativeGlassViewProps &sourceProps,
|
|
29
|
+
const RawProps &rawProps): ViewProps(context, sourceProps, rawProps),
|
|
30
|
+
|
|
31
|
+
glassType(convertRawProp(context, rawProps, "glassType", sourceProps.glassType, {ReactNativeGlassViewGlassType::Default})),
|
|
32
|
+
glassAmount(convertRawProp(context, rawProps, "glassAmount", sourceProps.glassAmount, {50.0})),
|
|
33
|
+
reducedTransparencyFallbackColor(convertRawProp(context, rawProps, "reducedTransparencyFallbackColor", sourceProps.reducedTransparencyFallbackColor, {}))
|
|
34
|
+
{}
|
|
26
35
|
|
|
27
36
|
} // namespace facebook::react
|
|
@@ -60,4 +60,32 @@ class ReactNativeBlurViewProps final : public ViewProps {
|
|
|
60
60
|
std::string reducedTransparencyFallbackColor{};
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
+
enum class ReactNativeGlassViewGlassType { Clear, Default };
|
|
64
|
+
|
|
65
|
+
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ReactNativeGlassViewGlassType &result) {
|
|
66
|
+
auto string = (std::string)value;
|
|
67
|
+
if (string == "clear") { result = ReactNativeGlassViewGlassType::Clear; return; }
|
|
68
|
+
if (string == "default") { result = ReactNativeGlassViewGlassType::Default; return; }
|
|
69
|
+
abort();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static inline std::string toString(const ReactNativeGlassViewGlassType &value) {
|
|
73
|
+
switch (value) {
|
|
74
|
+
case ReactNativeGlassViewGlassType::Clear: return "clear";
|
|
75
|
+
case ReactNativeGlassViewGlassType::Default: return "default";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
class ReactNativeGlassViewProps final : public ViewProps {
|
|
80
|
+
public:
|
|
81
|
+
ReactNativeGlassViewProps() = default;
|
|
82
|
+
ReactNativeGlassViewProps(const PropsParserContext& context, const ReactNativeGlassViewProps &sourceProps, const RawProps &rawProps);
|
|
83
|
+
|
|
84
|
+
#pragma mark - Props
|
|
85
|
+
|
|
86
|
+
ReactNativeGlassViewGlassType glassType{ReactNativeGlassViewGlassType::Default};
|
|
87
|
+
double glassAmount{50.0};
|
|
88
|
+
std::string reducedTransparencyFallbackColor{};
|
|
89
|
+
};
|
|
90
|
+
|
|
63
91
|
} // namespace facebook::react
|
|
@@ -29,4 +29,15 @@ using ReactNativeBlurViewShadowNode = ConcreteViewShadowNode<
|
|
|
29
29
|
ReactNativeBlurViewEventEmitter,
|
|
30
30
|
ReactNativeBlurViewState>;
|
|
31
31
|
|
|
32
|
+
JSI_EXPORT extern const char ReactNativeGlassViewComponentName[];
|
|
33
|
+
|
|
34
|
+
/*
|
|
35
|
+
* `ShadowNode` for <ReactNativeGlassView> component.
|
|
36
|
+
*/
|
|
37
|
+
using ReactNativeGlassViewShadowNode = ConcreteViewShadowNode<
|
|
38
|
+
ReactNativeGlassViewComponentName,
|
|
39
|
+
ReactNativeGlassViewProps,
|
|
40
|
+
ReactNativeGlassViewEventEmitter,
|
|
41
|
+
ReactNativeGlassViewState>;
|
|
42
|
+
|
|
32
43
|
} // namespace facebook::react
|
|
@@ -26,4 +26,16 @@ public:
|
|
|
26
26
|
#endif
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
class ReactNativeGlassViewState {
|
|
30
|
+
public:
|
|
31
|
+
ReactNativeGlassViewState() = default;
|
|
32
|
+
|
|
33
|
+
#ifdef ANDROID
|
|
34
|
+
ReactNativeGlassViewState(ReactNativeGlassViewState const &previousState, folly::dynamic data){};
|
|
35
|
+
folly::dynamic getDynamic() const {
|
|
36
|
+
return {};
|
|
37
|
+
};
|
|
38
|
+
#endif
|
|
39
|
+
};
|
|
40
|
+
|
|
29
41
|
} // namespace facebook::react
|
|
@@ -3,11 +3,13 @@ package com.sbaiahmed1.reactnativeblur
|
|
|
3
3
|
import android.content.Context
|
|
4
4
|
import android.graphics.Color
|
|
5
5
|
import android.graphics.drawable.ColorDrawable
|
|
6
|
+
import android.os.Build
|
|
6
7
|
import android.util.AttributeSet
|
|
7
8
|
import android.util.Log
|
|
8
9
|
import android.view.ViewGroup
|
|
9
10
|
import eightbitlab.com.blurview.BlurView
|
|
10
11
|
import eightbitlab.com.blurview.RenderEffectBlur
|
|
12
|
+
import eightbitlab.com.blurview.RenderScriptBlur
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Android implementation of React Native BlurView component.
|
|
@@ -210,27 +212,54 @@ class ReactNativeBlurView : BlurView {
|
|
|
210
212
|
val rootView = findRootView()
|
|
211
213
|
|
|
212
214
|
rootView?.let { root ->
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
215
|
+
try {
|
|
216
|
+
// Choose blur algorithm based on Android API level
|
|
217
|
+
val blurAlgorithm = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
218
|
+
// Android 12+ (API 31+): Use RenderEffectBlur for better performance
|
|
219
|
+
logDebug("Using RenderEffectBlur for API ${Build.VERSION.SDK_INT}")
|
|
220
|
+
RenderEffectBlur()
|
|
221
|
+
} else {
|
|
222
|
+
// Android 10-11 (API < 31): Use RenderScriptBlur for compatibility
|
|
223
|
+
logDebug("Using RenderScriptBlur for API ${Build.VERSION.SDK_INT}")
|
|
224
|
+
try {
|
|
225
|
+
RenderScriptBlur(context)
|
|
226
|
+
} catch (e: Exception) {
|
|
227
|
+
logWarning("RenderScriptBlur not supported on this device: ${e.message}")
|
|
228
|
+
// Fallback: return null to trigger transparent background fallback
|
|
229
|
+
throw UnsupportedOperationException("Blur not supported on this device", e)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Setup the blur view with the appropriate algorithm
|
|
234
|
+
this.setupWith(root, blurAlgorithm)
|
|
235
|
+
.setBlurRadius(blurRadius)
|
|
236
|
+
.setOverlayColor(overlayColor)
|
|
237
|
+
|
|
238
|
+
isSetup = true
|
|
239
|
+
pendingStyleUpdate = false
|
|
240
|
+
|
|
241
|
+
// Apply any pending background color after blur setup
|
|
242
|
+
if (hasExplicitBackground && originalBackgroundColor != null) {
|
|
243
|
+
logDebug("Applying pending background color: $originalBackgroundColor")
|
|
244
|
+
super.setBackgroundColor(originalBackgroundColor!!)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
logDebug("Blur setup successful with root: ${root.javaClass.simpleName}")
|
|
248
|
+
} catch (e: Exception) {
|
|
249
|
+
logWarning("Failed to setup blur algorithm: ${e.message}")
|
|
250
|
+
// Fallback: use semi-transparent overlay when blur is unsupported
|
|
251
|
+
super.setBackgroundColor(overlayColor)
|
|
252
|
+
isSetup = true // Mark as setup to prevent retry loops
|
|
225
253
|
}
|
|
226
|
-
|
|
227
|
-
logDebug("Blur setup successful with root: ${root.javaClass.simpleName}")
|
|
228
254
|
} ?: run {
|
|
229
255
|
logWarning("No suitable root view found for blur setup")
|
|
256
|
+
// Use semi-transparent overlay when no root view is available
|
|
257
|
+
super.setBackgroundColor(overlayColor)
|
|
258
|
+
isSetup = true
|
|
230
259
|
}
|
|
231
260
|
} catch (e: Exception) {
|
|
232
|
-
// Fallback:
|
|
233
|
-
super.setBackgroundColor(
|
|
261
|
+
// Fallback: use semi-transparent overlay to avoid visual issues
|
|
262
|
+
super.setBackgroundColor(overlayColor)
|
|
234
263
|
logError("Failed to setup blur: ${e.message}", e)
|
|
235
264
|
}
|
|
236
265
|
}
|
|
@@ -346,19 +375,13 @@ class ReactNativeBlurView : BlurView {
|
|
|
346
375
|
color?.let {
|
|
347
376
|
try {
|
|
348
377
|
val fallbackColor = Color.parseColor(it)
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
//
|
|
352
|
-
|
|
353
|
-
|
|
378
|
+
logDebug("setReducedTransparencyFallbackColor: $color -> $fallbackColor (stored but not applied unless accessibility requires it)")
|
|
379
|
+
|
|
380
|
+
// Store the fallback color but don't apply it unless accessibility settings require it
|
|
381
|
+
// For now, we'll just log it since Android doesn't have a direct equivalent to iOS's
|
|
382
|
+
// "Reduce Transparency" setting that we can easily check
|
|
383
|
+
// The blur effect should remain the primary visual
|
|
354
384
|
|
|
355
|
-
if (isSetup) {
|
|
356
|
-
try {
|
|
357
|
-
setOverlayColor(overlayColor)
|
|
358
|
-
} catch (e: Exception) {
|
|
359
|
-
logError("Failed to set fallback overlay color: ${e.message}", e)
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
385
|
} catch (e: Exception) {
|
|
363
386
|
logWarning("Invalid color format for reduced transparency fallback: $color")
|
|
364
387
|
}
|
package/lib/module/BlurView.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import React from 'react';
|
|
4
|
+
import { View } from 'react-native';
|
|
4
5
|
import ReactNativeBlurView from './ReactNativeBlurViewNativeComponent';
|
|
5
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
7
|
/**
|
|
7
8
|
* A cross-platform blur view component that provides native blur effects.
|
|
8
9
|
*
|
|
9
10
|
* On iOS, this uses UIVisualEffectView for true blur effects.
|
|
10
11
|
* On Android, this uses the BlurView library for hardware-accelerated blur effects.
|
|
11
12
|
*
|
|
13
|
+
* This component automatically handles the proper positioning pattern where the blur
|
|
14
|
+
* effect is positioned absolutely behind the content, ensuring interactive elements
|
|
15
|
+
* work correctly.
|
|
16
|
+
*
|
|
12
17
|
* @example
|
|
13
18
|
* ```tsx
|
|
14
19
|
* <BlurView
|
|
@@ -16,7 +21,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
16
21
|
* blurAmount={20}
|
|
17
22
|
* style={{ flex: 1 }}
|
|
18
23
|
* >
|
|
19
|
-
* <Text>Content
|
|
24
|
+
* <Text>Content on top of blur</Text>
|
|
25
|
+
* <Button title="Interactive Button" onPress={() => {}} />
|
|
20
26
|
* </BlurView>
|
|
21
27
|
* ```
|
|
22
28
|
*/
|
|
@@ -28,13 +34,42 @@ export const BlurView = ({
|
|
|
28
34
|
children,
|
|
29
35
|
...props
|
|
30
36
|
}) => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
// If no children, render the blur view directly (for background use)
|
|
38
|
+
if (React.Children.count(children) === 0) {
|
|
39
|
+
return /*#__PURE__*/_jsx(ReactNativeBlurView, {
|
|
40
|
+
blurType: blurType,
|
|
41
|
+
blurAmount: blurAmount,
|
|
42
|
+
reducedTransparencyFallbackColor: reducedTransparencyFallbackColor,
|
|
43
|
+
style: style,
|
|
44
|
+
...props
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// If children exist, use the absolute positioning pattern
|
|
49
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
50
|
+
style: [{
|
|
51
|
+
position: 'relative',
|
|
52
|
+
overflow: 'hidden'
|
|
53
|
+
}, style],
|
|
54
|
+
children: [/*#__PURE__*/_jsx(ReactNativeBlurView, {
|
|
55
|
+
blurType: blurType,
|
|
56
|
+
blurAmount: blurAmount,
|
|
57
|
+
reducedTransparencyFallbackColor: reducedTransparencyFallbackColor,
|
|
58
|
+
style: {
|
|
59
|
+
position: 'absolute',
|
|
60
|
+
top: 0,
|
|
61
|
+
left: 0,
|
|
62
|
+
right: 0,
|
|
63
|
+
bottom: 0
|
|
64
|
+
},
|
|
65
|
+
...props
|
|
66
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
67
|
+
style: {
|
|
68
|
+
position: 'relative',
|
|
69
|
+
zIndex: 1
|
|
70
|
+
},
|
|
71
|
+
children: children
|
|
72
|
+
})]
|
|
38
73
|
});
|
|
39
74
|
};
|
|
40
75
|
export default BlurView;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","ReactNativeBlurView","jsx","_jsx","BlurView","blurType","blurAmount","reducedTransparencyFallbackColor","style","children","props"],"sourceRoot":"../../src","sources":["BlurView.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;
|
|
1
|
+
{"version":3,"names":["React","View","ReactNativeBlurView","jsx","_jsx","jsxs","_jsxs","BlurView","blurType","blurAmount","reducedTransparencyFallbackColor","style","children","props","Children","count","position","overflow","top","left","right","bottom","zIndex"],"sourceRoot":"../../src","sources":["BlurView.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,QAAQ,cAAc;AAEnC,OAAOC,mBAAmB,MAEnB,sCAAsC;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAgC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,QAAiC,GAAGA,CAAC;EAChDC,QAAQ,GAAG,OAAO;EAClBC,UAAU,GAAG,EAAE;EACfC,gCAAgC;EAChCC,KAAK;EACLC,QAAQ;EACR,GAAGC;AACL,CAAC,KAAK;EACJ;EACA,IAAIb,KAAK,CAACc,QAAQ,CAACC,KAAK,CAACH,QAAQ,CAAC,KAAK,CAAC,EAAE;IACxC,oBACER,IAAA,CAACF,mBAAmB;MAClBM,QAAQ,EAAEA,QAAS;MACnBC,UAAU,EAAEA,UAAW;MACvBC,gCAAgC,EAAEA,gCAAiC;MACnEC,KAAK,EAAEA,KAAM;MAAA,GACTE;IAAK,CACV,CAAC;EAEN;;EAEA;EACA,oBACEP,KAAA,CAACL,IAAI;IAACU,KAAK,EAAE,CAAC;MAAEK,QAAQ,EAAE,UAAU;MAAEC,QAAQ,EAAE;IAAS,CAAC,EAAEN,KAAK,CAAE;IAAAC,QAAA,gBAEjER,IAAA,CAACF,mBAAmB;MAClBM,QAAQ,EAAEA,QAAS;MACnBC,UAAU,EAAEA,UAAW;MACvBC,gCAAgC,EAAEA,gCAAiC;MACnEC,KAAK,EAAE;QACLK,QAAQ,EAAE,UAAU;QACpBE,GAAG,EAAE,CAAC;QACNC,IAAI,EAAE,CAAC;QACPC,KAAK,EAAE,CAAC;QACRC,MAAM,EAAE;MACV,CAAE;MAAA,GACER;IAAK,CACV,CAAC,eAEFT,IAAA,CAACH,IAAI;MAACU,KAAK,EAAE;QAAEK,QAAQ,EAAE,UAAU;QAAEM,MAAM,EAAE;MAAE,CAAE;MAAAV,QAAA,EAAEA;IAAQ,CAAO,CAAC;EAAA,CAC/D,CAAC;AAEX,CAAC;AAED,eAAeL,QAAQ","ignoreList":[]}
|
|
@@ -32,6 +32,10 @@ export interface BlurViewProps {
|
|
|
32
32
|
* On iOS, this uses UIVisualEffectView for true blur effects.
|
|
33
33
|
* On Android, this uses the BlurView library for hardware-accelerated blur effects.
|
|
34
34
|
*
|
|
35
|
+
* This component automatically handles the proper positioning pattern where the blur
|
|
36
|
+
* effect is positioned absolutely behind the content, ensuring interactive elements
|
|
37
|
+
* work correctly.
|
|
38
|
+
*
|
|
35
39
|
* @example
|
|
36
40
|
* ```tsx
|
|
37
41
|
* <BlurView
|
|
@@ -39,7 +43,8 @@ export interface BlurViewProps {
|
|
|
39
43
|
* blurAmount={20}
|
|
40
44
|
* style={{ flex: 1 }}
|
|
41
45
|
* >
|
|
42
|
-
* <Text>Content
|
|
46
|
+
* <Text>Content on top of blur</Text>
|
|
47
|
+
* <Button title="Interactive Button" onPress={() => {}} />
|
|
43
48
|
* </BlurView>
|
|
44
49
|
* ```
|
|
45
50
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlurView.d.ts","sourceRoot":"","sources":["../../../src/BlurView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"BlurView.d.ts","sourceRoot":"","sources":["../../../src/BlurView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzD,OAA4B,EAC1B,KAAK,QAAQ,EACd,MAAM,sCAAsC,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAE1C;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA0C5C,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sbaiahmed1/react-native-blur",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "React native modern blur view",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
39
39
|
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
40
40
|
"prepare": "bob build",
|
|
41
|
-
"release": "release-it
|
|
41
|
+
"release": "release-it"
|
|
42
42
|
},
|
|
43
43
|
"keywords": [
|
|
44
44
|
"react-native",
|
package/src/BlurView.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
2
3
|
import type { ViewStyle, StyleProp } from 'react-native';
|
|
3
4
|
import ReactNativeBlurView, {
|
|
4
5
|
type BlurType,
|
|
@@ -40,6 +41,10 @@ export interface BlurViewProps {
|
|
|
40
41
|
* On iOS, this uses UIVisualEffectView for true blur effects.
|
|
41
42
|
* On Android, this uses the BlurView library for hardware-accelerated blur effects.
|
|
42
43
|
*
|
|
44
|
+
* This component automatically handles the proper positioning pattern where the blur
|
|
45
|
+
* effect is positioned absolutely behind the content, ensuring interactive elements
|
|
46
|
+
* work correctly.
|
|
47
|
+
*
|
|
43
48
|
* @example
|
|
44
49
|
* ```tsx
|
|
45
50
|
* <BlurView
|
|
@@ -47,7 +52,8 @@ export interface BlurViewProps {
|
|
|
47
52
|
* blurAmount={20}
|
|
48
53
|
* style={{ flex: 1 }}
|
|
49
54
|
* >
|
|
50
|
-
* <Text>Content
|
|
55
|
+
* <Text>Content on top of blur</Text>
|
|
56
|
+
* <Button title="Interactive Button" onPress={() => {}} />
|
|
51
57
|
* </BlurView>
|
|
52
58
|
* ```
|
|
53
59
|
*/
|
|
@@ -59,16 +65,39 @@ export const BlurView: React.FC<BlurViewProps> = ({
|
|
|
59
65
|
children,
|
|
60
66
|
...props
|
|
61
67
|
}) => {
|
|
68
|
+
// If no children, render the blur view directly (for background use)
|
|
69
|
+
if (React.Children.count(children) === 0) {
|
|
70
|
+
return (
|
|
71
|
+
<ReactNativeBlurView
|
|
72
|
+
blurType={blurType}
|
|
73
|
+
blurAmount={blurAmount}
|
|
74
|
+
reducedTransparencyFallbackColor={reducedTransparencyFallbackColor}
|
|
75
|
+
style={style}
|
|
76
|
+
{...props}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// If children exist, use the absolute positioning pattern
|
|
62
82
|
return (
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
83
|
+
<View style={[{ position: 'relative', overflow: 'hidden' }, style]}>
|
|
84
|
+
{/* Blur effect positioned absolutely behind content */}
|
|
85
|
+
<ReactNativeBlurView
|
|
86
|
+
blurType={blurType}
|
|
87
|
+
blurAmount={blurAmount}
|
|
88
|
+
reducedTransparencyFallbackColor={reducedTransparencyFallbackColor}
|
|
89
|
+
style={{
|
|
90
|
+
position: 'absolute',
|
|
91
|
+
top: 0,
|
|
92
|
+
left: 0,
|
|
93
|
+
right: 0,
|
|
94
|
+
bottom: 0,
|
|
95
|
+
}}
|
|
96
|
+
{...props}
|
|
97
|
+
/>
|
|
98
|
+
{/* Content positioned relatively on top */}
|
|
99
|
+
<View style={{ position: 'relative', zIndex: 1 }}>{children}</View>
|
|
100
|
+
</View>
|
|
72
101
|
);
|
|
73
102
|
};
|
|
74
103
|
|