@tamagui/static 1.100.6 → 1.101.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. package/dist/cjs/extractor/createExtractor.js +21 -12
  2. package/dist/cjs/extractor/createExtractor.js.map +1 -1
  3. package/dist/cjs/extractor/createExtractor.native.js +18 -12
  4. package/dist/cjs/extractor/createExtractor.native.js.map +2 -2
  5. package/dist/cjs/extractor/extractMediaStyle.js +2 -2
  6. package/dist/cjs/extractor/extractMediaStyle.js.map +1 -1
  7. package/dist/cjs/extractor/extractMediaStyle.native.js +2 -2
  8. package/dist/cjs/extractor/extractMediaStyle.native.js.map +2 -2
  9. package/dist/cjs/extractor/extractToClassNames.js +17 -15
  10. package/dist/cjs/extractor/extractToClassNames.js.map +1 -1
  11. package/dist/cjs/extractor/extractToClassNames.native.js +12 -14
  12. package/dist/cjs/extractor/extractToClassNames.native.js.map +2 -2
  13. package/dist/cjs/extractor/extractToNative.js +319 -0
  14. package/dist/cjs/extractor/extractToNative.js.map +6 -0
  15. package/dist/cjs/extractor/extractToNative.native.js +353 -0
  16. package/dist/cjs/extractor/extractToNative.native.js.map +6 -0
  17. package/dist/cjs/index.js +1 -0
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/cjs/index.native.js +2 -0
  20. package/dist/cjs/index.native.js.map +1 -1
  21. package/dist/esm/extractor/createExtractor.js +24 -11
  22. package/dist/esm/extractor/createExtractor.js.map +1 -1
  23. package/dist/esm/extractor/createExtractor.mjs +16 -12
  24. package/dist/esm/extractor/createExtractor.native.js +18 -11
  25. package/dist/esm/extractor/createExtractor.native.js.map +2 -2
  26. package/dist/esm/extractor/extractMediaStyle.js +2 -2
  27. package/dist/esm/extractor/extractMediaStyle.js.map +1 -1
  28. package/dist/esm/extractor/extractMediaStyle.mjs +2 -2
  29. package/dist/esm/extractor/extractMediaStyle.native.js +2 -2
  30. package/dist/esm/extractor/extractMediaStyle.native.js.map +2 -2
  31. package/dist/esm/extractor/extractToClassNames.js +16 -15
  32. package/dist/esm/extractor/extractToClassNames.js.map +1 -1
  33. package/dist/esm/extractor/extractToClassNames.mjs +14 -16
  34. package/dist/esm/extractor/extractToClassNames.native.js +11 -14
  35. package/dist/esm/extractor/extractToClassNames.native.js.map +2 -2
  36. package/dist/esm/extractor/extractToNative.js +309 -0
  37. package/dist/esm/extractor/extractToNative.js.map +6 -0
  38. package/dist/esm/extractor/extractToNative.mjs +232 -0
  39. package/dist/esm/extractor/extractToNative.native.js +329 -0
  40. package/dist/esm/extractor/extractToNative.native.js.map +6 -0
  41. package/dist/esm/index.js +1 -0
  42. package/dist/esm/index.js.map +1 -1
  43. package/dist/esm/index.mjs +1 -0
  44. package/dist/esm/index.native.js +1 -0
  45. package/dist/esm/index.native.js.map +1 -1
  46. package/package.json +16 -15
  47. package/src/extractor/createExtractor.ts +23 -22
  48. package/src/extractor/extractMediaStyle.ts +2 -2
  49. package/src/extractor/extractToClassNames.ts +30 -16
  50. package/src/extractor/extractToNative.ts +504 -0
  51. package/src/index.ts +1 -0
  52. package/types/extractor/babelParse.d.ts +0 -1
  53. package/types/extractor/babelParse.d.ts.map +1 -1
  54. package/types/extractor/createEvaluator.d.ts.map +1 -1
  55. package/types/extractor/createExtractor.d.ts.map +1 -1
  56. package/types/extractor/extractToClassNames.d.ts +0 -1
  57. package/types/extractor/extractToClassNames.d.ts.map +1 -1
  58. package/types/extractor/extractToNative.d.ts +13 -0
  59. package/types/extractor/extractToNative.d.ts.map +1 -0
  60. package/types/extractor/getStaticBindingsForScope.d.ts.map +1 -1
  61. package/types/extractor/loadTamagui.d.ts.map +1 -1
  62. package/types/index.d.ts +1 -0
  63. package/types/index.d.ts.map +1 -1
@@ -0,0 +1,309 @@
1
+ import { basename } from "node:path";
2
+ import { transformFromAstSync } from "@babel/core";
3
+ import generator from "@babel/generator";
4
+ import { declare } from "@babel/helper-plugin-utils";
5
+ import { parse } from "@babel/parser";
6
+ import template from "@babel/template";
7
+ import * as t from "@babel/types";
8
+ import {
9
+ createExtractor,
10
+ createLogger,
11
+ getPragmaOptions,
12
+ isSimpleSpread,
13
+ literalToAst,
14
+ loadTamaguiBuildConfigSync
15
+ } from "@tamagui/static";
16
+ const importNativeView = template(`
17
+ const __ReactNativeView = require('react-native').View;
18
+ const __ReactNativeText = require('react-native').Text;
19
+ `), importStyleSheet = template(`
20
+ const __ReactNativeStyleSheet = require('react-native').StyleSheet;
21
+ `), importWithStyle = template(`
22
+ const __withStableStyle = require('@tamagui/core')._withStableStyle;
23
+ `), extractor = createExtractor({ platform: "native" });
24
+ let tamaguiBuildOptionsLoaded;
25
+ function extractToNative(sourceFileName, sourceCode, options) {
26
+ const ast = parse(sourceCode, {
27
+ sourceType: "module",
28
+ plugins: ["jsx", "typescript"]
29
+ }), babelPlugin = getBabelPlugin(), out = transformFromAstSync(ast, sourceCode, {
30
+ plugins: [[babelPlugin, options]],
31
+ configFile: !1,
32
+ sourceFileName,
33
+ filename: sourceFileName
34
+ });
35
+ if (!out)
36
+ throw new Error("No output returned");
37
+ return out;
38
+ }
39
+ function getBabelPlugin() {
40
+ return declare((api, options) => (api.assertVersion(7), getBabelParseDefinition(options)));
41
+ }
42
+ function getBabelParseDefinition(options) {
43
+ return {
44
+ name: "tamagui",
45
+ visitor: {
46
+ Program: {
47
+ enter(root) {
48
+ let sourcePath = this.file.opts.filename;
49
+ if (sourcePath?.includes("node_modules") || !sourcePath?.endsWith(".jsx") && !sourcePath?.endsWith(".tsx"))
50
+ return;
51
+ process.env.SOURCE_ROOT?.endsWith("ios") && (sourcePath = sourcePath.replace("/ios", ""));
52
+ let hasImportedView = !1, hasImportedViewWrapper = !1;
53
+ const sheetStyles = {}, sheetIdentifier = root.scope.generateUidIdentifier("sheet"), firstCommentContents = (
54
+ // join because you can join together multiple pragmas
55
+ root.node.body[0]?.leadingComments?.map((comment) => comment?.value || " ").join(" ") ?? ""
56
+ ), firstComment = firstCommentContents ? `//${firstCommentContents}` : "", { shouldPrintDebug, shouldDisable } = getPragmaOptions({
57
+ source: firstComment,
58
+ path: sourcePath
59
+ });
60
+ if (shouldDisable)
61
+ return;
62
+ !options.config && !options.components && (tamaguiBuildOptionsLoaded ||= loadTamaguiBuildConfigSync({}));
63
+ const finalOptions = {
64
+ // @ts-ignore just in case they leave it out
65
+ platform: "native",
66
+ ...tamaguiBuildOptionsLoaded,
67
+ ...options
68
+ }, printLog = createLogger(sourcePath, finalOptions);
69
+ function addSheetStyle(style, node) {
70
+ let key = `${`${Object.keys(sheetStyles).length}`}`;
71
+ if (process.env.NODE_ENV === "development") {
72
+ const lineNumbers = node.loc ? node.loc.start.line + (node.loc.start.line !== node.loc.end.line ? `-${node.loc.end.line}` : "") : "";
73
+ key += `:${basename(sourcePath)}:${lineNumbers}`;
74
+ }
75
+ return sheetStyles[key] = style, readStyleExpr(key);
76
+ }
77
+ function readStyleExpr(key) {
78
+ return template("SHEET['KEY']")({
79
+ SHEET: sheetIdentifier.name,
80
+ KEY: key
81
+ }).expression;
82
+ }
83
+ let res;
84
+ try {
85
+ res = extractor.parseSync(root, {
86
+ importsWhitelist: ["constants.js", "colors.js"],
87
+ extractStyledDefinitions: options.forceExtractStyleDefinitions,
88
+ excludeProps: /* @__PURE__ */ new Set([
89
+ "className",
90
+ "userSelect",
91
+ "whiteSpace",
92
+ "textOverflow",
93
+ "cursor",
94
+ "contain"
95
+ ]),
96
+ shouldPrintDebug,
97
+ ...finalOptions,
98
+ // disable this extraction for now at least, need to figure out merging theme vs non-theme
99
+ // because theme need to stay in render(), whereas non-theme can be extracted
100
+ // for now just turn it off entirely at a small perf loss
101
+ disableExtractInlineMedia: !0,
102
+ // disable extracting variables as no native concept of them (only theme values)
103
+ disableExtractVariables: options.experimentalFlattenThemesOnNative ? !1 : "theme",
104
+ sourcePath,
105
+ // disabling flattening for now
106
+ // it's flattening a plain <Paragraph>hello</Paragraph> which breaks things because themes
107
+ // thinking it's not really worth the effort to do much compilation on native
108
+ // for now just disable flatten as it can only run in narrow places on native
109
+ // disableFlattening: 'styled',
110
+ getFlattenedNode({ isTextView }) {
111
+ return hasImportedView || (hasImportedView = !0, root.unshiftContainer("body", importNativeView())), isTextView ? "__ReactNativeText" : "__ReactNativeView";
112
+ },
113
+ onExtractTag(props) {
114
+ const { isFlattened } = props;
115
+ if (!isFlattened)
116
+ return;
117
+ assertValidTag(props.node);
118
+ const stylesExpr = t.arrayExpression([]), hocStylesExpr = t.arrayExpression([]), expressions = [], finalAttrs = [], themeKeysUsed = /* @__PURE__ */ new Set();
119
+ function getStyleExpression(style) {
120
+ if (!style) return;
121
+ const { plain, themed } = splitThemeStyles(style);
122
+ let themeExpr = null;
123
+ if (themed && options.experimentalFlattenThemesOnNative) {
124
+ for (const key in themed)
125
+ themeKeysUsed.add(themed[key].split("$")[1]);
126
+ themeExpr = getThemedStyleExpression(themed);
127
+ }
128
+ const ident = addSheetStyle(plain, props.node);
129
+ return themeExpr ? (addStyleExpression(ident), addStyleExpression(ident, !0), themeExpr) : ident;
130
+ }
131
+ function addStyleExpression(expr, HOC = !1) {
132
+ Array.isArray(expr) ? (HOC ? hocStylesExpr : stylesExpr).elements.push(...expr) : (HOC ? hocStylesExpr : stylesExpr).elements.push(expr);
133
+ }
134
+ function getThemedStyleExpression(styles) {
135
+ const themedStylesAst = literalToAst(styles);
136
+ return themedStylesAst.properties.forEach((_) => {
137
+ const prop = _;
138
+ prop.value.type === "StringLiteral" && (prop.value = t.memberExpression(
139
+ t.identifier("theme"),
140
+ t.identifier(prop.value.value.slice(1) + ".get()")
141
+ ));
142
+ }), themedStylesAst;
143
+ }
144
+ let hasDynamicStyle = !1;
145
+ for (const attr of props.attrs)
146
+ switch (attr.type) {
147
+ case "style": {
148
+ let styleExpr = getStyleExpression(attr.value);
149
+ addStyleExpression(styleExpr), options.experimentalFlattenThemesOnNative && addStyleExpression(styleExpr, !0);
150
+ break;
151
+ }
152
+ case "ternary": {
153
+ const { consequent, alternate } = attr.value, consExpr = getStyleExpression(consequent), altExpr = getStyleExpression(alternate);
154
+ options.experimentalFlattenThemesOnNative && (expressions.push(attr.value.test), addStyleExpression(
155
+ t.conditionalExpression(
156
+ t.identifier(`_expressions[${expressions.length - 1}]`),
157
+ consExpr || t.nullLiteral(),
158
+ altExpr || t.nullLiteral()
159
+ ),
160
+ !0
161
+ ));
162
+ const styleExpr = t.conditionalExpression(
163
+ attr.value.test,
164
+ consExpr || t.nullLiteral(),
165
+ altExpr || t.nullLiteral()
166
+ );
167
+ addStyleExpression(
168
+ styleExpr
169
+ // TODO: what is this for ?
170
+ // isFlattened ? simpleHash(JSON.stringify({ consequent, alternate })) : undefined
171
+ );
172
+ break;
173
+ }
174
+ case "dynamic-style": {
175
+ hasDynamicStyle = !0, expressions.push(attr.value), options.experimentalFlattenDynamicValues ? addStyleExpression(
176
+ t.objectExpression([
177
+ t.objectProperty(
178
+ t.identifier(attr.name),
179
+ t.identifier(`_expressions[${expressions.length - 1}]`)
180
+ )
181
+ ]),
182
+ !0
183
+ ) : addStyleExpression(
184
+ t.objectExpression([
185
+ t.objectProperty(
186
+ t.identifier(attr.name),
187
+ attr.value
188
+ )
189
+ ])
190
+ );
191
+ break;
192
+ }
193
+ case "attr": {
194
+ t.isJSXSpreadAttribute(attr.value) && isSimpleSpread(attr.value) && (stylesExpr.elements.push(
195
+ t.memberExpression(attr.value.argument, t.identifier("style"))
196
+ ), options.experimentalFlattenThemesOnNative && hocStylesExpr.elements.push(
197
+ t.memberExpression(
198
+ attr.value.argument,
199
+ t.identifier("style")
200
+ )
201
+ )), finalAttrs.push(attr.value);
202
+ break;
203
+ }
204
+ }
205
+ if (props.node.attributes = finalAttrs, props.isFlattened)
206
+ if (options.experimentalFlattenThemesOnNative && (themeKeysUsed.size || hocStylesExpr.elements.length > 1 || hasDynamicStyle)) {
207
+ hasImportedViewWrapper || (root.unshiftContainer("body", importWithStyle()), hasImportedViewWrapper = !0);
208
+ const name = props.node.name.name, WrapperIdentifier = root.scope.generateUidIdentifier(
209
+ name + "Wrapper"
210
+ );
211
+ root.pushContainer(
212
+ "body",
213
+ t.variableDeclaration("const", [
214
+ t.variableDeclarator(
215
+ WrapperIdentifier,
216
+ t.callExpression(t.identifier("__withStableStyle"), [
217
+ t.identifier(name),
218
+ t.arrowFunctionExpression(
219
+ [t.identifier("theme"), t.identifier("_expressions")],
220
+ t.blockStatement([
221
+ t.returnStatement(
222
+ t.callExpression(
223
+ t.memberExpression(
224
+ t.identifier("React"),
225
+ t.identifier("useMemo")
226
+ ),
227
+ [
228
+ t.arrowFunctionExpression(
229
+ [],
230
+ t.blockStatement([
231
+ t.returnStatement(
232
+ t.arrayExpression([...hocStylesExpr.elements])
233
+ )
234
+ ])
235
+ ),
236
+ t.arrayExpression([
237
+ t.spreadElement(t.identifier("_expressions"))
238
+ ])
239
+ ]
240
+ )
241
+ )
242
+ ])
243
+ )
244
+ ])
245
+ )
246
+ ])
247
+ ), props.node.name = WrapperIdentifier, props.jsxPath.node.closingElement && (props.jsxPath.node.closingElement.name = WrapperIdentifier), expressions.length && props.node.attributes.push(
248
+ t.jsxAttribute(
249
+ t.jsxIdentifier("expressions"),
250
+ t.jsxExpressionContainer(t.arrayExpression(expressions))
251
+ )
252
+ );
253
+ } else
254
+ props.node.attributes.push(
255
+ t.jsxAttribute(
256
+ t.jsxIdentifier("style"),
257
+ t.jsxExpressionContainer(
258
+ stylesExpr.elements.length === 1 ? stylesExpr.elements[0] : stylesExpr
259
+ )
260
+ )
261
+ );
262
+ }
263
+ });
264
+ } catch (err) {
265
+ if (err instanceof Error) {
266
+ let message = `${shouldPrintDebug === "verbose" ? err : err.message}`;
267
+ message.includes("Unexpected return value from visitor method") && (message = "Unexpected return value from visitor method"), console.warn("Error in Tamagui parse, skipping", message, err.stack);
268
+ return;
269
+ }
270
+ }
271
+ if (!Object.keys(sheetStyles).length) {
272
+ shouldPrintDebug && console.info("END no styles"), res && printLog(res);
273
+ return;
274
+ }
275
+ const sheetObject = literalToAst(sheetStyles), sheetOuter = template(
276
+ "const SHEET = __ReactNativeStyleSheet.create(null)"
277
+ )({
278
+ SHEET: sheetIdentifier.name
279
+ });
280
+ sheetOuter.declarations[0].init.arguments[0] = sheetObject, root.unshiftContainer("body", sheetOuter), root.unshiftContainer("body", importStyleSheet()), shouldPrintDebug && (console.info(`
281
+ -------- output code -------
282
+ `), console.info(
283
+ generator(root.parent).code.split(`
284
+ `).filter((x) => !x.startsWith("//")).join(`
285
+ `)
286
+ )), res && printLog(res);
287
+ }
288
+ }
289
+ }
290
+ };
291
+ }
292
+ function assertValidTag(node) {
293
+ node.attributes.find((x) => x.type === "JSXAttribute" && x.name.name === "style") && process.env.DEBUG?.startsWith("tamagui") && console.warn("\u26A0\uFE0F Cannot pass style attribute to extracted style");
294
+ }
295
+ function splitThemeStyles(style) {
296
+ const themed = {}, plain = {};
297
+ let noTheme = !0;
298
+ for (const key in style) {
299
+ const val = style[key];
300
+ val && val[0] === "$" ? (themed[key] = val, noTheme = !1) : plain[key] = val;
301
+ }
302
+ return { themed: noTheme ? null : themed, plain };
303
+ }
304
+ export {
305
+ extractToNative,
306
+ getBabelParseDefinition,
307
+ getBabelPlugin
308
+ };
309
+ //# sourceMappingURL=extractToNative.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/extractor/extractToNative.ts"],
4
+ "mappings": "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",
5
+ "names": []
6
+ }
@@ -0,0 +1,232 @@
1
+ import { basename } from "node:path";
2
+ import { transformFromAstSync } from "@babel/core";
3
+ import generator from "@babel/generator";
4
+ import { declare } from "@babel/helper-plugin-utils";
5
+ import { parse } from "@babel/parser";
6
+ import template from "@babel/template";
7
+ import * as t from "@babel/types";
8
+ import { createExtractor, createLogger, getPragmaOptions, isSimpleSpread, literalToAst, loadTamaguiBuildConfigSync } from "@tamagui/static";
9
+ const importNativeView = template(`
10
+ const __ReactNativeView = require('react-native').View;
11
+ const __ReactNativeText = require('react-native').Text;
12
+ `),
13
+ importStyleSheet = template(`
14
+ const __ReactNativeStyleSheet = require('react-native').StyleSheet;
15
+ `),
16
+ importWithStyle = template(`
17
+ const __withStableStyle = require('@tamagui/core')._withStableStyle;
18
+ `),
19
+ extractor = createExtractor({
20
+ platform: "native"
21
+ });
22
+ let tamaguiBuildOptionsLoaded;
23
+ function extractToNative(sourceFileName, sourceCode, options) {
24
+ const ast = parse(sourceCode, {
25
+ sourceType: "module",
26
+ plugins: ["jsx", "typescript"]
27
+ }),
28
+ babelPlugin = getBabelPlugin(),
29
+ out = transformFromAstSync(ast, sourceCode, {
30
+ plugins: [[babelPlugin, options]],
31
+ configFile: !1,
32
+ sourceFileName,
33
+ filename: sourceFileName
34
+ });
35
+ if (!out) throw new Error("No output returned");
36
+ return out;
37
+ }
38
+ function getBabelPlugin() {
39
+ return declare((api, options) => (api.assertVersion(7), getBabelParseDefinition(options)));
40
+ }
41
+ function getBabelParseDefinition(options) {
42
+ return {
43
+ name: "tamagui",
44
+ visitor: {
45
+ Program: {
46
+ enter(root) {
47
+ let sourcePath = this.file.opts.filename;
48
+ if (sourcePath?.includes("node_modules") || !sourcePath?.endsWith(".jsx") && !sourcePath?.endsWith(".tsx")) return;
49
+ process.env.SOURCE_ROOT?.endsWith("ios") && (sourcePath = sourcePath.replace("/ios", ""));
50
+ let hasImportedView = !1,
51
+ hasImportedViewWrapper = !1;
52
+ const sheetStyles = {},
53
+ sheetIdentifier = root.scope.generateUidIdentifier("sheet"),
54
+ firstCommentContents =
55
+ // join because you can join together multiple pragmas
56
+ root.node.body[0]?.leadingComments?.map(comment => comment?.value || " ").join(" ") ?? "",
57
+ firstComment = firstCommentContents ? `//${firstCommentContents}` : "",
58
+ {
59
+ shouldPrintDebug,
60
+ shouldDisable
61
+ } = getPragmaOptions({
62
+ source: firstComment,
63
+ path: sourcePath
64
+ });
65
+ if (shouldDisable) return;
66
+ !options.config && !options.components && (tamaguiBuildOptionsLoaded ||= loadTamaguiBuildConfigSync({}));
67
+ const finalOptions = {
68
+ // @ts-ignore just in case they leave it out
69
+ platform: "native",
70
+ ...tamaguiBuildOptionsLoaded,
71
+ ...options
72
+ },
73
+ printLog = createLogger(sourcePath, finalOptions);
74
+ function addSheetStyle(style, node) {
75
+ let key = `${`${Object.keys(sheetStyles).length}`}`;
76
+ if (process.env.NODE_ENV === "development") {
77
+ const lineNumbers = node.loc ? node.loc.start.line + (node.loc.start.line !== node.loc.end.line ? `-${node.loc.end.line}` : "") : "";
78
+ key += `:${basename(sourcePath)}:${lineNumbers}`;
79
+ }
80
+ return sheetStyles[key] = style, readStyleExpr(key);
81
+ }
82
+ function readStyleExpr(key) {
83
+ return template("SHEET['KEY']")({
84
+ SHEET: sheetIdentifier.name,
85
+ KEY: key
86
+ }).expression;
87
+ }
88
+ let res;
89
+ try {
90
+ res = extractor.parseSync(root, {
91
+ importsWhitelist: ["constants.js", "colors.js"],
92
+ extractStyledDefinitions: options.forceExtractStyleDefinitions,
93
+ excludeProps: /* @__PURE__ */new Set(["className", "userSelect", "whiteSpace", "textOverflow", "cursor", "contain"]),
94
+ shouldPrintDebug,
95
+ ...finalOptions,
96
+ // disable this extraction for now at least, need to figure out merging theme vs non-theme
97
+ // because theme need to stay in render(), whereas non-theme can be extracted
98
+ // for now just turn it off entirely at a small perf loss
99
+ disableExtractInlineMedia: !0,
100
+ // disable extracting variables as no native concept of them (only theme values)
101
+ disableExtractVariables: options.experimentalFlattenThemesOnNative ? !1 : "theme",
102
+ sourcePath,
103
+ // disabling flattening for now
104
+ // it's flattening a plain <Paragraph>hello</Paragraph> which breaks things because themes
105
+ // thinking it's not really worth the effort to do much compilation on native
106
+ // for now just disable flatten as it can only run in narrow places on native
107
+ // disableFlattening: 'styled',
108
+ getFlattenedNode({
109
+ isTextView
110
+ }) {
111
+ return hasImportedView || (hasImportedView = !0, root.unshiftContainer("body", importNativeView())), isTextView ? "__ReactNativeText" : "__ReactNativeView";
112
+ },
113
+ onExtractTag(props) {
114
+ const {
115
+ isFlattened
116
+ } = props;
117
+ if (!isFlattened) return;
118
+ assertValidTag(props.node);
119
+ const stylesExpr = t.arrayExpression([]),
120
+ hocStylesExpr = t.arrayExpression([]),
121
+ expressions = [],
122
+ finalAttrs = [],
123
+ themeKeysUsed = /* @__PURE__ */new Set();
124
+ function getStyleExpression(style) {
125
+ if (!style) return;
126
+ const {
127
+ plain,
128
+ themed
129
+ } = splitThemeStyles(style);
130
+ let themeExpr = null;
131
+ if (themed && options.experimentalFlattenThemesOnNative) {
132
+ for (const key in themed) themeKeysUsed.add(themed[key].split("$")[1]);
133
+ themeExpr = getThemedStyleExpression(themed);
134
+ }
135
+ const ident = addSheetStyle(plain, props.node);
136
+ return themeExpr ? (addStyleExpression(ident), addStyleExpression(ident, !0), themeExpr) : ident;
137
+ }
138
+ function addStyleExpression(expr, HOC = !1) {
139
+ Array.isArray(expr) ? (HOC ? hocStylesExpr : stylesExpr).elements.push(...expr) : (HOC ? hocStylesExpr : stylesExpr).elements.push(expr);
140
+ }
141
+ function getThemedStyleExpression(styles) {
142
+ const themedStylesAst = literalToAst(styles);
143
+ return themedStylesAst.properties.forEach(_ => {
144
+ const prop = _;
145
+ prop.value.type === "StringLiteral" && (prop.value = t.memberExpression(t.identifier("theme"), t.identifier(prop.value.value.slice(1) + ".get()")));
146
+ }), themedStylesAst;
147
+ }
148
+ let hasDynamicStyle = !1;
149
+ for (const attr of props.attrs) switch (attr.type) {
150
+ case "style":
151
+ {
152
+ let styleExpr = getStyleExpression(attr.value);
153
+ addStyleExpression(styleExpr), options.experimentalFlattenThemesOnNative && addStyleExpression(styleExpr, !0);
154
+ break;
155
+ }
156
+ case "ternary":
157
+ {
158
+ const {
159
+ consequent,
160
+ alternate
161
+ } = attr.value,
162
+ consExpr = getStyleExpression(consequent),
163
+ altExpr = getStyleExpression(alternate);
164
+ options.experimentalFlattenThemesOnNative && (expressions.push(attr.value.test), addStyleExpression(t.conditionalExpression(t.identifier(`_expressions[${expressions.length - 1}]`), consExpr || t.nullLiteral(), altExpr || t.nullLiteral()), !0));
165
+ const styleExpr = t.conditionalExpression(attr.value.test, consExpr || t.nullLiteral(), altExpr || t.nullLiteral());
166
+ addStyleExpression(styleExpr
167
+ // TODO: what is this for ?
168
+ // isFlattened ? simpleHash(JSON.stringify({ consequent, alternate })) : undefined
169
+ );
170
+ break;
171
+ }
172
+ case "dynamic-style":
173
+ {
174
+ hasDynamicStyle = !0, expressions.push(attr.value), options.experimentalFlattenDynamicValues ? addStyleExpression(t.objectExpression([t.objectProperty(t.identifier(attr.name), t.identifier(`_expressions[${expressions.length - 1}]`))]), !0) : addStyleExpression(t.objectExpression([t.objectProperty(t.identifier(attr.name), attr.value)]));
175
+ break;
176
+ }
177
+ case "attr":
178
+ {
179
+ t.isJSXSpreadAttribute(attr.value) && isSimpleSpread(attr.value) && (stylesExpr.elements.push(t.memberExpression(attr.value.argument, t.identifier("style"))), options.experimentalFlattenThemesOnNative && hocStylesExpr.elements.push(t.memberExpression(attr.value.argument, t.identifier("style")))), finalAttrs.push(attr.value);
180
+ break;
181
+ }
182
+ }
183
+ if (props.node.attributes = finalAttrs, props.isFlattened) if (options.experimentalFlattenThemesOnNative && (themeKeysUsed.size || hocStylesExpr.elements.length > 1 || hasDynamicStyle)) {
184
+ hasImportedViewWrapper || (root.unshiftContainer("body", importWithStyle()), hasImportedViewWrapper = !0);
185
+ const name = props.node.name.name,
186
+ WrapperIdentifier = root.scope.generateUidIdentifier(name + "Wrapper");
187
+ root.pushContainer("body", t.variableDeclaration("const", [t.variableDeclarator(WrapperIdentifier, t.callExpression(t.identifier("__withStableStyle"), [t.identifier(name), t.arrowFunctionExpression([t.identifier("theme"), t.identifier("_expressions")], t.blockStatement([t.returnStatement(t.callExpression(t.memberExpression(t.identifier("React"), t.identifier("useMemo")), [t.arrowFunctionExpression([], t.blockStatement([t.returnStatement(t.arrayExpression([...hocStylesExpr.elements]))])), t.arrayExpression([t.spreadElement(t.identifier("_expressions"))])]))]))]))])), props.node.name = WrapperIdentifier, props.jsxPath.node.closingElement && (props.jsxPath.node.closingElement.name = WrapperIdentifier), expressions.length && props.node.attributes.push(t.jsxAttribute(t.jsxIdentifier("expressions"), t.jsxExpressionContainer(t.arrayExpression(expressions))));
188
+ } else props.node.attributes.push(t.jsxAttribute(t.jsxIdentifier("style"), t.jsxExpressionContainer(stylesExpr.elements.length === 1 ? stylesExpr.elements[0] : stylesExpr)));
189
+ }
190
+ });
191
+ } catch (err) {
192
+ if (err instanceof Error) {
193
+ let message = `${shouldPrintDebug === "verbose" ? err : err.message}`;
194
+ message.includes("Unexpected return value from visitor method") && (message = "Unexpected return value from visitor method"), console.warn("Error in Tamagui parse, skipping", message, err.stack);
195
+ return;
196
+ }
197
+ }
198
+ if (!Object.keys(sheetStyles).length) {
199
+ shouldPrintDebug && console.info("END no styles"), res && printLog(res);
200
+ return;
201
+ }
202
+ const sheetObject = literalToAst(sheetStyles),
203
+ sheetOuter = template("const SHEET = __ReactNativeStyleSheet.create(null)")({
204
+ SHEET: sheetIdentifier.name
205
+ });
206
+ sheetOuter.declarations[0].init.arguments[0] = sheetObject, root.unshiftContainer("body", sheetOuter), root.unshiftContainer("body", importStyleSheet()), shouldPrintDebug && (console.info(`
207
+ -------- output code -------
208
+ `), console.info(generator(root.parent).code.split(`
209
+ `).filter(x => !x.startsWith("//")).join(`
210
+ `))), res && printLog(res);
211
+ }
212
+ }
213
+ }
214
+ };
215
+ }
216
+ function assertValidTag(node) {
217
+ node.attributes.find(x => x.type === "JSXAttribute" && x.name.name === "style") && process.env.DEBUG?.startsWith("tamagui") && console.warn("\u26A0\uFE0F Cannot pass style attribute to extracted style");
218
+ }
219
+ function splitThemeStyles(style) {
220
+ const themed = {},
221
+ plain = {};
222
+ let noTheme = !0;
223
+ for (const key in style) {
224
+ const val = style[key];
225
+ val && val[0] === "$" ? (themed[key] = val, noTheme = !1) : plain[key] = val;
226
+ }
227
+ return {
228
+ themed: noTheme ? null : themed,
229
+ plain
230
+ };
231
+ }
232
+ export { extractToNative, getBabelParseDefinition, getBabelPlugin };