zyzz 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Zyzz.podspec +16 -0
- package/dist/Style.d.ts +3 -1
- package/dist/Style.d.ts.map +1 -1
- package/dist/Style.js.map +1 -1
- package/dist/babel/NativeJsx.d.ts.map +1 -1
- package/dist/babel/NativeJsx.js +217 -15
- package/dist/babel/NativeJsx.js.map +1 -1
- package/dist/babel/index.d.ts +6 -2
- package/dist/babel/index.d.ts.map +1 -1
- package/dist/babel/index.js +10 -1
- package/dist/babel/index.js.map +1 -1
- package/dist/compiler/Graph.d.ts.map +1 -1
- package/dist/compiler/Graph.js +107 -0
- package/dist/compiler/Graph.js.map +1 -1
- package/dist/compiler/Native.d.ts +6 -3
- package/dist/compiler/Native.d.ts.map +1 -1
- package/dist/compiler/Native.js +142 -24
- package/dist/compiler/Native.js.map +1 -1
- package/dist/compiler/Source.d.ts +2 -0
- package/dist/compiler/Source.d.ts.map +1 -1
- package/dist/compiler/Source.js +17 -5
- package/dist/compiler/Source.js.map +1 -1
- package/dist/compiler/internal/Configurations.d.ts +2 -0
- package/dist/compiler/internal/Configurations.d.ts.map +1 -1
- package/dist/compiler/internal/Configurations.js +21 -3
- package/dist/compiler/internal/Configurations.js.map +1 -1
- package/dist/compiler/internal/Contract.d.ts.map +1 -1
- package/dist/compiler/internal/Contract.js +75 -38
- package/dist/compiler/internal/Contract.js.map +1 -1
- package/dist/compiler/internal/Contributions.d.ts.map +1 -1
- package/dist/compiler/internal/Contributions.js +7 -1
- package/dist/compiler/internal/Contributions.js.map +1 -1
- package/dist/compiler/internal/Descriptors.d.ts.map +1 -1
- package/dist/compiler/internal/Descriptors.js +11 -2
- package/dist/compiler/internal/Descriptors.js.map +1 -1
- package/dist/compiler/internal/Dynamic.d.ts.map +1 -1
- package/dist/compiler/internal/Dynamic.js +3 -0
- package/dist/compiler/internal/Dynamic.js.map +1 -1
- package/dist/compiler/internal/Expression.js +2 -2
- package/dist/compiler/internal/Expression.js.map +1 -1
- package/dist/compiler/internal/NativeBindings.d.ts +24 -26
- package/dist/compiler/internal/NativeBindings.d.ts.map +1 -1
- package/dist/compiler/internal/NativeBindings.js +62 -8
- package/dist/compiler/internal/NativeBindings.js.map +1 -1
- package/dist/compiler/internal/NativeMedia.d.ts +14 -0
- package/dist/compiler/internal/NativeMedia.d.ts.map +1 -0
- package/dist/compiler/internal/NativeMedia.js +287 -0
- package/dist/compiler/internal/NativeMedia.js.map +1 -0
- package/dist/compiler/internal/NativeVars.d.ts +28 -0
- package/dist/compiler/internal/NativeVars.d.ts.map +1 -0
- package/dist/compiler/internal/NativeVars.js +160 -0
- package/dist/compiler/internal/NativeVars.js.map +1 -0
- package/dist/compiler/internal/PackedStyles.d.ts +2 -0
- package/dist/compiler/internal/PackedStyles.d.ts.map +1 -1
- package/dist/compiler/internal/PackedStyles.js +2 -0
- package/dist/compiler/internal/PackedStyles.js.map +1 -1
- package/dist/compiler/internal/Themes.d.ts +24 -1
- package/dist/compiler/internal/Themes.d.ts.map +1 -1
- package/dist/compiler/internal/Themes.js +120 -3
- package/dist/compiler/internal/Themes.js.map +1 -1
- package/dist/compiler/internal/Vars.d.ts +1 -1
- package/dist/compiler/internal/Vars.d.ts.map +1 -1
- package/dist/compiler/internal/Vars.js +7 -2
- package/dist/compiler/internal/Vars.js.map +1 -1
- package/dist/default.js.zyzz.json +1 -1
- package/dist/internal/Completion.d.ts +1 -1
- package/dist/internal/Completion.d.ts.map +1 -1
- package/dist/internal/Targets.d.ts.map +1 -1
- package/dist/internal/Targets.js +2 -0
- package/dist/internal/Targets.js.map +1 -1
- package/dist/internal/Token.d.ts +0 -2
- package/dist/internal/Token.d.ts.map +1 -1
- package/dist/internal/Token.js.map +1 -1
- package/dist/internal/Value.d.ts +7 -0
- package/dist/internal/Value.d.ts.map +1 -1
- package/dist/internal/Value.js.map +1 -1
- package/dist/metro/Graph.d.ts +22 -7
- package/dist/metro/Graph.d.ts.map +1 -1
- package/dist/metro/Graph.js +188 -42
- package/dist/metro/Graph.js.map +1 -1
- package/dist/metro/Watch.d.ts +28 -4
- package/dist/metro/Watch.d.ts.map +1 -1
- package/dist/metro/Watch.js +39 -7
- package/dist/metro/Watch.js.map +1 -1
- package/dist/metro/index.d.ts +15 -4
- package/dist/metro/index.d.ts.map +1 -1
- package/dist/metro/index.js +27 -0
- package/dist/metro/index.js.map +1 -1
- package/dist/metro/transformer.d.ts +5 -1
- package/dist/metro/transformer.d.ts.map +1 -1
- package/dist/metro/transformer.js +5 -3
- package/dist/metro/transformer.js.map +1 -1
- package/dist/react-native/StyleSheet.d.ts +8 -3
- package/dist/react-native/StyleSheet.d.ts.map +1 -1
- package/dist/react-native/StyleSheet.js +25 -34
- package/dist/react-native/StyleSheet.js.map +1 -1
- package/dist/react-native/index.d.ts +1 -1
- package/dist/react-native/index.d.ts.map +1 -1
- package/dist/react-native/index.js +1 -1
- package/dist/react-native/index.js.map +1 -1
- package/dist/react-native/index.native.d.ts +5 -0
- package/dist/react-native/index.native.js +20 -0
- package/dist/react-native/index.native.js.map +7 -0
- package/dist/react-native/internal/Calculation.d.ts +7 -0
- package/dist/react-native/internal/Calculation.d.ts.map +1 -0
- package/dist/react-native/internal/Calculation.js +134 -0
- package/dist/react-native/internal/Calculation.js.map +1 -0
- package/dist/react-native/internal/Device.js +218 -0
- package/dist/react-native/internal/Device.js.map +7 -0
- package/dist/react-native/internal/NativeZyzz.js +7 -0
- package/dist/react-native/internal/NativeZyzz.js.map +7 -0
- package/dist/react-native/internal/Scalar.d.ts +16 -0
- package/dist/react-native/internal/Scalar.d.ts.map +1 -1
- package/dist/react-native/internal/Scalar.js +62 -4
- package/dist/react-native/internal/Scalar.js.map +1 -1
- package/dist/react-native/internal/Store.d.ts +32 -0
- package/dist/react-native/internal/Store.d.ts.map +1 -0
- package/dist/react-native/internal/Store.js +57 -0
- package/dist/react-native/internal/Store.js.map +1 -0
- package/dist/react-native/internal/Styles.d.ts +19 -0
- package/dist/react-native/internal/Styles.d.ts.map +1 -0
- package/dist/react-native/internal/Styles.js +35 -0
- package/dist/react-native/internal/Styles.js.map +1 -0
- package/dist/react-native/internal/Tokens.d.ts +21 -0
- package/dist/react-native/internal/Tokens.d.ts.map +1 -0
- package/dist/react-native/internal/Tokens.js +58 -0
- package/dist/react-native/internal/Tokens.js.map +1 -0
- package/dist/react-native/internal/Viewport.d.ts +6 -0
- package/dist/react-native/internal/Viewport.d.ts.map +1 -0
- package/dist/react-native/internal/Viewport.js +4 -0
- package/dist/react-native/internal/Viewport.js.map +1 -0
- package/dist/react-native/react.d.ts +102 -14
- package/dist/react-native/react.d.ts.map +1 -1
- package/dist/react-native/react.js +86 -18
- package/dist/react-native/react.js.map +1 -1
- package/dist/react-native/reanimated.d.ts +39 -0
- package/dist/react-native/reanimated.d.ts.map +1 -0
- package/dist/react-native/reanimated.js +76 -0
- package/dist/react-native/reanimated.js.map +1 -0
- package/dist/runtime/NativeContext.d.ts +10 -1
- package/dist/runtime/NativeContext.d.ts.map +1 -1
- package/dist/runtime/NativeContext.js +67 -14
- package/dist/runtime/NativeContext.js.map +1 -1
- package/dist/runtime/NativeDynamic.d.ts +3 -2
- package/dist/runtime/NativeDynamic.d.ts.map +1 -1
- package/dist/runtime/NativeDynamic.js +37 -7
- package/dist/runtime/NativeDynamic.js.map +1 -1
- package/dist/runtime/NativeStatic.d.ts +23 -0
- package/dist/runtime/NativeStatic.d.ts.map +1 -0
- package/dist/runtime/NativeStatic.js +106 -0
- package/dist/runtime/NativeStatic.js.map +1 -0
- package/dist/runtime/NativeVars.d.ts +53 -0
- package/dist/runtime/NativeVars.d.ts.map +1 -0
- package/dist/runtime/NativeVars.js +77 -0
- package/dist/runtime/NativeVars.js.map +1 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +4 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/internal/NativeMedia.d.ts +25 -0
- package/dist/runtime/internal/NativeMedia.d.ts.map +1 -0
- package/dist/runtime/internal/NativeMedia.js +36 -0
- package/dist/runtime/internal/NativeMedia.js.map +1 -0
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +7 -35
- package/dist/vite/index.js.map +1 -1
- package/dist/web/Css.d.ts.map +1 -1
- package/dist/web/Css.js +31 -19
- package/dist/web/Css.js.map +1 -1
- package/dist/web/internal/Themes.d.ts +0 -2
- package/dist/web/internal/Themes.d.ts.map +1 -1
- package/dist/web/internal/Themes.js +30 -28
- package/dist/web/internal/Themes.js.map +1 -1
- package/dist/web/page.d.ts +2 -0
- package/dist/web/page.d.ts.map +1 -1
- package/native/NativeZyzz.cpp +215 -0
- package/native/NativeZyzz.h +52 -0
- package/native/ZyzzSpecJSI.h +65 -0
- package/native/android/CMakeLists.txt +8 -0
- package/native/android/ZyzzSpec-generated.cpp +50 -0
- package/native/android/ZyzzSpec.h +31 -0
- package/native/ios/ZyzzModuleProvider.mm +13 -0
- package/package.json +39 -1
- package/react-native.config.ts +14 -0
- package/src/Style.ts +11 -8
- package/src/babel/NativeJsx.ts +319 -33
- package/src/babel/index.ts +21 -3
- package/src/compiler/Graph.ts +126 -0
- package/src/compiler/Native.ts +158 -26
- package/src/compiler/Source.ts +32 -5
- package/src/compiler/internal/Configurations.ts +25 -3
- package/src/compiler/internal/Contract.ts +98 -50
- package/src/compiler/internal/Contributions.ts +7 -1
- package/src/compiler/internal/Descriptors.ts +12 -8
- package/src/compiler/internal/Dynamic.ts +4 -0
- package/src/compiler/internal/Expression.ts +2 -2
- package/src/compiler/internal/NativeBindings.ts +99 -15
- package/src/compiler/internal/NativeMedia.ts +342 -0
- package/src/compiler/internal/NativeVars.ts +231 -0
- package/src/compiler/internal/PackedStyles.ts +4 -0
- package/src/compiler/internal/Themes.ts +193 -2
- package/src/compiler/internal/Vars.ts +12 -1
- package/src/internal/Completion.ts +6 -3
- package/src/internal/Targets.ts +2 -0
- package/src/internal/Token.ts +0 -2
- package/src/internal/Value.ts +20 -0
- package/src/metro/Graph.ts +250 -50
- package/src/metro/Watch.ts +95 -10
- package/src/metro/index.ts +62 -4
- package/src/metro/transformer.ts +21 -11
- package/src/react-native/StyleSheet.ts +56 -49
- package/src/react-native/index.native.ts +10 -0
- package/src/react-native/index.ts +1 -1
- package/src/react-native/internal/Calculation.ts +159 -0
- package/src/react-native/internal/Device.ts +297 -0
- package/src/react-native/internal/NativeZyzz.ts +20 -0
- package/src/react-native/internal/Scalar.ts +86 -4
- package/src/react-native/internal/Store.ts +78 -0
- package/src/react-native/internal/Styles.ts +77 -0
- package/src/react-native/internal/Tokens.ts +85 -0
- package/src/react-native/internal/Viewport.ts +8 -0
- package/src/react-native/react.ts +218 -26
- package/src/react-native/reanimated.ts +162 -0
- package/src/runtime/NativeContext.ts +88 -17
- package/src/runtime/NativeDynamic.ts +42 -10
- package/src/runtime/NativeStatic.ts +145 -0
- package/src/runtime/NativeVars.ts +189 -0
- package/src/runtime/index.ts +6 -0
- package/src/runtime/internal/NativeMedia.ts +63 -0
- package/src/vite/index.ts +9 -42
- package/src/web/Css.ts +42 -27
- package/src/web/internal/Themes.ts +34 -57
- package/src/web/page.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zyzz",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Modern, universal, simple styling library for the Web and React Native",
|
|
6
6
|
"repository": {
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
"files": [
|
|
17
17
|
"dist",
|
|
18
18
|
"src",
|
|
19
|
+
"native",
|
|
20
|
+
"react-native.config.ts",
|
|
21
|
+
"Zyzz.podspec",
|
|
19
22
|
"!src/**/*.bench-d.ts",
|
|
20
23
|
"!src/**/*.bench.ts",
|
|
21
24
|
"!src/**/*.test-d.ts",
|
|
@@ -25,6 +28,20 @@
|
|
|
25
28
|
"./src/reset.css",
|
|
26
29
|
"./dist/reset.css"
|
|
27
30
|
],
|
|
31
|
+
"codegenConfig": {
|
|
32
|
+
"name": "ZyzzSpec",
|
|
33
|
+
"type": "modules",
|
|
34
|
+
"jsSrcsDir": "src/react-native/internal",
|
|
35
|
+
"android": {
|
|
36
|
+
"javaPackageName": "xyz.wevm.zyzz"
|
|
37
|
+
},
|
|
38
|
+
"ios": {
|
|
39
|
+
"modulesProvider": {
|
|
40
|
+
"NativeZyzz": "ZyzzModuleProvider"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"includesGeneratedCode": true
|
|
44
|
+
},
|
|
28
45
|
"module": "./dist/index.js",
|
|
29
46
|
"types": "./dist/index.d.ts",
|
|
30
47
|
"exports": {
|
|
@@ -84,11 +101,24 @@
|
|
|
84
101
|
"default": "./dist/oxlint/index.js"
|
|
85
102
|
},
|
|
86
103
|
"./react-native": {
|
|
104
|
+
"react-native": {
|
|
105
|
+
"types": "./dist/react-native/index.native.d.ts",
|
|
106
|
+
"default": "./dist/react-native/index.native.js"
|
|
107
|
+
},
|
|
87
108
|
"src": "./src/react-native/index.ts",
|
|
88
109
|
"types": "./dist/react-native/index.d.ts",
|
|
89
110
|
"default": "./dist/react-native/index.js"
|
|
90
111
|
},
|
|
112
|
+
"./react-native/reanimated": {
|
|
113
|
+
"src": "./src/react-native/reanimated.ts",
|
|
114
|
+
"types": "./dist/react-native/reanimated.d.ts",
|
|
115
|
+
"default": "./dist/react-native/reanimated.js"
|
|
116
|
+
},
|
|
91
117
|
"./react-native/react": {
|
|
118
|
+
"react-native": {
|
|
119
|
+
"types": "./dist/react-native/react.d.ts",
|
|
120
|
+
"default": "./dist/react-native/internal/Device.js"
|
|
121
|
+
},
|
|
92
122
|
"src": "./src/react-native/react.ts",
|
|
93
123
|
"types": "./dist/react-native/react.d.ts",
|
|
94
124
|
"default": "./dist/react-native/react.js"
|
|
@@ -146,6 +176,8 @@
|
|
|
146
176
|
"@babel/core": "^7.29.7",
|
|
147
177
|
"next": "^16.3.5",
|
|
148
178
|
"react": "^19.0.0",
|
|
179
|
+
"react-native": ">=0.86.0 <1.0.0",
|
|
180
|
+
"react-native-reanimated": ">=4.5.3 <5.0.0",
|
|
149
181
|
"vite": "^8.0.0"
|
|
150
182
|
},
|
|
151
183
|
"peerDependenciesMeta": {
|
|
@@ -158,6 +190,12 @@
|
|
|
158
190
|
"react": {
|
|
159
191
|
"optional": true
|
|
160
192
|
},
|
|
193
|
+
"react-native": {
|
|
194
|
+
"optional": true
|
|
195
|
+
},
|
|
196
|
+
"react-native-reanimated": {
|
|
197
|
+
"optional": true
|
|
198
|
+
},
|
|
161
199
|
"vite": {
|
|
162
200
|
"optional": true
|
|
163
201
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Autolinks the shared native adapter without application registration. @module */
|
|
2
|
+
export default {
|
|
3
|
+
dependency: {
|
|
4
|
+
platforms: {
|
|
5
|
+
android: {
|
|
6
|
+
cxxModuleCMakeListsModuleName: 'react_codegen_ZyzzSpec',
|
|
7
|
+
cxxModuleCMakeListsPath: 'CMakeLists.txt',
|
|
8
|
+
cxxModuleHeaderName: 'NativeZyzz',
|
|
9
|
+
sourceDir: 'native/android',
|
|
10
|
+
},
|
|
11
|
+
ios: {},
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
}
|
package/src/Style.ts
CHANGED
|
@@ -75,14 +75,17 @@ export type Accepted<
|
|
|
75
75
|
? LiteralDeclarations
|
|
76
76
|
: DeclarationProperties<tokens>)[key] extends style[key]
|
|
77
77
|
? style[key]
|
|
78
|
-
:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
78
|
+
: // Naming the expected tokens avoids a `never` diagnostic and keeps completions to accepted values.
|
|
79
|
+
[Value.Tokens<style[key], tokens, key>] extends [never]
|
|
80
|
+
? Value.Mismatch<tokens, key>
|
|
81
|
+
: Value.Accepted<
|
|
82
|
+
Pick<style, key>,
|
|
83
|
+
literal extends true
|
|
84
|
+
? LiteralDeclarations
|
|
85
|
+
: DeclarationProperties<tokens>
|
|
86
|
+
>[key] &
|
|
87
|
+
Value.Checked<Pick<style, key>, tokens>[key] &
|
|
88
|
+
Value.Tokens<style[key], tokens, key>
|
|
86
89
|
: key extends Condition.Keys<tokens, key>
|
|
87
90
|
? [style[key]] extends [undefined]
|
|
88
91
|
? never
|
package/src/babel/NativeJsx.ts
CHANGED
|
@@ -112,9 +112,13 @@ export function visitor(
|
|
|
112
112
|
callables: WeakSet<Babel.types.Node>,
|
|
113
113
|
): Babel.Visitor<Babel.PluginPass> {
|
|
114
114
|
const t = api.types
|
|
115
|
-
type
|
|
115
|
+
type Method = 'nativeStyle' | 'props' | 'style' | 'view'
|
|
116
|
+
type Bindings = Map<Method, Babel.types.Identifier>
|
|
116
117
|
type Owners = Map<Babel.NodePath<Babel.types.Function>, Bindings>
|
|
117
118
|
const files = new WeakMap<Babel.BabelFile, Owners>()
|
|
119
|
+
const native = new WeakSet<Babel.types.JSXOpeningElement>()
|
|
120
|
+
const animated = new WeakSet<Babel.types.JSXOpeningElement>()
|
|
121
|
+
const wrapped = new WeakSet<Babel.types.JSXOpeningElement>()
|
|
118
122
|
return {
|
|
119
123
|
Program: {
|
|
120
124
|
enter(_, state) {
|
|
@@ -123,50 +127,275 @@ export function visitor(
|
|
|
123
127
|
exit(path, state) {
|
|
124
128
|
const owners = files.get(state.file)!
|
|
125
129
|
if (!owners.size) return
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
130
|
+
const hooks = new Map<boolean, Babel.types.Identifier>()
|
|
131
|
+
for (const native of [false, true]) {
|
|
132
|
+
if (
|
|
133
|
+
![...owners.values()].some((bindings) =>
|
|
134
|
+
[...bindings.keys()].some(
|
|
135
|
+
(method) =>
|
|
136
|
+
(method === 'nativeStyle' || method === 'view') === native,
|
|
137
|
+
),
|
|
138
|
+
)
|
|
139
|
+
)
|
|
140
|
+
continue
|
|
141
|
+
const hook = path.scope.generateUidIdentifier(
|
|
142
|
+
native ? 'useZyzzNativeStyles' : 'useZyzzStyles',
|
|
143
|
+
)
|
|
144
|
+
hooks.set(native, hook)
|
|
145
|
+
path.unshiftContainer(
|
|
146
|
+
'body',
|
|
147
|
+
t.importDeclaration(
|
|
148
|
+
[
|
|
149
|
+
t.importSpecifier(
|
|
150
|
+
t.cloneNode(hook),
|
|
151
|
+
t.identifier(native ? 'useNativeStyles' : 'useStyles'),
|
|
152
|
+
),
|
|
153
|
+
],
|
|
154
|
+
t.stringLiteral('zyzz/react-native/react'),
|
|
155
|
+
),
|
|
156
|
+
)
|
|
157
|
+
}
|
|
134
158
|
for (const [owner, bindings] of owners) {
|
|
135
159
|
if (!t.isBlockStatement(owner.node.body))
|
|
136
160
|
owner.node.body = t.blockStatement([
|
|
137
161
|
t.returnStatement(owner.node.body),
|
|
138
162
|
])
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
? [t.variableDeclarator(context, t.callExpression(hook, []))]
|
|
145
|
-
: []
|
|
146
|
-
for (const [method, binding] of bindings)
|
|
147
|
-
declarations.push(
|
|
148
|
-
t.variableDeclarator(
|
|
149
|
-
binding,
|
|
150
|
-
t.memberExpression(
|
|
151
|
-
context ?? t.callExpression(hook, []),
|
|
152
|
-
t.identifier(method),
|
|
153
|
-
),
|
|
154
|
-
),
|
|
163
|
+
const declarations: Babel.types.VariableDeclarator[] = []
|
|
164
|
+
for (const [native, hook] of hooks) {
|
|
165
|
+
const entries = [...bindings].filter(
|
|
166
|
+
([method]) =>
|
|
167
|
+
(method === 'nativeStyle' || method === 'view') === native,
|
|
155
168
|
)
|
|
169
|
+
const context =
|
|
170
|
+
entries.length > 1
|
|
171
|
+
? owner.scope.generateUidIdentifier('zyzzStyles')
|
|
172
|
+
: undefined
|
|
173
|
+
if (context)
|
|
174
|
+
declarations.push(
|
|
175
|
+
t.variableDeclarator(
|
|
176
|
+
t.cloneNode(context),
|
|
177
|
+
t.callExpression(t.cloneNode(hook), []),
|
|
178
|
+
),
|
|
179
|
+
)
|
|
180
|
+
for (const [method, binding] of entries)
|
|
181
|
+
declarations.push(
|
|
182
|
+
t.variableDeclarator(
|
|
183
|
+
t.cloneNode(binding),
|
|
184
|
+
t.memberExpression(
|
|
185
|
+
context
|
|
186
|
+
? t.cloneNode(context)
|
|
187
|
+
: t.callExpression(t.cloneNode(hook), []),
|
|
188
|
+
t.identifier(method === 'nativeStyle' ? 'style' : method),
|
|
189
|
+
),
|
|
190
|
+
),
|
|
191
|
+
)
|
|
192
|
+
}
|
|
156
193
|
owner.node.body.body.unshift(
|
|
157
194
|
t.variableDeclaration('var', declarations),
|
|
158
195
|
)
|
|
159
196
|
}
|
|
160
197
|
},
|
|
161
198
|
},
|
|
199
|
+
JSXOpeningElement: {
|
|
200
|
+
enter(path, state) {
|
|
201
|
+
const name = path.node.name
|
|
202
|
+
const root = (() => {
|
|
203
|
+
if (t.isJSXIdentifier(name)) return name
|
|
204
|
+
if (t.isJSXMemberExpression(name) && t.isJSXIdentifier(name.object))
|
|
205
|
+
return name.object
|
|
206
|
+
return undefined
|
|
207
|
+
})()
|
|
208
|
+
if (!root) return
|
|
209
|
+
const binding = path.scope.getBinding(root.name)
|
|
210
|
+
if (
|
|
211
|
+
binding?.path.parentPath?.isImportDeclaration() &&
|
|
212
|
+
binding.path.parentPath.node.source.value ===
|
|
213
|
+
'react-native-reanimated'
|
|
214
|
+
) {
|
|
215
|
+
animated.add(path.node)
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
if (binding?.constant && binding.path.isVariableDeclarator()) {
|
|
219
|
+
const call = binding.path.node.init
|
|
220
|
+
if (t.isCallExpression(call)) {
|
|
221
|
+
const callee = call.callee
|
|
222
|
+
const name = t.isIdentifier(callee)
|
|
223
|
+
? callee
|
|
224
|
+
: t.isMemberExpression(callee) &&
|
|
225
|
+
!callee.computed &&
|
|
226
|
+
t.isIdentifier(callee.object) &&
|
|
227
|
+
t.isIdentifier(callee.property, { name: 'withStyles' })
|
|
228
|
+
? callee.object
|
|
229
|
+
: undefined
|
|
230
|
+
const factory = name && binding.path.scope.getBinding(name.name)
|
|
231
|
+
if (
|
|
232
|
+
factory?.path.parentPath?.isImportDeclaration() &&
|
|
233
|
+
['zyzz/react-native', 'zyzz/react-native/react'].includes(
|
|
234
|
+
factory.path.parentPath.node.source.value,
|
|
235
|
+
) &&
|
|
236
|
+
(t.isIdentifier(callee)
|
|
237
|
+
? factory.path.isImportSpecifier() &&
|
|
238
|
+
t.isIdentifier(factory.path.node.imported, {
|
|
239
|
+
name: 'withStyles',
|
|
240
|
+
})
|
|
241
|
+
: factory.path.isImportNamespaceSpecifier())
|
|
242
|
+
) {
|
|
243
|
+
wrapped.add(path.node)
|
|
244
|
+
return
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (
|
|
249
|
+
!binding?.path.parentPath?.isImportDeclaration() ||
|
|
250
|
+
binding.path.parentPath.node.source.value !== 'react-native'
|
|
251
|
+
)
|
|
252
|
+
return
|
|
253
|
+
const imported = (() => {
|
|
254
|
+
if (
|
|
255
|
+
binding.path.isImportSpecifier() &&
|
|
256
|
+
t.isIdentifier(binding.path.node.imported)
|
|
257
|
+
)
|
|
258
|
+
return binding.path.node.imported.name
|
|
259
|
+
if (
|
|
260
|
+
t.isJSXMemberExpression(name) &&
|
|
261
|
+
binding.path.isImportNamespaceSpecifier()
|
|
262
|
+
)
|
|
263
|
+
return name.property.name
|
|
264
|
+
return undefined
|
|
265
|
+
})()
|
|
266
|
+
if (
|
|
267
|
+
!imported ||
|
|
268
|
+
!['Image', 'Pressable', 'Text', 'TextInput', 'View'].includes(
|
|
269
|
+
imported,
|
|
270
|
+
)
|
|
271
|
+
)
|
|
272
|
+
return
|
|
273
|
+
if (
|
|
274
|
+
!path.node.attributes.some(
|
|
275
|
+
(attribute) =>
|
|
276
|
+
t.isJSXSpreadAttribute(attribute) ||
|
|
277
|
+
(t.isJSXAttribute(attribute) &&
|
|
278
|
+
t.isJSXIdentifier(attribute.name, { name: 'style' })),
|
|
279
|
+
)
|
|
280
|
+
)
|
|
281
|
+
return
|
|
282
|
+
native.add(path.node)
|
|
283
|
+
owner(path, files.get(state.file)!, 'view')
|
|
284
|
+
},
|
|
285
|
+
exit(path, state) {
|
|
286
|
+
if (!native.has(path.node)) return
|
|
287
|
+
const properties: (
|
|
288
|
+
| Babel.types.ObjectProperty
|
|
289
|
+
| Babel.types.SpreadElement
|
|
290
|
+
)[] = []
|
|
291
|
+
for (const attribute of path.node.attributes) {
|
|
292
|
+
if (t.isJSXSpreadAttribute(attribute))
|
|
293
|
+
properties.push(t.spreadElement(attribute.argument))
|
|
294
|
+
else if (t.isJSXIdentifier(attribute.name)) {
|
|
295
|
+
const value = attribute.value
|
|
296
|
+
const expression = (() => {
|
|
297
|
+
if (value === null) return t.booleanLiteral(true)
|
|
298
|
+
if (
|
|
299
|
+
t.isJSXExpressionContainer(value) &&
|
|
300
|
+
!t.isJSXEmptyExpression(value.expression)
|
|
301
|
+
)
|
|
302
|
+
return value.expression
|
|
303
|
+
if (t.isStringLiteral(value))
|
|
304
|
+
return t.stringLiteral(value.value.replace(/\n\s+/g, ' '))
|
|
305
|
+
if (t.isJSXElement(value) || t.isJSXFragment(value)) return value
|
|
306
|
+
return undefined
|
|
307
|
+
})()
|
|
308
|
+
if (!expression)
|
|
309
|
+
throw path.buildCodeFrameError(
|
|
310
|
+
'Unsupported native JSX attribute.',
|
|
311
|
+
)
|
|
312
|
+
properties.push(
|
|
313
|
+
t.objectProperty(
|
|
314
|
+
t.stringLiteral(attribute.name.name),
|
|
315
|
+
expression,
|
|
316
|
+
),
|
|
317
|
+
)
|
|
318
|
+
} else
|
|
319
|
+
throw path.buildCodeFrameError('Unsupported native JSX attribute.')
|
|
320
|
+
}
|
|
321
|
+
const binding = owner(path, files.get(state.file)!, 'view')
|
|
322
|
+
const props = t.objectExpression(properties)
|
|
323
|
+
const key = path.node.attributes.some(
|
|
324
|
+
(attribute) =>
|
|
325
|
+
t.isJSXAttribute(attribute) &&
|
|
326
|
+
t.isJSXIdentifier(attribute.name, { name: 'key' }),
|
|
327
|
+
)
|
|
328
|
+
const temporary = key
|
|
329
|
+
? path.scope.generateUidIdentifier('zyzzProps')
|
|
330
|
+
: undefined
|
|
331
|
+
if (temporary)
|
|
332
|
+
path.scope.push({ id: t.cloneNode(temporary), kind: 'var' })
|
|
333
|
+
path.node.attributes = [
|
|
334
|
+
t.jsxSpreadAttribute(
|
|
335
|
+
t.callExpression(binding, [
|
|
336
|
+
temporary
|
|
337
|
+
? t.assignmentExpression('=', t.cloneNode(temporary), props)
|
|
338
|
+
: props,
|
|
339
|
+
]),
|
|
340
|
+
),
|
|
341
|
+
...(temporary
|
|
342
|
+
? [
|
|
343
|
+
t.jsxAttribute(
|
|
344
|
+
t.jsxIdentifier('key'),
|
|
345
|
+
t.jsxExpressionContainer(
|
|
346
|
+
t.memberExpression(
|
|
347
|
+
t.cloneNode(temporary),
|
|
348
|
+
t.identifier('key'),
|
|
349
|
+
),
|
|
350
|
+
),
|
|
351
|
+
),
|
|
352
|
+
]
|
|
353
|
+
: []),
|
|
354
|
+
]
|
|
355
|
+
},
|
|
356
|
+
},
|
|
162
357
|
JSXAttribute(path, state) {
|
|
358
|
+
const name = path.node.name
|
|
163
359
|
if (
|
|
164
|
-
!t.isJSXIdentifier(
|
|
360
|
+
!t.isJSXIdentifier(name) ||
|
|
361
|
+
(name.name !== 'style' && !name.name.endsWith('Style')) ||
|
|
165
362
|
!t.isJSXExpressionContainer(path.node.value) ||
|
|
166
363
|
t.isJSXEmptyExpression(path.node.value.expression)
|
|
167
364
|
)
|
|
168
365
|
return
|
|
169
|
-
|
|
366
|
+
if (
|
|
367
|
+
animated.has(path.parentPath.node as Babel.types.JSXOpeningElement) &&
|
|
368
|
+
!requiresResolution(path, path.node.value.expression)
|
|
369
|
+
)
|
|
370
|
+
return
|
|
371
|
+
if (wrapped.has(path.parentPath.node as Babel.types.JSXOpeningElement)) {
|
|
372
|
+
const value = path.node.value.expression
|
|
373
|
+
if (t.isIdentifier(value) && callables.has(value))
|
|
374
|
+
path.node.value.expression = t.memberExpression(
|
|
375
|
+
t.callExpression(value, []),
|
|
376
|
+
t.identifier('style'),
|
|
377
|
+
)
|
|
378
|
+
else if (
|
|
379
|
+
t.isCallExpression(value) &&
|
|
380
|
+
t.isIdentifier(value.callee) &&
|
|
381
|
+
callables.has(value.callee)
|
|
382
|
+
)
|
|
383
|
+
path.node.value.expression = t.memberExpression(
|
|
384
|
+
value,
|
|
385
|
+
t.identifier('style'),
|
|
386
|
+
)
|
|
387
|
+
return
|
|
388
|
+
}
|
|
389
|
+
// Unlike style, other style props stay untouched outside components, so class and module-scope JSX keep compiling.
|
|
390
|
+
if (name.name !== 'style' && !component(path)) return
|
|
391
|
+
const binding = owner(
|
|
392
|
+
path,
|
|
393
|
+
files.get(state.file)!,
|
|
394
|
+
name.name === 'style' &&
|
|
395
|
+
native.has(path.parentPath.node as Babel.types.JSXOpeningElement)
|
|
396
|
+
? 'nativeStyle'
|
|
397
|
+
: 'style',
|
|
398
|
+
)
|
|
170
399
|
let inputs = [path.node.value.expression]
|
|
171
400
|
let value = path.node.value.expression
|
|
172
401
|
while (
|
|
@@ -216,15 +445,64 @@ export function visitor(
|
|
|
216
445
|
path.node.value.expression = t.callExpression(binding, inputs)
|
|
217
446
|
},
|
|
218
447
|
JSXSpreadAttribute(path, state) {
|
|
448
|
+
if (
|
|
449
|
+
(animated.has(path.parentPath.node as Babel.types.JSXOpeningElement) &&
|
|
450
|
+
!requiresResolution(path, path.node.argument)) ||
|
|
451
|
+
native.has(path.parentPath.node as Babel.types.JSXOpeningElement) ||
|
|
452
|
+
wrapped.has(path.parentPath.node as Babel.types.JSXOpeningElement)
|
|
453
|
+
)
|
|
454
|
+
return
|
|
219
455
|
const binding = owner(path, files.get(state.file)!, 'props')
|
|
220
456
|
path.node.argument = t.callExpression(binding, [path.node.argument])
|
|
221
457
|
},
|
|
222
458
|
}
|
|
223
|
-
function
|
|
459
|
+
function requiresResolution(
|
|
224
460
|
path: Babel.NodePath,
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
461
|
+
expression: Babel.types.Node,
|
|
462
|
+
): boolean {
|
|
463
|
+
const pending = [{ expression, scope: path.scope }]
|
|
464
|
+
const seen = new Set<Babel.types.VariableDeclarator>()
|
|
465
|
+
for (const entry of pending) {
|
|
466
|
+
let required = false
|
|
467
|
+
t.traverseFast(entry.expression, (node) => {
|
|
468
|
+
if (
|
|
469
|
+
callables.has(node) ||
|
|
470
|
+
(entry.expression === expression && t.isCallExpression(node)) ||
|
|
471
|
+
(t.isMemberExpression(node) &&
|
|
472
|
+
!node.computed &&
|
|
473
|
+
t.isIdentifier(node.property, { name: 'style' }))
|
|
474
|
+
) {
|
|
475
|
+
required = true
|
|
476
|
+
return t.traverseFast.stop
|
|
477
|
+
}
|
|
478
|
+
// Alias factories stay opaque so worklet inputs do not become React subscriptions.
|
|
479
|
+
if (
|
|
480
|
+
t.isCallExpression(node) ||
|
|
481
|
+
t.isFunction(node) ||
|
|
482
|
+
t.isNewExpression(node)
|
|
483
|
+
)
|
|
484
|
+
return t.traverseFast.skip
|
|
485
|
+
if (!t.isIdentifier(node)) return
|
|
486
|
+
const binding = entry.scope.getBinding(node.name)
|
|
487
|
+
if (
|
|
488
|
+
binding?.constant &&
|
|
489
|
+
binding.path.isVariableDeclarator() &&
|
|
490
|
+
binding.path.node.init &&
|
|
491
|
+
!seen.has(binding.path.node)
|
|
492
|
+
) {
|
|
493
|
+
seen.add(binding.path.node)
|
|
494
|
+
pending.push({
|
|
495
|
+
expression: binding.path.node.init,
|
|
496
|
+
scope: binding.path.scope,
|
|
497
|
+
})
|
|
498
|
+
}
|
|
499
|
+
})
|
|
500
|
+
if (required) return true
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
return false
|
|
504
|
+
}
|
|
505
|
+
function component(path: Babel.NodePath) {
|
|
228
506
|
const parent = path.findParent((candidate) => {
|
|
229
507
|
if (!candidate.isFunction()) return false
|
|
230
508
|
let declaration = candidate.parentPath
|
|
@@ -241,7 +519,15 @@ export function visitor(
|
|
|
241
519
|
candidate.parentPath.isExportDefaultDeclaration()
|
|
242
520
|
)
|
|
243
521
|
})
|
|
244
|
-
|
|
522
|
+
return parent?.isFunction() && !parent.isClassMethod() ? parent : undefined
|
|
523
|
+
}
|
|
524
|
+
function owner(
|
|
525
|
+
path: Babel.NodePath,
|
|
526
|
+
owners: Owners,
|
|
527
|
+
method: Method,
|
|
528
|
+
): Babel.types.Identifier {
|
|
529
|
+
const parent = component(path)
|
|
530
|
+
if (!parent)
|
|
245
531
|
throw path.buildCodeFrameError(
|
|
246
532
|
'Native style props must be rendered in a function component or custom hook.',
|
|
247
533
|
)
|
|
@@ -255,6 +541,6 @@ export function visitor(
|
|
|
255
541
|
binding = parent.scope.generateUidIdentifier(`zyzz${method}`)
|
|
256
542
|
bindings.set(method, binding)
|
|
257
543
|
}
|
|
258
|
-
return binding
|
|
544
|
+
return t.cloneNode(binding)
|
|
259
545
|
}
|
|
260
546
|
}
|
package/src/babel/index.ts
CHANGED
|
@@ -17,12 +17,16 @@ import * as Transform from '../compiler/Transform.js'
|
|
|
17
17
|
export type NativeOptions = {
|
|
18
18
|
/** Fixed build-time scheme. Omit for runtime selection through React. */
|
|
19
19
|
readonly colorScheme?: 'dark' | 'light' | undefined
|
|
20
|
-
/**
|
|
21
|
-
readonly
|
|
20
|
+
/** Packed authoring contracts supplied by the bundler. */
|
|
21
|
+
readonly contracts?: Graph.compile.Options['contracts']
|
|
22
|
+
/** Authored font-family text mapped to registered native families. */
|
|
23
|
+
readonly fonts?: Native.compile.Options['fonts']
|
|
22
24
|
/** Host-resolved graph imports. */
|
|
23
25
|
readonly imports?: Graph.compile.Options['imports']
|
|
24
26
|
/** Portable source identity. Defaults to a native module-local identity. */
|
|
25
27
|
readonly moduleId?: string | undefined
|
|
28
|
+
/** Closed source graph supplied by the bundler for imported authoring. */
|
|
29
|
+
readonly modules?: Readonly<Record<string, string>> | undefined
|
|
26
30
|
/** Native destination selected by the bundler. */
|
|
27
31
|
readonly platform: 'android' | 'ios'
|
|
28
32
|
/** Native compiler selection. Omission preserves existing native configurations. */
|
|
@@ -188,9 +192,11 @@ export function zyzz(
|
|
|
188
192
|
options[Compilation.key]?.programs ??
|
|
189
193
|
(parsed ? new Map([[moduleId, parsed]]) : undefined),
|
|
190
194
|
modules: { ...options.modules, [moduleId]: file.code },
|
|
195
|
+
contracts: options.contracts,
|
|
191
196
|
imports: options.imports,
|
|
192
197
|
native: {
|
|
193
198
|
[Edits.runtime]: true,
|
|
199
|
+
fonts: options.fonts,
|
|
194
200
|
platform: options.platform,
|
|
195
201
|
units: options.units,
|
|
196
202
|
colorScheme: options.colorScheme ?? 'light',
|
|
@@ -201,6 +207,7 @@ export function zyzz(
|
|
|
201
207
|
return Native.compile({
|
|
202
208
|
[Themes.context]: parsed ? { parsed, links: {} } : undefined,
|
|
203
209
|
[Edits.runtime]: true,
|
|
210
|
+
fonts: options.fonts,
|
|
204
211
|
platform: options.platform,
|
|
205
212
|
units: options.units,
|
|
206
213
|
colorScheme: options.colorScheme ?? 'light',
|
|
@@ -333,7 +340,18 @@ export function zyzz(
|
|
|
333
340
|
},
|
|
334
341
|
visitor:
|
|
335
342
|
options.target !== 'web' && options.colorScheme === undefined
|
|
336
|
-
?
|
|
343
|
+
? {
|
|
344
|
+
Program(path, state) {
|
|
345
|
+
// Bind before framework transforms clone components or rewrite imports.
|
|
346
|
+
api.traverse(
|
|
347
|
+
state.file.ast,
|
|
348
|
+
NativeJsx.visitor(api, callables),
|
|
349
|
+
path.scope,
|
|
350
|
+
state,
|
|
351
|
+
)
|
|
352
|
+
path.scope.crawl()
|
|
353
|
+
},
|
|
354
|
+
}
|
|
337
355
|
: {
|
|
338
356
|
Program(path) {
|
|
339
357
|
if (options.target !== 'web' || !options.reset) return
|