react-native-unistyles 3.0.0-alpha.26 → 3.0.0-alpha.28

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 (196) hide show
  1. package/cxx/core/UnistylesRegistry.cpp +4 -8
  2. package/cxx/core/UnistylesRegistry.h +1 -1
  3. package/cxx/core/UnistylesState.cpp +6 -10
  4. package/cxx/core/UnistylesState.h +2 -1
  5. package/cxx/hybridObjects/HybridStyleSheet.cpp +5 -2
  6. package/cxx/parser/Parser.cpp +73 -4
  7. package/cxx/parser/Parser.h +2 -0
  8. package/lib/commonjs/core/index.js.map +1 -1
  9. package/lib/commonjs/core/useTheme.js.map +1 -1
  10. package/lib/commonjs/core/useTheme.native.js.map +1 -1
  11. package/lib/commonjs/index.js.map +1 -1
  12. package/lib/commonjs/mq.js +1 -4
  13. package/lib/commonjs/mq.js.map +2 -1
  14. package/lib/commonjs/specs/NativePlatform/NativePlatform.nitro.js.map +1 -0
  15. package/lib/commonjs/specs/NavigtionBar/UnistylesNavigationBar.nitro.js.map +1 -1
  16. package/lib/commonjs/specs/NavigtionBar/index.js.map +2 -1
  17. package/lib/commonjs/specs/ShadowRegistry/ShadowRegistry.nitro.js.map +1 -1
  18. package/lib/commonjs/specs/ShadowRegistry/types.js +3 -0
  19. package/lib/commonjs/specs/ShadowRegistry/types.js.map +1 -1
  20. package/lib/commonjs/specs/StatusBar/UnistylesStatusBar.nitro.js.map +1 -1
  21. package/lib/commonjs/specs/StatusBar/index.js.map +2 -1
  22. package/lib/commonjs/specs/StyleSheet/UnistylesStyleSheet.nitro.js +2 -4
  23. package/lib/commonjs/specs/StyleSheet/UnistylesStyleSheet.nitro.js.map +1 -1
  24. package/lib/commonjs/specs/index.js.map +1 -1
  25. package/lib/commonjs/specs/types.js +10 -10
  26. package/lib/commonjs/specs/types.js.map +1 -1
  27. package/lib/commonjs/types/stylesheet.js.map +1 -1
  28. package/lib/commonjs/web/convert/index.js +1 -7
  29. package/lib/commonjs/web/convert/shadow.js +1 -5
  30. package/lib/commonjs/web/convert/shadow.js.map +2 -1
  31. package/lib/commonjs/web/convert/textShadow.js +1 -4
  32. package/lib/commonjs/web/convert/textShadow.js.map +2 -1
  33. package/lib/commonjs/web/convert/transform.js.map +2 -1
  34. package/lib/commonjs/web/create.js +1 -5
  35. package/lib/commonjs/web/create.js.map +2 -1
  36. package/lib/commonjs/web/mock.js.map +2 -1
  37. package/lib/commonjs/web/runtime.js.map +2 -1
  38. package/lib/commonjs/web/state.js.map +1 -1
  39. package/lib/commonjs/web/utils/common.js +1 -3
  40. package/lib/commonjs/web/utils/common.js.map +2 -1
  41. package/lib/commonjs/web/utils/unistyle.js.map +1 -1
  42. package/lib/commonjs/web/variants/index.js.map +1 -1
  43. package/lib/module/common.js.map +1 -1
  44. package/lib/module/core/useBreakpoint.js.map +1 -1
  45. package/lib/module/core/useBreakpoint.native.js.map +2 -1
  46. package/lib/module/core/useTheme.js.map +2 -1
  47. package/lib/module/core/useTheme.native.js.map +2 -1
  48. package/lib/module/index.js.map +1 -1
  49. package/lib/module/mq.js +1 -4
  50. package/lib/module/mq.js.map +2 -1
  51. package/lib/module/specs/NativePlatform/NativePlatform.nitro.js +5 -6
  52. package/lib/module/specs/NativePlatform/NativePlatform.nitro.js.map +1 -1
  53. package/lib/module/specs/NavigtionBar/UnistylesNavigationBar.nitro.js.map +1 -1
  54. package/lib/module/specs/NavigtionBar/index.js.map +2 -1
  55. package/lib/module/specs/ShadowRegistry/ShadowRegistry.nitro.js.map +1 -0
  56. package/lib/module/specs/ShadowRegistry/index.js.map +2 -1
  57. package/lib/module/specs/ShadowRegistry/types.js +2 -0
  58. package/lib/module/specs/ShadowRegistry/types.js.map +1 -1
  59. package/lib/module/specs/StatusBar/UnistylesStatusBar.nitro.js.map +1 -1
  60. package/lib/module/specs/StyleSheet/UnistylesStyleSheet.nitro.js +1 -1
  61. package/lib/module/specs/StyleSheet/UnistylesStyleSheet.nitro.js.map +1 -0
  62. package/lib/module/specs/TurboUnistyles/NativeTurboUnistyles.js +2 -3
  63. package/lib/module/specs/TurboUnistyles/NativeTurboUnistyles.js.map +2 -1
  64. package/lib/module/specs/UnistylesRuntime/UnistylesRuntime.nitro.js.map +1 -1
  65. package/lib/module/specs/index.web.js.map +2 -1
  66. package/lib/module/specs/types.js.map +1 -1
  67. package/lib/module/types/stylesheet.js.map +1 -1
  68. package/lib/module/web/convert/boxShadow.js +1 -4
  69. package/lib/module/web/convert/boxShadow.js.map +2 -1
  70. package/lib/module/web/convert/pseudo.js.map +2 -1
  71. package/lib/module/web/convert/shadow.js +1 -5
  72. package/lib/module/web/convert/shadow.js.map +2 -1
  73. package/lib/module/web/convert/style.js.map +2 -1
  74. package/lib/module/web/convert/textShadow.js +1 -4
  75. package/lib/module/web/convert/textShadow.js.map +2 -1
  76. package/lib/module/web/convert/transform.js.map +2 -1
  77. package/lib/module/web/convert/utils.js.map +2 -1
  78. package/lib/module/web/index.js +1 -2
  79. package/lib/module/web/index.js.map +2 -1
  80. package/lib/module/web/listener.js.map +2 -1
  81. package/lib/module/web/mock.js.map +2 -1
  82. package/lib/module/web/registry.js +1 -3
  83. package/lib/module/web/registry.js.map +2 -1
  84. package/lib/module/web/runtime.js.map +2 -1
  85. package/lib/module/web/shadowRegistry.js +1 -9
  86. package/lib/module/web/shadowRegistry.js.map +2 -1
  87. package/lib/module/web/state.js.map +1 -1
  88. package/lib/module/web/utils/index.js.map +1 -1
  89. package/lib/module/web/utils/unistyle.js.map +2 -1
  90. package/lib/module/web/variants/index.js.map +1 -1
  91. package/lib/module/web/variants/useVariants.js +1 -2
  92. package/lib/module/web/variants/useVariants.js.map +2 -1
  93. package/lib/typescript/src/core/useBreakpoint.d.ts +1 -1
  94. package/lib/typescript/src/core/useBreakpoint.d.ts.map +1 -1
  95. package/lib/typescript/src/core/useBreakpoint.native.d.ts +1 -1
  96. package/lib/typescript/src/core/useBreakpoint.native.d.ts.map +1 -1
  97. package/lib/typescript/src/core/useTheme.d.ts +2 -40
  98. package/lib/typescript/src/core/useTheme.d.ts.map +1 -1
  99. package/lib/typescript/src/core/useTheme.native.d.ts +2 -40
  100. package/lib/typescript/src/core/useTheme.native.d.ts.map +1 -1
  101. package/lib/typescript/src/types/stylesheet.d.ts +4 -2
  102. package/lib/typescript/src/types/stylesheet.d.ts.map +1 -1
  103. package/lib/typescript/src/types/variants.d.ts +1 -1
  104. package/lib/typescript/src/types/variants.d.ts.map +1 -1
  105. package/lib/typescript/src/web/create.d.ts +214 -1220
  106. package/lib/typescript/src/web/create.d.ts.map +1 -1
  107. package/lib/typescript/src/web/index.d.ts +214 -1220
  108. package/lib/typescript/src/web/index.d.ts.map +1 -1
  109. package/lib/typescript/src/web/runtime.d.ts +4 -4
  110. package/lib/typescript/src/web/runtime.d.ts.map +1 -1
  111. package/lib/typescript/src/web/state.d.ts +1 -2
  112. package/lib/typescript/src/web/state.d.ts.map +1 -1
  113. package/lib/typescript/src/web/utils/unistyle.d.ts +2 -2
  114. package/lib/typescript/src/web/utils/unistyle.d.ts.map +1 -1
  115. package/package.json +15 -16
  116. package/src/common.js +4 -0
  117. package/src/core/index.js +2 -0
  118. package/src/core/useBreakpoint.js +14 -0
  119. package/src/core/useBreakpoint.native.js +16 -0
  120. package/src/core/useTheme.js +14 -0
  121. package/src/core/useTheme.native.js +16 -0
  122. package/src/core/useTheme.native.ts +2 -1
  123. package/src/core/useTheme.ts +2 -1
  124. package/src/index.js +3 -0
  125. package/src/mq.js +38 -0
  126. package/src/specs/NativePlatform/NativePlatform.nitro.js +18 -0
  127. package/src/specs/NativePlatform/index.js +1 -0
  128. package/src/specs/NavigtionBar/UnistylesNavigationBar.nitro.js +1 -0
  129. package/src/specs/NavigtionBar/index.js +9 -0
  130. package/src/specs/ShadowRegistry/ShadowRegistry.nitro.js +1 -0
  131. package/src/specs/ShadowRegistry/index.js +26 -0
  132. package/src/specs/ShadowRegistry/types.js +1 -0
  133. package/src/specs/StatusBar/UnistylesStatusBar.nitro.js +1 -0
  134. package/src/specs/StatusBar/index.js +25 -0
  135. package/src/specs/StyleSheet/UnistylesStyleSheet.nitro.js +1 -0
  136. package/src/specs/StyleSheet/index.js +13 -0
  137. package/src/specs/TurboUnistyles/NativeTurboUnistyles.js +2 -0
  138. package/src/specs/TurboUnistyles/index.js +1 -0
  139. package/src/specs/UnistylesRuntime/UnistylesRuntime.nitro.js +1 -0
  140. package/src/specs/UnistylesRuntime/index.js +20 -0
  141. package/src/specs/index.js +8 -0
  142. package/src/specs/index.web.js +2 -0
  143. package/src/specs/types.js +17 -0
  144. package/src/types/stylesheet.ts +5 -3
  145. package/src/types/variants.ts +1 -1
  146. package/src/web/convert/boxShadow.js +59 -0
  147. package/src/web/convert/index.js +56 -0
  148. package/src/web/convert/pseudo.js +131 -0
  149. package/src/web/convert/shadow.js +50 -0
  150. package/src/web/convert/style.js +137 -0
  151. package/src/web/convert/textShadow.js +56 -0
  152. package/src/web/convert/transform.js +65 -0
  153. package/src/web/convert/types.js +2 -0
  154. package/src/web/convert/utils.js +39 -0
  155. package/src/web/create.js +39 -0
  156. package/src/web/index.js +22 -0
  157. package/src/web/listener.js +26 -0
  158. package/src/web/mock.js +21 -0
  159. package/src/web/mq.js +14 -0
  160. package/src/web/registry.js +168 -0
  161. package/src/web/runtime.js +160 -0
  162. package/src/web/runtime.ts +1 -1
  163. package/src/web/shadowRegistry.js +99 -0
  164. package/src/web/state.ts +3 -3
  165. package/src/web/utils/common.js +79 -0
  166. package/src/web/utils/index.js +2 -0
  167. package/src/web/utils/unistyle.js +72 -0
  168. package/src/web/utils/unistyle.ts +2 -2
  169. package/src/web/variants/getVariants.js +26 -0
  170. package/src/web/variants/index.js +2 -0
  171. package/src/web/variants/useVariants.js +50 -0
  172. package/lib/typescript/example/App.d.ts +0 -4
  173. package/lib/typescript/example/App.d.ts.map +0 -1
  174. package/lib/typescript/example/Typography.d.ts +0 -35
  175. package/lib/typescript/example/Typography.d.ts.map +0 -1
  176. package/lib/typescript/example/unistyles.d.ts +0 -63
  177. package/lib/typescript/example/unistyles.d.ts.map +0 -1
  178. package/lib/typescript/expo-example/App.d.ts +0 -4
  179. package/lib/typescript/expo-example/App.d.ts.map +0 -1
  180. package/lib/typescript/expo-example/app/(tabs)/_layout.d.ts +0 -3
  181. package/lib/typescript/expo-example/app/(tabs)/_layout.d.ts.map +0 -1
  182. package/lib/typescript/expo-example/app/(tabs)/explore.d.ts +0 -3
  183. package/lib/typescript/expo-example/app/(tabs)/explore.d.ts.map +0 -1
  184. package/lib/typescript/expo-example/app/(tabs)/index.d.ts +0 -3
  185. package/lib/typescript/expo-example/app/(tabs)/index.d.ts.map +0 -1
  186. package/lib/typescript/expo-example/app/+html.d.ts +0 -4
  187. package/lib/typescript/expo-example/app/+html.d.ts.map +0 -1
  188. package/lib/typescript/expo-example/app/+not-found.d.ts +0 -3
  189. package/lib/typescript/expo-example/app/+not-found.d.ts.map +0 -1
  190. package/lib/typescript/expo-example/app/_layout.d.ts +0 -3
  191. package/lib/typescript/expo-example/app/_layout.d.ts.map +0 -1
  192. package/lib/typescript/expo-example/unistyles.d.ts +0 -63
  193. package/lib/typescript/expo-example/unistyles.d.ts.map +0 -1
  194. package/plugin/__tests__/dependencies.spec.js +0 -448
  195. package/plugin/__tests__/ref.spec.js +0 -1427
  196. package/plugin/__tests__/stylesheet.spec.js +0 -507
@@ -0,0 +1,168 @@
1
+ import { UnistylesRuntime } from './runtime';
2
+ import { extractMediaQueryValue, keyInObject, getMediaQuery, generateHash, extractUnistyleDependencies } from './utils';
3
+ import { UnistylesListener } from './listener';
4
+ import { convertUnistyles } from './convert';
5
+ import { getVariants } from './variants';
6
+ class UnistylesRegistryBuilder {
7
+ stylesheets = new Map();
8
+ stylesCounter = new Map();
9
+ #styleTag = null;
10
+ disposeListenersMap = new Map();
11
+ dependenciesMap = new Map();
12
+ get styleTag() {
13
+ const tag = this.#styleTag;
14
+ if (!tag) {
15
+ const newTag = document.createElement('style');
16
+ newTag.id = 'unistyles-web';
17
+ this.#styleTag = newTag;
18
+ document.head.appendChild(newTag);
19
+ return newTag;
20
+ }
21
+ return tag;
22
+ }
23
+ getComputedStylesheet = (stylesheet) => {
24
+ if (typeof stylesheet !== 'function') {
25
+ return stylesheet;
26
+ }
27
+ const computedStylesheet = this.stylesheets.get(stylesheet);
28
+ if (computedStylesheet) {
29
+ return computedStylesheet;
30
+ }
31
+ const createdStylesheet = stylesheet(UnistylesRuntime.theme, UnistylesRuntime.miniRuntime);
32
+ const dependencies = Object.values(createdStylesheet).flatMap(value => extractUnistyleDependencies(value));
33
+ this.addDependenciesToStylesheet(stylesheet, dependencies);
34
+ this.stylesheets.set(stylesheet, createdStylesheet);
35
+ return createdStylesheet;
36
+ };
37
+ addDependenciesToStylesheet = (stylesheet, dependencies) => {
38
+ this.disposeListenersMap.get(stylesheet)?.();
39
+ const dependenciesMap = this.dependenciesMap.get(stylesheet) ?? new Set(dependencies);
40
+ dependencies.forEach(dependency => dependenciesMap.add(dependency));
41
+ const dispose = UnistylesListener.addListeners(Array.from(dependenciesMap), () => {
42
+ const newComputedStylesheet = stylesheet(UnistylesRuntime.theme, UnistylesRuntime.miniRuntime);
43
+ this.stylesheets.set(stylesheet, newComputedStylesheet);
44
+ });
45
+ this.dependenciesMap.set(stylesheet, dependenciesMap);
46
+ this.disposeListenersMap.set(stylesheet, dispose);
47
+ };
48
+ add = ({ key, value, stylesheet, args, variants }) => {
49
+ const hash = generateHash(value);
50
+ const existingCounter = this.stylesCounter.get(hash);
51
+ if (!existingCounter || existingCounter.size === 0) {
52
+ const counter = new Set();
53
+ const dependencies = extractUnistyleDependencies(value);
54
+ counter.add(value);
55
+ this.stylesCounter.set(hash, counter);
56
+ this.applyStyles(hash, convertUnistyles(value));
57
+ UnistylesListener.addListeners(dependencies, async () => {
58
+ // Move this callback to the end of the event loop
59
+ await Promise.resolve();
60
+ const newComputedStyleSheet = this.getComputedStylesheet(stylesheet);
61
+ const newValue = newComputedStyleSheet[key];
62
+ const result = typeof newValue === 'function'
63
+ ? newValue(...args)
64
+ : newValue;
65
+ const { variantsResult } = Object.fromEntries(getVariants({ variantsResult: result }, variants));
66
+ const resultWithVariants = {
67
+ ...result,
68
+ ...variantsResult
69
+ };
70
+ this.applyStyles(hash, convertUnistyles(resultWithVariants));
71
+ });
72
+ return hash;
73
+ }
74
+ existingCounter.add(value);
75
+ return hash;
76
+ };
77
+ applyStyles = (hash, styles) => {
78
+ Object.entries(styles).forEach(([key, value]) => {
79
+ if (!this.styleTag.sheet) {
80
+ return;
81
+ }
82
+ if (typeof value === 'object' && !key.startsWith('_')) {
83
+ const mediaQuery = getMediaQuery(key);
84
+ const cssRules = Array.from(this.styleTag.sheet.cssRules);
85
+ let queryRule = cssRules.find(rule => {
86
+ if (!(rule instanceof CSSMediaRule)) {
87
+ return false;
88
+ }
89
+ return rule.media.item(0)?.includes(mediaQuery);
90
+ }) ?? null;
91
+ if (!queryRule) {
92
+ const mediaQueryValue = extractMediaQueryValue(mediaQuery);
93
+ const ruleIndex = mediaQueryValue
94
+ ? cssRules.reduce((acc, rule, ruleIndex) => {
95
+ if (!(rule instanceof CSSMediaRule)) {
96
+ return acc;
97
+ }
98
+ const ruleMediaQueryValue = extractMediaQueryValue(rule.conditionText);
99
+ if (ruleMediaQueryValue === undefined) {
100
+ return;
101
+ }
102
+ return ruleMediaQueryValue > mediaQueryValue ? ruleIndex : acc;
103
+ }, cssRules.length)
104
+ : undefined;
105
+ queryRule = this.styleTag.sheet.cssRules.item(this.styleTag.sheet.insertRule(`@media ${mediaQuery} {.${hash} {}}`, ruleIndex));
106
+ }
107
+ if (queryRule instanceof CSSMediaRule) {
108
+ Object.entries(value).forEach(([mqKey, mqValue]) => {
109
+ this.applyRule({
110
+ hash,
111
+ key: mqKey,
112
+ value: mqValue,
113
+ sheet: queryRule
114
+ });
115
+ });
116
+ }
117
+ return;
118
+ }
119
+ // Pseudo
120
+ if (typeof value === 'object') {
121
+ Object.entries(value).forEach(([pseudoKey, pseudoValue]) => {
122
+ this.applyRule({
123
+ hash: `${hash}${key.replace('_', ':')}`,
124
+ key: pseudoKey,
125
+ value: pseudoValue,
126
+ sheet: this.styleTag.sheet
127
+ });
128
+ });
129
+ return;
130
+ }
131
+ this.applyRule({
132
+ hash,
133
+ key,
134
+ value,
135
+ sheet: this.styleTag.sheet
136
+ });
137
+ });
138
+ };
139
+ applyRule = ({ hash, key, value, sheet }) => {
140
+ let rule = Array.from(sheet.cssRules).find(rule => {
141
+ if (!(rule instanceof CSSStyleRule)) {
142
+ return false;
143
+ }
144
+ // In unistyles pseudos are prefixed with ':' but in css some of them are prefixed with '::'
145
+ return rule.selectorText.replace('::', ':').includes(hash);
146
+ }) ?? null;
147
+ if (!rule) {
148
+ rule = sheet.cssRules.item(sheet.insertRule(`.${hash} {}`));
149
+ }
150
+ if (!(rule instanceof CSSStyleRule) || !keyInObject(rule.style, key)) {
151
+ return;
152
+ }
153
+ rule.style[key] = value;
154
+ };
155
+ remove = (value) => {
156
+ const hash = generateHash(value);
157
+ const existingStyles = this.stylesCounter.get(hash);
158
+ if (!existingStyles) {
159
+ return;
160
+ }
161
+ existingStyles.delete(value);
162
+ if (existingStyles.size === 0) {
163
+ const ruleIndex = Array.from(this.styleTag.sheet?.cssRules ?? []).findIndex(rule => rule.cssText.includes(`.${hash}`));
164
+ this.styleTag.sheet?.deleteRule(ruleIndex);
165
+ }
166
+ };
167
+ }
168
+ export const UnistylesRegistry = new UnistylesRegistryBuilder();
@@ -0,0 +1,160 @@
1
+ import { UnistyleDependency } from '../specs/NativePlatform';
2
+ import { ColorScheme, Orientation } from '../specs/types';
3
+ import { WebContentSizeCategory } from '../types';
4
+ import { UnistylesListener } from './listener';
5
+ import { NavigationBar, StatusBar } from './mock';
6
+ import { UnistylesState } from './state';
7
+ import { hexToRGBA, isServer, schemeToTheme } from './utils';
8
+ class UnistylesRuntimeBuilder {
9
+ lightMedia = this.getLightMedia();
10
+ darkMedia = this.getDarkMedia();
11
+ getLightMedia() {
12
+ if (isServer()) {
13
+ return null;
14
+ }
15
+ if (!this.lightMedia) {
16
+ this.lightMedia = window.matchMedia('(prefers-color-scheme: light)');
17
+ }
18
+ return this.lightMedia;
19
+ }
20
+ getDarkMedia() {
21
+ if (isServer()) {
22
+ return null;
23
+ }
24
+ if (!this.darkMedia) {
25
+ this.darkMedia = window.matchMedia('(prefers-color-scheme: dark)');
26
+ }
27
+ return this.darkMedia;
28
+ }
29
+ get colorScheme() {
30
+ switch (true) {
31
+ case this.getLightMedia()?.matches:
32
+ return ColorScheme.Light;
33
+ case this.getDarkMedia()?.matches:
34
+ return ColorScheme.Dark;
35
+ default:
36
+ return ColorScheme.Unspecified;
37
+ }
38
+ }
39
+ get themeName() {
40
+ return UnistylesState.themeName;
41
+ }
42
+ get contentSizeCategory() {
43
+ return WebContentSizeCategory.Unspecified;
44
+ }
45
+ get breakpoint() {
46
+ return UnistylesState.breakpoint;
47
+ }
48
+ get orientation() {
49
+ if (isServer()) {
50
+ return Orientation.Portrait;
51
+ }
52
+ return screen.orientation.type.includes('portrait') ? Orientation.Portrait : Orientation.Landscape;
53
+ }
54
+ get theme() {
55
+ return this.getTheme(this.themeName);
56
+ }
57
+ get pixelRatio() {
58
+ return isServer() ? 1 : window.devicePixelRatio;
59
+ }
60
+ get screen() {
61
+ if (isServer()) {
62
+ return {
63
+ width: 0,
64
+ height: 0
65
+ };
66
+ }
67
+ return {
68
+ width: window.innerWidth,
69
+ height: window.innerHeight
70
+ };
71
+ }
72
+ get fontScale() {
73
+ return 1;
74
+ }
75
+ get insets() {
76
+ return {
77
+ top: 0,
78
+ bottom: 0,
79
+ left: 0,
80
+ right: 0,
81
+ ime: 0
82
+ };
83
+ }
84
+ get statusBar() {
85
+ return StatusBar;
86
+ }
87
+ get rtl() {
88
+ return isServer() ? true : document.documentElement.dir === 'rtl';
89
+ }
90
+ get hasAdaptiveThemes() {
91
+ return UnistylesState.hasAdaptiveThemes;
92
+ }
93
+ get navigationBar() {
94
+ return NavigationBar;
95
+ }
96
+ get miniRuntime() {
97
+ return {
98
+ colorScheme: this.colorScheme,
99
+ themeName: this.themeName,
100
+ contentSizeCategory: this.contentSizeCategory,
101
+ breakpoint: this.breakpoint,
102
+ isLandscape: this.orientation === Orientation.Landscape,
103
+ isPortrait: this.orientation === Orientation.Portrait,
104
+ pixelRatio: this.pixelRatio,
105
+ screen: this.screen,
106
+ fontScale: this.fontScale,
107
+ insets: this.insets,
108
+ statusBar: {
109
+ width: this.statusBar.width,
110
+ height: this.statusBar.height
111
+ },
112
+ navigationBar: {
113
+ width: this.navigationBar.width,
114
+ height: this.navigationBar.height,
115
+ },
116
+ rtl: this.rtl,
117
+ hasAdaptiveThemes: this.hasAdaptiveThemes
118
+ };
119
+ }
120
+ setTheme = (themeName) => {
121
+ if (themeName === UnistylesRuntime.themeName) {
122
+ return;
123
+ }
124
+ UnistylesState.themeName = themeName;
125
+ UnistylesListener.emitChange(UnistyleDependency.Theme);
126
+ UnistylesListener.emitChange(UnistyleDependency.ThemeName);
127
+ };
128
+ setAdaptiveThemes = (isEnabled) => {
129
+ UnistylesState.hasAdaptiveThemes = isEnabled;
130
+ if (!isEnabled) {
131
+ return;
132
+ }
133
+ this.setTheme(schemeToTheme(UnistylesRuntime.colorScheme));
134
+ };
135
+ setRootViewBackgroundColor = (hex, alpha) => {
136
+ if (isServer()) {
137
+ return;
138
+ }
139
+ document.documentElement.style.backgroundColor = alpha ? hexToRGBA(hex, alpha) : hex;
140
+ };
141
+ setImmersiveMode = () => { };
142
+ updateTheme = (themeName, updater) => {
143
+ const oldTheme = UnistylesState.themes.get(themeName);
144
+ if (!oldTheme) {
145
+ throw new Error(`🦄 Theme "${themeName}" is not registered!`);
146
+ }
147
+ UnistylesState.themes.set(themeName, updater(oldTheme));
148
+ };
149
+ getTheme = (themeName = this.themeName) => {
150
+ if (!themeName) {
151
+ throw new Error('🦄 No theme selected!');
152
+ }
153
+ const theme = UnistylesState.themes.get(themeName);
154
+ if (!theme) {
155
+ throw new Error(`🦄 Theme "${this.themeName}" is not registered!`);
156
+ }
157
+ return theme;
158
+ };
159
+ }
160
+ export const UnistylesRuntime = new UnistylesRuntimeBuilder();
@@ -160,7 +160,7 @@ class UnistylesRuntimeBuilder {
160
160
  return
161
161
  }
162
162
 
163
- this.setTheme(schemeToTheme(UnistylesRuntime.colorScheme))
163
+ this.setTheme(schemeToTheme(UnistylesRuntime.colorScheme) as AppThemeName)
164
164
  }
165
165
 
166
166
  setRootViewBackgroundColor = (hex: string, alpha?: number) => {
@@ -0,0 +1,99 @@
1
+ import { UnistylesRegistry } from './registry';
2
+ import { createDoubleMap, equal, extractSecrets, extractUnistyleDependencies, isInDocument } from './utils';
3
+ import { getVariants } from './variants';
4
+ class UnistylesShadowRegistryBuilder {
5
+ // MOCKS
6
+ name = 'UnistylesShadowRegistry';
7
+ __type = 'web';
8
+ equals = () => true;
9
+ toString = () => 'UnistylesShadowRegistry';
10
+ dispose = () => { };
11
+ // END MOCKS
12
+ resultsMap = createDoubleMap();
13
+ classNamesMap = createDoubleMap();
14
+ add = (ref, _style, _variants, _args) => {
15
+ // Style is not provided
16
+ if (!_style) {
17
+ return;
18
+ }
19
+ // Array of styles
20
+ if (Array.isArray(_style)) {
21
+ _style.forEach(style => this.add(ref, style, _variants, _args));
22
+ return;
23
+ }
24
+ // Not a unistyle
25
+ if (!Object.keys(_style).some(key => key.startsWith('__uni__'))) {
26
+ return;
27
+ }
28
+ // Ref is unmounted, remove style tags from the document
29
+ if (ref === null) {
30
+ const secrets = extractSecrets(_style);
31
+ secrets.forEach(({ __uni__refs, __uni__key }) => {
32
+ __uni__refs.forEach(ref => {
33
+ if (isInDocument(ref)) {
34
+ return;
35
+ }
36
+ const oldResult = this.resultsMap.get(ref, __uni__key);
37
+ this.resultsMap.delete(ref, __uni__key);
38
+ this.classNamesMap.delete(ref, __uni__key);
39
+ if (oldResult) {
40
+ UnistylesRegistry.remove(oldResult);
41
+ }
42
+ });
43
+ });
44
+ return;
45
+ }
46
+ // Ref is not an HTMLElement
47
+ if (!(ref instanceof HTMLElement)) {
48
+ return;
49
+ }
50
+ extractSecrets(_style).forEach(secret => {
51
+ const { __uni__key, __uni__stylesheet, __uni__variants, __uni__args = [], __uni__refs } = secret;
52
+ const newComputedStylesheet = UnistylesRegistry.getComputedStylesheet(__uni__stylesheet);
53
+ const style = newComputedStylesheet[__uni__key];
54
+ const args = _args ?? __uni__args;
55
+ const variants = _variants && Object.keys(_variants).length > 0 ? _variants : __uni__variants;
56
+ const result = typeof style === 'function'
57
+ ? style(...args)
58
+ : style;
59
+ const { variantsResult } = Object.fromEntries(getVariants({ variantsResult: result }, variants));
60
+ const resultWithVariants = {
61
+ ...result,
62
+ ...variantsResult
63
+ };
64
+ const oldResult = this.resultsMap.get(ref, __uni__key);
65
+ // If results are the same do nothing
66
+ if (equal(oldResult, resultWithVariants)) {
67
+ return;
68
+ }
69
+ const oldClassNames = this.classNamesMap.get(ref, __uni__key);
70
+ // Remove old styles
71
+ if (oldResult) {
72
+ UnistylesRegistry.remove(oldResult);
73
+ }
74
+ // Remove old classnames from the ref
75
+ oldClassNames?.forEach(className => ref.classList.remove(className));
76
+ this.resultsMap.set(ref, __uni__key, resultWithVariants);
77
+ const className = UnistylesRegistry.add({
78
+ key: __uni__key,
79
+ args,
80
+ stylesheet: __uni__stylesheet,
81
+ value: resultWithVariants,
82
+ variants
83
+ });
84
+ const injectedClassNames = resultWithVariants?._web?._classNames ?? [];
85
+ const newClassNames = injectedClassNames.concat(className);
86
+ const dependencies = extractUnistyleDependencies(resultWithVariants);
87
+ if (typeof __uni__stylesheet === 'function') {
88
+ // Add dependencies from dynamic styles to stylesheet
89
+ UnistylesRegistry.addDependenciesToStylesheet(__uni__stylesheet, dependencies);
90
+ }
91
+ __uni__refs.add(ref);
92
+ this.classNamesMap.set(ref, __uni__key, newClassNames);
93
+ // Add new classnames to the ref
94
+ ref.classList.add(...newClassNames);
95
+ });
96
+ };
97
+ remove = () => { };
98
+ }
99
+ export const UnistylesShadowRegistry = new UnistylesShadowRegistryBuilder();
package/src/web/state.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { UnistylesTheme } from '../types'
2
2
  import type { UnistylesConfig } from '../specs/StyleSheet'
3
- import type { AppBreakpoint, AppThemeName } from '../specs/types'
3
+ import type { AppBreakpoint, AppTheme, AppThemeName } from '../specs/types'
4
4
  import type { UnistylesBreakpoints, UnistylesThemes } from '../global'
5
5
  import { UnistylesRuntime } from './runtime'
6
6
  import { isServer, schemeToTheme } from './utils'
@@ -39,7 +39,7 @@ class UnistylesStateBuilder {
39
39
 
40
40
  private initThemes = (themes = {} as UnistylesThemes) => {
41
41
  Object.entries(themes).forEach(([themeName, theme]) => {
42
- this.themes.set(themeName, theme)
42
+ this.themes.set(themeName, theme as AppTheme)
43
43
  })
44
44
  }
45
45
 
@@ -61,7 +61,7 @@ class UnistylesStateBuilder {
61
61
 
62
62
  // Adaptive themes
63
63
  if (settings.adaptiveThemes) {
64
- this.themeName = schemeToTheme(UnistylesRuntime.colorScheme)
64
+ this.themeName = schemeToTheme(UnistylesRuntime.colorScheme) as AppThemeName
65
65
 
66
66
  return
67
67
  }
@@ -0,0 +1,79 @@
1
+ export const reduceObject = (obj, reducer) => Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, reducer(value, key)]));
2
+ export const keyInObject = (obj, key) => key in obj;
3
+ export const isServer = () => typeof window === 'undefined';
4
+ /**
5
+ * Deeply merges properties of passed object
6
+ */
7
+ export const deepMergeObjects = (...sources) => {
8
+ const target = {};
9
+ sources.forEach(source => {
10
+ Object.keys(source).forEach(key => {
11
+ const sourceValue = source[key];
12
+ const targetValue = target[key];
13
+ if (Object(sourceValue) == sourceValue && Object(targetValue) === targetValue) {
14
+ // @ts-expect-error - can't assign to generic
15
+ target[key] = deepMergeObjects(targetValue, sourceValue);
16
+ return;
17
+ }
18
+ // @ts-expect-error - can't assign to generic
19
+ target[key] = sourceValue;
20
+ });
21
+ });
22
+ return target;
23
+ };
24
+ export const warn = (message) => console.warn(`🦄 [react-native-unistyles] ${message}`);
25
+ export const equal = (a, b) => {
26
+ if (Object.is(a, b)) {
27
+ return true;
28
+ }
29
+ if (typeof a !== 'object'
30
+ || a === null
31
+ || typeof b !== 'object'
32
+ || b === null) {
33
+ return false;
34
+ }
35
+ const keysA = Object.keys(a);
36
+ if (keysA.length !== Object.keys(b).length) {
37
+ return false;
38
+ }
39
+ return keysA.every(key => Object.is(a[key], b[key]) && Object.prototype.hasOwnProperty.call(b, key));
40
+ };
41
+ export const generateHash = (value) => {
42
+ const str = JSON.stringify(value);
43
+ let hasher = 5381;
44
+ let length = str.length;
45
+ while (length--)
46
+ hasher = (hasher * 33) ^ str.charCodeAt(length);
47
+ return `unistyles-${(hasher >>> 0).toString(36)}`;
48
+ };
49
+ export const createDoubleMap = () => {
50
+ const map = new Map();
51
+ return {
52
+ get: (key, secondKey) => {
53
+ const mapForKey = map.get(key);
54
+ if (!mapForKey) {
55
+ return undefined;
56
+ }
57
+ return mapForKey.get(secondKey);
58
+ },
59
+ set: (key, secondKey, value) => {
60
+ const mapForKey = map.get(key) ?? new Map();
61
+ map.set(key, mapForKey);
62
+ mapForKey.set(secondKey, value);
63
+ },
64
+ delete: (key, secondKey) => {
65
+ const mapForKey = map.get(key);
66
+ if (!mapForKey) {
67
+ return;
68
+ }
69
+ mapForKey.delete(secondKey);
70
+ },
71
+ forEach: (callback) => {
72
+ map.forEach((mapForKey, key) => {
73
+ mapForKey.forEach((value, secondKey) => {
74
+ callback(key, secondKey, value);
75
+ });
76
+ });
77
+ }
78
+ };
79
+ };
@@ -0,0 +1,2 @@
1
+ export * from './common';
2
+ export * from './unistyle';
@@ -0,0 +1,72 @@
1
+ import { ColorScheme, Orientation } from '../../specs/types';
2
+ import { isUnistylesMq, parseMq } from '../mq';
3
+ import { UnistylesState } from '../state';
4
+ import { keyInObject, reduceObject } from './common';
5
+ export const schemeToTheme = (scheme) => {
6
+ switch (scheme) {
7
+ case ColorScheme.Dark:
8
+ return 'dark';
9
+ case ColorScheme.Light:
10
+ default:
11
+ return 'light';
12
+ }
13
+ };
14
+ export const hexToRGBA = (hex, opacity) => hex
15
+ .replace('#', '')
16
+ .split(/(?=(?:..)*$)/)
17
+ .map(x => parseInt(x, 16))
18
+ .filter(num => !isNaN(num))
19
+ .reduce((acc, color) => `${acc}${color},`, 'rgba(')
20
+ .concat(`${opacity})`);
21
+ export const assignSecrets = (object, secrets) => {
22
+ // @ts-expect-error - assign secrets to object
23
+ object[`__uni__secrets__${Math.random().toString(16).slice(2)}`] = secrets;
24
+ return object;
25
+ };
26
+ export const extractSecrets = (object) => {
27
+ const secrets = Object.entries(object).reduce((acc, [key, value]) => {
28
+ if (key.startsWith('__uni__secrets__')) {
29
+ acc.push(value);
30
+ }
31
+ return acc;
32
+ }, []);
33
+ return secrets;
34
+ };
35
+ export const getStyles = (values) => {
36
+ const returnValue = {};
37
+ Object.defineProperties(returnValue, reduceObject(values, value => ({
38
+ value,
39
+ enumerable: false,
40
+ configurable: true
41
+ })));
42
+ return returnValue;
43
+ };
44
+ export const isInDocument = (element) => document.body.contains(element);
45
+ export const extractMediaQueryValue = (query) => {
46
+ const [_, px] = query.match(/(\d+)px/) ?? [];
47
+ if (!px) {
48
+ return undefined;
49
+ }
50
+ const value = Number(px);
51
+ return isNaN(value) ? undefined : value;
52
+ };
53
+ export const getMediaQuery = (query) => {
54
+ if (Object.values(Orientation).includes(query)) {
55
+ return `(orientation: ${query})`;
56
+ }
57
+ if (isUnistylesMq(query)) {
58
+ const { minWidth, maxWidth, minHeight, maxHeight } = parseMq(query);
59
+ return [
60
+ minWidth ? `(min-width: ${minWidth}px)` : undefined,
61
+ maxWidth ? `(max-width: ${maxWidth}px)` : undefined,
62
+ minHeight ? `(min-height: ${minHeight}px)` : undefined,
63
+ maxHeight ? `(max-height: ${maxHeight}px)` : undefined
64
+ ].filter(Boolean).join(' and ');
65
+ }
66
+ const minWidth = UnistylesState.breakpoints && keyInObject(UnistylesState.breakpoints, query) ? UnistylesState.breakpoints[query] : undefined;
67
+ return `(min-width: ${minWidth ?? 0}px)`;
68
+ };
69
+ export const extractUnistyleDependencies = (value) => {
70
+ const dependencies = keyInObject(value, 'uni__dependencies') ? value.uni__dependencies : [];
71
+ return dependencies;
72
+ };
@@ -1,11 +1,11 @@
1
1
  import type { UnistyleDependency } from '../../specs/NativePlatform'
2
- import { ColorScheme, Orientation, type AppThemeName } from '../../specs/types'
2
+ import { ColorScheme, Orientation } from '../../specs/types'
3
3
  import type { StyleSheet, StyleSheetWithSuperPowers, UnistylesValues } from '../../types/stylesheet'
4
4
  import { isUnistylesMq, parseMq } from '../mq'
5
5
  import { UnistylesState } from '../state'
6
6
  import { keyInObject, reduceObject } from './common'
7
7
 
8
- export const schemeToTheme = (scheme: ColorScheme): AppThemeName => {
8
+ export const schemeToTheme = (scheme: ColorScheme): string => {
9
9
  switch (scheme) {
10
10
  case ColorScheme.Dark:
11
11
  return 'dark'
@@ -0,0 +1,26 @@
1
+ import { deepMergeObjects } from '../utils';
2
+ const hasVariants = (value) => 'variants' in value[1];
3
+ export const getVariants = (styles, selectedVariants) => {
4
+ return Object.entries(styles)
5
+ .filter(hasVariants)
6
+ .filter(([_key, { variants }]) => Object.keys(variants).some(variant => variant in variants))
7
+ .map(([key, { variants, compoundVariants = [] }]) => {
8
+ const variantStyles = Object.entries(variants).flatMap(([variant, styles]) => {
9
+ const selectedVariant = selectedVariants[variant];
10
+ const selectedVariantStyles = styles[selectedVariant] ?? styles['default'];
11
+ if (!selectedVariantStyles) {
12
+ return [];
13
+ }
14
+ return selectedVariantStyles;
15
+ });
16
+ const compoundVariantStyles = compoundVariants.flatMap(compoundVariant => {
17
+ const { styles, ...conditions } = compoundVariant;
18
+ if (Object.entries(conditions).some(([variant, value]) => String(selectedVariants[variant]) !== String(value))) {
19
+ return [];
20
+ }
21
+ return styles;
22
+ });
23
+ const mergedVariantStyles = deepMergeObjects(...variantStyles, ...compoundVariantStyles);
24
+ return [key, mergedVariantStyles];
25
+ });
26
+ };
@@ -0,0 +1,2 @@
1
+ export * from './useVariants';
2
+ export * from './getVariants';