From 353fbd2bd328503daa7be5f350bed88014a00e9b Mon Sep 17 00:00:00 2001 From: Jacek Pudysz Date: Thu, 23 Apr 2026 22:40:19 +0200 Subject: [PATCH 1/2] fix: no ime updates in withUnistyles wrapped components --- .../cxx/hybridObjects/HybridStyleSheet.cpp | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.cpp b/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.cpp index be22e985..ad1233e5 100644 --- a/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.cpp +++ b/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.cpp @@ -276,27 +276,28 @@ void HybridStyleSheet::onPlatformDependenciesChange(std::vectornotifyJSListeners(unistyleDependencies); - } - // in a later step, we will rebuild only Unistyles with mounted StyleSheets // however, user may have StyleSheets with components that haven't mounted yet // we need to rebuild all dependent StyleSheets as well auto dependentStyleSheets = registry.getStyleSheetsToRefresh(unistyleDependencies); - parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, std::nullopt); - - // we need to stop here if there is nothing to update at the moment, - // but we need to compute dependentStyleSheets - if (dependencyMap.empty()) { + if (dependencyMap.empty() && dependentStyleSheets.empty()) { return; } - parser.rebuildShadowLeafUpdates(rt, dependencyMap); + // rebuild rawValue for all affected unistyles BEFORE notifying listeners + // so JS consumers (withUnistyles) re-render with fresh closures + parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, std::nullopt); + + if (!dependencyMap.empty()) { + parser.rebuildShadowLeafUpdates(rt, dependencyMap); + } self->notifyJSListeners(unistyleDependencies); - shadow::ShadowTreeManager::updateShadowTree(rt); + + if (!dependencyMap.empty()) { + shadow::ShadowTreeManager::updateShadowTree(rt); + } }); } @@ -341,27 +342,28 @@ void HybridStyleSheet::onPlatformNativeDependenciesChange(std::vectornotifyJSListeners(unistyleDependencies); - } - // in a later step, we will rebuild only Unistyles with mounted StyleSheets // however, user may have StyleSheets with components that haven't mounted yet // we need to rebuild all dependent StyleSheets as well auto dependentStyleSheets = registry.getStyleSheetsToRefresh(unistyleDependencies); - parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, miniRuntime); - - // we need to stop here if there is nothing to update at the moment, - // but we need to compute dependentStyleSheets - if (dependencyMap.empty()) { + if (dependencyMap.empty() && dependentStyleSheets.empty()) { return; } - parser.rebuildShadowLeafUpdates(rt, dependencyMap); + // rebuild rawValue for all affected unistyles BEFORE notifying listeners + // so JS consumers (withUnistyles) re-render with fresh closures + parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, miniRuntime); + + if (!dependencyMap.empty()) { + parser.rebuildShadowLeafUpdates(rt, dependencyMap); + } self->notifyJSListeners(unistyleDependencies); - shadow::ShadowTreeManager::updateShadowTree(rt); + + if (!dependencyMap.empty()) { + shadow::ShadowTreeManager::updateShadowTree(rt); + } }); } @@ -384,21 +386,25 @@ void HybridStyleSheet::onImeChange(UnistylesNativeMiniRuntime miniRuntime) { auto parser = parser::Parser(self->_unistylesRuntime); auto dependencyMap = registry.buildDependencyMap(dependencies); - if (dependencyMap.empty()) { - self->notifyJSListeners(dependencies); + // include StyleSheets consumed only by JS (withUnistyles) - they aren't in dependencyMap + // but their rawValue must still be refreshed so rerenders read fresh closures + auto dependentStyleSheets = registry.getStyleSheetsToRefresh(dependencies); + if (dependencyMap.empty() && dependentStyleSheets.empty()) { return; } - // we don't care about other unmounted stylesheets as their not visible - // so user won't see any changes - std::vector> dependentStyleSheets; - parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, miniRuntime); - parser.rebuildShadowLeafUpdates(rt, dependencyMap); + + if (!dependencyMap.empty()) { + parser.rebuildShadowLeafUpdates(rt, dependencyMap); + } self->notifyJSListeners(dependencies); - shadow::ShadowTreeManager::updateShadowTree(rt); + + if (!dependencyMap.empty()) { + shadow::ShadowTreeManager::updateShadowTree(rt); + } }); } From 5e66c3519bce7f61b4c3d19fa6605c3ecdb5ec95 Mon Sep 17 00:00:00 2001 From: Jacek Pudysz Date: Thu, 23 Apr 2026 22:58:53 +0200 Subject: [PATCH 2/2] chore: unify all paths to applyDependencyChanges --- .../cxx/hybridObjects/HybridStyleSheet.cpp | 94 +++++-------------- .../cxx/hybridObjects/HybridStyleSheet.h | 2 + 2 files changed, 28 insertions(+), 68 deletions(-) diff --git a/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.cpp b/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.cpp index ad1233e5..ae74c57f 100644 --- a/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.cpp +++ b/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.cpp @@ -271,33 +271,9 @@ void HybridStyleSheet::onPlatformDependenciesChange(std::vector_unistylesRuntime); auto unistyleDependencies = dependencies; - auto dependencyMap = registry.buildDependencyMap(unistyleDependencies); - - // in a later step, we will rebuild only Unistyles with mounted StyleSheets - // however, user may have StyleSheets with components that haven't mounted yet - // we need to rebuild all dependent StyleSheets as well - auto dependentStyleSheets = registry.getStyleSheetsToRefresh(unistyleDependencies); - - if (dependencyMap.empty() && dependentStyleSheets.empty()) { - return; - } - - // rebuild rawValue for all affected unistyles BEFORE notifying listeners - // so JS consumers (withUnistyles) re-render with fresh closures - parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, std::nullopt); - - if (!dependencyMap.empty()) { - parser.rebuildShadowLeafUpdates(rt, dependencyMap); - } - - self->notifyJSListeners(unistyleDependencies); - if (!dependencyMap.empty()) { - shadow::ShadowTreeManager::updateShadowTree(rt); - } + self->applyDependencyChanges(rt, unistyleDependencies, std::nullopt); }); } @@ -317,7 +293,6 @@ void HybridStyleSheet::onPlatformNativeDependenciesChange(std::vector_unistylesRuntime); auto unistyleDependencies = std::move(dependencies); // re-compute new breakpoint @@ -340,30 +315,7 @@ void HybridStyleSheet::onPlatformNativeDependenciesChange(std::vector_unistylesRuntime->includeDependenciesForColorSchemeChange(unistyleDependencies); } - auto dependencyMap = registry.buildDependencyMap(unistyleDependencies); - - // in a later step, we will rebuild only Unistyles with mounted StyleSheets - // however, user may have StyleSheets with components that haven't mounted yet - // we need to rebuild all dependent StyleSheets as well - auto dependentStyleSheets = registry.getStyleSheetsToRefresh(unistyleDependencies); - - if (dependencyMap.empty() && dependentStyleSheets.empty()) { - return; - } - - // rebuild rawValue for all affected unistyles BEFORE notifying listeners - // so JS consumers (withUnistyles) re-render with fresh closures - parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, miniRuntime); - - if (!dependencyMap.empty()) { - parser.rebuildShadowLeafUpdates(rt, dependencyMap); - } - - self->notifyJSListeners(unistyleDependencies); - - if (!dependencyMap.empty()) { - shadow::ShadowTreeManager::updateShadowTree(rt); - } + self->applyDependencyChanges(rt, unistyleDependencies, miniRuntime); }); } @@ -382,30 +334,36 @@ void HybridStyleSheet::onImeChange(UnistylesNativeMiniRuntime miniRuntime) { } std::vector dependencies{UnistyleDependency::IME}; - auto& registry = core::UnistylesRegistry::get(); - auto parser = parser::Parser(self->_unistylesRuntime); - auto dependencyMap = registry.buildDependencyMap(dependencies); - // include StyleSheets consumed only by JS (withUnistyles) - they aren't in dependencyMap - // but their rawValue must still be refreshed so rerenders read fresh closures - auto dependentStyleSheets = registry.getStyleSheetsToRefresh(dependencies); + self->applyDependencyChanges(rt, dependencies, miniRuntime); + }); +} - if (dependencyMap.empty() && dependentStyleSheets.empty()) { - return; - } +void HybridStyleSheet::applyDependencyChanges(jsi::Runtime& rt, std::vector& dependencies, std::optional maybeMiniRuntime) { + auto& registry = core::UnistylesRegistry::get(); + auto parser = parser::Parser(this->_unistylesRuntime); + auto dependencyMap = registry.buildDependencyMap(dependencies); - parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, miniRuntime); + // include StyleSheets consumed only by JS (withUnistyles) — they aren't in dependencyMap + // but their rawValue must still be refreshed so rerenders read fresh closures + auto dependentStyleSheets = registry.getStyleSheetsToRefresh(dependencies); - if (!dependencyMap.empty()) { - parser.rebuildShadowLeafUpdates(rt, dependencyMap); - } + if (dependencyMap.empty() && dependentStyleSheets.empty()) { + return; + } - self->notifyJSListeners(dependencies); + // rebuild rawValue BEFORE notifying listeners so JS rerenders read fresh closures + parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, maybeMiniRuntime); - if (!dependencyMap.empty()) { - shadow::ShadowTreeManager::updateShadowTree(rt); - } - }); + if (!dependencyMap.empty()) { + parser.rebuildShadowLeafUpdates(rt, dependencyMap); + } + + this->notifyJSListeners(dependencies); + + if (!dependencyMap.empty()) { + shadow::ShadowTreeManager::updateShadowTree(rt); + } } void HybridStyleSheet::notifyJSListeners(std::vector& dependencies) { diff --git a/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.h b/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.h index 0df55858..6dea9d4f 100644 --- a/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.h +++ b/packages/unistyles/cxx/hybridObjects/HybridStyleSheet.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "HybridUnistylesRuntime.h" #include "HybridUnistylesStyleSheetSpec.hpp" @@ -69,6 +70,7 @@ struct HybridStyleSheet: public HybridUnistylesStyleSheetSpec { void onPlatformDependenciesChange(std::vector dependencies); void onPlatformNativeDependenciesChange(std::vector dependencies, UnistylesNativeMiniRuntime miniRuntime); void onImeChange(UnistylesNativeMiniRuntime miniRuntime); + void applyDependencyChanges(jsi::Runtime& rt, std::vector& dependencies, std::optional maybeMiniRuntime); void notifyJSListeners(std::vector& dependencies); bool isInitialized = false;