react-native-unistyles 3.0.0-alpha.34 → 3.0.0-alpha.36

Sign up to get free protection for your applications and to get access to all the features.
Files changed (208) hide show
  1. package/android/CMakeLists.txt +31 -36
  2. package/android/build.gradle +2 -1
  3. package/android/src/main/cxx/NativeUnistylesModule.cpp +71 -0
  4. package/android/src/main/cxx/NativeUnistylesModule.h +42 -0
  5. package/android/src/main/cxx/cpp-adapter.cpp +8 -86
  6. package/android/src/main/java/com/unistyles/NativePlatform.kt +184 -0
  7. package/android/src/main/java/com/unistyles/UnistylesModule+insets.kt +8 -0
  8. package/android/src/main/java/com/unistyles/UnistylesModule.kt +47 -0
  9. package/android/src/main/java/com/unistyles/UnistylesPackage.kt +16 -14
  10. package/cxx/NativePlatform.h +11 -0
  11. package/cxx/common/Helpers.h +1 -1
  12. package/cxx/core/Unistyle.h +1 -1
  13. package/cxx/core/UnistylesRegistry.h +1 -1
  14. package/cxx/hybridObjects/HybridNavigationBar.h +3 -3
  15. package/cxx/hybridObjects/HybridStatusBar.h +3 -3
  16. package/cxx/hybridObjects/HybridUnistylesRuntime.cpp +4 -4
  17. package/cxx/hybridObjects/HybridUnistylesRuntime.h +2 -2
  18. package/lib/commonjs/components/useMedia.js.map +1 -1
  19. package/lib/commonjs/components/useMedia.web.js +43 -0
  20. package/lib/commonjs/components/useMedia.web.js.map +1 -0
  21. package/lib/commonjs/core/createUnistylesComponent.js +57 -4
  22. package/lib/commonjs/core/createUnistylesComponent.js.map +1 -1
  23. package/lib/commonjs/core/createUnistylesComponent.native.js +6 -5
  24. package/lib/commonjs/core/createUnistylesComponent.native.js.map +1 -1
  25. package/lib/commonjs/specs/ShadowRegistry/index.js +5 -0
  26. package/lib/commonjs/specs/ShadowRegistry/index.js.map +1 -1
  27. package/lib/commonjs/web/convert/index.js +16 -11
  28. package/lib/commonjs/web/convert/index.js.map +1 -1
  29. package/lib/commonjs/web/convert/object/boxShadow.js +58 -0
  30. package/lib/commonjs/web/convert/object/boxShadow.js.map +1 -0
  31. package/lib/commonjs/web/convert/object/filter.js +42 -0
  32. package/lib/commonjs/web/convert/object/filter.js.map +1 -0
  33. package/lib/commonjs/web/convert/object/index.js +39 -0
  34. package/lib/commonjs/web/convert/object/index.js.map +1 -0
  35. package/lib/commonjs/web/convert/object/objectStyle.js +55 -0
  36. package/lib/commonjs/web/convert/object/objectStyle.js.map +1 -0
  37. package/lib/commonjs/web/convert/object/transform.js +27 -0
  38. package/lib/commonjs/web/convert/object/transform.js.map +1 -0
  39. package/lib/commonjs/web/convert/{boxShadow.js → shadow/boxShadow.js} +9 -24
  40. package/lib/commonjs/web/convert/shadow/boxShadow.js.map +1 -0
  41. package/lib/commonjs/web/convert/shadow/getShadowBreakpoints.js +38 -0
  42. package/lib/commonjs/web/convert/shadow/getShadowBreakpoints.js.map +1 -0
  43. package/lib/commonjs/web/convert/shadow/index.js +28 -0
  44. package/lib/commonjs/web/convert/shadow/index.js.map +1 -0
  45. package/lib/commonjs/web/convert/{textShadow.js → shadow/textShadow.js} +9 -23
  46. package/lib/commonjs/web/convert/shadow/textShadow.js.map +1 -0
  47. package/lib/commonjs/web/convert/utils.js +7 -3
  48. package/lib/commonjs/web/convert/utils.js.map +1 -1
  49. package/lib/commonjs/web/listener.js +10 -0
  50. package/lib/commonjs/web/listener.js.map +1 -1
  51. package/lib/commonjs/web/registry.js +13 -26
  52. package/lib/commonjs/web/registry.js.map +1 -1
  53. package/lib/commonjs/web/runtime.js +3 -0
  54. package/lib/commonjs/web/runtime.js.map +1 -1
  55. package/lib/commonjs/web/shadowRegistry.js +79 -39
  56. package/lib/commonjs/web/shadowRegistry.js.map +1 -1
  57. package/lib/commonjs/web/utils/common.js +3 -33
  58. package/lib/commonjs/web/utils/common.js.map +1 -1
  59. package/lib/commonjs/web/utils/unistyle.js +4 -1
  60. package/lib/commonjs/web/utils/unistyle.js.map +1 -1
  61. package/lib/module/components/useMedia.js.map +1 -1
  62. package/lib/module/components/useMedia.web.js +38 -0
  63. package/lib/module/components/useMedia.web.js.map +1 -0
  64. package/lib/module/core/createUnistylesComponent.js +55 -3
  65. package/lib/module/core/createUnistylesComponent.js.map +1 -1
  66. package/lib/module/core/createUnistylesComponent.native.js +6 -5
  67. package/lib/module/core/createUnistylesComponent.native.js.map +1 -1
  68. package/lib/module/specs/ShadowRegistry/index.js +5 -0
  69. package/lib/module/specs/ShadowRegistry/index.js.map +1 -1
  70. package/lib/module/web/convert/index.js +14 -9
  71. package/lib/module/web/convert/index.js.map +1 -1
  72. package/lib/module/web/convert/object/boxShadow.js +53 -0
  73. package/lib/module/web/convert/object/boxShadow.js.map +1 -0
  74. package/lib/module/web/convert/object/filter.js +37 -0
  75. package/lib/module/web/convert/object/filter.js.map +1 -0
  76. package/lib/module/web/convert/object/index.js +6 -0
  77. package/lib/module/web/convert/object/index.js.map +1 -0
  78. package/lib/module/web/convert/object/objectStyle.js +50 -0
  79. package/lib/module/web/convert/object/objectStyle.js.map +1 -0
  80. package/lib/module/web/convert/object/transform.js +22 -0
  81. package/lib/module/web/convert/object/transform.js.map +1 -0
  82. package/lib/module/web/convert/{boxShadow.js → shadow/boxShadow.js} +9 -24
  83. package/lib/module/web/convert/shadow/boxShadow.js.map +1 -0
  84. package/lib/module/web/convert/shadow/getShadowBreakpoints.js +33 -0
  85. package/lib/module/web/convert/shadow/getShadowBreakpoints.js.map +1 -0
  86. package/lib/module/web/convert/shadow/index.js +5 -0
  87. package/lib/module/web/convert/shadow/index.js.map +1 -0
  88. package/lib/module/web/convert/{textShadow.js → shadow/textShadow.js} +9 -23
  89. package/lib/module/web/convert/shadow/textShadow.js.map +1 -0
  90. package/lib/module/web/convert/utils.js +4 -2
  91. package/lib/module/web/convert/utils.js.map +1 -1
  92. package/lib/module/web/listener.js +10 -0
  93. package/lib/module/web/listener.js.map +1 -1
  94. package/lib/module/web/registry.js +14 -27
  95. package/lib/module/web/registry.js.map +1 -1
  96. package/lib/module/web/runtime.js +3 -0
  97. package/lib/module/web/runtime.js.map +1 -1
  98. package/lib/module/web/shadowRegistry.js +80 -40
  99. package/lib/module/web/shadowRegistry.js.map +1 -1
  100. package/lib/module/web/utils/common.js +1 -31
  101. package/lib/module/web/utils/common.js.map +1 -1
  102. package/lib/module/web/utils/unistyle.js +4 -1
  103. package/lib/module/web/utils/unistyle.js.map +1 -1
  104. package/lib/typescript/src/components/useMedia.web.d.ts +6 -0
  105. package/lib/typescript/src/components/useMedia.web.d.ts.map +1 -0
  106. package/lib/typescript/src/core/createUnistylesComponent.d.ts +4 -3
  107. package/lib/typescript/src/core/createUnistylesComponent.d.ts.map +1 -1
  108. package/lib/typescript/src/core/createUnistylesComponent.native.d.ts +4 -3
  109. package/lib/typescript/src/core/createUnistylesComponent.native.d.ts.map +1 -1
  110. package/lib/typescript/src/specs/ShadowRegistry/index.d.ts.map +1 -1
  111. package/lib/typescript/src/specs/ShadowRegistry/types.d.ts +3 -0
  112. package/lib/typescript/src/specs/ShadowRegistry/types.d.ts.map +1 -1
  113. package/lib/typescript/src/types/common.d.ts +1 -0
  114. package/lib/typescript/src/types/common.d.ts.map +1 -1
  115. package/lib/typescript/src/web/convert/index.d.ts.map +1 -1
  116. package/lib/typescript/src/web/convert/object/boxShadow.d.ts +9 -0
  117. package/lib/typescript/src/web/convert/object/boxShadow.d.ts.map +1 -0
  118. package/lib/typescript/src/web/convert/object/filter.d.ts +3 -0
  119. package/lib/typescript/src/web/convert/object/filter.d.ts.map +1 -0
  120. package/lib/typescript/src/web/convert/object/index.d.ts +4 -0
  121. package/lib/typescript/src/web/convert/object/index.d.ts.map +1 -0
  122. package/lib/typescript/src/web/convert/object/objectStyle.d.ts +5 -0
  123. package/lib/typescript/src/web/convert/object/objectStyle.d.ts.map +1 -0
  124. package/lib/typescript/src/web/convert/object/transform.d.ts +3 -0
  125. package/lib/typescript/src/web/convert/object/transform.d.ts.map +1 -0
  126. package/lib/typescript/src/web/convert/shadow/boxShadow.d.ts.map +1 -0
  127. package/lib/typescript/src/web/convert/shadow/getShadowBreakpoints.d.ts +2 -0
  128. package/lib/typescript/src/web/convert/shadow/getShadowBreakpoints.d.ts.map +1 -0
  129. package/lib/typescript/src/web/convert/shadow/index.d.ts +3 -0
  130. package/lib/typescript/src/web/convert/shadow/index.d.ts.map +1 -0
  131. package/lib/typescript/src/web/convert/shadow/textShadow.d.ts.map +1 -0
  132. package/lib/typescript/src/web/convert/types.d.ts +7 -1
  133. package/lib/typescript/src/web/convert/types.d.ts.map +1 -1
  134. package/lib/typescript/src/web/convert/utils.d.ts +8 -4
  135. package/lib/typescript/src/web/convert/utils.d.ts.map +1 -1
  136. package/lib/typescript/src/web/create.d.ts +8 -8
  137. package/lib/typescript/src/web/index.d.ts +8 -8
  138. package/lib/typescript/src/web/listener.d.ts +2 -0
  139. package/lib/typescript/src/web/listener.d.ts.map +1 -1
  140. package/lib/typescript/src/web/registry.d.ts +5 -9
  141. package/lib/typescript/src/web/registry.d.ts.map +1 -1
  142. package/lib/typescript/src/web/runtime.d.ts +1 -0
  143. package/lib/typescript/src/web/runtime.d.ts.map +1 -1
  144. package/lib/typescript/src/web/shadowRegistry.d.ts +4 -1
  145. package/lib/typescript/src/web/shadowRegistry.d.ts.map +1 -1
  146. package/lib/typescript/src/web/utils/common.d.ts +1 -6
  147. package/lib/typescript/src/web/utils/common.d.ts.map +1 -1
  148. package/lib/typescript/src/web/utils/unistyle.d.ts.map +1 -1
  149. package/nitrogen/generated/android/c++/JHybridNativePlatformSpec.hpp +6 -0
  150. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unistyles/Dimensions.kt +1 -0
  151. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unistyles/Func_void.kt +1 -0
  152. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unistyles/Func_void_std__vector_UnistyleDependency_.kt +1 -0
  153. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unistyles/Insets.kt +1 -0
  154. package/nitrogen/generated/android/kotlin/com/margelo/nitro/unistyles/UnistylesNativeMiniRuntime.kt +1 -0
  155. package/nitrogen/generated/android/unistyles+autolinking.gradle +2 -0
  156. package/nitrogen/generated/ios/Unistyles+autolinking.rb +1 -1
  157. package/package.json +3 -3
  158. package/src/components/useMedia.ts +1 -1
  159. package/src/components/useMedia.web.ts +47 -0
  160. package/src/core/createUnistylesComponent.native.tsx +12 -10
  161. package/src/core/createUnistylesComponent.tsx +72 -6
  162. package/src/specs/ShadowRegistry/index.ts +5 -0
  163. package/src/specs/ShadowRegistry/types.ts +4 -1
  164. package/src/types/common.ts +1 -0
  165. package/src/web/convert/index.ts +16 -9
  166. package/src/web/convert/object/boxShadow.ts +54 -0
  167. package/src/web/convert/object/filter.ts +39 -0
  168. package/src/web/convert/object/index.ts +3 -0
  169. package/src/web/convert/object/objectStyle.ts +68 -0
  170. package/src/web/convert/object/transform.ts +24 -0
  171. package/src/web/convert/{boxShadow.ts → shadow/boxShadow.ts} +9 -30
  172. package/src/web/convert/shadow/getShadowBreakpoints.ts +34 -0
  173. package/src/web/convert/shadow/index.ts +2 -0
  174. package/src/web/convert/{textShadow.ts → shadow/textShadow.ts} +9 -29
  175. package/src/web/convert/types.ts +8 -1
  176. package/src/web/convert/utils.ts +11 -5
  177. package/src/web/listener.ts +10 -0
  178. package/src/web/registry.ts +10 -31
  179. package/src/web/runtime.ts +4 -0
  180. package/src/web/shadowRegistry.ts +85 -46
  181. package/src/web/utils/common.ts +1 -37
  182. package/src/web/utils/unistyle.ts +5 -1
  183. package/android/src/main/cxx/helpers.cpp +0 -105
  184. package/android/src/main/cxx/helpers.h +0 -16
  185. package/android/src/main/cxx/platform.cpp +0 -170
  186. package/android/src/main/cxx/platform.h +0 -20
  187. package/lib/commonjs/web/convert/boxShadow.js.map +0 -1
  188. package/lib/commonjs/web/convert/shadow.js +0 -68
  189. package/lib/commonjs/web/convert/shadow.js.map +0 -1
  190. package/lib/commonjs/web/convert/textShadow.js.map +0 -1
  191. package/lib/commonjs/web/convert/transform.js +0 -72
  192. package/lib/commonjs/web/convert/transform.js.map +0 -1
  193. package/lib/module/web/convert/boxShadow.js.map +0 -1
  194. package/lib/module/web/convert/shadow.js +0 -63
  195. package/lib/module/web/convert/shadow.js.map +0 -1
  196. package/lib/module/web/convert/textShadow.js.map +0 -1
  197. package/lib/module/web/convert/transform.js +0 -67
  198. package/lib/module/web/convert/transform.js.map +0 -1
  199. package/lib/typescript/src/web/convert/boxShadow.d.ts.map +0 -1
  200. package/lib/typescript/src/web/convert/shadow.d.ts +0 -2
  201. package/lib/typescript/src/web/convert/shadow.d.ts.map +0 -1
  202. package/lib/typescript/src/web/convert/textShadow.d.ts.map +0 -1
  203. package/lib/typescript/src/web/convert/transform.d.ts +0 -4
  204. package/lib/typescript/src/web/convert/transform.d.ts.map +0 -1
  205. package/src/web/convert/shadow.ts +0 -68
  206. package/src/web/convert/transform.ts +0 -88
  207. /package/lib/typescript/src/web/convert/{boxShadow.d.ts → shadow/boxShadow.d.ts} +0 -0
  208. /package/lib/typescript/src/web/convert/{textShadow.d.ts → shadow/textShadow.d.ts} +0 -0
@@ -0,0 +1,34 @@
1
+ import type { ShadowOffset } from '../types'
2
+
3
+ export const getShadowBreakpoints = (shadowProperties: ReadonlyArray<string>, styles: Record<string, any>) => {
4
+ const breakpoints = new Set<string>()
5
+
6
+ shadowProperties.forEach(key => {
7
+ const value = styles[key]
8
+
9
+ if (typeof value !== 'object') {
10
+ return
11
+ }
12
+
13
+ if (key === 'shadowOffset' || key === 'textShadowOffset') {
14
+ const { width, height } = value as ShadowOffset
15
+
16
+ // If shadowOffset.width has breakpoints
17
+ if (typeof width === 'object') {
18
+ Object.keys(width).forEach(breakpoint => breakpoints.add(breakpoint))
19
+ }
20
+
21
+ // If shadowOffset.height has breakpoints
22
+ if (typeof height === 'object') {
23
+ Object.keys(height).forEach(breakpoint => breakpoints.add(breakpoint))
24
+ }
25
+
26
+ return
27
+ }
28
+
29
+ // Collect regular breakpoints
30
+ Object.keys(value).forEach(breakpoint => breakpoints.add(breakpoint))
31
+ })
32
+
33
+ return Array.from(breakpoints)
34
+ }
@@ -0,0 +1,2 @@
1
+ export * from './boxShadow'
2
+ export * from './textShadow'
@@ -1,40 +1,20 @@
1
- import { deepMergeObjects, warn } from '../utils'
2
- import { validateShadow } from './shadow'
3
- import { TEXT_SHADOW_STYLES, type TextShadow } from './types'
4
- import { extractShadowValue, normalizeColor, normalizeNumericValue } from './utils'
1
+ import { deepMergeObjects } from '../../utils'
2
+ import { TEXT_SHADOW_STYLES, type TextShadow } from '../types'
3
+ import { extractShadowValue, normalizeColor, normalizeNumericValue } from '../utils'
4
+ import { getShadowBreakpoints } from './getShadowBreakpoints'
5
5
 
6
6
  const createTextShadowValue = (style: TextShadow) => {
7
7
  const { textShadowColor, textShadowOffset, textShadowRadius } = style
8
- const offsetX = normalizeNumericValue(textShadowOffset.width)
9
- const offsetY = normalizeNumericValue(textShadowOffset.height)
10
- const radius = normalizeNumericValue(textShadowRadius)
11
- const color = normalizeColor(textShadowColor as string)
8
+ const offsetX = normalizeNumericValue(textShadowOffset?.width ?? 0)
9
+ const offsetY = normalizeNumericValue(textShadowOffset?.height ?? 0)
10
+ const radius = normalizeNumericValue(textShadowRadius ?? 0)
11
+ const color = normalizeColor((textShadowColor ?? '#000000') as string)
12
12
 
13
13
  return `${offsetX} ${offsetY} ${radius} ${color}`
14
14
  }
15
15
 
16
16
  export const getTextShadowStyle = (styles: Record<string, any>) => {
17
- const missingStyles = TEXT_SHADOW_STYLES.filter(key => !(key in styles))
18
-
19
- if (missingStyles.length) {
20
- warn(`can't apply text shadow as you miss these properties: ${missingStyles.join(', ')}`)
21
-
22
- return {}
23
- }
24
-
25
- const breakpointsSet = new Set<string>()
26
-
27
- try {
28
- validateShadow(TEXT_SHADOW_STYLES, styles, breakpointsSet)
29
- } catch (error) {
30
- if (typeof error === 'string') {
31
- warn(error)
32
- }
33
-
34
- return {}
35
- }
36
-
37
- const breakpoints = Array.from(breakpointsSet)
17
+ const breakpoints = getShadowBreakpoints(TEXT_SHADOW_STYLES, styles)
38
18
 
39
19
  // If no breakpoints were used return styles without media queries
40
20
  if (breakpoints.length === 0) {
@@ -1,4 +1,4 @@
1
- import type { TextStyle, ViewStyle } from 'react-native'
1
+ import type { FilterFunction, TextStyle, ViewStyle } from 'react-native'
2
2
  import type { ToDeepUnistyles } from '../../types/stylesheet'
3
3
 
4
4
  export type ShadowOffset = ToDeepUnistyles<{ width: number, height: number }>
@@ -14,3 +14,10 @@ export type BoxShadow = Required<Pick<ViewStyle, typeof BOX_SHADOW_STYLES[number
14
14
  export type AllShadow = TextShadow & BoxShadow
15
15
 
16
16
  export type AllShadowKeys = keyof AllShadow
17
+
18
+ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never
19
+ type FilterKeys = keyof UnionToIntersection<FilterFunction>
20
+
21
+ export type Filters = {
22
+ [K in FilterKeys]: UnionToIntersection<FilterFunction>[K]
23
+ }
@@ -1,17 +1,23 @@
1
1
  // based on react-native-web normalizer
2
2
  // https://github.com/necolas/react-native-web
3
3
  import normalizeColors from '@react-native/normalize-colors'
4
- import { BOX_SHADOW_STYLES, TEXT_SHADOW_STYLES, type AllShadow, type AllShadowKeys } from './types'
4
+ import { BOX_SHADOW_STYLES, TEXT_SHADOW_STYLES, type AllShadow, type AllShadowKeys, type Filters } from './types'
5
+ import type { TransformStyles } from '../../types/core'
6
+ import type { BoxShadowValue } from 'react-native'
5
7
 
6
- export const isTransform = (key: string, value: any): value is Array<Record<string, any>> => key === 'transform' && Array.isArray(value)
8
+ export const isTransform = (key: string, value: any): value is Array<TransformStyles> => key === 'transform' && Array.isArray(value)
7
9
 
8
10
  export const isTextShadow = (key: string) => TEXT_SHADOW_STYLES.includes(key as typeof TEXT_SHADOW_STYLES[number])
9
11
 
10
- export const isBoxShadow = (key: string) => BOX_SHADOW_STYLES.includes(key as typeof BOX_SHADOW_STYLES[number])
12
+ export const isShadow = (key: string) => BOX_SHADOW_STYLES.includes(key as typeof BOX_SHADOW_STYLES[number])
11
13
 
12
- export const normalizeNumericValue = (value: number) => value ? `${value}px` : value
14
+ export const isFilter = (key: string, value: any): value is Array<Filters> => key === 'filter' && Array.isArray(value)
13
15
 
14
- export const normalizeColor = (color: string, opacity: number = 1) => {
16
+ export const isBoxShadow = (key: string, value: any): value is Array<BoxShadowValue> => key === 'boxShadow' && Array.isArray(value)
17
+
18
+ export const normalizeNumericValue = (value: number | string) => value && typeof value === 'number' ? `${value}px` : value
19
+
20
+ export const normalizeColor = (color: string, opacity = 1) => {
15
21
  // If the opacity is 1 there's no need to normalize the color
16
22
  if (opacity === 1) {
17
23
  return color
@@ -4,8 +4,10 @@ import { UnistylesRuntime } from './runtime'
4
4
  class UnistylesListenerBuilder {
5
5
  private isInitialized = false
6
6
  private listeners = Array.from({ length: Object.keys(UnistyleDependency).length / 2 }, () => new Set<VoidFunction>())
7
+ private stylesheetListeners = Array.from({ length: Object.keys(UnistyleDependency).length / 2 }, () => new Set<VoidFunction>())
7
8
 
8
9
  emitChange = (dependency: UnistyleDependency) => {
10
+ this.stylesheetListeners[dependency]?.forEach(listener => listener())
9
11
  this.listeners[dependency]?.forEach(listener => listener())
10
12
  }
11
13
 
@@ -28,6 +30,14 @@ class UnistylesListenerBuilder {
28
30
  dependencies.forEach(dependency => this.listeners[dependency]?.delete(listener))
29
31
  }
30
32
  }
33
+
34
+ addStylesheetListeners = (dependencies: Array<UnistyleDependency>, listener: VoidFunction) => {
35
+ dependencies.forEach(dependency => this.stylesheetListeners[dependency]?.add(listener))
36
+
37
+ return () => {
38
+ dependencies.forEach(dependency => this.stylesheetListeners[dependency]?.delete(listener))
39
+ }
40
+ }
31
41
  }
32
42
 
33
43
  export const UnistylesListener = new UnistylesListenerBuilder()
@@ -1,20 +1,11 @@
1
1
  import type { UnistylesTheme, UnistylesValues } from '../types'
2
2
  import type { StyleSheet, StyleSheetWithSuperPowers } from '../types/stylesheet'
3
3
  import { UnistylesRuntime } from './runtime'
4
- import { extractMediaQueryValue, keyInObject, getMediaQuery, generateHash, extractUnistyleDependencies, deepMergeObjects } from './utils'
4
+ import { extractMediaQueryValue, keyInObject, getMediaQuery, generateHash, extractUnistyleDependencies } from './utils'
5
5
  import { UnistylesListener } from './listener'
6
6
  import { convertUnistyles } from './convert'
7
7
  import type { UnistyleDependency } from '../specs/NativePlatform'
8
8
  import type { UnistylesMiniRuntime } from '../specs'
9
- import { getVariants } from './variants'
10
-
11
- type AddProps = {
12
- value: UnistylesValues,
13
- stylesheet: StyleSheetWithSuperPowers<StyleSheet>,
14
- key: string,
15
- args: Array<any>,
16
- variants: Record<string, any>
17
- }
18
9
 
19
10
  type ApplyRuleProps = {
20
11
  hash: string,
@@ -75,7 +66,7 @@ class UnistylesRegistryBuilder {
75
66
 
76
67
  dependencies.forEach(dependency => dependenciesMap.add(dependency))
77
68
 
78
- const dispose = UnistylesListener.addListeners(Array.from(dependenciesMap), () => {
69
+ const dispose = UnistylesListener.addStylesheetListeners(Array.from(dependenciesMap), () => {
79
70
  const newComputedStylesheet = stylesheet(UnistylesRuntime.theme, UnistylesRuntime.miniRuntime)
80
71
 
81
72
  this.stylesheets.set(stylesheet, newComputedStylesheet)
@@ -85,42 +76,26 @@ class UnistylesRegistryBuilder {
85
76
  this.disposeListenersMap.set(stylesheet, dispose)
86
77
  }
87
78
 
88
- add = ({ key, value, stylesheet, args, variants }: AddProps) => {
79
+ add = (value: UnistylesValues) => {
89
80
  const hash = generateHash(value)
90
81
  const existingCounter = this.stylesCounter.get(hash)
91
82
 
92
83
  if (!existingCounter || existingCounter.size === 0) {
93
84
  const counter = new Set<UnistylesValues>()
94
- const dependencies = extractUnistyleDependencies(value)
95
85
 
96
86
  counter.add(value)
97
87
  this.stylesCounter.set(hash, counter)
98
88
  this.applyStyles(hash, convertUnistyles(value))
99
89
 
100
- UnistylesListener.addListeners(dependencies, async () => {
101
- // Move this callback to the end of the event loop
102
- await Promise.resolve()
103
-
104
- const newComputedStyleSheet = this.getComputedStylesheet(stylesheet)
105
- const newValue = newComputedStyleSheet[key]!
106
- const result = typeof newValue === 'function'
107
- ? newValue(...args)
108
- : newValue
109
- const { variantsResult } = Object.fromEntries(getVariants({ variantsResult: result }, variants))
110
- const resultWithVariants = deepMergeObjects(result, variantsResult ?? {})
111
-
112
- this.applyStyles(hash, convertUnistyles(resultWithVariants))
113
- })
114
-
115
- return hash
90
+ return { hash, existingHash: false }
116
91
  }
117
92
 
118
93
  existingCounter.add(value)
119
94
 
120
- return hash
95
+ return { hash, existingHash: true }
121
96
  }
122
97
 
123
- private applyStyles = (hash: string, styles: Record<string, any>) => {
98
+ applyStyles = (hash: string, styles: Record<string, any>) => {
124
99
  Object.entries(styles).forEach(([key, value]) => {
125
100
  if (!this.styleTag.sheet) {
126
101
  return
@@ -228,6 +203,10 @@ class UnistylesRegistryBuilder {
228
203
  if (existingStyles.size === 0) {
229
204
  const ruleIndex = Array.from(this.styleTag.sheet?.cssRules ?? []).findIndex(rule => rule.cssText.includes(`.${hash}`))
230
205
 
206
+ if (ruleIndex === -1) {
207
+ return
208
+ }
209
+
231
210
  this.styleTag.sheet?.deleteRule(ruleIndex)
232
211
  }
233
212
  }
@@ -54,6 +54,10 @@ class UnistylesRuntimeBuilder {
54
54
  return WebContentSizeCategory.Unspecified
55
55
  }
56
56
 
57
+ get breakpoints() {
58
+ return UnistylesState.breakpoints ?? {}
59
+ }
60
+
57
61
  get breakpoint() {
58
62
  return UnistylesState.breakpoint
59
63
  }
@@ -1,6 +1,8 @@
1
1
  import type { UnistylesValues } from '../types'
2
+ import { convertUnistyles } from './convert'
3
+ import { UnistylesListener } from './listener'
2
4
  import { UnistylesRegistry } from './registry'
3
- import { createDoubleMap, deepMergeObjects, equal, extractSecrets, extractUnistyleDependencies, isInDocument } from './utils'
5
+ import { deepMergeObjects, equal, extractSecrets, extractUnistyleDependencies, isInDocument } from './utils'
4
6
  import { getVariants } from './variants'
5
7
 
6
8
  type Style = UnistylesValues | ((...args: Array<any>) => UnistylesValues)
@@ -14,10 +16,13 @@ class UnistylesShadowRegistryBuilder {
14
16
  dispose = () => {}
15
17
  // END MOCKS
16
18
 
17
- private resultsMap = createDoubleMap<HTMLElement, string, UnistylesValues>()
18
- private classNamesMap = createDoubleMap<HTMLElement, string, Array<string>>()
19
+ private resultsMap = new Map<HTMLElement, UnistylesValues>()
20
+ private hashMap = new Map<HTMLElement, string>()
21
+ private classNamesMap = new Map<HTMLElement, Array<string>>()
22
+ private timeoutMap = new Map<HTMLElement, NodeJS.Timeout>()
23
+ private queuedResultMap = new Map<HTMLElement, Record<string, any>>()
19
24
 
20
- add = (ref: any, _style?: Style | Array<Style>, _variants?: Record<string, any>, _args?: Array<any>) => {
25
+ add = (ref: any, _style?: Style | Array<Style>, _variants?: Record<string, any>, _args?: Array<any>) => new Promise<Array<string>>(resolve => {
21
26
  // Style is not provided
22
27
  if (!_style) {
23
28
  return
@@ -39,15 +44,15 @@ class UnistylesShadowRegistryBuilder {
39
44
  if (ref === null) {
40
45
  const secrets = extractSecrets(_style)
41
46
 
42
- secrets.forEach(({ __uni__refs, __uni__key }) => {
47
+ secrets.forEach(({ __uni__refs }) => {
43
48
  __uni__refs.forEach(ref => {
44
49
  if (isInDocument(ref)) {
45
50
  return
46
51
  }
47
52
 
48
- const oldResult = this.resultsMap.get(ref, __uni__key)
49
- this.resultsMap.delete(ref, __uni__key)
50
- this.classNamesMap.delete(ref, __uni__key)
53
+ const oldResult = this.resultsMap.get(ref)
54
+ this.resultsMap.delete(ref)
55
+ this.classNamesMap.delete(ref)
51
56
 
52
57
  if (oldResult) {
53
58
  UnistylesRegistry.remove(oldResult)
@@ -74,46 +79,80 @@ class UnistylesShadowRegistryBuilder {
74
79
  : style
75
80
  const { variantsResult } = Object.fromEntries(getVariants({ variantsResult: result }, variants))
76
81
  const resultWithVariants = deepMergeObjects(result, variantsResult ?? {})
77
- const oldResult = this.resultsMap.get(ref, __uni__key)
78
-
79
- // If results are the same do nothing
80
- if (equal(oldResult, resultWithVariants)) {
81
- return
82
- }
83
-
84
- const oldClassNames = this.classNamesMap.get(ref, __uni__key)
85
-
86
- // Remove old styles
87
- if (oldResult) {
88
- UnistylesRegistry.remove(oldResult)
89
- }
90
-
91
- // Remove old classnames from the ref
92
- oldClassNames?.forEach(className => ref.classList.remove(className))
93
- this.resultsMap.set(ref, __uni__key, resultWithVariants)
94
-
95
- const className = UnistylesRegistry.add({
96
- key: __uni__key,
97
- args,
98
- stylesheet: __uni__stylesheet,
99
- value: resultWithVariants,
100
- variants
82
+
83
+ // Get stored result from queue
84
+ const storedResult = this.queuedResultMap.get(ref) ?? {}
85
+ // Merge stored result with new result
86
+ const newResult = deepMergeObjects(storedResult, resultWithVariants)
87
+ const timeout = this.timeoutMap.get(ref)
88
+
89
+ // Add callback to the queue and remove old one
90
+ this.queuedResultMap.set(ref, newResult)
91
+ clearTimeout(timeout)
92
+ this.timeoutMap.set(ref, setTimeout(() => {
93
+ const oldResult = this.resultsMap.get(ref)
94
+
95
+ // If results are the same do nothing
96
+ if (equal(oldResult, newResult)) {
97
+ return
98
+ }
99
+
100
+ const oldClassNames = this.classNamesMap.get(ref)
101
+
102
+ // Remove old styles
103
+ if (oldResult) {
104
+ UnistylesRegistry.remove(oldResult)
105
+ }
106
+
107
+ // Remove old classnames from the ref
108
+ oldClassNames?.forEach(className => ref.classList.remove(className))
109
+ this.resultsMap.set(ref, newResult)
110
+
111
+ const { hash, existingHash } = UnistylesRegistry.add(newResult)
112
+ const injectedClassNames: Array<string> = newResult?._web?._classNames ?? []
113
+ const newClassNames = injectedClassNames.concat(hash)
114
+ const dependencies = extractUnistyleDependencies(newResult)
115
+
116
+ if (typeof __uni__stylesheet === 'function') {
117
+ // Add dependencies from dynamic styles to stylesheet
118
+ UnistylesRegistry.addDependenciesToStylesheet(__uni__stylesheet, dependencies)
119
+ }
120
+
121
+ __uni__refs.add(ref)
122
+ this.classNamesMap.set(ref, newClassNames)
123
+ // Add new classnames to the ref
124
+ ref.classList.add(...newClassNames)
125
+ resolve(newClassNames)
126
+
127
+ // If it is new hash add it to the map to use for the listener
128
+ if (!existingHash) {
129
+ this.hashMap.set(ref, hash)
130
+ }
131
+ }, 0))
132
+
133
+ // Listen for theme / runtime changes
134
+ const dispose = UnistylesListener.addListeners(extractUnistyleDependencies(newResult), () => {
135
+ const hash = this.hashMap.get(ref)
136
+
137
+ // Dispose listener if there is no hash
138
+ if (!hash) {
139
+ dispose()
140
+
141
+ return
142
+ }
143
+
144
+ const newComputedStyleSheet = UnistylesRegistry.getComputedStylesheet(__uni__stylesheet)
145
+ const newValue = newComputedStyleSheet[__uni__key]!
146
+ const result = typeof newValue === 'function'
147
+ ? newValue(...args)
148
+ : newValue
149
+ const { variantsResult } = Object.fromEntries(getVariants({ variantsResult: result }, variants))
150
+ const resultWithVariants = deepMergeObjects(result, variantsResult ?? {})
151
+
152
+ UnistylesRegistry.applyStyles(hash, convertUnistyles(resultWithVariants))
101
153
  })
102
- const injectedClassNames: Array<string> = resultWithVariants?._web?._classNames ?? []
103
- const newClassNames = injectedClassNames.concat(className)
104
- const dependencies = extractUnistyleDependencies(resultWithVariants)
105
-
106
- if (typeof __uni__stylesheet === 'function') {
107
- // Add dependencies from dynamic styles to stylesheet
108
- UnistylesRegistry.addDependenciesToStylesheet(__uni__stylesheet, dependencies)
109
- }
110
-
111
- __uni__refs.add(ref)
112
- this.classNamesMap.set(ref, __uni__key, newClassNames)
113
- // Add new classnames to the ref
114
- ref.classList.add(...newClassNames)
115
154
  })
116
- }
155
+ })
117
156
 
118
157
  remove = () => {}
119
158
  }
@@ -68,40 +68,4 @@ export const generateHash = (value: any) => {
68
68
  return `unistyles-${(hasher >>> 0).toString(36)}`
69
69
  }
70
70
 
71
- export const createDoubleMap = <TKey, TSecondKey, TValue>() => {
72
- const map = new Map<TKey, Map<TSecondKey, TValue>>()
73
-
74
- return {
75
- get: (key: TKey, secondKey: TSecondKey) => {
76
- const mapForKey = map.get(key)
77
-
78
- if (!mapForKey) {
79
- return undefined
80
- }
81
-
82
- return mapForKey.get(secondKey)
83
- },
84
- set: (key: TKey, secondKey: TSecondKey, value: TValue) => {
85
- const mapForKey = map.get(key) ?? new Map<TSecondKey, TValue>()
86
-
87
- map.set(key, mapForKey)
88
- mapForKey.set(secondKey, value)
89
- },
90
- delete: (key: TKey, secondKey: TSecondKey) => {
91
- const mapForKey = map.get(key)
92
-
93
- if (!mapForKey) {
94
- return
95
- }
96
-
97
- mapForKey.delete(secondKey)
98
- },
99
- forEach: (callback: (key: TKey, secondKey: TSecondKey, value: TValue) => void) => {
100
- map.forEach((mapForKey, key) => {
101
- mapForKey.forEach((value, secondKey) => {
102
- callback(key, secondKey, value)
103
- })
104
- })
105
- }
106
- }
107
- }
71
+ export const hyphenate = (propertyName: string) => propertyName.replace(/[A-Z]/g, (m: string) => `-${m.toLowerCase()}`)
@@ -98,7 +98,11 @@ export const getMediaQuery = (query: string) => {
98
98
  }
99
99
 
100
100
  export const extractUnistyleDependencies = (value: any) => {
101
+ if (!value) {
102
+ return []
103
+ }
104
+
101
105
  const dependencies: Array<UnistyleDependency> = keyInObject(value, 'uni__dependencies') ? value.uni__dependencies : []
102
106
 
103
- return dependencies
107
+ return Array.isArray(dependencies) ? dependencies : []
104
108
  }
@@ -1,105 +0,0 @@
1
- #include "helpers.h"
2
- #include "UnistylesRuntime.h"
3
-
4
- Dimensions jobjectToDimensions(JNIEnv *env, jobject dimensionObj) {
5
- jclass dimensionClass = env->FindClass("com/unistyles/Dimensions");
6
- jfieldID widthFieldID = env->GetFieldID(dimensionClass, "width", "I");
7
- jfieldID heightFieldID = env->GetFieldID(dimensionClass, "height", "I");
8
-
9
- int width = env->GetIntField(dimensionObj, widthFieldID);
10
- int height = env->GetIntField(dimensionObj, heightFieldID);
11
-
12
- env->DeleteLocalRef(dimensionClass);
13
-
14
- return Dimensions{width, height};
15
- }
16
-
17
- Screen jobjectToScreen(JNIEnv *env, jobject screenObj) {
18
- jclass screenClass = env->FindClass("com/unistyles/Screen");
19
- jfieldID widthFieldID = env->GetFieldID(screenClass, "width", "I");
20
- jfieldID heightFieldID = env->GetFieldID(screenClass, "height", "I");
21
- jfieldID pixelRatioFieldID = env->GetFieldID(screenClass, "pixelRatio", "F");
22
- jfieldID scaleFieldID = env->GetFieldID(screenClass, "fontScale", "F");
23
-
24
- int width = env->GetIntField(screenObj, widthFieldID);
25
- int height = env->GetIntField(screenObj, heightFieldID);
26
- float pixelRatio = env->GetFloatField(screenObj, pixelRatioFieldID);
27
- float fontScale = env->GetFloatField(screenObj, scaleFieldID);
28
-
29
- env->DeleteLocalRef(screenClass);
30
-
31
- return Screen{width, height, pixelRatio, fontScale};
32
- }
33
-
34
- Insets jobjectToInsets(JNIEnv *env, jobject insetsObj) {
35
- jclass insetsClass = env->FindClass("com/unistyles/Insets");
36
- jfieldID leftFieldID = env->GetFieldID(insetsClass, "left", "I");
37
- jfieldID topFieldID = env->GetFieldID(insetsClass, "top", "I");
38
- jfieldID rightFieldID = env->GetFieldID(insetsClass, "right", "I");
39
- jfieldID bottomFieldID = env->GetFieldID(insetsClass, "bottom", "I");
40
-
41
- int left = env->GetIntField(insetsObj, leftFieldID);
42
- int top = env->GetIntField(insetsObj, topFieldID);
43
- int right = env->GetIntField(insetsObj, rightFieldID);
44
- int bottom = env->GetIntField(insetsObj, bottomFieldID);
45
-
46
- env->DeleteLocalRef(insetsClass);
47
-
48
- return Insets{top, bottom, left, right};
49
- }
50
-
51
- void JNI_callPlatformWithColor(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig, std::string param, float alpha) {
52
- jclass cls = env->GetObjectClass(unistylesModule);
53
- jfieldID platformFieldId = env->GetFieldID(cls, "platform", "Lcom/unistyles/Platform;");
54
- jobject platformInstance = env->GetObjectField(unistylesModule, platformFieldId);
55
- jclass platformClass = env->GetObjectClass(platformInstance);
56
- jstring strParam = env->NewStringUTF(param.c_str());
57
- jmethodID methodId = env->GetMethodID(platformClass, name.c_str(), sig.c_str());
58
-
59
- env->CallVoidMethod(platformInstance, methodId, strParam, static_cast<jfloat>(alpha));
60
-
61
- env->DeleteLocalRef(cls);
62
- env->DeleteLocalRef(platformInstance);
63
- env->DeleteLocalRef(platformClass);
64
- env->DeleteLocalRef(strParam);
65
- }
66
-
67
- void JNI_callPlatformWithBool(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig, bool param) {
68
- jclass cls = env->GetObjectClass(unistylesModule);
69
- jfieldID platformFieldId = env->GetFieldID(cls, "platform", "Lcom/unistyles/Platform;");
70
- jobject platformInstance = env->GetObjectField(unistylesModule, platformFieldId);
71
- jclass platformClass = env->GetObjectClass(platformInstance);
72
- jmethodID methodId = env->GetMethodID(platformClass, name.c_str(), sig.c_str());
73
-
74
- env->CallVoidMethod(platformInstance, methodId, param);
75
- env->DeleteLocalRef(cls);
76
- env->DeleteLocalRef(platformInstance);
77
- env->DeleteLocalRef(platformClass);
78
- }
79
-
80
- jobject JNI_callPlatform(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig) {
81
- jclass cls = env->GetObjectClass(unistylesModule);
82
- jfieldID platformFieldId = env->GetFieldID(cls, "platform", "Lcom/unistyles/Platform;");
83
- jobject platformInstance = env->GetObjectField(unistylesModule, platformFieldId);
84
- jclass platformClass = env->GetObjectClass(platformInstance);
85
- jmethodID methodId = env->GetMethodID(platformClass, name.c_str(), sig.c_str());
86
- jobject result = env->CallObjectMethod(platformInstance, methodId);
87
-
88
- env->DeleteLocalRef(cls);
89
- env->DeleteLocalRef(platformInstance);
90
- env->DeleteLocalRef(platformClass);
91
-
92
- return result;
93
- }
94
-
95
- void throwKotlinException(
96
- JNIEnv *env,
97
- const char *message
98
- ) {
99
- jclass runtimeExceptionClass = env->FindClass("java/lang/RuntimeException");
100
-
101
- if (runtimeExceptionClass != nullptr) {
102
- env->ThrowNew(runtimeExceptionClass, message);
103
- env->DeleteLocalRef(runtimeExceptionClass);
104
- }
105
- }
@@ -1,16 +0,0 @@
1
- #pragma once
2
-
3
- #include <jni.h>
4
- #include <string>
5
- #include <map>
6
- #include <UnistylesRuntime.h>
7
-
8
- Dimensions jobjectToDimensions(JNIEnv *env, jobject dimensionObj);
9
- Screen jobjectToScreen(JNIEnv *env, jobject screenObj);
10
- Insets jobjectToInsets(JNIEnv *env, jobject insetsObj);
11
-
12
- void JNI_callPlatformWithColor(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig, std::string param, float alpha);
13
- jobject JNI_callPlatform(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig);
14
- void JNI_callPlatformWithBool(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig, bool param);
15
-
16
- void throwKotlinException(JNIEnv *env, const char *message);