react-native-blur-vibe 0.1.1 → 0.1.2

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.
@@ -6,7 +6,9 @@ import com.facebook.react.bridge.ReactApplicationContext
6
6
  import com.facebook.react.uimanager.ViewManager
7
7
 
8
8
  class BlurVibePackage : ReactPackage {
9
- override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> = emptyList()
9
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> =
10
+ emptyList()
11
+
10
12
  override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> =
11
13
  listOf(BlurVibeViewManager())
12
14
  }
@@ -17,16 +17,19 @@ import android.view.ViewGroup
17
17
  import android.widget.FrameLayout
18
18
 
19
19
  /**
20
- * BlurVibeView — Android implementation
20
+ * BlurVibeView
21
21
  *
22
- * API 31+ : RenderEffect (hardware accelerated)
23
- * API 24-30: RenderScript (built-in SDK, no extra dep)
22
+ * Extends FrameLayout required because:
23
+ * 1. We host children (overlay view + React children)
24
+ * 2. ViewGroupManager (used in manager) requires a ViewGroup subclass
25
+ * 3. SimpleViewManager cast to IViewGroupManager would crash
24
26
  *
25
- * Color props (overlayColor, reducedTransparencyFallbackColor) are
26
- * received as hex strings from JS and parsed manually here.
27
- * This gives full control over alpha channel handling.
27
+ * Blur strategy:
28
+ * API 31+ → RenderEffect (hardware accelerated, no bitmap)
29
+ * API 24-30 RenderScript (bitmap-based, built into Android SDK)
28
30
  *
29
- * Supports: "#RGB" "#RRGGBB" "#RRGGBBAA" "transparent"
31
+ * Color props received as hex strings from JS, parsed manually.
32
+ * Supports: "transparent", "#RGB", "#RRGGBB", "#RRGGBBAA"
30
33
  */
31
34
  @SuppressLint("NewApi")
32
35
  class BlurVibeView(context: Context) : FrameLayout(context) {
@@ -38,33 +41,58 @@ class BlurVibeView(context: Context) : FrameLayout(context) {
38
41
  private var blurRadiusDownscale: Int = 4
39
42
 
40
43
  init {
41
- setWillNotDraw(false)
42
- overlayView.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
44
+ // overlayView fills entire frame, sits above blur, below React children
45
+ overlayView.layoutParams = LayoutParams(
46
+ LayoutParams.MATCH_PARENT,
47
+ LayoutParams.MATCH_PARENT
48
+ )
43
49
  overlayView.isClickable = false
44
50
  overlayView.isFocusable = false
45
- addView(overlayView)
46
- applyBlur()
51
+ // Add overlay as first child — React children added later will be on top
52
+ super.addView(overlayView, 0)
47
53
  }
48
54
 
49
- // MARK: - Public setters (called by ViewManager)
55
+ // MARK: - React child management
56
+ // Must override to ensure React children go ABOVE our overlay view
57
+
58
+ override fun addView(child: View, index: Int) {
59
+ if (child === overlayView) {
60
+ super.addView(child, index)
61
+ return
62
+ }
63
+ // React children always go on top of overlay
64
+ super.addView(child, childCount)
65
+ }
66
+
67
+ override fun addView(child: View) {
68
+ if (child === overlayView) {
69
+ super.addView(child)
70
+ return
71
+ }
72
+ super.addView(child, childCount)
73
+ }
74
+
75
+ // MARK: - Setters (called by BlurVibeViewManager)
50
76
 
51
77
  fun setBlurAmount(amount: Float) {
52
78
  blurAmountValue = amount.coerceIn(0f, 100f)
53
79
  applyBlur()
54
80
  }
55
81
 
56
- fun setOverlayColor(colorString: String) {
57
- overlayColorValue = parseHexColor(colorString) ?: Color.TRANSPARENT
58
- updateOverlay()
82
+ fun setOverlayColor(colorString: String?) {
83
+ overlayColorValue = parseHexColor(colorString ?: "transparent") ?: Color.TRANSPARENT
84
+ overlayView.setBackgroundColor(overlayColorValue)
59
85
  }
60
86
 
61
- fun setReducedTransparencyFallbackColor(colorString: String) {
62
- fallbackColorValue = parseHexColor(colorString) ?: Color.parseColor("#F2F2F2")
87
+ fun setReducedTransparencyFallbackColor(colorString: String?) {
88
+ fallbackColorValue = parseHexColor(colorString ?: "#F2F2F2") ?: Color.parseColor("#F2F2F2")
63
89
  }
64
90
 
65
91
  fun setBlurRadius(radius: Int) {
66
92
  blurRadiusDownscale = radius.coerceIn(1, 8)
67
- applyBlur()
93
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
94
+ post { renderScriptBlur() }
95
+ }
68
96
  }
69
97
 
70
98
  // MARK: - Blur
@@ -75,7 +103,6 @@ class BlurVibeView(context: Context) : FrameLayout(context) {
75
103
  } else {
76
104
  post { renderScriptBlur() }
77
105
  }
78
- updateOverlay()
79
106
  }
80
107
 
81
108
  private fun applyRenderEffect() {
@@ -117,17 +144,6 @@ class BlurVibeView(context: Context) : FrameLayout(context) {
117
144
  }
118
145
  }
119
146
 
120
- // MARK: - Overlay
121
-
122
- private fun updateOverlay() {
123
- overlayView.setBackgroundColor(overlayColorValue)
124
- bringChildToFront(overlayView)
125
- for (i in 0 until childCount) {
126
- val child = getChildAt(i)
127
- if (child !== overlayView) bringChildToFront(child)
128
- }
129
- }
130
-
131
147
  override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
132
148
  super.onLayout(changed, l, t, r, b)
133
149
  if (changed && Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
@@ -135,36 +151,33 @@ class BlurVibeView(context: Context) : FrameLayout(context) {
135
151
  }
136
152
  }
137
153
 
138
- // MARK: - Color parser
154
+ // MARK: - Hex color parser
139
155
  // Supports: "transparent", "#RGB", "#RRGGBB", "#RRGGBBAA"
140
- // Returns null if unparseable (caller uses fallback)
141
156
  private fun parseHexColor(colorString: String): Int? {
142
157
  val s = colorString.trim()
143
158
  if (s.equals("transparent", ignoreCase = true)) return Color.TRANSPARENT
144
159
  if (!s.startsWith("#")) return null
145
-
146
160
  val hex = s.removePrefix("#")
147
161
  return try {
148
162
  when (hex.length) {
149
- 3 -> { // #RGB → #RRGGBB
150
- val r = hex[0].toString().repeat(2).toInt(16)
151
- val g = hex[1].toString().repeat(2).toInt(16)
152
- val b = hex[2].toString().repeat(2).toInt(16)
153
- Color.argb(255, r, g, b)
154
- }
155
- 6 -> { // #RRGGBB
156
- val r = hex.substring(0, 2).toInt(16)
157
- val g = hex.substring(2, 4).toInt(16)
158
- val b = hex.substring(4, 6).toInt(16)
159
- Color.argb(255, r, g, b)
160
- }
161
- 8 -> { // #RRGGBBAA — note: AA is alpha, last two digits
162
- val r = hex.substring(0, 2).toInt(16)
163
- val g = hex.substring(2, 4).toInt(16)
164
- val b = hex.substring(4, 6).toInt(16)
165
- val a = hex.substring(6, 8).toInt(16)
166
- Color.argb(a, r, g, b)
167
- }
163
+ 3 -> Color.argb(
164
+ 255,
165
+ hex[0].toString().repeat(2).toInt(16),
166
+ hex[1].toString().repeat(2).toInt(16),
167
+ hex[2].toString().repeat(2).toInt(16)
168
+ )
169
+ 6 -> Color.argb(
170
+ 255,
171
+ hex.substring(0, 2).toInt(16),
172
+ hex.substring(2, 4).toInt(16),
173
+ hex.substring(4, 6).toInt(16)
174
+ )
175
+ 8 -> Color.argb(
176
+ hex.substring(6, 8).toInt(16), // alpha last in #RRGGBBAA
177
+ hex.substring(0, 2).toInt(16),
178
+ hex.substring(2, 4).toInt(16),
179
+ hex.substring(4, 6).toInt(16)
180
+ )
168
181
  else -> null
169
182
  }
170
183
  } catch (e: NumberFormatException) {
@@ -1,42 +1,49 @@
1
1
  package com.blurvibe
2
2
 
3
- import com.facebook.react.uimanager.SimpleViewManager
4
3
  import com.facebook.react.uimanager.ThemedReactContext
4
+ import com.facebook.react.uimanager.ViewGroupManager
5
5
  import com.facebook.react.uimanager.annotations.ReactProp
6
6
 
7
- class BlurVibeViewManager : SimpleViewManager<BlurVibeView>() {
7
+ /**
8
+ * BlurVibeViewManager
9
+ *
10
+ * Extends ViewGroupManager — NOT SimpleViewManager.
11
+ * Reason: BlurVibeView hosts children (overlay + React children).
12
+ * SimpleViewManager cast to IViewGroupManager crashes at runtime.
13
+ * ViewGroupManager correctly implements IViewGroupManager interface.
14
+ */
15
+ class BlurVibeViewManager : ViewGroupManager<BlurVibeView>() {
8
16
 
9
17
  override fun getName() = "BlurVibeView"
10
18
 
11
19
  override fun createViewInstance(context: ThemedReactContext) = BlurVibeView(context)
12
20
 
13
- // Float — matches TS codegen Float type ✅
21
+ // Float — matches TS NativeComponent Float
14
22
  @ReactProp(name = "blurAmount", defaultFloat = 10f)
15
23
  fun setBlurAmount(view: BlurVibeView, amount: Float) {
16
24
  view.setBlurAmount(amount)
17
25
  }
18
26
 
19
- // String — matches TS codegen string type ✅ (no-op on Android)
27
+ // String — matches TS NativeComponent string (no-op on Android)
20
28
  @ReactProp(name = "blurType")
21
29
  fun setBlurType(view: BlurVibeView, type: String?) {
22
- // No-op on Android — blurType is iOS UIBlurEffectStyle only
30
+ // No-op — blurType maps to iOS UIBlurEffectStyle only
23
31
  }
24
32
 
25
- // String — matches TS codegen string type ✅
26
- // We parse hex manually in BlurVibeView for full alpha control
27
- // Do NOT use Int with customType="Color" — RN reorders alpha bytes unexpectedly
33
+ // String — matches TS NativeComponent string
34
+ // Parsed as hex in BlurVibeView no customType="Color" needed
28
35
  @ReactProp(name = "overlayColor")
29
36
  fun setOverlayColor(view: BlurVibeView, color: String?) {
30
- view.setOverlayColor(color ?: "transparent")
37
+ view.setOverlayColor(color)
31
38
  }
32
39
 
33
- // String — matches TS codegen string type ✅
40
+ // String — matches TS NativeComponent string
34
41
  @ReactProp(name = "reducedTransparencyFallbackColor")
35
42
  fun setReducedTransparencyFallbackColor(view: BlurVibeView, color: String?) {
36
- view.setReducedTransparencyFallbackColor(color ?: "#F2F2F2")
43
+ view.setReducedTransparencyFallbackColor(color)
37
44
  }
38
45
 
39
- // Int32 — matches TS codegen Int32 type ✅
46
+ // Int — matches TS NativeComponent Int32
40
47
  @ReactProp(name = "blurRadius", defaultInt = 4)
41
48
  fun setBlurRadius(view: BlurVibeView, radius: Int) {
42
49
  view.setBlurRadius(radius)
@@ -3,8 +3,17 @@
3
3
 
4
4
  RCT_EXTERN_MODULE(BlurVibeViewManager, RCTViewManager)
5
5
 
6
+ // Float → NSNumber matches TS Float
6
7
  RCT_EXPORT_VIEW_PROPERTY(blurAmount, NSNumber)
8
+
9
+ // String → NSString matches TS string
7
10
  RCT_EXPORT_VIEW_PROPERTY(blurType, NSString)
11
+
12
+ // String → NSString matches TS string
8
13
  RCT_EXPORT_VIEW_PROPERTY(overlayColor, NSString)
14
+
15
+ // String → NSString matches TS string
9
16
  RCT_EXPORT_VIEW_PROPERTY(reducedTransparencyFallbackColor, NSString)
17
+
18
+ // Int32 → NSNumber matches TS Int32 (no-op in Swift)
10
19
  RCT_EXPORT_VIEW_PROPERTY(blurRadius, NSNumber)
@@ -1,5 +1,11 @@
1
1
  import Foundation
2
2
 
3
+ /**
4
+ * BlurVibeViewManager
5
+ *
6
+ * RCTViewManager subclass — registers BlurVibeView with React Native.
7
+ * requiresMainQueueSetup = true because we create UIKit views.
8
+ */
3
9
  @objc(BlurVibeViewManager)
4
10
  class BlurVibeViewManager: RCTViewManager {
5
11
 
@@ -10,8 +16,4 @@ class BlurVibeViewManager: RCTViewManager {
10
16
  override static func requiresMainQueueSetup() -> Bool {
11
17
  return true
12
18
  }
13
-
14
- @objc override func constantsToExport() -> [AnyHashable: Any]! {
15
- return [:]
16
- }
17
19
  }
@@ -1,14 +1,37 @@
1
- // @ts-ignore - codegenNativeComponent is available at runtime in RN 0.71+
1
+ // @ts-ignore - internal RN path, exists at runtime
2
2
  import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
3
3
  import type { HostComponent, ViewProps } from 'react-native';
4
- // @ts-ignore - CodegenTypes available at runtime
4
+ // @ts-ignore - internal RN path, exists at runtime
5
5
  import type { Float, Int32 } from 'react-native/Libraries/Types/CodegenTypes';
6
6
 
7
+ /**
8
+ * NativeComponent codegen spec for BlurVibeView.
9
+ *
10
+ * Type mapping (JS → Native):
11
+ * Float → NSNumber (iOS) / Float (Android)
12
+ * string → NSString (iOS) / String (Android)
13
+ * Int32 → NSNumber (iOS) / Int (Android)
14
+ *
15
+ * Color props (overlayColor, reducedTransparencyFallbackColor) use
16
+ * plain `string` — NOT the RN `ColorValue` type — because we parse
17
+ * hex manually on both platforms for full alpha channel control.
18
+ * Using ColorValue would trigger RN's color normalization which
19
+ * reorders alpha bytes and breaks #RRGGBBAA format.
20
+ */
7
21
  export interface NativeBlurVibeViewProps extends ViewProps {
22
+ // 0–100 blur intensity
8
23
  blurAmount?: Float;
24
+
25
+ // iOS UIBlurEffectStyle name — no-op on Android
9
26
  blurType?: string;
27
+
28
+ // Hex color string with alpha — "transparent", "#RGB", "#RRGGBB", "#RRGGBBAA"
10
29
  overlayColor?: string;
30
+
31
+ // Fallback when blur unavailable (Reduce Transparency / old API)
11
32
  reducedTransparencyFallbackColor?: string;
33
+
34
+ // Android downscale factor 1–8 — no-op on iOS
12
35
  blurRadius?: Int32;
13
36
  }
14
37
 
@@ -1,14 +1,37 @@
1
- // @ts-ignore - codegenNativeComponent is available at runtime in RN 0.71+
1
+ // @ts-ignore - internal RN path, exists at runtime
2
2
  import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
3
3
  import type { HostComponent, ViewProps } from 'react-native';
4
- // @ts-ignore - CodegenTypes available at runtime
4
+ // @ts-ignore - internal RN path, exists at runtime
5
5
  import type { Float, Int32 } from 'react-native/Libraries/Types/CodegenTypes';
6
6
 
7
+ /**
8
+ * NativeComponent codegen spec for BlurVibeView.
9
+ *
10
+ * Type mapping (JS → Native):
11
+ * Float → NSNumber (iOS) / Float (Android)
12
+ * string → NSString (iOS) / String (Android)
13
+ * Int32 → NSNumber (iOS) / Int (Android)
14
+ *
15
+ * Color props (overlayColor, reducedTransparencyFallbackColor) use
16
+ * plain `string` — NOT the RN `ColorValue` type — because we parse
17
+ * hex manually on both platforms for full alpha channel control.
18
+ * Using ColorValue would trigger RN's color normalization which
19
+ * reorders alpha bytes and breaks #RRGGBBAA format.
20
+ */
7
21
  export interface NativeBlurVibeViewProps extends ViewProps {
22
+ // 0–100 blur intensity
8
23
  blurAmount?: Float;
24
+
25
+ // iOS UIBlurEffectStyle name — no-op on Android
9
26
  blurType?: string;
27
+
28
+ // Hex color string with alpha — "transparent", "#RGB", "#RRGGBB", "#RRGGBBAA"
10
29
  overlayColor?: string;
30
+
31
+ // Fallback when blur unavailable (Reduce Transparency / old API)
11
32
  reducedTransparencyFallbackColor?: string;
33
+
34
+ // Android downscale factor 1–8 — no-op on iOS
12
35
  blurRadius?: Int32;
13
36
  }
14
37
 
@@ -1,5 +1,19 @@
1
1
  import type { HostComponent, ViewProps } from 'react-native';
2
2
  import type { Float, Int32 } from 'react-native/Libraries/Types/CodegenTypes';
3
+ /**
4
+ * NativeComponent codegen spec for BlurVibeView.
5
+ *
6
+ * Type mapping (JS → Native):
7
+ * Float → NSNumber (iOS) / Float (Android)
8
+ * string → NSString (iOS) / String (Android)
9
+ * Int32 → NSNumber (iOS) / Int (Android)
10
+ *
11
+ * Color props (overlayColor, reducedTransparencyFallbackColor) use
12
+ * plain `string` — NOT the RN `ColorValue` type — because we parse
13
+ * hex manually on both platforms for full alpha channel control.
14
+ * Using ColorValue would trigger RN's color normalization which
15
+ * reorders alpha bytes and breaks #RRGGBBAA format.
16
+ */
3
17
  export interface NativeBlurVibeViewProps extends ViewProps {
4
18
  blurAmount?: Float;
5
19
  blurType?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"BlurVibeViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/BlurVibeViewNativeComponent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE7D,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AAE9E,MAAM,WAAW,uBAAwB,SAAQ,SAAS;IACxD,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,UAAU,CAAC,EAAE,KAAK,CAAC;CACpB;wBAII,aAAa,CAAC,uBAAuB,CAAC;AAF3C,wBAE4C"}
1
+ {"version":3,"file":"BlurVibeViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/BlurVibeViewNativeComponent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE7D,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AAE9E;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,uBAAwB,SAAQ,SAAS;IAExD,UAAU,CAAC,EAAE,KAAK,CAAC;IAGnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAG1C,UAAU,CAAC,EAAE,KAAK,CAAC;CACpB;wBAII,aAAa,CAAC,uBAAuB,CAAC;AAF3C,wBAE4C"}
@@ -1,5 +1,19 @@
1
1
  import type { HostComponent, ViewProps } from 'react-native';
2
2
  import type { Float, Int32 } from 'react-native/Libraries/Types/CodegenTypes';
3
+ /**
4
+ * NativeComponent codegen spec for BlurVibeView.
5
+ *
6
+ * Type mapping (JS → Native):
7
+ * Float → NSNumber (iOS) / Float (Android)
8
+ * string → NSString (iOS) / String (Android)
9
+ * Int32 → NSNumber (iOS) / Int (Android)
10
+ *
11
+ * Color props (overlayColor, reducedTransparencyFallbackColor) use
12
+ * plain `string` — NOT the RN `ColorValue` type — because we parse
13
+ * hex manually on both platforms for full alpha channel control.
14
+ * Using ColorValue would trigger RN's color normalization which
15
+ * reorders alpha bytes and breaks #RRGGBBAA format.
16
+ */
3
17
  export interface NativeBlurVibeViewProps extends ViewProps {
4
18
  blurAmount?: Float;
5
19
  blurType?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"BlurVibeViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/BlurVibeViewNativeComponent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE7D,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AAE9E,MAAM,WAAW,uBAAwB,SAAQ,SAAS;IACxD,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,UAAU,CAAC,EAAE,KAAK,CAAC;CACpB;wBAII,aAAa,CAAC,uBAAuB,CAAC;AAF3C,wBAE4C"}
1
+ {"version":3,"file":"BlurVibeViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/BlurVibeViewNativeComponent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE7D,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AAE9E;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,uBAAwB,SAAQ,SAAS;IAExD,UAAU,CAAC,EAAE,KAAK,CAAC;IAGnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAG1C,UAAU,CAAC,EAAE,KAAK,CAAC;CACpB;wBAII,aAAa,CAAC,uBAAuB,CAAC;AAF3C,wBAE4C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-blur-vibe",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "React Native package implementing Blur View in iOS and Android",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/module/index.js",
@@ -1,14 +1,37 @@
1
- // @ts-ignore - codegenNativeComponent is available at runtime in RN 0.71+
1
+ // @ts-ignore - internal RN path, exists at runtime
2
2
  import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
3
3
  import type { HostComponent, ViewProps } from 'react-native';
4
- // @ts-ignore - CodegenTypes available at runtime
4
+ // @ts-ignore - internal RN path, exists at runtime
5
5
  import type { Float, Int32 } from 'react-native/Libraries/Types/CodegenTypes';
6
6
 
7
+ /**
8
+ * NativeComponent codegen spec for BlurVibeView.
9
+ *
10
+ * Type mapping (JS → Native):
11
+ * Float → NSNumber (iOS) / Float (Android)
12
+ * string → NSString (iOS) / String (Android)
13
+ * Int32 → NSNumber (iOS) / Int (Android)
14
+ *
15
+ * Color props (overlayColor, reducedTransparencyFallbackColor) use
16
+ * plain `string` — NOT the RN `ColorValue` type — because we parse
17
+ * hex manually on both platforms for full alpha channel control.
18
+ * Using ColorValue would trigger RN's color normalization which
19
+ * reorders alpha bytes and breaks #RRGGBBAA format.
20
+ */
7
21
  export interface NativeBlurVibeViewProps extends ViewProps {
22
+ // 0–100 blur intensity
8
23
  blurAmount?: Float;
24
+
25
+ // iOS UIBlurEffectStyle name — no-op on Android
9
26
  blurType?: string;
27
+
28
+ // Hex color string with alpha — "transparent", "#RGB", "#RRGGBB", "#RRGGBBAA"
10
29
  overlayColor?: string;
30
+
31
+ // Fallback when blur unavailable (Reduce Transparency / old API)
11
32
  reducedTransparencyFallbackColor?: string;
33
+
34
+ // Android downscale factor 1–8 — no-op on iOS
12
35
  blurRadius?: Int32;
13
36
  }
14
37