react-native-unistyles 2.7.2 → 2.8.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/android/CMakeLists.txt +8 -1
  2. package/android/build.gradle +4 -1
  3. package/android/src/main/cxx/cpp-adapter.cpp +10 -100
  4. package/android/src/main/cxx/helpers.h +2 -0
  5. package/android/src/main/cxx/platform.cpp +126 -0
  6. package/android/src/main/cxx/platform.h +15 -0
  7. package/android/src/main/java/com/unistyles/Config.kt +31 -5
  8. package/android/src/main/java/com/unistyles/Platform.kt +24 -0
  9. package/android/src/main/java/com/unistyles/UnistylesModule.kt +24 -87
  10. package/cxx/Macros.h +11 -0
  11. package/cxx/UnistylesImpl.cpp +241 -0
  12. package/cxx/UnistylesModel.cpp +230 -0
  13. package/cxx/UnistylesModel.h +112 -0
  14. package/cxx/UnistylesRuntime.cpp +17 -388
  15. package/cxx/UnistylesRuntime.h +56 -95
  16. package/ios/UnistylesModule.h +8 -0
  17. package/ios/UnistylesModule.mm +12 -89
  18. package/ios/platform/Platform_Shared.h +5 -0
  19. package/ios/platform/Platform_Shared.mm +69 -0
  20. package/ios/platform/Platform_iOS.h +3 -10
  21. package/ios/platform/Platform_iOS.mm +53 -96
  22. package/ios/platform/Platform_macOS.h +2 -7
  23. package/ios/platform/Platform_macOS.mm +36 -36
  24. package/ios/platform/Platform_tvOS.h +2 -9
  25. package/ios/platform/Platform_tvOS.mm +30 -92
  26. package/ios/platform/Platform_visionOS.h +3 -9
  27. package/ios/platform/Platform_visionOS.mm +29 -84
  28. package/lib/commonjs/common.js.map +1 -1
  29. package/lib/commonjs/normalizer/normalizeStyle.js.map +1 -1
  30. package/lib/commonjs/normalizer/normalizer.js +1 -1
  31. package/lib/commonjs/normalizer/normalizer.js.map +1 -1
  32. package/lib/commonjs/utils/cssMediaQuery.js.map +1 -1
  33. package/lib/commonjs/utils/generateId.js.map +1 -1
  34. package/lib/commonjs/utils/mq.js.map +1 -1
  35. package/lib/module/common.js.map +1 -1
  36. package/lib/module/normalizer/normalizeStyle.js.map +1 -1
  37. package/lib/module/normalizer/normalizer.js.map +1 -1
  38. package/lib/module/utils/cssMediaQuery.js.map +1 -1
  39. package/lib/module/utils/generateId.js.map +1 -1
  40. package/lib/module/utils/mq.js.map +1 -1
  41. package/package.json +2 -1
  42. package/react-native-unistyles.podspec +3 -0
  43. package/ios/UnistylesHelpers.h +0 -3
  44. package/ios/UnistylesHelpers.mm +0 -5
@@ -0,0 +1,241 @@
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
+
181
+ if (this->setStatusBarColor.has_value()) {
182
+ this->setStatusBarColor.value()(color);
183
+ }
184
+
185
+ return jsi::Value::undefined();
186
+ });
187
+
188
+ statusBar.setProperty(rt, "width", this->statusBar.width);
189
+ statusBar.setProperty(rt, "height", this->statusBar.height);
190
+ statusBar.setProperty(rt, "setColor", setStatusBarColorFunction);
191
+
192
+ return statusBar;
193
+ }
194
+
195
+ jsi::Value UnistylesRuntime::getNavigationBar(jsi::Runtime& rt, std::string fnName) {
196
+ auto navigationBarValue = jsi::Object(rt);
197
+ auto setNavigationBarColorFunction = HOST_FN("setColor", 1, {
198
+ std::string color = arguments[0].asString(rt).utf8(rt);
199
+
200
+ if (this->setNavigationBarColor.has_value()) {
201
+ this->setNavigationBarColor.value()(color);
202
+ }
203
+
204
+ return jsi::Value::undefined();
205
+ });
206
+
207
+ navigationBarValue.setProperty(rt, "width", this->navigationBar.width);
208
+ navigationBarValue.setProperty(rt, "height", this->navigationBar.height);
209
+ navigationBarValue.setProperty(rt, "setColor", setNavigationBarColorFunction);
210
+
211
+ return navigationBarValue;
212
+ }
213
+
214
+ std::optional<jsi::Value> UnistylesRuntime::setThemes(jsi::Runtime& rt, const jsi::Value& value) {
215
+ jsi::Array themes = value.asObject(rt).asArray(rt);
216
+ std::vector<std::string> themesVector;
217
+ size_t length = themes.size(rt);
218
+
219
+ for (size_t i = 0; i < length; ++i) {
220
+ jsi::Value element = themes.getValueAtIndex(rt, i);
221
+
222
+ if (element.isString()) {
223
+ std::string theme = element.asString(rt).utf8(rt);
224
+ themesVector.push_back(theme);
225
+ }
226
+ }
227
+
228
+ if (themesVector.size() == 0) {
229
+ throw jsi::JSError(rt, UnistylesErrorThemesCannotBeEmpty);
230
+ }
231
+
232
+ this->themes = themesVector;
233
+ this->themeName = "";
234
+
235
+ bool hasLightTheme = std::find(themesVector.begin(), themesVector.end(), "light") != themesVector.end();
236
+ bool hasDarkTheme = std::find(themesVector.begin(), themesVector.end(), "dark") != themesVector.end();
237
+
238
+ this->supportsAutomaticColorScheme = hasLightTheme && hasDarkTheme;
239
+
240
+ return std::nullopt;
241
+ }
@@ -0,0 +1,230 @@
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(Dimensions& 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 hasDifferentInsets = insets.has_value()
21
+ ? this->insets.top != insets->top || this->insets.bottom != insets->bottom || this->insets.left != insets->left || this->insets.right != insets->right
22
+ : false;
23
+
24
+ // we don't need to check statusBar/navigationBar as they will only change on orientation change witch is equal to hasDifferentScreenDimensions
25
+ bool shouldNotify = hasDifferentBreakpoint || hasDifferentScreenDimensions || hasDifferentInsets;
26
+
27
+ this->breakpoint = breakpoint;
28
+ this->screen = {screen.width, screen.height};
29
+
30
+ if (insets.has_value()) {
31
+ this->insets = {insets->top, insets->bottom, insets->left, insets->right};
32
+ }
33
+
34
+ if (statusBar.has_value()) {
35
+ this->statusBar = {statusBar->width, statusBar->height};
36
+ }
37
+
38
+ if (navigationBar.has_value()) {
39
+ this->navigationBar = {navigationBar->width, navigationBar->height};
40
+ }
41
+
42
+ if (shouldNotify) {
43
+ this->onLayoutChange();
44
+ }
45
+ }
46
+
47
+ void UnistylesModel::handleAppearanceChange(std::string colorScheme) {
48
+ this->colorScheme = colorScheme;
49
+
50
+ if (!this->supportsAutomaticColorScheme || !this->hasAdaptiveThemes) {
51
+ return;
52
+ }
53
+
54
+ if (this->themeName != this->colorScheme) {
55
+ this->onThemeChange(this->colorScheme);
56
+ this->themeName = this->colorScheme;
57
+ }
58
+ }
59
+
60
+ void UnistylesModel::handleContentSizeCategoryChange(std::string contentSizeCategory) {
61
+ this->contentSizeCategory = contentSizeCategory;
62
+ this->onContentSizeCategoryChange(contentSizeCategory);
63
+ }
64
+
65
+ jsi::Value UnistylesModel::getThemeOrFail(jsi::Runtime& runtime) {
66
+ if (this->themes.size() == 1) {
67
+ std::string themeName = this->themes.at(0);
68
+
69
+ this->themeName = themeName;
70
+
71
+ return jsi::String::createFromUtf8(runtime, themeName);
72
+ }
73
+
74
+ return jsi::Value().undefined();
75
+ }
76
+
77
+ std::vector<std::pair<std::string, double>> UnistylesModel::toSortedBreakpointPairs(jsi::Runtime& rt, jsi::Object& breakpointsObj) {
78
+ jsi::Array propertyNames = breakpointsObj.getPropertyNames(rt);
79
+ std::vector<std::pair<std::string, double>> sortedBreakpointEntriesVec;
80
+
81
+ for (size_t i = 0; i < propertyNames.size(rt); ++i) {
82
+ jsi::Value propNameValue = propertyNames.getValueAtIndex(rt, i);
83
+ std::string name = propNameValue.asString(rt).utf8(rt);
84
+ jsi::PropNameID propNameID = jsi::PropNameID::forUtf8(rt, name);
85
+ jsi::Value value = breakpointsObj.getProperty(rt, propNameID);
86
+
87
+ if (value.isNumber()) {
88
+ double breakpointValue = value.asNumber();
89
+
90
+ sortedBreakpointEntriesVec.push_back(std::make_pair(name, breakpointValue));
91
+ }
92
+ }
93
+
94
+ std::sort(sortedBreakpointEntriesVec.begin(), sortedBreakpointEntriesVec.end(), [](const std::pair<std::string, double>& a, const std::pair<std::string, double>& b) {
95
+ return a.second < b.second;
96
+ });
97
+
98
+ return sortedBreakpointEntriesVec;
99
+ }
100
+
101
+ // a little bit hacky, but works like Turbo Module emitDeviceEvent
102
+ // it will be super easy to refactor for Unistyles 3.0
103
+ // ref: https://github.com/facebook/react-native/pull/43375
104
+ // ref: https://github.com/facebook/react-native/blob/b5fd041917d197f256433a41a126f0dff767c429/packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModule.cpp#L42
105
+ void UnistylesModel::emitDeviceEvent(const std::string eventType, EventPayload payload) {
106
+ this->callInvoker->invokeAsync([eventType, payload, this](){
107
+ jsi::Value emitter = this->runtime.global().getProperty(this->runtime, "__rctDeviceEventEmitter");
108
+
109
+ if (emitter.isUndefined()) {
110
+ return;
111
+ }
112
+
113
+ jsi::Object emitterObject = emitter.asObject(runtime);
114
+ jsi::Function emitFunction = emitterObject.getPropertyAsFunction(runtime, "emit");
115
+
116
+ std::vector<jsi::Value> arguments;
117
+ jsi::Object event = jsi::Object(this->runtime);
118
+
119
+ event.setProperty(this->runtime, "type", jsi::String::createFromUtf8(this->runtime, eventType));
120
+
121
+ jsi::Object eventPayload = this->parseEventPayload(payload);
122
+
123
+ event.setProperty(this->runtime, "payload", eventPayload);
124
+
125
+ arguments.emplace_back(jsi::String::createFromAscii(runtime, "__unistylesOnChange"));
126
+ arguments.emplace_back(std::move(event));
127
+
128
+ emitFunction.callWithThis(runtime, emitterObject, (const jsi::Value*)arguments.data(), arguments.size());
129
+ });
130
+ }
131
+
132
+ void UnistylesModel::onThemeChange(std::string themeName) {
133
+ EventPayload payload;
134
+ payload["themeName"] = themeName;
135
+
136
+ this->emitDeviceEvent("theme", payload);
137
+ }
138
+
139
+ void UnistylesModel::onContentSizeCategoryChange(std::string contentSizeCategory) {
140
+ EventPayload payload;
141
+ payload["contentSizeCategory"] = contentSizeCategory;
142
+
143
+ this->emitDeviceEvent("dynamicTypeSize", payload);
144
+ }
145
+
146
+ void UnistylesModel::onPluginChange() {
147
+ this->emitDeviceEvent("plugin", {});
148
+ }
149
+
150
+ void UnistylesModel::onLayoutChange() {
151
+ EventPayload payload;
152
+ std::string orientation = screen.width > screen.height
153
+ ? UnistylesOrientationLandscape
154
+ : UnistylesOrientationPortrait;
155
+
156
+ payload["breakpoint"] = this->breakpoint;
157
+ payload["orientation"] = orientation;
158
+
159
+ EventNestedValue screenPayload;
160
+ auto screen = this->screen;
161
+
162
+ screenPayload["width"] = screen.width;
163
+ screenPayload["height"] = screen.height;
164
+
165
+ payload["screen"] = screenPayload;
166
+
167
+ EventNestedValue statusBarPayload;
168
+ auto statusBar = this->statusBar;
169
+
170
+ statusBarPayload["width"] = statusBar.width;
171
+ statusBarPayload["height"] = statusBar.height;
172
+
173
+ payload["statusBar"] = statusBarPayload;
174
+
175
+ EventNestedValue navigationBarPayload;
176
+ auto navigationBar = this->navigationBar;
177
+
178
+ navigationBarPayload["width"] = navigationBar.width;
179
+ navigationBarPayload["height"] = navigationBar.height;
180
+
181
+ payload["navigationBar"] = navigationBarPayload;
182
+
183
+ EventNestedValue insetsPayload;
184
+ auto insets = this->insets;
185
+
186
+ insetsPayload["top"] = insets.top;
187
+ insetsPayload["bottom"] = insets.bottom;
188
+ insetsPayload["left"] = insets.left;
189
+ insetsPayload["right"] = insets.right;
190
+
191
+ payload["insets"] = insetsPayload;
192
+
193
+ this->emitDeviceEvent("layout", payload);
194
+ }
195
+
196
+ jsi::Object UnistylesModel::parseEventPayload(EventPayload payload) {
197
+ jsi::Object eventPayload = jsi::Object(this->runtime);
198
+
199
+ for (const auto& [key, value] : payload) {
200
+ if (std::holds_alternative<std::string>(value)) {
201
+ eventPayload.setProperty(this->runtime, key.c_str(), jsi::String::createFromUtf8(this->runtime, std::get<std::string>(value)));
202
+ }
203
+
204
+ if (std::holds_alternative<int>(value)) {
205
+ eventPayload.setProperty(this->runtime, key.c_str(), std::get<int>(value));
206
+ }
207
+
208
+ if (std::holds_alternative<EventNestedValue>(value)) {
209
+ eventPayload.setProperty(this->runtime, key.c_str(), this->parseEventNestedPayload(std::get<EventNestedValue>(value)));
210
+ }
211
+ }
212
+
213
+ return eventPayload;
214
+ }
215
+
216
+ jsi::Object UnistylesModel::parseEventNestedPayload(EventNestedValue payload) {
217
+ jsi::Object eventPayload = jsi::Object(this->runtime);
218
+
219
+ for (const auto& [key, value] : payload) {
220
+ if (std::holds_alternative<std::string>(value)) {
221
+ eventPayload.setProperty(this->runtime, key.c_str(), jsi::String::createFromUtf8(this->runtime, std::get<std::string>(value)));
222
+ }
223
+
224
+ if (std::holds_alternative<int>(value)) {
225
+ eventPayload.setProperty(this->runtime, key.c_str(), std::get<int>(value));
226
+ }
227
+ }
228
+
229
+ return eventPayload;
230
+ }
@@ -0,0 +1,112 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <ReactCommon/CallInvoker.h>
5
+ #include <vector>
6
+ #include <map>
7
+ #include <optional>
8
+ #include <variant>
9
+
10
+ using namespace facebook;
11
+
12
+ const std::string UnistylesOrientationPortrait = "portrait";
13
+ const std::string UnistylesOrientationLandscape = "landscape";
14
+
15
+ const std::string UnistylesDarkScheme = "dark";
16
+ const std::string UnistylesLightScheme = "light";
17
+ const std::string UnistylesUnspecifiedScheme = "unspecified";
18
+
19
+ const std::string UnistylesErrorBreakpointsCannotBeEmpty = "You are trying to register empty breakpoints object";
20
+ const std::string UnistylesErrorBreakpointsMustStartFromZero = "You are trying to register breakpoints that don't start from 0";
21
+ const std::string UnistylesErrorThemesCannotBeEmpty = "You are trying to register empty themes object";
22
+ const std::string UnistylesErrorAdaptiveThemesNotSupported = "Your platform doesn't support adaptive themes";
23
+
24
+ struct Dimensions {
25
+ int width;
26
+ int height;
27
+ };
28
+
29
+ struct Insets {
30
+ int top;
31
+ int bottom;
32
+ int left;
33
+ int right;
34
+ };
35
+
36
+ using EventNestedValue = std::map<std::string, std::variant<std::string, int>>;
37
+ using EventValue = std::variant<std::string, int>;
38
+ using EventPayload = std::map<std::string, std::variant<std::string, int, EventNestedValue>>;
39
+
40
+ struct UnistylesModel {
41
+ void emitDeviceEvent(const std::string eventType, EventPayload payload);
42
+ void onThemeChange(std::string themeName);
43
+ void onPluginChange();
44
+ void onContentSizeCategoryChange(std::string contentSizeCategory);
45
+ void onLayoutChange();
46
+ jsi::Object parseEventPayload(EventPayload payload);
47
+ jsi::Object parseEventNestedPayload(EventNestedValue payload);
48
+
49
+ std::function<Dimensions()> getScreenDimensions;
50
+ std::function<std::string()> getContentSizeCategory;
51
+ std::function<std::string()> getColorScheme;
52
+ std::function<Dimensions()> getStatusBarDimensions;
53
+ std::function<Dimensions()> getNavigationBarDimensions;
54
+ std::function<Insets()> getInsets;
55
+ std::optional<std::function<void(std::string)>> setStatusBarColor;
56
+ std::optional<std::function<void(std::string)>> setNavigationBarColor;
57
+
58
+ void setScreenDimensionsCallback(std::function<Dimensions()> callback) {
59
+ this->getScreenDimensions = callback;
60
+ }
61
+ void setContentSizeCategoryCallback(std::function<std::string()> callback) {
62
+ this->getContentSizeCategory = callback;
63
+ }
64
+ void setColorSchemeCallback(std::function<std::string()> callback) {
65
+ this->getColorScheme = callback;
66
+ }
67
+ void setStatusBarDimensionsCallback(std::function<Dimensions()> callback) {
68
+ this->getStatusBarDimensions = callback;
69
+ }
70
+ void setNavigationBarDimensionsCallback(std::function<Dimensions()> callback) {
71
+ this->getNavigationBarDimensions = callback;
72
+ }
73
+ void setInsetsCallback(std::function<Insets()> callback) {
74
+ this->getInsets = callback;
75
+ }
76
+ void setStatusBarColorCallback(std::function<void(std::string color)> callback) {
77
+ this->setStatusBarColor = callback;
78
+ }
79
+ void setNavigationBarColorCallback(std::function<void(std::string color)> callback) {
80
+ this->setNavigationBarColor = callback;
81
+ }
82
+
83
+ Dimensions screen = {0, 0};
84
+ Dimensions statusBar = {0, 0};
85
+ Dimensions navigationBar = {0, 0};
86
+ Insets insets = {0, 0, 0, 0};
87
+ std::string colorScheme = UnistylesUnspecifiedScheme;
88
+ std::string contentSizeCategory = UnistylesUnspecifiedScheme;
89
+
90
+ UnistylesModel(jsi::Runtime& rt, std::shared_ptr<react::CallInvoker> callInvoker): runtime(rt), callInvoker(callInvoker) {}
91
+
92
+ bool hasAdaptiveThemes;
93
+ bool supportsAutomaticColorScheme;
94
+
95
+ std::string themeName;
96
+ std::string breakpoint;
97
+ std::vector<std::string> pluginNames;
98
+ std::vector<std::string> themes;
99
+ std::vector<std::pair<std::string, double>> sortedBreakpointPairs;
100
+
101
+ void handleScreenSizeChange(Dimensions& screen, std::optional<Insets> insets, std::optional<Dimensions> statusBar, std::optional<Dimensions> navigationBar);
102
+ void handleAppearanceChange(std::string colorScheme);
103
+ void handleContentSizeCategoryChange(std::string contentSizeCategory);
104
+
105
+ jsi::Value getThemeOrFail(jsi::Runtime&);
106
+ std::string getBreakpointFromScreenWidth(int width, const std::vector<std::pair<std::string, double>>& sortedBreakpointEntries);
107
+ std::vector<std::pair<std::string, double>> toSortedBreakpointPairs(jsi::Runtime&, jsi::Object&);
108
+
109
+ private:
110
+ jsi::Runtime& runtime;
111
+ std::shared_ptr<react::CallInvoker> callInvoker;
112
+ };