react-native-unistyles 2.0.0-rc.2 → 2.0.0-rc.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +10 -4
  3. package/android/src/main/cxx/cpp-adapter.cpp +26 -2
  4. package/android/src/main/java/com/unistyles/UnistylesModule.kt +29 -3
  5. package/cxx/UnistylesRuntime.cpp +10 -0
  6. package/cxx/UnistylesRuntime.h +10 -2
  7. package/ios/UnistylesHelpers.h +0 -1
  8. package/ios/UnistylesHelpers.mm +0 -15
  9. package/ios/UnistylesModule.h +7 -1
  10. package/ios/UnistylesModule.mm +17 -47
  11. package/ios/platform/Platform_iOS.h +21 -0
  12. package/ios/platform/Platform_iOS.mm +132 -0
  13. package/ios/platform/Platform_macOS.h +20 -0
  14. package/ios/platform/Platform_macOS.mm +83 -0
  15. package/lib/commonjs/common.js +21 -1
  16. package/lib/commonjs/common.js.map +1 -1
  17. package/lib/commonjs/core/UnistylesModule.js +3 -0
  18. package/lib/commonjs/core/UnistylesModule.js.map +1 -1
  19. package/lib/commonjs/core/UnistylesRuntime.js +8 -0
  20. package/lib/commonjs/core/UnistylesRuntime.js.map +1 -1
  21. package/lib/commonjs/hooks/useUnistyles.js +8 -1
  22. package/lib/commonjs/hooks/useUnistyles.js.map +1 -1
  23. package/lib/commonjs/index.js +12 -0
  24. package/lib/commonjs/index.js.map +1 -1
  25. package/lib/commonjs/normalizer/normalizer.js.map +1 -1
  26. package/lib/commonjs/normalizer/normalizer.macos.js +3 -0
  27. package/lib/commonjs/normalizer/normalizer.macos.js.map +1 -0
  28. package/lib/commonjs/useStyles.js +1 -1
  29. package/lib/commonjs/useStyles.js.map +1 -1
  30. package/lib/commonjs/utils/index.js +6 -0
  31. package/lib/commonjs/utils/index.js.map +1 -1
  32. package/lib/module/common.js +20 -0
  33. package/lib/module/common.js.map +1 -1
  34. package/lib/module/core/UnistylesModule.js +3 -0
  35. package/lib/module/core/UnistylesModule.js.map +1 -1
  36. package/lib/module/core/UnistylesRuntime.js +8 -0
  37. package/lib/module/core/UnistylesRuntime.js.map +1 -1
  38. package/lib/module/hooks/useUnistyles.js +8 -1
  39. package/lib/module/hooks/useUnistyles.js.map +1 -1
  40. package/lib/module/index.js +2 -2
  41. package/lib/module/index.js.map +1 -1
  42. package/lib/module/normalizer/normalizer.js.map +1 -1
  43. package/lib/module/normalizer/normalizer.macos.js +2 -0
  44. package/lib/module/normalizer/normalizer.macos.js.map +1 -0
  45. package/lib/module/useStyles.js +1 -1
  46. package/lib/module/useStyles.js.map +1 -1
  47. package/lib/module/utils/index.js +1 -1
  48. package/lib/module/utils/index.js.map +1 -1
  49. package/lib/typescript/src/common.d.ts +19 -1
  50. package/lib/typescript/src/common.d.ts.map +1 -1
  51. package/lib/typescript/src/core/UnistylesModule.d.ts.map +1 -1
  52. package/lib/typescript/src/core/UnistylesRuntime.d.ts +5 -0
  53. package/lib/typescript/src/core/UnistylesRuntime.d.ts.map +1 -1
  54. package/lib/typescript/src/hooks/useUnistyles.d.ts +1 -0
  55. package/lib/typescript/src/hooks/useUnistyles.d.ts.map +1 -1
  56. package/lib/typescript/src/index.d.ts +2 -2
  57. package/lib/typescript/src/index.d.ts.map +1 -1
  58. package/lib/typescript/src/normalizer/normalizer.macos.d.ts +1 -0
  59. package/lib/typescript/src/normalizer/normalizer.macos.d.ts.map +1 -0
  60. package/lib/typescript/src/types/unistyles.d.ts +9 -2
  61. package/lib/typescript/src/types/unistyles.d.ts.map +1 -1
  62. package/lib/typescript/src/utils/index.d.ts +1 -1
  63. package/lib/typescript/src/utils/index.d.ts.map +1 -1
  64. package/package.json +11 -3
  65. package/react-native-unistyles.podspec +2 -2
  66. package/src/common.ts +21 -1
  67. package/src/core/UnistylesModule.ts +3 -0
  68. package/src/core/UnistylesRuntime.ts +8 -0
  69. package/src/hooks/useUnistyles.ts +9 -2
  70. package/src/index.ts +3 -1
  71. package/src/normalizer/normalizer.macos.ts +1 -0
  72. package/src/normalizer/normalizer.ts +1 -1
  73. package/src/types/unistyles.ts +10 -2
  74. package/src/useStyles.ts +1 -1
  75. package/src/utils/index.ts +1 -1
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 Jacek Pudysz
3
+ Copyright (c) 2023-2024 Jacek Pudysz
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
6
6
  in the Software without restriction, including without limitation the rights
package/README.md CHANGED
@@ -1,9 +1,15 @@
1
1
  [<img alt="react-native-unistyles" src="assets/banner.png">](https://reactnativeunistyles.vercel.app/)
2
2
 
3
3
  ![GitHub package.json version](https://img.shields.io/github/package-json/v/jpudysz/react-native-unistyles?style=for-the-badge)
4
- [![npm downloads](https://img.shields.io/npm/dm/react-native-unistyles.svg?style=for-the-badge)](https://www.npmjs.com/package/react-native-unistyles)
5
- ![Platform - Android and iOS](https://img.shields.io/badge/platform-Android%20%7C%20IOS%20%7C%20SSR%20%7C%20Web-blue.svg?style=for-the-badge)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)](https://opensource.org/licenses/MIT)
4
+ [![npm downloads](https://img.shields.io/npm/dt/react-native-unistyles?style=for-the-badge)](https://www.npmjs.com/package/react-native-unistyles)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-44CD11.svg?style=for-the-badge)](https://opensource.org/licenses/MIT)
6
+ <br />
7
+ [![platform - expo](https://img.shields.io/badge/Expo-fff?style=for-the-badge&logo=expo&logoColor=black)](https://docs.expo.dev/)
8
+ [![platform - web](https://img.shields.io/badge/React_Native_Web-white?logo=react&logoColor=57BDDA&style=for-the-badge)](https://www.w3.org/)
9
+ [![platform - ios](https://img.shields.io/badge/iOS-000?logo=apple&style=for-the-badge)](https://developer.apple.com/ios/)
10
+ [![platform - macos](https://img.shields.io/badge/macOS-000?logo=apple&style=for-the-badge)](https://developer.apple.com/macos/)
11
+ [![platform - ssr](https://img.shields.io/badge/SSR-black?style=for-the-badge&logo=next.js&logoColor=white)](https://nextjs.org/)
12
+ [![platform - android](https://img.shields.io/badge/Android-44CD11?style=for-the-badge&logo=android&logoColor=white)](https://developer.android.com/)
7
13
 
8
14
  ## [Documentation](https://reactnativeunistyles.vercel.app/)
9
15
  - [Start here](https://reactnativeunistyles.vercel.app/start/introduction/)
@@ -20,7 +26,7 @@
20
26
  - ⚛️ No React Context
21
27
  - 🖥️ Supports custom breakpoints, css-like media queries and variants
22
28
  - 🎨 Register multiple themes and change them with single function call
23
- - 🥳 Compatible with Expo, Bare React Native, React Native Web and SSR
29
+ - 🥳 Compatible with Expo, Bare React Native, React Native Web, React Native macOS and SSR
24
30
  - 🛡️ ~99% Test coverage
25
31
  - 🔌 Extend stylesheets with your own plugins
26
32
  - ⚔️ No 3rd party dependencies
@@ -27,7 +27,8 @@ Java_com_unistyles_UnistylesModule_nativeInstall(
27
27
  jlong jsi,
28
28
  jint screenWidth,
29
29
  jint screenHeight,
30
- jstring colorScheme
30
+ jstring colorScheme,
31
+ jstring contentSizeCategory
31
32
  ) {
32
33
  auto runtime = reinterpret_cast<facebook::jsi::Runtime *>(jsi);
33
34
 
@@ -43,10 +44,15 @@ Java_com_unistyles_UnistylesModule_nativeInstall(
43
44
  std::string colorSchemeStr(colorSchemeChars);
44
45
  env->ReleaseStringUTFChars(colorScheme, colorSchemeChars);
45
46
 
47
+ const char *contentSizeCategoryChars = env->GetStringUTFChars(contentSizeCategory, nullptr);
48
+ std::string contentSizeCategoryStr(contentSizeCategoryChars);
49
+ env->ReleaseStringUTFChars(contentSizeCategory, contentSizeCategoryChars);
50
+
46
51
  unistylesRuntime = std::make_shared<UnistylesRuntime>(
47
52
  screenWidth,
48
53
  screenHeight,
49
- colorSchemeStr
54
+ colorSchemeStr,
55
+ contentSizeCategoryStr
50
56
  );
51
57
 
52
58
  unistylesRuntime->onThemeChange([=](const std::string &theme) {
@@ -79,6 +85,16 @@ Java_com_unistyles_UnistylesModule_nativeInstall(
79
85
  env->DeleteLocalRef(cls);
80
86
  });
81
87
 
88
+ unistylesRuntime->onContentSizeCategoryChange([=](const std::string &contentSizeCategory) {
89
+ jstring contentSizeCategoryStr = env->NewStringUTF(contentSizeCategory.c_str());
90
+ jclass cls = env->GetObjectClass(unistylesModule);
91
+ jmethodID methodId = env->GetMethodID(cls, "onContentSizeCategoryChange", "(Ljava/lang/String;)V");
92
+
93
+ env->CallVoidMethod(unistylesModule, methodId, contentSizeCategoryStr);
94
+ env->DeleteLocalRef(contentSizeCategoryStr);
95
+ env->DeleteLocalRef(cls);
96
+ });
97
+
82
98
  jsi::Object hostObject = jsi::Object::createFromHostObject(*runtime, unistylesRuntime);
83
99
 
84
100
  runtime->global().setProperty(*runtime, "__UNISTYLES__", std::move(hostObject));
@@ -106,3 +122,11 @@ Java_com_unistyles_UnistylesModule_nativeOnAppearanceChange(JNIEnv *env, jobject
106
122
  unistylesRuntime->handleAppearanceChange(env->GetStringUTFChars(colorScheme, nullptr));
107
123
  }
108
124
  }
125
+
126
+ extern "C"
127
+ JNIEXPORT void JNICALL
128
+ Java_com_unistyles_UnistylesModule_nativeOnContentSizeCategoryChange(JNIEnv *env, jobject thiz, jstring contentSizeCategory) {
129
+ if (unistylesRuntime != nullptr) {
130
+ unistylesRuntime->handleContentSizeCategoryChange(env->GetStringUTFChars(contentSizeCategory, nullptr));
131
+ }
132
+ }
@@ -15,6 +15,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule
15
15
  import com.facebook.react.bridge.ReactMethod
16
16
  import com.facebook.react.modules.core.DeviceEventManagerModule
17
17
 
18
+
18
19
  class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), LifecycleEventListener {
19
20
  private val configurationChangeReceiver = object : BroadcastReceiver() {
20
21
  override fun onReceive(context: Context, intent: Intent) {
@@ -54,6 +55,7 @@ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
54
55
  this.nativeOnAppearanceChange(
55
56
  config["colorScheme"] as String
56
57
  )
58
+ this.nativeOnContentSizeCategoryChange(config["contentSizeCategory"] as String)
57
59
  }
58
60
  }
59
61
 
@@ -64,11 +66,20 @@ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
64
66
  Configuration.UI_MODE_NIGHT_NO -> "light"
65
67
  else -> "unspecified"
66
68
  }
69
+ val fontScale = reactApplicationContext.resources.configuration.fontScale
70
+ val contentSizeCategory = when {
71
+ fontScale <= 0.85f -> "Small"
72
+ fontScale <= 1.0f -> "Default"
73
+ fontScale <= 1.15f -> "Large"
74
+ fontScale <= 1.3f -> "ExtraLarge"
75
+ else -> "Huge"
76
+ }
67
77
 
68
78
  return mapOf(
69
79
  "width" to (displayMetrics.widthPixels / displayMetrics.density).toInt(),
70
80
  "height" to (displayMetrics.heightPixels / displayMetrics.density).toInt(),
71
- "colorScheme" to colorScheme
81
+ "colorScheme" to colorScheme,
82
+ "contentSizeCategory" to contentSizeCategory
72
83
  )
73
84
  }
74
85
 
@@ -85,7 +96,8 @@ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
85
96
  it.get(),
86
97
  config["width"] as Int,
87
98
  config["height"] as Int,
88
- config["colorScheme"] as String
99
+ config["colorScheme"] as String,
100
+ config["contentSizeCategory"] as String
89
101
  )
90
102
 
91
103
  Log.i(NAME, "Installed Unistyles \uD83E\uDD84!")
@@ -99,10 +111,11 @@ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
99
111
  }
100
112
  }
101
113
 
102
- private external fun nativeInstall(jsi: Long, width: Int, height: Int, colorScheme: String)
114
+ private external fun nativeInstall(jsi: Long, width: Int, height: Int, colorScheme: String, contentSizeCategory: String)
103
115
  private external fun nativeDestroy()
104
116
  private external fun nativeOnOrientationChange(width: Int, height: Int)
105
117
  private external fun nativeOnAppearanceChange(colorScheme: String)
118
+ private external fun nativeOnContentSizeCategoryChange(contentSizeCategory: String)
106
119
 
107
120
  //endregion
108
121
  //region Event emitter
@@ -147,6 +160,19 @@ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
147
160
  .emit("__unistylesOnChange", body)
148
161
  }
149
162
 
163
+ private fun onContentSizeCategoryChange(contentSizeCategory: String) {
164
+ val body = Arguments.createMap().apply {
165
+ putString("type", "dynamicTypeSize")
166
+ putMap("payload", Arguments.createMap().apply {
167
+ putString("contentSizeCategory", contentSizeCategory)
168
+ })
169
+ }
170
+
171
+ reactApplicationContext
172
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
173
+ .emit("__unistylesOnChange", body)
174
+ }
175
+
150
176
  @ReactMethod
151
177
  fun addListener(eventName: String?) = Unit
152
178
 
@@ -11,6 +11,7 @@ std::vector<jsi::PropNameID> UnistylesRuntime::getPropertyNames(jsi::Runtime& ru
11
11
  // getters
12
12
  properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("screenWidth")));
13
13
  properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("screenHeight")));
14
+ properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("contentSizeCategory")));
14
15
  properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("hasAdaptiveThemes")));
15
16
  properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("themeName")));
16
17
  properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("breakpoint")));
@@ -43,6 +44,10 @@ jsi::Value UnistylesRuntime::get(jsi::Runtime& runtime, const jsi::PropNameID& p
43
44
  if (propName == "hasAdaptiveThemes") {
44
45
  return jsi::Value(this->hasAdaptiveThemes);
45
46
  }
47
+
48
+ if (propName == "contentSizeCategory") {
49
+ return jsi::Value(jsi::String::createFromUtf8(runtime, this->contentSizeCategory));
50
+ }
46
51
 
47
52
  if (propName == "themeName") {
48
53
  return !this->themeName.empty()
@@ -293,6 +298,11 @@ void UnistylesRuntime::handleAppearanceChange(std::string colorScheme) {
293
298
  }
294
299
  }
295
300
 
301
+ void UnistylesRuntime::handleContentSizeCategoryChange(std::string contentSizeCategory) {
302
+ this->contentSizeCategory = contentSizeCategory;
303
+ this->onContentSizeCategoryChangeCallback(contentSizeCategory);
304
+ }
305
+
296
306
  jsi::Value UnistylesRuntime::getThemeOrFail(jsi::Runtime& runtime) {
297
307
  if (this->themes.size() == 1) {
298
308
  std::string themeName = this->themes.at(0);
@@ -20,18 +20,21 @@ class JSI_EXPORT UnistylesRuntime : public jsi::HostObject {
20
20
  private:
21
21
  std::function<void(std::string)> onThemeChangeCallback;
22
22
  std::function<void(std::string breakpoint, std::string orientation, int screenWidth, int screenHeight)> onLayoutChangeCallback;
23
+ std::function<void(std::string)> onContentSizeCategoryChangeCallback;
23
24
  std::function<void()> onPluginChangeCallback;
24
25
 
25
26
  int screenWidth;
26
27
  int screenHeight;
27
28
  std::string colorScheme;
29
+ std::string contentSizeCategory;
28
30
 
29
31
  public:
30
32
  UnistylesRuntime(
31
33
  int screenWidth,
32
34
  int screenHeight,
33
- std::string colorScheme
34
- ): screenWidth(screenWidth), screenHeight(screenHeight), colorScheme(colorScheme) {}
35
+ std::string colorScheme,
36
+ std::string contentSizeCategory
37
+ ): screenWidth(screenWidth), screenHeight(screenHeight), colorScheme(colorScheme), contentSizeCategory(contentSizeCategory) {}
35
38
 
36
39
  bool hasAdaptiveThemes;
37
40
  bool supportsAutomaticColorScheme;
@@ -53,6 +56,10 @@ public:
53
56
  void onPluginChange(std::function<void()> callback) {
54
57
  this->onPluginChangeCallback = callback;
55
58
  }
59
+
60
+ void onContentSizeCategoryChange(std::function<void(std::string)> callback) {
61
+ this->onContentSizeCategoryChangeCallback = callback;
62
+ }
56
63
 
57
64
  jsi::Value get(jsi::Runtime&, const jsi::PropNameID& name) override;
58
65
  void set(jsi::Runtime& runtime, const jsi::PropNameID& propNameId, const jsi::Value& value) override;
@@ -60,6 +67,7 @@ public:
60
67
 
61
68
  void handleScreenSizeChange(int width, int height);
62
69
  void handleAppearanceChange(std::string colorScheme);
70
+ void handleContentSizeCategoryChange(std::string contentSizeCategory);
63
71
 
64
72
  jsi::Value getThemeOrFail(jsi::Runtime&);
65
73
  std::string getBreakpointFromScreenWidth(int width, const std::vector<std::pair<std::string, double>>& sortedBreakpointEntries);
@@ -1,4 +1,3 @@
1
1
  #include <string>
2
2
 
3
- std::string getColorScheme();
4
3
  NSString* cxxStringToNSString(std::string);
@@ -1,19 +1,4 @@
1
1
  #import "UnistylesHelpers.h"
2
- #import "UnistylesRuntime.h"
3
-
4
- std::string getColorScheme() {
5
- UIUserInterfaceStyle colorScheme = [UIScreen mainScreen].traitCollection.userInterfaceStyle;
6
-
7
- switch (colorScheme) {
8
- case UIUserInterfaceStyleLight:
9
- return UnistylesLightScheme;
10
- case UIUserInterfaceStyleDark:
11
- return UnistylesDarkScheme;
12
- case UIUserInterfaceStyleUnspecified:
13
- default:
14
- return UnistylesUnspecifiedScheme;
15
- }
16
- }
17
2
 
18
3
  NSString* cxxStringToNSString(std::string cxxString) {
19
4
  return [NSString stringWithUTF8String:cxxString.c_str()];
@@ -2,9 +2,15 @@
2
2
  #import <React/RCTEventEmitter.h>
3
3
  #import <string>
4
4
 
5
+ #if TARGET_OS_OSX
6
+ #import "Platform_macOS.h"
7
+ #elif TARGET_OS_IOS
8
+ #import "Platform_iOS.h"
9
+ #endif
10
+
5
11
  @interface UnistylesModule : RCTEventEmitter<RCTBridgeModule>
6
12
 
7
13
  @property (nonatomic, assign) BOOL hasListeners;
8
- @property (nonatomic, assign) void* unistylesRuntime;
14
+ @property (nonatomic, strong) Platform *platform;
9
15
 
10
16
  @end
@@ -2,7 +2,6 @@
2
2
  #import "UnistylesHelpers.h"
3
3
  #import "UnistylesRuntime.h"
4
4
 
5
- #import <React/RCTAppearance.h>
6
5
  #import <React/RCTBridge+Private.h>
7
6
  #import <jsi/jsi.h>
8
7
 
@@ -16,53 +15,16 @@ RCT_EXPORT_MODULE(Unistyles)
16
15
 
17
16
  - (instancetype)init {
18
17
  if ((self = [super init])) {
19
- [[NSNotificationCenter defaultCenter] addObserver:self
20
- selector:@selector(handleOrientationChange:)
21
- name:UIDeviceOrientationDidChangeNotification
22
- object:nil];
23
- [[NSNotificationCenter defaultCenter] addObserver:self
24
- selector:@selector(appearanceChanged:)
25
- name:RCTUserInterfaceStyleDidChangeNotification
26
- object:nil];
18
+ self.platform = [[Platform alloc] init];
27
19
  }
28
20
 
29
21
  return self;
30
22
  }
31
23
 
32
- - (void)dealloc {
33
- if (self.unistylesRuntime != nullptr) {
34
- self.unistylesRuntime = nullptr;
35
- }
36
-
37
- [[NSNotificationCenter defaultCenter] removeObserver:self];
38
- }
39
-
40
-
41
24
  + (BOOL)requiresMainQueueSetup {
42
25
  return YES;
43
26
  }
44
27
 
45
- #pragma mark - Event handlers
46
-
47
- - (void)handleOrientationChange:(NSNotification *)notification {
48
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
49
- CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
50
- CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
51
-
52
- if (self.unistylesRuntime != nullptr) {
53
- ((UnistylesRuntime*)self.unistylesRuntime)->handleScreenSizeChange((int)screenWidth, (int)screenHeight);
54
- }
55
- });
56
- }
57
-
58
- - (void)appearanceChanged:(NSNotification *)notification {
59
- std::string colorScheme = getColorScheme();
60
-
61
- if (self.unistylesRuntime != nullptr) {
62
- ((UnistylesRuntime*)self.unistylesRuntime)->handleAppearanceChange(colorScheme);
63
- }
64
- }
65
-
66
28
  #pragma mark - Event emitter
67
29
  - (NSArray<NSString *> *)supportedEvents {
68
30
  return @[@"__unistylesOnChange"];
@@ -109,14 +71,11 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) {
109
71
  }
110
72
 
111
73
  void registerUnistylesHostObject(jsi::Runtime &runtime, UnistylesModule* weakSelf) {
112
- CGFloat initialScreenWidth = [UIScreen mainScreen].bounds.size.width;
113
- CGFloat initialScreenHeight = [UIScreen mainScreen].bounds.size.height;
114
- std::string initialColorScheme = getColorScheme();
115
-
116
74
  auto unistylesRuntime = std::make_shared<UnistylesRuntime>(
117
- (int)initialScreenWidth,
118
- (int)initialScreenHeight,
119
- initialColorScheme
75
+ (int)weakSelf.platform.initialWidth,
76
+ (int)weakSelf.platform.initialWidth,
77
+ weakSelf.platform.initialColorScheme,
78
+ weakSelf.platform.initialContentSizeCategory
120
79
  );
121
80
 
122
81
  unistylesRuntime.get()->onThemeChange([=](std::string theme) {
@@ -155,8 +114,19 @@ void registerUnistylesHostObject(jsi::Runtime &runtime, UnistylesModule* weakSel
155
114
  [weakSelf emitEvent:@"__unistylesOnChange" withBody:body];
156
115
  });
157
116
  });
117
+
118
+ unistylesRuntime.get()->onContentSizeCategoryChange([=](std::string contentSizeCategory) {
119
+ NSDictionary *body = @{
120
+ @"type": @"dynamicTypeSize",
121
+ @"payload": @{
122
+ @"contentSizeCategory": cxxStringToNSString(contentSizeCategory)
123
+ }
124
+ };
125
+
126
+ [weakSelf emitEvent:@"__unistylesOnChange" withBody:body];
127
+ });
158
128
 
159
- weakSelf.unistylesRuntime = unistylesRuntime.get();
129
+ weakSelf.platform.unistylesRuntime = unistylesRuntime.get();
160
130
 
161
131
  auto hostObject = jsi::Object::createFromHostObject(runtime, unistylesRuntime);
162
132
 
@@ -0,0 +1,21 @@
1
+ #include <string>
2
+
3
+ @interface Platform : NSObject
4
+
5
+ @property (nonatomic, assign) CGFloat initialWidth;
6
+ @property (nonatomic, assign) CGFloat initialHeight;
7
+ @property (nonatomic, assign) std::string initialColorScheme;
8
+ @property (nonatomic, assign) std::string initialContentSizeCategory;
9
+ @property (nonatomic, assign) void* unistylesRuntime;
10
+
11
+ - (instancetype)init;
12
+
13
+ - (void)setupListeners;
14
+ - (void)onOrientationChange:(NSNotification *)notification;
15
+ - (void)onAppearanceChange:(NSNotification *)notification;
16
+ - (void)onContentSizeCategoryChange:(NSNotification *)notification;
17
+
18
+ - (std::string)getColorScheme;
19
+ - (std::string)getContentSizeCategory:(UIContentSizeCategory)contentSizeCategory;
20
+
21
+ @end
@@ -0,0 +1,132 @@
1
+ #if TARGET_OS_IOS
2
+
3
+ #import "Platform_iOS.h"
4
+ #import "UnistylesRuntime.h"
5
+ #import <React/RCTAppearance.h>
6
+
7
+ @implementation Platform
8
+
9
+ - (instancetype)init {
10
+ self = [super init];
11
+ if (self) {
12
+ UIScreen *screen = [UIScreen mainScreen];
13
+ UIContentSizeCategory contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory];
14
+
15
+ self.initialWidth = screen.bounds.size.width;
16
+ self.initialHeight = screen.bounds.size.height;
17
+ self.initialColorScheme = [self getColorScheme];
18
+ self.initialContentSizeCategory = [self getContentSizeCategory:contentSizeCategory];
19
+
20
+ [self setupListeners];
21
+ }
22
+ return self;
23
+ }
24
+
25
+ - (void)dealloc {
26
+ if (self.unistylesRuntime != nullptr) {
27
+ self.unistylesRuntime = nullptr;
28
+ }
29
+
30
+ [[NSNotificationCenter defaultCenter] removeObserver:self
31
+ name: UIContentSizeCategoryDidChangeNotification
32
+ object: nil];
33
+ [[NSNotificationCenter defaultCenter] removeObserver:self
34
+ name: RCTUserInterfaceStyleDidChangeNotification
35
+ object: nil];
36
+ [[NSNotificationCenter defaultCenter] removeObserver:self
37
+ name: UIDeviceOrientationDidChangeNotification
38
+ object: nil];
39
+ }
40
+
41
+ - (void)setupListeners {
42
+ [[NSNotificationCenter defaultCenter] addObserver:self
43
+ selector:@selector(onOrientationChange:)
44
+ name:UIDeviceOrientationDidChangeNotification
45
+ object:nil];
46
+ [[NSNotificationCenter defaultCenter] addObserver:self
47
+ selector:@selector(onAppearanceChange:)
48
+ name:RCTUserInterfaceStyleDidChangeNotification
49
+ object:nil];
50
+ [[NSNotificationCenter defaultCenter] addObserver:self
51
+ selector:@selector(onContentSizeCategoryChange:)
52
+ name:UIContentSizeCategoryDidChangeNotification
53
+ object:nil];
54
+ }
55
+
56
+ - (void)onAppearanceChange:(NSNotification *)notification {
57
+ std::string colorScheme = [self getColorScheme];
58
+
59
+ if (self.unistylesRuntime != nullptr) {
60
+ ((UnistylesRuntime*)self.unistylesRuntime)->handleAppearanceChange(colorScheme);
61
+ }
62
+ }
63
+
64
+ - (void)onContentSizeCategoryChange:(NSNotification *)notification {
65
+ UIContentSizeCategory contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory];
66
+
67
+ if (self.unistylesRuntime != nullptr) {
68
+ ((UnistylesRuntime*)self.unistylesRuntime)->handleContentSizeCategoryChange([self getContentSizeCategory:contentSizeCategory]);
69
+ }
70
+ }
71
+
72
+ - (void)onOrientationChange:(NSNotification *)notification {
73
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
74
+ UIScreen *screen = [UIScreen mainScreen];
75
+ CGFloat screenWidth = screen.bounds.size.width;
76
+ CGFloat screenHeight = screen.bounds.size.height;
77
+
78
+ if (self.unistylesRuntime != nullptr) {
79
+ ((UnistylesRuntime*)self.unistylesRuntime)->handleScreenSizeChange((int)screenWidth, (int)screenHeight);
80
+ }
81
+ });
82
+ }
83
+
84
+ - (std::string)getColorScheme {
85
+ UIUserInterfaceStyle colorScheme = [UIScreen mainScreen].traitCollection.userInterfaceStyle;
86
+
87
+ switch (colorScheme) {
88
+ case UIUserInterfaceStyleLight:
89
+ return UnistylesLightScheme;
90
+ case UIUserInterfaceStyleDark:
91
+ return UnistylesDarkScheme;
92
+ case UIUserInterfaceStyleUnspecified:
93
+ default:
94
+ return UnistylesUnspecifiedScheme;
95
+ }
96
+ }
97
+
98
+ - (std::string)getContentSizeCategory:(UIContentSizeCategory)contentSizeCategory {
99
+ if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraExtraExtraLarge]) {
100
+ return std::string([@"xxxLarge" UTF8String]);
101
+ }
102
+
103
+ if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraExtraLarge]) {
104
+ return std::string([@"xxLarge" UTF8String]);
105
+ }
106
+
107
+ if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraLarge]) {
108
+ return std::string([@"xLarge" UTF8String]);
109
+ }
110
+
111
+ if ([contentSizeCategory isEqualToString:UIContentSizeCategoryLarge]) {
112
+ return std::string([@"Large" UTF8String]);
113
+ }
114
+
115
+ if ([contentSizeCategory isEqualToString:UIContentSizeCategoryMedium]) {
116
+ return std::string([@"Medium" UTF8String]);
117
+ }
118
+
119
+ if ([contentSizeCategory isEqualToString:UIContentSizeCategorySmall]) {
120
+ return std::string([@"Small" UTF8String]);
121
+ }
122
+
123
+ if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraSmall]) {
124
+ return std::string([@"xSmall" UTF8String]);
125
+ }
126
+
127
+ return std::string([@"unspecified" UTF8String]);
128
+ }
129
+
130
+ @end
131
+
132
+ #endif
@@ -0,0 +1,20 @@
1
+ #include <string>
2
+
3
+ @interface Platform : NSObject
4
+
5
+ @property (nonatomic, assign) CGFloat initialWidth;
6
+ @property (nonatomic, assign) CGFloat initialHeight;
7
+ @property (nonatomic, assign) std::string initialColorScheme;
8
+ @property (nonatomic, assign) std::string initialContentSizeCategory;
9
+ @property (nonatomic, assign) void* unistylesRuntime;
10
+
11
+ - (instancetype)init;
12
+
13
+ - (void)setupListeners;
14
+ - (void)onWindowResize;
15
+ - (void)onAppearanceChange;
16
+
17
+ - (std::string)getColorScheme;
18
+
19
+ @end
20
+
@@ -0,0 +1,83 @@
1
+ #if TARGET_OS_OSX
2
+
3
+ #import "Platform_macOS.h"
4
+ #import "UnistylesRuntime.h"
5
+ #import <React/RCTUtils.h>
6
+
7
+ @implementation Platform
8
+
9
+ - (instancetype)init {
10
+ self = [super init];
11
+ if (self) {
12
+ NSWindow *window = RCTSharedApplication().mainWindow;
13
+
14
+ self.initialWidth = window.frame.size.width;
15
+ self.initialHeight = window.frame.size.height;
16
+ self.initialContentSizeCategory = std::string([@"unspecified" UTF8String]);
17
+ self.initialColorScheme = [self getColorScheme];
18
+
19
+ [self setupListeners];
20
+ }
21
+ return self;
22
+ }
23
+
24
+ - (void)dealloc {
25
+ if (self.unistylesRuntime != nullptr) {
26
+ self.unistylesRuntime = nullptr;
27
+ }
28
+
29
+ NSWindow *window = RCTSharedApplication().mainWindow;
30
+
31
+ [window removeObserver:self forKeyPath:@"effectiveAppearance"];
32
+ [window removeObserver:self forKeyPath:@"frame"];
33
+ }
34
+
35
+ - (void)setupListeners {
36
+ NSWindow *window = RCTSharedApplication().mainWindow;
37
+
38
+ [window addObserver:self forKeyPath:@"effectiveAppearance" options:NSKeyValueObservingOptionNew context:nil];
39
+ [window addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
40
+ }
41
+
42
+ - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
43
+ if ([keyPath isEqualToString:@"effectiveAppearance"]) {
44
+ return [self onAppearanceChange];
45
+ }
46
+
47
+ if ([keyPath isEqualToString:@"frame"]) {
48
+ return [self onWindowResize];
49
+ }
50
+ }
51
+
52
+ - (void)onAppearanceChange {
53
+ std::string colorScheme = [self getColorScheme];
54
+
55
+ if (self.unistylesRuntime != nullptr) {
56
+ ((UnistylesRuntime*)self.unistylesRuntime)->handleAppearanceChange(colorScheme);
57
+ }
58
+ }
59
+
60
+ - (void)onWindowResize {
61
+ NSWindow *window = RCTSharedApplication().mainWindow;
62
+
63
+ CGFloat screenWidth = window.frame.size.width;
64
+ CGFloat screenHeight = window.frame.size.height;
65
+
66
+ if (self.unistylesRuntime != nullptr) {
67
+ ((UnistylesRuntime*)self.unistylesRuntime)->handleScreenSizeChange((int)screenWidth, (int)screenHeight);
68
+ }
69
+ }
70
+
71
+ - (std::string)getColorScheme {
72
+ NSAppearance *appearance = RCTSharedApplication().effectiveAppearance;
73
+
74
+ if (appearance.name == NSAppearanceNameDarkAqua) {
75
+ return UnistylesDarkScheme;
76
+ }
77
+
78
+ return UnistylesLightScheme;
79
+ }
80
+
81
+ @end
82
+
83
+ #endif