react-native-unistyles 3.0.0-alpha.35 → 3.0.0-alpha.37

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. package/Unistyles.podspec +1 -1
  2. package/android/CMakeLists.txt +19 -36
  3. package/android/build.gradle +2 -1
  4. package/android/src/main/cxx/NativeUnistylesModule.cpp +71 -0
  5. package/android/src/main/cxx/NativeUnistylesModule.h +42 -0
  6. package/android/src/main/cxx/cpp-adapter.cpp +8 -86
  7. package/android/src/main/java/com/unistyles/Equatable.kt +61 -0
  8. package/android/src/main/java/com/unistyles/NativePlatform+android.kt +302 -0
  9. package/android/src/main/java/com/unistyles/NativePlatform+insets.kt +148 -0
  10. package/android/src/main/java/com/unistyles/NativePlatform+listener.kt +54 -0
  11. package/android/src/main/java/com/unistyles/UnistylesModule.kt +51 -0
  12. package/android/src/main/java/com/unistyles/UnistylesPackage.kt +16 -14
  13. package/cxx/NativePlatform.h +11 -0
  14. package/cxx/common/Helpers.h +1 -1
  15. package/cxx/core/Unistyle.h +1 -1
  16. package/cxx/core/UnistyleData.h +1 -1
  17. package/cxx/core/UnistyleWrapper.h +1 -2
  18. package/cxx/core/UnistylesCommitHook.cpp +1 -1
  19. package/cxx/core/UnistylesMountHook.cpp +1 -1
  20. package/cxx/core/UnistylesRegistry.cpp +4 -13
  21. package/cxx/core/UnistylesRegistry.h +2 -3
  22. package/cxx/core/UnistylesState.cpp +10 -7
  23. package/cxx/hybridObjects/HybridNavigationBar.h +3 -3
  24. package/cxx/hybridObjects/HybridStatusBar.h +3 -3
  25. package/cxx/hybridObjects/HybridStyleSheet.cpp +21 -18
  26. package/cxx/hybridObjects/HybridUnistylesRuntime.cpp +4 -8
  27. package/cxx/hybridObjects/HybridUnistylesRuntime.h +2 -3
  28. package/cxx/parser/Parser.cpp +3 -27
  29. package/cxx/parser/Parser.h +2 -3
  30. package/cxx/shadowTree/ShadowTrafficController.h +9 -5
  31. package/cxx/shadowTree/ShadowTreeManager.cpp +10 -5
  32. package/cxx/shadowTree/ShadowTreeManager.h +1 -1
  33. package/lib/commonjs/components/useMedia.js.map +1 -1
  34. package/lib/commonjs/components/useMedia.web.js +43 -0
  35. package/lib/commonjs/components/useMedia.web.js.map +1 -0
  36. package/lib/commonjs/core/createUnistylesComponent.js +57 -4
  37. package/lib/commonjs/core/createUnistylesComponent.js.map +1 -1
  38. package/lib/commonjs/core/createUnistylesComponent.native.js +6 -5
  39. package/lib/commonjs/core/createUnistylesComponent.native.js.map +1 -1
  40. package/lib/commonjs/web/convert/index.js +16 -11
  41. package/lib/commonjs/web/convert/index.js.map +1 -1
  42. package/lib/commonjs/web/convert/object/boxShadow.js +58 -0
  43. package/lib/commonjs/web/convert/object/boxShadow.js.map +1 -0
  44. package/lib/commonjs/web/convert/object/filter.js +42 -0
  45. package/lib/commonjs/web/convert/object/filter.js.map +1 -0
  46. package/lib/commonjs/web/convert/object/index.js +39 -0
  47. package/lib/commonjs/web/convert/object/index.js.map +1 -0
  48. package/lib/commonjs/web/convert/object/objectStyle.js +55 -0
  49. package/lib/commonjs/web/convert/object/objectStyle.js.map +1 -0
  50. package/lib/commonjs/web/convert/object/transform.js +27 -0
  51. package/lib/commonjs/web/convert/object/transform.js.map +1 -0
  52. package/lib/commonjs/web/convert/{boxShadow.js → shadow/boxShadow.js} +9 -24
  53. package/lib/commonjs/web/convert/shadow/boxShadow.js.map +1 -0
  54. package/lib/commonjs/web/convert/shadow/getShadowBreakpoints.js +38 -0
  55. package/lib/commonjs/web/convert/shadow/getShadowBreakpoints.js.map +1 -0
  56. package/lib/commonjs/web/convert/shadow/index.js +28 -0
  57. package/lib/commonjs/web/convert/shadow/index.js.map +1 -0
  58. package/lib/commonjs/web/convert/{textShadow.js → shadow/textShadow.js} +9 -23
  59. package/lib/commonjs/web/convert/shadow/textShadow.js.map +1 -0
  60. package/lib/commonjs/web/convert/utils.js +7 -3
  61. package/lib/commonjs/web/convert/utils.js.map +1 -1
  62. package/lib/commonjs/web/listener.js +10 -0
  63. package/lib/commonjs/web/listener.js.map +1 -1
  64. package/lib/commonjs/web/registry.js +13 -26
  65. package/lib/commonjs/web/registry.js.map +1 -1
  66. package/lib/commonjs/web/runtime.js +3 -0
  67. package/lib/commonjs/web/runtime.js.map +1 -1
  68. package/lib/commonjs/web/shadowRegistry.js +79 -39
  69. package/lib/commonjs/web/shadowRegistry.js.map +1 -1
  70. package/lib/commonjs/web/utils/common.js +3 -33
  71. package/lib/commonjs/web/utils/common.js.map +1 -1
  72. package/lib/commonjs/web/utils/unistyle.js +4 -1
  73. package/lib/commonjs/web/utils/unistyle.js.map +1 -1
  74. package/lib/module/components/useMedia.js.map +1 -1
  75. package/lib/module/components/useMedia.web.js +38 -0
  76. package/lib/module/components/useMedia.web.js.map +1 -0
  77. package/lib/module/core/createUnistylesComponent.js +55 -3
  78. package/lib/module/core/createUnistylesComponent.js.map +1 -1
  79. package/lib/module/core/createUnistylesComponent.native.js +6 -5
  80. package/lib/module/core/createUnistylesComponent.native.js.map +1 -1
  81. package/lib/module/web/convert/index.js +14 -9
  82. package/lib/module/web/convert/index.js.map +1 -1
  83. package/lib/module/web/convert/object/boxShadow.js +53 -0
  84. package/lib/module/web/convert/object/boxShadow.js.map +1 -0
  85. package/lib/module/web/convert/object/filter.js +37 -0
  86. package/lib/module/web/convert/object/filter.js.map +1 -0
  87. package/lib/module/web/convert/object/index.js +6 -0
  88. package/lib/module/web/convert/object/index.js.map +1 -0
  89. package/lib/module/web/convert/object/objectStyle.js +50 -0
  90. package/lib/module/web/convert/object/objectStyle.js.map +1 -0
  91. package/lib/module/web/convert/object/transform.js +22 -0
  92. package/lib/module/web/convert/object/transform.js.map +1 -0
  93. package/lib/module/web/convert/{boxShadow.js → shadow/boxShadow.js} +9 -24
  94. package/lib/module/web/convert/shadow/boxShadow.js.map +1 -0
  95. package/lib/module/web/convert/shadow/getShadowBreakpoints.js +33 -0
  96. package/lib/module/web/convert/shadow/getShadowBreakpoints.js.map +1 -0
  97. package/lib/module/web/convert/shadow/index.js +5 -0
  98. package/lib/module/web/convert/shadow/index.js.map +1 -0
  99. package/lib/module/web/convert/{textShadow.js → shadow/textShadow.js} +9 -23
  100. package/lib/module/web/convert/shadow/textShadow.js.map +1 -0
  101. package/lib/module/web/convert/utils.js +4 -2
  102. package/lib/module/web/convert/utils.js.map +1 -1
  103. package/lib/module/web/listener.js +10 -0
  104. package/lib/module/web/listener.js.map +1 -1
  105. package/lib/module/web/registry.js +14 -27
  106. package/lib/module/web/registry.js.map +1 -1
  107. package/lib/module/web/runtime.js +3 -0
  108. package/lib/module/web/runtime.js.map +1 -1
  109. package/lib/module/web/shadowRegistry.js +80 -40
  110. package/lib/module/web/shadowRegistry.js.map +1 -1
  111. package/lib/module/web/utils/common.js +1 -31
  112. package/lib/module/web/utils/common.js.map +1 -1
  113. package/lib/module/web/utils/unistyle.js +4 -1
  114. package/lib/module/web/utils/unistyle.js.map +1 -1
  115. package/lib/typescript/src/components/useMedia.web.d.ts +6 -0
  116. package/lib/typescript/src/components/useMedia.web.d.ts.map +1 -0
  117. package/lib/typescript/src/core/createUnistylesComponent.d.ts +4 -3
  118. package/lib/typescript/src/core/createUnistylesComponent.d.ts.map +1 -1
  119. package/lib/typescript/src/core/createUnistylesComponent.native.d.ts +4 -3
  120. package/lib/typescript/src/core/createUnistylesComponent.native.d.ts.map +1 -1
  121. package/lib/typescript/src/types/common.d.ts +1 -0
  122. package/lib/typescript/src/types/common.d.ts.map +1 -1
  123. package/lib/typescript/src/web/convert/index.d.ts.map +1 -1
  124. package/lib/typescript/src/web/convert/object/boxShadow.d.ts +9 -0
  125. package/lib/typescript/src/web/convert/object/boxShadow.d.ts.map +1 -0
  126. package/lib/typescript/src/web/convert/object/filter.d.ts +3 -0
  127. package/lib/typescript/src/web/convert/object/filter.d.ts.map +1 -0
  128. package/lib/typescript/src/web/convert/object/index.d.ts +4 -0
  129. package/lib/typescript/src/web/convert/object/index.d.ts.map +1 -0
  130. package/lib/typescript/src/web/convert/object/objectStyle.d.ts +5 -0
  131. package/lib/typescript/src/web/convert/object/objectStyle.d.ts.map +1 -0
  132. package/lib/typescript/src/web/convert/object/transform.d.ts +3 -0
  133. package/lib/typescript/src/web/convert/object/transform.d.ts.map +1 -0
  134. package/lib/typescript/src/web/convert/shadow/boxShadow.d.ts.map +1 -0
  135. package/lib/typescript/src/web/convert/shadow/getShadowBreakpoints.d.ts +2 -0
  136. package/lib/typescript/src/web/convert/shadow/getShadowBreakpoints.d.ts.map +1 -0
  137. package/lib/typescript/src/web/convert/shadow/index.d.ts +3 -0
  138. package/lib/typescript/src/web/convert/shadow/index.d.ts.map +1 -0
  139. package/lib/typescript/src/web/convert/shadow/textShadow.d.ts.map +1 -0
  140. package/lib/typescript/src/web/convert/types.d.ts +7 -1
  141. package/lib/typescript/src/web/convert/types.d.ts.map +1 -1
  142. package/lib/typescript/src/web/convert/utils.d.ts +8 -4
  143. package/lib/typescript/src/web/convert/utils.d.ts.map +1 -1
  144. package/lib/typescript/src/web/create.d.ts +8 -8
  145. package/lib/typescript/src/web/index.d.ts +8 -8
  146. package/lib/typescript/src/web/listener.d.ts +2 -0
  147. package/lib/typescript/src/web/listener.d.ts.map +1 -1
  148. package/lib/typescript/src/web/registry.d.ts +5 -9
  149. package/lib/typescript/src/web/registry.d.ts.map +1 -1
  150. package/lib/typescript/src/web/runtime.d.ts +1 -0
  151. package/lib/typescript/src/web/runtime.d.ts.map +1 -1
  152. package/lib/typescript/src/web/shadowRegistry.d.ts +4 -1
  153. package/lib/typescript/src/web/shadowRegistry.d.ts.map +1 -1
  154. package/lib/typescript/src/web/utils/common.d.ts +1 -6
  155. package/lib/typescript/src/web/utils/common.d.ts.map +1 -1
  156. package/lib/typescript/src/web/utils/unistyle.d.ts.map +1 -1
  157. package/nitrogen/generated/android/c++/JHybridNativePlatformSpec.hpp +6 -0
  158. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unistyles/Dimensions.kt +1 -0
  159. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unistyles/Func_void.kt +1 -0
  160. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unistyles/Func_void_std__vector_UnistyleDependency_.kt +1 -0
  161. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unistyles/Insets.kt +1 -0
  162. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unistyles/UnistylesNativeMiniRuntime.kt +1 -0
  163. package/nitrogen/generated/android/unistyles+autolinking.gradle +2 -0
  164. package/nitrogen/generated/ios/Unistyles+autolinking.rb +1 -1
  165. package/package.json +3 -3
  166. package/src/components/useMedia.ts +1 -1
  167. package/src/components/useMedia.web.ts +47 -0
  168. package/src/core/createUnistylesComponent.native.tsx +12 -10
  169. package/src/core/createUnistylesComponent.tsx +72 -6
  170. package/src/types/common.ts +1 -0
  171. package/src/web/convert/index.ts +16 -9
  172. package/src/web/convert/object/boxShadow.ts +54 -0
  173. package/src/web/convert/object/filter.ts +39 -0
  174. package/src/web/convert/object/index.ts +3 -0
  175. package/src/web/convert/object/objectStyle.ts +68 -0
  176. package/src/web/convert/object/transform.ts +24 -0
  177. package/src/web/convert/{boxShadow.ts → shadow/boxShadow.ts} +9 -30
  178. package/src/web/convert/shadow/getShadowBreakpoints.ts +34 -0
  179. package/src/web/convert/shadow/index.ts +2 -0
  180. package/src/web/convert/{textShadow.ts → shadow/textShadow.ts} +9 -29
  181. package/src/web/convert/types.ts +8 -1
  182. package/src/web/convert/utils.ts +11 -5
  183. package/src/web/listener.ts +10 -0
  184. package/src/web/registry.ts +10 -31
  185. package/src/web/runtime.ts +4 -0
  186. package/src/web/shadowRegistry.ts +85 -46
  187. package/src/web/utils/common.ts +1 -37
  188. package/src/web/utils/unistyle.ts +5 -1
  189. package/android/src/main/cxx/helpers.cpp +0 -105
  190. package/android/src/main/cxx/helpers.h +0 -16
  191. package/android/src/main/cxx/platform.cpp +0 -170
  192. package/android/src/main/cxx/platform.h +0 -20
  193. package/lib/commonjs/web/convert/boxShadow.js.map +0 -1
  194. package/lib/commonjs/web/convert/shadow.js +0 -68
  195. package/lib/commonjs/web/convert/shadow.js.map +0 -1
  196. package/lib/commonjs/web/convert/textShadow.js.map +0 -1
  197. package/lib/commonjs/web/convert/transform.js +0 -72
  198. package/lib/commonjs/web/convert/transform.js.map +0 -1
  199. package/lib/module/web/convert/boxShadow.js.map +0 -1
  200. package/lib/module/web/convert/shadow.js +0 -63
  201. package/lib/module/web/convert/shadow.js.map +0 -1
  202. package/lib/module/web/convert/textShadow.js.map +0 -1
  203. package/lib/module/web/convert/transform.js +0 -67
  204. package/lib/module/web/convert/transform.js.map +0 -1
  205. package/lib/typescript/src/web/convert/boxShadow.d.ts.map +0 -1
  206. package/lib/typescript/src/web/convert/shadow.d.ts +0 -2
  207. package/lib/typescript/src/web/convert/shadow.d.ts.map +0 -1
  208. package/lib/typescript/src/web/convert/textShadow.d.ts.map +0 -1
  209. package/lib/typescript/src/web/convert/transform.d.ts +0 -4
  210. package/lib/typescript/src/web/convert/transform.d.ts.map +0 -1
  211. package/src/web/convert/shadow.ts +0 -68
  212. package/src/web/convert/transform.ts +0 -88
  213. /package/lib/typescript/src/web/convert/{boxShadow.d.ts → shadow/boxShadow.d.ts} +0 -0
  214. /package/lib/typescript/src/web/convert/{textShadow.d.ts → shadow/textShadow.d.ts} +0 -0
@@ -0,0 +1,148 @@
1
+ package com.unistyles
2
+
3
+ import android.graphics.Rect
4
+ import android.os.Build
5
+ import android.view.View
6
+ import android.view.Window
7
+ import android.view.WindowManager
8
+ import androidx.core.view.ViewCompat
9
+ import androidx.core.view.WindowInsetsAnimationCompat
10
+ import androidx.core.view.WindowInsetsCompat
11
+ import com.facebook.react.bridge.ReactApplicationContext
12
+ import com.margelo.nitro.unistyles.Insets
13
+ import com.margelo.nitro.unistyles.UnistyleDependency
14
+
15
+ typealias CxxImeListener = () -> Unit
16
+
17
+ class NativePlatformInsets(private val reactContext: ReactApplicationContext, private val diffMiniRuntime: () -> Array<UnistyleDependency>) {
18
+ private val _imeListeners: MutableList<CxxImeListener> = mutableListOf()
19
+ private var _insets: Insets = Insets(0.0, 0.0, 0.0, 0.0, 0.0)
20
+
21
+ fun getInsets(): Insets {
22
+ val density = reactContext.resources.displayMetrics.density
23
+
24
+ return Insets(
25
+ this._insets.top / density,
26
+ this._insets.bottom / density,
27
+ this._insets.left / density,
28
+ this._insets.right / density,
29
+ this._insets.ime / density
30
+ )
31
+ }
32
+
33
+ fun setInsets(insetsCompat: WindowInsetsCompat, window: Window, animatedBottomInsets: Double?) {
34
+ // below Android 11, we need to use window flags to detect status bar visibility
35
+ val isStatusBarVisible = when(Build.VERSION.SDK_INT) {
36
+ in 30..Int.MAX_VALUE -> {
37
+ insetsCompat.isVisible(WindowInsetsCompat.Type.statusBars())
38
+ }
39
+ else -> {
40
+ @Suppress("DEPRECATION")
41
+ window.attributes.flags and WindowManager.LayoutParams.FLAG_FULLSCREEN != WindowManager.LayoutParams.FLAG_FULLSCREEN
42
+ }
43
+ }
44
+ // React Native is forcing insets to make status bar translucent
45
+ // so we need to calculate top inset manually, as WindowInsetCompat will always return 0
46
+ val statusBarTopInset = when(isStatusBarVisible) {
47
+ true -> {
48
+ val visibleRect = Rect()
49
+
50
+ window.decorView.getWindowVisibleDisplayFrame(visibleRect)
51
+
52
+ visibleRect.top
53
+ }
54
+ false -> 0
55
+ }
56
+
57
+ val insets = insetsCompat.getInsets(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout())
58
+
59
+ // Android 10 and below - set bottom insets to 0 while keyboard is visible and use default bottom insets otherwise
60
+ // Android 11 and above - animate bottom insets while keyboard is appearing and disappearing
61
+ val imeInsets = if (Build.VERSION.SDK_INT >= 30) {
62
+ animatedBottomInsets ?: this._insets.ime
63
+ } else {
64
+ val nextBottomInset = insetsCompat.getInsets(WindowInsetsCompat.Type.ime()).bottom - insets.bottom
65
+
66
+ // call new IME event here, as for SDK >= 30 it's called in AnimationCallback
67
+ this@NativePlatformInsets.emitImeEvent()
68
+
69
+ if (nextBottomInset < 0) {
70
+ 0
71
+ } else {
72
+ nextBottomInset
73
+ }
74
+ }
75
+
76
+ this._insets = Insets(
77
+ statusBarTopInset.toDouble(),
78
+ insets.bottom.toDouble(),
79
+ insets.left.toDouble(),
80
+ insets.right.toDouble(),
81
+ imeInsets.toDouble()
82
+ )
83
+
84
+ diffMiniRuntime()
85
+ }
86
+
87
+ fun startInsetsListener() {
88
+ reactContext.currentActivity?.let { activity ->
89
+ activity.findViewById<View>(android.R.id.content)?.let { mainView ->
90
+ ViewCompat.setOnApplyWindowInsetsListener(mainView) { _, insets ->
91
+ setInsets(insets, activity.window, null)
92
+
93
+ insets
94
+ }
95
+
96
+ // IME insets are available from Android 11
97
+ if (Build.VERSION.SDK_INT >= 30) {
98
+ ViewCompat.setWindowInsetsAnimationCallback(
99
+ mainView,
100
+ object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP) {
101
+ override fun onProgress(
102
+ insets: WindowInsetsCompat,
103
+ runningAnimations: List<WindowInsetsAnimationCompat>
104
+ ): WindowInsetsCompat {
105
+ runningAnimations.firstOrNull()?.let {
106
+ val bottomInset = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom.toDouble() - this@NativePlatformInsets._insets.bottom
107
+ val nextBottomInset = if (bottomInset < 0) {
108
+ 0.0
109
+ } else {
110
+ bottomInset
111
+ }
112
+
113
+ this@NativePlatformInsets.setInsets(insets, activity.window, nextBottomInset)
114
+ this@NativePlatformInsets.emitImeEvent()
115
+ }
116
+
117
+ return insets
118
+ }
119
+ }
120
+ )
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ fun emitImeEvent() {
127
+ _imeListeners.forEach { listener ->
128
+ listener()
129
+ }
130
+ }
131
+
132
+ fun stopInsetsListener() {
133
+ reactContext.currentActivity?.let { activity ->
134
+ activity.window?.decorView?.let { view ->
135
+ ViewCompat.setOnApplyWindowInsetsListener(view, null)
136
+ ViewCompat.setWindowInsetsAnimationCallback(view, null)
137
+ }
138
+ }
139
+ }
140
+
141
+ fun addImeListener(listener: CxxImeListener) {
142
+ this._imeListeners.add(listener)
143
+ }
144
+
145
+ fun removeImeListeners() {
146
+ this._imeListeners.clear()
147
+ }
148
+ }
@@ -0,0 +1,54 @@
1
+ package com.unistyles
2
+
3
+ import android.content.BroadcastReceiver
4
+ import android.content.Context
5
+ import android.content.Intent
6
+ import android.content.IntentFilter
7
+ import android.os.Handler
8
+ import android.os.Looper
9
+ import com.facebook.react.bridge.ReactApplicationContext
10
+ import com.margelo.nitro.unistyles.UnistyleDependency
11
+
12
+ typealias CxxDependencyListener = (dependencies: Array<UnistyleDependency>) -> Unit
13
+
14
+ class NativePlatformListener(private val reactContext: ReactApplicationContext, private val diffMiniRuntime: () -> Array<UnistyleDependency>) {
15
+ private val _dependencyListeners: MutableList<CxxDependencyListener> = mutableListOf()
16
+
17
+ private val configurationChangeReceiver = object : BroadcastReceiver() {
18
+ override fun onReceive(context: Context, intent: Intent) {
19
+ Handler(Looper.getMainLooper()).postDelayed({
20
+ this@NativePlatformListener.onConfigChange()
21
+ }, 10)
22
+ }
23
+ }
24
+
25
+ init {
26
+ reactContext.registerReceiver(configurationChangeReceiver, IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED))
27
+ }
28
+
29
+ fun invalidate() {
30
+ reactContext.unregisterReceiver(configurationChangeReceiver)
31
+ }
32
+
33
+ fun addPlatformListener(listener: CxxDependencyListener) {
34
+ this._dependencyListeners.add(listener)
35
+ }
36
+
37
+ fun removePlatformListeners() {
38
+ this._dependencyListeners.clear()
39
+ }
40
+
41
+ private fun emitCxxEvent(dependencies: Array<UnistyleDependency>) {
42
+ this._dependencyListeners.forEach { listener ->
43
+ listener(dependencies)
44
+ }
45
+ }
46
+
47
+ fun onConfigChange() {
48
+ val changedDependencies = diffMiniRuntime()
49
+
50
+ if (changedDependencies.isNotEmpty()) {
51
+ emitCxxEvent(changedDependencies)
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,51 @@
1
+ package com.unistyles
2
+
3
+ import com.facebook.fbreact.specs.NativeTurboUnistylesSpec
4
+ import com.facebook.jni.HybridData
5
+ import com.facebook.proguard.annotations.DoNotStrip
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.bridge.RuntimeExecutor
8
+ import com.facebook.react.fabric.FabricUIManager
9
+ import com.facebook.react.turbomodule.core.interfaces.BindingsInstallerHolder
10
+ import com.facebook.react.turbomodule.core.interfaces.TurboModuleWithJSIBindings
11
+ import com.facebook.react.uimanager.UIManagerHelper
12
+ import com.facebook.react.uimanager.common.UIManagerType
13
+ import com.margelo.nitro.unistyles.HybridNativePlatformSpec
14
+
15
+ @Suppress("KotlinJniMissingFunction")
16
+ class UnistylesModule(reactContext: ReactApplicationContext): NativeTurboUnistylesSpec(reactContext), TurboModuleWithJSIBindings {
17
+ @DoNotStrip
18
+ private var mHybridData: HybridData?
19
+ private val _nativePlatform = NativePlatformAndroid(reactContext)
20
+
21
+ companion object {
22
+ const val NAME = NativeTurboUnistylesSpec.NAME
23
+ }
24
+
25
+ init {
26
+ mHybridData = initializeHybridData(reactContext)
27
+ }
28
+
29
+ override fun invalidate() {
30
+ _nativePlatform.invalidate()
31
+ }
32
+
33
+ private fun initializeHybridData(reactContext: ReactApplicationContext): HybridData {
34
+ val runtimeExecutor = reactContext.catalystInstance?.runtimeExecutor
35
+ ?: throw IllegalStateException("Unistyles: React Native runtime executor is not available. Please follow installation guides.")
36
+ val fabricUIManager = UIManagerHelper.getUIManager(reactContext, UIManagerType.FABRIC) as? FabricUIManager
37
+ ?: throw IllegalStateException("Unistyles: Fabric UI Manager is not available. Please follow installation guides.")
38
+
39
+ return initHybrid(runtimeExecutor, fabricUIManager, _nativePlatform)
40
+ }
41
+
42
+ @DoNotStrip
43
+ external override fun getBindingsInstaller(): BindingsInstallerHolder
44
+
45
+ @DoNotStrip
46
+ private external fun initHybrid(
47
+ runtimeExecutor: RuntimeExecutor,
48
+ fabricUIManager: FabricUIManager,
49
+ nativePlatform: HybridNativePlatformSpec
50
+ ): HybridData
51
+ }
@@ -1,28 +1,30 @@
1
1
  package com.unistyles
2
2
 
3
- import android.util.Log
4
3
  import com.facebook.react.TurboReactPackage
5
4
  import com.facebook.react.bridge.NativeModule
6
5
  import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfo
7
7
  import com.facebook.react.module.model.ReactModuleInfoProvider
8
8
 
9
9
  class UnistylesPackage: TurboReactPackage() {
10
- companion object {
11
- private const val TAG: String = "Unistyles"
12
-
13
- init {
14
- try {
15
- System.loadLibrary("unistyles")
16
- Log.i(TAG, "Installed Unistyles \uD83E\uDD84!")
17
- } catch (e: Throwable) {
18
- Log.e(TAG, "Failed to load Unistyles C++ library! Is it properly linked?", e)
19
- throw e
20
- }
10
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
11
+ return if (name == UnistylesModule.NAME) {
12
+ UnistylesModule(reactContext)
13
+ } else {
14
+ null
21
15
  }
22
16
  }
23
17
 
24
- override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? = null
25
18
  override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
26
- return ReactModuleInfoProvider { emptyMap() }
19
+ return ReactModuleInfoProvider {
20
+ mapOf(UnistylesModule.NAME to ReactModuleInfo(
21
+ UnistylesModule.NAME,
22
+ UnistylesModule.NAME,
23
+ _canOverrideExistingModule = true,
24
+ _needsEagerInit = true,
25
+ isCxxModule = true,
26
+ isTurboModule = true
27
+ ))
28
+ }
27
29
  }
28
30
  }
@@ -0,0 +1,11 @@
1
+ #if __has_include("Unistyles-Swift-Cxx-Umbrella.hpp")
2
+ #include "Unistyles-Swift-Cxx-Umbrella.hpp"
3
+ #elif __has_include("JHybridNativePlatformSpec.hpp")
4
+ #include "JHybridNativePlatformSpec.hpp"
5
+
6
+ namespace Unistyles {
7
+ using HybridNativePlatformSpecCxx = margelo::nitro::unistyles::JHybridNativePlatformSpec;
8
+ }
9
+ #else
10
+ #error "Unistyles: Can't find platform specific header!"
11
+ #endif
@@ -3,7 +3,7 @@
3
3
  #include <jsi/jsi.h>
4
4
  #include <jsi/JSIDynamic.h>
5
5
  #include <folly/dynamic.h>
6
- #include "Unistyles-Swift-Cxx-Umbrella.hpp"
6
+ #include "NativePlatform.h"
7
7
  #include <unordered_set>
8
8
 
9
9
  using namespace facebook;
@@ -3,7 +3,7 @@
3
3
  #include "string"
4
4
  #include <jsi/jsi.h>
5
5
  #include <folly/dynamic.h>
6
- #include "Unistyles-Swift-Cxx-Umbrella.hpp"
6
+ #include "NativePlatform.h"
7
7
 
8
8
  namespace margelo::nitro::unistyles::core {
9
9
 
@@ -12,7 +12,7 @@ struct UnistyleData {
12
12
  : unistyle{unistyle}, variants(std::move(variants)), dynamicFunctionMetadata{std::move(arguments)} {}
13
13
 
14
14
  UnistyleData(const UnistyleData&) = delete;
15
- UnistyleData(UnistyleData&& other): unistyle{other.unistyle}, variants(std::move(other.variants)) {}
15
+ UnistyleData(UnistyleData&& other) = delete;
16
16
 
17
17
  core::Unistyle::Shared unistyle;
18
18
  core::Variants variants;
@@ -32,7 +32,6 @@ inline static Unistyle::Shared unistyleFromStaticStyleSheet(jsi::Runtime& rt, js
32
32
  return exoticUnistyle;
33
33
  }
34
34
 
35
-
36
35
  inline static std::vector<Unistyle::Shared> unistylesFromNonExistentNativeState(jsi::Runtime& rt, jsi::Object& value) {
37
36
  auto hasUnistyleName = value.hasProperty(rt, helpers::NAME_STYLE_KEY.c_str());
38
37
 
@@ -71,7 +70,7 @@ inline static jsi::Object generateUnistylesPrototype(
71
70
  auto hostFn = jsi::Function::createFromHostFunction(rt, jsi::PropNameID::forUtf8(rt, "getStyle"), 0, [unistyle, unistylesRuntime](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count){
72
71
  auto variants = helpers::variantsToPairs(rt, thisValue.asObject(rt).getProperty(rt, "variants").asObject(rt));
73
72
  auto arguments = helpers::parseDynamicFunctionArguments(rt, thisValue.asObject(rt).getProperty(rt, "arguments").asObject(rt).asArray(rt));
74
-
73
+
75
74
  parser::Parser(unistylesRuntime).rebuildUnistyle(rt, unistyle->parent, unistyle, variants, std::make_optional<std::vector<folly::dynamic>>(arguments));
76
75
 
77
76
  return jsi::Value(rt, unistyle->parsedStyle.value()).asObject(rt);
@@ -31,7 +31,7 @@ RootShadowNode::Unshared core::UnistylesCommitHook::shadowTreeWillCommit(
31
31
  auto& registry = core::UnistylesRegistry::get();
32
32
  auto& shadowLeafUpdates = registry.trafficController.getUpdates();
33
33
 
34
- // oops, not updates from Unistyles yet, skip it!
34
+ // oops, no updates from Unistyles yet, skip it!
35
35
  if (shadowLeafUpdates.size() == 0) {
36
36
  return newRootShadowNode;
37
37
  }
@@ -23,6 +23,6 @@ void core::UnistylesMountHook::shadowTreeDidMount(RootShadowNode::Shared const &
23
23
  auto& registry = core::UnistylesRegistry::get();
24
24
 
25
25
  if (!registry.trafficController.shouldStop()) {
26
- shadow::ShadowTreeManager::updateShadowTree(this->_unistylesRuntime->getRuntime());
26
+ shadow::ShadowTreeManager::updateShadowTree(this->_uiManager->getShadowTreeRegistry());
27
27
  }
28
28
  }
@@ -78,10 +78,6 @@ void core::UnistylesRegistry::linkShadowNodeWithUnistyle(
78
78
  auto parser = parser::Parser(nullptr);
79
79
  shadow::ShadowLeafUpdates updates;
80
80
 
81
- if (!this->_shadowRegistry[&rt].contains(shadowNodeFamily)) {
82
- this->_shadowRegistry[&rt][shadowNodeFamily] = {};
83
- }
84
-
85
81
  std::for_each(unistyles.begin(), unistyles.end(), [&, this](Unistyle::Shared unistyle){
86
82
  this->_shadowRegistry[&rt][shadowNodeFamily].emplace_back(std::make_shared<UnistyleData>(unistyle, variants, arguments));
87
83
 
@@ -104,16 +100,11 @@ void core::UnistylesRegistry::linkShadowNodeWithUnistyle(
104
100
 
105
101
  void core::UnistylesRegistry::unlinkShadowNodeWithUnistyles(jsi::Runtime& rt, const ShadowNodeFamily* shadowNodeFamily) {
106
102
  this->_shadowRegistry[&rt].erase(shadowNodeFamily);
107
- }
103
+ this->trafficController.removeShadowNode(shadowNodeFamily);
108
104
 
109
- core::Unistyle::Shared core::UnistylesRegistry::findUnistyleFromKey(jsi::Runtime& rt, std::string styleKey, int tag) {
110
- auto targetStyleSheet = this->_styleSheetRegistry[&rt][tag];
111
-
112
- if (targetStyleSheet == nullptr) {
113
- return nullptr;
105
+ if (this->_shadowRegistry[&rt].empty()) {
106
+ this->_shadowRegistry.erase(&rt);
114
107
  }
115
-
116
- return targetStyleSheet.get()->unistyles[styleKey];
117
108
  }
118
109
 
119
110
  std::shared_ptr<core::StyleSheet> core::UnistylesRegistry::addStyleSheet(jsi::Runtime& rt, int unid, core::StyleSheetType type, jsi::Object&& rawValue) {
@@ -162,7 +153,7 @@ void core::UnistylesRegistry::shadowLeafUpdateFromUnistyle(jsi::Runtime& rt, Uni
162
153
  for (const auto& [family, unistyles] : this->_shadowRegistry[&rt]) {
163
154
  for (const auto& unistyleData : unistyles) {
164
155
  if (unistyleData->unistyle == unistyle) {
165
- updates[family] = parser.parseStylesToShadowTreeStyles(rt, {unistyleData});
156
+ updates[family] = parser.parseStylesToShadowTreeStyles(rt, { unistyleData });
166
157
  }
167
158
  }
168
159
  }
@@ -41,7 +41,6 @@ struct UnistylesRegistry: public StyleSheetRegistry {
41
41
  void unlinkShadowNodeWithUnistyles(jsi::Runtime& rt, const ShadowNodeFamily*);
42
42
  std::shared_ptr<core::StyleSheet> addStyleSheet(jsi::Runtime& rt, int tag, core::StyleSheetType type, jsi::Object&& rawValue);
43
43
  DependencyMap buildDependencyMap(jsi::Runtime& rt, std::vector<UnistyleDependency>& deps);
44
- Unistyle::Shared findUnistyleFromKey(jsi::Runtime& rt, std::string styleKey, int tag);
45
44
  void shadowLeafUpdateFromUnistyle(jsi::Runtime& rt, Unistyle::Shared unistyle);
46
45
  shadow::ShadowTrafficController trafficController{};
47
46
 
@@ -50,10 +49,10 @@ private:
50
49
 
51
50
  std::unordered_map<jsi::Runtime*, UnistylesState> _states{};
52
51
  std::unordered_map<jsi::Runtime*, std::unordered_map<int, std::shared_ptr<core::StyleSheet>>> _styleSheetRegistry{};
53
- std::unordered_map<jsi::Runtime*, std::unordered_map<const ShadowNodeFamily*, std::vector<std::shared_ptr<UnistyleData>>>> _shadowRegistry{};
52
+ std::unordered_map<jsi::Runtime*, std::unordered_map<const ShadowNodeFamily*, std::vector<const std::shared_ptr<UnistyleData>>>> _shadowRegistry{};
54
53
  };
55
54
 
56
- UnistylesRegistry& UnistylesRegistry::get() {
55
+ inline UnistylesRegistry& UnistylesRegistry::get() {
57
56
  static UnistylesRegistry cache;
58
57
 
59
58
  return cache;
@@ -25,7 +25,7 @@ std::optional<std::string>& core::UnistylesState::getCurrentThemeName() {
25
25
 
26
26
  jsi::Object core::UnistylesState::getCurrentJSTheme() {
27
27
  auto hasSomeThemes = _registeredThemeNames.size() > 0;
28
-
28
+
29
29
  if (!hasSomeThemes && !this->hasUserConfig) {
30
30
  helpers::assertThat(*_rt, false, "Unistyles: One of your stylesheets is trying to get the theme, but no theme has been selected yet. Did you forget to call StyleSheet.configure? If you called it, make sure you did so before any StyleSheet.create.");
31
31
  }
@@ -99,15 +99,18 @@ int core::UnistylesState::parseColor(jsi::Value& maybeColor) {
99
99
  if (!maybeColor.isString()) {
100
100
  return 0;
101
101
  }
102
-
102
+
103
103
  auto colorString = maybeColor.asString(*_rt);
104
-
104
+
105
105
  if (!this->_colorCache.contains(colorString.utf8(*_rt).c_str())) {
106
- // we must convert it to uint32_t first, otherwise color will be broken
107
- uint32_t color = this->_processColorFn.get()->call(*_rt, colorString).asNumber();
108
-
106
+ #ifdef ANDROID
107
+ int color = this->_processColorFn.get()->call(*_rt, colorString).asNumber();
108
+ #else
109
+ uint32_t color = this->_processColorFn.get()->call(*_rt, colorString).asNumber();
110
+ #endif
111
+
109
112
  this->_colorCache[colorString.utf8(*_rt).c_str()] = color ? color : 0;
110
113
  }
111
-
114
+
112
115
  return this->_colorCache[colorString.utf8(*_rt).c_str()];
113
116
  }
@@ -1,19 +1,19 @@
1
1
  #pragma once
2
2
 
3
3
  #include "HybridUnistylesNavigationBarSpec.hpp"
4
- #include "Unistyles-Swift-Cxx-Umbrella.hpp"
4
+ #include "NativePlatform.h"
5
5
  #include <optional>
6
6
 
7
7
  using namespace margelo::nitro::unistyles;
8
8
 
9
9
  struct HybridNavigationBar: public HybridUnistylesNavigationBarSpec {
10
10
  HybridNavigationBar(Unistyles::HybridNativePlatformSpecCxx nativePlatform): HybridObject(TAG), _nativePlatform{nativePlatform} {}
11
-
11
+
12
12
  void setBackgroundColor(double color) override;
13
13
  void setHidden(bool isHidden) override;
14
14
  double getWidth() override;
15
15
  double getHeight() override;
16
-
16
+
17
17
  private:
18
18
  Unistyles::HybridNativePlatformSpecCxx _nativePlatform;
19
19
  };
@@ -1,19 +1,19 @@
1
1
  #pragma once
2
2
 
3
3
  #include "HybridUnistylesStatusBarSpec.hpp"
4
- #include "Unistyles-Swift-Cxx-Umbrella.hpp"
4
+ #include "NativePlatform.h"
5
5
  #include <optional>
6
6
 
7
7
  using namespace margelo::nitro::unistyles;
8
8
 
9
9
  struct HybridStatusBar: public HybridUnistylesStatusBarSpec {
10
10
  HybridStatusBar(Unistyles::HybridNativePlatformSpecCxx nativePlatform): HybridObject(TAG), _nativePlatform{nativePlatform} {}
11
-
11
+
12
12
  void setBackgroundColor(double color) override;
13
13
  double getWidth() override;
14
14
  double getHeight() override;
15
15
  void setHidden(bool isHidden) override;
16
-
16
+
17
17
  private:
18
18
  Unistyles::HybridNativePlatformSpecCxx _nativePlatform;
19
19
  };
@@ -15,7 +15,7 @@ double HybridStyleSheet::getUnid() {
15
15
 
16
16
  jsi::Value HybridStyleSheet::create(jsi::Runtime& rt, const jsi::Value &thisVal, const jsi::Value *arguments, size_t count) {
17
17
  if (count == 1) {
18
- helpers::assertThat(rt, count == 2, "Unistyles is not initialized correctly. Please add babel plugin to your babel config.");
18
+ helpers::assertThat(rt, false, "Unistyles is not initialized correctly. Please add babel plugin to your babel config.");
19
19
  }
20
20
 
21
21
  // second argument is hidden, so validation is perfectly fine
@@ -128,7 +128,7 @@ void HybridStyleSheet::parseSettings(jsi::Runtime &rt, jsi::Object settings) {
128
128
  void HybridStyleSheet::parseBreakpoints(jsi::Runtime &rt, jsi::Object breakpoints){
129
129
  helpers::Breakpoints sortedBreakpoints = helpers::jsiBreakpointsToVecPairs(rt, std::move(breakpoints));
130
130
 
131
- helpers::assertThat(rt, sortedBreakpoints.size() > 0, "StyleSheet.configure's breakpoints can't be empty.");
131
+ helpers::assertThat(rt, !sortedBreakpoints.empty(), "StyleSheet.configure's breakpoints can't be empty.");
132
132
  helpers::assertThat(rt, sortedBreakpoints.front().second == 0, "StyleSheet.configure's first breakpoint must start from 0.");
133
133
 
134
134
  auto& registry = core::UnistylesRegistry::get();
@@ -197,7 +197,7 @@ void HybridStyleSheet::verifyAndSelectTheme(jsi::Runtime &rt) {
197
197
 
198
198
  void HybridStyleSheet::setThemeFromColorScheme(jsi::Runtime& rt) {
199
199
  auto& state = core::UnistylesRegistry::get().getState(rt);
200
- ColorScheme colorScheme = static_cast<ColorScheme>(this->_unistylesRuntime->getColorScheme());
200
+ auto colorScheme = static_cast<ColorScheme>(this->_unistylesRuntime->getColorScheme());
201
201
 
202
202
  switch (colorScheme) {
203
203
  case ColorScheme::LIGHT:
@@ -232,7 +232,7 @@ void HybridStyleSheet::loadExternalMethods(const jsi::Value& thisValue, jsi::Run
232
232
  void HybridStyleSheet::registerHooks(jsi::Runtime& rt) {
233
233
  // cleanup Shadow updates
234
234
  core::UnistylesRegistry::get().trafficController.restore();
235
-
235
+
236
236
  this->_unistylesCommitHook = std::make_shared<core::UnistylesCommitHook>(this->_uiManager);
237
237
  this->_unistylesMountHook = std::make_shared<core::UnistylesMountHook>(this->_uiManager, this->_unistylesRuntime);
238
238
  }
@@ -248,20 +248,20 @@ void HybridStyleSheet::onPlatformDependenciesChange(std::vector<UnistyleDependen
248
248
  auto dependencies = std::move(unistylesDependencies);
249
249
 
250
250
  // re-compute new breakpoint
251
- auto dimensionsIt = std::find(dependencies.begin(), dependencies.end(), UnistyleDependency::DIMENSIONS);
251
+ auto dimensionsIt = std::find(unistylesDependencies.begin(), unistylesDependencies.end(), UnistyleDependency::DIMENSIONS);
252
252
 
253
- if (dimensionsIt != dependencies.end()) {
253
+ if (dimensionsIt != unistylesDependencies.end()) {
254
254
  registry.getState(rt).computeCurrentBreakpoint(this->_unistylesRuntime->getScreen().width);
255
255
  }
256
256
 
257
257
  // check if color scheme changed and then if Unistyles state depend on it (adaptive themes)
258
- auto colorSchemeIt = std::find(dependencies.begin(), dependencies.end(), UnistyleDependency::COLORSCHEME);
259
- auto hasNewColorScheme = colorSchemeIt != dependencies.end();
258
+ auto colorSchemeIt = std::find(unistylesDependencies.begin(), unistylesDependencies.end(), UnistyleDependency::COLORSCHEME);
259
+ auto hasNewColorScheme = colorSchemeIt != unistylesDependencies.end();
260
260
 
261
261
  // in a later step, we will rebuild only Unistyles with mounted StyleSheets
262
262
  // however, user may have StyleSheets with components that haven't mounted yet
263
263
  // we need to rebuild all dependent StyleSheets as well
264
- auto dependentStyleSheets = registry.getStyleSheetsToRefresh(rt, hasNewColorScheme, dependencies.size() > 1);
264
+ auto dependentStyleSheets = registry.getStyleSheetsToRefresh(rt, hasNewColorScheme, unistylesDependencies.size() > 1);
265
265
 
266
266
  if (hasNewColorScheme) {
267
267
  this->_unistylesRuntime->includeDependenciesForColorSchemeChange(dependencies);
@@ -269,17 +269,17 @@ void HybridStyleSheet::onPlatformDependenciesChange(std::vector<UnistyleDependen
269
269
 
270
270
  auto dependencyMap = registry.buildDependencyMap(rt, dependencies);
271
271
 
272
- if (dependencyMap.size() == 0) {
272
+ if (dependencyMap.empty()) {
273
273
  this->notifyJSListeners(dependencies);
274
274
 
275
275
  return;
276
276
  }
277
277
 
278
278
  parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets);
279
- parser.rebuildShadowLeafUpdates(dependencyMap);
280
-
279
+ parser.rebuildShadowLeafUpdates(rt, dependencyMap);
280
+
281
281
  this->notifyJSListeners(dependencies);
282
- shadow::ShadowTreeManager::updateShadowTree(rt);
282
+ shadow::ShadowTreeManager::updateShadowTree(UIManagerBinding::getBinding(rt)->getUIManager().getShadowTreeRegistry());
283
283
  });
284
284
  }
285
285
 
@@ -298,18 +298,21 @@ void HybridStyleSheet::onImeChange() {
298
298
 
299
299
  auto dependencyMap = registry.buildDependencyMap(rt, dependencies);
300
300
 
301
- if (dependencyMap.size() == 0) {
301
+ if (dependencyMap.empty()) {
302
302
  return;
303
303
  }
304
+
305
+ std::vector<std::shared_ptr<core::StyleSheet>> styleSheet;
306
+
307
+ parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, styleSheet);
308
+ parser.rebuildShadowLeafUpdates(rt, dependencyMap);
304
309
 
305
- parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, {});
306
- parser.rebuildShadowLeafUpdates(dependencyMap);
307
- shadow::ShadowTreeManager::updateShadowTree(rt);
310
+ shadow::ShadowTreeManager::updateShadowTree(UIManagerBinding::getBinding(rt)->getUIManager().getShadowTreeRegistry());
308
311
  });
309
312
  }
310
313
 
311
314
  void HybridStyleSheet::notifyJSListeners(std::vector<UnistyleDependency>& dependencies) {
312
- if (dependencies.size() > 0) {
315
+ if (!dependencies.empty()) {
313
316
  std::for_each(this->_changeListeners.begin(), this->_changeListeners.end(), [&](auto& listener){
314
317
  (*listener)(dependencies);
315
318
  });