@sbaiahmed1/react-native-blur 0.2.1 → 0.3.0-beta.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.
- package/README.md +124 -20
- package/ReactNativeBlur.podspec +2 -1
- package/android/src/main/java/com/sbaiahmed1/reactnativeblur/ReactNativeBlurView.kt +142 -46
- package/android/src/main/java/com/sbaiahmed1/reactnativeblur/ReactNativeBlurViewManager.kt +20 -0
- package/ios/ReactNativeBlurView.mm +190 -238
- package/ios/ReactNativeBlurView.swift +309 -0
- package/ios/ReactNativeBlurViewManager.h +5 -0
- package/ios/ReactNativeBlurViewManager.m +165 -0
- package/lib/module/BlurView.js +14 -2
- package/lib/module/BlurView.js.map +1 -1
- package/lib/module/ReactNativeBlurViewNativeComponent.ts +9 -3
- package/lib/typescript/src/BlurView.d.ts +30 -1
- package/lib/typescript/src/BlurView.d.ts.map +1 -1
- package/lib/typescript/src/ReactNativeBlurViewNativeComponent.d.ts +8 -3
- package/lib/typescript/src/ReactNativeBlurViewNativeComponent.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/BlurView.tsx +48 -3
- package/src/ReactNativeBlurViewNativeComponent.ts +9 -3
- package/ios/ReactNativeBlurViewManager.mm +0 -23
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @sbaiahmed1/react-native-blur
|
|
2
2
|
|
|
3
|
-
A modern React Native blur view component that provides native blur effects for both iOS and Android platforms.
|
|
3
|
+
A modern React Native blur view component that provides native blur effects and **liquid glass effects** for both iOS and Android platforms.
|
|
4
4
|
<div align="center">
|
|
5
5
|
<p>
|
|
6
6
|
<img src="https://img.shields.io/npm/v/@sbaiahmed1/react-native-blur?style=for-the-badge&color=blue" alt="npm version" />
|
|
@@ -11,28 +11,44 @@ A modern React Native blur view component that provides native blur effects for
|
|
|
11
11
|
|
|
12
12
|
<p>
|
|
13
13
|
<img src="https://img.shields.io/badge/New%20Architecture-Ready-purple?style=for-the-badge" alt="New Architecture" />
|
|
14
|
+
<img src="https://img.shields.io/badge/iOS%2026+-Liquid%20Glass-blue?style=for-the-badge" alt="Liquid Glass" />
|
|
15
|
+
<img src="https://img.shields.io/badge/SwiftUI-Powered-orange?style=for-the-badge" alt="SwiftUI" />
|
|
14
16
|
</p>
|
|
15
17
|
</div>
|
|
16
|
-
|
|
18
|
+
|
|
19
|
+
## Liquid Glass Demo
|
|
20
|
+
|
|
21
|
+
<div align="center">
|
|
22
|
+
<img src="liquidGlass.gif" alt="Liquid Glass Demo" width="300" />
|
|
23
|
+
<br>
|
|
24
|
+
<em>Liquid Glass effect in action</em>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
## Blur Demo
|
|
17
28
|
|
|
18
29
|
<div align="center">
|
|
19
30
|
<img src="iOS-demo.gif" alt="iOS Demo" width="300" />
|
|
20
31
|
<img src="android-demo.gif" alt="Android Demo" width="300" />
|
|
32
|
+
|
|
21
33
|
<br>
|
|
22
34
|
<em>iOS (left) and Android (right) blur effects in action</em>
|
|
23
35
|
</div>
|
|
24
36
|
|
|
37
|
+
|
|
38
|
+
|
|
25
39
|
## Features
|
|
26
40
|
|
|
41
|
+
- 🌊 **Liquid Glass Effects**: Revolutionary glass effects using iOS 26+ UIGlassEffect API
|
|
27
42
|
- 🎨 **Multiple Blur Types**: Support for various blur styles including system materials on iOS
|
|
28
43
|
- 📱 **Cross-Platform**: Works on both iOS and Android
|
|
29
44
|
- ♿ **Accessibility**: Automatic fallback for reduced transparency settings
|
|
30
45
|
- 🔧 **TypeScript**: Full TypeScript support with proper type definitions
|
|
31
46
|
- 🚀 **Turbo Module**: Built with React Native's new architecture (Fabric)
|
|
32
|
-
- 🎯 **Customizable**: Adjustable blur intensity
|
|
47
|
+
- 🎯 **Customizable**: Adjustable blur intensity, glass tint colors, and opacity
|
|
33
48
|
- 💡 **Performance Optimized**: Uses hardware acceleration for smooth rendering
|
|
34
49
|
- 🛠️ **Easy to Use**: Simple API for quick integration into your React Native projects
|
|
35
|
-
- 📦 **Modern**: Uses
|
|
50
|
+
- 📦 **Modern**: Uses SwiftUI for iOS and Kotlin for Android, ensuring cutting-edge development practices
|
|
51
|
+
- 🔄 **Smart Fallbacks**: Graceful degradation from liquid glass to blur on older iOS versions
|
|
36
52
|
|
|
37
53
|
## 📊 Library Comparison
|
|
38
54
|
|
|
@@ -43,8 +59,9 @@ This section provides a detailed comparison between `@sbaiahmed1/react-native-bl
|
|
|
43
59
|
| Feature | @sbaiahmed1/react-native-blur | @react-native-community/blur |
|
|
44
60
|
|------------------------------|-------------------------------------|---------------------------------------|
|
|
45
61
|
| **New Architecture Support** | ✅ Full Fabric/Turbo Module support | ❌ Limited support (crashes on android |
|
|
46
|
-
| **Android Real Blur** | ✅ Hardware-accelerated real blur
|
|
62
|
+
| **Android Real Blur** | ✅ Hardware-accelerated real blur (including liquid glass) | ✅ Hardware-accelerated real blur |
|
|
47
63
|
| **iOS Blur Quality** | ✅ Native UIVisualEffectView | ✅ Native UIVisualEffectView |
|
|
64
|
+
| **Liquid Glass Effects** | ✅ Full support (iOS 26+ UIGlassEffect & Android) | ❌ Not supported |
|
|
48
65
|
| **TypeScript Support** | ✅ Full TypeScript definitions | ⚠️ Basic TypeScript support |
|
|
49
66
|
| **Maintenance Status** | ✅ Actively maintained | ⚠️ Community-maintained |
|
|
50
67
|
| **Bundle Size** | 🟡 Moderate (includes BlurView lib) | 🟡 Moderate (includes BlurView lib) |
|
|
@@ -54,7 +71,7 @@ This section provides a detailed comparison between `@sbaiahmed1/react-native-bl
|
|
|
54
71
|
| **Documentation** | ✅ Comprehensive with examples | 🟡 Basic documentation |
|
|
55
72
|
|
|
56
73
|
**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
|
|
74
|
+
- **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, including liquid glass effects.
|
|
58
75
|
- **Future-Ready**: Built from the ground up with React Native's new architecture (Fabric) in mind
|
|
59
76
|
- **Modern Codebase**: Uses the latest development practices with Kotlin for Android
|
|
60
77
|
- ** Uses Swift**: Use of Swift for iOS, ensuring modern and efficient native code
|
|
@@ -74,6 +91,7 @@ This section provides a detailed comparison between `@sbaiahmed1/react-native-bl
|
|
|
74
91
|
| **Bare React Native** | ✅ Works with any RN project | ⚠️ Requires Expo configuration |
|
|
75
92
|
| **Android Support** | ✅ Real blur effects | ❌ Semi-transparent view only |
|
|
76
93
|
| **iOS Support** | ✅ Full native blur support | ✅ Full native blur support |
|
|
94
|
+
| **Liquid Glass Effects** | ✅ Full support (iOS 26+ UIGlassEffect & Android) | ❌ Not supported |
|
|
77
95
|
| **Bundle Size** | 🟡 Moderate | ✅ Lightweight (when using Expo) |
|
|
78
96
|
| **Setup Complexity** | ✅ Simple npm install | 🟡 Requires Expo setup |
|
|
79
97
|
| **Customization** | ✅ Extensive blur type options | 🟡 Limited blur types |
|
|
@@ -83,7 +101,7 @@ This section provides a detailed comparison between `@sbaiahmed1/react-native-bl
|
|
|
83
101
|
|
|
84
102
|
**Advantages of @sbaiahmed1/react-native-blur:**
|
|
85
103
|
- **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
|
|
104
|
+
- **Real Android Blur**: Provides actual blur effects on Android, not just transparency, including liquid glass effects.
|
|
87
105
|
- **Flexibility**: Can be used in brownfield apps, custom native modules, and any deployment scenario
|
|
88
106
|
- **More Blur Types**: Extensive support for iOS system materials and custom blur types
|
|
89
107
|
- **Direct Control**: Full control over native implementation without abstraction layers
|
|
@@ -149,7 +167,7 @@ import { BlurView } from '@sbaiahmed1/react-native-blur';
|
|
|
149
167
|
### Recommendation
|
|
150
168
|
|
|
151
169
|
**Choose @sbaiahmed1/react-native-blur if:**
|
|
152
|
-
- You want real blur effects on Android
|
|
170
|
+
- You want real blur effects on Android, including liquid glass effects.
|
|
153
171
|
- You're building for the new React Native architecture
|
|
154
172
|
- You need maximum flexibility and don't want vendor lock-in
|
|
155
173
|
- You want the latest performance optimizations
|
|
@@ -289,16 +307,48 @@ function MyComponent() {
|
|
|
289
307
|
}
|
|
290
308
|
```
|
|
291
309
|
|
|
310
|
+
### Liquid Glass Usage (iOS 26+)
|
|
311
|
+
|
|
312
|
+
```tsx
|
|
313
|
+
import React from 'react';
|
|
314
|
+
import { BlurView } from '@sbaiahmed1/react-native-blur';
|
|
315
|
+
|
|
316
|
+
function LiquidGlassComponent() {
|
|
317
|
+
return (
|
|
318
|
+
<BlurView
|
|
319
|
+
type="liquidGlass"
|
|
320
|
+
glassType="regular"
|
|
321
|
+
glassTintColor="#007AFF"
|
|
322
|
+
glassOpacity={0.8}
|
|
323
|
+
style={{
|
|
324
|
+
padding: 20,
|
|
325
|
+
borderRadius: 20,
|
|
326
|
+
}}
|
|
327
|
+
>
|
|
328
|
+
<Text>Beautiful liquid glass effect</Text>
|
|
329
|
+
</BlurView>
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
292
334
|
## Props
|
|
293
335
|
|
|
336
|
+
All props are optional and have sensible defaults.
|
|
337
|
+
|
|
294
338
|
| Prop | Type | Default | Description |
|
|
295
339
|
|------|------|---------|-------------|
|
|
296
|
-
| `
|
|
297
|
-
| `
|
|
298
|
-
| `
|
|
340
|
+
| `type` | `'blur' \| 'liquidGlass'` | `'blur'` | The type of effect to apply |
|
|
341
|
+
| `blurType` | `BlurType` | `'xlight'` | The type of blur effect to apply |
|
|
342
|
+
| `blurAmount` | `number` | `10.0` | The intensity of the blur effect (0-100) |
|
|
343
|
+
| `glassType` | `GlassType` | `'clear'` | The type of glass effect |
|
|
344
|
+
| `glassTintColor` | `string` | `'clear'` | The tint color for glass effect |
|
|
345
|
+
| `glassOpacity` | `number` | `1.0` | The opacity of glass effect (0-1) |
|
|
346
|
+
| `reducedTransparencyFallbackColor` | `string` | `'#FFFFFF'` | Fallback color when reduced transparency is enabled |
|
|
299
347
|
| `style` | `ViewStyle` | `undefined` | Style object for the blur view |
|
|
300
348
|
| `children` | `ReactNode` | `undefined` | Child components to render inside the blur view |
|
|
301
349
|
|
|
350
|
+
> **Note**: The `BlurType` and `GlassType` are exported types from the library. See [Blur Types](#blur-types) section below for all available values.
|
|
351
|
+
|
|
302
352
|
## Blur Types
|
|
303
353
|
|
|
304
354
|
The following blur types are supported:
|
|
@@ -321,10 +371,15 @@ The following blur types are supported:
|
|
|
321
371
|
## Platform Differences
|
|
322
372
|
|
|
323
373
|
### iOS
|
|
324
|
-
On iOS, this component
|
|
374
|
+
On iOS, this component has been completely rewritten using **SwiftUI** for modern performance and features:
|
|
375
|
+
|
|
376
|
+
- **iOS 26+**: Uses native `UIGlassEffect` API for true liquid glass effects with customizable tint colors and opacity
|
|
377
|
+
- **iOS 13-25**: Uses enhanced `UIVisualEffectView` with precise blur intensity control
|
|
378
|
+
- **Older iOS**: Graceful fallback to standard blur effects
|
|
379
|
+
- **SwiftUI Integration**: Leverages SwiftUI's declarative UI for better performance and maintainability
|
|
325
380
|
|
|
326
381
|
### Android
|
|
327
|
-
On Android, the component uses the BlurView library to provide real blur effects with hardware acceleration. The implementation supports multiple blur algorithms and gracefully falls back to translucent overlay approximation on devices with limited graphics capabilities.
|
|
382
|
+
On Android, the component uses the BlurView library to provide real blur effects with hardware acceleration. The implementation supports multiple blur algorithms and gracefully falls back to translucent overlay approximation on devices with limited graphics capabilities. Liquid glass effects fall back to enhanced blur with tint overlay.
|
|
328
383
|
|
|
329
384
|
## Accessibility
|
|
330
385
|
|
|
@@ -340,36 +395,85 @@ You can customize the fallback color using the `reducedTransparencyFallbackColor
|
|
|
340
395
|
This package includes full TypeScript definitions:
|
|
341
396
|
|
|
342
397
|
```tsx
|
|
343
|
-
import { BlurView, BlurType, BlurViewProps } from '@sbaiahmed1/react-native-blur';
|
|
398
|
+
import { BlurView, BlurType, GlassType, BlurViewProps } from '@sbaiahmed1/react-native-blur';
|
|
344
399
|
|
|
345
400
|
// BlurType is exported for type checking
|
|
346
401
|
const blurType: BlurType = 'systemMaterial';
|
|
347
402
|
|
|
403
|
+
// GlassType for liquid glass effects
|
|
404
|
+
const glassType: GlassType = 'regular';
|
|
405
|
+
|
|
348
406
|
// BlurViewProps for component props
|
|
349
407
|
interface MyComponentProps {
|
|
350
408
|
blurProps: BlurViewProps;
|
|
351
409
|
}
|
|
410
|
+
|
|
411
|
+
// Example with all liquid glass properties
|
|
412
|
+
const liquidGlassProps: BlurViewProps = {
|
|
413
|
+
type: 'liquidGlass',
|
|
414
|
+
glassType: 'regular',
|
|
415
|
+
glassTintColor: '#007AFF',
|
|
416
|
+
glassOpacity: 0.8,
|
|
417
|
+
};
|
|
352
418
|
```
|
|
353
419
|
|
|
354
420
|
## Example App
|
|
355
421
|
|
|
356
|
-
The package includes a comprehensive example app that demonstrates all blur types and
|
|
422
|
+
The package includes a comprehensive example app that demonstrates all blur types, liquid glass effects, and practical use cases. The example app features:
|
|
423
|
+
|
|
424
|
+
- **Main Demo**: Interactive blur type selector with live preview
|
|
425
|
+
- **Liquid Glass Examples**: Showcase of iOS 26+ glass effects with customizable properties
|
|
426
|
+
- **Practical Use Cases**: Real-world examples like cards, modals, and overlays
|
|
427
|
+
- **Comparison Views**: Side-by-side comparisons of different effects
|
|
428
|
+
|
|
429
|
+
To run the example:
|
|
357
430
|
|
|
358
431
|
```bash
|
|
359
432
|
cd example
|
|
360
|
-
|
|
433
|
+
yarn install
|
|
361
434
|
# For iOS
|
|
362
|
-
|
|
435
|
+
yarn ios
|
|
363
436
|
# For Android
|
|
364
|
-
|
|
437
|
+
yarn android
|
|
365
438
|
```
|
|
366
439
|
|
|
367
440
|
## Performance Considerations
|
|
368
441
|
|
|
369
|
-
- **iOS**:
|
|
442
|
+
- **iOS**:
|
|
443
|
+
- **SwiftUI Implementation**: Enhanced performance with declarative UI updates
|
|
444
|
+
- **Liquid Glass (iOS 26+)**: Hardware-accelerated glass effects with minimal performance impact
|
|
445
|
+
- **Blur Effects**: Native blur effects are hardware-accelerated and performant
|
|
446
|
+
- **Smart Fallbacks**: Automatic degradation ensures smooth performance on older devices
|
|
370
447
|
- **Android**: Real blur effects are hardware-accelerated with fallback to lightweight overlay when needed
|
|
371
|
-
- Avoid using too many blur views simultaneously on lower-end devices
|
|
448
|
+
- Avoid using too many blur/glass views simultaneously on lower-end devices
|
|
372
449
|
- Consider using `reducedTransparencyFallbackColor` for better accessibility
|
|
450
|
+
- Liquid glass effects automatically fall back to enhanced blur on Android and older iOS versions
|
|
451
|
+
|
|
452
|
+
## What's New in v0.3.0
|
|
453
|
+
|
|
454
|
+
### 🌊 Liquid Glass Effects (iOS 26+)
|
|
455
|
+
- Revolutionary glass effects using Apple's new UIGlassEffect API
|
|
456
|
+
- Customizable glass types: `clear` and `regular`
|
|
457
|
+
- Adjustable tint colors and opacity for stunning visual effects
|
|
458
|
+
- Automatic fallback to enhanced blur on older iOS versions and Android
|
|
459
|
+
|
|
460
|
+
### 🔄 SwiftUI Rewrite
|
|
461
|
+
- Complete iOS implementation rewritten using SwiftUI
|
|
462
|
+
- Enhanced performance with declarative UI updates
|
|
463
|
+
- Better integration with React Native's new architecture
|
|
464
|
+
- Improved blur intensity control with precise animation handling
|
|
465
|
+
|
|
466
|
+
### 📱 Enhanced Example App
|
|
467
|
+
- New liquid glass demonstration section
|
|
468
|
+
- Interactive property controls for real-time customization
|
|
469
|
+
- Practical use case examples (cards, modals, overlays)
|
|
470
|
+
- Comparison views for different effect types
|
|
471
|
+
|
|
472
|
+
### 🛠️ Developer Experience
|
|
473
|
+
- Full TypeScript support for all new properties
|
|
474
|
+
- Improved component layout handling
|
|
475
|
+
- Better accessibility support with smart fallbacks
|
|
476
|
+
- Enhanced documentation and examples
|
|
373
477
|
|
|
374
478
|
## Contributing
|
|
375
479
|
|
package/ReactNativeBlur.podspec
CHANGED
|
@@ -13,7 +13,8 @@ Pod::Spec.new do |s|
|
|
|
13
13
|
s.platforms = { :ios => min_ios_version_supported }
|
|
14
14
|
s.source = { :git => "https://github.com/sbaiahmed1/sbaiahmed1-react-native-blur.git", :tag => "#{s.version}" }
|
|
15
15
|
|
|
16
|
-
s.source_files = "ios/**/*.{h,m,mm,cpp}"
|
|
16
|
+
s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
|
|
17
|
+
s.swift_version = '5.0'
|
|
17
18
|
s.private_header_files = "ios/**/*.h"
|
|
18
19
|
|
|
19
20
|
install_modules_dependencies(s)
|
|
@@ -22,6 +22,10 @@ class ReactNativeBlurView : BlurView {
|
|
|
22
22
|
private var pendingStyleUpdate: Boolean = false
|
|
23
23
|
private var originalBackgroundColor: Int? = null
|
|
24
24
|
private var hasExplicitBackground: Boolean = false
|
|
25
|
+
private var glassTintColor: Int = Color.TRANSPARENT
|
|
26
|
+
private var glassOpacity: Float = 1.0f
|
|
27
|
+
private var viewType: String = "blur"
|
|
28
|
+
private var glassType: String = "clear"
|
|
25
29
|
|
|
26
30
|
companion object {
|
|
27
31
|
private const val TAG = "ReactNativeBlurView"
|
|
@@ -29,26 +33,26 @@ class ReactNativeBlurView : BlurView {
|
|
|
29
33
|
private const val MAX_BLUR_RADIUS = 25f
|
|
30
34
|
private const val DEFAULT_BLUR_RADIUS = 10f
|
|
31
35
|
private const val DEBUG = false // Set to true for debug builds
|
|
32
|
-
|
|
36
|
+
|
|
33
37
|
// Cross-platform blur amount constants
|
|
34
38
|
private const val MIN_BLUR_AMOUNT = 0f
|
|
35
39
|
private const val MAX_BLUR_AMOUNT = 100f
|
|
36
40
|
private const val DEFAULT_BLUR_AMOUNT = 10f
|
|
37
|
-
|
|
41
|
+
|
|
38
42
|
private fun logDebug(message: String) {
|
|
39
43
|
if (DEBUG) {
|
|
40
44
|
Log.d(TAG, message)
|
|
41
45
|
}
|
|
42
46
|
}
|
|
43
|
-
|
|
47
|
+
|
|
44
48
|
private fun logWarning(message: String) {
|
|
45
49
|
Log.w(TAG, message)
|
|
46
50
|
}
|
|
47
|
-
|
|
51
|
+
|
|
48
52
|
private fun logError(message: String, throwable: Throwable? = null) {
|
|
49
53
|
Log.e(TAG, message, throwable)
|
|
50
54
|
}
|
|
51
|
-
|
|
55
|
+
|
|
52
56
|
/**
|
|
53
57
|
* Maps blur amount (0-100) to Android blur radius (0-25).
|
|
54
58
|
* This ensures cross-platform consistency while respecting Android's limitations.
|
|
@@ -64,11 +68,11 @@ class ReactNativeBlurView : BlurView {
|
|
|
64
68
|
constructor(context: Context?) : super(context) {
|
|
65
69
|
initializeBlur()
|
|
66
70
|
}
|
|
67
|
-
|
|
71
|
+
|
|
68
72
|
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
|
69
73
|
initializeBlur()
|
|
70
74
|
}
|
|
71
|
-
|
|
75
|
+
|
|
72
76
|
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
|
73
77
|
context,
|
|
74
78
|
attrs,
|
|
@@ -86,21 +90,21 @@ class ReactNativeBlurView : BlurView {
|
|
|
86
90
|
super.setBackgroundColor(Color.TRANSPARENT)
|
|
87
91
|
logDebug("ReactNativeBlurView initialized")
|
|
88
92
|
}
|
|
89
|
-
|
|
93
|
+
|
|
90
94
|
/**
|
|
91
95
|
* Override setBackgroundColor to handle blur setup timing and background preservation.
|
|
92
96
|
* @param color The background color to apply
|
|
93
97
|
*/
|
|
94
98
|
override fun setBackgroundColor(color: Int) {
|
|
95
99
|
logDebug("setBackgroundColor called: $color (isSetup: $isSetup)")
|
|
96
|
-
|
|
100
|
+
|
|
97
101
|
// Store the original background color if it's not transparent
|
|
98
102
|
if (color != Color.TRANSPARENT) {
|
|
99
103
|
originalBackgroundColor = color
|
|
100
104
|
hasExplicitBackground = true
|
|
101
105
|
logDebug("Stored explicit background color: $color")
|
|
102
106
|
}
|
|
103
|
-
|
|
107
|
+
|
|
104
108
|
// If blur is not setup yet, defer setting the background
|
|
105
109
|
if (!isSetup) {
|
|
106
110
|
logDebug("Blur not setup, deferring background color")
|
|
@@ -114,7 +118,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
114
118
|
}
|
|
115
119
|
return
|
|
116
120
|
}
|
|
117
|
-
|
|
121
|
+
|
|
118
122
|
// If blur is setup and we have an explicit background, apply it carefully
|
|
119
123
|
if (hasExplicitBackground && color != Color.TRANSPARENT) {
|
|
120
124
|
logDebug("Applying background color over blur: $color")
|
|
@@ -124,17 +128,17 @@ class ReactNativeBlurView : BlurView {
|
|
|
124
128
|
super.setBackgroundColor(Color.TRANSPARENT)
|
|
125
129
|
}
|
|
126
130
|
}
|
|
127
|
-
|
|
131
|
+
|
|
128
132
|
/**
|
|
129
133
|
* Override setAlpha to handle blur setup timing.
|
|
130
134
|
* @param alpha The alpha value to apply
|
|
131
135
|
*/
|
|
132
136
|
override fun setAlpha(alpha: Float) {
|
|
133
137
|
logDebug("setAlpha called: $alpha (isSetup: $isSetup)")
|
|
134
|
-
|
|
138
|
+
|
|
135
139
|
// Always apply alpha changes immediately as they don't interfere with blur setup
|
|
136
140
|
super.setAlpha(alpha)
|
|
137
|
-
|
|
141
|
+
|
|
138
142
|
// If blur is not setup yet, trigger setup attempt
|
|
139
143
|
if (!isSetup && isAttachedToWindow) {
|
|
140
144
|
pendingStyleUpdate = true
|
|
@@ -146,17 +150,17 @@ class ReactNativeBlurView : BlurView {
|
|
|
146
150
|
}
|
|
147
151
|
}
|
|
148
152
|
}
|
|
149
|
-
|
|
153
|
+
|
|
150
154
|
/**
|
|
151
155
|
* Override setElevation to handle blur setup timing.
|
|
152
156
|
* @param elevation The elevation value to apply
|
|
153
157
|
*/
|
|
154
158
|
override fun setElevation(elevation: Float) {
|
|
155
159
|
logDebug("setElevation called: $elevation (isSetup: $isSetup)")
|
|
156
|
-
|
|
160
|
+
|
|
157
161
|
// Always apply elevation changes immediately
|
|
158
162
|
super.setElevation(elevation)
|
|
159
|
-
|
|
163
|
+
|
|
160
164
|
// If blur is not setup yet, trigger setup attempt
|
|
161
165
|
if (!isSetup && isAttachedToWindow) {
|
|
162
166
|
pendingStyleUpdate = true
|
|
@@ -177,7 +181,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
177
181
|
super.onAttachedToWindow()
|
|
178
182
|
setupBlurView()
|
|
179
183
|
}
|
|
180
|
-
|
|
184
|
+
|
|
181
185
|
/**
|
|
182
186
|
* Called when the view is detached from a window.
|
|
183
187
|
* Performs cleanup to prevent memory leaks.
|
|
@@ -186,7 +190,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
186
190
|
super.onDetachedFromWindow()
|
|
187
191
|
cleanup()
|
|
188
192
|
}
|
|
189
|
-
|
|
193
|
+
|
|
190
194
|
/**
|
|
191
195
|
* Cleanup method to reset state and remove pending callbacks.
|
|
192
196
|
* Helps prevent memory leaks and ensures clean state.
|
|
@@ -207,10 +211,10 @@ class ReactNativeBlurView : BlurView {
|
|
|
207
211
|
*/
|
|
208
212
|
private fun setupBlurView() {
|
|
209
213
|
if (isSetup) return
|
|
210
|
-
|
|
214
|
+
|
|
211
215
|
try {
|
|
212
216
|
val rootView = findRootView()
|
|
213
|
-
|
|
217
|
+
|
|
214
218
|
rootView?.let { root ->
|
|
215
219
|
try {
|
|
216
220
|
// Choose blur algorithm based on Android API level
|
|
@@ -229,23 +233,22 @@ class ReactNativeBlurView : BlurView {
|
|
|
229
233
|
throw UnsupportedOperationException("Blur not supported on this device", e)
|
|
230
234
|
}
|
|
231
235
|
}
|
|
232
|
-
|
|
236
|
+
|
|
233
237
|
// Setup the blur view with the appropriate algorithm
|
|
234
238
|
this.setupWith(root, blurAlgorithm)
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
} catch (e: Exception) {
|
|
239
|
+
.setBlurRadius(blurRadius)
|
|
240
|
+
.setOverlayColor(overlayColor)
|
|
241
|
+
|
|
242
|
+
isSetup = true
|
|
243
|
+
pendingStyleUpdate = false
|
|
244
|
+
|
|
245
|
+
// Apply any pending background color after blur setup
|
|
246
|
+
if (hasExplicitBackground && originalBackgroundColor != null) {
|
|
247
|
+
logDebug("Applying pending background color: $originalBackgroundColor")
|
|
248
|
+
super.setBackgroundColor(originalBackgroundColor!!)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
logDebug("Blur setup successful with root: ${root.javaClass.simpleName}")} catch (e: Exception) {
|
|
249
252
|
logWarning("Failed to setup blur algorithm: ${e.message}")
|
|
250
253
|
// Fallback: use semi-transparent overlay when blur is unsupported
|
|
251
254
|
super.setBackgroundColor(overlayColor)
|
|
@@ -263,7 +266,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
263
266
|
logError("Failed to setup blur: ${e.message}", e)
|
|
264
267
|
}
|
|
265
268
|
}
|
|
266
|
-
|
|
269
|
+
|
|
267
270
|
/**
|
|
268
271
|
* Find the root view using multiple strategies.
|
|
269
272
|
* @return The root ViewGroup or null if not found
|
|
@@ -277,7 +280,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
277
280
|
}
|
|
278
281
|
parent = parent.parent
|
|
279
282
|
}
|
|
280
|
-
|
|
283
|
+
|
|
281
284
|
// Strategy 2: If content view not found, use the activity's root view
|
|
282
285
|
try {
|
|
283
286
|
val activity = context as? android.app.Activity
|
|
@@ -287,7 +290,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
287
290
|
} catch (e: Exception) {
|
|
288
291
|
logDebug("Could not access activity root view: ${e.message}")
|
|
289
292
|
}
|
|
290
|
-
|
|
293
|
+
|
|
291
294
|
// Strategy 3: Fallback to immediate parent
|
|
292
295
|
return this.parent as? ViewGroup
|
|
293
296
|
}
|
|
@@ -299,7 +302,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
299
302
|
fun setBlurAmount(amount: Float) {
|
|
300
303
|
blurRadius = mapBlurAmountToRadius(amount)
|
|
301
304
|
logDebug("setBlurAmount: $amount -> $blurRadius (mapped from 0-100 to 0-25 range, isSetup: $isSetup)")
|
|
302
|
-
|
|
305
|
+
|
|
303
306
|
if (isSetup) {
|
|
304
307
|
try {
|
|
305
308
|
setBlurRadius(blurRadius)
|
|
@@ -325,7 +328,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
325
328
|
SYSTEM_MATERIAL(Color.argb(50, 255, 255, 255)),
|
|
326
329
|
SYSTEM_THICK_MATERIAL(Color.argb(65, 255, 255, 255)),
|
|
327
330
|
SYSTEM_CHROME_MATERIAL(Color.argb(45, 240, 240, 240));
|
|
328
|
-
|
|
331
|
+
|
|
329
332
|
companion object {
|
|
330
333
|
/**
|
|
331
334
|
* Get BlurType from string, with fallback to LIGHT for unknown types.
|
|
@@ -348,7 +351,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
348
351
|
}
|
|
349
352
|
}
|
|
350
353
|
}
|
|
351
|
-
|
|
354
|
+
|
|
352
355
|
/**
|
|
353
356
|
* Set the blur type which determines the overlay color.
|
|
354
357
|
* @param type The blur type string (case-insensitive)
|
|
@@ -357,7 +360,7 @@ class ReactNativeBlurView : BlurView {
|
|
|
357
360
|
val blurType = BlurType.fromString(type)
|
|
358
361
|
overlayColor = blurType.overlayColor
|
|
359
362
|
logDebug("setBlurType: $type -> ${blurType.name} (isSetup: $isSetup)")
|
|
360
|
-
|
|
363
|
+
|
|
361
364
|
if (isSetup) {
|
|
362
365
|
try {
|
|
363
366
|
setOverlayColor(overlayColor)
|
|
@@ -376,12 +379,12 @@ class ReactNativeBlurView : BlurView {
|
|
|
376
379
|
try {
|
|
377
380
|
val fallbackColor = Color.parseColor(it)
|
|
378
381
|
logDebug("setReducedTransparencyFallbackColor: $color -> $fallbackColor (stored but not applied unless accessibility requires it)")
|
|
379
|
-
|
|
382
|
+
|
|
380
383
|
// 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
|
|
384
|
+
// For now, we'll just log it since Android doesn't have a direct equivalent to iOS's
|
|
382
385
|
// "Reduce Transparency" setting that we can easily check
|
|
383
386
|
// The blur effect should remain the primary visual
|
|
384
|
-
|
|
387
|
+
|
|
385
388
|
} catch (e: Exception) {
|
|
386
389
|
logWarning("Invalid color format for reduced transparency fallback: $color")
|
|
387
390
|
}
|
|
@@ -389,4 +392,97 @@ class ReactNativeBlurView : BlurView {
|
|
|
389
392
|
logDebug("Cleared reduced transparency fallback color")
|
|
390
393
|
}
|
|
391
394
|
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Set the glass tint color for liquid glass effect.
|
|
398
|
+
* @param color The color string in hex format (e.g., "#FF0000") or null to clear
|
|
399
|
+
*/
|
|
400
|
+
fun setGlassTintColor(color: String?) {
|
|
401
|
+
color?.let {
|
|
402
|
+
try {
|
|
403
|
+
glassTintColor = Color.parseColor(it)
|
|
404
|
+
logDebug("setGlassTintColor: $color -> $glassTintColor")
|
|
405
|
+
updateGlassEffect()
|
|
406
|
+
} catch (e: Exception) {
|
|
407
|
+
logWarning("Invalid color format for glass tint: $color")
|
|
408
|
+
glassTintColor = Color.TRANSPARENT
|
|
409
|
+
}
|
|
410
|
+
} ?: run {
|
|
411
|
+
glassTintColor = Color.TRANSPARENT
|
|
412
|
+
logDebug("Cleared glass tint color")
|
|
413
|
+
updateGlassEffect()
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Set the glass opacity for liquid glass effect.
|
|
419
|
+
* @param opacity The opacity value (0.0 to 1.0)
|
|
420
|
+
*/
|
|
421
|
+
fun setGlassOpacity(opacity: Float) {
|
|
422
|
+
glassOpacity = opacity.coerceIn(0.0f, 1.0f)
|
|
423
|
+
logDebug("setGlassOpacity: $opacity")
|
|
424
|
+
updateGlassEffect()
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Set the view type (blur or liquidGlass).
|
|
429
|
+
* @param type The view type string
|
|
430
|
+
*/
|
|
431
|
+
fun setType(type: String) {
|
|
432
|
+
viewType = type
|
|
433
|
+
logDebug("setType: $type")
|
|
434
|
+
updateViewType()
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Set the glass type for liquid glass effect.
|
|
439
|
+
* @param type The glass type string
|
|
440
|
+
*/
|
|
441
|
+
fun setGlassType(type: String) {
|
|
442
|
+
glassType = type
|
|
443
|
+
logDebug("setGlassType: $type")
|
|
444
|
+
updateGlassEffect()
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Update the glass effect based on current glass properties.
|
|
449
|
+
*/
|
|
450
|
+
private fun updateGlassEffect() {
|
|
451
|
+
if (viewType == "liquidGlass" && isSetup) {
|
|
452
|
+
try {
|
|
453
|
+
// Apply glass tint with opacity
|
|
454
|
+
val glassColor = Color.argb(
|
|
455
|
+
(glassOpacity * 255).toInt(),
|
|
456
|
+
Color.red(glassTintColor),
|
|
457
|
+
Color.green(glassTintColor),
|
|
458
|
+
Color.blue(glassTintColor)
|
|
459
|
+
)
|
|
460
|
+
setOverlayColor(glassColor)
|
|
461
|
+
logDebug("Applied glass effect: color=$glassColor, opacity=$glassOpacity")
|
|
462
|
+
} catch (e: Exception) {
|
|
463
|
+
logError("Failed to update glass effect: ${e.message}", e)
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Update the view type and apply appropriate effects.
|
|
470
|
+
*/
|
|
471
|
+
private fun updateViewType() {
|
|
472
|
+
when (viewType) {
|
|
473
|
+
"liquidGlass" -> {
|
|
474
|
+
updateGlassEffect()
|
|
475
|
+
}
|
|
476
|
+
"blur" -> {
|
|
477
|
+
// Restore original blur overlay color
|
|
478
|
+
if (isSetup) {
|
|
479
|
+
try {
|
|
480
|
+
setOverlayColor(overlayColor)
|
|
481
|
+
} catch (e: Exception) {
|
|
482
|
+
logError("Failed to restore blur overlay: ${e.message}", e)
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
392
488
|
}
|
|
@@ -44,6 +44,26 @@ class ReactNativeBlurViewManager : ViewGroupManager<ReactNativeBlurView>(),
|
|
|
44
44
|
view?.setReducedTransparencyFallbackColor(reducedTransparencyFallbackColor)
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
@ReactProp(name = "glassTintColor")
|
|
48
|
+
override fun setGlassTintColor(view: ReactNativeBlurView?, glassTintColor: String?) {
|
|
49
|
+
view?.setGlassTintColor(glassTintColor)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@ReactProp(name = "glassOpacity")
|
|
53
|
+
override fun setGlassOpacity(view: ReactNativeBlurView?, glassOpacity: Double) {
|
|
54
|
+
view?.setGlassOpacity(glassOpacity.toFloat())
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@ReactProp(name = "type")
|
|
58
|
+
override fun setType(view: ReactNativeBlurView?, type: String?) {
|
|
59
|
+
view?.setType(type ?: "blur")
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@ReactProp(name = "glassType")
|
|
63
|
+
override fun setGlassType(view: ReactNativeBlurView?, glassType: String?) {
|
|
64
|
+
view?.setGlassType(glassType ?: "clear")
|
|
65
|
+
}
|
|
66
|
+
|
|
47
67
|
companion object {
|
|
48
68
|
const val NAME = "ReactNativeBlurView"
|
|
49
69
|
}
|