react-native-unistyles 3.1.1 → 3.2.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.
- package/README.md +3 -2
- package/android/src/main/cxx/NativeUnistylesModule.cpp +2 -5
- package/android/src/main/cxx/NativeUnistylesModule.h +1 -7
- package/android/src/main/java/com/unistyles/Equatable.kt +5 -1
- package/android/src/main/java/com/unistyles/NativePlatform+android.kt +6 -1
- package/android/src/main/java/com/unistyles/NativePlatform+listener.kt +21 -3
- package/cxx/core/UnistyleWrapper.h +2 -2
- package/cxx/core/UnistylesRegistry.cpp +57 -48
- package/cxx/core/UnistylesRegistry.h +16 -14
- package/cxx/core/UnistylesState.cpp +22 -20
- package/cxx/core/UnistylesState.h +5 -6
- package/cxx/hybridObjects/HybridShadowRegistry.cpp +14 -3
- package/cxx/hybridObjects/HybridShadowRegistry.h +5 -0
- package/cxx/hybridObjects/HybridStyleSheet.cpp +71 -45
- package/cxx/hybridObjects/HybridUnistylesRuntime.cpp +22 -32
- package/cxx/hybridObjects/HybridUnistylesRuntime.h +3 -4
- package/cxx/parser/Parser.cpp +14 -14
- package/cxx/shadowTree/ShadowTreeManager.cpp +10 -7
- package/ios/UnistylesModuleOnLoad.mm +3 -10
- package/lib/commonjs/core/useProxifiedUnistyles/useProxifiedUnistyles.js +4 -1
- package/lib/commonjs/core/useProxifiedUnistyles/useProxifiedUnistyles.js.map +1 -1
- package/lib/commonjs/specs/ShadowRegistry/index.js +20 -1
- package/lib/commonjs/specs/ShadowRegistry/index.js.map +1 -1
- package/lib/commonjs/web/convert/style.js +6 -6
- package/lib/commonjs/web/convert/style.js.map +1 -1
- package/lib/commonjs/web/listener.js +6 -0
- package/lib/commonjs/web/listener.js.map +1 -1
- package/lib/commonjs/web/utils/createUnistylesRef.js +1 -1
- package/lib/commonjs/web/utils/createUnistylesRef.js.map +1 -1
- package/lib/module/core/useProxifiedUnistyles/useProxifiedUnistyles.js +4 -1
- package/lib/module/core/useProxifiedUnistyles/useProxifiedUnistyles.js.map +1 -1
- package/lib/module/specs/ShadowRegistry/index.js +20 -1
- package/lib/module/specs/ShadowRegistry/index.js.map +1 -1
- package/lib/module/web/convert/style.js +6 -6
- package/lib/module/web/convert/style.js.map +1 -1
- package/lib/module/web/listener.js +6 -0
- package/lib/module/web/listener.js.map +1 -1
- package/lib/module/web/utils/createUnistylesRef.js +1 -1
- package/lib/module/web/utils/createUnistylesRef.js.map +1 -1
- package/lib/typescript/src/core/useProxifiedUnistyles/useProxifiedUnistyles.d.ts.map +1 -1
- package/lib/typescript/src/specs/ShadowRegistry/index.d.ts +2 -1
- package/lib/typescript/src/specs/ShadowRegistry/index.d.ts.map +1 -1
- package/lib/typescript/src/web/listener.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JColorScheme.hpp +1 -1
- package/nitrogen/generated/android/c++/JDimensions.hpp +1 -1
- package/nitrogen/generated/android/c++/JFunc_void_UnistylesNativeMiniRuntime.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_UnistyleDependency__UnistylesNativeMiniRuntime.hpp +2 -2
- package/nitrogen/generated/android/c++/JHybridNativePlatformSpec.hpp +2 -2
- package/nitrogen/generated/android/c++/JInsets.hpp +1 -1
- package/nitrogen/generated/android/c++/JOrientation.hpp +1 -1
- package/nitrogen/generated/android/c++/JUnistyleDependency.hpp +1 -1
- package/nitrogen/generated/android/c++/JUnistylesNativeMiniRuntime.hpp +1 -1
- package/package.json +3 -3
- package/src/core/useProxifiedUnistyles/useProxifiedUnistyles.ts +4 -1
- package/src/specs/ShadowRegistry/index.ts +36 -2
- package/src/web/convert/style.ts +6 -6
- package/src/web/listener.ts +6 -0
- package/src/web/utils/createUnistylesRef.ts +1 -1
package/README.md
CHANGED
|
@@ -24,10 +24,11 @@ Install dependencies:
|
|
|
24
24
|
yarn add react-native-nitro-modules
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
| react-native-unistyles | Minimum react-native-nitro-modules
|
|
28
|
-
|
|
27
|
+
| react-native-unistyles | Minimum react-native-nitro-modules |
|
|
28
|
+
|------------------------|----------------------------------------|
|
|
29
29
|
| >= 3.0.0 | >= 0.33.9 |
|
|
30
30
|
| >= 3.1.0 | >= 0.35.0 |
|
|
31
|
+
| >= 3.2.0 | >= 0.35.2 |
|
|
31
32
|
|
|
32
33
|
> **Note:** Since v3.1.0, `react-native-edge-to-edge` is an **optional** dependency. We strongly recommend setting `edgeToEdgeEnabled=true` in your `android/gradle.properties` — it enforces translucent system bars on modals, disables legacy StatusBar hacks, and enables additional React Native core fixes. **Expo SDK 54+** enables this automatically. You can still install `react-native-edge-to-edge` for ecosystem compatibility with libraries like `react-native-bootsplash` or `react-native-permissions`.
|
|
33
34
|
|
|
@@ -33,11 +33,8 @@ void UnistylesModule::registerNatives() {
|
|
|
33
33
|
jni::local_ref<BindingsInstallerHolder::javaobject> UnistylesModule::getBindingsInstaller(jni::alias_ref<UnistylesModule::javaobject> jobj) {
|
|
34
34
|
auto& runtimeExecutor = jobj->cthis()->_runtimeExecutor;
|
|
35
35
|
auto& nativePlatform = jobj->cthis()->_nativePlatform;
|
|
36
|
-
auto* self = jobj->cthis();
|
|
37
|
-
|
|
38
|
-
return BindingsInstallerHolder::newObjectCxxArgs([&runtimeExecutor, &nativePlatform, self](jsi::Runtime& rt) {
|
|
39
|
-
self->_runtime = &rt;
|
|
40
36
|
|
|
37
|
+
return BindingsInstallerHolder::newObjectCxxArgs([&runtimeExecutor, &nativePlatform](jsi::Runtime& rt) {
|
|
41
38
|
// function is called on: first init and every live reload
|
|
42
39
|
// check if this is live reload, if so let's replace UnistylesRuntime with new runtime
|
|
43
40
|
auto hasUnistylesRuntime = HybridObjectRegistry::hasHybridObject("UnistylesRuntime");
|
|
@@ -55,7 +52,7 @@ jni::local_ref<BindingsInstallerHolder::javaobject> UnistylesModule::getBindings
|
|
|
55
52
|
};
|
|
56
53
|
|
|
57
54
|
// init hybrids
|
|
58
|
-
auto unistylesRuntime = std::make_shared<HybridUnistylesRuntime>(nativePlatform,
|
|
55
|
+
auto unistylesRuntime = std::make_shared<HybridUnistylesRuntime>(nativePlatform, runOnJSThread);
|
|
59
56
|
auto styleSheet = std::make_shared<HybridStyleSheet>(unistylesRuntime);
|
|
60
57
|
|
|
61
58
|
HybridObjectRegistry::registerHybridObjectConstructor("UnistylesRuntime", [unistylesRuntime]() -> std::shared_ptr<HybridObject>{
|
|
@@ -29,12 +29,7 @@ struct UnistylesModule : public jni::HybridClass<UnistylesModule> {
|
|
|
29
29
|
jni::alias_ref<JHybridNativePlatformSpec::JavaPart> nativePlatform
|
|
30
30
|
);
|
|
31
31
|
static void invalidateNative(jni::alias_ref<jhybridobject> jThis) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (self->_runtime) {
|
|
35
|
-
core::UnistylesRegistry::get().destroyState(self->_runtime);
|
|
36
|
-
self->_runtime = nullptr;
|
|
37
|
-
}
|
|
32
|
+
core::UnistylesRegistry::get().destroy();
|
|
38
33
|
}
|
|
39
34
|
|
|
40
35
|
static jni::local_ref<BindingsInstallerHolder::javaobject> getBindingsInstaller(jni::alias_ref<UnistylesModule::javaobject> jThis);
|
|
@@ -42,7 +37,6 @@ struct UnistylesModule : public jni::HybridClass<UnistylesModule> {
|
|
|
42
37
|
private:
|
|
43
38
|
RuntimeExecutor _runtimeExecutor;
|
|
44
39
|
std::shared_ptr<HybridNativePlatformSpec> _nativePlatform;
|
|
45
|
-
jsi::Runtime* _runtime = nullptr;
|
|
46
40
|
};
|
|
47
41
|
|
|
48
42
|
}
|
|
@@ -54,7 +54,11 @@ fun NativePlatformAndroid.diffMiniRuntimes(lhs: UnistylesNativeMiniRuntime, rhs:
|
|
|
54
54
|
dependencies.add(UnistyleDependency.NAVIGATIONBAR)
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
if (lhs.rtl != rhs.rtl) {
|
|
58
|
+
dependencies.add(UnistyleDependency.RTL)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// pixel ratio is not dynamic
|
|
58
62
|
|
|
59
63
|
return dependencies.toTypedArray()
|
|
60
64
|
}
|
|
@@ -37,6 +37,8 @@ class NativePlatformAndroid(private val reactContext: ReactApplicationContext):
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
fun onDestroy() {
|
|
40
|
+
_listener.onDestroy()
|
|
41
|
+
_insets.onDestroy()
|
|
40
42
|
reactContext.removeLifecycleEventListener(this)
|
|
41
43
|
}
|
|
42
44
|
|
|
@@ -155,11 +157,14 @@ class NativePlatformAndroid(private val reactContext: ReactApplicationContext):
|
|
|
155
157
|
"com.facebook.react.modules.i18nmanager.I18nUtil",
|
|
156
158
|
Context.MODE_PRIVATE
|
|
157
159
|
)
|
|
160
|
+
val resourcesLocale = reactContext.resources.configuration.locales[0]
|
|
158
161
|
val hasForcedRtl = sharedPrefs.getBoolean("RCTI18nUtil_forceRTL", false)
|
|
159
162
|
// user preferences
|
|
160
163
|
val isRtl = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL
|
|
164
|
+
val isResourcesRtl = TextUtilsCompat.getLayoutDirectionFromLocale(resourcesLocale) == ViewCompat.LAYOUT_DIRECTION_RTL
|
|
161
165
|
|
|
162
|
-
|
|
166
|
+
|
|
167
|
+
return hasForcedRtl || isRtl || isResourcesRtl
|
|
163
168
|
}
|
|
164
169
|
|
|
165
170
|
override fun setRootViewBackgroundColor(color: Double) {
|
|
@@ -4,6 +4,7 @@ import android.content.BroadcastReceiver
|
|
|
4
4
|
import android.content.Context
|
|
5
5
|
import android.content.Intent
|
|
6
6
|
import android.content.IntentFilter
|
|
7
|
+
import android.content.SharedPreferences
|
|
7
8
|
import android.os.Handler
|
|
8
9
|
import android.os.Looper
|
|
9
10
|
import androidx.annotation.Keep
|
|
@@ -23,21 +24,38 @@ class NativePlatformListener(
|
|
|
23
24
|
) {
|
|
24
25
|
private val _dependencyListeners: MutableList<CxxDependencyListener> = mutableListOf()
|
|
25
26
|
|
|
27
|
+
private fun notifyConfigChangedWithDelay() {
|
|
28
|
+
Handler(Looper.getMainLooper()).postDelayed({
|
|
29
|
+
this@NativePlatformListener.onConfigChange()
|
|
30
|
+
}, 25)
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
private val configurationChangeReceiver = object : BroadcastReceiver() {
|
|
27
34
|
override fun onReceive(context: Context, intent: Intent) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
notifyConfigChangedWithDelay()
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private val rtlPreferenceListener = SharedPreferences.OnSharedPreferenceChangeListener { prefs, key ->
|
|
40
|
+
if (key == "RCTI18nUtil_forceRTL") {
|
|
41
|
+
notifyConfigChangedWithDelay()
|
|
31
42
|
}
|
|
32
43
|
}
|
|
33
44
|
|
|
45
|
+
private val i18nUtilSharedPrefs = reactContext.getSharedPreferences(
|
|
46
|
+
"com.facebook.react.modules.i18nmanager.I18nUtil",
|
|
47
|
+
Context.MODE_PRIVATE
|
|
48
|
+
)
|
|
49
|
+
|
|
34
50
|
init {
|
|
35
51
|
reactContext.registerReceiver(configurationChangeReceiver, IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED))
|
|
52
|
+
i18nUtilSharedPrefs.registerOnSharedPreferenceChangeListener(rtlPreferenceListener)
|
|
36
53
|
}
|
|
37
54
|
|
|
38
55
|
fun onDestroy() {
|
|
39
56
|
this.removePlatformListeners()
|
|
40
57
|
reactContext.unregisterReceiver(configurationChangeReceiver)
|
|
58
|
+
i18nUtilSharedPrefs.unregisterOnSharedPreferenceChangeListener(rtlPreferenceListener)
|
|
41
59
|
}
|
|
42
60
|
|
|
43
61
|
fun addPlatformListener(listener: CxxDependencyListener) {
|
|
@@ -57,7 +57,7 @@ inline static std::vector<Unistyle::Shared> unistylesFromHashKeys(jsi::Runtime&
|
|
|
57
57
|
auto& registry = UnistylesRegistry::get();
|
|
58
58
|
|
|
59
59
|
for (auto& key: keys) {
|
|
60
|
-
unistyles.emplace_back(registry.getUnistyleById(
|
|
60
|
+
unistyles.emplace_back(registry.getUnistyleById(key));
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
return unistyles;
|
|
@@ -157,7 +157,7 @@ inline static jsi::Value objectFromUnistyle(jsi::Runtime& rt, std::shared_ptr<Hy
|
|
|
157
157
|
[unistyleID = unistyle->unid, unistylesRuntime, variants, parsedArguments](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count
|
|
158
158
|
) {
|
|
159
159
|
auto& registry = UnistylesRegistry::get();
|
|
160
|
-
auto unistyle = registry.getUnistyleById(
|
|
160
|
+
auto unistyle = registry.getUnistyleById(unistyleID);
|
|
161
161
|
|
|
162
162
|
parser::Parser(unistylesRuntime).rebuildUnistyle(rt, unistyle, variants, parsedArguments);
|
|
163
163
|
|
|
@@ -9,50 +9,44 @@ using namespace facebook::react;
|
|
|
9
9
|
std::atomic<int> core::UnistylesRegistry::_nextStyleSheetTag{0};
|
|
10
10
|
|
|
11
11
|
void core::UnistylesRegistry::registerTheme(jsi::Runtime& rt, std::string name, jsi::Value& theme) {
|
|
12
|
-
auto& state = this->getState(
|
|
12
|
+
auto& state = this->getState();
|
|
13
13
|
|
|
14
14
|
state._jsThemes.emplace(name, std::move(theme));
|
|
15
15
|
state._registeredThemeNames.push_back(name);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
void core::UnistylesRegistry::registerBreakpoints(
|
|
19
|
-
auto& state = this->getState(
|
|
18
|
+
void core::UnistylesRegistry::registerBreakpoints(std::vector<std::pair<std::string, double>>& sortedBreakpoints) {
|
|
19
|
+
auto& state = this->getState();
|
|
20
20
|
|
|
21
21
|
state._sortedBreakpointPairs = std::move(sortedBreakpoints);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
void core::UnistylesRegistry::setPrefersAdaptiveThemes(
|
|
25
|
-
auto& state = this->getState(
|
|
24
|
+
void core::UnistylesRegistry::setPrefersAdaptiveThemes(bool prefersAdaptiveThemes) {
|
|
25
|
+
auto& state = this->getState();
|
|
26
26
|
|
|
27
27
|
state._prefersAdaptiveThemes = prefersAdaptiveThemes;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
void core::UnistylesRegistry::setInitialThemeName(
|
|
31
|
-
auto& state = this->getState(
|
|
30
|
+
void core::UnistylesRegistry::setInitialThemeName(std::string themeName) {
|
|
31
|
+
auto& state = this->getState();
|
|
32
32
|
|
|
33
33
|
state._initialThemeName = themeName;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
core::UnistylesState& core::UnistylesRegistry::getState(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
core::UnistylesState& core::UnistylesRegistry::getState() {
|
|
37
|
+
if (!this->_state) {
|
|
38
|
+
throw std::runtime_error("Unistyles was loaded, but it's not configured. Did you forget to call StyleSheet.configure? If you don't want to use any themes or breakpoints, simply call it with an empty object {}.");
|
|
39
|
+
}
|
|
40
40
|
|
|
41
|
-
return
|
|
41
|
+
return *this->_state;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
void core::UnistylesRegistry::createState(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this->_states.emplace(
|
|
48
|
-
std::piecewise_construct,
|
|
49
|
-
std::forward_as_tuple(&rt),
|
|
50
|
-
std::forward_as_tuple(rt)
|
|
51
|
-
);
|
|
44
|
+
void core::UnistylesRegistry::createState() {
|
|
45
|
+
this->_state = std::make_unique<UnistylesState>();
|
|
52
46
|
}
|
|
53
47
|
|
|
54
48
|
void core::UnistylesRegistry::updateTheme(jsi::Runtime& rt, std::string& themeName, jsi::Function&& callback) {
|
|
55
|
-
auto& state = this->getState(
|
|
49
|
+
auto& state = this->getState();
|
|
56
50
|
auto it = state._jsThemes.find(themeName);
|
|
57
51
|
|
|
58
52
|
helpers::assertThat(rt, it != state._jsThemes.end(), "Unistyles: You're trying to update theme '" + themeName + "' but it wasn't registered.");
|
|
@@ -70,22 +64,36 @@ void core::UnistylesRegistry::linkShadowNodeWithUnistyle(
|
|
|
70
64
|
std::vector<std::shared_ptr<UnistyleData>>& unistylesData
|
|
71
65
|
) {
|
|
72
66
|
this->trafficController.withLock([this, &rt, &unistylesData, shadowNodeFamily](){
|
|
67
|
+
// Clear suspension state if this family was previously suspended
|
|
68
|
+
if (_suspendedFamilies.erase(shadowNodeFamily) > 0) {
|
|
69
|
+
auto* mutableFamily = const_cast<ShadowNodeFamily*>(shadowNodeFamily);
|
|
70
|
+
mutableFamily->nativeProps_DEPRECATED.reset();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
73
|
shadow::ShadowLeafUpdates updates;
|
|
74
74
|
auto parser = parser::Parser(nullptr);
|
|
75
75
|
|
|
76
|
-
std::for_each(unistylesData.begin(), unistylesData.end(), [this,
|
|
77
|
-
this->_shadowRegistry[
|
|
76
|
+
std::for_each(unistylesData.begin(), unistylesData.end(), [this, shadowNodeFamily](std::shared_ptr<UnistyleData> unistyleData){
|
|
77
|
+
this->_shadowRegistry[shadowNodeFamily].emplace_back(unistyleData);
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
updates[shadowNodeFamily] = parser.parseStylesToShadowTreeStyles(rt, unistylesData);
|
|
81
81
|
|
|
82
|
+
auto* mutableFamily = const_cast<ShadowNodeFamily*>(shadowNodeFamily);
|
|
83
|
+
|
|
84
|
+
if (mutableFamily->nativeProps_DEPRECATED) {
|
|
85
|
+
mutableFamily->nativeProps_DEPRECATED->update(updates[shadowNodeFamily]);
|
|
86
|
+
} else {
|
|
87
|
+
mutableFamily->nativeProps_DEPRECATED = std::make_unique<folly::dynamic>(updates[shadowNodeFamily]);
|
|
88
|
+
}
|
|
89
|
+
|
|
82
90
|
this->trafficController.setUpdates(updates);
|
|
83
91
|
this->trafficController.resumeUnistylesTraffic();
|
|
84
92
|
});
|
|
85
93
|
}
|
|
86
94
|
|
|
87
|
-
void core::UnistylesRegistry::removeDuplicatedUnistyles(
|
|
88
|
-
auto targetFamilyUnistyles = this->_shadowRegistry[
|
|
95
|
+
void core::UnistylesRegistry::removeDuplicatedUnistyles(const ShadowNodeFamily *shadowNodeFamily, std::vector<core::Unistyle::Shared>& unistyles) {
|
|
96
|
+
auto targetFamilyUnistyles = this->_shadowRegistry[shadowNodeFamily];
|
|
89
97
|
|
|
90
98
|
unistyles.erase(
|
|
91
99
|
std::remove_if(
|
|
@@ -105,32 +113,41 @@ void core::UnistylesRegistry::removeDuplicatedUnistyles(jsi::Runtime& rt, const
|
|
|
105
113
|
);
|
|
106
114
|
}
|
|
107
115
|
|
|
108
|
-
void core::UnistylesRegistry::unlinkShadowNodeWithUnistyles(
|
|
109
|
-
this->trafficController.withLock([this,
|
|
110
|
-
this->_shadowRegistry
|
|
116
|
+
void core::UnistylesRegistry::unlinkShadowNodeWithUnistyles(const ShadowNodeFamily* shadowNodeFamily) {
|
|
117
|
+
this->trafficController.withLock([this, shadowNodeFamily](){
|
|
118
|
+
this->_shadowRegistry.erase(shadowNodeFamily);
|
|
119
|
+
this->_suspendedFamilies.erase(shadowNodeFamily);
|
|
111
120
|
this->trafficController.removeShadowNode(shadowNodeFamily);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
112
123
|
|
|
113
|
-
|
|
114
|
-
|
|
124
|
+
void core::UnistylesRegistry::suspendShadowNode(const ShadowNodeFamily* shadowNodeFamily) {
|
|
125
|
+
this->trafficController.withLock([this, shadowNodeFamily](){
|
|
126
|
+
if (this->_shadowRegistry.contains(shadowNodeFamily)) {
|
|
127
|
+
this->_suspendedFamilies.insert(shadowNodeFamily);
|
|
115
128
|
}
|
|
116
129
|
});
|
|
117
130
|
}
|
|
118
131
|
|
|
132
|
+
bool core::UnistylesRegistry::isSuspended(const ShadowNodeFamily* family) const noexcept {
|
|
133
|
+
return _suspendedFamilies.count(family) > 0;
|
|
134
|
+
}
|
|
135
|
+
|
|
119
136
|
std::shared_ptr<core::StyleSheet> core::UnistylesRegistry::addStyleSheet(jsi::Runtime& rt, core::StyleSheetType type, jsi::Object&& rawValue) {
|
|
120
137
|
int tag = _nextStyleSheetTag.fetch_add(1);
|
|
121
138
|
|
|
122
139
|
auto sheet = std::make_shared<core::StyleSheet>(tag, type, std::move(rawValue));
|
|
123
|
-
this->_styleSheetRegistry[
|
|
140
|
+
this->_styleSheetRegistry[tag] = sheet;
|
|
124
141
|
|
|
125
142
|
return sheet;
|
|
126
143
|
}
|
|
127
144
|
|
|
128
|
-
core::DependencyMap core::UnistylesRegistry::buildDependencyMap(
|
|
145
|
+
core::DependencyMap core::UnistylesRegistry::buildDependencyMap(std::vector<UnistyleDependency>& deps) {
|
|
129
146
|
core::DependencyMap dependencyMap;
|
|
130
147
|
|
|
131
148
|
std::unordered_set<UnistyleDependency> uniqueDependencies(deps.begin(), deps.end());
|
|
132
149
|
|
|
133
|
-
for (const auto& [family, unistyles] : this->_shadowRegistry
|
|
150
|
+
for (const auto& [family, unistyles] : this->_shadowRegistry) {
|
|
134
151
|
bool hasAnyOfDependencies = false;
|
|
135
152
|
|
|
136
153
|
// Check if any dependency matches
|
|
@@ -171,7 +188,7 @@ void core::UnistylesRegistry::shadowLeafUpdateFromUnistyle(jsi::Runtime& rt, Uni
|
|
|
171
188
|
? std::make_optional(maybePressableId.asString(rt).utf8(rt))
|
|
172
189
|
: std::nullopt;
|
|
173
190
|
|
|
174
|
-
for (const auto& [family, unistyles] : this->_shadowRegistry
|
|
191
|
+
for (const auto& [family, unistyles] : this->_shadowRegistry) {
|
|
175
192
|
for (const auto& unistyleData : unistyles) {
|
|
176
193
|
if (unistyleData->unistyle == unistyle) {
|
|
177
194
|
updates[family] = parser.parseStylesToShadowTreeStyles(rt, { unistyleData });
|
|
@@ -183,7 +200,7 @@ void core::UnistylesRegistry::shadowLeafUpdateFromUnistyle(jsi::Runtime& rt, Uni
|
|
|
183
200
|
});
|
|
184
201
|
}
|
|
185
202
|
|
|
186
|
-
std::vector<std::shared_ptr<core::StyleSheet>>core::UnistylesRegistry::getStyleSheetsToRefresh(
|
|
203
|
+
std::vector<std::shared_ptr<core::StyleSheet>>core::UnistylesRegistry::getStyleSheetsToRefresh(std::vector<UnistyleDependency>& unistylesDependencies) {
|
|
187
204
|
std::vector<std::shared_ptr<core::StyleSheet>> stylesheetsToRefresh;
|
|
188
205
|
std::unordered_set<UnistyleDependency> depSet(
|
|
189
206
|
unistylesDependencies.begin(),
|
|
@@ -197,8 +214,6 @@ std::vector<std::shared_ptr<core::StyleSheet>>core::UnistylesRegistry::getStyleS
|
|
|
197
214
|
return stylesheetsToRefresh;
|
|
198
215
|
}
|
|
199
216
|
|
|
200
|
-
auto& styleSheets = this->_styleSheetRegistry[&rt];
|
|
201
|
-
|
|
202
217
|
auto hasMatchingDependency = [&depSet](const auto& unistyles) {
|
|
203
218
|
for (const auto& [_, unistyle] : unistyles) {
|
|
204
219
|
for (const auto& dep : unistyle->dependencies) {
|
|
@@ -211,7 +226,7 @@ std::vector<std::shared_ptr<core::StyleSheet>>core::UnistylesRegistry::getStyleS
|
|
|
211
226
|
return false;
|
|
212
227
|
};
|
|
213
228
|
|
|
214
|
-
for (const auto& [_, styleSheet] :
|
|
229
|
+
for (const auto& [_, styleSheet] : this->_styleSheetRegistry) {
|
|
215
230
|
if (styleSheet->type == StyleSheetType::ThemableWithMiniRuntime || styleSheet->type == StyleSheetType::Static) {
|
|
216
231
|
if (hasMatchingDependency(styleSheet->unistyles)) {
|
|
217
232
|
stylesheetsToRefresh.emplace_back(styleSheet);
|
|
@@ -226,8 +241,8 @@ std::vector<std::shared_ptr<core::StyleSheet>>core::UnistylesRegistry::getStyleS
|
|
|
226
241
|
return stylesheetsToRefresh;
|
|
227
242
|
}
|
|
228
243
|
|
|
229
|
-
core::Unistyle::Shared core::UnistylesRegistry::getUnistyleById(
|
|
230
|
-
for (auto& pair: this->_styleSheetRegistry
|
|
244
|
+
core::Unistyle::Shared core::UnistylesRegistry::getUnistyleById(std::string unistyleID) {
|
|
245
|
+
for (auto& pair: this->_styleSheetRegistry) {
|
|
231
246
|
auto [_, stylesheet] = pair;
|
|
232
247
|
|
|
233
248
|
for (auto unistylePair: stylesheet->unistyles) {
|
|
@@ -251,16 +266,10 @@ void core::UnistylesRegistry::setScopedTheme(std::optional<std::string> themeNam
|
|
|
251
266
|
}
|
|
252
267
|
|
|
253
268
|
void core::UnistylesRegistry::destroy() {
|
|
254
|
-
this->
|
|
269
|
+
this->_state.reset();
|
|
255
270
|
this->_styleSheetRegistry.clear();
|
|
256
271
|
this->_shadowRegistry.clear();
|
|
272
|
+
this->_suspendedFamilies.clear();
|
|
257
273
|
this->_scopedTheme = std::nullopt;
|
|
258
274
|
_nextStyleSheetTag.store(0);
|
|
259
275
|
}
|
|
260
|
-
|
|
261
|
-
void core::UnistylesRegistry::destroyState(jsi::Runtime* rt) {
|
|
262
|
-
this->_states.erase(rt);
|
|
263
|
-
this->_styleSheetRegistry.erase(rt);
|
|
264
|
-
this->_shadowRegistry.erase(rt);
|
|
265
|
-
this->_scopedTheme = std::nullopt;
|
|
266
|
-
}
|
|
@@ -32,35 +32,37 @@ struct UnistylesRegistry: public StyleSheetRegistry {
|
|
|
32
32
|
bool shouldUsePointsForBreakpoints = false;
|
|
33
33
|
|
|
34
34
|
void registerTheme(jsi::Runtime& rt, std::string name, jsi::Value& theme);
|
|
35
|
-
void registerBreakpoints(
|
|
36
|
-
void setPrefersAdaptiveThemes(
|
|
37
|
-
void setInitialThemeName(
|
|
35
|
+
void registerBreakpoints(std::vector<std::pair<std::string, double>>& sortedBreakpoints);
|
|
36
|
+
void setPrefersAdaptiveThemes(bool prefersAdaptiveThemes);
|
|
37
|
+
void setInitialThemeName(std::string themeName);
|
|
38
38
|
void updateTheme(jsi::Runtime& rt, std::string& themeName, jsi::Function&& callback);
|
|
39
39
|
|
|
40
|
-
UnistylesState& getState(
|
|
41
|
-
void createState(
|
|
42
|
-
std::vector<std::shared_ptr<core::StyleSheet>> getStyleSheetsToRefresh(
|
|
40
|
+
UnistylesState& getState();
|
|
41
|
+
void createState();
|
|
42
|
+
std::vector<std::shared_ptr<core::StyleSheet>> getStyleSheetsToRefresh(std::vector<UnistyleDependency>& unistylesDependencies);
|
|
43
43
|
void linkShadowNodeWithUnistyle(jsi::Runtime& rt, const ShadowNodeFamily*, std::vector<std::shared_ptr<UnistyleData>>& unistylesData);
|
|
44
|
-
void unlinkShadowNodeWithUnistyles(
|
|
44
|
+
void unlinkShadowNodeWithUnistyles(const ShadowNodeFamily*);
|
|
45
|
+
void suspendShadowNode(const ShadowNodeFamily*);
|
|
46
|
+
bool isSuspended(const ShadowNodeFamily*) const noexcept;
|
|
45
47
|
std::shared_ptr<core::StyleSheet> addStyleSheet(jsi::Runtime& rt, core::StyleSheetType type, jsi::Object&& rawValue);
|
|
46
|
-
DependencyMap buildDependencyMap(
|
|
48
|
+
DependencyMap buildDependencyMap(std::vector<UnistyleDependency>& deps);
|
|
47
49
|
void shadowLeafUpdateFromUnistyle(jsi::Runtime& rt, Unistyle::Shared unistyle, jsi::Value& maybePressableId);
|
|
48
50
|
shadow::ShadowTrafficController trafficController{};
|
|
49
51
|
const std::optional<std::string> getScopedTheme();
|
|
50
|
-
void removeDuplicatedUnistyles(
|
|
52
|
+
void removeDuplicatedUnistyles(const ShadowNodeFamily* shadowNodeFamily, std::vector<core::Unistyle::Shared>& unistyles);
|
|
51
53
|
void setScopedTheme(std::optional<std::string> themeName);
|
|
52
|
-
core::Unistyle::Shared getUnistyleById(
|
|
54
|
+
core::Unistyle::Shared getUnistyleById(std::string unistyleID);
|
|
53
55
|
void destroy();
|
|
54
|
-
void destroyState(jsi::Runtime* rt);
|
|
55
56
|
|
|
56
57
|
private:
|
|
57
58
|
UnistylesRegistry() = default;
|
|
58
59
|
|
|
59
60
|
static std::atomic<int> _nextStyleSheetTag;
|
|
60
61
|
std::optional<std::string> _scopedTheme{};
|
|
61
|
-
std::
|
|
62
|
-
std::unordered_map<
|
|
63
|
-
std::unordered_map<
|
|
62
|
+
std::unique_ptr<UnistylesState> _state{};
|
|
63
|
+
std::unordered_map<int, std::shared_ptr<core::StyleSheet>> _styleSheetRegistry{};
|
|
64
|
+
std::unordered_map<const ShadowNodeFamily*, std::vector<std::shared_ptr<UnistyleData>>> _shadowRegistry{};
|
|
65
|
+
std::unordered_set<const ShadowNodeFamily*> _suspendedFamilies{};
|
|
64
66
|
};
|
|
65
67
|
|
|
66
68
|
inline UnistylesRegistry& UnistylesRegistry::get() {
|
|
@@ -12,7 +12,9 @@ bool core::UnistylesState::hasAdaptiveThemes() {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
void core::UnistylesState::setTheme(std::string themeName) {
|
|
15
|
-
|
|
15
|
+
if (!helpers::vecContainsKeys(this->_registeredThemeNames, {themeName})) {
|
|
16
|
+
throw std::runtime_error("Unistyles: You're trying to set theme to: '" + std::string(themeName) + "', but it wasn't registered.");
|
|
17
|
+
}
|
|
16
18
|
|
|
17
19
|
if (themeName != this->_currentThemeName) {
|
|
18
20
|
this->_currentThemeName = themeName;
|
|
@@ -23,33 +25,33 @@ std::optional<std::string>& core::UnistylesState::getCurrentThemeName() {
|
|
|
23
25
|
return this->_currentThemeName;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
jsi::Object core::UnistylesState::getCurrentJSTheme() {
|
|
28
|
+
jsi::Object core::UnistylesState::getCurrentJSTheme(jsi::Runtime& rt) {
|
|
27
29
|
auto hasSomeThemes = _registeredThemeNames.size() > 0;
|
|
28
30
|
|
|
29
31
|
if (!hasSomeThemes && !this->hasUserConfig) {
|
|
30
|
-
helpers::assertThat(
|
|
32
|
+
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
33
|
}
|
|
32
34
|
|
|
33
35
|
// return empty object, if user didn't register any themes
|
|
34
36
|
if (!hasSomeThemes) {
|
|
35
|
-
return jsi::Object(
|
|
37
|
+
return jsi::Object(rt);
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
helpers::assertThat(
|
|
40
|
+
helpers::assertThat(rt, _currentThemeName.has_value(), "Unistyles: One of your stylesheets is trying to get the theme, but no theme has been selected yet. Did you forget to select an initial theme?");
|
|
39
41
|
|
|
40
42
|
auto it = this->_jsThemes.find(_currentThemeName.value());
|
|
41
43
|
|
|
42
|
-
helpers::assertThat(
|
|
44
|
+
helpers::assertThat(rt, it != this->_jsThemes.end(), "Unistyles: You're trying to get theme '" + _currentThemeName.value() + "', but it was not registered. Did you forget to register it with StyleSheet.configure?");
|
|
43
45
|
|
|
44
|
-
return it->second.asObject(
|
|
46
|
+
return it->second.asObject(rt);
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
jsi::Object core::UnistylesState::getJSThemeByName(std::string& themeName) {
|
|
49
|
+
jsi::Object core::UnistylesState::getJSThemeByName(jsi::Runtime& rt, std::string& themeName) {
|
|
48
50
|
auto it = this->_jsThemes.find(themeName);
|
|
49
51
|
|
|
50
|
-
helpers::assertThat(
|
|
52
|
+
helpers::assertThat(rt, it != this->_jsThemes.end(), "Unistyles: You're trying to get theme '" + themeName + "', but it was not registered. Did you forget to register it with StyleSheet.configure?");
|
|
51
53
|
|
|
52
|
-
return it->second.asObject(
|
|
54
|
+
return it->second.asObject(rt);
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
void core::UnistylesState::computeCurrentBreakpoint(int screenWidth) {
|
|
@@ -99,28 +101,28 @@ void core::UnistylesState::registerParseBoxShadowString(jsi::Function&& fn) {
|
|
|
99
101
|
this->_parseBoxShadowStringFn = std::make_shared<jsi::Function>(std::move(fn));
|
|
100
102
|
}
|
|
101
103
|
|
|
102
|
-
int core::UnistylesState::parseColor(jsi::Value& maybeColor) {
|
|
104
|
+
int core::UnistylesState::parseColor(jsi::Runtime& rt, jsi::Value& maybeColor) {
|
|
103
105
|
if (!maybeColor.isString()) {
|
|
104
106
|
return 0;
|
|
105
107
|
}
|
|
106
108
|
|
|
107
|
-
auto colorString = maybeColor.asString(
|
|
109
|
+
auto colorString = maybeColor.asString(rt);
|
|
108
110
|
|
|
109
|
-
if (!this->_colorCache.contains(colorString.utf8(
|
|
111
|
+
if (!this->_colorCache.contains(colorString.utf8(rt).c_str())) {
|
|
110
112
|
#ifdef ANDROID
|
|
111
|
-
int color = this->_processColorFn.get()->call(
|
|
113
|
+
int color = this->_processColorFn.get()->call(rt, colorString).asNumber();
|
|
112
114
|
#else
|
|
113
|
-
uint32_t color = this->_processColorFn.get()->call(
|
|
115
|
+
uint32_t color = this->_processColorFn.get()->call(rt, colorString).asNumber();
|
|
114
116
|
#endif
|
|
115
117
|
|
|
116
|
-
this->_colorCache[colorString.utf8(
|
|
118
|
+
this->_colorCache[colorString.utf8(rt).c_str()] = color ? color : 0;
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
return this->_colorCache[colorString.utf8(
|
|
121
|
+
return this->_colorCache[colorString.utf8(rt).c_str()];
|
|
120
122
|
}
|
|
121
123
|
|
|
122
|
-
jsi::Array core::UnistylesState::parseBoxShadowString(std::string&& boxShadowString) {
|
|
123
|
-
jsi::Value result = this->_parseBoxShadowStringFn.get()->call(
|
|
124
|
+
jsi::Array core::UnistylesState::parseBoxShadowString(jsi::Runtime& rt, std::string&& boxShadowString) {
|
|
125
|
+
jsi::Value result = this->_parseBoxShadowStringFn.get()->call(rt, boxShadowString);
|
|
124
126
|
|
|
125
|
-
return result.asObject(
|
|
127
|
+
return result.asObject(rt).asArray(rt);
|
|
126
128
|
}
|
|
@@ -13,7 +13,7 @@ struct UnistylesRegistry;
|
|
|
13
13
|
using namespace facebook;
|
|
14
14
|
|
|
15
15
|
struct UnistylesState {
|
|
16
|
-
UnistylesState(
|
|
16
|
+
UnistylesState() = default;
|
|
17
17
|
UnistylesState(const UnistylesState&) = delete;
|
|
18
18
|
UnistylesState(const UnistylesState&&) = delete;
|
|
19
19
|
|
|
@@ -29,16 +29,15 @@ struct UnistylesState {
|
|
|
29
29
|
std::optional<std::string> getCurrentBreakpointName();
|
|
30
30
|
std::vector<std::pair<std::string, double>> getSortedBreakpointPairs();
|
|
31
31
|
|
|
32
|
-
jsi::Object getCurrentJSTheme();
|
|
33
|
-
jsi::Object getJSThemeByName(std::string& themeName);
|
|
34
|
-
int parseColor(jsi::Value& color);
|
|
35
|
-
jsi::Array parseBoxShadowString(std::string&& boxShadowString);
|
|
32
|
+
jsi::Object getCurrentJSTheme(jsi::Runtime& rt);
|
|
33
|
+
jsi::Object getJSThemeByName(jsi::Runtime& rt, std::string& themeName);
|
|
34
|
+
int parseColor(jsi::Runtime& rt, jsi::Value& color);
|
|
35
|
+
jsi::Array parseBoxShadowString(jsi::Runtime& rt, std::string&& boxShadowString);
|
|
36
36
|
void computeCurrentBreakpoint(int screenWidth);
|
|
37
37
|
void registerProcessColorFunction(jsi::Function&& fn);
|
|
38
38
|
void registerParseBoxShadowString(jsi::Function&& fn);
|
|
39
39
|
|
|
40
40
|
private:
|
|
41
|
-
jsi::Runtime* _rt;
|
|
42
41
|
std::unordered_map<std::string, jsi::Value> _jsThemes{};
|
|
43
42
|
std::optional<bool> _prefersAdaptiveThemes = std::nullopt;
|
|
44
43
|
std::optional<std::string> _initialThemeName = std::nullopt;
|
|
@@ -13,7 +13,7 @@ jsi::Value HybridShadowRegistry::link(jsi::Runtime &rt, const jsi::Value &thisVa
|
|
|
13
13
|
auto& registry = core::UnistylesRegistry::get();
|
|
14
14
|
|
|
15
15
|
// this is special case for Animated, and prevents appending same unistyles to node
|
|
16
|
-
registry.removeDuplicatedUnistyles(
|
|
16
|
+
registry.removeDuplicatedUnistyles(&shadowNodeWrapper->getFamily(), unistyleWrappers);
|
|
17
17
|
|
|
18
18
|
if (unistyleWrappers.empty()) {
|
|
19
19
|
return jsi::Value::undefined();
|
|
@@ -45,7 +45,7 @@ jsi::Value HybridShadowRegistry::link(jsi::Runtime &rt, const jsi::Value &thisVa
|
|
|
45
45
|
if (scopedTheme.has_value()) {
|
|
46
46
|
auto themeName = scopedTheme.value();
|
|
47
47
|
|
|
48
|
-
helpers::assertThat(rt, registry.getState(
|
|
48
|
+
helpers::assertThat(rt, registry.getState().hasTheme(themeName), "Unistyles: You're trying to use scoped theme '" + themeName + "' but it wasn't registered.");
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
auto parser = parser::Parser(this->_unistylesRuntime);
|
|
@@ -107,7 +107,18 @@ jsi::Value HybridShadowRegistry::unlink(jsi::Runtime &rt, const jsi::Value &this
|
|
|
107
107
|
|
|
108
108
|
auto& registry = core::UnistylesRegistry::get();
|
|
109
109
|
|
|
110
|
-
registry.unlinkShadowNodeWithUnistyles(
|
|
110
|
+
registry.unlinkShadowNodeWithUnistyles(&shadowNodeWrapper->getFamily());
|
|
111
|
+
|
|
112
|
+
return jsi::Value::undefined();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
jsi::Value HybridShadowRegistry::suspend(jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
|
116
|
+
helpers::assertThat(rt, count == 1, "Unistyles: Invalid babel transform 'ShadowRegistry suspend' expected 1 argument.");
|
|
117
|
+
|
|
118
|
+
auto shadowNodeWrapper = getShadowNodeFromRef(rt, args[0]);
|
|
119
|
+
auto& registry = core::UnistylesRegistry::get();
|
|
120
|
+
|
|
121
|
+
registry.suspendShadowNode(&shadowNodeWrapper->getFamily());
|
|
111
122
|
|
|
112
123
|
return jsi::Value::undefined();
|
|
113
124
|
}
|
|
@@ -22,6 +22,10 @@ struct HybridShadowRegistry: public HybridUnistylesShadowRegistrySpec {
|
|
|
22
22
|
const jsi::Value& thisValue,
|
|
23
23
|
const jsi::Value* args,
|
|
24
24
|
size_t count);
|
|
25
|
+
jsi::Value suspend(jsi::Runtime& rt,
|
|
26
|
+
const jsi::Value& thisValue,
|
|
27
|
+
const jsi::Value* args,
|
|
28
|
+
size_t count);
|
|
25
29
|
jsi::Value flush(jsi::Runtime& rt,
|
|
26
30
|
const jsi::Value& thisValue,
|
|
27
31
|
const jsi::Value* args,
|
|
@@ -41,6 +45,7 @@ struct HybridShadowRegistry: public HybridUnistylesShadowRegistrySpec {
|
|
|
41
45
|
registerHybrids(this, [](Prototype& prototype) {
|
|
42
46
|
prototype.registerRawHybridMethod("link", 2, &HybridShadowRegistry::link);
|
|
43
47
|
prototype.registerRawHybridMethod("unlink", 1, &HybridShadowRegistry::unlink);
|
|
48
|
+
prototype.registerRawHybridMethod("suspend", 1, &HybridShadowRegistry::suspend);
|
|
44
49
|
prototype.registerRawHybridMethod("flush", 0, &HybridShadowRegistry::flush);
|
|
45
50
|
prototype.registerRawHybridMethod("setScopedTheme", 1, &HybridShadowRegistry::setScopedTheme);
|
|
46
51
|
prototype.registerRawHybridMethod("getScopedTheme", 0, &HybridShadowRegistry::getScopedTheme);
|