react-native-unistyles 3.0.0-alpha.41 → 3.0.0-alpha.43

Sign up to get free protection for your applications and to get access to all the features.
Files changed (236) hide show
  1. package/README.md +7 -1
  2. package/cxx/common/Constants.h +0 -1
  3. package/cxx/core/UnistylesRegistry.cpp +10 -4
  4. package/cxx/core/UnistylesRegistry.h +1 -1
  5. package/cxx/hybridObjects/HybridShadowRegistry.cpp +2 -2
  6. package/cxx/parser/Parser.cpp +7 -22
  7. package/cxx/parser/Parser.h +0 -1
  8. package/lib/commonjs/components/Display.js +2 -2
  9. package/lib/commonjs/components/Display.js.map +1 -1
  10. package/lib/commonjs/components/Hide.js +2 -2
  11. package/lib/commonjs/components/Hide.js.map +1 -1
  12. package/lib/commonjs/components/Pressable.js +82 -0
  13. package/lib/commonjs/components/Pressable.js.map +1 -0
  14. package/lib/commonjs/components/Pressable.web.js +97 -0
  15. package/lib/commonjs/components/Pressable.web.js.map +1 -0
  16. package/lib/commonjs/components/index.js +7 -0
  17. package/lib/commonjs/components/index.js.map +1 -1
  18. package/lib/commonjs/core/getBoundArgs.js +18 -0
  19. package/lib/commonjs/core/getBoundArgs.js.map +1 -0
  20. package/lib/commonjs/core/getId.js +9 -0
  21. package/lib/commonjs/core/getId.js.map +1 -0
  22. package/lib/commonjs/core/index.js +14 -0
  23. package/lib/commonjs/core/index.js.map +1 -1
  24. package/lib/commonjs/hooks/index.js +13 -0
  25. package/lib/commonjs/hooks/index.js.map +1 -0
  26. package/lib/commonjs/hooks/useMedia.js.map +1 -0
  27. package/lib/commonjs/hooks/useMedia.web.js.map +1 -0
  28. package/lib/commonjs/index.js +8 -1
  29. package/lib/commonjs/index.js.map +1 -1
  30. package/lib/commonjs/mq.js +6 -6
  31. package/lib/commonjs/mq.js.map +1 -1
  32. package/lib/commonjs/specs/ShadowRegistry/index.js +3 -4
  33. package/lib/commonjs/specs/ShadowRegistry/index.js.map +1 -1
  34. package/lib/commonjs/specs/StyleSheet/index.js.map +1 -1
  35. package/lib/commonjs/specs/TurboUnistyles/NativeTurboUnistyles.js +1 -2
  36. package/lib/commonjs/specs/TurboUnistyles/NativeTurboUnistyles.js.map +1 -1
  37. package/lib/commonjs/specs/index.web.js +0 -7
  38. package/lib/commonjs/specs/index.web.js.map +1 -1
  39. package/lib/commonjs/utils.js +1 -1
  40. package/lib/commonjs/utils.js.map +1 -1
  41. package/lib/commonjs/web/convert/types.js.map +1 -1
  42. package/lib/commonjs/web/convert/utils.js +1 -1
  43. package/lib/commonjs/web/convert/utils.js.map +1 -1
  44. package/lib/commonjs/web/create.js +10 -2
  45. package/lib/commonjs/web/create.js.map +1 -1
  46. package/lib/commonjs/web/index.js +7 -5
  47. package/lib/commonjs/web/index.js.map +1 -1
  48. package/lib/commonjs/web/listener.js.map +1 -1
  49. package/lib/commonjs/web/runtime.js +7 -7
  50. package/lib/commonjs/web/runtime.js.map +1 -1
  51. package/lib/commonjs/web/shadowRegistry.js +1 -1
  52. package/lib/commonjs/web/shadowRegistry.js.map +1 -1
  53. package/lib/commonjs/web/state.js +23 -16
  54. package/lib/commonjs/web/state.js.map +1 -1
  55. package/lib/commonjs/web/utils/common.js +3 -3
  56. package/lib/commonjs/web/utils/common.js.map +1 -1
  57. package/lib/commonjs/web/utils/unistyle.js +2 -4
  58. package/lib/commonjs/web/utils/unistyle.js.map +1 -1
  59. package/lib/commonjs/web/{variants/getVariants.js → variants.js} +3 -3
  60. package/lib/commonjs/web/variants.js.map +1 -0
  61. package/lib/module/components/Display.js +1 -1
  62. package/lib/module/components/Display.js.map +1 -1
  63. package/lib/module/components/Hide.js +1 -1
  64. package/lib/module/components/Hide.js.map +1 -1
  65. package/lib/module/components/Pressable.js +76 -0
  66. package/lib/module/components/Pressable.js.map +1 -0
  67. package/lib/module/components/Pressable.web.js +91 -0
  68. package/lib/module/components/Pressable.web.js.map +1 -0
  69. package/lib/module/components/index.js +1 -0
  70. package/lib/module/components/index.js.map +1 -1
  71. package/lib/module/core/getBoundArgs.js +13 -0
  72. package/lib/module/core/getBoundArgs.js.map +1 -0
  73. package/lib/module/core/getId.js +4 -0
  74. package/lib/module/core/getId.js.map +1 -0
  75. package/lib/module/core/index.js +2 -0
  76. package/lib/module/core/index.js.map +1 -1
  77. package/lib/module/hooks/index.js +4 -0
  78. package/lib/module/hooks/index.js.map +1 -0
  79. package/lib/module/hooks/useMedia.js.map +1 -0
  80. package/lib/module/hooks/useMedia.web.js.map +1 -0
  81. package/lib/module/index.js +1 -1
  82. package/lib/module/index.js.map +1 -1
  83. package/lib/module/mq.js +6 -6
  84. package/lib/module/mq.js.map +1 -1
  85. package/lib/module/specs/ShadowRegistry/index.js +3 -4
  86. package/lib/module/specs/ShadowRegistry/index.js.map +1 -1
  87. package/lib/module/specs/StyleSheet/index.js.map +1 -1
  88. package/lib/module/specs/TurboUnistyles/NativeTurboUnistyles.js +1 -2
  89. package/lib/module/specs/TurboUnistyles/NativeTurboUnistyles.js.map +1 -1
  90. package/lib/module/specs/index.web.js +0 -1
  91. package/lib/module/specs/index.web.js.map +1 -1
  92. package/lib/module/utils.js +1 -1
  93. package/lib/module/utils.js.map +1 -1
  94. package/lib/module/web/convert/types.js.map +1 -1
  95. package/lib/module/web/convert/utils.js +1 -1
  96. package/lib/module/web/convert/utils.js.map +1 -1
  97. package/lib/module/web/create.js +12 -4
  98. package/lib/module/web/create.js.map +1 -1
  99. package/lib/module/web/index.js +7 -3
  100. package/lib/module/web/index.js.map +1 -1
  101. package/lib/module/web/listener.js.map +1 -1
  102. package/lib/module/web/runtime.js +8 -8
  103. package/lib/module/web/runtime.js.map +1 -1
  104. package/lib/module/web/shadowRegistry.js +1 -1
  105. package/lib/module/web/shadowRegistry.js.map +1 -1
  106. package/lib/module/web/state.js +24 -17
  107. package/lib/module/web/state.js.map +1 -1
  108. package/lib/module/web/utils/common.js +1 -1
  109. package/lib/module/web/utils/common.js.map +1 -1
  110. package/lib/module/web/utils/unistyle.js +1 -2
  111. package/lib/module/web/utils/unistyle.js.map +1 -1
  112. package/lib/module/web/{variants/getVariants.js → variants.js} +3 -3
  113. package/lib/module/web/variants.js.map +1 -0
  114. package/lib/typescript/src/components/Pressable.d.ts +7 -0
  115. package/lib/typescript/src/components/Pressable.d.ts.map +1 -0
  116. package/lib/typescript/src/components/Pressable.web.d.ts +13 -0
  117. package/lib/typescript/src/components/Pressable.web.d.ts.map +1 -0
  118. package/lib/typescript/src/components/index.d.ts +1 -0
  119. package/lib/typescript/src/components/index.d.ts.map +1 -1
  120. package/lib/typescript/src/core/getBoundArgs.d.ts +2 -0
  121. package/lib/typescript/src/core/getBoundArgs.d.ts.map +1 -0
  122. package/lib/typescript/src/core/getId.d.ts +2 -0
  123. package/lib/typescript/src/core/getId.d.ts.map +1 -0
  124. package/lib/typescript/src/core/index.d.ts +2 -0
  125. package/lib/typescript/src/core/index.d.ts.map +1 -1
  126. package/lib/typescript/src/hooks/index.d.ts +2 -0
  127. package/lib/typescript/src/hooks/index.d.ts.map +1 -0
  128. package/lib/typescript/src/hooks/useMedia.d.ts.map +1 -0
  129. package/lib/typescript/src/hooks/useMedia.web.d.ts.map +1 -0
  130. package/lib/typescript/src/index.d.ts +1 -1
  131. package/lib/typescript/src/index.d.ts.map +1 -1
  132. package/lib/typescript/src/specs/NativePlatform/NativePlatform.nitro.d.ts +1 -1
  133. package/lib/typescript/src/specs/NativePlatform/NativePlatform.nitro.d.ts.map +1 -1
  134. package/lib/typescript/src/specs/ShadowRegistry/index.d.ts +2 -2
  135. package/lib/typescript/src/specs/ShadowRegistry/index.d.ts.map +1 -1
  136. package/lib/typescript/src/specs/ShadowRegistry/types.d.ts +1 -0
  137. package/lib/typescript/src/specs/ShadowRegistry/types.d.ts.map +1 -1
  138. package/lib/typescript/src/specs/StyleSheet/UnistylesStyleSheet.nitro.d.ts +1 -1
  139. package/lib/typescript/src/specs/StyleSheet/UnistylesStyleSheet.nitro.d.ts.map +1 -1
  140. package/lib/typescript/src/specs/StyleSheet/index.d.ts +3 -2
  141. package/lib/typescript/src/specs/StyleSheet/index.d.ts.map +1 -1
  142. package/lib/typescript/src/specs/UnistylesRuntime/index.d.ts +1 -1
  143. package/lib/typescript/src/specs/UnistylesRuntime/index.d.ts.map +1 -1
  144. package/lib/typescript/src/specs/index.web.d.ts +0 -2
  145. package/lib/typescript/src/specs/index.web.d.ts.map +1 -1
  146. package/lib/typescript/src/types/common.d.ts +1 -0
  147. package/lib/typescript/src/types/common.d.ts.map +1 -1
  148. package/lib/typescript/src/types/index.d.ts +1 -1
  149. package/lib/typescript/src/types/index.d.ts.map +1 -1
  150. package/lib/typescript/src/web/convert/types.d.ts +1 -1
  151. package/lib/typescript/src/web/convert/types.d.ts.map +1 -1
  152. package/lib/typescript/src/web/create.d.ts +1 -1
  153. package/lib/typescript/src/web/create.d.ts.map +1 -1
  154. package/lib/typescript/src/web/index.d.ts +8 -2
  155. package/lib/typescript/src/web/index.d.ts.map +1 -1
  156. package/lib/typescript/src/web/listener.d.ts.map +1 -1
  157. package/lib/typescript/src/web/runtime.d.ts.map +1 -1
  158. package/lib/typescript/src/web/state.d.ts.map +1 -1
  159. package/lib/typescript/src/web/utils/common.d.ts +1 -1
  160. package/lib/typescript/src/web/utils/common.d.ts.map +1 -1
  161. package/lib/typescript/src/web/utils/unistyle.d.ts +0 -1
  162. package/lib/typescript/src/web/utils/unistyle.d.ts.map +1 -1
  163. package/lib/typescript/src/web/{variants/getVariants.d.ts → variants.d.ts} +2 -2
  164. package/lib/typescript/src/web/variants.d.ts.map +1 -0
  165. package/package.json +12 -16
  166. package/plugin/common.js +1 -4
  167. package/plugin/import.js +29 -3
  168. package/plugin/index.js +18 -8
  169. package/plugin/ref.js +15 -75
  170. package/plugin/style.js +251 -88
  171. package/src/components/Display.tsx +1 -1
  172. package/src/components/Hide.tsx +1 -1
  173. package/src/components/Pressable.tsx +101 -0
  174. package/src/components/Pressable.web.tsx +103 -0
  175. package/src/components/index.ts +1 -0
  176. package/src/core/getBoundArgs.ts +15 -0
  177. package/src/core/getId.ts +1 -0
  178. package/src/core/index.ts +2 -0
  179. package/src/hooks/index.ts +1 -0
  180. package/src/index.ts +1 -1
  181. package/src/mq.ts +6 -6
  182. package/src/specs/NativePlatform/NativePlatform.nitro.ts +1 -1
  183. package/src/specs/ShadowRegistry/index.ts +5 -6
  184. package/src/specs/ShadowRegistry/types.ts +2 -1
  185. package/src/specs/StyleSheet/UnistylesStyleSheet.nitro.ts +1 -1
  186. package/src/specs/StyleSheet/index.ts +3 -2
  187. package/src/specs/TurboUnistyles/NativeTurboUnistyles.ts +1 -2
  188. package/src/specs/UnistylesRuntime/UnistylesRuntime.nitro.ts +1 -1
  189. package/src/specs/UnistylesRuntime/index.ts +1 -1
  190. package/src/specs/index.web.ts +0 -4
  191. package/src/types/common.ts +1 -0
  192. package/src/types/index.ts +1 -1
  193. package/src/utils.ts +1 -1
  194. package/src/web/convert/types.ts +1 -1
  195. package/src/web/convert/utils.ts +2 -2
  196. package/src/web/create.ts +13 -4
  197. package/src/web/index.ts +7 -3
  198. package/src/web/listener.ts +2 -0
  199. package/src/web/registry.ts +1 -1
  200. package/src/web/runtime.ts +9 -9
  201. package/src/web/shadowRegistry.ts +3 -3
  202. package/src/web/state.ts +36 -17
  203. package/src/web/utils/common.ts +1 -1
  204. package/src/web/utils/unistyle.ts +3 -9
  205. package/src/web/{variants/getVariants.ts → variants.ts} +3 -3
  206. package/lib/commonjs/components/useMedia.js.map +0 -1
  207. package/lib/commonjs/components/useMedia.web.js.map +0 -1
  208. package/lib/commonjs/web/variants/getVariants.js.map +0 -1
  209. package/lib/commonjs/web/variants/index.js +0 -28
  210. package/lib/commonjs/web/variants/index.js.map +0 -1
  211. package/lib/commonjs/web/variants/useVariants.js +0 -59
  212. package/lib/commonjs/web/variants/useVariants.js.map +0 -1
  213. package/lib/module/components/useMedia.js.map +0 -1
  214. package/lib/module/components/useMedia.web.js.map +0 -1
  215. package/lib/module/web/variants/getVariants.js.map +0 -1
  216. package/lib/module/web/variants/index.js +0 -5
  217. package/lib/module/web/variants/index.js.map +0 -1
  218. package/lib/module/web/variants/useVariants.js +0 -54
  219. package/lib/module/web/variants/useVariants.js.map +0 -1
  220. package/lib/typescript/src/components/useMedia.d.ts.map +0 -1
  221. package/lib/typescript/src/components/useMedia.web.d.ts.map +0 -1
  222. package/lib/typescript/src/web/variants/getVariants.d.ts.map +0 -1
  223. package/lib/typescript/src/web/variants/index.d.ts +0 -3
  224. package/lib/typescript/src/web/variants/index.d.ts.map +0 -1
  225. package/lib/typescript/src/web/variants/useVariants.d.ts +0 -3
  226. package/lib/typescript/src/web/variants/useVariants.d.ts.map +0 -1
  227. package/src/web/variants/index.ts +0 -2
  228. package/src/web/variants/useVariants.ts +0 -65
  229. /package/lib/commonjs/{components → hooks}/useMedia.js +0 -0
  230. /package/lib/commonjs/{components → hooks}/useMedia.web.js +0 -0
  231. /package/lib/module/{components → hooks}/useMedia.js +0 -0
  232. /package/lib/module/{components → hooks}/useMedia.web.js +0 -0
  233. /package/lib/typescript/src/{components → hooks}/useMedia.d.ts +0 -0
  234. /package/lib/typescript/src/{components → hooks}/useMedia.web.d.ts +0 -0
  235. /package/src/{components → hooks}/useMedia.ts +0 -0
  236. /package/src/{components → hooks}/useMedia.web.ts +0 -0
package/plugin/style.js CHANGED
@@ -1,6 +1,3 @@
1
- const { PRESSABLE_STATE_NAME } = require('./common')
2
- const { generateUniqueId } = require('./ref')
3
-
4
1
  function getStyleMetadata(t, node, dynamicFunction = null) {
5
2
  // {styles.container}
6
3
  if (t.isMemberExpression(node)) {
@@ -13,7 +10,8 @@ function getStyleMetadata(t, node, dynamicFunction = null) {
13
10
  members: members.filter(Boolean),
14
11
  inlineStyle: undefined,
15
12
  dynamicFunction,
16
- conditionalExpression: undefined
13
+ conditionalExpression: undefined,
14
+ logicalExpression: undefined
17
15
  }
18
16
  ]
19
17
  }
@@ -39,7 +37,8 @@ function getStyleMetadata(t, node, dynamicFunction = null) {
39
37
  members: [],
40
38
  inlineStyle: t.objectExpression([prop]),
41
39
  dynamicFunction: undefined,
42
- conditionalExpression: undefined
40
+ conditionalExpression: undefined,
41
+ logicalExpression: undefined
43
42
  }]
44
43
  }
45
44
 
@@ -58,7 +57,8 @@ function getStyleMetadata(t, node, dynamicFunction = null) {
58
57
  members: [node.name],
59
58
  inlineStyle: undefined,
60
59
  dynamicFunction: undefined,
61
- conditionalExpression: undefined
60
+ conditionalExpression: undefined,
61
+ logicalExpression: undefined
62
62
  }]
63
63
  }
64
64
 
@@ -67,15 +67,26 @@ function getStyleMetadata(t, node, dynamicFunction = null) {
67
67
  members: [],
68
68
  inlineStyle: undefined,
69
69
  dynamicFunction: undefined,
70
- conditionalExpression: node
70
+ conditionalExpression: node,
71
+ logicalExpression: undefined
71
72
  }]
72
73
  }
73
74
 
74
- // pressable
75
75
  if (t.isArrowFunctionExpression(node)) {
76
76
  return getStyleMetadata(t, node.body, node)
77
77
  }
78
78
 
79
+ // {condition && styles.container}
80
+ if (t.isLogicalExpression(node)) {
81
+ return [{
82
+ members: [],
83
+ inlineStyle: undefined,
84
+ dynamicFunction: undefined,
85
+ conditionalExpression: undefined,
86
+ logicalExpression: node
87
+ }]
88
+ }
89
+
79
90
  return []
80
91
  }
81
92
 
@@ -90,12 +101,6 @@ function getStyleAttribute(t, path) {
90
101
  function styleAttributeToArray(t, path) {
91
102
  const styleAttribute = getStyleAttribute(t, path)
92
103
 
93
- // special case for pressable
94
- // {state => styles.pressable(state)}
95
- if (t.isArrowFunctionExpression(styleAttribute.value.expression)) {
96
- return
97
- }
98
-
99
104
  // {{...style.container, ...style.container}}
100
105
  if (t.isObjectExpression(styleAttribute.value.expression)) {
101
106
  const properties = styleAttribute.value.expression.properties
@@ -127,112 +132,270 @@ function styleAttributeToArray(t, path) {
127
132
  styleAttribute.value.expression = t.arrayExpression([styleAttribute.value.expression])
128
133
  }
129
134
 
130
- function handlePressable(t, path, styleAttr, metadata) {
131
- const styleExpression = styleAttr.value.expression
135
+ function metadataToRawStyle(t, metadata) {
136
+ const expressions = []
132
137
 
133
- // {style.pressable}
134
- // the worst case, we don't know if user rely on state
135
- if (t.isMemberExpression(styleExpression)) {
136
- const members = metadata.at(0).members
138
+ metadata.forEach(meta => {
139
+ if (meta.inlineStyle) {
140
+ return meta.inlineStyle.properties.forEach(prop => {
141
+ if (t.isObjectProperty(prop)) {
142
+ expressions.push(t.objectExpression([prop]))
143
+ }
144
+ })
145
+ }
137
146
 
138
- if (members.length === 0) {
139
- return
147
+ if (meta.members.length > 0) {
148
+ return expressions.push(t.memberExpression(...meta.members.map(member => t.identifier(member))))
149
+ }
150
+
151
+ if (meta.logicalExpression) {
152
+ if (t.isIdentifier(meta.logicalExpression.left)) {
153
+ if (t.isMemberExpression(meta.logicalExpression.right)) {
154
+ return expressions.push(meta.logicalExpression.right)
155
+ }
156
+
157
+ expressions.push(meta.logicalExpression.right.callee)
158
+ }
140
159
  }
160
+ })
141
161
 
142
- const stylePath = members.slice(1).reduce(
162
+ return t.jsxAttribute(
163
+ t.jsxIdentifier('rawStyle'),
164
+ t.jsxExpressionContainer(t.arrayExpression([
165
+ ...expressions
166
+ ]))
167
+ )
168
+ }
169
+
170
+ function wrapInGetBoundArgs(t, toWrap, extraArgs) {
171
+ const expression = t.callExpression(
172
+ t.identifier('getBoundArgs'),
173
+ [toWrap]
174
+ )
175
+
176
+ return t.callExpression(
177
+ t.memberExpression(expression, t.identifier('bind')),
178
+ [t.identifier('undefined'), ...extraArgs].filter(Boolean)
179
+ )
180
+ }
181
+
182
+ function handlePressableFromMemberExpression(t, path, metadata, wrapInArrowFunction) {
183
+ let expression = undefined
184
+
185
+ const members = metadata.at(0).members
186
+
187
+ if (members) {
188
+ expression = members.slice(1).reduce(
143
189
  (acc, property) => t.memberExpression(acc, t.identifier(property)),
144
- t.identifier(members[0])
145
- )
190
+ t.identifier(members[0]))
191
+ }
146
192
 
147
- const uniquePressableId = generateUniqueId()
148
-
149
- // state => typeof style.pressable === 'function' ? style.pressable(state) : style.pressable
150
- styleAttr.value.expression = t.arrowFunctionExpression(
151
- [t.identifier("state")],
152
- t.conditionalExpression(
153
- t.binaryExpression(
154
- "===",
155
- t.unaryExpression(
156
- "typeof",
157
- stylePath
158
- ),
159
- t.stringLiteral("function")
160
- ),
161
- t.callExpression(
162
- stylePath,
163
- [t.identifier("state"), t.objectExpression([
164
- t.objectProperty(
165
- t.identifier("__uni_pressable_id"),
166
- t.stringLiteral(uniquePressableId)
167
- )
168
- ])]
193
+ if (t.isMemberExpression(metadata.at(0))) {
194
+ expression = metadata.at(0)
195
+ }
196
+
197
+ if (!expression) {
198
+ return
199
+ }
200
+
201
+ const bindCall = wrapInGetBoundArgs(t , expression, wrapInArrowFunction ? [t.identifier("state")] : [])
202
+
203
+ if (!wrapInArrowFunction) {
204
+ return t.conditionalExpression(
205
+ t.binaryExpression(
206
+ "===",
207
+ t.unaryExpression(
208
+ "typeof",
209
+ expression
169
210
  ),
170
- stylePath
171
- )
211
+ t.stringLiteral("function")
212
+ ),
213
+ bindCall,
214
+ expression
172
215
  )
173
-
174
- return uniquePressableId
175
216
  }
176
217
 
177
- // {style.pressable(1, 2)}
178
- if (t.isCallExpression(styleExpression)) {
179
- // user already called dynamic function
180
- // there is no work to do
218
+ // state => typeof style.pressable === 'function'
219
+ // ? getBoundArgs(style.pressable).bind(undefined, state)
220
+ // : style.pressable
221
+ return t.arrowFunctionExpression(
222
+ [t.identifier("state")],
223
+ t.conditionalExpression(
224
+ t.binaryExpression(
225
+ "===",
226
+ t.unaryExpression(
227
+ "typeof",
228
+ expression
229
+ ),
230
+ t.stringLiteral("function")
231
+ ),
232
+ bindCall,
233
+ expression
234
+ )
235
+ )
236
+ }
237
+
238
+ function handlePressableArgs(t, path, styleExpression, metadata, parentWrapper, wrapper, index) {
239
+ if (t.isObjectExpression(wrapper)) {
181
240
  return
182
241
  }
183
242
 
184
- // {() => style.pressable(1, 2)}
185
- if (t.isArrowFunctionExpression(styleExpression) && styleExpression.params.length === 0) {
186
- // user doesn't care about the state
187
- // we can safely unwrap the function
188
- styleAttr.value.expression = styleExpression.body
243
+ if (t.isMemberExpression(wrapper)) {
244
+ parentWrapper.elements[index] = handlePressableFromMemberExpression(t, path, [metadata[index]])
189
245
 
190
246
  return
191
247
  }
192
248
 
193
- // {state => style.pressable(state, 1, 2)}
194
- if (t.isArrowFunctionExpression(styleExpression) && styleExpression.params.length > 0) {
195
- // already a function, we need to set state to false
196
- // and pass it to C++ as in background it will never be true
197
- const args = metadata.at(0).dynamicFunction
249
+ if (t.isLogicalExpression(wrapper)) {
250
+ if (t.isIdentifier(wrapper.left) && t.isMemberExpression(wrapper.right)) {
251
+ parentWrapper.elements[index].right = handlePressableFromMemberExpression(t, path, [parentWrapper.elements[index].right])
198
252
 
199
- if (!t.isCallExpression(args) || args.arguments.length === 0) {
200
253
  return
201
254
  }
202
255
 
203
- // get state local name
204
- const stateIdentifier = styleExpression.params[0]
256
+ return
257
+ }
205
258
 
206
- if (!stateIdentifier || !t.isIdentifier(stateIdentifier)) {
207
- return
259
+ if (t.isConditionalExpression(wrapper)) {
260
+ if (t.isMemberExpression(wrapper.alternate)) {
261
+ parentWrapper.elements[index].alternate = handlePressableFromMemberExpression(t, path, [parentWrapper.elements[index].alternate])
208
262
  }
209
263
 
210
- // replace state name with matching identifier
211
- args.arguments.map(arg => {
212
- if (t.isIdentifier(arg) && arg.name === stateIdentifier.name) {
213
- arg.name = PRESSABLE_STATE_NAME
214
- }
264
+ if (t.isMemberExpression(wrapper.consequent)) {
265
+ parentWrapper.elements[index].consequent = handlePressableFromMemberExpression(t, path, [parentWrapper.elements[index].consequent])
266
+ }
267
+
268
+ return
269
+ }
270
+
271
+ const pressableArgs = t.isCallExpression(wrapper)
272
+ ? wrapper.arguments
273
+ : wrapper.argument.arguments
274
+ const callee = t.isCallExpression(wrapper)
275
+ ? wrapper.callee
276
+ : wrapper.argument.callee
277
+
278
+ const getBoundArgsCall = t.callExpression(
279
+ t.identifier('getBoundArgs'),
280
+ [callee]
281
+ )
282
+ const bindCall = t.callExpression(
283
+ t.memberExpression(getBoundArgsCall, t.identifier('bind')),
284
+ [t.identifier('undefined'), ...pressableArgs]
285
+ )
286
+
287
+ if (t.isCallExpression(wrapper) && t.isArrayExpression(parentWrapper)) {
288
+ parentWrapper.elements[index] = bindCall
289
+
290
+ return
291
+ }
292
+
293
+ if (t.isCallExpression(wrapper)) {
294
+ styleExpression.body = bindCall
295
+ }
296
+ }
215
297
 
216
- if (t.isMemberExpression(arg) && arg.object.name === stateIdentifier.name) {
217
- arg.object.name = PRESSABLE_STATE_NAME
298
+ function handlePressable(t, path, styleAttr, metadata, state) {
299
+ // add variants
300
+ if (state.file.hasVariants) {
301
+ const variants = t.jsxAttribute(
302
+ t.jsxIdentifier('variants'),
303
+ t.jsxExpressionContainer(t.identifier('__uni__variants'))
304
+ )
305
+
306
+ path.node.openingElement.attributes.push(variants)
307
+ }
308
+
309
+ // add raw C++ style as prop to be bound
310
+ path.node.openingElement.attributes.push(metadataToRawStyle(t, metadata))
311
+
312
+ const styleExpression = styleAttr.value.expression
313
+
314
+ // {style.pressable}
315
+ if (t.isMemberExpression(styleExpression)) {
316
+ styleAttr.value.expression = handlePressableFromMemberExpression(t, path, metadata, true)
317
+
318
+ return
319
+ }
320
+
321
+ // {style.pressable(1, 2)}
322
+ if (t.isCallExpression(styleExpression)) {
323
+ // user already called dynamic function
324
+ const expression = t.callExpression(
325
+ t.identifier('getBoundArgs'),
326
+ [styleExpression.callee]
327
+ )
328
+ const bindCall = t.callExpression(
329
+ t.memberExpression(expression, t.identifier('bind')),
330
+ [t.identifier('undefined'), ...styleExpression.arguments]
331
+ )
332
+
333
+ path.node.openingElement.attributes = path.node.openingElement.attributes.map(attribute => {
334
+ if (attribute.name.name === "style") {
335
+ attribute.value.expression = t.arrowFunctionExpression([], bindCall)
218
336
  }
219
337
 
220
- return arg
338
+ return attribute
221
339
  })
222
340
 
223
- const uniquePressableId = generateUniqueId()
341
+ return
342
+ }
224
343
 
225
- args.arguments.push(t.objectExpression([
226
- t.objectProperty(
227
- t.identifier("__uni_pressable_id"),
228
- t.stringLiteral(uniquePressableId)
229
- )
230
- ]))
344
+ // {() => style.pressable(1, 2)}
345
+ if (t.isArrowFunctionExpression(styleExpression) && styleExpression.params.length === 0) {
346
+ const parentWrapper = t.isBlockStatement(styleExpression.body)
347
+ ? styleExpression.body.body.find(node => t.isReturnStatement(node))
348
+ : styleExpression.body
349
+
350
+ if (t.isMemberExpression(parentWrapper)) {
351
+ return
352
+ }
353
+
354
+ if (t.isArrayExpression(parentWrapper)) {
355
+ return parentWrapper.elements.forEach((wrapper, index) => handlePressableArgs(t, path, styleExpression, metadata, parentWrapper, wrapper, index))
356
+ }
231
357
 
232
- // update arrow function arg name
233
- styleExpression.params[0].name = PRESSABLE_STATE_NAME
358
+ const pressableArgs = t.isCallExpression(parentWrapper)
359
+ ? parentWrapper.arguments
360
+ : parentWrapper.argument.arguments
361
+ const callee = t.isCallExpression(parentWrapper)
362
+ ? parentWrapper.callee
363
+ : parentWrapper.argument.callee
364
+ const getBoundArgsCall = t.callExpression(
365
+ t.identifier('getBoundArgs'),
366
+ [callee]
367
+ )
368
+ const bindCall = t.callExpression(
369
+ t.memberExpression(getBoundArgsCall, t.identifier('bind')),
370
+ [t.identifier('undefined'), ...pressableArgs]
371
+ )
372
+
373
+ if (t.isCallExpression(parentWrapper)) {
374
+ styleExpression.body = bindCall
375
+
376
+ return
377
+ }
378
+
379
+ if (parentWrapper) {
380
+ parentWrapper.argument = bindCall
381
+ }
382
+
383
+ return
384
+ }
385
+
386
+ // {state => style.pressable(state, 1, 2)}
387
+ if (t.isArrowFunctionExpression(styleExpression) && styleExpression.params.length > 0) {
388
+ // user used state with custom args we need to getBoundArgs
389
+ // detect between arrow function with body and arrow function
390
+ const parentWrapper = t.isBlockStatement(styleExpression.body)
391
+ ? styleExpression.body.body.find(node => t.isReturnStatement(node))
392
+ : styleExpression.body
393
+
394
+ if (t.isArrayExpression(parentWrapper)) {
395
+ return parentWrapper.elements.forEach((wrapper, index) =>handlePressableArgs(t, path, styleExpression, metadata, parentWrapper, wrapper, index))
396
+ }
234
397
 
235
- return uniquePressableId
398
+ handlePressableArgs(t, path, styleExpression, metadata, parentWrapper, parentWrapper)
236
399
  }
237
400
  }
238
401
 
@@ -1,5 +1,5 @@
1
1
  import React, { type PropsWithChildren } from 'react'
2
- import { useMedia } from './useMedia'
2
+ import { useMedia } from '../hooks'
3
3
 
4
4
  type DisplayProps = { mq: symbol } & PropsWithChildren
5
5
 
@@ -1,5 +1,5 @@
1
1
  import React, { type PropsWithChildren } from 'react'
2
- import { useMedia } from './useMedia'
2
+ import { useMedia } from '../hooks'
3
3
 
4
4
  type HideProps = { mq: symbol } & PropsWithChildren
5
5
 
@@ -0,0 +1,101 @@
1
+ import React, { forwardRef, useRef } from 'react'
2
+ import { Pressable as NativePressableReactNative } from 'react-native'
3
+ import type { PressableProps as Props, View } from 'react-native'
4
+ import { UnistylesShadowRegistry } from '../specs'
5
+ import { getId } from '../core'
6
+
7
+ type PressableProps = Props & {
8
+ rawStyle?: Array<any>
9
+ variants?: Record<string, string | boolean>
10
+ }
11
+
12
+ export const Pressable = forwardRef<View, PressableProps>(({ variants, style, rawStyle, ...props }, passedRef) => {
13
+ const storedRef = useRef<View | null>()
14
+
15
+ return (
16
+ <NativePressableReactNative
17
+ {...props}
18
+ ref={ref => {
19
+ storedRef.current = ref
20
+ const styleResult = typeof style === 'function'
21
+ ? style({ pressed: false })
22
+ : style
23
+ const fnArgs = typeof styleResult === 'function'
24
+ // @ts-expect-error - this is hidden from TS
25
+ ? styleResult.getBoundArgs()
26
+ : Array.isArray(styleResult)
27
+ ? styleResult
28
+ // @ts-expect-error - this is hidden from TS
29
+ .map(style => typeof style === 'function' ? style.getBoundArgs() : [])
30
+ : []
31
+
32
+ if (typeof passedRef === 'object' && passedRef !== null) {
33
+ passedRef.current = ref
34
+ }
35
+
36
+ const returnFn = typeof passedRef === 'function'
37
+ ? passedRef(ref)
38
+ : () => {}
39
+ const unistyles = (rawStyle ?? [])
40
+ .map((style, index) => {
41
+ if (fnArgs[index]) {
42
+ return style
43
+ }
44
+
45
+ return undefined
46
+ })
47
+ .filter(Boolean)
48
+
49
+ // @ts-expect-error - this is hidden from TS
50
+ UnistylesShadowRegistry.add(ref, unistyles, variants, [...fnArgs])
51
+
52
+ return () => {
53
+ // @ts-expect-error - this is hidden from TS
54
+ UnistylesShadowRegistry.remove(ref)
55
+
56
+ if (typeof returnFn === 'function') {
57
+ returnFn()
58
+ }
59
+ }
60
+ }}
61
+ style={state => {
62
+ const styleResult = typeof style === 'function'
63
+ ? style(state)
64
+ : style
65
+ const fnArgs = typeof styleResult === 'function'
66
+ // @ts-expect-error - this is hidden from TS
67
+ ? styleResult.getBoundArgs()
68
+ : Array.isArray(styleResult)
69
+ ? styleResult
70
+ // @ts-expect-error - this is hidden from TS
71
+ .map(style => typeof style === 'function' ? style.getBoundArgs() : [])
72
+ : []
73
+ const pressId = getId()
74
+ const unistyles = (rawStyle ?? [])
75
+ .map((style, index) => {
76
+ if (fnArgs[index]) {
77
+ return style
78
+ }
79
+
80
+ return undefined
81
+ })
82
+ .filter(Boolean)
83
+
84
+ if (storedRef.current) {
85
+ // @ts-expect-error - this is hidden from TS
86
+ UnistylesShadowRegistry.remove(storedRef.current)
87
+ // @ts-expect-error - this is hidden from TS
88
+ UnistylesShadowRegistry.add(storedRef.current, unistyles, variants, [...fnArgs], pressId)
89
+ }
90
+
91
+ return typeof styleResult === 'function'
92
+ // @ts-expect-error - this is hidden from TS
93
+ ? styleResult(pressId)
94
+ : Array.isArray(styleResult)
95
+ // @ts-expect-error - this is hidden from TS
96
+ ? styleResult.map(style => typeof style === 'function' ? style(pressId) : style)
97
+ : styleResult
98
+ }}
99
+ />
100
+ )
101
+ })
@@ -0,0 +1,103 @@
1
+ import React, { forwardRef, useEffect, useRef } from 'react'
2
+ import { Pressable as NativePressableReactNative } from 'react-native'
3
+ import type { PressableProps as Props, View, ViewStyle } from 'react-native'
4
+ import { UnistylesShadowRegistry } from '../specs'
5
+
6
+ type WebPressableState = {
7
+ pressed: boolean,
8
+ hovered: boolean,
9
+ focused: boolean
10
+ }
11
+
12
+ type PressableProps = Props & {
13
+ variants?: Record<string, string | boolean>
14
+ style?: ((state: WebPressableState) => ViewStyle) | ViewStyle,
15
+ }
16
+
17
+ const initialState: WebPressableState = {
18
+ pressed: false,
19
+ hovered: false,
20
+ focused: false
21
+ }
22
+
23
+ const events = {
24
+ 'pointerdown': { pressed: true },
25
+ 'pointerup': { pressed: false },
26
+ 'pointerenter': { hovered: true },
27
+ 'pointerleave': { hovered: false },
28
+ 'focus': { focused: true },
29
+ 'blur': { focused: false }
30
+ } satisfies Partial<Record<keyof HTMLElementEventMap, Partial<WebPressableState>>>
31
+
32
+ export const Pressable = forwardRef<View, PressableProps>(({ variants, style, ...props }, passedRef) => {
33
+ const storedRef = useRef<View | null>()
34
+ const state = useRef<WebPressableState>(initialState)
35
+ const styleRef = useRef(style)
36
+
37
+ useEffect(() => {
38
+ styleRef.current = style
39
+ }, [style])
40
+
41
+ useEffect(() => {
42
+ const handler = (newState: Partial<WebPressableState>) => () => {
43
+ state.current = { ...state.current, ...newState }
44
+
45
+ const styleResult = typeof styleRef.current === 'function'
46
+ ? styleRef.current(state.current)
47
+ : styleRef.current
48
+ const fnArgs = typeof styleResult === 'function'
49
+ // @ts-expect-error - this is hidden from TS
50
+ ? styleResult.getBoundArgs()
51
+ : []
52
+ const extractedResult = typeof styleResult === 'function'
53
+ ? (styleResult as Function)()
54
+ : styleResult
55
+
56
+ // @ts-expect-error - this is hidden from TS
57
+ UnistylesShadowRegistry.add(storedRef.current, [extractedResult], variants, [fnArgs])
58
+ }
59
+
60
+ if (!storedRef.current) {
61
+ return
62
+ }
63
+
64
+ // ref on the web is dom element
65
+ const ref = storedRef.current as unknown as HTMLDivElement
66
+
67
+ Object.entries(events).forEach(([event, state]) => {
68
+ ref.addEventListener(event, handler(state))
69
+ })
70
+
71
+ return () => {
72
+ Object.entries(events).forEach(([event, state]) => {
73
+ ref.removeEventListener(event, handler(state))
74
+ })
75
+ }
76
+ }, [])
77
+
78
+ return (
79
+ <NativePressableReactNative
80
+ {...props}
81
+ ref={ref => {
82
+ storedRef.current = ref
83
+ const styleResult = typeof style === 'function'
84
+ ? style(initialState)
85
+ : style
86
+ const fnArgs = typeof styleResult === 'function'
87
+ // @ts-expect-error - this is hidden from TS
88
+ ? styleResult.getBoundArgs()
89
+ : []
90
+ const extractedResult = typeof styleResult === 'function'
91
+ ? (styleResult as Function)()
92
+ : styleResult
93
+
94
+ if (typeof passedRef === 'object' && passedRef !== null) {
95
+ passedRef.current = ref
96
+ }
97
+
98
+ // @ts-expect-error - this is hidden from TS
99
+ UnistylesShadowRegistry.add(ref, [extractedResult], variants, [fnArgs])
100
+ }}
101
+ />
102
+ )
103
+ })
@@ -1,2 +1,3 @@
1
1
  export { Hide } from './Hide'
2
2
  export { Display } from './Display'
3
+ export { Pressable } from './Pressable'
@@ -0,0 +1,15 @@
1
+ export const getBoundArgs = (fn: Function) => {
2
+ const boundArgs = [] as Array<any>
3
+
4
+ fn.bind = (thisArg, ...args) => {
5
+ boundArgs.push(...args)
6
+
7
+ const newFn = Function.prototype.bind.apply(fn, [thisArg, ...args])
8
+
9
+ newFn.getBoundArgs = () => boundArgs
10
+
11
+ return newFn
12
+ }
13
+
14
+ return fn
15
+ }
@@ -0,0 +1 @@
1
+ export const getId = () => `${Math.random().toString(36).substring(2, 9)}`
package/src/core/index.ts CHANGED
@@ -1 +1,3 @@
1
1
  export { createUnistylesComponent } from './createUnistylesComponent'
2
+ export { getBoundArgs } from './getBoundArgs'
3
+ export { getId } from './getId'
@@ -0,0 +1 @@
1
+ export { useMedia } from './useMedia'