@sbaiahmed1/react-native-blur 4.5.7 → 4.5.8-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
@@ -54,7 +54,7 @@ A modern React Native library providing **six specialized components** for advan
54
54
  ## Requirements
55
55
 
56
56
  | Platform | Minimum Version |
57
- | ------------------------- |-------------------------------------------------------|
57
+ | ------------------------- | ----------------------------------------------------- |
58
58
  | **iOS** | iOS 13.0+ |
59
59
  | **Xcode** | min: Xcode 16; Xcode 26.0+ (for liquid glass support) |
60
60
  | **React Native** | 0.68+ (New Architecture) |
@@ -158,7 +158,7 @@ import { LiquidGlassView } from '@sbaiahmed1/react-native-blur';
158
158
  - `LiquidGlassContainer` - iOS 26+ glass container with configurable spacing for grouping glass elements
159
159
  - `BlurSwitch` - Beautiful blur switch button using QmBlurView (Android)
160
160
  - `Vibrancy View`- Beautiful Vibrancy view for iOS (iOS only)
161
-
161
+
162
162
  - �🌊 **Liquid Glass Effects**: Revolutionary glass effects using iOS 26+ UIGlassEffect API
163
163
  - 🎨 **Multiple Blur Types**: Support for various blur styles including system materials on iOS
164
164
  - 📱 **Cross-Platform**: Works on both iOS and Android
@@ -380,6 +380,7 @@ function GradientBlurComponent() {
380
380
  ```
381
381
 
382
382
  Tips:
383
+
383
384
  - `startOffset` shifts where the blur plateau begins; 0 = longest body, higher = shorter.
384
385
  - `blurAmount` controls peak intensity; center direction balances strength per platform.
385
386
  - Works on iOS and Android with matching props.
@@ -625,7 +626,7 @@ All props are optional and have sensible defaults.
625
626
  | ---------------------------------- | ------------ | ----------- | ----------------------------------------------------------------------------- |
626
627
  | `blurType` | `BlurType` | `'xlight'` | The type of blur effect to apply |
627
628
  | `blurAmount` | `number` | `10.0` | The intensity of the blur effect (0-100) |
628
- | `ignoreSafeArea` | `boolean` | `true` | (iOS only) Controls whether the blur effect should ignore all safe area edges |
629
+ | `ignoreSafeArea` | `boolean` | `true` | (iOS only) Controls whether the blur effect should ignore all safe area edges |
629
630
  | `reducedTransparencyFallbackColor` | `string` | `'#FFFFFF'` | Fallback color when reduced transparency is enabled |
630
631
  | `overlayColor` | `ColorValue` | `undefined` | The overlay color to apply on top of the blur effect |
631
632
  | `style` | `ViewStyle` | `undefined` | Style object for the blur view |
@@ -635,27 +636,27 @@ All props are optional and have sensible defaults.
635
636
 
636
637
  All props are optional and have sensible defaults.
637
638
 
638
- | Prop | Type | Default | Description |
639
- | ------------ | ------------ | ----------- | ----------------------------------------------- |
640
- | `blurType` | `BlurType` | `'xlight'` | The type of blur/vibrancy effect to apply |
641
- | `blurAmount` | `number` | `10.0` | The intensity of the blur effect (0-100) |
642
- | `style` | `ViewStyle` | `undefined` | Style object for the vibrancy view |
643
- | `children` | `ReactNode` | `undefined` | Child components to render inside the vibrancy view |
639
+ | Prop | Type | Default | Description |
640
+ | ------------ | ----------- | ----------- | --------------------------------------------------- |
641
+ | `blurType` | `BlurType` | `'xlight'` | The type of blur/vibrancy effect to apply |
642
+ | `blurAmount` | `number` | `10.0` | The intensity of the blur effect (0-100) |
643
+ | `style` | `ViewStyle` | `undefined` | Style object for the vibrancy view |
644
+ | `children` | `ReactNode` | `undefined` | Child components to render inside the vibrancy view |
644
645
 
645
646
  ### ProgressiveBlurView Props
646
647
 
647
648
  All props are optional and have sensible defaults.
648
649
 
649
- | Prop | Type | Default | Description |
650
- | ---------------------------------- | ---------------------------------------------------- | ------------------------- | ---------------------------------------------------- |
651
- | `blurType` | `BlurType` | `'regular'` | The type of blur effect to apply |
652
- | `blurAmount` | `number` | `20.0` | Maximum blur radius in pixels |
650
+ | Prop | Type | Default | Description |
651
+ | ---------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------- | ---------------------------------------------------- |
652
+ | `blurType` | `BlurType` | `'regular'` | The type of blur effect to apply |
653
+ | `blurAmount` | `number` | `20.0` | Maximum blur radius in pixels |
653
654
  | `direction` | `'blurredTopClearBottom' \| 'blurredBottomClearTop' \| 'blurredCenterClearTopAndBottom'` | `'blurredTopClearBottom'` | Direction of the blur gradient |
654
- | `startOffset` | `number` | `0.0` | Where the gradient starts (0.0 to 1.0) |
655
- | `reducedTransparencyFallbackColor` | `string` | `'#FFFFFF'` | Fallback color when reduced transparency is enabled |
656
- | `overlayColor` | `ColorValue` | `undefined` | The overlay color to apply on top of the blur effect |
657
- | `style` | `ViewStyle` | `undefined` | Style object for the blur view |
658
- | `children` | `ReactNode` | `undefined` | Child components to render inside the blur view |
655
+ | `startOffset` | `number` | `0.0` | Where the gradient starts (0.0 to 1.0) |
656
+ | `reducedTransparencyFallbackColor` | `string` | `'#FFFFFF'` | Fallback color when reduced transparency is enabled |
657
+ | `overlayColor` | `ColorValue` | `undefined` | The overlay color to apply on top of the blur effect |
658
+ | `style` | `ViewStyle` | `undefined` | Style object for the blur view |
659
+ | `children` | `ReactNode` | `undefined` | Child components to render inside the blur view |
659
660
 
660
661
  > **Platform Note**: `ProgressiveBlurView` works on both **iOS** and **Android**.
661
662
  >
@@ -672,7 +673,7 @@ All props are optional and have sensible defaults.
672
673
  | `glassTintColor` | `string` | `'clear'` | The tint color for glass effect. Accepts hex colors or color names |
673
674
  | `glassOpacity` | `number` | `1.0` | The opacity of glass effect (0-1) |
674
675
  | `isInteractive` | `boolean` | `true` | (iOS 26+ only) Controls whether the liquid glass effect is interactive and reacts to touch |
675
- | `ignoreSafeArea` | `boolean` | `true` | (iOS only) Controls whether the glass effect should ignore all safe area edges |
676
+ | `ignoreSafeArea` | `boolean` | `true` | (iOS only) Controls whether the glass effect should ignore all safe area edges |
676
677
  | `reducedTransparencyFallbackColor` | `string` | `'#FFFFFF'` | Fallback color when reduced transparency is enabled or on older iOS versions |
677
678
  | `style` | `ViewStyle` | `undefined` | Style object for the glass view |
678
679
  | `children` | `ReactNode` | `undefined` | Child components to render inside the glass view |
@@ -691,15 +692,15 @@ All props are optional and have sensible defaults.
691
692
 
692
693
  All props are optional and have sensible defaults.
693
694
 
694
- | Prop | Type | Default | Description |
695
- | -------------- | ----------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
696
- | `value` | `boolean` | `false` | The current value of the switch |
697
- | `onValueChange`| `(value: boolean) => void` | `undefined` | Callback invoked when the switch value changes |
698
- | `blurAmount` | `number` | `10` | (Android only) The intensity of the blur effect (0-100) |
699
- | `thumbColor` | `ColorValue` | `'#FFFFFF'` | (iOS only) The color of the switch thumb |
700
- | `trackColor` | `{ false?: ColorValue; true?: ColorValue }`| `{ false: '#E5E5EA', true: '#34C759' }` | Track colors. On Android, only `true` is used - QmBlurView auto-calculates on/off colors from base color |
701
- | `disabled` | `boolean` | `false` | Whether the switch is disabled (prevents interaction but maintains current value) |
702
- | `style` | `ViewStyle` | `undefined` | Style object for the switch view |
695
+ | Prop | Type | Default | Description |
696
+ | --------------- | ------------------------------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------- |
697
+ | `value` | `boolean` | `false` | The current value of the switch |
698
+ | `onValueChange` | `(value: boolean) => void` | `undefined` | Callback invoked when the switch value changes |
699
+ | `blurAmount` | `number` | `10` | (Android only) The intensity of the blur effect (0-100) |
700
+ | `thumbColor` | `ColorValue` | `'#FFFFFF'` | (iOS only) The color of the switch thumb |
701
+ | `trackColor` | `{ false?: ColorValue; true?: ColorValue }` | `{ false: '#E5E5EA', true: '#34C759' }` | Track colors. On Android, only `true` is used - QmBlurView auto-calculates on/off colors from base color |
702
+ | `disabled` | `boolean` | `false` | Whether the switch is disabled (prevents interaction but maintains current value) |
703
+ | `style` | `ViewStyle` | `undefined` | Style object for the switch view |
703
704
 
704
705
  > **Note**: The `BlurType` and `GlassType` are exported types from the library. See [Blur Types](#blur-types) and [Glass Types](#glass-types) sections below for all available values.
705
706
 
@@ -773,7 +774,7 @@ The component uses the QmBlurView library to provide real blur effects with hard
773
774
 
774
775
  #### L+ssibility
775
776
 
776
- All components automatically respect the "Reduce Transparency" accessibility setting:
777
+ All components automatically respect the "Reduce Transparency" accessibility setting. The `reducedTransparencyFallbackColor` property accepts hexadecimal colors and named colors: `black`, `blue`, `brown`, `clear`, `cyan`, `magenta`, `gray`, `green`, `orange`, `purple`, `red`, `transparent`, `white` and `yellow`.
777
778
 
778
779
  ### BlurView
779
780
 
@@ -790,7 +791,7 @@ All components automatically respect the "Reduce Transparency" accessibility set
790
791
  - **iOS 26+**: When reduce transparency is enabled, falls back to regular View
791
792
  - **iOS < 26 & Android**: Always renders as regular View
792
793
 
793
- You can customize the fallback color using the `reducedTransparencyFallbackColor` prop on `BlurView` and `LiquidGlassView` components.
794
+ You can customize the fallback color using the `reducedTransparencyFallbackColor` prop on `BlurView`, `ProgressiveBlurView`, and `LiquidGlassView` components.
794
795
 
795
796
  ## TypeScript Support
796
797
 
@@ -107,15 +107,12 @@ class ReactNativeBlurView : BlurViewGroup {
107
107
 
108
108
  if (isBlurInitialized) return
109
109
 
110
- // Defer the blur root swap to next frame so the view tree is fully mounted
111
- val runnable = Runnable {
112
- initRunnable = null
113
- if (isBlurInitialized) return@Runnable
114
- swapBlurRootToScreenAncestor()
115
- initializeBlur()
116
- }
117
- initRunnable = runnable
118
- post(runnable)
110
+ // Immediately try to swap blur root and initialize.
111
+ // We avoid posting a runnable to prevent the 1-second delay artifact.
112
+ // If the parent hierarchy is not ready yet (unlikely in onAttachedToWindow),
113
+ // we could fall back to post, but for now we prioritize immediate execution.
114
+ swapBlurRootToScreenAncestor()
115
+ initializeBlur()
119
116
  }
120
117
 
121
118
  /**
@@ -37,17 +37,20 @@ using namespace facebook::react;
37
37
 
38
38
  // Handle common color names
39
39
  NSDictionary *colorMap = @{
40
- @"red": [UIColor redColor],
40
+ @"black": [UIColor blackColor],
41
41
  @"blue": [UIColor blueColor],
42
+ @"brown": [UIColor brownColor],
43
+ @"clear": [UIColor clearColor],
44
+ @"cyan": [UIColor cyanColor],
45
+ @"magenta": [UIColor magentaColor],
46
+ @"gray": [UIColor grayColor],
42
47
  @"green": [UIColor greenColor],
43
- @"yellow": [UIColor yellowColor],
44
48
  @"orange": [UIColor orangeColor],
45
49
  @"purple": [UIColor purpleColor],
46
- @"black": [UIColor blackColor],
50
+ @"red": [UIColor redColor],
51
+ @"transparent": [UIColor clearColor],
47
52
  @"white": [UIColor whiteColor],
48
- @"gray": [UIColor grayColor],
49
- @"clear": [UIColor clearColor],
50
- @"transparent": [UIColor clearColor]
53
+ @"yellow": [UIColor yellowColor],
51
54
  };
52
55
 
53
56
  UIColor *namedColor = colorMap[colorString.lowercaseString];
@@ -95,6 +98,20 @@ using namespace facebook::react;
95
98
  alpha:(hexValue & 0x000000FF) / 255.0];
96
99
  }
97
100
  }
101
+ // Handle 4-character hex (RGBA shorthand)
102
+ else if (hexString.length == 4) {
103
+ unsigned int hexValue;
104
+ NSScanner *scanner = [NSScanner scannerWithString:hexString];
105
+ if ([scanner scanHexInt:&hexValue] && [scanner isAtEnd]) {
106
+ // Expand 4-digit hex to 8-digit (e.g., "FFF0" -> "FFFFFF00")
107
+ unsigned int r = (hexValue & 0xF000) >> 12;
108
+ unsigned int g = (hexValue & 0x0F00) >> 8;
109
+ unsigned int b = (hexValue & 0x00F0) >> 4;
110
+ unsigned int a = (hexValue & 0x000F);
111
+
112
+ return [UIColor colorWithRed:(r | (r << 4)) / 255.0 green:(g | (g << 4)) / 255.0 blue:(b | (b << 4)) / 255.0 alpha:(a | (a << 4)) / 255.0];
113
+ }
114
+ }
98
115
  // Handle 3-character hex (RGB shorthand)
99
116
  else if (hexString.length == 3) {
100
117
  unsigned int hexValue;
@@ -112,7 +129,7 @@ using namespace facebook::react;
112
129
  }
113
130
  }
114
131
  else {
115
- NSLog(@"[ReactNativeBlurView] Warning: Unsupported hex color length (%lu) for '%@', expected 3, 6, or 8 characters",
132
+ NSLog(@"[ReactNativeBlurView] Warning: Unsupported hex color length (%lu) for '%@', expected 3, 4, 6, or 8 characters",
116
133
  (unsigned long)hexString.length, colorString);
117
134
  }
118
135
 
@@ -66,17 +66,20 @@ RCT_CUSTOM_VIEW_PROPERTY(ignoreSafeArea, BOOL, AdvancedBlurView)
66
66
 
67
67
  // Handle common color names
68
68
  NSDictionary *colorMap = @{
69
- @"red": [UIColor redColor],
69
+ @"black": [UIColor blackColor],
70
70
  @"blue": [UIColor blueColor],
71
+ @"brown": [UIColor brownColor],
72
+ @"clear": [UIColor clearColor],
73
+ @"cyan": [UIColor cyanColor],
74
+ @"magenta": [UIColor magentaColor],
75
+ @"gray": [UIColor grayColor],
71
76
  @"green": [UIColor greenColor],
72
- @"yellow": [UIColor yellowColor],
73
77
  @"orange": [UIColor orangeColor],
74
78
  @"purple": [UIColor purpleColor],
75
- @"black": [UIColor blackColor],
79
+ @"red": [UIColor redColor],
80
+ @"transparent": [UIColor clearColor],
76
81
  @"white": [UIColor whiteColor],
77
- @"gray": [UIColor grayColor],
78
- @"clear": [UIColor clearColor],
79
- @"transparent": [UIColor clearColor]
82
+ @"yellow": [UIColor yellowColor],
80
83
  };
81
84
 
82
85
  UIColor *namedColor = colorMap[colorString.lowercaseString];
@@ -124,6 +127,20 @@ RCT_CUSTOM_VIEW_PROPERTY(ignoreSafeArea, BOOL, AdvancedBlurView)
124
127
  alpha:(hexValue & 0x000000FF) / 255.0];
125
128
  }
126
129
  }
130
+ // Handle 4-character hex (RGBA shorthand)
131
+ else if (hexString.length == 4) {
132
+ unsigned int hexValue;
133
+ NSScanner *scanner = [NSScanner scannerWithString:hexString];
134
+ if ([scanner scanHexInt:&hexValue] && [scanner isAtEnd]) {
135
+ // Expand 4-digit hex to 8-digit (e.g., "FFF0" -> "FFFFFF00")
136
+ unsigned int r = (hexValue & 0xF000) >> 12;
137
+ unsigned int g = (hexValue & 0x0F00) >> 8;
138
+ unsigned int b = (hexValue & 0x00F0) >> 4;
139
+ unsigned int a = (hexValue & 0x000F);
140
+
141
+ return [UIColor colorWithRed:(r | (r << 4)) / 255.0 green:(g | (g << 4)) / 255.0 blue:(b | (b << 4)) / 255.0 alpha:(a | (a << 4)) / 255.0];
142
+ }
143
+ }
127
144
  // Handle 3-character hex (RGB shorthand)
128
145
  else if (hexString.length == 3) {
129
146
  unsigned int hexValue;
@@ -141,7 +158,7 @@ RCT_CUSTOM_VIEW_PROPERTY(ignoreSafeArea, BOOL, AdvancedBlurView)
141
158
  }
142
159
  }
143
160
  else {
144
- NSLog(@"[ReactNativeBlurViewManager] Warning: Unsupported hex color length (%lu) for '%@', expected 3, 6, or 8 characters",
161
+ NSLog(@"[ReactNativeBlurViewManager] Warning: Unsupported hex color length (%lu) for '%@', expected 3, 4, 6, or 8 characters",
145
162
  (unsigned long)hexString.length, colorString);
146
163
  }
147
164
 
@@ -38,17 +38,20 @@ using namespace facebook::react;
38
38
 
39
39
  // Handle common color names
40
40
  NSDictionary *colorMap = @{
41
- @"red": [UIColor redColor],
41
+ @"black": [UIColor blackColor],
42
42
  @"blue": [UIColor blueColor],
43
+ @"brown": [UIColor brownColor],
44
+ @"clear": [UIColor clearColor],
45
+ @"cyan": [UIColor cyanColor],
46
+ @"magenta": [UIColor magentaColor],
47
+ @"gray": [UIColor grayColor],
43
48
  @"green": [UIColor greenColor],
44
- @"yellow": [UIColor yellowColor],
45
49
  @"orange": [UIColor orangeColor],
46
50
  @"purple": [UIColor purpleColor],
47
- @"black": [UIColor blackColor],
51
+ @"red": [UIColor redColor],
52
+ @"transparent": [UIColor clearColor],
48
53
  @"white": [UIColor whiteColor],
49
- @"gray": [UIColor grayColor],
50
- @"clear": [UIColor clearColor],
51
- @"transparent": [UIColor clearColor]
54
+ @"yellow": [UIColor yellowColor],
52
55
  };
53
56
 
54
57
  UIColor *namedColor = colorMap[colorString.lowercaseString];
@@ -96,6 +99,20 @@ using namespace facebook::react;
96
99
  alpha:(hexValue & 0x000000FF) / 255.0];
97
100
  }
98
101
  }
102
+ // Handle 4-character hex (RGBA shorthand)
103
+ else if (hexString.length == 4) {
104
+ unsigned int hexValue;
105
+ NSScanner *scanner = [NSScanner scannerWithString:hexString];
106
+ if ([scanner scanHexInt:&hexValue] && [scanner isAtEnd]) {
107
+ // Expand 4-digit hex to 8-digit (e.g., "FFF0" -> "FFFFFF00")
108
+ unsigned int r = (hexValue & 0xF000) >> 12;
109
+ unsigned int g = (hexValue & 0x0F00) >> 8;
110
+ unsigned int b = (hexValue & 0x00F0) >> 4;
111
+ unsigned int a = (hexValue & 0x000F);
112
+
113
+ return [UIColor colorWithRed:(r | (r << 4)) / 255.0 green:(g | (g << 4)) / 255.0 blue:(b | (b << 4)) / 255.0 alpha:(a | (a << 4)) / 255.0];
114
+ }
115
+ }
99
116
  // Handle 3-character hex (RGB shorthand)
100
117
  else if (hexString.length == 3) {
101
118
  unsigned int hexValue;
@@ -113,7 +130,7 @@ using namespace facebook::react;
113
130
  }
114
131
  }
115
132
  else {
116
- NSLog(@"[ReactNativeLiquidGlassView] Warning: Unsupported hex color length (%lu) for '%@', expected 3, 6, or 8 characters",
133
+ NSLog(@"[ReactNativeLiquidGlassView] Warning: Unsupported hex color length (%lu) for '%@', expected 3, 4, 6, or 8 characters",
117
134
  (unsigned long)hexString.length, colorString);
118
135
  }
119
136
 
@@ -223,15 +240,15 @@ using namespace facebook::react;
223
240
  - (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask
224
241
  {
225
242
  [super finalizeUpdates:updateMask];
226
-
243
+
227
244
  // Apply border radius from layout metrics to the inner glass view (Callstack pattern)
228
245
  if (@available(iOS 26.0, *)) {
229
246
  const auto &props = *std::static_pointer_cast<ReactNativeLiquidGlassViewProps const>(_props);
230
247
  const auto borderMetrics = props.resolveBorderMetrics(_layoutMetrics);
231
-
248
+
232
249
  // Use topLeft.horizontal same as React Native RCTViewComponentView implementation
233
250
  CGFloat radius = borderMetrics.borderRadii.topLeft.horizontal;
234
-
251
+
235
252
  if (radius > 0) {
236
253
  [_liquidGlassView setBorderRadius:radius];
237
254
  }
@@ -242,11 +259,11 @@ using namespace facebook::react;
242
259
  {
243
260
  [super layoutSubviews];
244
261
  _liquidGlassView.frame = self.bounds;
245
-
262
+
246
263
  // Copy corner radius from the Fabric view to the inner glass view (Callstack pattern)
247
264
  _liquidGlassView.layer.cornerRadius = self.layer.cornerRadius;
248
265
  _liquidGlassView.layer.cornerCurve = self.layer.cornerCurve;
249
-
266
+
250
267
  // On iOS 26+, don't clip bounds to allow interactive glass animations to be visible
251
268
  // The glass effect view handles its own clipping via cornerConfiguration
252
269
  if (@available(iOS 26.0, *)) {
@@ -36,17 +36,20 @@ using namespace facebook::react;
36
36
 
37
37
  // Handle common color names
38
38
  NSDictionary *colorMap = @{
39
- @"red": [UIColor redColor],
39
+ @"black": [UIColor blackColor],
40
40
  @"blue": [UIColor blueColor],
41
+ @"brown": [UIColor brownColor],
42
+ @"clear": [UIColor clearColor],
43
+ @"cyan": [UIColor cyanColor],
44
+ @"magenta": [UIColor magentaColor],
45
+ @"gray": [UIColor grayColor],
41
46
  @"green": [UIColor greenColor],
42
- @"yellow": [UIColor yellowColor],
43
47
  @"orange": [UIColor orangeColor],
44
48
  @"purple": [UIColor purpleColor],
45
- @"black": [UIColor blackColor],
49
+ @"red": [UIColor redColor],
50
+ @"transparent": [UIColor clearColor],
46
51
  @"white": [UIColor whiteColor],
47
- @"gray": [UIColor grayColor],
48
- @"clear": [UIColor clearColor],
49
- @"transparent": [UIColor clearColor]
52
+ @"yellow": [UIColor yellowColor],
50
53
  };
51
54
 
52
55
  UIColor *namedColor = colorMap[colorString.lowercaseString];
@@ -71,6 +74,7 @@ using namespace facebook::react;
71
74
  return [UIColor clearColor];
72
75
  }
73
76
 
77
+ // Handle 6-character hex (RGB)
74
78
  if (hexString.length == 6) {
75
79
  unsigned int hexValue;
76
80
  NSScanner *scanner = [NSScanner scannerWithString:hexString];
@@ -80,7 +84,9 @@ using namespace facebook::react;
80
84
  blue:(hexValue & 0x0000FF) / 255.0
81
85
  alpha:1.0];
82
86
  }
83
- } else if (hexString.length == 8) {
87
+ }
88
+ // Handle 8-character hex (RGBA)
89
+ else if (hexString.length == 8) {
84
90
  unsigned long long hexValue;
85
91
  NSScanner *scanner = [NSScanner scannerWithString:hexString];
86
92
  if ([scanner scanHexLongLong:&hexValue] && [scanner isAtEnd]) {
@@ -89,7 +95,23 @@ using namespace facebook::react;
89
95
  blue:((hexValue & 0x0000FF00) >> 8) / 255.0
90
96
  alpha:(hexValue & 0x000000FF) / 255.0];
91
97
  }
92
- } else if (hexString.length == 3) {
98
+ }
99
+ // Handle 4-character hex (RGBA shorthand)
100
+ else if (hexString.length == 4) {
101
+ unsigned int hexValue;
102
+ NSScanner *scanner = [NSScanner scannerWithString:hexString];
103
+ if ([scanner scanHexInt:&hexValue] && [scanner isAtEnd]) {
104
+ // Expand 4-digit hex to 8-digit (e.g., "FFF0" -> "FFFFFF00")
105
+ unsigned int r = (hexValue & 0xF000) >> 12;
106
+ unsigned int g = (hexValue & 0x0F00) >> 8;
107
+ unsigned int b = (hexValue & 0x00F0) >> 4;
108
+ unsigned int a = (hexValue & 0x000F);
109
+
110
+ return [UIColor colorWithRed:(r | (r << 4)) / 255.0 green:(g | (g << 4)) / 255.0 blue:(b | (b << 4)) / 255.0 alpha:(a | (a << 4)) / 255.0];
111
+ }
112
+ }
113
+ // Handle 3-character hex (RGB shorthand)
114
+ else if (hexString.length == 3) {
93
115
  unsigned int hexValue;
94
116
  NSScanner *scanner = [NSScanner scannerWithString:hexString];
95
117
  if ([scanner scanHexInt:&hexValue] && [scanner isAtEnd]) {
@@ -101,6 +123,9 @@ using namespace facebook::react;
101
123
  blue:(b | (b << 4)) / 255.0
102
124
  alpha:1.0];
103
125
  }
126
+ } else {
127
+ NSLog(@"[ReactNativeProgressiveBlurView] Warning: Unsupported hex color length (%lu) for '%@', expected 3, 4, 6, or 8 characters",
128
+ (unsigned long)hexString.length, colorString);
104
129
  }
105
130
 
106
131
  NSLog(@"[ReactNativeProgressiveBlurView] Warning: Could not parse color '%@'", colorString);
@@ -67,17 +67,20 @@ RCT_CUSTOM_VIEW_PROPERTY(reducedTransparencyFallbackColor, NSString, Progressive
67
67
  }
68
68
 
69
69
  NSDictionary *colorMap = @{
70
- @"red": [UIColor redColor],
70
+ @"black": [UIColor blackColor],
71
71
  @"blue": [UIColor blueColor],
72
+ @"brown": [UIColor brownColor],
73
+ @"clear": [UIColor clearColor],
74
+ @"cyan": [UIColor cyanColor],
75
+ @"magenta": [UIColor magentaColor],
76
+ @"gray": [UIColor grayColor],
72
77
  @"green": [UIColor greenColor],
73
- @"yellow": [UIColor yellowColor],
74
78
  @"orange": [UIColor orangeColor],
75
79
  @"purple": [UIColor purpleColor],
76
- @"black": [UIColor blackColor],
80
+ @"red": [UIColor redColor],
81
+ @"transparent": [UIColor clearColor],
77
82
  @"white": [UIColor whiteColor],
78
- @"gray": [UIColor grayColor],
79
- @"clear": [UIColor clearColor],
80
- @"transparent": [UIColor clearColor]
83
+ @"yellow": [UIColor yellowColor],
81
84
  };
82
85
 
83
86
  UIColor *namedColor = colorMap[colorString.lowercaseString];
@@ -99,6 +102,7 @@ RCT_CUSTOM_VIEW_PROPERTY(reducedTransparencyFallbackColor, NSString, Progressive
99
102
  return [UIColor clearColor];
100
103
  }
101
104
 
105
+ // Handle 6-character hex (RGB)
102
106
  if (hexString.length == 6) {
103
107
  unsigned int hexValue;
104
108
  NSScanner *scanner = [NSScanner scannerWithString:hexString];
@@ -108,7 +112,9 @@ RCT_CUSTOM_VIEW_PROPERTY(reducedTransparencyFallbackColor, NSString, Progressive
108
112
  blue:(hexValue & 0x0000FF) / 255.0
109
113
  alpha:1.0];
110
114
  }
111
- } else if (hexString.length == 8) {
115
+ }
116
+ // Handle 8-character hex (RGBA)
117
+ else if (hexString.length == 8) {
112
118
  unsigned long long hexValue;
113
119
  NSScanner *scanner = [NSScanner scannerWithString:hexString];
114
120
  if ([scanner scanHexLongLong:&hexValue] && [scanner isAtEnd]) {
@@ -117,7 +123,23 @@ RCT_CUSTOM_VIEW_PROPERTY(reducedTransparencyFallbackColor, NSString, Progressive
117
123
  blue:((hexValue & 0x0000FF00) >> 8) / 255.0
118
124
  alpha:(hexValue & 0x000000FF) / 255.0];
119
125
  }
120
- } else if (hexString.length == 3) {
126
+ }
127
+ // Handle 4-character hex (RGBA shorthand)
128
+ else if (hexString.length == 4) {
129
+ unsigned int hexValue;
130
+ NSScanner *scanner = [NSScanner scannerWithString:hexString];
131
+ if ([scanner scanHexInt:&hexValue] && [scanner isAtEnd]) {
132
+ // Expand 4-digit hex to 8-digit (e.g., "FFF0" -> "FFFFFF00")
133
+ unsigned int r = (hexValue & 0xF000) >> 12;
134
+ unsigned int g = (hexValue & 0x0F00) >> 8;
135
+ unsigned int b = (hexValue & 0x00F0) >> 4;
136
+ unsigned int a = (hexValue & 0x000F);
137
+
138
+ return [UIColor colorWithRed:(r | (r << 4)) / 255.0 green:(g | (g << 4)) / 255.0 blue:(b | (b << 4)) / 255.0 alpha:(a | (a << 4)) / 255.0];
139
+ }
140
+ }
141
+ // Handle 3-character hex (RGB shorthand)
142
+ else if (hexString.length == 3) {
121
143
  unsigned int hexValue;
122
144
  NSScanner *scanner = [NSScanner scannerWithString:hexString];
123
145
  if ([scanner scanHexInt:&hexValue] && [scanner isAtEnd]) {
@@ -129,6 +151,9 @@ RCT_CUSTOM_VIEW_PROPERTY(reducedTransparencyFallbackColor, NSString, Progressive
129
151
  blue:(b | (b << 4)) / 255.0
130
152
  alpha:1.0];
131
153
  }
154
+ } else {
155
+ NSLog(@"[ReactNativeProgressiveBlurView] Warning: Unsupported hex color length (%lu) for '%@', expected 3, 4, 6, or 8 characters",
156
+ (unsigned long)hexString.length, colorString);
132
157
  }
133
158
 
134
159
  return [UIColor clearColor];
@@ -68,7 +68,14 @@ import UIKit
68
68
  hosting.view.backgroundColor = .clear
69
69
  hosting.view.translatesAutoresizingMaskIntoConstraints = false
70
70
 
71
- addSubview(hosting.view)
71
+ // Insert at index 0 to ensure it stays behind any potential subviews (though usually this view has no children)
72
+ // This fixes the z-ordering bug where blur covers content
73
+ if !subviews.isEmpty {
74
+ insertSubview(hosting.view, at: 0)
75
+ } else {
76
+ addSubview(hosting.view)
77
+ }
78
+
72
79
  NSLayoutConstraint.activate([
73
80
  hosting.view.topAnchor.constraint(equalTo: topAnchor),
74
81
  hosting.view.leadingAnchor.constraint(equalTo: leadingAnchor),
@@ -80,8 +87,20 @@ import UIKit
80
87
  }
81
88
 
82
89
  private func updateView() {
83
- if hostingController != nil {
84
- setupHostingController()
90
+ if let hosting = hostingController {
91
+ // Update the existing controller's root view to avoid expensive recreation
92
+ // This fixes performance bottlenecks and state synchronization issues
93
+ let blurStyle = blurStyleFromString(blurTypeString)
94
+ let swiftUIView = BasicColoredView(
95
+ blurAmount: blurAmount,
96
+ blurStyle: blurStyle,
97
+ ignoreSafeArea: ignoreSafeArea,
98
+ reducedTransparencyFallbackColor: reducedTransparencyFallbackColor
99
+ )
100
+ hosting.rootView = swiftUIView
101
+ hosting.view.setNeedsLayout()
102
+ } else {
103
+ setupHostingController()
85
104
  }
86
105
  }
87
106
 
@@ -74,10 +74,7 @@ export const BlurView = ({
74
74
  style: StyleSheet.absoluteFill,
75
75
  ...commonProps,
76
76
  ...props
77
- }), /*#__PURE__*/_jsx(View, {
78
- style: styles.children,
79
- children: children
80
- })]
77
+ }), children]
81
78
  });
82
79
  };
83
80
  export default BlurView;
@@ -85,10 +82,6 @@ const styles = StyleSheet.create({
85
82
  container: {
86
83
  position: 'relative',
87
84
  overflow: 'hidden'
88
- },
89
- children: {
90
- position: 'relative',
91
- zIndex: 1
92
85
  }
93
86
  });
94
87
  //# sourceMappingURL=BlurView.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["React","Children","Platform","StyleSheet","View","ReactNativeBlurView","jsx","_jsx","jsxs","_jsxs","BlurView","blurType","blurAmount","reducedTransparencyFallbackColor","overlayColor","style","children","ignoreSafeArea","props","overlay","backgroundColor","commonProps","count","OS","absoluteFill","styles","container","create","position","overflow","zIndex"],"sourceRoot":"../../src","sources":["BlurView.tsx"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,QAAQ,QAAQ,OAAO;AACvC,SAASC,QAAQ,EAAEC,UAAU,EAAEC,IAAI,QAAQ,cAAc;AAEzD,OAAOC,mBAAmB,MAEnB,sCAAsC;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAuD9C;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,QAAQ;EACnBC,UAAU,GAAG,EAAE;EACfC,gCAAgC,GAAG,SAAS;EAC5CC,YAAY;EACZC,KAAK;EACLC,QAAQ;EACRC,cAAc,GAAG,IAAI;EACrB,GAAGC;AACL,CAAC,KAAK;EACJ,MAAMC,OAAO,GAAG;IAAEC,eAAe,EAAEN;EAAa,CAAC;EACjD,MAAMO,WAA0B,GAAG;IACjCV,QAAQ;IACRC,UAAU;IACVK,cAAc;IACdJ;EACF,CAAC;;EAED;EACA,IAAI,CAACZ,QAAQ,CAACqB,KAAK,CAACN,QAAQ,CAAC,EAAE;IAC7B,oBACET,IAAA,CAACF,mBAAmB;MAClBU,KAAK,EAAE,CAACA,KAAK,EAAEI,OAAO,CAAE;MAAA,GACpBE,WAAW;MAAA,GACXH;IAAK,CACV,CAAC;EAEN;;EAEA;EACA,IAAIhB,QAAQ,CAACqB,EAAE,KAAK,SAAS,EAAE;IAC7B,oBACEd,KAAA,CAACJ,mBAAmB;MAACU,KAAK,EAAEA,KAAM;MAAA,GAAKM,WAAW;MAAA,GAAMH,KAAK;MAAAF,QAAA,gBAC3DT,IAAA,CAACH,IAAI;QAACW,KAAK,EAAE,CAACZ,UAAU,CAACqB,YAAY,EAAEL,OAAO;MAAE,CAAE,CAAC,EAElDH,QAAQ;IAAA,CACU,CAAC;EAE1B;;EAEA;EACA,oBACEP,KAAA,CAACL,IAAI;IAACW,KAAK,EAAE,CAACU,MAAM,CAACC,SAAS,EAAEX,KAAK,EAAEI,OAAO,CAAE;IAAAH,QAAA,gBAE9CT,IAAA,CAACF,mBAAmB;MAClBU,KAAK,EAAEZ,UAAU,CAACqB,YAAa;MAAA,GAC3BH,WAAW;MAAA,GACXH;IAAK,CACV,CAAC,eAEFX,IAAA,CAACH,IAAI;MAACW,KAAK,EAAEU,MAAM,CAACT,QAAS;MAAAA,QAAA,EAAEA;IAAQ,CAAO,CAAC;EAAA,CAC3C,CAAC;AAEX,CAAC;AAED,eAAeN,QAAQ;AAEvB,MAAMe,MAAM,GAAGtB,UAAU,CAACwB,MAAM,CAAC;EAC/BD,SAAS,EAAE;IACTE,QAAQ,EAAE,UAAU;IACpBC,QAAQ,EAAE;EACZ,CAAC;EACDb,QAAQ,EAAE;IACRY,QAAQ,EAAE,UAAU;IACpBE,MAAM,EAAE;EACV;AACF,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["React","Children","Platform","StyleSheet","View","ReactNativeBlurView","jsx","_jsx","jsxs","_jsxs","BlurView","blurType","blurAmount","reducedTransparencyFallbackColor","overlayColor","style","children","ignoreSafeArea","props","overlay","backgroundColor","commonProps","count","OS","absoluteFill","styles","container","create","position","overflow"],"sourceRoot":"../../src","sources":["BlurView.tsx"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,QAAQ,QAAQ,OAAO;AACvC,SAASC,QAAQ,EAAEC,UAAU,EAAEC,IAAI,QAAQ,cAAc;AAEzD,OAAOC,mBAAmB,MAEnB,sCAAsC;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAuD9C;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,QAAQ;EACnBC,UAAU,GAAG,EAAE;EACfC,gCAAgC,GAAG,SAAS;EAC5CC,YAAY;EACZC,KAAK;EACLC,QAAQ;EACRC,cAAc,GAAG,IAAI;EACrB,GAAGC;AACL,CAAC,KAAK;EACJ,MAAMC,OAAO,GAAG;IAAEC,eAAe,EAAEN;EAAa,CAAC;EACjD,MAAMO,WAA0B,GAAG;IACjCV,QAAQ;IACRC,UAAU;IACVK,cAAc;IACdJ;EACF,CAAC;;EAED;EACA,IAAI,CAACZ,QAAQ,CAACqB,KAAK,CAACN,QAAQ,CAAC,EAAE;IAC7B,oBACET,IAAA,CAACF,mBAAmB;MAClBU,KAAK,EAAE,CAACA,KAAK,EAAEI,OAAO,CAAE;MAAA,GACpBE,WAAW;MAAA,GACXH;IAAK,CACV,CAAC;EAEN;;EAEA;EACA,IAAIhB,QAAQ,CAACqB,EAAE,KAAK,SAAS,EAAE;IAC7B,oBACEd,KAAA,CAACJ,mBAAmB;MAACU,KAAK,EAAEA,KAAM;MAAA,GAAKM,WAAW;MAAA,GAAMH,KAAK;MAAAF,QAAA,gBAC3DT,IAAA,CAACH,IAAI;QAACW,KAAK,EAAE,CAACZ,UAAU,CAACqB,YAAY,EAAEL,OAAO;MAAE,CAAE,CAAC,EAElDH,QAAQ;IAAA,CACU,CAAC;EAE1B;;EAEA;EACA,oBACEP,KAAA,CAACL,IAAI;IAACW,KAAK,EAAE,CAACU,MAAM,CAACC,SAAS,EAAEX,KAAK,EAAEI,OAAO,CAAE;IAAAH,QAAA,gBAE9CT,IAAA,CAACF,mBAAmB;MAClBU,KAAK,EAAEZ,UAAU,CAACqB,YAAa;MAAA,GAC3BH,WAAW;MAAA,GACXH;IAAK,CACV,CAAC,EACDF,QAAQ;EAAA,CACL,CAAC;AAEX,CAAC;AAED,eAAeN,QAAQ;AAEvB,MAAMe,MAAM,GAAGtB,UAAU,CAACwB,MAAM,CAAC;EAC/BD,SAAS,EAAE;IACTE,QAAQ,EAAE,UAAU;IACpBC,QAAQ,EAAE;EACZ;AACF,CAAC,CAAC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"BlurView.d.ts","sourceRoot":"","sources":["../../../src/BlurView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACrE,OAA4B,EAC1B,KAAK,QAAQ,EACd,MAAM,sCAAsC,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;OAMG;IACH,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAE1C;;;;OAIG;IACH,YAAY,CAAC,EAAE,UAAU,CAAC;IAE1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAqD5C,CAAC;AAEF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"BlurView.d.ts","sourceRoot":"","sources":["../../../src/BlurView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACrE,OAA4B,EAC1B,KAAK,QAAQ,EACd,MAAM,sCAAsC,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;OAMG;IACH,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAE1C;;;;OAIG;IACH,YAAY,CAAC,EAAE,UAAU,CAAC;IAE1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAoD5C,CAAC;AAEF,eAAe,QAAQ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sbaiahmed1/react-native-blur",
3
- "version": "4.5.7",
3
+ "version": "4.5.8-beta.0",
4
4
  "description": "React native modern blur view",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -32,14 +32,14 @@
32
32
  "!**/.*"
33
33
  ],
34
34
  "scripts": {
35
+ "example": "yarn workspace @sbaiahmed1/react-native-blur-example-app",
35
36
  "test": "jest",
36
37
  "typecheck": "tsc",
37
38
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
38
- "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
39
+ "clean": "del-cli example/android example/ios lib",
39
40
  "prepare": "bob build",
40
41
  "release": "release-it",
41
- "setup": "yarn && yarn prepare",
42
- "setup:example": "yarn setup && cd example && bundle install && cd ios && bundle exec pod install && cd .. && yarn start --client-logs"
42
+ "setup": "yarn && yarn prepare"
43
43
  },
44
44
  "keywords": [
45
45
  "react-native",
@@ -87,7 +87,7 @@
87
87
  "react-native": "0.79.2",
88
88
  "react-native-builder-bob": "^0.40.11",
89
89
  "release-it": "^19.2.4",
90
- "turbo": "^1.10.7",
90
+ "turbo": "latest",
91
91
  "typescript": "^5.8.3"
92
92
  },
93
93
  "peerDependencies": {
@@ -176,4 +176,4 @@
176
176
  "type": "fabric-view",
177
177
  "version": "0.50.3"
178
178
  }
179
- }
179
+ }
package/src/BlurView.tsx CHANGED
@@ -129,8 +129,7 @@ export const BlurView: React.FC<BlurViewProps> = ({
129
129
  {...commonProps}
130
130
  {...props}
131
131
  />
132
- {/* Content positioned relatively on top when device is not Android */}
133
- <View style={styles.children}>{children}</View>
132
+ {children}
134
133
  </View>
135
134
  );
136
135
  };
@@ -142,8 +141,4 @@ const styles = StyleSheet.create({
142
141
  position: 'relative',
143
142
  overflow: 'hidden',
144
143
  },
145
- children: {
146
- position: 'relative',
147
- zIndex: 1,
148
- },
149
144
  });