@sbaiahmed1/react-native-blur 3.2.0 → 4.0.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.
Files changed (41) hide show
  1. package/README.md +319 -309
  2. package/ReactNativeBlur.podspec +1 -1
  3. package/android/build.gradle +2 -3
  4. package/android/src/main/java/com/sbaiahmed1/reactnativeblur/ReactNativeBlurView.kt +62 -269
  5. package/android/src/main/java/com/sbaiahmed1/reactnativeblur/ReactNativeBlurViewManager.kt +9 -9
  6. package/ios/Helpers/BlurStyleHelpers.swift +1 -1
  7. package/ios/Helpers/ReactNativeBlurViewHelper.swift +6 -35
  8. package/ios/Helpers/ReactNativeLiquidGlassViewHelper.swift +44 -0
  9. package/ios/ReactNativeBlurView.mm +8 -61
  10. package/ios/{ReactNativeBlurViewManager.m → ReactNativeBlurViewManager.mm} +5 -35
  11. package/ios/ReactNativeLiquidGlassView.h +14 -0
  12. package/ios/ReactNativeLiquidGlassView.mm +284 -0
  13. package/ios/ReactNativeLiquidGlassViewManager.h +6 -0
  14. package/ios/ReactNativeLiquidGlassViewManager.mm +20 -0
  15. package/ios/Views/AdvancedBlurView.swift +5 -40
  16. package/ios/Views/BasicColoredView.swift +6 -50
  17. package/ios/Views/LiquidGlassContainerView.swift +173 -0
  18. package/lib/module/BlurView.js +16 -33
  19. package/lib/module/BlurView.js.map +1 -1
  20. package/lib/module/LiquidGlassView.js +75 -0
  21. package/lib/module/LiquidGlassView.js.map +1 -0
  22. package/lib/module/ReactNativeBlurViewNativeComponent.ts +0 -7
  23. package/lib/module/ReactNativeLiquidGlassViewNativeComponent.ts +57 -0
  24. package/lib/module/index.js +2 -0
  25. package/lib/module/index.js.map +1 -1
  26. package/lib/typescript/src/BlurView.d.ts +19 -45
  27. package/lib/typescript/src/BlurView.d.ts.map +1 -1
  28. package/lib/typescript/src/LiquidGlassView.d.ts +85 -0
  29. package/lib/typescript/src/LiquidGlassView.d.ts.map +1 -0
  30. package/lib/typescript/src/ReactNativeBlurViewNativeComponent.d.ts +0 -6
  31. package/lib/typescript/src/ReactNativeBlurViewNativeComponent.d.ts.map +1 -1
  32. package/lib/typescript/src/ReactNativeLiquidGlassViewNativeComponent.d.ts +44 -0
  33. package/lib/typescript/src/ReactNativeLiquidGlassViewNativeComponent.d.ts.map +1 -0
  34. package/lib/typescript/src/index.d.ts +4 -0
  35. package/lib/typescript/src/index.d.ts.map +1 -1
  36. package/package.json +6 -3
  37. package/src/BlurView.tsx +36 -77
  38. package/src/LiquidGlassView.tsx +138 -0
  39. package/src/ReactNativeBlurViewNativeComponent.ts +0 -7
  40. package/src/ReactNativeLiquidGlassViewNativeComponent.ts +57 -0
  41. package/src/index.tsx +6 -0
@@ -137,14 +137,6 @@ using namespace facebook::react;
137
137
 
138
138
  _advancedBlurView = [ReactNativeBlurViewHelper createBlurViewWithFrame:frame];
139
139
 
140
- // Set initial glassTintColor from default props
141
- NSString *defaultGlassTintColorString = [[NSString alloc] initWithUTF8String:bvProps.glassTintColor.c_str()];
142
- UIColor *defaultGlassTintColor = [ReactNativeBlurView colorFromString:defaultGlassTintColorString];
143
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withGlassTintColor:defaultGlassTintColor];
144
-
145
- // Set initial glassOpacity from default props
146
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withGlassOpacity:bvProps.glassOpacity];
147
-
148
140
  // Set initial blurAmount from default props
149
141
  [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withBlurAmount:bvProps.blurAmount];
150
142
 
@@ -154,22 +146,6 @@ using namespace facebook::react;
154
146
  [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withBlurType:blurTypeString];
155
147
  }
156
148
 
157
- // Set initial isInteractive from default props
158
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withIsInteractive:bvProps.isInteractive];
159
-
160
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withIgnoringSafeArea:bvProps.ignoreSafeArea];
161
-
162
-
163
- // Set initial glassType from default props
164
- if (bvProps.glassType != facebook::react::ReactNativeBlurViewGlassType::Clear) {
165
- NSString *glassTypeString = [[NSString alloc] initWithUTF8String:toString(bvProps.glassType).c_str()];
166
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withGlassType:glassTypeString];
167
- }
168
-
169
- // Set initial type from default props
170
- NSString *blurTypeString = [[NSString alloc] initWithUTF8String:toString(bvProps.type).c_str()];
171
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withType:blurTypeString];
172
-
173
149
  // Set initial reducedTransparencyFallbackColor from default props
174
150
  if (!bvProps.reducedTransparencyFallbackColor.empty()) {
175
151
  NSString *fallbackColorString = [[NSString alloc] initWithUTF8String:bvProps.reducedTransparencyFallbackColor.c_str()];
@@ -177,6 +153,9 @@ using namespace facebook::react;
177
153
  [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withReducedTransparencyFallbackColor:fallbackColor];
178
154
  }
179
155
 
156
+ // Set initial ignoreSafeArea from default props
157
+ [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withIgnoringSafeArea:bvProps.ignoreSafeArea];
158
+
180
159
  [self addSubview:_advancedBlurView];
181
160
  }
182
161
  return self;
@@ -187,20 +166,6 @@ using namespace facebook::react;
187
166
  const auto &oldViewProps = *std::static_pointer_cast<ReactNativeBlurViewProps const>(_props);
188
167
  const auto &newViewProps = *std::static_pointer_cast<ReactNativeBlurViewProps const>(props);
189
168
 
190
- // Update glassTintColor if it has changed
191
- if (oldViewProps.glassTintColor != newViewProps.glassTintColor) {
192
- if (!newViewProps.glassTintColor.empty()) {
193
- NSString *glassTintColorString = [[NSString alloc] initWithUTF8String:newViewProps.glassTintColor.c_str()];
194
- UIColor *newGlassTintColor = [ReactNativeBlurView colorFromString:glassTintColorString];
195
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withGlassTintColor:newGlassTintColor];
196
- }
197
- }
198
-
199
- // Update glassOpacity if it has changed
200
- if (oldViewProps.glassOpacity != newViewProps.glassOpacity) {
201
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withGlassOpacity:newViewProps.glassOpacity];
202
- }
203
-
204
169
  // Update blurAmount if it has changed
205
170
  if (oldViewProps.blurAmount != newViewProps.blurAmount) {
206
171
  [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withBlurAmount:newViewProps.blurAmount];
@@ -214,29 +179,6 @@ using namespace facebook::react;
214
179
  }
215
180
  }
216
181
 
217
- // Update glassType if it has changed
218
- if (oldViewProps.glassType != newViewProps.glassType) {
219
- if (newViewProps.glassType != facebook::react::ReactNativeBlurViewGlassType::Clear) {
220
- NSString *glassTypeString = [[NSString alloc] initWithUTF8String:toString(newViewProps.glassType).c_str()];
221
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withGlassType:glassTypeString];
222
- }
223
- }
224
-
225
- // Update type if it has changed
226
- if (oldViewProps.type != newViewProps.type) {
227
- NSString *blurTypeString = [[NSString alloc] initWithUTF8String:toString(newViewProps.type).c_str()];
228
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withType:blurTypeString];
229
- }
230
-
231
- // Update isInteractive if it has changed
232
- if (oldViewProps.isInteractive != newViewProps.isInteractive) {
233
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withIsInteractive:newViewProps.isInteractive];
234
- }
235
-
236
- if (oldViewProps.ignoreSafeArea != newViewProps.ignoreSafeArea) {
237
- [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withIgnoringSafeArea:newViewProps.ignoreSafeArea];
238
- }
239
-
240
182
  // Update reducedTransparencyFallbackColor if it has changed
241
183
  if (oldViewProps.reducedTransparencyFallbackColor != newViewProps.reducedTransparencyFallbackColor) {
242
184
  if (!newViewProps.reducedTransparencyFallbackColor.empty()) {
@@ -246,6 +188,11 @@ using namespace facebook::react;
246
188
  }
247
189
  }
248
190
 
191
+ // Update ignoreSafeArea if it has changed
192
+ if (oldViewProps.ignoreSafeArea != newViewProps.ignoreSafeArea) {
193
+ [ReactNativeBlurViewHelper updateBlurView:_advancedBlurView withIgnoringSafeArea:newViewProps.ignoreSafeArea];
194
+ }
195
+
249
196
  // Store the new props
250
197
  _props = props;
251
198
 
@@ -25,18 +25,6 @@ RCT_EXPORT_MODULE(ReactNativeBlurView)
25
25
  // Export properties
26
26
 
27
27
  // Custom setters for proper type conversion
28
- RCT_CUSTOM_VIEW_PROPERTY(glassTintColor, NSString, AdvancedBlurView)
29
- {
30
- NSString *colorString = json ? [RCTConvert NSString:json] : @"clear";
31
- UIColor *color = [self colorFromString:colorString];
32
- [ReactNativeBlurViewHelper updateBlurView:view withGlassTintColor:color];
33
- }
34
-
35
- RCT_CUSTOM_VIEW_PROPERTY(glassOpacity, NSNumber, AdvancedBlurView)
36
- {
37
- double opacity = json ? [RCTConvert double:json] : 1.0;
38
- [ReactNativeBlurViewHelper updateBlurView:view withGlassOpacity:opacity];
39
- }
40
28
 
41
29
  RCT_CUSTOM_VIEW_PROPERTY(blurAmount, NSNumber, AdvancedBlurView)
42
30
  {
@@ -50,37 +38,19 @@ RCT_CUSTOM_VIEW_PROPERTY(blurType, NSString, AdvancedBlurView)
50
38
  [ReactNativeBlurViewHelper updateBlurView:view withBlurType:blurType];
51
39
  }
52
40
 
53
- RCT_CUSTOM_VIEW_PROPERTY(glassType, NSString, AdvancedBlurView)
54
- {
55
- NSString *glassType = json ? [RCTConvert NSString:json] : @"clear";
56
- [ReactNativeBlurViewHelper updateBlurView:view withGlassType:glassType];
57
- }
58
-
59
- RCT_CUSTOM_VIEW_PROPERTY(type, NSString, AdvancedBlurView)
60
- {
61
- NSString *type = json ? [RCTConvert NSString:json] : @"blur";
62
- [ReactNativeBlurViewHelper updateBlurView:view withType:type];
63
- }
64
-
65
- RCT_CUSTOM_VIEW_PROPERTY(isInteractive, NSNumber, AdvancedBlurView)
41
+ RCT_CUSTOM_VIEW_PROPERTY(reducedTransparencyFallbackColor, NSString, AdvancedBlurView)
66
42
  {
67
- BOOL isInteractive = json ? [RCTConvert BOOL:json] : YES;
68
- [ReactNativeBlurViewHelper updateBlurView:view withIsInteractive:isInteractive];
43
+ NSString *colorString = json ? [RCTConvert NSString:json] : @"#FFFFFF";
44
+ UIColor *color = [self colorFromString:colorString];
45
+ [ReactNativeBlurViewHelper updateBlurView:view withReducedTransparencyFallbackColor:color];
69
46
  }
70
47
 
71
- RCT_CUSTOM_VIEW_PROPERTY(ignoreSafeArea, NSNumber, AdvancedBlurView)
48
+ RCT_CUSTOM_VIEW_PROPERTY(ignoreSafeArea, BOOL, AdvancedBlurView)
72
49
  {
73
50
  BOOL ignoreSafeArea = json ? [RCTConvert BOOL:json] : NO;
74
51
  [ReactNativeBlurViewHelper updateBlurView:view withIgnoringSafeArea:ignoreSafeArea];
75
52
  }
76
53
 
77
- RCT_CUSTOM_VIEW_PROPERTY(reducedTransparencyFallbackColor, NSString, AdvancedBlurView)
78
- {
79
- NSString *colorString = json ? [RCTConvert NSString:json] : @"#FFFFFF";
80
- UIColor *color = [self colorFromString:colorString];
81
- [ReactNativeBlurViewHelper updateBlurView:view withReducedTransparencyFallbackColor:color];
82
- }
83
-
84
54
  // Color parsing helper method (copied from ReactNativeBlurView.mm)
85
55
  - (UIColor *)colorFromString:(NSString *)colorString {
86
56
  // Input validation
@@ -0,0 +1,14 @@
1
+ #import <React/RCTViewComponentView.h>
2
+ #import <UIKit/UIKit.h>
3
+
4
+ #ifndef ReactNativeLiquidGlassViewNativeComponent_h
5
+ #define ReactNativeLiquidGlassViewNativeComponent_h
6
+
7
+ NS_ASSUME_NONNULL_BEGIN
8
+
9
+ @interface ReactNativeLiquidGlassView : RCTViewComponentView
10
+ @end
11
+
12
+ NS_ASSUME_NONNULL_END
13
+
14
+ #endif /* ReactNativeLiquidGlassViewNativeComponent_h */
@@ -0,0 +1,284 @@
1
+ #import "ReactNativeLiquidGlassView.h"
2
+
3
+ #import <react/renderer/components/ReactNativeBlurViewSpec/ComponentDescriptors.h>
4
+ #import <react/renderer/components/ReactNativeBlurViewSpec/EventEmitters.h>
5
+ #import <react/renderer/components/ReactNativeBlurViewSpec/Props.h>
6
+ #import <react/renderer/components/ReactNativeBlurViewSpec/RCTComponentViewHelpers.h>
7
+
8
+ #import "RCTFabricComponentsPlugins.h"
9
+
10
+ #if __has_include("ReactNativeBlur-Swift.h")
11
+ #import "ReactNativeBlur-Swift.h"
12
+ #else
13
+ #import <ReactNativeBlur/ReactNativeBlur-Swift.h>
14
+ #endif
15
+
16
+ using namespace facebook::react;
17
+
18
+ @interface ReactNativeLiquidGlassView () <RCTReactNativeLiquidGlassViewViewProtocol>
19
+ @end
20
+
21
+ @implementation ReactNativeLiquidGlassView {
22
+ LiquidGlassContainerView *_liquidGlassView;
23
+ Props::Shared _props;
24
+ LayoutMetrics _layoutMetrics;
25
+ }
26
+
27
+ + (UIColor *)colorFromString:(NSString *)colorString {
28
+ // Input validation
29
+ if (!colorString || [colorString isEqualToString:@""] || colorString.length == 0) {
30
+ return [UIColor clearColor]; // Default color
31
+ }
32
+
33
+ // Prevent excessively long strings that could cause performance issues
34
+ if (colorString.length > 50) {
35
+ NSLog(@"[ReactNativeLiquidGlassView] Warning: Color string too long, using default clear color");
36
+ return [UIColor clearColor];
37
+ }
38
+
39
+ // Handle common color names
40
+ NSDictionary *colorMap = @{
41
+ @"red": [UIColor redColor],
42
+ @"blue": [UIColor blueColor],
43
+ @"green": [UIColor greenColor],
44
+ @"yellow": [UIColor yellowColor],
45
+ @"orange": [UIColor orangeColor],
46
+ @"purple": [UIColor purpleColor],
47
+ @"black": [UIColor blackColor],
48
+ @"white": [UIColor whiteColor],
49
+ @"gray": [UIColor grayColor],
50
+ @"clear": [UIColor clearColor],
51
+ @"transparent": [UIColor clearColor]
52
+ };
53
+
54
+ UIColor *namedColor = colorMap[colorString.lowercaseString];
55
+ if (namedColor) {
56
+ return namedColor;
57
+ }
58
+
59
+ // Handle hex colors (e.g., "#FF0000", "FF0000", "#FF00FF00", "FF00FF00")
60
+ NSString *hexString = colorString;
61
+ if ([hexString hasPrefix:@"#"]) {
62
+ if (hexString.length < 2) {
63
+ NSLog(@"[ReactNativeLiquidGlassView] Warning: Invalid hex color format '%@', using default clear color", colorString);
64
+ return [UIColor clearColor];
65
+ }
66
+ hexString = [hexString substringFromIndex:1];
67
+ }
68
+
69
+ // Validate hex string contains only valid hex characters
70
+ NSCharacterSet *hexCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEFabcdef"];
71
+ NSCharacterSet *invalidCharacters = [hexCharacterSet invertedSet];
72
+ if ([hexString rangeOfCharacterFromSet:invalidCharacters].location != NSNotFound) {
73
+ NSLog(@"[ReactNativeLiquidGlassView] Warning: Invalid hex color format '%@', contains non-hex characters", colorString);
74
+ return [UIColor clearColor];
75
+ }
76
+
77
+ // Handle 6-character hex (RGB)
78
+ if (hexString.length == 6) {
79
+ unsigned int hexValue;
80
+ NSScanner *scanner = [NSScanner scannerWithString:hexString];
81
+ if ([scanner scanHexInt:&hexValue] && [scanner isAtEnd]) {
82
+ return [UIColor colorWithRed:((hexValue & 0xFF0000) >> 16) / 255.0
83
+ green:((hexValue & 0x00FF00) >> 8) / 255.0
84
+ blue:(hexValue & 0x0000FF) / 255.0
85
+ alpha:1.0];
86
+ }
87
+ }
88
+ // Handle 8-character hex (RGBA)
89
+ else if (hexString.length == 8) {
90
+ unsigned long long hexValue;
91
+ NSScanner *scanner = [NSScanner scannerWithString:hexString];
92
+ if ([scanner scanHexLongLong:&hexValue] && [scanner isAtEnd]) {
93
+ return [UIColor colorWithRed:((hexValue & 0xFF000000) >> 24) / 255.0
94
+ green:((hexValue & 0x00FF0000) >> 16) / 255.0
95
+ blue:((hexValue & 0x0000FF00) >> 8) / 255.0
96
+ alpha:(hexValue & 0x000000FF) / 255.0];
97
+ }
98
+ }
99
+ // Handle 3-character hex (RGB shorthand)
100
+ else if (hexString.length == 3) {
101
+ unsigned int hexValue;
102
+ NSScanner *scanner = [NSScanner scannerWithString:hexString];
103
+ if ([scanner scanHexInt:&hexValue] && [scanner isAtEnd]) {
104
+ // Expand 3-digit hex to 6-digit (e.g., "F0A" -> "FF00AA")
105
+ unsigned int r = (hexValue & 0xF00) >> 8;
106
+ unsigned int g = (hexValue & 0x0F0) >> 4;
107
+ unsigned int b = (hexValue & 0x00F);
108
+
109
+ return [UIColor colorWithRed:(r | (r << 4)) / 255.0
110
+ green:(g | (g << 4)) / 255.0
111
+ blue:(b | (b << 4)) / 255.0
112
+ alpha:1.0];
113
+ }
114
+ }
115
+ else {
116
+ NSLog(@"[ReactNativeLiquidGlassView] Warning: Unsupported hex color length (%lu) for '%@', expected 3, 6, or 8 characters",
117
+ (unsigned long)hexString.length, colorString);
118
+ }
119
+
120
+ NSLog(@"[ReactNativeLiquidGlassView] Warning: Could not parse color '%@', using default clear color", colorString);
121
+ return [UIColor clearColor]; // Fallback to clear
122
+ }
123
+
124
+ + (ComponentDescriptorProvider)componentDescriptorProvider
125
+ {
126
+ return concreteComponentDescriptorProvider<ReactNativeLiquidGlassViewComponentDescriptor>();
127
+ }
128
+
129
+ - (instancetype)initWithFrame:(CGRect)frame
130
+ {
131
+ if (self = [super initWithFrame:frame]) {
132
+ static const auto defaultProps = std::make_shared<const ReactNativeLiquidGlassViewProps>();
133
+ _props = defaultProps;
134
+
135
+ const auto &lgProps = *std::static_pointer_cast<const ReactNativeLiquidGlassViewProps>(defaultProps);
136
+
137
+ _liquidGlassView = [ReactNativeLiquidGlassViewHelper createLiquidGlassViewWithFrame:frame];
138
+
139
+ // Set initial glassTintColor from default props
140
+ NSString *defaultGlassTintColorString = [[NSString alloc] initWithUTF8String:lgProps.glassTintColor.c_str()];
141
+ UIColor *defaultGlassTintColor = [ReactNativeLiquidGlassView colorFromString:defaultGlassTintColorString];
142
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withGlassTintColor:defaultGlassTintColor];
143
+
144
+ // Set initial glassOpacity from default props
145
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withGlassOpacity:lgProps.glassOpacity];
146
+
147
+ // Set initial glassType from default props
148
+ if (lgProps.glassType != facebook::react::ReactNativeLiquidGlassViewGlassType::Clear) {
149
+ NSString *glassTypeString = [[NSString alloc] initWithUTF8String:toString(lgProps.glassType).c_str()];
150
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withGlassType:glassTypeString];
151
+ }
152
+
153
+ // Set initial isInteractive from default props
154
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withIsInteractive:lgProps.isInteractive];
155
+
156
+ // Set initial ignoreSafeArea from default props
157
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withIgnoringSafeArea:lgProps.ignoreSafeArea];
158
+
159
+ // Set initial reducedTransparencyFallbackColor from default props
160
+ if (!lgProps.reducedTransparencyFallbackColor.empty()) {
161
+ NSString *fallbackColorString = [[NSString alloc] initWithUTF8String:lgProps.reducedTransparencyFallbackColor.c_str()];
162
+ UIColor *fallbackColor = [ReactNativeLiquidGlassView colorFromString:fallbackColorString];
163
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withReducedTransparencyFallbackColor:fallbackColor];
164
+ }
165
+
166
+ [self addSubview:_liquidGlassView];
167
+ }
168
+ return self;
169
+ }
170
+
171
+ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
172
+ {
173
+ const auto &oldViewProps = *std::static_pointer_cast<ReactNativeLiquidGlassViewProps const>(_props);
174
+ const auto &newViewProps = *std::static_pointer_cast<ReactNativeLiquidGlassViewProps const>(props);
175
+
176
+ // Update glassTintColor if it has changed
177
+ if (oldViewProps.glassTintColor != newViewProps.glassTintColor) {
178
+ if (!newViewProps.glassTintColor.empty()) {
179
+ NSString *glassTintColorString = [[NSString alloc] initWithUTF8String:newViewProps.glassTintColor.c_str()];
180
+ UIColor *newGlassTintColor = [ReactNativeLiquidGlassView colorFromString:glassTintColorString];
181
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withGlassTintColor:newGlassTintColor];
182
+ }
183
+ }
184
+
185
+ // Update glassOpacity if it has changed
186
+ if (oldViewProps.glassOpacity != newViewProps.glassOpacity) {
187
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withGlassOpacity:newViewProps.glassOpacity];
188
+ }
189
+
190
+ // Update glassType if it has changed
191
+ if (oldViewProps.glassType != newViewProps.glassType) {
192
+ if (newViewProps.glassType != facebook::react::ReactNativeLiquidGlassViewGlassType::Clear) {
193
+ NSString *glassTypeString = [[NSString alloc] initWithUTF8String:toString(newViewProps.glassType).c_str()];
194
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withGlassType:glassTypeString];
195
+ }
196
+ }
197
+
198
+ // Update isInteractive if it has changed
199
+ if (oldViewProps.isInteractive != newViewProps.isInteractive) {
200
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withIsInteractive:newViewProps.isInteractive];
201
+ }
202
+
203
+ // Update ignoreSafeArea if it has changed
204
+ if (oldViewProps.ignoreSafeArea != newViewProps.ignoreSafeArea) {
205
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withIgnoringSafeArea:newViewProps.ignoreSafeArea];
206
+ }
207
+
208
+ // Update reducedTransparencyFallbackColor if it has changed
209
+ if (oldViewProps.reducedTransparencyFallbackColor != newViewProps.reducedTransparencyFallbackColor) {
210
+ if (!newViewProps.reducedTransparencyFallbackColor.empty()) {
211
+ NSString *fallbackColorString = [[NSString alloc] initWithUTF8String:newViewProps.reducedTransparencyFallbackColor.c_str()];
212
+ UIColor *fallbackColor = [ReactNativeLiquidGlassView colorFromString:fallbackColorString];
213
+ [ReactNativeLiquidGlassViewHelper updateLiquidGlassView:_liquidGlassView withReducedTransparencyFallbackColor:fallbackColor];
214
+ }
215
+ }
216
+
217
+ // Store the new props
218
+ _props = props;
219
+
220
+ [super updateProps:props oldProps:oldProps];
221
+ }
222
+
223
+ - (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask
224
+ {
225
+ [super finalizeUpdates:updateMask];
226
+
227
+ // Apply border radius from layout metrics to the inner glass view (Callstack pattern)
228
+ if (@available(iOS 26.0, *)) {
229
+ const auto &props = *std::static_pointer_cast<ReactNativeLiquidGlassViewProps const>(_props);
230
+ const auto borderMetrics = props.resolveBorderMetrics(_layoutMetrics);
231
+
232
+ // Use topLeft.horizontal same as React Native RCTViewComponentView implementation
233
+ CGFloat radius = borderMetrics.borderRadii.topLeft.horizontal;
234
+
235
+ if (radius > 0) {
236
+ [_liquidGlassView setBorderRadius:radius];
237
+ }
238
+ }
239
+ }
240
+
241
+ - (void)layoutSubviews
242
+ {
243
+ [super layoutSubviews];
244
+ _liquidGlassView.frame = self.bounds;
245
+
246
+ // Copy corner radius from the Fabric view to the inner glass view (Callstack pattern)
247
+ _liquidGlassView.layer.cornerRadius = self.layer.cornerRadius;
248
+ _liquidGlassView.layer.cornerCurve = self.layer.cornerCurve;
249
+ _liquidGlassView.layer.masksToBounds = YES;
250
+ }
251
+
252
+ - (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics
253
+ {
254
+ _layoutMetrics = layoutMetrics;
255
+ [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
256
+ }
257
+
258
+ - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
259
+ {
260
+ UIView *contentView = [_liquidGlassView getContentView];
261
+ if (contentView) {
262
+ [contentView insertSubview:childComponentView atIndex:index];
263
+ } else {
264
+ [_liquidGlassView addSubview:childComponentView];
265
+ }
266
+ }
267
+
268
+ - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
269
+ {
270
+ [childComponentView removeFromSuperview];
271
+ }
272
+
273
+ - (void)dealloc
274
+ {
275
+ [_liquidGlassView removeFromSuperview];
276
+ _liquidGlassView = nil;
277
+ }
278
+
279
+ @end
280
+
281
+ Class<RCTComponentViewProtocol> LiquidGlassViewCls(void)
282
+ {
283
+ return ReactNativeLiquidGlassView.class;
284
+ }
@@ -0,0 +1,6 @@
1
+ #import <React/RCTViewManager.h>
2
+ #import <React/RCTUIManager.h>
3
+ #import "RCTBridge.h"
4
+
5
+ @interface ReactNativeLiquidGlassViewManager : RCTViewManager
6
+ @end
@@ -0,0 +1,20 @@
1
+ #import "ReactNativeLiquidGlassViewManager.h"
2
+ #import "ReactNativeLiquidGlassView.h"
3
+
4
+ @implementation ReactNativeLiquidGlassViewManager
5
+
6
+ RCT_EXPORT_MODULE(ReactNativeLiquidGlassView)
7
+
8
+ - (UIView *)view
9
+ {
10
+ return [[ReactNativeLiquidGlassView alloc] init];
11
+ }
12
+
13
+ RCT_EXPORT_VIEW_PROPERTY(glassType, NSString)
14
+ RCT_EXPORT_VIEW_PROPERTY(glassTintColor, NSString)
15
+ RCT_EXPORT_VIEW_PROPERTY(glassOpacity, NSNumber)
16
+ RCT_EXPORT_VIEW_PROPERTY(reducedTransparencyFallbackColor, NSString)
17
+ RCT_EXPORT_VIEW_PROPERTY(isInteractive, BOOL)
18
+ RCT_EXPORT_VIEW_PROPERTY(ignoreSafeArea, BOOL)
19
+
20
+ @end
@@ -1,65 +1,35 @@
1
1
  import SwiftUI
2
2
  import UIKit
3
3
 
4
- // MARK: - UIKit Wrapper
4
+ // MARK: - UIKit Wrapper for Blur
5
5
 
6
6
  @objc public class AdvancedBlurView: UIView {
7
7
 
8
8
  private var hostingController: UIHostingController<BasicColoredView>?
9
9
 
10
- @objc public var glassTintColor: UIColor = .clear {
11
- didSet {
12
- updateView()
13
- }
14
- }
15
-
16
- @objc public var glassOpacity: Double = 1.0 {
17
- didSet {
18
- updateView()
19
- }
20
- }
21
-
22
10
  @objc public var blurAmount: Double = 10.0 {
23
11
  didSet {
24
12
  updateView()
25
13
  }
26
14
  }
27
15
 
28
- @objc public var type: String = "blur" {
29
- didSet {
30
- updateView()
31
- }
32
- }
33
-
34
16
  @objc public var blurTypeString: String = "xlight" {
35
17
  didSet {
36
18
  updateView()
37
19
  }
38
20
  }
39
21
 
40
- @objc public var glassType: String = "clear" {
41
- didSet {
42
- updateView()
43
- }
44
- }
45
-
46
22
  @objc public var reducedTransparencyFallbackColor: UIColor = .white {
47
23
  didSet {
48
24
  updateView()
49
25
  }
50
26
  }
51
27
 
52
- @objc public var isInteractive: Bool = true {
53
- didSet {
54
- updateView()
55
- }
56
- }
57
-
58
28
  @objc public var ignoreSafeArea: Bool = false {
59
29
  didSet {
60
30
  updateView()
61
31
  }
62
- }
32
+ }
63
33
 
64
34
  public override init(frame: CGRect) {
65
35
  super.init(frame: frame)
@@ -88,15 +58,10 @@ import UIKit
88
58
 
89
59
  let blurStyle = blurStyleFromString(blurTypeString)
90
60
  let swiftUIView = BasicColoredView(
91
- glassTintColor: glassTintColor,
92
- glassOpacity: glassOpacity,
93
61
  blurAmount: blurAmount,
94
62
  blurStyle: blurStyle,
95
- type: type,
96
- glassType: glassType,
97
- reducedTransparencyFallbackColor: reducedTransparencyFallbackColor,
98
- isInteractive: isInteractive,
99
- ignoreSafeArea: ignoreSafeArea
63
+ ignoreSafeArea: ignoreSafeArea,
64
+ reducedTransparencyFallbackColor: reducedTransparencyFallbackColor
100
65
  )
101
66
 
102
67
  let hosting = UIHostingController(rootView: swiftUIView)
@@ -124,7 +89,7 @@ import UIKit
124
89
  setupHostingController()
125
90
  }
126
91
  }
127
-
92
+
128
93
  public override func didMoveToWindow() {
129
94
  super.didMoveToWindow()
130
95
  if window != nil {
@@ -3,42 +3,25 @@
3
3
  import SwiftUI
4
4
  import UIKit
5
5
 
6
- // MARK: - SwiftUI View Component
6
+ // MARK: - SwiftUI View Component for Blur
7
7
 
8
8
  struct BasicColoredView: View {
9
- let glassTintColor: UIColor
10
- let glassOpacity: Double
11
9
  let blurAmount: Double
12
10
  let blurStyle: UIBlurEffect.Style
13
- let type: String
14
- let glassType: String
15
11
  let reducedTransparencyFallbackColor: UIColor
16
- let isInteractive: Bool
17
12
  let blurIntensity: Double
18
13
  let ignoreSafeArea: Bool
19
14
 
20
15
  let isReducedTransparencyEnabled = UIAccessibility.isReduceTransparencyEnabled
21
16
 
22
-
23
- init(glassTintColor: UIColor,
24
- glassOpacity: Double,
25
- blurAmount: Double,
17
+ init(blurAmount: Double,
26
18
  blurStyle: UIBlurEffect.Style,
27
- type: String,
28
- glassType: String,
29
- reducedTransparencyFallbackColor: UIColor,
30
- isInteractive: Bool,
31
- ignoreSafeArea: Bool = false) {
32
- self.glassTintColor = glassTintColor
33
- self.glassOpacity = glassOpacity
19
+ ignoreSafeArea: Bool,
20
+ reducedTransparencyFallbackColor: UIColor) {
34
21
  self.blurAmount = blurAmount
35
22
  self.blurStyle = blurStyle
36
- self.type = type
37
- self.glassType = glassType
38
- self.reducedTransparencyFallbackColor = reducedTransparencyFallbackColor
39
- self.isInteractive = isInteractive
40
23
  self.ignoreSafeArea = ignoreSafeArea
41
-
24
+ self.reducedTransparencyFallbackColor = reducedTransparencyFallbackColor
42
25
  self.blurIntensity = mapBlurAmountToIntensity(blurAmount)
43
26
  }
44
27
 
@@ -54,34 +37,7 @@ struct BasicColoredView: View {
54
37
  .fill(Color(reducedTransparencyFallbackColor))
55
38
  )
56
39
  } else {
57
- if (type == "liquidGlass"){
58
- AnyView(liquidGlassBlurView)
59
- } else {
60
- AnyView(regularBlurView)
61
- }
62
- }
63
- }
64
-
65
- private var liquidGlassBlurView: some View {
66
- Group {
67
- if #available(iOS 26.0, *) {
68
- let baseGlassEffect = glassEffectFromString(glassType)
69
- Rectangle()
70
- .glassEffect(
71
- baseGlassEffect
72
- .tint(Color(glassTintColor).opacity(glassOpacity))
73
- .interactive(isInteractive), in: .rect
74
- )
75
- } else {
76
- // Use proper blur intensity control for liquid glass fallback
77
- Rectangle()
78
- .fill(Color(.clear))
79
- .background(Blur(style: blurStyle, intensity: blurIntensity))
80
- .overlay(
81
- Color(glassTintColor)
82
- .opacity(glassOpacity)
83
- )
84
- }
40
+ AnyView(regularBlurView)
85
41
  }
86
42
  }
87
43