react-native-unistyles 2.4.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/README.md +72 -26
  2. package/android/CMakeLists.txt +18 -2
  3. package/android/build.gradle +5 -1
  4. package/android/src/main/cxx/cpp-adapter.cpp +16 -80
  5. package/android/src/main/cxx/helpers.cpp +61 -0
  6. package/android/src/main/cxx/helpers.h +7 -0
  7. package/android/src/main/cxx/platform.cpp +170 -0
  8. package/android/src/main/cxx/platform.h +20 -0
  9. package/android/src/main/java/com/unistyles/Models.kt +12 -70
  10. package/android/src/main/java/com/unistyles/Platform.kt +311 -10
  11. package/android/src/main/java/com/unistyles/UnistylesModule.kt +145 -153
  12. package/cxx/Macros.h +11 -0
  13. package/cxx/UnistylesImpl.cpp +310 -0
  14. package/cxx/UnistylesModel.cpp +234 -0
  15. package/cxx/UnistylesModel.h +141 -0
  16. package/cxx/UnistylesRuntime.cpp +17 -356
  17. package/cxx/UnistylesRuntime.h +71 -87
  18. package/ios/UnistylesModule.h +13 -0
  19. package/ios/UnistylesModule.mm +20 -90
  20. package/ios/platform/Platform_Shared.h +8 -0
  21. package/ios/platform/Platform_Shared.mm +160 -0
  22. package/ios/platform/Platform_iOS.h +6 -10
  23. package/ios/platform/Platform_iOS.mm +143 -93
  24. package/ios/platform/Platform_macOS.h +3 -7
  25. package/ios/platform/Platform_macOS.mm +52 -34
  26. package/ios/platform/Platform_tvOS.h +17 -0
  27. package/ios/platform/Platform_tvOS.mm +96 -0
  28. package/ios/platform/Platform_visionOS.h +20 -0
  29. package/ios/platform/Platform_visionOS.mm +120 -0
  30. package/lib/commonjs/UnistylesProvider.js +32 -0
  31. package/lib/commonjs/UnistylesProvider.js.map +1 -0
  32. package/lib/commonjs/common.js +3 -2
  33. package/lib/commonjs/common.js.map +1 -1
  34. package/lib/commonjs/core/UnistyleRegistry.js +14 -4
  35. package/lib/commonjs/core/UnistyleRegistry.js.map +1 -1
  36. package/lib/commonjs/core/Unistyles.js +7 -0
  37. package/lib/commonjs/core/Unistyles.js.map +1 -1
  38. package/lib/commonjs/core/UnistylesModule.js +52 -8
  39. package/lib/commonjs/core/UnistylesModule.js.map +1 -1
  40. package/lib/commonjs/core/UnistylesModule.native.js.map +1 -1
  41. package/lib/commonjs/core/UnistylesModule.windows.js.map +1 -1
  42. package/lib/commonjs/core/UnistylesRuntime.js +114 -4
  43. package/lib/commonjs/core/UnistylesRuntime.js.map +1 -1
  44. package/lib/commonjs/core/index.js.map +1 -1
  45. package/lib/commonjs/core/mocks/UnistylesMockedBridge.js +36 -0
  46. package/lib/commonjs/core/mocks/UnistylesMockedBridge.js.map +1 -0
  47. package/lib/commonjs/core/mocks/UnistylesMockedRegistry.js +46 -0
  48. package/lib/commonjs/core/mocks/UnistylesMockedRegistry.js.map +1 -0
  49. package/lib/commonjs/core/mocks/UnistylesMockedRuntime.js +122 -0
  50. package/lib/commonjs/core/mocks/UnistylesMockedRuntime.js.map +1 -0
  51. package/lib/commonjs/core/mocks/index.js +27 -0
  52. package/lib/commonjs/core/mocks/index.js.map +1 -0
  53. package/lib/commonjs/createStyleSheet.js.map +1 -1
  54. package/lib/commonjs/global.js.map +1 -1
  55. package/lib/commonjs/hooks/index.js.map +1 -1
  56. package/lib/commonjs/hooks/useCSS.js.map +1 -1
  57. package/lib/commonjs/hooks/useCSS.native.js.map +1 -1
  58. package/lib/commonjs/hooks/useInitialTheme.js.map +1 -1
  59. package/lib/commonjs/hooks/useSharedContext.js +77 -0
  60. package/lib/commonjs/hooks/useSharedContext.js.map +1 -0
  61. package/lib/commonjs/hooks/useUnistyles.js +18 -65
  62. package/lib/commonjs/hooks/useUnistyles.js.map +1 -1
  63. package/lib/commonjs/hooks/useVariants.js.map +1 -1
  64. package/lib/commonjs/index.js +7 -0
  65. package/lib/commonjs/index.js.map +1 -1
  66. package/lib/commonjs/normalizer/index.js.map +1 -1
  67. package/lib/commonjs/normalizer/module.d.js.map +1 -1
  68. package/lib/commonjs/normalizer/normalizeStyle.js.map +1 -1
  69. package/lib/commonjs/normalizer/normalizer.js +1 -1
  70. package/lib/commonjs/normalizer/normalizer.js.map +1 -1
  71. package/lib/commonjs/normalizer/normalizer.macos.js.map +1 -1
  72. package/lib/commonjs/plugins/cssMediaQueriesPlugin.js.map +1 -1
  73. package/lib/commonjs/plugins/index.js.map +1 -1
  74. package/lib/commonjs/plugins/normalizeWebStylesPlugin.js.map +1 -1
  75. package/lib/commonjs/types/breakpoints.js.map +1 -1
  76. package/lib/commonjs/types/color.js +2 -0
  77. package/lib/commonjs/types/color.js.map +1 -0
  78. package/lib/commonjs/types/common.js.map +1 -1
  79. package/lib/commonjs/types/core.js.map +1 -1
  80. package/lib/commonjs/types/index.js +11 -0
  81. package/lib/commonjs/types/index.js.map +1 -1
  82. package/lib/commonjs/types/normalizer.js.map +1 -1
  83. package/lib/commonjs/types/plugin.js.map +1 -1
  84. package/lib/commonjs/types/stylesheet.js.map +1 -1
  85. package/lib/commonjs/types/unistyles.js.map +1 -1
  86. package/lib/commonjs/types/variants.js.map +1 -1
  87. package/lib/commonjs/useStyles.js +1 -1
  88. package/lib/commonjs/useStyles.js.map +1 -1
  89. package/lib/commonjs/utils/breakpoints.js.map +1 -1
  90. package/lib/commonjs/utils/cssMediaQuery.js.map +1 -1
  91. package/lib/commonjs/utils/generateId.js.map +1 -1
  92. package/lib/commonjs/utils/hash32.js.map +1 -1
  93. package/lib/commonjs/utils/index.js +7 -0
  94. package/lib/commonjs/utils/index.js.map +1 -1
  95. package/lib/commonjs/utils/mq.js.map +1 -1
  96. package/lib/commonjs/utils/mqParser.js.map +1 -1
  97. package/lib/commonjs/utils/parseColor.js +35 -0
  98. package/lib/commonjs/utils/parseColor.js.map +1 -0
  99. package/lib/commonjs/utils/styles.js +15 -1
  100. package/lib/commonjs/utils/styles.js.map +1 -1
  101. package/lib/commonjs/utils/withPlugins.js.map +1 -1
  102. package/lib/module/UnistylesProvider.js +24 -0
  103. package/lib/module/UnistylesProvider.js.map +1 -0
  104. package/lib/module/common.js +2 -1
  105. package/lib/module/common.js.map +1 -1
  106. package/lib/module/core/UnistyleRegistry.js +15 -5
  107. package/lib/module/core/UnistyleRegistry.js.map +1 -1
  108. package/lib/module/core/Unistyles.js +8 -1
  109. package/lib/module/core/Unistyles.js.map +1 -1
  110. package/lib/module/core/UnistylesModule.js +52 -8
  111. package/lib/module/core/UnistylesModule.js.map +1 -1
  112. package/lib/module/core/UnistylesModule.native.js.map +1 -1
  113. package/lib/module/core/UnistylesModule.windows.js.map +1 -1
  114. package/lib/module/core/UnistylesRuntime.js +115 -4
  115. package/lib/module/core/UnistylesRuntime.js.map +1 -1
  116. package/lib/module/core/index.js +2 -1
  117. package/lib/module/core/index.js.map +1 -1
  118. package/lib/module/core/mocks/UnistylesMockedBridge.js +29 -0
  119. package/lib/module/core/mocks/UnistylesMockedBridge.js.map +1 -0
  120. package/lib/module/core/mocks/UnistylesMockedRegistry.js +39 -0
  121. package/lib/module/core/mocks/UnistylesMockedRegistry.js.map +1 -0
  122. package/lib/module/core/mocks/UnistylesMockedRuntime.js +114 -0
  123. package/lib/module/core/mocks/UnistylesMockedRuntime.js.map +1 -0
  124. package/lib/module/core/mocks/index.js +4 -0
  125. package/lib/module/core/mocks/index.js.map +1 -0
  126. package/lib/module/createStyleSheet.js.map +1 -1
  127. package/lib/module/global.js.map +1 -1
  128. package/lib/module/hooks/index.js.map +1 -1
  129. package/lib/module/hooks/useCSS.js.map +1 -1
  130. package/lib/module/hooks/useCSS.native.js.map +1 -1
  131. package/lib/module/hooks/useInitialTheme.js.map +1 -1
  132. package/lib/module/hooks/useSharedContext.js +70 -0
  133. package/lib/module/hooks/useSharedContext.js.map +1 -0
  134. package/lib/module/hooks/useUnistyles.js +19 -66
  135. package/lib/module/hooks/useUnistyles.js.map +1 -1
  136. package/lib/module/hooks/useVariants.js.map +1 -1
  137. package/lib/module/index.js +2 -2
  138. package/lib/module/index.js.map +1 -1
  139. package/lib/module/normalizer/index.js.map +1 -1
  140. package/lib/module/normalizer/module.d.js.map +1 -1
  141. package/lib/module/normalizer/normalizeStyle.js.map +1 -1
  142. package/lib/module/normalizer/normalizer.js.map +1 -1
  143. package/lib/module/normalizer/normalizer.macos.js.map +1 -1
  144. package/lib/module/plugins/cssMediaQueriesPlugin.js.map +1 -1
  145. package/lib/module/plugins/index.js.map +1 -1
  146. package/lib/module/plugins/normalizeWebStylesPlugin.js.map +1 -1
  147. package/lib/module/types/breakpoints.js.map +1 -1
  148. package/lib/module/types/color.js +2 -0
  149. package/lib/module/types/color.js.map +1 -0
  150. package/lib/module/types/common.js.map +1 -1
  151. package/lib/module/types/core.js.map +1 -1
  152. package/lib/module/types/index.js +1 -0
  153. package/lib/module/types/index.js.map +1 -1
  154. package/lib/module/types/normalizer.js.map +1 -1
  155. package/lib/module/types/plugin.js.map +1 -1
  156. package/lib/module/types/stylesheet.js.map +1 -1
  157. package/lib/module/types/unistyles.js.map +1 -1
  158. package/lib/module/types/variants.js.map +1 -1
  159. package/lib/module/useStyles.js +1 -1
  160. package/lib/module/useStyles.js.map +1 -1
  161. package/lib/module/utils/breakpoints.js.map +1 -1
  162. package/lib/module/utils/cssMediaQuery.js.map +1 -1
  163. package/lib/module/utils/generateId.js.map +1 -1
  164. package/lib/module/utils/hash32.js.map +1 -1
  165. package/lib/module/utils/index.js +1 -0
  166. package/lib/module/utils/index.js.map +1 -1
  167. package/lib/module/utils/mq.js.map +1 -1
  168. package/lib/module/utils/mqParser.js.map +1 -1
  169. package/lib/module/utils/parseColor.js +28 -0
  170. package/lib/module/utils/parseColor.js.map +1 -0
  171. package/lib/module/utils/styles.js +15 -1
  172. package/lib/module/utils/styles.js.map +1 -1
  173. package/lib/module/utils/withPlugins.js.map +1 -1
  174. package/lib/typescript/src/UnistylesProvider.d.ts +20 -0
  175. package/lib/typescript/src/UnistylesProvider.d.ts.map +1 -0
  176. package/lib/typescript/src/common.d.ts +3 -2
  177. package/lib/typescript/src/common.d.ts.map +1 -1
  178. package/lib/typescript/src/core/UnistyleRegistry.d.ts.map +1 -1
  179. package/lib/typescript/src/core/Unistyles.d.ts.map +1 -1
  180. package/lib/typescript/src/core/UnistylesModule.d.ts +1 -0
  181. package/lib/typescript/src/core/UnistylesModule.d.ts.map +1 -1
  182. package/lib/typescript/src/core/UnistylesModule.native.d.ts.map +1 -1
  183. package/lib/typescript/src/core/UnistylesModule.windows.d.ts.map +1 -1
  184. package/lib/typescript/src/core/UnistylesRuntime.d.ts +84 -8
  185. package/lib/typescript/src/core/UnistylesRuntime.d.ts.map +1 -1
  186. package/lib/typescript/src/core/index.d.ts +3 -1
  187. package/lib/typescript/src/core/index.d.ts.map +1 -1
  188. package/lib/typescript/src/core/mocks/UnistylesMockedBridge.d.ts +28 -0
  189. package/lib/typescript/src/core/mocks/UnistylesMockedBridge.d.ts.map +1 -0
  190. package/lib/typescript/src/core/mocks/UnistylesMockedRegistry.d.ts +21 -0
  191. package/lib/typescript/src/core/mocks/UnistylesMockedRegistry.d.ts.map +1 -0
  192. package/lib/typescript/src/core/mocks/UnistylesMockedRuntime.d.ts +79 -0
  193. package/lib/typescript/src/core/mocks/UnistylesMockedRuntime.d.ts.map +1 -0
  194. package/lib/typescript/src/core/mocks/index.d.ts +4 -0
  195. package/lib/typescript/src/core/mocks/index.d.ts.map +1 -0
  196. package/lib/typescript/src/createStyleSheet.d.ts.map +1 -1
  197. package/lib/typescript/src/hooks/useCSS.d.ts.map +1 -1
  198. package/lib/typescript/src/hooks/useCSS.native.d.ts.map +1 -1
  199. package/lib/typescript/src/hooks/useSharedContext.d.ts +33 -0
  200. package/lib/typescript/src/hooks/useSharedContext.d.ts.map +1 -0
  201. package/lib/typescript/src/hooks/useUnistyles.d.ts +4 -19
  202. package/lib/typescript/src/hooks/useUnistyles.d.ts.map +1 -1
  203. package/lib/typescript/src/hooks/useVariants.d.ts.map +1 -1
  204. package/lib/typescript/src/index.d.ts +7 -15
  205. package/lib/typescript/src/index.d.ts.map +1 -1
  206. package/lib/typescript/src/normalizer/normalizeStyle.d.ts.map +1 -1
  207. package/lib/typescript/src/types/breakpoints.d.ts +9 -8
  208. package/lib/typescript/src/types/breakpoints.d.ts.map +1 -1
  209. package/lib/typescript/src/types/color.d.ts +4 -0
  210. package/lib/typescript/src/types/color.d.ts.map +1 -0
  211. package/lib/typescript/src/types/core.d.ts +2 -2
  212. package/lib/typescript/src/types/core.d.ts.map +1 -1
  213. package/lib/typescript/src/types/index.d.ts +2 -1
  214. package/lib/typescript/src/types/index.d.ts.map +1 -1
  215. package/lib/typescript/src/types/normalizer.d.ts +1 -1
  216. package/lib/typescript/src/types/normalizer.d.ts.map +1 -1
  217. package/lib/typescript/src/types/stylesheet.d.ts +9 -6
  218. package/lib/typescript/src/types/stylesheet.d.ts.map +1 -1
  219. package/lib/typescript/src/types/unistyles.d.ts +20 -9
  220. package/lib/typescript/src/types/unistyles.d.ts.map +1 -1
  221. package/lib/typescript/src/useStyles.d.ts +1 -1
  222. package/lib/typescript/src/useStyles.d.ts.map +1 -1
  223. package/lib/typescript/src/utils/breakpoints.d.ts.map +1 -1
  224. package/lib/typescript/src/utils/index.d.ts +1 -0
  225. package/lib/typescript/src/utils/index.d.ts.map +1 -1
  226. package/lib/typescript/src/utils/mqParser.d.ts.map +1 -1
  227. package/lib/typescript/src/utils/parseColor.d.ts +3 -0
  228. package/lib/typescript/src/utils/parseColor.d.ts.map +1 -0
  229. package/lib/typescript/src/utils/styles.d.ts.map +1 -1
  230. package/package.json +38 -25
  231. package/react-native-unistyles.podspec +4 -1
  232. package/src/UnistylesProvider.tsx +33 -0
  233. package/src/common.ts +3 -2
  234. package/src/core/UnistyleRegistry.ts +19 -5
  235. package/src/core/Unistyles.ts +10 -1
  236. package/src/core/UnistylesModule.ts +61 -14
  237. package/src/core/UnistylesRuntime.ts +120 -5
  238. package/src/core/index.ts +7 -1
  239. package/src/core/mocks/UnistylesMockedBridge.ts +30 -0
  240. package/src/core/mocks/UnistylesMockedRegistry.ts +47 -0
  241. package/src/core/mocks/UnistylesMockedRuntime.ts +144 -0
  242. package/src/core/mocks/index.ts +3 -0
  243. package/src/hooks/useSharedContext.ts +83 -0
  244. package/src/hooks/useUnistyles.ts +15 -71
  245. package/src/index.ts +10 -4
  246. package/src/types/breakpoints.ts +19 -9
  247. package/src/types/color.ts +26 -0
  248. package/src/types/core.ts +2 -2
  249. package/src/types/index.ts +5 -1
  250. package/src/types/normalizer.ts +1 -1
  251. package/src/types/stylesheet.ts +10 -7
  252. package/src/types/unistyles.ts +28 -12
  253. package/src/useStyles.ts +1 -1
  254. package/src/utils/index.ts +1 -0
  255. package/src/utils/parseColor.ts +33 -0
  256. package/src/utils/styles.ts +24 -1
  257. package/windows/ExperimentalFeatures.props +4 -4
  258. package/windows/NuGet.Config +0 -1
  259. package/windows/ReactNativeUnistyles/ReactNativeUnistyles.h +42 -118
  260. package/windows/ReactNativeUnistyles/ReactNativeUnistyles.vcxproj +7 -2
  261. package/windows/ReactNativeUnistyles/ReactNativeUnistyles.vcxproj.filters +6 -1
  262. package/windows/ReactNativeUnistyles/packages.lock.json +31 -31
  263. package/android/src/main/java/com/unistyles/Config.kt +0 -116
  264. package/android/src/main/java/com/unistyles/Insets.kt +0 -138
  265. package/ios/UnistylesHelpers.h +0 -3
  266. package/ios/UnistylesHelpers.mm +0 -5
@@ -0,0 +1,310 @@
1
+ #include "UnistylesRuntime.h"
2
+ #include <jsi/jsi.h>
3
+
4
+ using namespace facebook;
5
+
6
+ jsi::Value UnistylesRuntime::getScreenWidth(jsi::Runtime& rt, std::string fnName) {
7
+ return jsi::Value(this->screen.width);
8
+ }
9
+
10
+ jsi::Value UnistylesRuntime::getScreenHeight(jsi::Runtime& rt, std::string fnName) {
11
+ return jsi::Value(this->screen.height);
12
+ }
13
+
14
+ jsi::Value UnistylesRuntime::getContentSizeCategory(jsi::Runtime & rt, std::string fnName) {
15
+ return jsi::Value(jsi::String::createFromUtf8(rt, this->contentSizeCategory));
16
+ }
17
+
18
+ jsi::Value UnistylesRuntime::hasEnabledAdaptiveThemes(jsi::Runtime& rt, std::string fnName) {
19
+ return jsi::Value(this->hasAdaptiveThemes);
20
+ }
21
+
22
+ jsi::Value UnistylesRuntime::getThemeName(jsi::Runtime& rt, std::string fnName) {
23
+ return !this->themeName.empty()
24
+ ? jsi::Value(jsi::String::createFromUtf8(rt, this->themeName))
25
+ : this->getThemeOrFail(rt);
26
+ }
27
+
28
+ jsi::Value UnistylesRuntime::getCurrentBreakpoint(jsi::Runtime& rt, std::string fnName) {
29
+ return !this->breakpoint.empty()
30
+ ? jsi::Value(jsi::String::createFromUtf8(rt, this->breakpoint))
31
+ : jsi::Value::undefined();
32
+ }
33
+
34
+ jsi::Value UnistylesRuntime::getColorScheme(jsi::Runtime& rt, std::string fnName) {
35
+ return jsi::Value(jsi::String::createFromUtf8(rt, this->colorScheme));
36
+ }
37
+
38
+ jsi::Value UnistylesRuntime::getSortedBreakpointPairs(jsi::Runtime& rt, std::string fnName) {
39
+ std::unique_ptr<jsi::Array> sortedBreakpointEntriesArray = std::make_unique<jsi::Array>(rt, this->sortedBreakpointPairs.size());
40
+
41
+ for (size_t i = 0; i < this->sortedBreakpointPairs.size(); ++i) {
42
+ std::unique_ptr<jsi::Array> pairArray = std::make_unique<jsi::Array>(rt, 2);
43
+ jsi::String nameValue = jsi::String::createFromUtf8(rt, this->sortedBreakpointPairs[i].first);
44
+
45
+ pairArray->setValueAtIndex(rt, 0, nameValue);
46
+ pairArray->setValueAtIndex(rt, 1, jsi::Value(this->sortedBreakpointPairs[i].second));
47
+ sortedBreakpointEntriesArray->setValueAtIndex(rt, i, *pairArray);
48
+ }
49
+
50
+ return jsi::Value(rt, *sortedBreakpointEntriesArray);
51
+ }
52
+
53
+ jsi::Value UnistylesRuntime::setBreakpoints(jsi::Runtime& rt, std::string fnName) {
54
+ return HOST_FN(fnName, 1, {
55
+ jsi::Object breakpointsObj = arguments[0].asObject(rt);
56
+ auto sortedBreakpoints = this->toSortedBreakpointPairs(rt, breakpointsObj);
57
+
58
+ if (sortedBreakpoints.size() == 0) {
59
+ throw jsi::JSError(rt, UnistylesErrorBreakpointsCannotBeEmpty);
60
+ }
61
+
62
+ if (sortedBreakpoints.at(0).second != 0) {
63
+ throw jsi::JSError(rt, UnistylesErrorBreakpointsMustStartFromZero);
64
+ }
65
+
66
+ this->sortedBreakpointPairs = sortedBreakpoints;
67
+
68
+ std::string breakpoint = this->getBreakpointFromScreenWidth(this->screen.width, sortedBreakpoints);
69
+
70
+ this->breakpoint = breakpoint;
71
+
72
+ return jsi::Value::undefined();
73
+ });
74
+ }
75
+
76
+ jsi::Value UnistylesRuntime::setActiveTheme(jsi::Runtime& rt, std::string fnName) {
77
+ return HOST_FN(fnName, 1, {
78
+ std::string themeName = arguments[0].asString(rt).utf8(rt);
79
+
80
+ if (this->themeName != themeName) {
81
+ this->themeName = themeName;
82
+ this->onThemeChange(themeName);
83
+ }
84
+
85
+ return jsi::Value::undefined();
86
+ });
87
+ }
88
+
89
+ jsi::Value UnistylesRuntime::updateTheme(jsi::Runtime& rt, std::string fnName) {
90
+ return HOST_FN(fnName, 1, {
91
+ std::string themeName = arguments[0].asString(rt).utf8(rt);
92
+
93
+ if (this->themeName == themeName) {
94
+ this->onThemeChange(themeName);
95
+ }
96
+
97
+ return jsi::Value::undefined();
98
+ });
99
+ }
100
+
101
+ jsi::Value UnistylesRuntime::useAdaptiveThemes(jsi::Runtime& rt, std::string fnName) {
102
+ return HOST_FN(fnName, 1, {
103
+ bool enableAdaptiveThemes = arguments[0].asBool();
104
+
105
+ if (enableAdaptiveThemes && this->colorScheme == UnistylesUnspecifiedScheme) {
106
+ throw jsi::JSError(rt, UnistylesErrorAdaptiveThemesNotSupported);
107
+ }
108
+
109
+ this->hasAdaptiveThemes = enableAdaptiveThemes;
110
+
111
+ if (!enableAdaptiveThemes || !this->supportsAutomaticColorScheme) {
112
+ return jsi::Value::undefined();
113
+ }
114
+
115
+ if (this->themeName != this->colorScheme) {
116
+ this->themeName = this->colorScheme;
117
+ this->onThemeChange(this->themeName);
118
+ }
119
+
120
+ return jsi::Value::undefined();
121
+ });
122
+ }
123
+
124
+ jsi::Value UnistylesRuntime::addPlugin(jsi::Runtime& rt, std::string fnName) {
125
+ return HOST_FN(fnName, 1, {
126
+ std::string pluginName = arguments[0].asString(rt).utf8(rt);
127
+ bool notify = arguments[1].asBool();
128
+
129
+ this->pluginNames.push_back(pluginName);
130
+
131
+ // registry enabled plugins won't notify listeners
132
+ if (notify) {
133
+ this->onPluginChange();
134
+ }
135
+
136
+ return jsi::Value::undefined();
137
+ });
138
+ }
139
+
140
+ jsi::Value UnistylesRuntime::removePlugin(jsi::Runtime& rt, std::string fnName) {
141
+ return HOST_FN(fnName, 1, {
142
+ std::string pluginName = arguments[0].asString(rt).utf8(rt);
143
+
144
+ auto it = std::find(this->pluginNames.begin(), this->pluginNames.end(), pluginName);
145
+
146
+ if (it != this->pluginNames.end()) {
147
+ this->pluginNames.erase(it);
148
+ this->onPluginChange();
149
+ }
150
+
151
+ return jsi::Value::undefined();
152
+ });
153
+ }
154
+
155
+ jsi::Value UnistylesRuntime::getEnabledPlugins(jsi::Runtime& rt, std::string fnName) {
156
+ auto jsiArray = facebook::jsi::Array(rt, this->pluginNames.size());
157
+
158
+ for (size_t i = 0; i < this->pluginNames.size(); i++) {
159
+ jsiArray.setValueAtIndex(rt, i, facebook::jsi::String::createFromUtf8(rt, this->pluginNames[i]));
160
+ }
161
+
162
+ return jsiArray;
163
+ }
164
+
165
+ jsi::Value UnistylesRuntime::getInsets(jsi::Runtime& rt, std::string fnName) {
166
+ auto insets = jsi::Object(rt);
167
+
168
+ insets.setProperty(rt, "top", this->insets.top);
169
+ insets.setProperty(rt, "bottom", this->insets.bottom);
170
+ insets.setProperty(rt, "left", this->insets.left);
171
+ insets.setProperty(rt, "right", this->insets.right);
172
+
173
+ return insets;
174
+ }
175
+
176
+ jsi::Value UnistylesRuntime::getStatusBar(jsi::Runtime& rt, std::string fnName) {
177
+ auto statusBar = jsi::Object(rt);
178
+ auto setStatusBarColorFunction = HOST_FN("setColor", 1, {
179
+ std::string color = arguments[0].asString(rt).utf8(rt);
180
+ float alpha = arguments[1].asNumber();
181
+
182
+ if (this->setStatusBarColor.has_value()) {
183
+ this->setStatusBarColor.value()(color, alpha);
184
+ }
185
+
186
+ return jsi::Value::undefined();
187
+ });
188
+ auto setStatusBarHiddenFunction = HOST_FN("setHidden", 1, {
189
+ bool hidden = arguments[0].asBool();
190
+
191
+ if (this->setStatusBarHidden.has_value()) {
192
+ this->setStatusBarHidden.value()(hidden);
193
+ }
194
+
195
+ return jsi::Value::undefined();
196
+ });
197
+
198
+ statusBar.setProperty(rt, "width", this->statusBar.width);
199
+ statusBar.setProperty(rt, "height", this->statusBar.height);
200
+ statusBar.setProperty(rt, "setColor", setStatusBarColorFunction);
201
+ statusBar.setProperty(rt, "setHidden", setStatusBarHiddenFunction);
202
+
203
+ return statusBar;
204
+ }
205
+
206
+ jsi::Value UnistylesRuntime::getNavigationBar(jsi::Runtime& rt, std::string fnName) {
207
+ auto navigationBarValue = jsi::Object(rt);
208
+ auto setNavigationBarColorFunction = HOST_FN("setColor", 1, {
209
+ std::string color = arguments[0].asString(rt).utf8(rt);
210
+ float alpha = arguments[1].asNumber();
211
+
212
+ if (this->setNavigationBarColor.has_value()) {
213
+ this->setNavigationBarColor.value()(color, alpha);
214
+ }
215
+
216
+ return jsi::Value::undefined();
217
+ });
218
+ auto setHiddenFunction = HOST_FN("setHidden", 1, {
219
+ bool hidden = arguments[0].asBool();
220
+
221
+ if (this->setNavigationBarHidden.has_value()) {
222
+ this->setNavigationBarHidden.value()(hidden);
223
+ }
224
+
225
+ return jsi::Value::undefined();
226
+ });
227
+
228
+ navigationBarValue.setProperty(rt, "width", this->navigationBar.width);
229
+ navigationBarValue.setProperty(rt, "height", this->navigationBar.height);
230
+ navigationBarValue.setProperty(rt, "setColor", setNavigationBarColorFunction);
231
+ navigationBarValue.setProperty(rt, "setHidden", setHiddenFunction);
232
+
233
+ return navigationBarValue;
234
+ }
235
+
236
+ jsi::Value UnistylesRuntime::getPixelRatio(jsi::Runtime& rt, std::string fnName) {
237
+ return jsi::Value(static_cast<double>(roundf(this->pixelRatio * 100)/ 100));
238
+ }
239
+
240
+ jsi::Value UnistylesRuntime::getFontScale(jsi::Runtime& rt, std::string fnName) {
241
+ return jsi::Value(static_cast<double>(roundf(this->fontScale * 100) / 100));
242
+ }
243
+
244
+ std::optional<jsi::Value> UnistylesRuntime::setThemes(jsi::Runtime& rt, const jsi::Value& value) {
245
+ jsi::Array themes = value.asObject(rt).asArray(rt);
246
+ std::vector<std::string> themesVector;
247
+ size_t length = themes.size(rt);
248
+
249
+ for (size_t i = 0; i < length; ++i) {
250
+ jsi::Value element = themes.getValueAtIndex(rt, i);
251
+
252
+ if (element.isString()) {
253
+ std::string theme = element.asString(rt).utf8(rt);
254
+ themesVector.push_back(theme);
255
+ }
256
+ }
257
+
258
+ if (themesVector.size() == 0) {
259
+ throw jsi::JSError(rt, UnistylesErrorThemesCannotBeEmpty);
260
+ }
261
+
262
+ this->themes = themesVector;
263
+ this->themeName = "";
264
+
265
+ bool hasLightTheme = std::find(themesVector.begin(), themesVector.end(), "light") != themesVector.end();
266
+ bool hasDarkTheme = std::find(themesVector.begin(), themesVector.end(), "dark") != themesVector.end();
267
+
268
+ this->supportsAutomaticColorScheme = hasLightTheme && hasDarkTheme;
269
+
270
+ return std::nullopt;
271
+ }
272
+
273
+ jsi::Value UnistylesRuntime::setImmersiveModeEnabled(jsi::Runtime& rt, std::string fnName) {
274
+ return HOST_FN(fnName, 1, {
275
+ bool enabled = arguments[0].asBool();
276
+
277
+ if (this->setImmersiveMode.has_value()) {
278
+ this->setImmersiveMode.value()(enabled);
279
+ }
280
+
281
+ return jsi::Value::undefined();
282
+ });
283
+ }
284
+
285
+ jsi::Value UnistylesRuntime::setRootBackgroundColor(jsi::Runtime& rt, std::string fnName) {
286
+ return HOST_FN(fnName, 1, {
287
+ std::string color = arguments[0].asString(rt).utf8(rt);
288
+ float alpha = arguments[1].asNumber();
289
+
290
+ if (this->setRootViewBackgroundColor.has_value()) {
291
+ this->setRootViewBackgroundColor.value()(color, alpha);
292
+ }
293
+
294
+ return jsi::Value::undefined();
295
+ });
296
+ }
297
+
298
+ jsi::Value UnistylesRuntime::getIsRtl(jsi::Runtime& rt, std::string fnName) {
299
+ return jsi::Value(this->rtl);
300
+ }
301
+
302
+ jsi::Value UnistylesRuntime::disableAnimatedInsets(jsi::Runtime& rt, std::string fnName) {
303
+ return HOST_FN(fnName, 1, {
304
+ if (this->disableAnimatedInsetsAndroid.has_value()) {
305
+ this->disableAnimatedInsetsAndroid.value()();
306
+ }
307
+
308
+ return jsi::Value::undefined();
309
+ });
310
+ }
@@ -0,0 +1,234 @@
1
+ #include "UnistylesModel.h"
2
+
3
+ std::string UnistylesModel::getBreakpointFromScreenWidth(int width, const std::vector<std::pair<std::string, double>>& sortedBreakpointPairs) {
4
+ for (size_t i = 0; i < sortedBreakpointPairs.size(); ++i) {
5
+ const auto& [key, value] = sortedBreakpointPairs[i];
6
+ const double maxVal = (i + 1 < sortedBreakpointPairs.size()) ? sortedBreakpointPairs[i + 1].second : std::numeric_limits<double>::infinity();
7
+
8
+ if (width >= value && width < maxVal) {
9
+ return key;
10
+ }
11
+ }
12
+
13
+ return sortedBreakpointPairs.empty() ? "" : sortedBreakpointPairs.back().first;
14
+ }
15
+
16
+ void UnistylesModel::handleScreenSizeChange(Screen& screen, std::optional<Insets> insets, std::optional<Dimensions> statusBar, std::optional<Dimensions> navigationBar) {
17
+ std::string breakpoint = this->getBreakpointFromScreenWidth(screen.width, this->sortedBreakpointPairs);
18
+ bool hasDifferentBreakpoint = this->breakpoint != breakpoint;
19
+ bool hasDifferentScreenDimensions = this->screen.width != screen.width || this->screen.height != screen.height;
20
+ bool hasDifferentPixelRatio = this->pixelRatio != screen.pixelRatio;
21
+ bool hasDifferentFontScale = this->fontScale != screen.fontScale;
22
+ bool hasDifferentInsets = insets.has_value()
23
+ ? this->insets.top != insets->top || this->insets.bottom != insets->bottom || this->insets.left != insets->left || this->insets.right != insets->right
24
+ : false;
25
+
26
+ // we don't need to check statusBar/navigationBar as they will only change on orientation change witch is equal to hasDifferentScreenDimensions
27
+ bool shouldNotify = hasDifferentBreakpoint || hasDifferentScreenDimensions || hasDifferentInsets || hasDifferentPixelRatio || hasDifferentFontScale;
28
+
29
+ this->breakpoint = breakpoint;
30
+ this->screen = {screen.width, screen.height};
31
+ this->pixelRatio = screen.pixelRatio;
32
+ this->fontScale = screen.fontScale;
33
+
34
+ if (insets.has_value()) {
35
+ this->insets = {insets->top, insets->bottom, insets->left, insets->right};
36
+ }
37
+
38
+ if (statusBar.has_value()) {
39
+ this->statusBar = {statusBar->width, statusBar->height};
40
+ }
41
+
42
+ if (navigationBar.has_value()) {
43
+ this->navigationBar = {navigationBar->width, navigationBar->height};
44
+ }
45
+
46
+ if (shouldNotify) {
47
+ this->onLayoutChange();
48
+ }
49
+ }
50
+
51
+ void UnistylesModel::handleAppearanceChange(std::string colorScheme) {
52
+ this->colorScheme = colorScheme;
53
+
54
+ if (!this->supportsAutomaticColorScheme || !this->hasAdaptiveThemes) {
55
+ return;
56
+ }
57
+
58
+ if (this->themeName != this->colorScheme) {
59
+ this->onThemeChange(this->colorScheme);
60
+ this->themeName = this->colorScheme;
61
+ }
62
+ }
63
+
64
+ void UnistylesModel::handleContentSizeCategoryChange(std::string contentSizeCategory) {
65
+ if (this->contentSizeCategory == contentSizeCategory) {
66
+ return;
67
+ }
68
+
69
+ this->contentSizeCategory = contentSizeCategory;
70
+ }
71
+
72
+ jsi::Value UnistylesModel::getThemeOrFail(jsi::Runtime& runtime) {
73
+ if (this->themes.size() == 1) {
74
+ std::string themeName = this->themes.at(0);
75
+
76
+ this->themeName = themeName;
77
+
78
+ return jsi::String::createFromUtf8(runtime, themeName);
79
+ }
80
+
81
+ return jsi::Value().undefined();
82
+ }
83
+
84
+ std::vector<std::pair<std::string, double>> UnistylesModel::toSortedBreakpointPairs(jsi::Runtime& rt, jsi::Object& breakpointsObj) {
85
+ jsi::Array propertyNames = breakpointsObj.getPropertyNames(rt);
86
+ std::vector<std::pair<std::string, double>> sortedBreakpointEntriesVec;
87
+
88
+ for (size_t i = 0; i < propertyNames.size(rt); ++i) {
89
+ jsi::Value propNameValue = propertyNames.getValueAtIndex(rt, i);
90
+ std::string name = propNameValue.asString(rt).utf8(rt);
91
+ jsi::PropNameID propNameID = jsi::PropNameID::forUtf8(rt, name);
92
+ jsi::Value value = breakpointsObj.getProperty(rt, propNameID);
93
+
94
+ if (value.isNumber()) {
95
+ double breakpointValue = value.asNumber();
96
+
97
+ sortedBreakpointEntriesVec.push_back(std::make_pair(name, breakpointValue));
98
+ }
99
+ }
100
+
101
+ std::sort(sortedBreakpointEntriesVec.begin(), sortedBreakpointEntriesVec.end(), [](const std::pair<std::string, double>& a, const std::pair<std::string, double>& b) {
102
+ return a.second < b.second;
103
+ });
104
+
105
+ return sortedBreakpointEntriesVec;
106
+ }
107
+
108
+ // a little bit hacky, but works like Turbo Module emitDeviceEvent
109
+ // it will be super easy to refactor for Unistyles 3.0
110
+ // ref: https://github.com/facebook/react-native/pull/43375
111
+ // ref: https://github.com/facebook/react-native/blob/b5fd041917d197f256433a41a126f0dff767c429/packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModule.cpp#L42
112
+ void UnistylesModel::emitDeviceEvent(const std::string eventType, EventPayload payload) {
113
+ this->runOnJSThread([this, &eventType, payload = std::move(payload)](jsi::Runtime& rt){
114
+ jsi::Value emitter = rt.global().getProperty(rt, "__rctDeviceEventEmitter");
115
+
116
+ if (emitter.isUndefined()) {
117
+ return;
118
+ }
119
+
120
+ jsi::Object emitterObject = emitter.asObject(rt);
121
+ jsi::Function emitFunction = emitterObject.getPropertyAsFunction(rt, "emit");
122
+
123
+ std::vector<jsi::Value> arguments;
124
+ jsi::Object event = jsi::Object(rt);
125
+ jsi::Object eventPayload = this->parseEventPayload(rt, payload);
126
+
127
+ event.setProperty(rt, "type", jsi::String::createFromUtf8(rt, std::move(eventType)));
128
+ event.setProperty(rt, "payload", std::move(eventPayload));
129
+
130
+ arguments.emplace_back(jsi::String::createFromAscii(rt, "__unistylesOnChange"));
131
+ arguments.emplace_back(std::move(event));
132
+
133
+ emitFunction.callWithThis(rt, emitterObject, (const jsi::Value*)arguments.data(), arguments.size());
134
+ });
135
+ }
136
+
137
+ void UnistylesModel::onThemeChange(std::string themeName) {
138
+ EventPayload payload;
139
+ payload["themeName"] = themeName;
140
+
141
+ this->emitDeviceEvent("theme", payload);
142
+ }
143
+
144
+ void UnistylesModel::onPluginChange() {
145
+ this->emitDeviceEvent("plugin", {});
146
+ }
147
+
148
+ void UnistylesModel::onLayoutChange() {
149
+ EventPayload payload;
150
+ std::string orientation = screen.width > screen.height
151
+ ? UnistylesOrientationLandscape
152
+ : UnistylesOrientationPortrait;
153
+
154
+ payload["breakpoint"] = this->breakpoint;
155
+ payload["orientation"] = orientation;
156
+
157
+ EventNestedValue screenPayload;
158
+ auto screen = this->screen;
159
+
160
+ screenPayload["width"] = screen.width;
161
+ screenPayload["height"] = screen.height;
162
+
163
+ payload["screen"] = screenPayload;
164
+
165
+ EventNestedValue statusBarPayload;
166
+ auto statusBar = this->statusBar;
167
+
168
+ statusBarPayload["width"] = statusBar.width;
169
+ statusBarPayload["height"] = statusBar.height;
170
+
171
+ payload["statusBar"] = statusBarPayload;
172
+
173
+ EventNestedValue navigationBarPayload;
174
+ auto navigationBar = this->navigationBar;
175
+
176
+ navigationBarPayload["width"] = navigationBar.width;
177
+ navigationBarPayload["height"] = navigationBar.height;
178
+
179
+ payload["navigationBar"] = navigationBarPayload;
180
+
181
+ EventNestedValue insetsPayload;
182
+ auto insets = this->insets;
183
+
184
+ insetsPayload["top"] = insets.top;
185
+ insetsPayload["bottom"] = insets.bottom;
186
+ insetsPayload["left"] = insets.left;
187
+ insetsPayload["right"] = insets.right;
188
+
189
+ payload["insets"] = insetsPayload;
190
+
191
+ this->emitDeviceEvent("layout", payload);
192
+ }
193
+
194
+ jsi::Object UnistylesModel::parseEventPayload(jsi::Runtime& rt, const EventPayload& payload) {
195
+ jsi::Object eventPayload = jsi::Object(rt);
196
+
197
+ for (const auto& [key, value] : payload) {
198
+ if (std::holds_alternative<std::string>(value)) {
199
+ eventPayload.setProperty(rt, key.c_str(), jsi::String::createFromUtf8(rt, std::get<std::string>(value)));
200
+
201
+ continue;
202
+ }
203
+
204
+ if (std::holds_alternative<int>(value)) {
205
+ eventPayload.setProperty(rt, key.c_str(), std::get<int>(value));
206
+
207
+ continue;
208
+ }
209
+
210
+ if (std::holds_alternative<EventNestedValue>(value)) {
211
+ eventPayload.setProperty(rt, key.c_str(), this->parseEventNestedPayload(rt, std::get<EventNestedValue>(value)));
212
+
213
+ continue;
214
+ }
215
+ }
216
+
217
+ return eventPayload;
218
+ }
219
+
220
+ jsi::Object UnistylesModel::parseEventNestedPayload(jsi::Runtime& rt, const EventNestedValue& payload) {
221
+ jsi::Object eventPayload = jsi::Object(rt);
222
+
223
+ for (const auto& [key, value] : payload) {
224
+ if (std::holds_alternative<std::string>(value)) {
225
+ eventPayload.setProperty(rt, key.c_str(), jsi::String::createFromUtf8(rt, std::get<std::string>(value)));
226
+ }
227
+
228
+ if (std::holds_alternative<int>(value)) {
229
+ eventPayload.setProperty(rt, key.c_str(), std::get<int>(value));
230
+ }
231
+ }
232
+
233
+ return eventPayload;
234
+ }
@@ -0,0 +1,141 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <vector>
5
+ #include <map>
6
+ #include <optional>
7
+ #include <variant>
8
+ #include <math.h>
9
+ #include <algorithm>
10
+
11
+ using namespace facebook;
12
+
13
+ const std::string UnistylesOrientationPortrait = "portrait";
14
+ const std::string UnistylesOrientationLandscape = "landscape";
15
+
16
+ const std::string UnistylesDarkScheme = "dark";
17
+ const std::string UnistylesLightScheme = "light";
18
+ const std::string UnistylesUnspecifiedScheme = "unspecified";
19
+
20
+ const std::string UnistylesErrorBreakpointsCannotBeEmpty = "You are trying to register empty breakpoints object";
21
+ const std::string UnistylesErrorBreakpointsMustStartFromZero = "You are trying to register breakpoints that don't start from 0";
22
+ const std::string UnistylesErrorThemesCannotBeEmpty = "You are trying to register empty themes object";
23
+ const std::string UnistylesErrorAdaptiveThemesNotSupported = "Your platform doesn't support adaptive themes";
24
+
25
+ struct Dimensions {
26
+ int width;
27
+ int height;
28
+ };
29
+
30
+ struct Screen {
31
+ int width;
32
+ int height;
33
+ float pixelRatio;
34
+ float fontScale;
35
+ };
36
+
37
+ struct Insets {
38
+ int top;
39
+ int bottom;
40
+ int left;
41
+ int right;
42
+ };
43
+
44
+ using EventNestedValue = std::map<std::string, std::variant<std::string, int>>;
45
+ using EventValue = std::variant<std::string, int>;
46
+ using EventPayload = std::map<std::string, std::variant<std::string, int, EventNestedValue>>;
47
+
48
+ struct UnistylesModel {
49
+ void emitDeviceEvent(const std::string eventType, EventPayload payload);
50
+ void onThemeChange(std::string themeName);
51
+ void onPluginChange();
52
+ void onLayoutChange();
53
+ jsi::Object parseEventPayload(jsi::Runtime& rt, const EventPayload& payload);
54
+ jsi::Object parseEventNestedPayload(jsi::Runtime& rt, const EventNestedValue& payload);
55
+
56
+ std::function<Screen()> getScreenDimensions;
57
+ std::function<std::string()> getContentSizeCategory;
58
+ std::function<std::string()> getColorScheme;
59
+ std::function<Dimensions()> getStatusBarDimensions;
60
+ std::function<Dimensions()> getNavigationBarDimensions;
61
+ std::function<Insets()> getInsets;
62
+ std::optional<std::function<void(std::string, float alpha)>> setStatusBarColor;
63
+ std::optional<std::function<void(std::string, float alpha)>> setNavigationBarColor;
64
+ std::optional<std::function<void(bool)>> setNavigationBarHidden;
65
+ std::optional<std::function<void(bool)>> setStatusBarHidden;
66
+ std::optional<std::function<void(bool)>> setImmersiveMode;
67
+ std::optional<std::function<void(std::string, float alpha)>> setRootViewBackgroundColor;
68
+ std::optional<std::function<void()>> disableAnimatedInsetsAndroid;
69
+
70
+ void setScreenDimensionsCallback(std::function<Screen()> callback) {
71
+ this->getScreenDimensions = callback;
72
+ }
73
+ void setContentSizeCategoryCallback(std::function<std::string()> callback) {
74
+ this->getContentSizeCategory = callback;
75
+ }
76
+ void setColorSchemeCallback(std::function<std::string()> callback) {
77
+ this->getColorScheme = callback;
78
+ }
79
+ void setStatusBarDimensionsCallback(std::function<Dimensions()> callback) {
80
+ this->getStatusBarDimensions = callback;
81
+ }
82
+ void setNavigationBarDimensionsCallback(std::function<Dimensions()> callback) {
83
+ this->getNavigationBarDimensions = callback;
84
+ }
85
+ void setInsetsCallback(std::function<Insets()> callback) {
86
+ this->getInsets = callback;
87
+ }
88
+ void setStatusBarColorCallback(std::function<void(std::string color, float alpha)> callback) {
89
+ this->setStatusBarColor = callback;
90
+ }
91
+ void setNavigationBarColorCallback(std::function<void(std::string color, float alpha)> callback) {
92
+ this->setNavigationBarColor = callback;
93
+ }
94
+ void setNavigationBarHiddenCallback(std::function<void(bool hidden)> callback) {
95
+ this->setNavigationBarHidden = callback;
96
+ }
97
+ void setStatusBarHiddenCallback(std::function<void(bool hidden)> callback) {
98
+ this->setStatusBarHidden = callback;
99
+ }
100
+ void setImmersiveModeCallback(std::function<void(bool enabled)> callback) {
101
+ this->setImmersiveMode = callback;
102
+ }
103
+ void setRootViewBackgroundColorCallback(std::function<void(std::string color, float alpha)> callback) {
104
+ this->setRootViewBackgroundColor = callback;
105
+ }
106
+ void setDisableAnimatedInsetsAndroidCallback(std::function<void()> callback) {
107
+ this->disableAnimatedInsetsAndroid = callback;
108
+ }
109
+
110
+ Dimensions screen = {0, 0};
111
+ Dimensions statusBar = {0, 0};
112
+ Dimensions navigationBar = {0, 0};
113
+ Insets insets = {0, 0, 0, 0};
114
+ float pixelRatio = 1.0;
115
+ float fontScale = 1.0;
116
+ bool rtl = false;
117
+ std::string colorScheme = UnistylesUnspecifiedScheme;
118
+ std::string contentSizeCategory = UnistylesUnspecifiedScheme;
119
+
120
+ UnistylesModel(std::function<void(std::function<void(jsi::Runtime&)>&&)> runOnJSThread): runOnJSThread(std::move(runOnJSThread)) {}
121
+
122
+ bool hasAdaptiveThemes;
123
+ bool supportsAutomaticColorScheme;
124
+
125
+ std::string themeName;
126
+ std::string breakpoint;
127
+ std::vector<std::string> pluginNames;
128
+ std::vector<std::string> themes;
129
+ std::vector<std::pair<std::string, double>> sortedBreakpointPairs;
130
+
131
+ void handleScreenSizeChange(Screen& screen, std::optional<Insets> insets, std::optional<Dimensions> statusBar, std::optional<Dimensions> navigationBar);
132
+ void handleAppearanceChange(std::string colorScheme);
133
+ void handleContentSizeCategoryChange(std::string contentSizeCategory);
134
+
135
+ jsi::Value getThemeOrFail(jsi::Runtime&);
136
+ std::string getBreakpointFromScreenWidth(int width, const std::vector<std::pair<std::string, double>>& sortedBreakpointEntries);
137
+ std::vector<std::pair<std::string, double>> toSortedBreakpointPairs(jsi::Runtime&, jsi::Object&);
138
+
139
+ private:
140
+ std::function<void(std::function<void(jsi::Runtime&)>&&)> runOnJSThread;
141
+ };