react-native-unistyles 3.2.3 → 3.2.4

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 CHANGED
@@ -76,9 +76,6 @@ Then follow [installation guides](https://unistyl.es/v3/start/getting-started) f
76
76
  <a href="https://github.com/AdiRishi">
77
77
  <img src="https://avatars.githubusercontent.com/u/8351234?v=4" height="70px" width="70px" alt="AdiRishi" />
78
78
  </a>
79
- <a href="https://github.com/cybercarrot">
80
- <img src="https://avatars.githubusercontent.com/u/6837094?v=4" height="70px" width="70px" alt="cybercarrot" />
81
- </a>
82
79
 
83
80
 
84
81
  ## Past sponsors
@@ -155,6 +152,9 @@ Then follow [installation guides](https://unistyl.es/v3/start/getting-started) f
155
152
  <a href="https://github.com/biw">
156
153
  <img src="https://avatars.githubusercontent.com/u/6139501?v=4" height="60px" width="60px" alt="biw" />
157
154
  </a>
155
+ <a href="https://github.com/cybercarrot">
156
+ <img src="https://avatars.githubusercontent.com/u/6837094?v=4" height="60px" width="60px" alt="cybercarrot" />
157
+ </a>
158
158
 
159
159
  ## Sponsor my work
160
160
 
@@ -158,8 +158,29 @@ inline static jsi::Value objectFromUnistyle(jsi::Runtime& rt, std::shared_ptr<Hy
158
158
  ) {
159
159
  auto& registry = UnistylesRegistry::get();
160
160
  auto unistyle = registry.getUnistyleById(unistyleID);
161
+ auto scopedTheme = registry.getScopedTheme();
162
+ parser::Parser parser(unistylesRuntime);
161
163
 
162
- parser::Parser(unistylesRuntime).rebuildUnistyle(rt, unistyle, variants, parsedArguments);
164
+ // scoped theme path — parse with scope so `withUnistyles`-wrapped
165
+ // components inside <ScopedTheme> reflect the scope instead of the global theme
166
+ if (scopedTheme.has_value() && unistyle->styleKey != helpers::EXOTIC_STYLE_KEY) {
167
+ std::vector<folly::dynamic> scopedArguments = parsedArguments.has_value()
168
+ ? parsedArguments.value()
169
+ : std::vector<folly::dynamic>{};
170
+
171
+ auto unistyleData = std::make_shared<UnistyleData>(unistyle, variants, scopedArguments, scopedTheme);
172
+ auto parsedStyleSheet = parser.getParsedStyleSheetForScopedTheme(rt, unistyle, scopedTheme.value());
173
+
174
+ if (!parsedStyleSheet.isUndefined()) {
175
+ parser.rebuildUnistyleWithScopedTheme(rt, parsedStyleSheet, unistyleData);
176
+
177
+ if (unistyleData->parsedStyle.has_value()) {
178
+ return jsi::Value(rt, unistyleData->parsedStyle.value()).asObject(rt);
179
+ }
180
+ }
181
+ }
182
+
183
+ parser.rebuildUnistyle(rt, unistyle, variants, parsedArguments);
163
184
 
164
185
  return jsi::Value(rt, unistyle->parsedStyle.value()).asObject(rt);
165
186
  });
@@ -271,32 +271,9 @@ void HybridStyleSheet::onPlatformDependenciesChange(std::vector<UnistyleDependen
271
271
  return;
272
272
  }
273
273
 
274
- auto& registry = core::UnistylesRegistry::get();
275
- auto parser = parser::Parser(self->_unistylesRuntime);
276
274
  auto unistyleDependencies = dependencies;
277
- auto dependencyMap = registry.buildDependencyMap(unistyleDependencies);
278
-
279
- if (dependencyMap.empty()) {
280
- self->notifyJSListeners(unistyleDependencies);
281
- }
282
-
283
- // in a later step, we will rebuild only Unistyles with mounted StyleSheets
284
- // however, user may have StyleSheets with components that haven't mounted yet
285
- // we need to rebuild all dependent StyleSheets as well
286
- auto dependentStyleSheets = registry.getStyleSheetsToRefresh(unistyleDependencies);
287
-
288
- parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, std::nullopt);
289
-
290
- // we need to stop here if there is nothing to update at the moment,
291
- // but we need to compute dependentStyleSheets
292
- if (dependencyMap.empty()) {
293
- return;
294
- }
295
-
296
- parser.rebuildShadowLeafUpdates(rt, dependencyMap);
297
275
 
298
- self->notifyJSListeners(unistyleDependencies);
299
- shadow::ShadowTreeManager::updateShadowTree(rt);
276
+ self->applyDependencyChanges(rt, unistyleDependencies, std::nullopt);
300
277
  });
301
278
  }
302
279
 
@@ -316,7 +293,6 @@ void HybridStyleSheet::onPlatformNativeDependenciesChange(std::vector<UnistyleDe
316
293
  }
317
294
 
318
295
  auto& registry = core::UnistylesRegistry::get();
319
- auto parser = parser::Parser(self->_unistylesRuntime);
320
296
  auto unistyleDependencies = std::move(dependencies);
321
297
 
322
298
  // re-compute new breakpoint
@@ -339,29 +315,7 @@ void HybridStyleSheet::onPlatformNativeDependenciesChange(std::vector<UnistyleDe
339
315
  self->_unistylesRuntime->includeDependenciesForColorSchemeChange(unistyleDependencies);
340
316
  }
341
317
 
342
- auto dependencyMap = registry.buildDependencyMap(unistyleDependencies);
343
-
344
- if (dependencyMap.empty()) {
345
- self->notifyJSListeners(unistyleDependencies);
346
- }
347
-
348
- // in a later step, we will rebuild only Unistyles with mounted StyleSheets
349
- // however, user may have StyleSheets with components that haven't mounted yet
350
- // we need to rebuild all dependent StyleSheets as well
351
- auto dependentStyleSheets = registry.getStyleSheetsToRefresh(unistyleDependencies);
352
-
353
- parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, miniRuntime);
354
-
355
- // we need to stop here if there is nothing to update at the moment,
356
- // but we need to compute dependentStyleSheets
357
- if (dependencyMap.empty()) {
358
- return;
359
- }
360
-
361
- parser.rebuildShadowLeafUpdates(rt, dependencyMap);
362
-
363
- self->notifyJSListeners(unistyleDependencies);
364
- shadow::ShadowTreeManager::updateShadowTree(rt);
318
+ self->applyDependencyChanges(rt, unistyleDependencies, miniRuntime);
365
319
  });
366
320
  }
367
321
 
@@ -380,26 +334,36 @@ void HybridStyleSheet::onImeChange(UnistylesNativeMiniRuntime miniRuntime) {
380
334
  }
381
335
 
382
336
  std::vector<UnistyleDependency> dependencies{UnistyleDependency::IME};
383
- auto& registry = core::UnistylesRegistry::get();
384
- auto parser = parser::Parser(self->_unistylesRuntime);
385
- auto dependencyMap = registry.buildDependencyMap(dependencies);
386
337
 
387
- if (dependencyMap.empty()) {
388
- self->notifyJSListeners(dependencies);
338
+ self->applyDependencyChanges(rt, dependencies, miniRuntime);
339
+ });
340
+ }
389
341
 
390
- return;
391
- }
342
+ void HybridStyleSheet::applyDependencyChanges(jsi::Runtime& rt, std::vector<UnistyleDependency>& dependencies, std::optional<UnistylesNativeMiniRuntime> maybeMiniRuntime) {
343
+ auto& registry = core::UnistylesRegistry::get();
344
+ auto parser = parser::Parser(this->_unistylesRuntime);
345
+ auto dependencyMap = registry.buildDependencyMap(dependencies);
346
+
347
+ // include StyleSheets consumed only by JS (withUnistyles) — they aren't in dependencyMap
348
+ // but their rawValue must still be refreshed so rerenders read fresh closures
349
+ auto dependentStyleSheets = registry.getStyleSheetsToRefresh(dependencies);
350
+
351
+ if (dependencyMap.empty() && dependentStyleSheets.empty()) {
352
+ return;
353
+ }
392
354
 
393
- // we don't care about other unmounted stylesheets as their not visible
394
- // so user won't see any changes
395
- std::vector<std::shared_ptr<core::StyleSheet>> dependentStyleSheets;
355
+ // rebuild rawValue BEFORE notifying listeners so JS rerenders read fresh closures
356
+ parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, maybeMiniRuntime);
396
357
 
397
- parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, miniRuntime);
358
+ if (!dependencyMap.empty()) {
398
359
  parser.rebuildShadowLeafUpdates(rt, dependencyMap);
360
+ }
361
+
362
+ this->notifyJSListeners(dependencies);
399
363
 
400
- self->notifyJSListeners(dependencies);
364
+ if (!dependencyMap.empty()) {
401
365
  shadow::ShadowTreeManager::updateShadowTree(rt);
402
- });
366
+ }
403
367
  }
404
368
 
405
369
  void HybridStyleSheet::notifyJSListeners(std::vector<UnistyleDependency>& dependencies) {
@@ -3,6 +3,7 @@
3
3
  #include <cmath>
4
4
  #include <jsi/jsi.h>
5
5
  #include <mutex>
6
+ #include <optional>
6
7
  #include <unordered_map>
7
8
  #include "HybridUnistylesRuntime.h"
8
9
  #include "HybridUnistylesStyleSheetSpec.hpp"
@@ -69,6 +70,7 @@ private:
69
70
  void onPlatformDependenciesChange(std::vector<UnistyleDependency> dependencies);
70
71
  void onPlatformNativeDependenciesChange(std::vector<UnistyleDependency> dependencies, UnistylesNativeMiniRuntime miniRuntime);
71
72
  void onImeChange(UnistylesNativeMiniRuntime miniRuntime);
73
+ void applyDependencyChanges(jsi::Runtime& rt, std::vector<UnistyleDependency>& dependencies, std::optional<UnistylesNativeMiniRuntime> maybeMiniRuntime);
72
74
  void notifyJSListeners(std::vector<UnistyleDependency>& dependencies);
73
75
 
74
76
  bool isInitialized = false;
@@ -494,7 +494,7 @@ jsi::Object parser::Parser::parseFirstLevel(jsi::Runtime& rt, Unistyle::Shared u
494
494
 
495
495
  return;
496
496
  }
497
-
497
+
498
498
  if (propertyValue.isBool() && propertyName == "includeFontPadding") {
499
499
  parsedStyle.setProperty(rt, jsi::PropNameID::forUtf8(rt, propertyName), propertyValue);
500
500
 
@@ -1008,6 +1008,15 @@ jsi::Value parser::Parser::parseSecondLevel(jsi::Runtime &rt, Unistyle::Shared u
1008
1008
  return;
1009
1009
  }
1010
1010
 
1011
+ // PlatformColor / DynamicColorIOS / Android ColorResource objects must
1012
+ // pass through unchanged — otherwise getValueFromBreakpoints treats them
1013
+ // as a breakpoint map and strips the color
1014
+ if (helpers::isPlatformColor(rt, nestedObjectStyle)) {
1015
+ parsedStyle.setProperty(rt, propertyName.c_str(), propertyValue);
1016
+
1017
+ return;
1018
+ }
1019
+
1011
1020
  auto isArray = nestedObjectStyle.isArray(rt);
1012
1021
 
1013
1022
  if (!isArray) {
@@ -9,6 +9,7 @@ package com.margelo.nitro.unistyles
9
9
 
10
10
  import androidx.annotation.Keep
11
11
  import com.facebook.proguard.annotations.DoNotStrip
12
+ import java.util.Objects
12
13
 
13
14
 
14
15
  /**
@@ -26,6 +27,20 @@ data class Dimensions(
26
27
  ) {
27
28
  /* primary constructor */
28
29
 
30
+ override fun equals(other: Any?): Boolean {
31
+ if (this === other) return true
32
+ if (other !is Dimensions) return false
33
+ return Objects.deepEquals(this.width, other.width)
34
+ && Objects.deepEquals(this.height, other.height)
35
+ }
36
+
37
+ override fun hashCode(): Int {
38
+ return arrayOf(
39
+ width,
40
+ height
41
+ ).contentDeepHashCode()
42
+ }
43
+
29
44
  companion object {
30
45
  /**
31
46
  * Constructor called from C++
@@ -9,6 +9,7 @@ package com.margelo.nitro.unistyles
9
9
 
10
10
  import androidx.annotation.Keep
11
11
  import com.facebook.proguard.annotations.DoNotStrip
12
+ import java.util.Objects
12
13
 
13
14
 
14
15
  /**
@@ -35,6 +36,26 @@ data class Insets(
35
36
  ) {
36
37
  /* primary constructor */
37
38
 
39
+ override fun equals(other: Any?): Boolean {
40
+ if (this === other) return true
41
+ if (other !is Insets) return false
42
+ return Objects.deepEquals(this.top, other.top)
43
+ && Objects.deepEquals(this.bottom, other.bottom)
44
+ && Objects.deepEquals(this.left, other.left)
45
+ && Objects.deepEquals(this.right, other.right)
46
+ && Objects.deepEquals(this.ime, other.ime)
47
+ }
48
+
49
+ override fun hashCode(): Int {
50
+ return arrayOf(
51
+ top,
52
+ bottom,
53
+ left,
54
+ right,
55
+ ime
56
+ ).contentDeepHashCode()
57
+ }
58
+
38
59
  companion object {
39
60
  /**
40
61
  * Constructor called from C++
@@ -9,6 +9,7 @@ package com.margelo.nitro.unistyles
9
9
 
10
10
  import androidx.annotation.Keep
11
11
  import com.facebook.proguard.annotations.DoNotStrip
12
+ import java.util.Objects
12
13
 
13
14
 
14
15
  /**
@@ -53,6 +54,38 @@ data class UnistylesNativeMiniRuntime(
53
54
  ) {
54
55
  /* primary constructor */
55
56
 
57
+ override fun equals(other: Any?): Boolean {
58
+ if (this === other) return true
59
+ if (other !is UnistylesNativeMiniRuntime) return false
60
+ return Objects.deepEquals(this.colorScheme, other.colorScheme)
61
+ && Objects.deepEquals(this.screen, other.screen)
62
+ && Objects.deepEquals(this.contentSizeCategory, other.contentSizeCategory)
63
+ && Objects.deepEquals(this.insets, other.insets)
64
+ && Objects.deepEquals(this.pixelRatio, other.pixelRatio)
65
+ && Objects.deepEquals(this.fontScale, other.fontScale)
66
+ && Objects.deepEquals(this.rtl, other.rtl)
67
+ && Objects.deepEquals(this.statusBar, other.statusBar)
68
+ && Objects.deepEquals(this.navigationBar, other.navigationBar)
69
+ && Objects.deepEquals(this.isPortrait, other.isPortrait)
70
+ && Objects.deepEquals(this.isLandscape, other.isLandscape)
71
+ }
72
+
73
+ override fun hashCode(): Int {
74
+ return arrayOf(
75
+ colorScheme,
76
+ screen,
77
+ contentSizeCategory,
78
+ insets,
79
+ pixelRatio,
80
+ fontScale,
81
+ rtl,
82
+ statusBar,
83
+ navigationBar,
84
+ isPortrait,
85
+ isLandscape
86
+ ).contentDeepHashCode()
87
+ }
88
+
56
89
  companion object {
57
90
  /**
58
91
  * Constructor called from C++
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-unistyles",
3
- "version": "3.2.3",
3
+ "version": "3.2.4",
4
4
  "description": "Level up your React Native StyleSheet",
5
5
  "scripts": {
6
6
  "test": "NODE_ENV=babel-test jest ./plugin ./src/__tests__",
@@ -145,13 +145,13 @@
145
145
  "@babel/plugin-syntax-jsx": "7.28.6",
146
146
  "@babel/runtime": "7.28.6",
147
147
  "@react-native/babel-preset": "0.83.2",
148
- "nitrogen": "0.35.4",
148
+ "nitrogen": "0.35.5",
149
149
  "oxfmt": "0.35.0",
150
150
  "oxlint": "1.50.0",
151
151
  "react": "19.2.0",
152
152
  "react-native": "0.83.2",
153
153
  "react-native-builder-bob": "0.40.18",
154
- "react-native-nitro-modules": "0.35.4",
154
+ "react-native-nitro-modules": "0.35.5",
155
155
  "react-native-reanimated": "4.2.2",
156
156
  "react-native-web": "0.21.2",
157
157
  "typescript": "5.9.3"