react-native-screens 3.9.0 → 3.11.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.
- package/LICENSE +1 -1
- package/README.md +47 -7
- package/android/build.gradle +1 -2
- package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +71 -0
- package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +29 -0
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -1
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +35 -52
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +83 -34
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +38 -33
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +77 -42
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +25 -9
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +8 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +7 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +1 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +10 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +72 -11
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +107 -0
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +155 -0
- package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +67 -0
- package/android/src/main/res/anim/rns_default_enter_in.xml +18 -0
- package/android/src/main/res/anim/rns_default_enter_out.xml +19 -0
- package/android/src/main/res/anim/rns_default_exit_in.xml +17 -0
- package/android/src/main/res/anim/rns_default_exit_out.xml +18 -0
- package/android/src/main/res/anim/rns_fade_in.xml +7 -0
- package/android/src/main/res/anim/rns_fade_out.xml +7 -0
- package/android/src/main/res/anim/rns_no_animation_20.xml +6 -0
- package/createNativeStackNavigator/README.md +12 -0
- package/ios/RNSScreen.h +10 -0
- package/ios/RNSScreen.m +38 -0
- package/ios/RNSScreenContainer.m +5 -0
- package/ios/RNSScreenStack.m +29 -13
- package/ios/RNSScreenStackAnimator.m +45 -14
- package/ios/RNSScreenStackHeaderConfig.m +4 -1
- package/ios/RNSScreenWindowTraits.h +1 -0
- package/ios/RNSScreenWindowTraits.m +20 -0
- package/ios/UIViewController+RNScreens.m +10 -0
- package/lib/commonjs/index.js +17 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.native.js +66 -18
- package/lib/commonjs/index.native.js.map +1 -1
- package/lib/commonjs/native-stack/utils/useBackPressSubscription.js +67 -0
- package/lib/commonjs/native-stack/utils/useBackPressSubscription.js.map +1 -0
- package/lib/commonjs/native-stack/views/HeaderConfig.js +46 -4
- package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -1
- package/lib/commonjs/native-stack/views/NativeStackView.js +33 -4
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +60 -0
- package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedScreen.js +7 -79
- package/lib/commonjs/reanimated/ReanimatedScreen.js.map +1 -1
- package/lib/commonjs/reanimated/ReanimatedScreenProvider.js +61 -0
- package/lib/commonjs/reanimated/ReanimatedScreenProvider.js.map +1 -0
- package/lib/commonjs/reanimated/index.js +2 -2
- package/lib/commonjs/reanimated/index.js.map +1 -1
- package/lib/commonjs/utils.js +20 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.native.js +65 -19
- package/lib/module/index.native.js.map +1 -1
- package/lib/module/native-stack/utils/useBackPressSubscription.js +50 -0
- package/lib/module/native-stack/utils/useBackPressSubscription.js.map +1 -0
- package/lib/module/native-stack/views/HeaderConfig.js +46 -5
- package/lib/module/native-stack/views/HeaderConfig.js.map +1 -1
- package/lib/module/native-stack/views/NativeStackView.js +33 -4
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/module/reanimated/ReanimatedNativeStackScreen.js +40 -0
- package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
- package/lib/module/reanimated/ReanimatedScreen.js +6 -73
- package/lib/module/reanimated/ReanimatedScreen.js.map +1 -1
- package/lib/module/reanimated/ReanimatedScreenProvider.js +49 -0
- package/lib/module/reanimated/ReanimatedScreenProvider.js.map +1 -0
- package/lib/module/reanimated/index.js +1 -1
- package/lib/module/reanimated/index.js.map +1 -1
- package/lib/module/utils.js +8 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/native-stack/types.d.ts +34 -2
- package/lib/typescript/native-stack/utils/useBackPressSubscription.d.ts +16 -0
- package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +5 -0
- package/lib/typescript/reanimated/ReanimatedScreen.d.ts +5 -2
- package/lib/typescript/reanimated/ReanimatedScreenProvider.d.ts +2 -0
- package/lib/typescript/reanimated/index.d.ts +1 -1
- package/lib/typescript/types.d.ts +101 -1
- package/lib/typescript/utils.d.ts +2 -0
- package/native-stack/README.md +70 -8
- package/package.json +2 -1
- package/reanimated/package.json +6 -0
- package/src/index.native.tsx +94 -36
- package/src/index.tsx +4 -0
- package/src/native-stack/types.tsx +34 -2
- package/src/native-stack/utils/useBackPressSubscription.tsx +66 -0
- package/src/native-stack/views/HeaderConfig.tsx +46 -3
- package/src/native-stack/views/NativeStackView.tsx +33 -4
- package/src/reanimated/ReanimatedNativeStackScreen.tsx +61 -0
- package/src/reanimated/ReanimatedScreen.tsx +6 -84
- package/src/reanimated/ReanimatedScreenProvider.tsx +42 -0
- package/src/reanimated/index.tsx +1 -1
- package/src/types.tsx +101 -1
- package/src/utils.ts +12 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.JSApplicationIllegalArgumentException
|
|
4
|
+
import com.facebook.react.common.MapBuilder
|
|
5
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
6
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
7
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
8
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
9
|
+
|
|
10
|
+
@ReactModule(name = SearchBarManager.REACT_CLASS)
|
|
11
|
+
class SearchBarManager : ViewGroupManager<SearchBarView>() {
|
|
12
|
+
override fun getName(): String {
|
|
13
|
+
return REACT_CLASS
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
override fun createViewInstance(context: ThemedReactContext): SearchBarView {
|
|
17
|
+
return SearchBarView(context)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
override fun onAfterUpdateTransaction(view: SearchBarView) {
|
|
21
|
+
super.onAfterUpdateTransaction(view)
|
|
22
|
+
view.onUpdate()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@ReactProp(name = "autoCapitalize")
|
|
26
|
+
fun setAutoCapitalize(view: SearchBarView, autoCapitalize: String?) {
|
|
27
|
+
view.autoCapitalize = when (autoCapitalize) {
|
|
28
|
+
null, "none" -> SearchBarView.SearchBarAutoCapitalize.NONE
|
|
29
|
+
"words" -> SearchBarView.SearchBarAutoCapitalize.WORDS
|
|
30
|
+
"sentences" -> SearchBarView.SearchBarAutoCapitalize.SENTENCES
|
|
31
|
+
"characters" -> SearchBarView.SearchBarAutoCapitalize.CHARACTERS
|
|
32
|
+
else -> throw JSApplicationIllegalArgumentException(
|
|
33
|
+
"Forbidden auto capitalize value passed"
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@ReactProp(name = "autoFocus")
|
|
39
|
+
fun setAutoFocus(view: SearchBarView, autoFocus: Boolean?) {
|
|
40
|
+
view.autoFocus = autoFocus ?: false
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@ReactProp(name = "barTintColor", customType = "Color")
|
|
44
|
+
fun setTintColor(view: SearchBarView, color: Int?) {
|
|
45
|
+
view.tintColor = color
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@ReactProp(name = "disableBackButtonOverride")
|
|
49
|
+
fun setDisableBackButtonOverride(view: SearchBarView, disableBackButtonOverride: Boolean?) {
|
|
50
|
+
view.shouldOverrideBackButton = disableBackButtonOverride != true
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@ReactProp(name = "inputType")
|
|
54
|
+
fun setInputType(view: SearchBarView, inputType: String?) {
|
|
55
|
+
view.inputType = when (inputType) {
|
|
56
|
+
null, "text" -> SearchBarView.SearchBarInputTypes.TEXT
|
|
57
|
+
"phone" -> SearchBarView.SearchBarInputTypes.PHONE
|
|
58
|
+
"number" -> SearchBarView.SearchBarInputTypes.NUMBER
|
|
59
|
+
"email" -> SearchBarView.SearchBarInputTypes.EMAIL
|
|
60
|
+
else -> throw JSApplicationIllegalArgumentException(
|
|
61
|
+
"Forbidden input type value"
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@ReactProp(name = "placeholder")
|
|
67
|
+
fun setPlaceholder(view: SearchBarView, placeholder: String?) {
|
|
68
|
+
if (placeholder != null) {
|
|
69
|
+
view.placeholder = placeholder
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@ReactProp(name = "textColor", customType = "Color")
|
|
74
|
+
fun setTextColor(view: SearchBarView, color: Int?) {
|
|
75
|
+
view.textColor = color
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@ReactProp(name = "headerIconColor", customType = "Color")
|
|
79
|
+
fun setHeaderIconColor(view: SearchBarView, color: Int?) {
|
|
80
|
+
view.headerIconColor = color
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@ReactProp(name = "hintTextColor", customType = "Color")
|
|
84
|
+
fun setHintTextColor(view: SearchBarView, color: Int?) {
|
|
85
|
+
view.hintTextColor = color
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@ReactProp(name = "shouldShowHintSearchIcon")
|
|
89
|
+
fun setShouldShowHintSearchIcon(view: SearchBarView, shouldShowHintSearchIcon: Boolean?) {
|
|
90
|
+
view.shouldShowHintSearchIcon = shouldShowHintSearchIcon ?: true
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any>? {
|
|
94
|
+
return MapBuilder.builder<String, Any>()
|
|
95
|
+
.put("onChangeText", MapBuilder.of("registrationName", "onChangeText"))
|
|
96
|
+
.put("onSearchButtonPress", MapBuilder.of("registrationName", "onSearchButtonPress"))
|
|
97
|
+
.put("onFocus", MapBuilder.of("registrationName", "onFocus"))
|
|
98
|
+
.put("onBlur", MapBuilder.of("registrationName", "onBlur"))
|
|
99
|
+
.put("onClose", MapBuilder.of("registrationName", "onClose"))
|
|
100
|
+
.put("onOpen", MapBuilder.of("registrationName", "onOpen"))
|
|
101
|
+
.build()
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
companion object {
|
|
105
|
+
const val REACT_CLASS = "RNSSearchBar"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.text.InputType
|
|
5
|
+
import androidx.appcompat.widget.SearchView
|
|
6
|
+
import com.facebook.react.bridge.Arguments
|
|
7
|
+
import com.facebook.react.bridge.ReactContext
|
|
8
|
+
import com.facebook.react.bridge.WritableMap
|
|
9
|
+
import com.facebook.react.uimanager.events.RCTEventEmitter
|
|
10
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
11
|
+
|
|
12
|
+
@SuppressLint("ViewConstructor")
|
|
13
|
+
class SearchBarView(reactContext: ReactContext?) : ReactViewGroup(reactContext) {
|
|
14
|
+
var inputType: SearchBarInputTypes = SearchBarInputTypes.TEXT
|
|
15
|
+
var autoCapitalize: SearchBarAutoCapitalize = SearchBarAutoCapitalize.NONE
|
|
16
|
+
var textColor: Int? = null
|
|
17
|
+
var tintColor: Int? = null
|
|
18
|
+
var headerIconColor: Int? = null
|
|
19
|
+
var hintTextColor: Int? = null
|
|
20
|
+
var placeholder: String = ""
|
|
21
|
+
var shouldOverrideBackButton: Boolean = true
|
|
22
|
+
var autoFocus: Boolean = false
|
|
23
|
+
var shouldShowHintSearchIcon: Boolean = true
|
|
24
|
+
|
|
25
|
+
private var mSearchViewFormatter: SearchViewFormatter? = null
|
|
26
|
+
|
|
27
|
+
private var mAreListenersSet: Boolean = false
|
|
28
|
+
|
|
29
|
+
private val screenStackFragment: ScreenStackFragment?
|
|
30
|
+
get() {
|
|
31
|
+
val currentParent = parent
|
|
32
|
+
if (currentParent is ScreenStackHeaderSubview) {
|
|
33
|
+
return currentParent.config?.screenFragment
|
|
34
|
+
}
|
|
35
|
+
return null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
fun onUpdate() {
|
|
39
|
+
setSearchViewProps()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private fun setSearchViewProps() {
|
|
43
|
+
val searchView = screenStackFragment?.searchView
|
|
44
|
+
if (searchView != null) {
|
|
45
|
+
if (!mAreListenersSet) {
|
|
46
|
+
setSearchViewListeners(searchView)
|
|
47
|
+
mAreListenersSet = true
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
searchView.inputType = inputType.toAndroidInputType(autoCapitalize)
|
|
51
|
+
mSearchViewFormatter?.setTextColor(textColor)
|
|
52
|
+
mSearchViewFormatter?.setTintColor(tintColor)
|
|
53
|
+
mSearchViewFormatter?.setHeaderIconColor(headerIconColor)
|
|
54
|
+
mSearchViewFormatter?.setHintTextColor(hintTextColor)
|
|
55
|
+
mSearchViewFormatter?.setPlaceholder(placeholder, shouldShowHintSearchIcon)
|
|
56
|
+
searchView.overrideBackAction = shouldOverrideBackButton
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
override fun onAttachedToWindow() {
|
|
61
|
+
super.onAttachedToWindow()
|
|
62
|
+
|
|
63
|
+
screenStackFragment?.onSearchViewCreate = { newSearchView ->
|
|
64
|
+
if (mSearchViewFormatter == null) mSearchViewFormatter =
|
|
65
|
+
SearchViewFormatter(newSearchView)
|
|
66
|
+
setSearchViewProps()
|
|
67
|
+
if (autoFocus) {
|
|
68
|
+
screenStackFragment?.searchView?.focus()
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private fun setSearchViewListeners(searchView: SearchView) {
|
|
74
|
+
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
|
75
|
+
override fun onQueryTextChange(newText: String?): Boolean {
|
|
76
|
+
handleTextChange(newText)
|
|
77
|
+
return true
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
override fun onQueryTextSubmit(query: String?): Boolean {
|
|
81
|
+
handleTextSubmit(query)
|
|
82
|
+
return true
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
searchView.setOnQueryTextFocusChangeListener { _, hasFocus ->
|
|
86
|
+
handleFocusChange(hasFocus)
|
|
87
|
+
}
|
|
88
|
+
searchView.setOnCloseListener {
|
|
89
|
+
handleClose()
|
|
90
|
+
false
|
|
91
|
+
}
|
|
92
|
+
searchView.setOnSearchClickListener {
|
|
93
|
+
handleOpen()
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private fun handleTextChange(newText: String?) {
|
|
98
|
+
val event = Arguments.createMap()
|
|
99
|
+
event.putString("text", newText)
|
|
100
|
+
sendEvent("onChangeText", event)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private fun handleFocusChange(hasFocus: Boolean) {
|
|
104
|
+
sendEvent(if (hasFocus) "onFocus" else "onBlur", null)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private fun handleClose() {
|
|
108
|
+
sendEvent("onClose", null)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private fun handleOpen() {
|
|
112
|
+
sendEvent("onOpen", null)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private fun handleTextSubmit(newText: String?) {
|
|
116
|
+
val event = Arguments.createMap()
|
|
117
|
+
event.putString("text", newText)
|
|
118
|
+
sendEvent("onSearchButtonPress", event)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private fun sendEvent(eventName: String, eventContent: WritableMap?) {
|
|
122
|
+
(context as ReactContext).getJSModule(RCTEventEmitter::class.java)
|
|
123
|
+
?.receiveEvent(id, eventName, eventContent)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
enum class SearchBarAutoCapitalize {
|
|
127
|
+
NONE, WORDS, SENTENCES, CHARACTERS
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
enum class SearchBarInputTypes {
|
|
131
|
+
TEXT {
|
|
132
|
+
override fun toAndroidInputType(capitalize: SearchBarAutoCapitalize) =
|
|
133
|
+
when (capitalize) {
|
|
134
|
+
SearchBarAutoCapitalize.NONE -> InputType.TYPE_CLASS_TEXT
|
|
135
|
+
SearchBarAutoCapitalize.WORDS -> InputType.TYPE_TEXT_FLAG_CAP_WORDS
|
|
136
|
+
SearchBarAutoCapitalize.SENTENCES -> InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
|
|
137
|
+
SearchBarAutoCapitalize.CHARACTERS -> InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
PHONE {
|
|
141
|
+
override fun toAndroidInputType(capitalize: SearchBarAutoCapitalize) =
|
|
142
|
+
InputType.TYPE_CLASS_PHONE
|
|
143
|
+
},
|
|
144
|
+
NUMBER {
|
|
145
|
+
override fun toAndroidInputType(capitalize: SearchBarAutoCapitalize) =
|
|
146
|
+
InputType.TYPE_CLASS_NUMBER
|
|
147
|
+
},
|
|
148
|
+
EMAIL {
|
|
149
|
+
override fun toAndroidInputType(capitalize: SearchBarAutoCapitalize) =
|
|
150
|
+
InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
abstract fun toAndroidInputType(capitalize: SearchBarAutoCapitalize): Int
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import android.graphics.drawable.Drawable
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.widget.EditText
|
|
6
|
+
import android.widget.ImageView
|
|
7
|
+
import androidx.appcompat.R
|
|
8
|
+
import androidx.appcompat.widget.SearchView
|
|
9
|
+
|
|
10
|
+
class SearchViewFormatter(var searchView: SearchView) {
|
|
11
|
+
private var mDefaultTextColor: Int? = null
|
|
12
|
+
private var mDefaultTintBackground: Drawable? = null
|
|
13
|
+
|
|
14
|
+
private val searchEditText
|
|
15
|
+
get() = searchView.findViewById<View>(R.id.search_src_text) as? EditText
|
|
16
|
+
private val searchTextPlate
|
|
17
|
+
get() = searchView.findViewById<View>(R.id.search_plate)
|
|
18
|
+
private val searchIcon
|
|
19
|
+
get() = searchView.findViewById<ImageView>(R.id.search_button)
|
|
20
|
+
private val searchCloseIcon
|
|
21
|
+
get() = searchView.findViewById<ImageView>(R.id.search_close_btn)
|
|
22
|
+
|
|
23
|
+
fun setTextColor(textColor: Int?) {
|
|
24
|
+
val currentDefaultTextColor = mDefaultTextColor
|
|
25
|
+
if (textColor != null) {
|
|
26
|
+
if (mDefaultTextColor == null) {
|
|
27
|
+
mDefaultTextColor = searchEditText?.textColors?.defaultColor
|
|
28
|
+
}
|
|
29
|
+
searchEditText?.setTextColor(textColor)
|
|
30
|
+
} else if (currentDefaultTextColor != null) {
|
|
31
|
+
searchEditText?.setTextColor(currentDefaultTextColor)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
fun setTintColor(tintColor: Int?) {
|
|
36
|
+
val currentDefaultTintColor = mDefaultTintBackground
|
|
37
|
+
if (tintColor != null) {
|
|
38
|
+
if (mDefaultTintBackground == null) {
|
|
39
|
+
mDefaultTintBackground = searchTextPlate.background
|
|
40
|
+
}
|
|
41
|
+
searchTextPlate.setBackgroundColor(tintColor)
|
|
42
|
+
} else if (currentDefaultTintColor != null) {
|
|
43
|
+
searchTextPlate.background = currentDefaultTintColor
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
fun setHeaderIconColor(headerIconColor: Int?) {
|
|
48
|
+
headerIconColor?.let {
|
|
49
|
+
searchIcon.setColorFilter(it)
|
|
50
|
+
searchCloseIcon.setColorFilter(it)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
fun setHintTextColor(hintTextColor: Int?) {
|
|
55
|
+
hintTextColor?.let {
|
|
56
|
+
searchEditText?.setHintTextColor(it)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fun setPlaceholder(placeholder: String, shouldShowHintSearchIcon: Boolean) {
|
|
61
|
+
if (shouldShowHintSearchIcon) {
|
|
62
|
+
searchView.queryHint = placeholder
|
|
63
|
+
} else {
|
|
64
|
+
searchEditText?.hint = placeholder
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
+
<alpha
|
|
4
|
+
android:interpolator="@android:interpolator/accelerate_decelerate"
|
|
5
|
+
android:fromAlpha="0"
|
|
6
|
+
android:toAlpha="1.0"
|
|
7
|
+
android:startOffset="100"
|
|
8
|
+
android:duration="100"/>
|
|
9
|
+
<scale
|
|
10
|
+
android:interpolator="@android:interpolator/accelerate_decelerate"
|
|
11
|
+
android:fromXScale="0.85"
|
|
12
|
+
android:toXScale="1"
|
|
13
|
+
android:fromYScale="0.85"
|
|
14
|
+
android:toYScale="1"
|
|
15
|
+
android:pivotX="50%"
|
|
16
|
+
android:pivotY="50%"
|
|
17
|
+
android:duration="200"/>
|
|
18
|
+
</set>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
+
<alpha
|
|
4
|
+
android:fromAlpha="1"
|
|
5
|
+
android:toAlpha="0.4"
|
|
6
|
+
android:startOffset="100"
|
|
7
|
+
android:duration="100"
|
|
8
|
+
android:interpolator="@android:interpolator/accelerate_decelerate" />
|
|
9
|
+
|
|
10
|
+
<scale
|
|
11
|
+
android:interpolator="@android:interpolator/accelerate_decelerate"
|
|
12
|
+
android:fromXScale="1"
|
|
13
|
+
android:toXScale="1.15"
|
|
14
|
+
android:fromYScale="1"
|
|
15
|
+
android:toYScale="1.15"
|
|
16
|
+
android:pivotX="50%"
|
|
17
|
+
android:pivotY="50%"
|
|
18
|
+
android:duration="200"/>
|
|
19
|
+
</set>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:shareInterpolator="false">
|
|
4
|
+
<alpha
|
|
5
|
+
android:fromAlpha="0.0"
|
|
6
|
+
android:toAlpha="1"
|
|
7
|
+
android:startOffset="50"
|
|
8
|
+
android:duration="100"/>
|
|
9
|
+
<scale
|
|
10
|
+
android:fromXScale="1.15"
|
|
11
|
+
android:toXScale="1"
|
|
12
|
+
android:fromYScale="1.15"
|
|
13
|
+
android:toYScale="1"
|
|
14
|
+
android:pivotX="50%"
|
|
15
|
+
android:pivotY="50%"
|
|
16
|
+
android:duration="200"/>
|
|
17
|
+
</set>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:shareInterpolator="false"
|
|
4
|
+
android:zAdjustment="top">
|
|
5
|
+
<alpha
|
|
6
|
+
android:fromAlpha="1"
|
|
7
|
+
android:toAlpha="0.0"
|
|
8
|
+
android:startOffset="50"
|
|
9
|
+
android:duration="100"/>
|
|
10
|
+
<scale
|
|
11
|
+
android:fromXScale="1"
|
|
12
|
+
android:toXScale="0.85"
|
|
13
|
+
android:fromYScale="1"
|
|
14
|
+
android:toYScale="0.85"
|
|
15
|
+
android:pivotX="50%"
|
|
16
|
+
android:pivotY="50%"
|
|
17
|
+
android:duration="200"/>
|
|
18
|
+
</set>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!--Duration taken from debugging source code-->
|
|
3
|
+
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
|
+
android:fromAlpha="0.0"
|
|
5
|
+
android:toAlpha="1.0"
|
|
6
|
+
android:duration="150"
|
|
7
|
+
/> <!--Remember to change duration in the corresponding xml when modifying it-->
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!--Duration taken from debugging source code-->
|
|
3
|
+
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
|
+
android:fromAlpha="1.0"
|
|
5
|
+
android:toAlpha="0.0"
|
|
6
|
+
android:duration="150"
|
|
7
|
+
/> <!--Remember to change duration in the corresponding xml when modifying it-->
|
|
@@ -464,6 +464,18 @@ Defaults to an empty string.
|
|
|
464
464
|
|
|
465
465
|
The search field text color.
|
|
466
466
|
|
|
467
|
+
#### `hintTextColor`
|
|
468
|
+
|
|
469
|
+
The search hint text color. (Android only)
|
|
470
|
+
|
|
471
|
+
#### `headerIconColor`
|
|
472
|
+
|
|
473
|
+
The search and close icon color shown in the header. (Android only)
|
|
474
|
+
|
|
475
|
+
#### `shouldShowHintSearchIcon`
|
|
476
|
+
|
|
477
|
+
Show the search hint icon when search bar is focused. (Android only)
|
|
478
|
+
|
|
467
479
|
### Helpers
|
|
468
480
|
|
|
469
481
|
The stack navigator adds the following methods to the navigation prop:
|
package/ios/RNSScreen.h
CHANGED
|
@@ -29,6 +29,11 @@ typedef NS_ENUM(NSInteger, RNSScreenReplaceAnimation) {
|
|
|
29
29
|
RNSScreenReplaceAnimationPush,
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
+
typedef NS_ENUM(NSInteger, RNSScreenSwipeDirection) {
|
|
33
|
+
RNSScreenSwipeDirectionVertical,
|
|
34
|
+
RNSScreenSwipeDirectionHorizontal,
|
|
35
|
+
};
|
|
36
|
+
|
|
32
37
|
typedef NS_ENUM(NSInteger, RNSActivityState) {
|
|
33
38
|
RNSActivityStateInactive = 0,
|
|
34
39
|
RNSActivityStateTransitioningOrBelowTop = 1,
|
|
@@ -47,6 +52,7 @@ typedef NS_ENUM(NSInteger, RNSWindowTrait) {
|
|
|
47
52
|
RNSWindowTraitAnimation,
|
|
48
53
|
RNSWindowTraitHidden,
|
|
49
54
|
RNSWindowTraitOrientation,
|
|
55
|
+
RNSWindowTraitHomeIndicatorHidden,
|
|
50
56
|
};
|
|
51
57
|
|
|
52
58
|
@interface RCTConvert (RNSScreen)
|
|
@@ -91,19 +97,23 @@ typedef NS_ENUM(NSInteger, RNSWindowTrait) {
|
|
|
91
97
|
@property (nonatomic) RNSScreenStackAnimation stackAnimation;
|
|
92
98
|
@property (nonatomic) RNSScreenStackPresentation stackPresentation;
|
|
93
99
|
@property (nonatomic) RNSScreenReplaceAnimation replaceAnimation;
|
|
100
|
+
@property (nonatomic) RNSScreenSwipeDirection swipeDirection;
|
|
94
101
|
@property (nonatomic) BOOL preventNativeDismiss;
|
|
95
102
|
@property (nonatomic) BOOL hasOrientationSet;
|
|
96
103
|
@property (nonatomic) BOOL hasStatusBarStyleSet;
|
|
97
104
|
@property (nonatomic) BOOL hasStatusBarAnimationSet;
|
|
98
105
|
@property (nonatomic) BOOL hasStatusBarHiddenSet;
|
|
106
|
+
@property (nonatomic) BOOL hasHomeIndicatorHiddenSet;
|
|
99
107
|
@property (nonatomic) BOOL customAnimationOnSwipe;
|
|
100
108
|
@property (nonatomic) BOOL fullScreenSwipeEnabled;
|
|
109
|
+
@property (nonatomic, retain) NSNumber *transitionDuration;
|
|
101
110
|
|
|
102
111
|
#if !TARGET_OS_TV
|
|
103
112
|
@property (nonatomic) RNSStatusBarStyle statusBarStyle;
|
|
104
113
|
@property (nonatomic) UIStatusBarAnimation statusBarAnimation;
|
|
105
114
|
@property (nonatomic) BOOL statusBarHidden;
|
|
106
115
|
@property (nonatomic) UIInterfaceOrientationMask screenOrientation;
|
|
116
|
+
@property (nonatomic) BOOL homeIndicatorHidden;
|
|
107
117
|
#endif
|
|
108
118
|
|
|
109
119
|
- (void)notifyFinishTransitioning;
|
package/ios/RNSScreen.m
CHANGED
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
_hasStatusBarAnimationSet = NO;
|
|
35
35
|
_hasStatusBarHiddenSet = NO;
|
|
36
36
|
_hasOrientationSet = NO;
|
|
37
|
+
_hasHomeIndicatorHiddenSet = NO;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
return self;
|
|
@@ -206,6 +207,13 @@
|
|
|
206
207
|
_screenOrientation = screenOrientation;
|
|
207
208
|
[RNSScreenWindowTraits enforceDesiredDeviceOrientation];
|
|
208
209
|
}
|
|
210
|
+
|
|
211
|
+
- (void)setHomeIndicatorHidden:(BOOL)homeIndicatorHidden
|
|
212
|
+
{
|
|
213
|
+
_hasHomeIndicatorHiddenSet = YES;
|
|
214
|
+
_homeIndicatorHidden = homeIndicatorHidden;
|
|
215
|
+
[RNSScreenWindowTraits updateHomeIndicatorAutoHidden];
|
|
216
|
+
}
|
|
209
217
|
#endif
|
|
210
218
|
|
|
211
219
|
- (UIView *)reactSuperview
|
|
@@ -436,6 +444,17 @@
|
|
|
436
444
|
return UIInterfaceOrientationMaskAllButUpsideDown;
|
|
437
445
|
}
|
|
438
446
|
|
|
447
|
+
- (UIViewController *)childViewControllerForHomeIndicatorAutoHidden
|
|
448
|
+
{
|
|
449
|
+
UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitHomeIndicatorHidden includingModals:YES];
|
|
450
|
+
return vc == self ? nil : vc;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
- (BOOL)prefersHomeIndicatorAutoHidden
|
|
454
|
+
{
|
|
455
|
+
return ((RNSScreenView *)self.view).homeIndicatorHidden;
|
|
456
|
+
}
|
|
457
|
+
|
|
439
458
|
// if the returned vc is a child, it means that it can provide config;
|
|
440
459
|
// if the returned vc is self, it means that there is no child for config and self has config to provide,
|
|
441
460
|
// so we return self which results in asking self for preferredStatusBarStyle/Animation etc.;
|
|
@@ -495,6 +514,9 @@
|
|
|
495
514
|
case RNSWindowTraitOrientation: {
|
|
496
515
|
return ((RNSScreenView *)self.view).hasOrientationSet;
|
|
497
516
|
}
|
|
517
|
+
case RNSWindowTraitHomeIndicatorHidden: {
|
|
518
|
+
return ((RNSScreenView *)self.view).hasHomeIndicatorHiddenSet;
|
|
519
|
+
}
|
|
498
520
|
default: {
|
|
499
521
|
RCTLogError(@"Unknown trait passed: %d", (int)trait);
|
|
500
522
|
}
|
|
@@ -688,6 +710,10 @@
|
|
|
688
710
|
|
|
689
711
|
- (void)traverseForScrollView:(UIView *)view
|
|
690
712
|
{
|
|
713
|
+
if (![[self.view valueForKey:@"_bridge"] valueForKey:@"_jsThread"]) {
|
|
714
|
+
// we don't want to send `scrollViewDidEndDecelerating` event to JS before the JS thread is ready
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
691
717
|
if ([view isKindOfClass:[UIScrollView class]] &&
|
|
692
718
|
([[(UIScrollView *)view delegate] respondsToSelector:@selector(scrollViewDidEndDecelerating:)])) {
|
|
693
719
|
[[(UIScrollView *)view delegate] scrollViewDidEndDecelerating:(id)view];
|
|
@@ -767,6 +793,8 @@ RCT_EXPORT_VIEW_PROPERTY(preventNativeDismiss, BOOL)
|
|
|
767
793
|
RCT_EXPORT_VIEW_PROPERTY(replaceAnimation, RNSScreenReplaceAnimation)
|
|
768
794
|
RCT_EXPORT_VIEW_PROPERTY(stackPresentation, RNSScreenStackPresentation)
|
|
769
795
|
RCT_EXPORT_VIEW_PROPERTY(stackAnimation, RNSScreenStackAnimation)
|
|
796
|
+
RCT_EXPORT_VIEW_PROPERTY(swipeDirection, RNSScreenSwipeDirection)
|
|
797
|
+
RCT_EXPORT_VIEW_PROPERTY(transitionDuration, NSNumber)
|
|
770
798
|
|
|
771
799
|
RCT_EXPORT_VIEW_PROPERTY(onAppear, RCTDirectEventBlock);
|
|
772
800
|
RCT_EXPORT_VIEW_PROPERTY(onDisappear, RCTDirectEventBlock);
|
|
@@ -781,6 +809,7 @@ RCT_EXPORT_VIEW_PROPERTY(screenOrientation, UIInterfaceOrientationMask)
|
|
|
781
809
|
RCT_EXPORT_VIEW_PROPERTY(statusBarAnimation, UIStatusBarAnimation)
|
|
782
810
|
RCT_EXPORT_VIEW_PROPERTY(statusBarHidden, BOOL)
|
|
783
811
|
RCT_EXPORT_VIEW_PROPERTY(statusBarStyle, RNSStatusBarStyle)
|
|
812
|
+
RCT_EXPORT_VIEW_PROPERTY(homeIndicatorHidden, BOOL)
|
|
784
813
|
#endif
|
|
785
814
|
|
|
786
815
|
- (UIView *)view
|
|
@@ -831,6 +860,15 @@ RCT_ENUM_CONVERTER(
|
|
|
831
860
|
RNSScreenReplaceAnimationPop,
|
|
832
861
|
integerValue)
|
|
833
862
|
|
|
863
|
+
RCT_ENUM_CONVERTER(
|
|
864
|
+
RNSScreenSwipeDirection,
|
|
865
|
+
(@{
|
|
866
|
+
@"vertical" : @(RNSScreenSwipeDirectionVertical),
|
|
867
|
+
@"horizontal" : @(RNSScreenSwipeDirectionHorizontal),
|
|
868
|
+
}),
|
|
869
|
+
RNSScreenSwipeDirectionHorizontal,
|
|
870
|
+
integerValue)
|
|
871
|
+
|
|
834
872
|
#if !TARGET_OS_TV
|
|
835
873
|
RCT_ENUM_CONVERTER(
|
|
836
874
|
RNSStatusBarStyle,
|
package/ios/RNSScreenContainer.m
CHANGED