@sbaiahmed1/react-native-blur 0.2.1 → 3.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -20
- package/ReactNativeBlur.podspec +2 -1
- package/android/src/main/java/com/sbaiahmed1/reactnativeblur/ReactNativeBlurView.kt +150 -46
- package/android/src/main/java/com/sbaiahmed1/reactnativeblur/ReactNativeBlurViewManager.kt +25 -0
- package/ios/ReactNativeBlurView.mm +197 -237
- package/ios/ReactNativeBlurView.swift +321 -0
- package/ios/ReactNativeBlurViewManager.h +5 -0
- package/ios/ReactNativeBlurViewManager.m +171 -0
- package/lib/module/BlurView.js +17 -2
- package/lib/module/BlurView.js.map +1 -1
- package/lib/module/ReactNativeBlurViewNativeComponent.ts +10 -3
- package/lib/typescript/src/BlurView.d.ts +36 -1
- package/lib/typescript/src/BlurView.d.ts.map +1 -1
- package/lib/typescript/src/ReactNativeBlurViewNativeComponent.d.ts +9 -3
- package/lib/typescript/src/ReactNativeBlurViewNativeComponent.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/BlurView.tsx +58 -3
- package/src/ReactNativeBlurViewNativeComponent.ts +10 -3
- package/ios/ReactNativeBlurViewManager.mm +0 -23
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
// ReactNativeBlurView.swift
|
|
2
|
+
|
|
3
|
+
import SwiftUI
|
|
4
|
+
import UIKit
|
|
5
|
+
|
|
6
|
+
// MARK: Blur View with proper intensity control
|
|
7
|
+
|
|
8
|
+
class BlurEffectView: UIVisualEffectView {
|
|
9
|
+
private var animator: UIViewPropertyAnimator?
|
|
10
|
+
private var blurStyle: UIBlurEffect.Style = .systemMaterial
|
|
11
|
+
private var intensity: Double = 1.0
|
|
12
|
+
|
|
13
|
+
override init(effect: UIVisualEffect?) {
|
|
14
|
+
super.init(effect: effect)
|
|
15
|
+
setupBlur()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
required init?(coder: NSCoder) {
|
|
19
|
+
super.init(coder: coder)
|
|
20
|
+
setupBlur()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func updateBlur(style: UIBlurEffect.Style, intensity: Double) {
|
|
24
|
+
self.blurStyle = style
|
|
25
|
+
self.intensity = intensity
|
|
26
|
+
setupBlur()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private func setupBlur() {
|
|
30
|
+
// Clean up existing animator
|
|
31
|
+
animator?.stopAnimation(true)
|
|
32
|
+
animator?.finishAnimation(at: .current)
|
|
33
|
+
animator = nil
|
|
34
|
+
|
|
35
|
+
// Reset effect
|
|
36
|
+
effect = nil
|
|
37
|
+
|
|
38
|
+
// Create new animator
|
|
39
|
+
animator = UIViewPropertyAnimator(duration: 1, curve: .linear)
|
|
40
|
+
animator?.addAnimations { [weak self] in
|
|
41
|
+
self?.effect = UIBlurEffect(style: self?.blurStyle ?? .systemMaterial)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Set intensity and pause
|
|
45
|
+
animator?.fractionComplete = intensity
|
|
46
|
+
animator?.pauseAnimation()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
deinit {
|
|
50
|
+
animator?.stopAnimation(true)
|
|
51
|
+
animator?.finishAnimation(at: .current)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
struct Blur: UIViewRepresentable {
|
|
56
|
+
var style: UIBlurEffect.Style = .systemMaterial
|
|
57
|
+
var intensity: Double = 1.0
|
|
58
|
+
|
|
59
|
+
func makeUIView(context: Context) -> BlurEffectView {
|
|
60
|
+
let effectView = BlurEffectView(effect: nil)
|
|
61
|
+
effectView.updateBlur(style: style, intensity: intensity)
|
|
62
|
+
return effectView
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
func updateUIView(_ uiView: BlurEffectView, context: Context) {
|
|
66
|
+
uiView.updateBlur(style: style, intensity: intensity)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// MARK: - Helper Functions
|
|
71
|
+
|
|
72
|
+
private func blurStyleFromString(_ styleString: String) -> UIBlurEffect.Style {
|
|
73
|
+
switch styleString {
|
|
74
|
+
case "xlight":
|
|
75
|
+
return .extraLight
|
|
76
|
+
case "light":
|
|
77
|
+
return .light
|
|
78
|
+
case "dark":
|
|
79
|
+
return .dark
|
|
80
|
+
case "extraDark":
|
|
81
|
+
return .systemThickMaterialDark
|
|
82
|
+
case "regular":
|
|
83
|
+
return .regular
|
|
84
|
+
case "prominent":
|
|
85
|
+
return .prominent
|
|
86
|
+
case "systemUltraThinMaterial":
|
|
87
|
+
return .systemUltraThinMaterial
|
|
88
|
+
case "systemThinMaterial":
|
|
89
|
+
return .systemThinMaterial
|
|
90
|
+
case "systemMaterial":
|
|
91
|
+
return .systemMaterial
|
|
92
|
+
case "systemThickMaterial":
|
|
93
|
+
return .systemThickMaterial
|
|
94
|
+
case "systemChromeMaterial":
|
|
95
|
+
return .systemChromeMaterial
|
|
96
|
+
default:
|
|
97
|
+
return .extraLight
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@available(iOS 26.0, *)
|
|
102
|
+
private func glassEffectFromString(_ glassTypeString: String) -> Glass {
|
|
103
|
+
switch glassTypeString {
|
|
104
|
+
case "regular":
|
|
105
|
+
return .regular
|
|
106
|
+
case "clear":
|
|
107
|
+
return .clear
|
|
108
|
+
default:
|
|
109
|
+
return .clear
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// MARK: - Helper Functions for Blur Amount Mapping
|
|
114
|
+
|
|
115
|
+
/// Maps blur amount (0-100) to proper blur intensity using UIViewPropertyAnimator approach
|
|
116
|
+
private func mapBlurAmountToIntensity(_ amount: Double) -> Double {
|
|
117
|
+
let clampedAmount = max(0.0, min(100.0, amount))
|
|
118
|
+
|
|
119
|
+
// Map 0-100 to 0-1.0 intensity for smooth progression
|
|
120
|
+
return clampedAmount / 100.0
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// MARK: - Simple SwiftUI View
|
|
124
|
+
|
|
125
|
+
private struct BasicColoredView: View {
|
|
126
|
+
var glassTintColor: UIColor
|
|
127
|
+
var glassOpacity: Double
|
|
128
|
+
var blurAmount: Double
|
|
129
|
+
var blurStyle: UIBlurEffect.Style
|
|
130
|
+
var type: String
|
|
131
|
+
var glassType: String
|
|
132
|
+
var reducedTransparencyFallbackColor: UIColor
|
|
133
|
+
var isInteractive: Bool
|
|
134
|
+
|
|
135
|
+
var body: some View {
|
|
136
|
+
let blurIntensity = mapBlurAmountToIntensity(blurAmount)
|
|
137
|
+
|
|
138
|
+
// Check if reduced transparency is enabled
|
|
139
|
+
let isReducedTransparencyEnabled = UIAccessibility.isReduceTransparencyEnabled
|
|
140
|
+
|
|
141
|
+
if isReducedTransparencyEnabled {
|
|
142
|
+
// Use fallback color when reduced transparency is enabled
|
|
143
|
+
Rectangle()
|
|
144
|
+
.fill(Color(reducedTransparencyFallbackColor))
|
|
145
|
+
} else {
|
|
146
|
+
if (type == "liquidGlass"){
|
|
147
|
+
if #available(iOS 26.0, *) {
|
|
148
|
+
let baseGlassEffect = glassEffectFromString(glassType)
|
|
149
|
+
Rectangle()
|
|
150
|
+
.glassEffect(
|
|
151
|
+
baseGlassEffect
|
|
152
|
+
.tint(Color(glassTintColor)
|
|
153
|
+
.opacity(glassOpacity))
|
|
154
|
+
.interactive(isInteractive)
|
|
155
|
+
, in: .rect)
|
|
156
|
+
|
|
157
|
+
} else {
|
|
158
|
+
// Use proper blur intensity control for liquid glass fallback
|
|
159
|
+
Rectangle()
|
|
160
|
+
.fill(Color(.clear))
|
|
161
|
+
.background(Blur(style: blurStyle, intensity: blurIntensity))
|
|
162
|
+
.overlay(
|
|
163
|
+
Color(glassTintColor)
|
|
164
|
+
.opacity(glassOpacity)
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
}else {
|
|
168
|
+
// Use proper blur intensity control for regular blur
|
|
169
|
+
Rectangle()
|
|
170
|
+
.fill(Color(.clear))
|
|
171
|
+
.background(Blur(style: blurStyle, intensity: blurIntensity))
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// MARK: - UIKit Wrapper
|
|
178
|
+
|
|
179
|
+
@objc public class AdvancedBlurView: UIView {
|
|
180
|
+
|
|
181
|
+
private var hostingController: UIHostingController<BasicColoredView>?
|
|
182
|
+
|
|
183
|
+
@objc public var glassTintColor: UIColor = .clear {
|
|
184
|
+
didSet {
|
|
185
|
+
updateView()
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
@objc public var glassOpacity: Double = 1.0 {
|
|
190
|
+
didSet {
|
|
191
|
+
updateView()
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@objc public var blurAmount: Double = 10.0 {
|
|
196
|
+
didSet {
|
|
197
|
+
updateView()
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@objc public var type: String = "blur" {
|
|
202
|
+
didSet {
|
|
203
|
+
updateView()
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
@objc public var blurTypeString: String = "xlight" {
|
|
208
|
+
didSet {
|
|
209
|
+
updateView()
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
@objc public var glassType: String = "clear" {
|
|
214
|
+
didSet {
|
|
215
|
+
updateView()
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
@objc public var reducedTransparencyFallbackColor: UIColor = .white {
|
|
220
|
+
didSet {
|
|
221
|
+
updateView()
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
@objc public var isInteractive: Bool = true {
|
|
226
|
+
didSet {
|
|
227
|
+
updateView()
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
public override init(frame: CGRect) {
|
|
232
|
+
super.init(frame: frame)
|
|
233
|
+
setupHostingController()
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
required init?(coder: NSCoder) {
|
|
237
|
+
super.init(coder: coder)
|
|
238
|
+
setupHostingController()
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private func setupHostingController() {
|
|
242
|
+
let blurStyle = blurStyleFromString(blurTypeString)
|
|
243
|
+
let swiftUIView = BasicColoredView(glassTintColor: glassTintColor, glassOpacity: glassOpacity, blurAmount: blurAmount, blurStyle: blurStyle, type: type, glassType: glassType, reducedTransparencyFallbackColor: reducedTransparencyFallbackColor, isInteractive: isInteractive)
|
|
244
|
+
let hosting = UIHostingController(rootView: swiftUIView)
|
|
245
|
+
|
|
246
|
+
hosting.view.backgroundColor = .clear
|
|
247
|
+
hosting.view.translatesAutoresizingMaskIntoConstraints = false
|
|
248
|
+
|
|
249
|
+
addSubview(hosting.view)
|
|
250
|
+
NSLayoutConstraint.activate([
|
|
251
|
+
hosting.view.topAnchor.constraint(equalTo: topAnchor),
|
|
252
|
+
hosting.view.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
253
|
+
hosting.view.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
254
|
+
hosting.view.bottomAnchor.constraint(equalTo: bottomAnchor)
|
|
255
|
+
])
|
|
256
|
+
|
|
257
|
+
self.hostingController = hosting
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
private func updateView() {
|
|
261
|
+
let blurStyle = blurStyleFromString(blurTypeString)
|
|
262
|
+
let newSwiftUIView = BasicColoredView(glassTintColor: glassTintColor, glassOpacity: glassOpacity, blurAmount: blurAmount, blurStyle: blurStyle, type:type, glassType: glassType, reducedTransparencyFallbackColor: reducedTransparencyFallbackColor, isInteractive: isInteractive)
|
|
263
|
+
hostingController?.rootView = newSwiftUIView
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// MARK: - Objective-C Bridging Helpers
|
|
268
|
+
|
|
269
|
+
@objc public class ReactNativeBlurViewHelper: NSObject {
|
|
270
|
+
|
|
271
|
+
/// Creates and returns a view containing a colored rectangle.
|
|
272
|
+
@objc public static func createBlurViewWithFrame(_ frame: CGRect) -> AdvancedBlurView {
|
|
273
|
+
return AdvancedBlurView(frame: frame)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/// Updates the blur view with a new glass tint color.
|
|
277
|
+
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withGlassTintColor glassTintColor: UIColor) {
|
|
278
|
+
blurView.glassTintColor = glassTintColor
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/// Updates the blur view with a new glass opacity.
|
|
282
|
+
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withGlassOpacity glassOpacity: Double) {
|
|
283
|
+
blurView.glassOpacity = glassOpacity
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/// Updates the blur view with a new blur amount.
|
|
287
|
+
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withBlurAmount blurAmount: Double) {
|
|
288
|
+
blurView.blurAmount = blurAmount
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/// Updates the blur view with a new blur type.
|
|
292
|
+
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withBlurType blurType: String) {
|
|
293
|
+
blurView.blurTypeString = blurType
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/// Updates the blur view with a new glass type.
|
|
297
|
+
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withGlassType glassType: String) {
|
|
298
|
+
blurView.glassType = glassType
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/// Updates the blur view with a new blur style.
|
|
302
|
+
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withType type: String) {
|
|
303
|
+
blurView.type = type
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/// Updates the blur view with a new blur style.
|
|
307
|
+
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withIsInteractive isInteractive: Bool) {
|
|
308
|
+
blurView.isInteractive = isInteractive
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/// Updates the blur view with a new reduced transparency fallback color.
|
|
312
|
+
@objc public static func updateBlurView(_ blurView: AdvancedBlurView, withReducedTransparencyFallbackColor fallbackColor: UIColor) {
|
|
313
|
+
blurView.reducedTransparencyFallbackColor = fallbackColor
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/// No-op updater kept for API compatibility.
|
|
317
|
+
@objc public static func updateBlurView(_ blurView: AdvancedBlurView) {
|
|
318
|
+
// Nothing to update in the minimal implementation
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
#import "ReactNativeBlurViewManager.h"
|
|
2
|
+
#import "ReactNativeBlur-Swift.h"
|
|
3
|
+
#import <React/RCTUIManager.h>
|
|
4
|
+
#import <React/RCTBridge.h>
|
|
5
|
+
|
|
6
|
+
@interface ReactNativeBlurViewManager ()
|
|
7
|
+
|
|
8
|
+
@end
|
|
9
|
+
|
|
10
|
+
@implementation ReactNativeBlurViewManager
|
|
11
|
+
|
|
12
|
+
RCT_EXPORT_MODULE(ReactNativeBlurView)
|
|
13
|
+
|
|
14
|
+
- (UIView *)view
|
|
15
|
+
{
|
|
16
|
+
return [ReactNativeBlurViewHelper createBlurViewWithFrame:CGRectZero];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Export properties
|
|
20
|
+
|
|
21
|
+
// Custom setters for proper type conversion
|
|
22
|
+
RCT_CUSTOM_VIEW_PROPERTY(glassTintColor, NSString, AdvancedBlurView)
|
|
23
|
+
{
|
|
24
|
+
NSString *colorString = json ? [RCTConvert NSString:json] : @"clear";
|
|
25
|
+
UIColor *color = [self colorFromString:colorString];
|
|
26
|
+
[ReactNativeBlurViewHelper updateBlurView:view withGlassTintColor:color];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
RCT_CUSTOM_VIEW_PROPERTY(glassOpacity, NSNumber, AdvancedBlurView)
|
|
30
|
+
{
|
|
31
|
+
double opacity = json ? [RCTConvert double:json] : 1.0;
|
|
32
|
+
[ReactNativeBlurViewHelper updateBlurView:view withGlassOpacity:opacity];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
RCT_CUSTOM_VIEW_PROPERTY(blurAmount, NSNumber, AdvancedBlurView)
|
|
36
|
+
{
|
|
37
|
+
double amount = json ? [RCTConvert double:json] : 10.0;
|
|
38
|
+
[ReactNativeBlurViewHelper updateBlurView:view withBlurAmount:amount];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
RCT_CUSTOM_VIEW_PROPERTY(blurType, NSString, AdvancedBlurView)
|
|
42
|
+
{
|
|
43
|
+
NSString *blurType = json ? [RCTConvert NSString:json] : @"xlight";
|
|
44
|
+
[ReactNativeBlurViewHelper updateBlurView:view withBlurType:blurType];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
RCT_CUSTOM_VIEW_PROPERTY(glassType, NSString, AdvancedBlurView)
|
|
48
|
+
{
|
|
49
|
+
NSString *glassType = json ? [RCTConvert NSString:json] : @"clear";
|
|
50
|
+
[ReactNativeBlurViewHelper updateBlurView:view withGlassType:glassType];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
RCT_CUSTOM_VIEW_PROPERTY(type, NSString, AdvancedBlurView)
|
|
54
|
+
{
|
|
55
|
+
NSString *type = json ? [RCTConvert NSString:json] : @"blur";
|
|
56
|
+
[ReactNativeBlurViewHelper updateBlurView:view withType:type];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
RCT_CUSTOM_VIEW_PROPERTY(isInteractive, NSNumber, AdvancedBlurView)
|
|
60
|
+
{
|
|
61
|
+
BOOL isInteractive = json ? [RCTConvert BOOL:json] : YES;
|
|
62
|
+
[ReactNativeBlurViewHelper updateBlurView:view withIsInteractive:isInteractive];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
RCT_CUSTOM_VIEW_PROPERTY(reducedTransparencyFallbackColor, NSString, AdvancedBlurView)
|
|
66
|
+
{
|
|
67
|
+
NSString *colorString = json ? [RCTConvert NSString:json] : @"#FFFFFF";
|
|
68
|
+
UIColor *color = [self colorFromString:colorString];
|
|
69
|
+
[ReactNativeBlurViewHelper updateBlurView:view withReducedTransparencyFallbackColor:color];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Color parsing helper method (copied from ReactNativeBlurView.mm)
|
|
73
|
+
- (UIColor *)colorFromString:(NSString *)colorString {
|
|
74
|
+
// Input validation
|
|
75
|
+
if (!colorString || [colorString isEqualToString:@""] || colorString.length == 0) {
|
|
76
|
+
return [UIColor clearColor]; // Default color
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Prevent excessively long strings that could cause performance issues
|
|
80
|
+
if (colorString.length > 50) {
|
|
81
|
+
NSLog(@"[ReactNativeBlurViewManager] Warning: Color string too long, using default clear color");
|
|
82
|
+
return [UIColor clearColor];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Handle common color names
|
|
86
|
+
NSDictionary *colorMap = @{
|
|
87
|
+
@"red": [UIColor redColor],
|
|
88
|
+
@"blue": [UIColor blueColor],
|
|
89
|
+
@"green": [UIColor greenColor],
|
|
90
|
+
@"yellow": [UIColor yellowColor],
|
|
91
|
+
@"orange": [UIColor orangeColor],
|
|
92
|
+
@"purple": [UIColor purpleColor],
|
|
93
|
+
@"black": [UIColor blackColor],
|
|
94
|
+
@"white": [UIColor whiteColor],
|
|
95
|
+
@"gray": [UIColor grayColor],
|
|
96
|
+
@"clear": [UIColor clearColor],
|
|
97
|
+
@"transparent": [UIColor clearColor]
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
UIColor *namedColor = colorMap[colorString.lowercaseString];
|
|
101
|
+
if (namedColor) {
|
|
102
|
+
return namedColor;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Handle hex colors (e.g., "#FF0000", "FF0000", "#FF00FF00", "FF00FF00")
|
|
106
|
+
NSString *hexString = colorString;
|
|
107
|
+
if ([hexString hasPrefix:@"#"]) {
|
|
108
|
+
if (hexString.length < 2) {
|
|
109
|
+
NSLog(@"[ReactNativeBlurViewManager] Warning: Invalid hex color format '%@', using default clear color", colorString);
|
|
110
|
+
return [UIColor clearColor];
|
|
111
|
+
}
|
|
112
|
+
hexString = [hexString substringFromIndex:1];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Validate hex string contains only valid hex characters
|
|
116
|
+
NSCharacterSet *hexCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEFabcdef"];
|
|
117
|
+
NSCharacterSet *invalidCharacters = [hexCharacterSet invertedSet];
|
|
118
|
+
if ([hexString rangeOfCharacterFromSet:invalidCharacters].location != NSNotFound) {
|
|
119
|
+
NSLog(@"[ReactNativeBlurViewManager] Warning: Invalid hex color format '%@', contains non-hex characters", colorString);
|
|
120
|
+
return [UIColor clearColor];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Handle 6-character hex (RGB)
|
|
124
|
+
if (hexString.length == 6) {
|
|
125
|
+
unsigned int hexValue;
|
|
126
|
+
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
|
127
|
+
if ([scanner scanHexInt:&hexValue] && [scanner isAtEnd]) {
|
|
128
|
+
return [UIColor colorWithRed:((hexValue & 0xFF0000) >> 16) / 255.0
|
|
129
|
+
green:((hexValue & 0x00FF00) >> 8) / 255.0
|
|
130
|
+
blue:(hexValue & 0x0000FF) / 255.0
|
|
131
|
+
alpha:1.0];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Handle 8-character hex (RGBA)
|
|
135
|
+
else if (hexString.length == 8) {
|
|
136
|
+
unsigned long long hexValue;
|
|
137
|
+
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
|
138
|
+
if ([scanner scanHexLongLong:&hexValue] && [scanner isAtEnd]) {
|
|
139
|
+
return [UIColor colorWithRed:((hexValue & 0xFF000000) >> 24) / 255.0
|
|
140
|
+
green:((hexValue & 0x00FF0000) >> 16) / 255.0
|
|
141
|
+
blue:((hexValue & 0x0000FF00) >> 8) / 255.0
|
|
142
|
+
alpha:(hexValue & 0x000000FF) / 255.0];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Handle 3-character hex (RGB shorthand)
|
|
146
|
+
else if (hexString.length == 3) {
|
|
147
|
+
unsigned int hexValue;
|
|
148
|
+
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
|
149
|
+
if ([scanner scanHexInt:&hexValue] && [scanner isAtEnd]) {
|
|
150
|
+
// Expand 3-digit hex to 6-digit (e.g., "F0A" -> "FF00AA")
|
|
151
|
+
unsigned int r = (hexValue & 0xF00) >> 8;
|
|
152
|
+
unsigned int g = (hexValue & 0x0F0) >> 4;
|
|
153
|
+
unsigned int b = (hexValue & 0x00F);
|
|
154
|
+
|
|
155
|
+
return [UIColor colorWithRed:(r | (r << 4)) / 255.0
|
|
156
|
+
green:(g | (g << 4)) / 255.0
|
|
157
|
+
blue:(b | (b << 4)) / 255.0
|
|
158
|
+
alpha:1.0];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
NSLog(@"[ReactNativeBlurViewManager] Warning: Unsupported hex color length (%lu) for '%@', expected 3, 6, or 8 characters",
|
|
163
|
+
(unsigned long)hexString.length, colorString);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
NSLog(@"[ReactNativeBlurViewManager] Warning: Could not parse color '%@', using default clear color", colorString);
|
|
167
|
+
return [UIColor clearColor]; // Fallback to clear
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@end
|
|
171
|
+
|
package/lib/module/BlurView.js
CHANGED
|
@@ -27,11 +27,16 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
29
|
export const BlurView = ({
|
|
30
|
-
blurType = '
|
|
30
|
+
blurType = 'xlight',
|
|
31
31
|
blurAmount = 10,
|
|
32
|
-
reducedTransparencyFallbackColor,
|
|
32
|
+
reducedTransparencyFallbackColor = '#FFFFFF',
|
|
33
33
|
style,
|
|
34
34
|
children,
|
|
35
|
+
type = 'blur',
|
|
36
|
+
glassType = 'clear',
|
|
37
|
+
glassTintColor = 'clear',
|
|
38
|
+
glassOpacity = 1.0,
|
|
39
|
+
isInteractive = true,
|
|
35
40
|
...props
|
|
36
41
|
}) => {
|
|
37
42
|
// If no children, render the blur view directly (for background use)
|
|
@@ -39,8 +44,13 @@ export const BlurView = ({
|
|
|
39
44
|
return /*#__PURE__*/_jsx(ReactNativeBlurView, {
|
|
40
45
|
blurType: blurType,
|
|
41
46
|
blurAmount: blurAmount,
|
|
47
|
+
glassType: glassType,
|
|
48
|
+
glassTintColor: glassTintColor,
|
|
49
|
+
glassOpacity: glassOpacity,
|
|
50
|
+
type: type,
|
|
42
51
|
reducedTransparencyFallbackColor: reducedTransparencyFallbackColor,
|
|
43
52
|
style: style,
|
|
53
|
+
isInteractive: isInteractive,
|
|
44
54
|
...props
|
|
45
55
|
});
|
|
46
56
|
}
|
|
@@ -54,6 +64,11 @@ export const BlurView = ({
|
|
|
54
64
|
children: [/*#__PURE__*/_jsx(ReactNativeBlurView, {
|
|
55
65
|
blurType: blurType,
|
|
56
66
|
blurAmount: blurAmount,
|
|
67
|
+
glassType: glassType,
|
|
68
|
+
glassTintColor: glassTintColor,
|
|
69
|
+
glassOpacity: glassOpacity,
|
|
70
|
+
type: type,
|
|
71
|
+
isInteractive: isInteractive,
|
|
57
72
|
reducedTransparencyFallbackColor: reducedTransparencyFallbackColor,
|
|
58
73
|
style: {
|
|
59
74
|
position: 'absolute',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","View","ReactNativeBlurView","jsx","_jsx","jsxs","_jsxs","BlurView","blurType","blurAmount","reducedTransparencyFallbackColor","style","children","props","Children","count","position","overflow","top","left","right","bottom","zIndex"],"sourceRoot":"../../src","sources":["BlurView.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,QAAQ,cAAc;AAEnC,OAAOC,mBAAmB,MAEnB,sCAAsC;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;
|
|
1
|
+
{"version":3,"names":["React","View","ReactNativeBlurView","jsx","_jsx","jsxs","_jsxs","BlurView","blurType","blurAmount","reducedTransparencyFallbackColor","style","children","type","glassType","glassTintColor","glassOpacity","isInteractive","props","Children","count","position","overflow","top","left","right","bottom","zIndex"],"sourceRoot":"../../src","sources":["BlurView.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,QAAQ,cAAc;AAEnC,OAAOC,mBAAmB,MAEnB,sCAAsC;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAwE9C;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,KAAK;EACLC,QAAQ;EACRC,IAAI,GAAG,MAAM;EACbC,SAAS,GAAG,OAAO;EACnBC,cAAc,GAAG,OAAO;EACxBC,YAAY,GAAG,GAAG;EAClBC,aAAa,GAAG,IAAI;EACpB,GAAGC;AACL,CAAC,KAAK;EACJ;EACA,IAAIlB,KAAK,CAACmB,QAAQ,CAACC,KAAK,CAACR,QAAQ,CAAC,KAAK,CAAC,EAAE;IACxC,oBACER,IAAA,CAACF,mBAAmB;MAClBM,QAAQ,EAAEA,QAAS;MACnBC,UAAU,EAAEA,UAAW;MACvBK,SAAS,EAAEA,SAAU;MACrBC,cAAc,EAAEA,cAAe;MAC/BC,YAAY,EAAEA,YAAa;MAC3BH,IAAI,EAAEA,IAAK;MACXH,gCAAgC,EAAEA,gCAAiC;MACnEC,KAAK,EAAEA,KAAM;MACbM,aAAa,EAAEA,aAAc;MAAA,GACzBC;IAAK,CACV,CAAC;EAEN;;EAEA;EACA,oBACEZ,KAAA,CAACL,IAAI;IAACU,KAAK,EAAE,CAAC;MAAEU,QAAQ,EAAE,UAAU;MAAEC,QAAQ,EAAE;IAAS,CAAC,EAAEX,KAAK,CAAE;IAAAC,QAAA,gBAEjER,IAAA,CAACF,mBAAmB;MAClBM,QAAQ,EAAEA,QAAS;MACnBC,UAAU,EAAEA,UAAW;MACvBK,SAAS,EAAEA,SAAU;MACrBC,cAAc,EAAEA,cAAe;MAC/BC,YAAY,EAAEA,YAAa;MAC3BH,IAAI,EAAEA,IAAK;MACXI,aAAa,EAAEA,aAAc;MAC7BP,gCAAgC,EAAEA,gCAAiC;MACnEC,KAAK,EAAE;QACLU,QAAQ,EAAE,UAAU;QACpBE,GAAG,EAAE,CAAC;QACNC,IAAI,EAAE,CAAC;QACPC,KAAK,EAAE,CAAC;QACRC,MAAM,EAAE;MACV,CAAE;MAAA,GACER;IAAK,CACV,CAAC,eAEFd,IAAA,CAACH,IAAI;MAACU,KAAK,EAAE;QAAEU,QAAQ,EAAE,UAAU;QAAEM,MAAM,EAAE;MAAE,CAAE;MAAAf,QAAA,EAAEA;IAAQ,CAAO,CAAC;EAAA,CAC/D,CAAC;AAEX,CAAC;AAED,eAAeL,QAAQ","ignoreList":[]}
|
|
@@ -18,10 +18,17 @@ export type BlurType =
|
|
|
18
18
|
| 'systemThickMaterial'
|
|
19
19
|
| 'systemChromeMaterial';
|
|
20
20
|
|
|
21
|
+
export type GlassType = 'clear' | 'regular';
|
|
22
|
+
|
|
21
23
|
interface NativeProps extends ViewProps {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
glassTintColor?: WithDefault<string, 'clear'>;
|
|
25
|
+
glassOpacity?: WithDefault<Double, 1.0>;
|
|
26
|
+
blurAmount?: WithDefault<Double, 10.0>;
|
|
27
|
+
type?: WithDefault<'blur' | 'liquidGlass', 'blur'>;
|
|
28
|
+
blurType?: WithDefault<BlurType, 'xlight'>;
|
|
29
|
+
glassType?: WithDefault<GlassType, 'clear'>;
|
|
30
|
+
reducedTransparencyFallbackColor?: WithDefault<string, '#FFFFFF'>;
|
|
31
|
+
isInteractive?: WithDefault<boolean, true>;
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
export default codegenNativeComponent<NativeProps>('ReactNativeBlurView');
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { ViewStyle, StyleProp } from 'react-native';
|
|
3
3
|
import { type BlurType } from './ReactNativeBlurViewNativeComponent';
|
|
4
|
+
import type { GlassType } from '../src/ReactNativeBlurViewNativeComponent';
|
|
4
5
|
export interface BlurViewProps {
|
|
5
6
|
/**
|
|
6
7
|
* The type of blur effect to apply
|
|
7
|
-
* @default '
|
|
8
|
+
* @default 'xlight'
|
|
8
9
|
*/
|
|
9
10
|
blurType?: BlurType;
|
|
10
11
|
/**
|
|
@@ -15,6 +16,7 @@ export interface BlurViewProps {
|
|
|
15
16
|
/**
|
|
16
17
|
* Fallback color when reduced transparency is enabled
|
|
17
18
|
* Accepts hex color strings like '#FFFFFF'
|
|
19
|
+
* @default '#FFFFFF'
|
|
18
20
|
*/
|
|
19
21
|
reducedTransparencyFallbackColor?: string;
|
|
20
22
|
/**
|
|
@@ -25,6 +27,39 @@ export interface BlurViewProps {
|
|
|
25
27
|
* Child components to render inside the blur view
|
|
26
28
|
*/
|
|
27
29
|
children?: React.ReactNode;
|
|
30
|
+
/**
|
|
31
|
+
* Platform: iOS only
|
|
32
|
+
* The type of glass effect to apply
|
|
33
|
+
* @default 'clear'
|
|
34
|
+
*/
|
|
35
|
+
glassType?: GlassType;
|
|
36
|
+
/**
|
|
37
|
+
* Platform: iOS only
|
|
38
|
+
* The tint color of the glass effect
|
|
39
|
+
* accepts hex color strings like '#FFFFFF'
|
|
40
|
+
* accepts color names like 'white', 'clear', 'black', 'red', 'green', 'blue', 'yellow', 'cyan', 'magenta'
|
|
41
|
+
* @default 'clear'
|
|
42
|
+
*/
|
|
43
|
+
glassTintColor?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Platform: iOS only
|
|
46
|
+
* The opacity of the glass effect (0-1)
|
|
47
|
+
* @default 1.0
|
|
48
|
+
*/
|
|
49
|
+
glassOpacity?: number;
|
|
50
|
+
/**
|
|
51
|
+
* The type of blur effect to apply
|
|
52
|
+
* liquidGlass = iOS Only
|
|
53
|
+
* blur = Android | iOS
|
|
54
|
+
* @default 'blur'
|
|
55
|
+
*/
|
|
56
|
+
type?: 'blur' | 'liquidGlass';
|
|
57
|
+
/**
|
|
58
|
+
* Platform: iOS only
|
|
59
|
+
* Whether the blur view should be interactive
|
|
60
|
+
* @default true
|
|
61
|
+
*/
|
|
62
|
+
isInteractive?: boolean;
|
|
28
63
|
}
|
|
29
64
|
/**
|
|
30
65
|
* A cross-platform blur view component that provides native blur effects.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlurView.d.ts","sourceRoot":"","sources":["../../../src/BlurView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzD,OAA4B,EAC1B,KAAK,QAAQ,EACd,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"BlurView.d.ts","sourceRoot":"","sources":["../../../src/BlurView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzD,OAA4B,EAC1B,KAAK,QAAQ,EACd,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAE3E,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAE1C;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IAE9B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAyD5C,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import type { ViewProps } from 'react-native';
|
|
2
2
|
import type { WithDefault, Double } from 'react-native/Libraries/Types/CodegenTypes';
|
|
3
3
|
export type BlurType = 'xlight' | 'light' | 'dark' | 'extraDark' | 'regular' | 'prominent' | 'systemUltraThinMaterial' | 'systemThinMaterial' | 'systemMaterial' | 'systemThickMaterial' | 'systemChromeMaterial';
|
|
4
|
+
export type GlassType = 'clear' | 'regular';
|
|
4
5
|
interface NativeProps extends ViewProps {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
glassTintColor?: WithDefault<string, 'clear'>;
|
|
7
|
+
glassOpacity?: WithDefault<Double, 1.0>;
|
|
8
|
+
blurAmount?: WithDefault<Double, 10.0>;
|
|
9
|
+
type?: WithDefault<'blur' | 'liquidGlass', 'blur'>;
|
|
10
|
+
blurType?: WithDefault<BlurType, 'xlight'>;
|
|
11
|
+
glassType?: WithDefault<GlassType, 'clear'>;
|
|
12
|
+
reducedTransparencyFallbackColor?: WithDefault<string, '#FFFFFF'>;
|
|
13
|
+
isInteractive?: WithDefault<boolean, true>;
|
|
8
14
|
}
|
|
9
15
|
declare const _default: import("react-native/Libraries/Utilities/codegenNativeComponent").NativeComponentType<NativeProps>;
|
|
10
16
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactNativeBlurViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/ReactNativeBlurViewNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACP,MAAM,2CAA2C,CAAC;AAEnD,MAAM,MAAM,QAAQ,GAChB,QAAQ,GACR,OAAO,GACP,MAAM,GACN,WAAW,GACX,SAAS,GACT,WAAW,GACX,yBAAyB,GACzB,oBAAoB,GACpB,gBAAgB,GAChB,qBAAqB,GACrB,sBAAsB,CAAC;AAE3B,UAAU,WAAY,SAAQ,SAAS;IACrC,
|
|
1
|
+
{"version":3,"file":"ReactNativeBlurViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/ReactNativeBlurViewNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACP,MAAM,2CAA2C,CAAC;AAEnD,MAAM,MAAM,QAAQ,GAChB,QAAQ,GACR,OAAO,GACP,MAAM,GACN,WAAW,GACX,SAAS,GACT,WAAW,GACX,yBAAyB,GACzB,oBAAoB,GACpB,gBAAgB,GAChB,qBAAqB,GACrB,sBAAsB,CAAC;AAE3B,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE5C,UAAU,WAAY,SAAQ,SAAS;IACrC,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9C,YAAY,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACxC,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,GAAG,aAAa,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC3C,SAAS,CAAC,EAAE,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC5C,gCAAgC,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClE,aAAa,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;CAC5C;;AAED,wBAA0E"}
|