golia-expo-utils 1.0.0 → 1.0.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.
- package/android/build.gradle +6 -1
- package/android/src/main/java/expo/modules/goliaexpoutils/segmentedControl/ReactSegmentedControl.kt +62 -22
- package/android/src/main/java/expo/modules/goliaexpoutils/waterView/ReactWaterView.kt +52 -21
- package/build/ReactWaterView.d.ts +1 -1
- package/build/ReactWaterView.d.ts.map +1 -1
- package/build/ReactWaterView.js +1 -1
- package/build/ReactWaterView.js.map +1 -1
- package/package.json +29 -20
- package/src/ReactWaterView.tsx +1 -1
- package/bun.lock +0 -2368
package/android/build.gradle
CHANGED
|
@@ -57,10 +57,15 @@ android {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
dependencies {
|
|
60
|
-
def composeBom = platform('androidx.compose:compose-bom:
|
|
60
|
+
def composeBom = platform('androidx.compose:compose-bom:2026.01.00')
|
|
61
61
|
implementation composeBom
|
|
62
62
|
implementation 'androidx.compose.ui:ui'
|
|
63
63
|
implementation 'androidx.compose.ui:ui-tooling-preview'
|
|
64
64
|
implementation 'androidx.compose.material3:material3'
|
|
65
65
|
implementation 'io.github.kyant0:backdrop:1.0.0'
|
|
66
|
+
implementation "androidx.appcompat:appcompat:1.7.1"
|
|
67
|
+
implementation "androidx.activity:activity-ktx:1.12.2"
|
|
68
|
+
implementation "androidx.savedstate:savedstate-ktx:1.4.0"
|
|
69
|
+
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.10.0"
|
|
70
|
+
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0"
|
|
66
71
|
}
|
package/android/src/main/java/expo/modules/goliaexpoutils/segmentedControl/ReactSegmentedControl.kt
CHANGED
|
@@ -2,11 +2,18 @@ package expo.modules.goliaexpoutils.segmentedControl
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.content.Context
|
|
5
|
+
import android.content.ContextWrapper
|
|
6
|
+
import androidx.appcompat.app.AppCompatActivity
|
|
5
7
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
6
8
|
import androidx.compose.runtime.mutableIntStateOf
|
|
7
9
|
import androidx.compose.runtime.mutableStateOf
|
|
8
10
|
import androidx.compose.ui.Modifier
|
|
9
11
|
import androidx.compose.ui.platform.ComposeView
|
|
12
|
+
import androidx.compose.ui.platform.ViewCompositionStrategy
|
|
13
|
+
import androidx.lifecycle.findViewTreeLifecycleOwner
|
|
14
|
+
import androidx.lifecycle.setViewTreeLifecycleOwner
|
|
15
|
+
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
|
|
16
|
+
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
|
|
10
17
|
import expo.modules.goliaexpoutils.Config
|
|
11
18
|
import expo.modules.kotlin.AppContext
|
|
12
19
|
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
@@ -27,30 +34,12 @@ class ReactSegmentedControl(context: Context, appContext: AppContext) :
|
|
|
27
34
|
val hapticEnabledState = mutableStateOf(true)
|
|
28
35
|
val enabledState = mutableStateOf(true)
|
|
29
36
|
|
|
37
|
+
private var isContentSet = false
|
|
38
|
+
|
|
30
39
|
private val composeView = ComposeView(context).apply {
|
|
31
40
|
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
setContent {
|
|
36
|
-
SegmentedControl(
|
|
37
|
-
items = itemsState.value,
|
|
38
|
-
selectedIndex = selectedIndexState.intValue,
|
|
39
|
-
onValueChange = { index ->
|
|
40
|
-
selectedIndexState.intValue = index
|
|
41
|
-
val title = itemsState.value.getOrNull(index)?.title ?: ""
|
|
42
|
-
onValueChange(mapOf("value" to title, "index" to index))
|
|
43
|
-
},
|
|
44
|
-
modifier = Modifier.fillMaxSize(),
|
|
45
|
-
activeColor = activeColorState.value,
|
|
46
|
-
ctrlBackgroundColor = ctrlBgColorState.value,
|
|
47
|
-
textColor = textColorState.value,
|
|
48
|
-
autoWidth = autoWidthState.value,
|
|
49
|
-
hapticEnabled = hapticEnabledState.value,
|
|
50
|
-
enabled = enabledState.value,
|
|
51
|
-
glassExpansion = Config.Common.Glass.DEFAULT_EXPANSION,
|
|
52
|
-
)
|
|
53
|
-
}
|
|
41
|
+
// 确保 View 卸载时清理 Compose 资源
|
|
42
|
+
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnDetachedFromWindow)
|
|
54
43
|
}
|
|
55
44
|
|
|
56
45
|
init {
|
|
@@ -58,4 +47,55 @@ class ReactSegmentedControl(context: Context, appContext: AppContext) :
|
|
|
58
47
|
clipToPadding = false
|
|
59
48
|
addView(composeView)
|
|
60
49
|
}
|
|
50
|
+
|
|
51
|
+
override fun onAttachedToWindow() {
|
|
52
|
+
super.onAttachedToWindow()
|
|
53
|
+
|
|
54
|
+
// ✅ 核心修复:查找 Activity 并强行注入 Lifecycle
|
|
55
|
+
val activity = context.lookupActivity()
|
|
56
|
+
if (activity != null) {
|
|
57
|
+
if (composeView.findViewTreeLifecycleOwner() == null) {
|
|
58
|
+
composeView.setViewTreeLifecycleOwner(activity)
|
|
59
|
+
}
|
|
60
|
+
if (composeView.findViewTreeSavedStateRegistryOwner() == null) {
|
|
61
|
+
composeView.setViewTreeSavedStateRegistryOwner(activity)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!isContentSet) {
|
|
66
|
+
composeView.setContent {
|
|
67
|
+
SegmentedControl(
|
|
68
|
+
items = itemsState.value,
|
|
69
|
+
selectedIndex = selectedIndexState.intValue,
|
|
70
|
+
onValueChange = { index ->
|
|
71
|
+
selectedIndexState.intValue = index
|
|
72
|
+
val title = itemsState.value.getOrNull(index)?.title ?: ""
|
|
73
|
+
onValueChange(mapOf("value" to title, "index" to index))
|
|
74
|
+
},
|
|
75
|
+
modifier = Modifier.fillMaxSize(),
|
|
76
|
+
activeColor = activeColorState.value,
|
|
77
|
+
ctrlBackgroundColor = ctrlBgColorState.value,
|
|
78
|
+
textColor = textColorState.value,
|
|
79
|
+
autoWidth = autoWidthState.value,
|
|
80
|
+
hapticEnabled = hapticEnabledState.value,
|
|
81
|
+
enabled = enabledState.value,
|
|
82
|
+
glassExpansion = Config.Common.Glass.DEFAULT_EXPANSION,
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
isContentSet = true
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ✅ 辅助扩展函数:从 ContextWrapper 中剥离出 Activity
|
|
91
|
+
// (虽然代码重复了,但这样解耦,避免跨包依赖问题)
|
|
92
|
+
private fun Context.lookupActivity(): AppCompatActivity? {
|
|
93
|
+
var ctx = this
|
|
94
|
+
while (ctx is ContextWrapper) {
|
|
95
|
+
if (ctx is AppCompatActivity) {
|
|
96
|
+
return ctx
|
|
97
|
+
}
|
|
98
|
+
ctx = ctx.baseContext
|
|
99
|
+
}
|
|
100
|
+
return null
|
|
61
101
|
}
|
|
@@ -2,9 +2,11 @@ package expo.modules.goliaexpoutils.waterView
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.content.Context
|
|
5
|
+
import android.content.ContextWrapper
|
|
5
6
|
import android.view.View
|
|
6
7
|
import android.view.ViewGroup
|
|
7
8
|
import android.widget.FrameLayout
|
|
9
|
+
import androidx.appcompat.app.AppCompatActivity
|
|
8
10
|
import androidx.compose.foundation.layout.Box
|
|
9
11
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
10
12
|
import androidx.compose.runtime.Composable
|
|
@@ -17,6 +19,10 @@ import androidx.compose.ui.platform.ViewCompositionStrategy
|
|
|
17
19
|
import androidx.compose.ui.unit.dp
|
|
18
20
|
import androidx.compose.ui.viewinterop.AndroidView
|
|
19
21
|
import androidx.core.view.isNotEmpty
|
|
22
|
+
import androidx.lifecycle.findViewTreeLifecycleOwner
|
|
23
|
+
import androidx.lifecycle.setViewTreeLifecycleOwner
|
|
24
|
+
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
|
|
25
|
+
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
|
|
20
26
|
import com.kyant.backdrop.backdrops.layerBackdrop
|
|
21
27
|
import com.kyant.backdrop.backdrops.rememberLayerBackdrop
|
|
22
28
|
import expo.modules.goliaexpoutils.Config
|
|
@@ -53,29 +59,14 @@ class ReactWaterView(context: Context, appContext: AppContext) : ExpoView(contex
|
|
|
53
59
|
private val onPressOut by EventDispatcher()
|
|
54
60
|
private val commandChannel = Channel<WaterCommand>(Channel.BUFFERED)
|
|
55
61
|
private val childContainer = FrameLayout(context).apply {
|
|
56
|
-
layoutParams = ViewGroup.LayoutParams(
|
|
57
|
-
LayoutParams.MATCH_PARENT,
|
|
58
|
-
LayoutParams.MATCH_PARENT
|
|
59
|
-
)
|
|
62
|
+
layoutParams = ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
60
63
|
}
|
|
64
|
+
|
|
65
|
+
private var isContentSet = false
|
|
66
|
+
|
|
61
67
|
private val composeView = ComposeView(context).apply {
|
|
62
|
-
layoutParams = ViewGroup.LayoutParams(
|
|
63
|
-
|
|
64
|
-
LayoutParams.MATCH_PARENT
|
|
65
|
-
)
|
|
66
|
-
clipChildren = false
|
|
67
|
-
clipToPadding = false
|
|
68
|
-
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnDetachedFromWindowOrReleasedFromPool)
|
|
69
|
-
setContent {
|
|
70
|
-
WaterViewEntry(
|
|
71
|
-
childContainer = childContainer,
|
|
72
|
-
props = props,
|
|
73
|
-
commandFlow = commandChannel.receiveAsFlow(),
|
|
74
|
-
onMoveDispatch = { x, y -> onMove(mapOf("x" to x, "y" to y)) },
|
|
75
|
-
onPressInDispatch = { onPressIn(mapOf()) },
|
|
76
|
-
onPressOutDispatch = { onPressOut(mapOf()) }
|
|
77
|
-
)
|
|
78
|
-
}
|
|
68
|
+
layoutParams = ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
69
|
+
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnDetachedFromWindow)
|
|
79
70
|
}
|
|
80
71
|
|
|
81
72
|
init {
|
|
@@ -84,6 +75,34 @@ class ReactWaterView(context: Context, appContext: AppContext) : ExpoView(contex
|
|
|
84
75
|
addView(composeView)
|
|
85
76
|
}
|
|
86
77
|
|
|
78
|
+
override fun onAttachedToWindow() {
|
|
79
|
+
super.onAttachedToWindow()
|
|
80
|
+
|
|
81
|
+
val activity = context.lookupActivity()
|
|
82
|
+
if (activity != null) {
|
|
83
|
+
if (composeView.findViewTreeLifecycleOwner() == null) {
|
|
84
|
+
composeView.setViewTreeLifecycleOwner(activity)
|
|
85
|
+
}
|
|
86
|
+
if (composeView.findViewTreeSavedStateRegistryOwner() == null) {
|
|
87
|
+
composeView.setViewTreeSavedStateRegistryOwner(activity)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!isContentSet) {
|
|
92
|
+
composeView.setContent {
|
|
93
|
+
WaterViewEntry(
|
|
94
|
+
childContainer = childContainer,
|
|
95
|
+
props = props,
|
|
96
|
+
commandFlow = commandChannel.receiveAsFlow(),
|
|
97
|
+
onMoveDispatch = { x, y -> onMove(mapOf("x" to x, "y" to y)) },
|
|
98
|
+
onPressInDispatch = { onPressIn(mapOf()) },
|
|
99
|
+
onPressOutDispatch = { onPressOut(mapOf()) }
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
isContentSet = true
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
87
106
|
override fun addView(child: View?, index: Int) {
|
|
88
107
|
if (child == composeView) super.addView(child, index)
|
|
89
108
|
else childContainer.addView(child)
|
|
@@ -111,6 +130,18 @@ class ReactWaterView(context: Context, appContext: AppContext) : ExpoView(contex
|
|
|
111
130
|
}
|
|
112
131
|
}
|
|
113
132
|
|
|
133
|
+
// ✅ 辅助扩展函数:从 ContextWrapper 中剥离出 Activity
|
|
134
|
+
private fun Context.lookupActivity(): AppCompatActivity? {
|
|
135
|
+
var ctx = this
|
|
136
|
+
while (ctx is ContextWrapper) {
|
|
137
|
+
if (ctx is AppCompatActivity) {
|
|
138
|
+
return ctx
|
|
139
|
+
}
|
|
140
|
+
ctx = ctx.baseContext
|
|
141
|
+
}
|
|
142
|
+
return null
|
|
143
|
+
}
|
|
144
|
+
|
|
114
145
|
@Composable
|
|
115
146
|
private fun WaterViewEntry(
|
|
116
147
|
childContainer: FrameLayout,
|
|
@@ -53,7 +53,7 @@ declare const WaterViewEffect: React.ForwardRefExoticComponent<ViewProps & {
|
|
|
53
53
|
onPressIn?: (event: NativeSyntheticEvent<WaterViewEventData>) => void;
|
|
54
54
|
onPressOut?: (event: NativeSyntheticEvent<WaterViewEventData>) => void;
|
|
55
55
|
} & React.RefAttributes<WaterViewRef>>;
|
|
56
|
-
export declare const
|
|
56
|
+
export declare const ReactWaterView: React.FC<WaterViewProps> & {
|
|
57
57
|
Effect: typeof WaterViewEffect;
|
|
58
58
|
};
|
|
59
59
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactWaterView.d.ts","sourceRoot":"","sources":["../src/ReactWaterView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAmD,MAAM,OAAO,CAAA;AACvE,OAAO,EAAE,oBAAoB,EAAgC,SAAS,EAAE,MAAM,cAAc,CAAA;AAM5F,MAAM,MAAM,kBAAkB,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AACzD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAA;AAE5C,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAClE,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACrE,CAAA;AAGD,KAAK,WAAW,GAAG,SAAS,GAAG;IAC7B,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACxC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAA;IAClE,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAA;IACrE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAA;CACvE,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,WAAW,CAAA;AAE9C,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAAA;AAOvE,QAAA,MAAM,eAAe;WA1BZ;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;cAC9B,MAAM;uBACG,OAAO;mBACX,YAAY;aAClB,OAAO;aACP,OAAO;WACT,MAAM;WACN,MAAM;WACN,MAAM;WACN,MAAM;qBACI,MAAM;qBACN,MAAM;aACd,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI;gBACtD,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI;iBACxD,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI;sCA6BvE,CAAA;AAqDD,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"ReactWaterView.d.ts","sourceRoot":"","sources":["../src/ReactWaterView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAmD,MAAM,OAAO,CAAA;AACvE,OAAO,EAAE,oBAAoB,EAAgC,SAAS,EAAE,MAAM,cAAc,CAAA;AAM5F,MAAM,MAAM,kBAAkB,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AACzD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAA;AAE5C,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAClE,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACrE,CAAA;AAGD,KAAK,WAAW,GAAG,SAAS,GAAG;IAC7B,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACxC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAA;IAClE,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAA;IACrE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAA;CACvE,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,WAAW,CAAA;AAE9C,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAAA;AAOvE,QAAA,MAAM,eAAe;WA1BZ;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;cAC9B,MAAM;uBACG,OAAO;mBACX,YAAY;aAClB,OAAO;aACP,OAAO;WACT,MAAM;WACN,MAAM;WACN,MAAM;WACN,MAAM;qBACI,MAAM;qBACN,MAAM;aACd,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI;gBACtD,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI;iBACxD,CAAC,KAAK,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,IAAI;sCA6BvE,CAAA;AAqDD,eAAO,MAAM,cAAc,EAAoB,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG;IACxE,MAAM,EAAE,OAAO,eAAe,CAAA;CAC/B,CAAA"}
|
package/build/ReactWaterView.js
CHANGED
|
@@ -47,5 +47,5 @@ const WaterViewRoot = ({ children, style, ...props }) => {
|
|
|
47
47
|
WaterViewRoot.displayName = 'WaterView';
|
|
48
48
|
WaterViewRoot.Effect = WaterViewEffect;
|
|
49
49
|
// 导出
|
|
50
|
-
export const
|
|
50
|
+
export const ReactWaterView = WaterViewRoot;
|
|
51
51
|
//# sourceMappingURL=ReactWaterView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactWaterView.js","sourceRoot":"","sources":["../src/ReactWaterView.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ReactWaterView.js","sourceRoot":"","sources":["../src/ReactWaterView.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeViewManager } from 'expo-modules-core'\nimport React, { isValidElement, cloneElement, forwardRef } from 'react'\nimport { NativeSyntheticEvent, Platform, processColor, View, ViewProps } from 'react-native'\n\n// =============================================================================\n// 1. 类型定义\n// =============================================================================\n\nexport type WaterViewEventData = { x: number; y: number }\nexport type RestrictMode = 'edge' | 'center'\n\nexport type WaterViewRef = {\n moveTo: (x: number, y: number, duration?: number) => Promise<void>\n moveBy: (dx: number, dy: number, duration?: number) => Promise<void>\n}\n\n// Native Props\ntype NativeProps = ViewProps & {\n size?: { width: number; height: number }\n bgColor?: string\n shouldSpringBack?: boolean\n restrictMode?: RestrictMode\n allowX?: boolean\n allowY?: boolean\n minX?: number\n maxX?: number\n minY?: number\n maxY?: number\n initialOffsetX?: number\n initialOffsetY?: number\n onMove?: (event: NativeSyntheticEvent<WaterViewEventData>) => void\n onPressIn?: (event: NativeSyntheticEvent<WaterViewEventData>) => void\n onPressOut?: (event: NativeSyntheticEvent<WaterViewEventData>) => void\n}\n\nexport type WaterViewEffectProps = NativeProps\n\nexport type WaterViewProps = ViewProps & { children?: React.ReactNode }\n\nconst NativeComponent = requireNativeViewManager('WaterViewModule', 'ReactWaterView')\n\n// =============================================================================\n// 2. 子组件: WaterView.Effect\n// =============================================================================\nconst WaterViewEffect = forwardRef<WaterViewRef, WaterViewEffectProps>(\n ({ bgColor, children, ...props }, ref) => {\n const nativeRef = React.useRef<any>(null)\n\n React.useImperativeHandle(ref, () => ({\n moveBy: async (dx, dy, duration) => nativeRef.current?.moveBy(dx, dy, duration),\n moveTo: async (x, y, duration) => nativeRef.current?.moveTo(x, y, duration),\n }))\n\n const nativeProps = { ...props, bgColor: processColor(bgColor), collapsable: false }\n\n return (\n <NativeComponent ref={nativeRef} {...nativeProps} collapsable={false}>\n {children}\n </NativeComponent>\n )\n }\n)\nWaterViewEffect.displayName = 'WaterView.Effect'\n\n// =============================================================================\n// 3. 父组件: WaterView (容器)\n// =============================================================================\n\nconst WaterViewRoot = ({ children, style, ...props }: WaterViewProps) => {\n // [修复]: 使用 React.Children.toArray + find,而不是 forEach 回调\n // 这样 TypeScript 可以正确推断 effectNode 不为 null/never\n const childrenArray = React.Children.toArray(children)\n\n const effectNode = childrenArray.find(\n (child): child is React.ReactElement<WaterViewEffectProps> =>\n isValidElement(child) && child.type === WaterViewEffect\n )\n\n const contentChildren = childrenArray.filter((child) => child !== effectNode)\n\n if (!effectNode) {\n console.warn('<WaterView> requires a <WaterView.Effect> child to work correctly.')\n return (\n <View style={style} {...props} collapsable={false}>\n {contentChildren}\n </View>\n )\n }\n\n // Android 渲染逻辑\n if (Platform.OS === 'android') {\n return cloneElement(\n effectNode,\n { ...effectNode.props },\n <View style={style} {...props} collapsable={false}>\n {contentChildren}\n </View>\n )\n }\n\n // iOS 渲染逻辑\n return (\n <View style={style} {...props} collapsable={false}>\n {contentChildren}\n {cloneElement(effectNode, { style: effectNode.props.style })}\n </View>\n )\n}\n\n// 挂载静态属性\n;(WaterViewRoot as any).displayName = 'WaterView'\n;(WaterViewRoot as any).Effect = WaterViewEffect\n\n// 导出\nexport const ReactWaterView = WaterViewRoot as React.FC<WaterViewProps> & {\n Effect: typeof WaterViewEffect\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "golia-expo-utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "expo utils provided by golia.jp",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"homepage": "https://expo.golia.jp/golia-expo-utils",
|
|
@@ -19,23 +19,32 @@
|
|
|
19
19
|
},
|
|
20
20
|
"keywords": ["react-native", "expo", "golia-expo-utils", "GoliaExpoUtils"],
|
|
21
21
|
"repository": "https://github.com/goliajp/golia-expo-utils",
|
|
22
|
-
"bugs": {
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/goliajp/golia-expo-utils/issues"
|
|
24
|
+
},
|
|
25
|
+
"author": "doracawl <lihao@golia.jp> (doracawl)",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"fs-extra": "^11.3.3",
|
|
29
|
+
"svg2vectordrawable": "^2.9.1"
|
|
30
|
+
},
|
|
31
|
+
"app.plugin": "./plugin/build/index.js",
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/fs-extra": "^11.0.4",
|
|
34
|
+
"@types/node": "^25.0.3",
|
|
35
|
+
"@types/react": "~19.1.0",
|
|
36
|
+
"eslint-config-expo": "^10.0.0",
|
|
37
|
+
"eslint-plugin-perfectionist": "^5.3.1",
|
|
38
|
+
"eslint-plugin-react": "^7.37.5",
|
|
39
|
+
"eslint-plugin-unused-imports": "^4.3.0",
|
|
40
|
+
"expo": "^54.0.31",
|
|
41
|
+
"expo-module-scripts": "^5.0.8",
|
|
42
|
+
"prettier": "^3.7.4",
|
|
43
|
+
"react-native": "0.81.5"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"expo": "*",
|
|
47
|
+
"react": "*",
|
|
48
|
+
"react-native": "*"
|
|
49
|
+
}
|
|
41
50
|
}
|
package/src/ReactWaterView.tsx
CHANGED
|
@@ -112,6 +112,6 @@ const WaterViewRoot = ({ children, style, ...props }: WaterViewProps) => {
|
|
|
112
112
|
;(WaterViewRoot as any).Effect = WaterViewEffect
|
|
113
113
|
|
|
114
114
|
// 导出
|
|
115
|
-
export const
|
|
115
|
+
export const ReactWaterView = WaterViewRoot as React.FC<WaterViewProps> & {
|
|
116
116
|
Effect: typeof WaterViewEffect
|
|
117
117
|
}
|