@abeman/react-native-nitro-blur 0.1.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 (86) hide show
  1. package/LICENSE +20 -0
  2. package/NitroBlur.podspec +29 -0
  3. package/README.md +200 -0
  4. package/android/CMakeLists.txt +24 -0
  5. package/android/build.gradle +120 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  8. package/android/src/main/java/com/margelo/nitro/nitroblur/NitroBlur.kt +229 -0
  9. package/android/src/main/java/com/margelo/nitro/nitroblur/NitroBlurPackage.kt +31 -0
  10. package/android/src/main/java/com/margelo/nitro/nitroblur/NitroBlurTarget.kt +149 -0
  11. package/android/src/main/java/com/margelo/nitro/nitroblur/NitroBlurTargetViewGroupManager.kt +47 -0
  12. package/android/src/main/java/com/margelo/nitro/nitroblur/TintStyle.kt +85 -0
  13. package/ios/NitroBlur.swift +173 -0
  14. package/ios/NitroBlurTarget.swift +5 -0
  15. package/lib/module/NitroBlur.nitro.js +4 -0
  16. package/lib/module/NitroBlur.nitro.js.map +1 -0
  17. package/lib/module/NitroBlurTarget.nitro.js +4 -0
  18. package/lib/module/NitroBlurTarget.nitro.js.map +1 -0
  19. package/lib/module/index.js +114 -0
  20. package/lib/module/index.js.map +1 -0
  21. package/lib/module/package.json +1 -0
  22. package/lib/typescript/package.json +1 -0
  23. package/lib/typescript/src/NitroBlur.nitro.d.ts +25 -0
  24. package/lib/typescript/src/NitroBlur.nitro.d.ts.map +1 -0
  25. package/lib/typescript/src/NitroBlurTarget.nitro.d.ts +7 -0
  26. package/lib/typescript/src/NitroBlurTarget.nitro.d.ts.map +1 -0
  27. package/lib/typescript/src/index.d.ts +201 -0
  28. package/lib/typescript/src/index.d.ts.map +1 -0
  29. package/nitro.json +33 -0
  30. package/nitrogen/generated/android/c++/JBlurMethod.hpp +61 -0
  31. package/nitrogen/generated/android/c++/JBlurTint.hpp +115 -0
  32. package/nitrogen/generated/android/c++/JHybridNitroBlurSpec.cpp +99 -0
  33. package/nitrogen/generated/android/c++/JHybridNitroBlurSpec.hpp +72 -0
  34. package/nitrogen/generated/android/c++/JHybridNitroBlurTargetSpec.cpp +49 -0
  35. package/nitrogen/generated/android/c++/JHybridNitroBlurTargetSpec.hpp +63 -0
  36. package/nitrogen/generated/android/c++/views/JHybridNitroBlurStateUpdater.cpp +72 -0
  37. package/nitrogen/generated/android/c++/views/JHybridNitroBlurStateUpdater.hpp +49 -0
  38. package/nitrogen/generated/android/c++/views/JHybridNitroBlurTargetStateUpdater.cpp +53 -0
  39. package/nitrogen/generated/android/c++/views/JHybridNitroBlurTargetStateUpdater.hpp +49 -0
  40. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroblur/BlurMethod.kt +24 -0
  41. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroblur/BlurTint.kt +42 -0
  42. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroblur/HybridNitroBlurSpec.kt +81 -0
  43. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroblur/HybridNitroBlurTargetSpec.kt +53 -0
  44. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroblur/nitroblurOnLoad.kt +35 -0
  45. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroblur/views/HybridNitroBlurManager.kt +80 -0
  46. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroblur/views/HybridNitroBlurStateUpdater.kt +23 -0
  47. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroblur/views/HybridNitroBlurTargetManager.kt +80 -0
  48. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroblur/views/HybridNitroBlurTargetStateUpdater.kt +23 -0
  49. package/nitrogen/generated/android/nitroblur+autolinking.cmake +87 -0
  50. package/nitrogen/generated/android/nitroblur+autolinking.gradle +27 -0
  51. package/nitrogen/generated/android/nitroblurOnLoad.cpp +74 -0
  52. package/nitrogen/generated/android/nitroblurOnLoad.hpp +34 -0
  53. package/nitrogen/generated/ios/NitroBlur+autolinking.rb +60 -0
  54. package/nitrogen/generated/ios/NitroBlur-Swift-Cxx-Bridge.cpp +50 -0
  55. package/nitrogen/generated/ios/NitroBlur-Swift-Cxx-Bridge.hpp +57 -0
  56. package/nitrogen/generated/ios/NitroBlur-Swift-Cxx-Umbrella.hpp +52 -0
  57. package/nitrogen/generated/ios/NitroBlurAutolinking.mm +41 -0
  58. package/nitrogen/generated/ios/NitroBlurAutolinking.swift +38 -0
  59. package/nitrogen/generated/ios/c++/HybridNitroBlurSpecSwift.cpp +11 -0
  60. package/nitrogen/generated/ios/c++/HybridNitroBlurSpecSwift.hpp +110 -0
  61. package/nitrogen/generated/ios/c++/HybridNitroBlurTargetSpecSwift.cpp +11 -0
  62. package/nitrogen/generated/ios/c++/HybridNitroBlurTargetSpecSwift.hpp +75 -0
  63. package/nitrogen/generated/ios/c++/views/HybridNitroBlurComponent.mm +142 -0
  64. package/nitrogen/generated/ios/c++/views/HybridNitroBlurTargetComponent.mm +118 -0
  65. package/nitrogen/generated/ios/swift/BlurMethod.swift +44 -0
  66. package/nitrogen/generated/ios/swift/BlurTint.swift +116 -0
  67. package/nitrogen/generated/ios/swift/HybridNitroBlurSpec.swift +59 -0
  68. package/nitrogen/generated/ios/swift/HybridNitroBlurSpec_cxx.swift +200 -0
  69. package/nitrogen/generated/ios/swift/HybridNitroBlurTargetSpec.swift +55 -0
  70. package/nitrogen/generated/ios/swift/HybridNitroBlurTargetSpec_cxx.swift +147 -0
  71. package/nitrogen/generated/shared/c++/BlurMethod.hpp +80 -0
  72. package/nitrogen/generated/shared/c++/BlurTint.hpp +152 -0
  73. package/nitrogen/generated/shared/c++/HybridNitroBlurSpec.cpp +30 -0
  74. package/nitrogen/generated/shared/c++/HybridNitroBlurSpec.hpp +75 -0
  75. package/nitrogen/generated/shared/c++/HybridNitroBlurTargetSpec.cpp +21 -0
  76. package/nitrogen/generated/shared/c++/HybridNitroBlurTargetSpec.hpp +62 -0
  77. package/nitrogen/generated/shared/c++/views/HybridNitroBlurComponent.cpp +127 -0
  78. package/nitrogen/generated/shared/c++/views/HybridNitroBlurComponent.hpp +116 -0
  79. package/nitrogen/generated/shared/c++/views/HybridNitroBlurTargetComponent.cpp +72 -0
  80. package/nitrogen/generated/shared/c++/views/HybridNitroBlurTargetComponent.hpp +109 -0
  81. package/nitrogen/generated/shared/json/NitroBlurConfig.json +14 -0
  82. package/nitrogen/generated/shared/json/NitroBlurTargetConfig.json +9 -0
  83. package/package.json +174 -0
  84. package/src/NitroBlur.nitro.ts +56 -0
  85. package/src/NitroBlurTarget.nitro.ts +13 -0
  86. package/src/index.tsx +215 -0
@@ -0,0 +1,149 @@
1
+ package com.margelo.nitro.nitroblur
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.view.View
5
+ import android.view.ViewGroup
6
+ import com.facebook.proguard.annotations.DoNotStrip
7
+ import com.facebook.react.uimanager.ThemedReactContext
8
+ import eightbitlab.com.blurview.BlurTarget
9
+
10
+ @DoNotStrip
11
+ class HybridNitroBlurTarget(val context: ThemedReactContext) : HybridNitroBlurTargetSpec() {
12
+
13
+ private val containerView = BlurTargetContainer(context)
14
+
15
+ override val view: View get() = containerView
16
+
17
+ val blurTargetView: BlurTarget get() = containerView.blurTargetView
18
+ }
19
+
20
+ /**
21
+ * A container view that delegates child management to an inner BlurTarget.
22
+ * This is needed because the Dimezis BlurView library requires a BlurTarget
23
+ * as the root view to capture and blur its content.
24
+ *
25
+ * When adding a child to this view, we want to actually add it to the blur target view.
26
+ * Because of this we need to override add, remove and measurement methods.
27
+ */
28
+ @SuppressLint("ViewConstructor")
29
+ class BlurTargetContainer(context: ThemedReactContext) : ViewGroup(context) {
30
+
31
+ internal val blurTargetView = ReactCompatibleBlurTarget(context)
32
+
33
+ init {
34
+ super.addView(
35
+ blurTargetView,
36
+ LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
37
+ )
38
+ }
39
+
40
+ // region Child delegation to blurTargetView
41
+
42
+ override fun addView(child: View?) {
43
+ if (child === blurTargetView) {
44
+ super.addView(child)
45
+ return
46
+ }
47
+ blurTargetView.addView(child)
48
+ }
49
+
50
+ override fun addView(child: View?, index: Int) {
51
+ if (child === blurTargetView) {
52
+ super.addView(child, index)
53
+ return
54
+ }
55
+ blurTargetView.addView(child, index)
56
+ }
57
+
58
+ override fun addView(child: View?, params: LayoutParams?) {
59
+ if (child === blurTargetView) {
60
+ super.addView(child, toHostLayoutParams(params))
61
+ return
62
+ }
63
+ blurTargetView.addView(child, params)
64
+ }
65
+
66
+ override fun addView(child: View?, index: Int, params: LayoutParams?) {
67
+ if (child === blurTargetView) {
68
+ super.addView(child, index, toHostLayoutParams(params))
69
+ return
70
+ }
71
+ blurTargetView.addView(child, index, params)
72
+ }
73
+
74
+ override fun addView(child: View?, width: Int, height: Int) {
75
+ if (child === blurTargetView) {
76
+ super.addView(child, width, height)
77
+ return
78
+ }
79
+ blurTargetView.addView(child, width, height)
80
+ }
81
+
82
+ override fun updateViewLayout(view: View?, params: LayoutParams?) {
83
+ if (view === blurTargetView) {
84
+ super.updateViewLayout(view, toHostLayoutParams(params))
85
+ return
86
+ }
87
+ blurTargetView.updateViewLayout(view, params)
88
+ }
89
+
90
+ override fun removeView(view: View?) {
91
+ if (view === blurTargetView) {
92
+ super.removeView(view)
93
+ return
94
+ }
95
+ blurTargetView.removeView(view)
96
+ }
97
+
98
+ override fun removeViewAt(index: Int) = blurTargetView.removeViewAt(index)
99
+ override fun removeViews(start: Int, count: Int) = blurTargetView.removeViews(start, count)
100
+ override fun removeViewsInLayout(start: Int, count: Int) = blurTargetView.removeViewsInLayout(start, count)
101
+ override fun removeAllViews() = blurTargetView.removeAllViews()
102
+ override fun removeAllViewsInLayout() = blurTargetView.removeAllViewsInLayout()
103
+ override fun getChildCount(): Int = blurTargetView.childCount
104
+ override fun getChildAt(index: Int): View? = blurTargetView.getChildAt(index)
105
+ override fun indexOfChild(child: View?): Int = blurTargetView.indexOfChild(child)
106
+
107
+ // endregion
108
+
109
+ // region Layout
110
+
111
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
112
+ val width = MeasureSpec.getSize(widthMeasureSpec)
113
+ val height = MeasureSpec.getSize(heightMeasureSpec)
114
+ setMeasuredDimension(width, height)
115
+ blurTargetView.measure(
116
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
117
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
118
+ )
119
+ }
120
+
121
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
122
+ blurTargetView.layout(0, 0, right - left, bottom - top)
123
+ }
124
+
125
+ // endregion
126
+
127
+ private fun toHostLayoutParams(params: LayoutParams?): LayoutParams = when (params) {
128
+ null -> LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
129
+ is LayoutParams -> params
130
+ else -> LayoutParams(params)
131
+ }
132
+ }
133
+
134
+ /**
135
+ * A BlurTarget compatible with React Native's layout system.
136
+ * Overrides requestLayout and onLayout to avoid conflicts with React Native's UIManager,
137
+ * which handles all layout operations for RN-managed views.
138
+ */
139
+ class ReactCompatibleBlurTarget(context: ThemedReactContext) : BlurTarget(context) {
140
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
141
+ // No-op since UIManager handles actually laying out children.
142
+ }
143
+
144
+ @SuppressLint("MissingSuperCall")
145
+ override fun requestLayout() {
146
+ // No-op, terminate requestLayout here, UIManager handles laying out children and
147
+ // layout is called on all RN-managed views by NativeViewHierarchyManager
148
+ }
149
+ }
@@ -0,0 +1,47 @@
1
+ package com.margelo.nitro.nitroblur
2
+
3
+ import android.view.ViewGroup
4
+ import com.facebook.react.uimanager.ReactStylesDiffMap
5
+ import com.facebook.react.uimanager.StateWrapper
6
+ import com.facebook.react.uimanager.ThemedReactContext
7
+ import com.facebook.react.uimanager.ViewGroupManager
8
+ import com.margelo.nitro.R.id.associated_hybrid_view_tag
9
+
10
+ /**
11
+ * Custom ViewGroupManager for NitroBlurTarget.
12
+ *
13
+ * The Nitrogen-generated HybridNitroBlurTargetManager extends SimpleViewManager,
14
+ * which does not support children. BlurTargetView must accept children so we need
15
+ * ViewGroupManager instead.
16
+ */
17
+ class NitroBlurTargetViewGroupManager : ViewGroupManager<BlurTargetContainer>() {
18
+ override fun getName(): String = "NitroBlurTarget"
19
+
20
+ override fun createViewInstance(reactContext: ThemedReactContext): BlurTargetContainer {
21
+ val hybridView = HybridNitroBlurTarget(reactContext)
22
+ val view = hybridView.view as BlurTargetContainer
23
+ view.setTag(associated_hybrid_view_tag, hybridView)
24
+ return view
25
+ }
26
+
27
+ override fun updateState(view: BlurTargetContainer, props: ReactStylesDiffMap, stateWrapper: StateWrapper): Any? {
28
+ val hybridView = getHybridView(view)
29
+ ?: throw Error("Couldn't find view $view in local views table!")
30
+
31
+ hybridView.beforeUpdate()
32
+ com.margelo.nitro.nitroblur.views.HybridNitroBlurTargetStateUpdater.updateViewProps(hybridView, stateWrapper)
33
+ hybridView.afterUpdate()
34
+
35
+ return super.updateState(view, props, stateWrapper)
36
+ }
37
+
38
+ override fun onDropViewInstance(view: BlurTargetContainer) {
39
+ val hybridView = getHybridView(view)
40
+ hybridView?.onDropView()
41
+ return super.onDropViewInstance(view)
42
+ }
43
+
44
+ private fun getHybridView(view: ViewGroup): HybridNitroBlurTarget? {
45
+ return view.getTag(associated_hybrid_view_tag) as? HybridNitroBlurTarget
46
+ }
47
+ }
@@ -0,0 +1,85 @@
1
+ package com.margelo.nitro.nitroblur
2
+
3
+ /**
4
+ * Extension function to convert BlurTint enum (generated by Nitrogen) to an overlay color int.
5
+ * Color values are based on Apple's iOS 14 Sketch Kit.
6
+ *
7
+ * Groups tint styles that share the same color base, then delegates to per-style
8
+ * color calculations for unique styles.
9
+ */
10
+ fun BlurTint.toOverlayColor(blurRadius: Double): Int {
11
+ return when (this) {
12
+ // Light group
13
+ BlurTint.EXTRALIGHT,
14
+ BlurTint.LIGHT,
15
+ BlurTint.SYSTEMMATERIALLIGHT,
16
+ BlurTint.SYSTEMULTRATHINMATERIALLIGHT,
17
+ BlurTint.SYSTEMTHICKMATERIALLIGHT -> BlurTint.LIGHT.toColorInt(blurRadius)
18
+
19
+ // Default group
20
+ BlurTint.PROMINENT,
21
+ BlurTint.DEFAULT,
22
+ BlurTint.SYSTEMMATERIAL -> BlurTint.DEFAULT.toColorInt(blurRadius)
23
+
24
+ // Dark group
25
+ BlurTint.DARK,
26
+ BlurTint.SYSTEMMATERIALDARK -> BlurTint.DARK.toColorInt(blurRadius)
27
+
28
+ // Each has unique color mapping
29
+ BlurTint.REGULAR,
30
+ BlurTint.SYSTEMULTRATHINMATERIAL,
31
+ BlurTint.SYSTEMTHICKMATERIAL,
32
+ BlurTint.SYSTEMCHROMEMATERIAL,
33
+ BlurTint.SYSTEMCHROMEMATERIALLIGHT,
34
+ BlurTint.SYSTEMTHICKMATERIALDARK,
35
+ BlurTint.SYSTEMTHINMATERIALLIGHT,
36
+ BlurTint.SYSTEMTHINMATERIALDARK,
37
+ BlurTint.SYSTEMULTRATHINMATERIALDARK,
38
+ BlurTint.SYSTEMCHROMEMATERIALDARK,
39
+ BlurTint.SYSTEMTHINMATERIAL -> this.toColorInt(blurRadius)
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Per-style ARGB color calculation.
45
+ * Color int represented by: a >> 24 + r >> 16 + g >> 8 + b
46
+ * From Apple iOS 14 Sketch Kit - https://developer.apple.com/design/resources/
47
+ */
48
+ private fun BlurTint.toColorInt(blurRadius: Double): Int {
49
+ val intensity = blurRadius / 100.0
50
+ return when (this) {
51
+ BlurTint.DARK ->
52
+ colorInt(25, 25, 25, intensity * 0.69)
53
+ BlurTint.LIGHT ->
54
+ colorInt(249, 249, 249, intensity * 0.78)
55
+ BlurTint.REGULAR ->
56
+ colorInt(179, 179, 179, intensity * 0.82)
57
+ BlurTint.SYSTEMTHINMATERIALLIGHT ->
58
+ colorInt(199, 199, 199, intensity * 0.78)
59
+ BlurTint.SYSTEMTHINMATERIAL ->
60
+ colorInt(199, 199, 199, intensity * 0.97)
61
+ BlurTint.SYSTEMCHROMEMATERIAL ->
62
+ colorInt(255, 255, 255, intensity * 0.75)
63
+ BlurTint.SYSTEMCHROMEMATERIALLIGHT ->
64
+ colorInt(255, 255, 255, intensity * 0.97)
65
+ BlurTint.SYSTEMULTRATHINMATERIAL ->
66
+ colorInt(191, 191, 191, intensity * 0.44)
67
+ BlurTint.SYSTEMTHICKMATERIAL ->
68
+ colorInt(153, 153, 153, intensity * 0.97)
69
+ BlurTint.SYSTEMTHICKMATERIALDARK ->
70
+ colorInt(37, 37, 37, intensity * 0.9)
71
+ BlurTint.SYSTEMTHINMATERIALDARK ->
72
+ colorInt(37, 37, 37, intensity * 0.7)
73
+ BlurTint.SYSTEMULTRATHINMATERIALDARK ->
74
+ colorInt(37, 37, 37, intensity * 0.55)
75
+ BlurTint.SYSTEMCHROMEMATERIALDARK ->
76
+ colorInt(0, 0, 0, intensity * 0.75)
77
+ else ->
78
+ colorInt(255, 255, 255, intensity * 0.44)
79
+ }
80
+ }
81
+
82
+ private fun colorInt(r: Int, g: Int, b: Int, alpha: Double): Int {
83
+ val a = (255 * alpha).toInt().coerceIn(0, 255)
84
+ return (a shl 24) or (r shl 16) or (g shl 8) or b
85
+ }
@@ -0,0 +1,173 @@
1
+ import UIKit
2
+
3
+ class HybridNitroBlur: HybridNitroBlurSpec {
4
+
5
+ // MARK: - View
6
+
7
+ private let containerView = UIView()
8
+ private let blurEffectView = BlurEffectView()
9
+
10
+ var view: UIView {
11
+ return containerView
12
+ }
13
+
14
+ // MARK: - Props
15
+
16
+ var tint: BlurTint = .default {
17
+ didSet {
18
+ blurEffectView.tint = tint.toUIBlurEffectStyle()
19
+ }
20
+ }
21
+
22
+ var intensity: Double = 50 {
23
+ didSet {
24
+ blurEffectView.intensity = intensity / 100.0
25
+ }
26
+ }
27
+
28
+ var blurReductionFactor: Double = 4 {
29
+ didSet {
30
+ // blurReductionFactor is Android-only, no-op on iOS
31
+ }
32
+ }
33
+
34
+ var blurTargetId: Double = 0 {
35
+ didSet {
36
+ // blurTargetId is Android-only, no-op on iOS
37
+ // iOS UIVisualEffectView naturally blurs whatever is behind it
38
+ }
39
+ }
40
+
41
+ var blurMethod: BlurMethod = .none {
42
+ didSet {
43
+ // blurMethod is Android-only, no-op on iOS
44
+ }
45
+ }
46
+
47
+ // MARK: - Init
48
+
49
+ override init() {
50
+ super.init()
51
+ containerView.clipsToBounds = true
52
+ blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
53
+ containerView.addSubview(blurEffectView)
54
+
55
+ // Apply defaults
56
+ blurEffectView.tint = tint.toUIBlurEffectStyle()
57
+ blurEffectView.intensity = intensity / 100.0
58
+ }
59
+ }
60
+
61
+ // MARK: - BlurEffectView
62
+
63
+ /**
64
+ * Based on https://gist.github.com/darrarski/29a2a4515508e385c90b3ffe6f975df7
65
+ */
66
+ final class BlurEffectView: UIVisualEffectView {
67
+ var intensity: Double = 0.5 {
68
+ didSet {
69
+ // Clamp between 0.01 and 1.0
70
+ intensity = max(0.01, min(1.0, intensity))
71
+ setNeedsDisplay()
72
+ }
73
+ }
74
+
75
+ var tint: UIBlurEffect.Style = .regular {
76
+ didSet {
77
+ visualEffect = UIBlurEffect(style: tint)
78
+ }
79
+ }
80
+
81
+ private var visualEffect: UIVisualEffect = UIBlurEffect(style: .regular) {
82
+ didSet {
83
+ setNeedsDisplay()
84
+ }
85
+ }
86
+ private var animator: UIViewPropertyAnimator?
87
+
88
+ init() {
89
+ super.init(effect: nil)
90
+ }
91
+
92
+ required init?(coder aDecoder: NSCoder) { nil }
93
+
94
+ deinit {
95
+ animator?.stopAnimation(true)
96
+ }
97
+
98
+ override func draw(_ rect: CGRect) {
99
+ super.draw(rect)
100
+
101
+ // BlurView intensity relies on running an animation and making it partially complete.
102
+ // This means there is a continually running animation, which makes Detox hang
103
+ // (it waits for the animation to finish indefinitely).
104
+ // Detect if Detox is running and use on/off behaviour instead.
105
+ if BlurEffectView.isDetoxPresent() {
106
+ effect = intensity > 0 ? visualEffect : nil
107
+ return
108
+ }
109
+
110
+ effect = nil
111
+ animator?.stopAnimation(true)
112
+ animator = UIViewPropertyAnimator(duration: 1, curve: .linear) { [unowned self] in
113
+ self.effect = visualEffect
114
+ }
115
+ animator?.fractionComplete = CGFloat(intensity)
116
+ }
117
+
118
+ private static func isDetoxPresent() -> Bool {
119
+ let args = ProcessInfo.processInfo.arguments
120
+ return args.contains("-detoxServer") && args.contains("-detoxSessionId")
121
+ }
122
+ }
123
+
124
+ // MARK: - BlurTint → UIBlurEffect.Style
125
+
126
+ extension BlurTint {
127
+ func toUIBlurEffectStyle() -> UIBlurEffect.Style {
128
+ switch self {
129
+ case .light:
130
+ return .light
131
+ case .dark:
132
+ return .dark
133
+ case .default:
134
+ return .regular
135
+ case .extralight:
136
+ return .extraLight
137
+ case .regular:
138
+ return .regular
139
+ case .prominent:
140
+ return .prominent
141
+ case .systemultrathinmaterial:
142
+ return .systemUltraThinMaterial
143
+ case .systemthinmaterial:
144
+ return .systemThinMaterial
145
+ case .systemmaterial:
146
+ return .systemMaterial
147
+ case .systemthickmaterial:
148
+ return .systemThickMaterial
149
+ case .systemchromematerial:
150
+ return .systemChromeMaterial
151
+ case .systemultrathinmateriallight:
152
+ return .systemUltraThinMaterialLight
153
+ case .systemthinmateriallight:
154
+ return .systemThinMaterialLight
155
+ case .systemmateriallight:
156
+ return .systemMaterialLight
157
+ case .systemthickmateriallight:
158
+ return .systemThickMaterialLight
159
+ case .systemchromemateriallight:
160
+ return .systemChromeMaterialLight
161
+ case .systemultrathinmaterialdark:
162
+ return .systemUltraThinMaterialDark
163
+ case .systemthinmaterialdark:
164
+ return .systemThinMaterialDark
165
+ case .systemmaterialdark:
166
+ return .systemMaterialDark
167
+ case .systemthickmaterialdark:
168
+ return .systemThickMaterialDark
169
+ case .systemchromematerialdark:
170
+ return .systemChromeMaterialDark
171
+ }
172
+ }
173
+ }
@@ -0,0 +1,5 @@
1
+ import UIKit
2
+
3
+ class HybridNitroBlurTarget: HybridNitroBlurTargetSpec {
4
+ var view: UIView = UIView()
5
+ }
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export {};
4
+ //# sourceMappingURL=NitroBlur.nitro.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["NitroBlur.nitro.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export {};
4
+ //# sourceMappingURL=NitroBlurTarget.nitro.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["NitroBlurTarget.nitro.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ 'use client';
3
+
4
+ import React from 'react';
5
+ import { findNodeHandle, Platform, StyleSheet, View } from 'react-native';
6
+ import { getHostComponent } from 'react-native-nitro-modules';
7
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
+ const NitroBlurConfig = require('../nitrogen/generated/shared/json/NitroBlurConfig.json');
9
+ const NitroBlurTargetConfig = require('../nitrogen/generated/shared/json/NitroBlurTargetConfig.json');
10
+ const NativeBlurView = getHostComponent('NitroBlur', () => NitroBlurConfig);
11
+ const NativeBlurTargetView = getHostComponent('NitroBlurTarget', () => NitroBlurTargetConfig);
12
+
13
+ // ----- BlurViewProps -----
14
+
15
+ // ----- BlurView -----
16
+
17
+ export class BlurView extends React.Component {
18
+ constructor(props) {
19
+ super(props);
20
+ this.state = {
21
+ blurTargetId: undefined
22
+ };
23
+ }
24
+ componentDidMount() {
25
+ this._updateBlurTargetId();
26
+ this._maybeWarnAboutBlurMethod();
27
+ if (this.props.experimentalBlurMethod != null) {
28
+ console.warn('The `experimentalBlurMethod` prop has been deprecated. Please use the `blurMethod` prop instead.');
29
+ }
30
+ }
31
+ componentDidUpdate(prevProps) {
32
+ if (prevProps.blurTarget?.current !== this.props.blurTarget?.current) {
33
+ this._updateBlurTargetId();
34
+ }
35
+ }
36
+ _maybeWarnAboutBlurMethod() {
37
+ const blurMethod = this._getBlurMethod();
38
+ if (Platform.OS === 'android' && (blurMethod === 'dimezisBlurView' || blurMethod === 'dimezisBlurViewSdk31Plus') && !this.props.blurTarget) {
39
+ // The fallback happens on the native side
40
+ console.warn(`You have selected the "${blurMethod}" blur method, but the \`blurTarget\` prop has not been configured. The blur view will fallback to "none" blur method to avoid errors.`);
41
+ }
42
+ }
43
+ _updateBlurTargetId = () => {
44
+ const blurTarget = this.props.blurTarget?.current;
45
+ const blurTargetId = blurTarget ? findNodeHandle(blurTarget) : undefined;
46
+ this.setState(() => ({
47
+ blurTargetId
48
+ }));
49
+ };
50
+ _getBlurMethod() {
51
+ const providedMethod = this.props.blurMethod ?? this.props.experimentalBlurMethod;
52
+ return providedMethod ?? 'none';
53
+ }
54
+ render() {
55
+ const {
56
+ tint = 'default',
57
+ intensity = 30,
58
+ blurReductionFactor = 4,
59
+ style,
60
+ children,
61
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
62
+ blurTarget,
63
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
64
+ blurMethod,
65
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
66
+ experimentalBlurMethod,
67
+ ...props
68
+ } = this.props;
69
+ return /*#__PURE__*/_jsxs(View, {
70
+ ...props,
71
+ style: [styles.container, style],
72
+ children: [/*#__PURE__*/_jsx(NativeBlurView, {
73
+ blurTargetId: this.state.blurTargetId ?? 0,
74
+ tint: tint,
75
+ intensity: intensity,
76
+ blurReductionFactor: blurReductionFactor,
77
+ blurMethod: this._getBlurMethod(),
78
+ style: StyleSheet.absoluteFill
79
+ }), children]
80
+ });
81
+ }
82
+ }
83
+ const styles = StyleSheet.create({
84
+ container: {
85
+ backgroundColor: 'transparent'
86
+ }
87
+ });
88
+
89
+ // ----- BlurTargetView -----
90
+
91
+ /**
92
+ * A container view that can be used as a blur target on Android.
93
+ * Wrap the content you want to blur with this view, then pass
94
+ * a ref to it via the `blurTarget` prop of `BlurView`.
95
+ *
96
+ * On iOS, this is just a regular View since UIVisualEffectView
97
+ * naturally blurs whatever is behind it.
98
+ */
99
+ export const BlurTargetView = /*#__PURE__*/React.forwardRef((props, ref) => {
100
+ if (Platform.OS === 'android') {
101
+ return /*#__PURE__*/_jsx(NativeBlurTargetView, {
102
+ ...props,
103
+ ref: ref
104
+ });
105
+ }
106
+ return /*#__PURE__*/_jsx(View, {
107
+ ...props,
108
+ ref: ref,
109
+ collapsable: false
110
+ });
111
+ });
112
+
113
+ // ----- Exports -----
114
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","findNodeHandle","Platform","StyleSheet","View","getHostComponent","jsx","_jsx","jsxs","_jsxs","NitroBlurConfig","require","NitroBlurTargetConfig","NativeBlurView","NativeBlurTargetView","BlurView","Component","constructor","props","state","blurTargetId","undefined","componentDidMount","_updateBlurTargetId","_maybeWarnAboutBlurMethod","experimentalBlurMethod","console","warn","componentDidUpdate","prevProps","blurTarget","current","blurMethod","_getBlurMethod","OS","setState","providedMethod","render","tint","intensity","blurReductionFactor","style","children","styles","container","absoluteFill","create","backgroundColor","BlurTargetView","forwardRef","ref","collapsable"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,25 @@
1
+ import type { HybridView, HybridViewMethods, HybridViewProps } from 'react-native-nitro-modules';
2
+ export type BlurTint = 'light' | 'dark' | 'default' | 'extraLight' | 'regular' | 'prominent' | 'systemUltraThinMaterial' | 'systemThinMaterial' | 'systemMaterial' | 'systemThickMaterial' | 'systemChromeMaterial' | 'systemUltraThinMaterialLight' | 'systemThinMaterialLight' | 'systemMaterialLight' | 'systemThickMaterialLight' | 'systemChromeMaterialLight' | 'systemUltraThinMaterialDark' | 'systemThinMaterialDark' | 'systemMaterialDark' | 'systemThickMaterialDark' | 'systemChromeMaterialDark';
3
+ /**
4
+ * Blur method to use on Android.
5
+ *
6
+ * - `'none'` - Renders a semi-transparent view instead of rendering a blur effect.
7
+ * - `'dimezisBlurView'` - Uses a native blur view implementation based on BlurView library.
8
+ * This method may lead to decreased performance on Android SDK 30 and below.
9
+ * - `'dimezisBlurViewSdk31Plus'` - Uses BlurView library on Android SDK 31 and above,
10
+ * for older versions falls back to 'none'.
11
+ *
12
+ * @platform android
13
+ */
14
+ export type BlurMethod = 'none' | 'dimezisBlurView' | 'dimezisBlurViewSdk31Plus';
15
+ export interface NitroBlurProps extends HybridViewProps {
16
+ tint: BlurTint;
17
+ intensity: number;
18
+ blurReductionFactor: number;
19
+ blurTargetId: number;
20
+ blurMethod: BlurMethod;
21
+ }
22
+ export interface NitroBlurMethods extends HybridViewMethods {
23
+ }
24
+ export type NitroBlur = HybridView<NitroBlurProps, NitroBlurMethods>;
25
+ //# sourceMappingURL=NitroBlur.nitro.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NitroBlur.nitro.d.ts","sourceRoot":"","sources":["../../../src/NitroBlur.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,MAAM,QAAQ,GAChB,OAAO,GACP,MAAM,GACN,SAAS,GACT,YAAY,GACZ,SAAS,GACT,WAAW,GACX,yBAAyB,GACzB,oBAAoB,GACpB,gBAAgB,GAChB,qBAAqB,GACrB,sBAAsB,GACtB,8BAA8B,GAC9B,yBAAyB,GACzB,qBAAqB,GACrB,0BAA0B,GAC1B,2BAA2B,GAC3B,6BAA6B,GAC7B,wBAAwB,GACxB,oBAAoB,GACpB,yBAAyB,GACzB,0BAA0B,CAAC;AAE/B;;;;;;;;;;GAUG;AACH,MAAM,MAAM,UAAU,GAClB,MAAM,GACN,iBAAiB,GACjB,0BAA0B,CAAC;AAE/B,MAAM,WAAW,cAAe,SAAQ,eAAe;IACrD,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;CAAG;AAE9D,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { HybridView, HybridViewMethods, HybridViewProps } from 'react-native-nitro-modules';
2
+ export interface NitroBlurTargetProps extends HybridViewProps {
3
+ }
4
+ export interface NitroBlurTargetMethods extends HybridViewMethods {
5
+ }
6
+ export type NitroBlurTarget = HybridView<NitroBlurTargetProps, NitroBlurTargetMethods>;
7
+ //# sourceMappingURL=NitroBlurTarget.nitro.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NitroBlurTarget.nitro.d.ts","sourceRoot":"","sources":["../../../src/NitroBlurTarget.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,WAAW,oBAAqB,SAAQ,eAAe;CAAG;AAChE,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;CAAG;AAEpE,MAAM,MAAM,eAAe,GAAG,UAAU,CACtC,oBAAoB,EACpB,sBAAsB,CACvB,CAAC"}