@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 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
- ## Demo
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 and fallback colors
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 Kotlin for Android implementation and *will* use Swift for iOS, ensuring modern development practices
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 | ✅ 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
- | `blurType` | `BlurType` | `'light'` | The type of blur effect to apply |
297
- | `blurAmount` | `number` | `10` | The intensity of the blur effect (0-100) |
298
- | `reducedTransparencyFallbackColor` | `string` | `undefined` | Fallback color when reduced transparency is enabled |
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 uses `UIVisualEffectView` to provide true blur effects. All blur types are supported with their native implementations.
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 features. To run the example:
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
- npm install
433
+ yarn install
361
434
  # For iOS
362
- npx react-native run-ios
435
+ yarn ios
363
436
  # For Android
364
- npx react-native run-android
437
+ yarn android
365
438
  ```
366
439
 
367
440
  ## Performance Considerations
368
441
 
369
- - **iOS**: Native blur effects are hardware-accelerated and performant
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
 
@@ -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
- .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) {
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
  }