@tamagui/static 1.88.13 → 1.89.0-1706308641099

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/dist/esm/constants.mjs +10 -0
  3. package/dist/esm/extractor/accessSafe.mjs +11 -0
  4. package/dist/esm/extractor/babelParse.mjs +18 -0
  5. package/dist/esm/extractor/buildClassName.mjs +26 -0
  6. package/dist/esm/extractor/bundle.mjs +94 -0
  7. package/dist/esm/extractor/bundleConfig.mjs +263 -0
  8. package/dist/esm/extractor/createEvaluator.mjs +34 -0
  9. package/dist/esm/extractor/createExtractor.mjs +952 -0
  10. package/dist/esm/extractor/ensureImportingConcat.mjs +13 -0
  11. package/dist/esm/extractor/esbuildAliasPlugin.mjs +20 -0
  12. package/dist/esm/extractor/evaluateAstNode.mjs +48 -0
  13. package/dist/esm/extractor/extractHelpers.mjs +72 -0
  14. package/dist/esm/extractor/extractMediaStyle.mjs +93 -0
  15. package/dist/esm/extractor/extractToClassNames.mjs +237 -0
  16. package/dist/esm/extractor/findTopmostFunction.mjs +10 -0
  17. package/dist/esm/extractor/generateTamaguiStudioConfig.mjs +108 -0
  18. package/dist/esm/extractor/generatedUid.mjs +12 -0
  19. package/dist/esm/extractor/getPrefixLogs.mjs +4 -0
  20. package/dist/esm/extractor/getPropValueFromAttributes.mjs +31 -0
  21. package/dist/esm/extractor/getSourceModule.mjs +33 -0
  22. package/dist/esm/extractor/getStaticBindingsForScope.mjs +112 -0
  23. package/dist/esm/extractor/getTamaguiConfigPathFromOptionsConfig.mjs +5 -0
  24. package/dist/esm/extractor/hoistClassNames.mjs +24 -0
  25. package/dist/esm/extractor/literalToAst.mjs +48 -0
  26. package/dist/esm/extractor/loadFile.mjs +11 -0
  27. package/dist/esm/extractor/loadTamagui.mjs +233 -0
  28. package/dist/esm/extractor/logLines.mjs +11 -0
  29. package/dist/esm/extractor/normalizeTernaries.mjs +33 -0
  30. package/dist/esm/extractor/propsToFontFamilyCache.mjs +12 -0
  31. package/dist/esm/extractor/removeUnusedHooks.mjs +41 -0
  32. package/dist/esm/extractor/timer.mjs +19 -0
  33. package/dist/esm/extractor/validHTMLAttributes.mjs +49 -0
  34. package/dist/esm/getPragmaOptions.mjs +19 -0
  35. package/dist/esm/helpers/memoize.mjs +13 -0
  36. package/dist/esm/helpers/requireTamaguiCore.mjs +5 -0
  37. package/dist/esm/index.mjs +3 -0
  38. package/dist/esm/minifyCSS.mjs +12 -0
  39. package/dist/esm/registerRequire.mjs +74 -0
  40. package/dist/esm/server.mjs +40 -0
  41. package/dist/esm/setup.mjs +1 -0
  42. package/dist/esm/static.mjs +10 -0
  43. package/dist/esm/types.mjs +0 -0
  44. package/dist/esm/webpackPlugin.mjs +7 -0
  45. package/package.json +15 -15
@@ -0,0 +1,952 @@
1
+ import { basename, relative } from "path";
2
+ import traverse from "@babel/traverse";
3
+ import * as t from "@babel/types";
4
+ import { Color, colorLog } from "@tamagui/cli-color";
5
+ import { createDOMProps } from "react-native-web-internals";
6
+ import { FAILED_EVAL } from "../constants.mjs";
7
+ import { requireTamaguiCore } from "../helpers/requireTamaguiCore.mjs";
8
+ import { createEvaluator, createSafeEvaluator } from "./createEvaluator.mjs";
9
+ import { evaluateAstNode } from "./evaluateAstNode.mjs";
10
+ import { attrStr, findComponentName, getValidComponent, getValidComponentsPaths, getValidImport, isPresent, isValidImport, objToStr } from "./extractHelpers.mjs";
11
+ import { findTopmostFunction } from "./findTopmostFunction.mjs";
12
+ import { cleanupBeforeExit, getStaticBindingsForScope } from "./getStaticBindingsForScope.mjs";
13
+ import { literalToAst } from "./literalToAst.mjs";
14
+ import { loadTamagui, loadTamaguiSync } from "./loadTamagui.mjs";
15
+ import { logLines } from "./logLines.mjs";
16
+ import { normalizeTernaries } from "./normalizeTernaries.mjs";
17
+ import { setPropsToFontFamily } from "./propsToFontFamilyCache.mjs";
18
+ import { removeUnusedHooks } from "./removeUnusedHooks.mjs";
19
+ import { timer } from "./timer.mjs";
20
+ import { validHTMLAttributes } from "./validHTMLAttributes.mjs";
21
+ const UNTOUCHED_PROPS = {
22
+ key: !0,
23
+ style: !0,
24
+ className: !0
25
+ },
26
+ validHooks = {
27
+ useMedia: !0,
28
+ useTheme: !0
29
+ },
30
+ createTernary = x => x;
31
+ let hasLoggedBaseInfo = !1;
32
+ function isFullyDisabled(props) {
33
+ return props.disableExtraction && props.disableDebugAttr;
34
+ }
35
+ function createExtractor({
36
+ logger = console,
37
+ platform = "web"
38
+ } = {
39
+ logger: console
40
+ }) {
41
+ const INLINE_EXTRACTABLE = {
42
+ ref: "ref",
43
+ key: "key",
44
+ ...(platform === "web" && {
45
+ onPress: "onClick",
46
+ onHoverIn: "onMouseEnter",
47
+ onHoverOut: "onMouseLeave",
48
+ onPressIn: "onMouseDown",
49
+ onPressOut: "onMouseUp"
50
+ })
51
+ },
52
+ componentState = {
53
+ focus: !1,
54
+ hover: !1,
55
+ unmounted: !0,
56
+ press: !1,
57
+ pressIn: !1
58
+ },
59
+ styleProps = {
60
+ resolveValues: "variable",
61
+ noClassNames: !1,
62
+ isAnimated: !1
63
+ },
64
+ shouldAddDebugProp =
65
+ // really basic disable this for next.js because it messes with ssr
66
+ !process.env.npm_package_dependencies_next && !0 && process.env.IDENTIFY_TAGS !== "false" && (process.env.NODE_ENV === "development" || process.env.DEBUG || process.env.IDENTIFY_TAGS);
67
+ let projectInfo = null;
68
+ function loadSync(props) {
69
+ return isFullyDisabled(props) ? null : projectInfo ||= loadTamaguiSync(props);
70
+ }
71
+ async function load(props) {
72
+ return isFullyDisabled(props) ? null : projectInfo ||= await loadTamagui(props);
73
+ }
74
+ return {
75
+ options: {
76
+ logger
77
+ },
78
+ cleanupBeforeExit,
79
+ loadTamagui: load,
80
+ loadTamaguiSync: loadSync,
81
+ getTamagui() {
82
+ return projectInfo?.tamaguiConfig;
83
+ },
84
+ parseSync: (f, props) => {
85
+ const projectInfo2 = loadSync(props);
86
+ return parseWithConfig(projectInfo2 || {}, f, props);
87
+ },
88
+ parse: async (f, props) => {
89
+ const projectInfo2 = await load(props);
90
+ return parseWithConfig(projectInfo2 || {}, f, props);
91
+ }
92
+ };
93
+ function parseWithConfig({
94
+ components,
95
+ tamaguiConfig
96
+ }, fileOrPath, options) {
97
+ const {
98
+ config = "tamagui.config.ts",
99
+ importsWhitelist = ["constants.js"],
100
+ evaluateVars = !0,
101
+ sourcePath = "",
102
+ onExtractTag,
103
+ onStyleRule,
104
+ getFlattenedNode,
105
+ disable,
106
+ disableExtraction,
107
+ disableExtractInlineMedia,
108
+ disableExtractVariables,
109
+ disableDebugAttr,
110
+ enableDynamicEvaluation = !1,
111
+ includeExtensions = [".ts", ".tsx", ".jsx"],
112
+ extractStyledDefinitions = !1,
113
+ prefixLogs,
114
+ excludeProps,
115
+ platform: platform2,
116
+ ...restProps
117
+ } = options;
118
+ if (sourcePath.includes(".tamagui-dynamic-eval")) return null;
119
+ const {
120
+ normalizeStyle,
121
+ getSplitStyles,
122
+ mediaQueryConfig,
123
+ propMapper,
124
+ proxyThemeVariables,
125
+ pseudoDescriptors
126
+ } = requireTamaguiCore(platform2);
127
+ let shouldPrintDebug = options.shouldPrintDebug || !1;
128
+ if (disable === !0 || Array.isArray(disable) && disable.includes(sourcePath)) return null;
129
+ if (!isFullyDisabled(options) && !components) throw new Error("Must provide components");
130
+ if (sourcePath && includeExtensions && !includeExtensions.some(ext => sourcePath.endsWith(ext))) return shouldPrintDebug && logger.info(`Ignoring file due to includeExtensions: ${sourcePath}, includeExtensions: ${includeExtensions.join(", ")}`), null;
131
+ function isValidStyleKey(name, staticConfig) {
132
+ if (!projectInfo) throw new Error("Tamagui extractor not loaded yet");
133
+ return platform2 === "native" && name[0] === "$" && mediaQueryConfig[name.slice(1)] ? !1 : !!(staticConfig.validStyles?.[name] || pseudoDescriptors[name] ||
134
+ // dont disable variants or else you lose many things flattening
135
+ staticConfig.variants?.[name] || projectInfo?.tamaguiConfig?.shorthands[name] || name[0] === "$" && mediaQueryConfig[name.slice(1)]);
136
+ }
137
+ const isTargetingHTML = platform2 === "web",
138
+ ogDebug = shouldPrintDebug,
139
+ tm = timer(),
140
+ propsWithFileInfo = {
141
+ ...options,
142
+ sourcePath,
143
+ allLoadedComponents: components ? [...components] : []
144
+ };
145
+ hasLoggedBaseInfo || (hasLoggedBaseInfo = !0, shouldPrintDebug && logger.info(["loaded components:", propsWithFileInfo.allLoadedComponents.map(comp => Object.keys(comp.nameToInfo).join(", ")).join(", ")].join(" ")), process.env.DEBUG?.startsWith("tamagui") && logger.info(["loaded:", propsWithFileInfo.allLoadedComponents.map(x => x.moduleName)].join(`
146
+ `))), tm.mark("load-tamagui", !!shouldPrintDebug), isFullyDisabled(options) || tamaguiConfig?.themes || (console.error('\u26D4\uFE0F Error: Missing "themes" in your tamagui.config file, this may be due to duplicated dependency versions. Try out https://github.com/bmish/check-dependency-version-consistency to see if there are mis-matches, or search your lockfile.'), console.info(" Got config:", tamaguiConfig), process.exit(0));
147
+ const firstThemeName = Object.keys(tamaguiConfig?.themes || {})[0],
148
+ firstTheme = tamaguiConfig?.themes[firstThemeName] || {};
149
+ (!firstTheme || typeof firstTheme != "object") && (console.error("Missing theme, an error occurred when importing your config"), console.info("Got config:", tamaguiConfig), console.info("Looking for theme:", firstThemeName), process.exit(0));
150
+ const proxiedTheme = proxyThemeVariables(firstTheme),
151
+ themeAccessListeners = /* @__PURE__ */new Set(),
152
+ defaultTheme = new Proxy(proxiedTheme, {
153
+ get(target, key) {
154
+ return Reflect.has(target, key) && themeAccessListeners.forEach(cb => cb(String(key))), Reflect.get(target, key);
155
+ }
156
+ }),
157
+ body = fileOrPath.type === "Program" ? fileOrPath.get("body") : fileOrPath.program.body;
158
+ isFullyDisabled(options) || Object.keys(components || []).length === 0 && (console.warn("Warning: Tamagui didn't find any valid components (DEBUG=tamagui for more)"), process.env.DEBUG === "tamagui" && console.info("components", Object.keys(components || []), components)), shouldPrintDebug === "verbose" && (logger.info(`allLoadedComponent modules ${propsWithFileInfo.allLoadedComponents.map(k => k.moduleName).join(", ")}`), logger.info(`valid import paths: ${JSON.stringify(getValidComponentsPaths(propsWithFileInfo))}`));
159
+ let doesUseValidImport = !1,
160
+ hasImportedTheme = !1;
161
+ const importDeclarations = [];
162
+ for (const bodyPath of body) {
163
+ if (bodyPath.type !== "ImportDeclaration") continue;
164
+ const node = "node" in bodyPath ? bodyPath.node : bodyPath,
165
+ moduleName = node.source.value,
166
+ valid = isValidImport(propsWithFileInfo, moduleName);
167
+ if (valid && importDeclarations.push(node), shouldPrintDebug === "verbose" && logger.info(` - import ${moduleName} ${valid}`), extractStyledDefinitions && valid && node.specifiers.some(specifier => specifier.local.name === "styled")) {
168
+ doesUseValidImport = !0;
169
+ break;
170
+ }
171
+ if (valid) {
172
+ const names = node.specifiers.map(specifier => specifier.local.name),
173
+ isValidComponent = names.some(name => !!(isValidImport(propsWithFileInfo, moduleName, name) || validHooks[name]));
174
+ if (shouldPrintDebug === "verbose" && logger.info(` - import ${isValidComponent ? "\u2705" : "\u21E3"} - ${names.join(", ")} from '${moduleName}' - (valid: ${JSON.stringify(getValidComponentsPaths(propsWithFileInfo))})`), isValidComponent) {
175
+ doesUseValidImport = !0;
176
+ break;
177
+ }
178
+ }
179
+ }
180
+ if (shouldPrintDebug && logger.info(`${JSON.stringify({
181
+ doesUseValidImport,
182
+ hasImportedTheme
183
+ }, null, 2)}
184
+ `), !doesUseValidImport) return null;
185
+ function getValidImportedComponent(componentName) {
186
+ const importDeclaration = importDeclarations.find(dec => dec.specifiers.some(spec => spec.local.name === componentName));
187
+ return importDeclaration ? getValidImport(propsWithFileInfo, importDeclaration.source.value, componentName) : null;
188
+ }
189
+ tm.mark("import-check", !!shouldPrintDebug);
190
+ let couldntParse = !1;
191
+ const modifiedComponents = /* @__PURE__ */new Set(),
192
+ bindingCache = {},
193
+ callTraverse = a => fileOrPath.type === "File" ? traverse(fileOrPath, a) : fileOrPath.traverse(a),
194
+ shouldDisableExtraction = disableExtraction === !0 || Array.isArray(disableExtraction) && disableExtraction.includes(sourcePath);
195
+ let programPath = null;
196
+ const res = {
197
+ styled: 0,
198
+ flattened: 0,
199
+ optimized: 0,
200
+ modified: 0,
201
+ found: 0
202
+ },
203
+ version = `${Math.random()}`;
204
+ if (callTraverse({
205
+ // @ts-ignore
206
+ Program: {
207
+ enter(path) {
208
+ programPath = path;
209
+ }
210
+ },
211
+ // styled() calls
212
+ CallExpression(path) {
213
+ if (disable || shouldDisableExtraction || extractStyledDefinitions === !1 || !t.isIdentifier(path.node.callee) || path.node.callee.name !== "styled") return;
214
+ const variableName = t.isVariableDeclarator(path.parent) && t.isIdentifier(path.parent.id) ? path.parent.id.name : "unknown",
215
+ parentNode = path.node.arguments[0];
216
+ if (!t.isIdentifier(parentNode)) return;
217
+ const parentName = parentNode.name,
218
+ definition = path.node.arguments[1];
219
+ if (!parentName || !definition || !t.isObjectExpression(definition)) return;
220
+ let Component = getValidImportedComponent(variableName);
221
+ if (!Component) {
222
+ if (enableDynamicEvaluation !== !0) return;
223
+ try {
224
+ shouldPrintDebug && logger.info(`Unknown component: ${variableName} = styled(${parentName}) attempting dynamic load: ${sourcePath}`);
225
+ const out2 = loadTamaguiSync({
226
+ forceExports: !0,
227
+ components: [sourcePath],
228
+ cacheKey: version
229
+ });
230
+ if (!out2?.components) {
231
+ shouldPrintDebug && logger.info(`Couldn't load, got ${out2}`);
232
+ return;
233
+ }
234
+ if (propsWithFileInfo.allLoadedComponents = [...propsWithFileInfo.allLoadedComponents, ...out2.components], Component = out2.components.flatMap(x => x.nameToInfo[variableName] ?? [])[0], !out2.cached) {
235
+ const foundNames = out2.components?.map(x => Object.keys(x.nameToInfo).join(", ")).join(", ").trim();
236
+ foundNames && colorLog(Color.FgYellow, ` | Tamagui found dynamic components: ${foundNames}`);
237
+ }
238
+ } catch {
239
+ shouldPrintDebug && logger.info(`skip optimize styled(${variableName}), unable to pre-process (DEBUG=tamagui for more)`);
240
+ }
241
+ }
242
+ if (!Component) {
243
+ shouldPrintDebug && logger.info(" No component found");
244
+ return;
245
+ }
246
+ const componentSkipProps = /* @__PURE__ */new Set([...(Component.staticConfig.inlineWhenUnflattened || []), ...(Component.staticConfig.inlineProps || []),
247
+ // for now skip variants, will return to them
248
+ "variants", "defaultVariants",
249
+ // skip fontFamily its basically a "variant", important for theme use to be value always
250
+ "fontFamily", "name", "focusStyle", "hoverStyle", "pressStyle"]),
251
+ skipped = /* @__PURE__ */new Set(),
252
+ styles = {},
253
+ staticNamespace = getStaticBindingsForScope(path.scope, importsWhitelist, sourcePath, bindingCache, shouldPrintDebug),
254
+ attemptEval = evaluateVars ? createEvaluator({
255
+ props: propsWithFileInfo,
256
+ staticNamespace,
257
+ sourcePath,
258
+ shouldPrintDebug
259
+ }) : evaluateAstNode,
260
+ attemptEvalSafe = createSafeEvaluator(attemptEval);
261
+ for (const property of definition.properties) {
262
+ if (!t.isObjectProperty(property) || !t.isIdentifier(property.key) || !isValidStyleKey(property.key.name, Component.staticConfig) ||
263
+ // TODO make pseudos and variants work
264
+ // skip pseudos
265
+ pseudoDescriptors[property.key.name] ||
266
+ // skip variants
267
+ Component.staticConfig.variants?.[property.key.name] || componentSkipProps.has(property.key.name)) {
268
+ skipped.add(property);
269
+ continue;
270
+ }
271
+ const out2 = attemptEvalSafe(property.value);
272
+ out2 === FAILED_EVAL ? skipped.add(property) : styles[property.key.name] = out2;
273
+ }
274
+ const out = getSplitStyles(styles, Component.staticConfig, defaultTheme, "", componentState, styleProps, void 0, void 0, void 0, shouldPrintDebug),
275
+ classNames = {
276
+ ...out.classNames
277
+ };
278
+ if (shouldPrintDebug && logger.info([`Extracted styled(${variableName})
279
+ `, JSON.stringify(styles, null, 2), `
280
+ classNames:`, JSON.stringify(classNames, null, 2), `
281
+ rulesToInsert:`, out.rulesToInsert.flatMap(rule => rule.rules).join(`
282
+ `)].join(" ")), definition.properties = definition.properties.map(prop => {
283
+ if (skipped.has(prop) || !t.isObjectProperty(prop) || !t.isIdentifier(prop.key)) return prop;
284
+ const key = prop.key.name,
285
+ value = classNames[key];
286
+ return value ? t.objectProperty(t.stringLiteral(key), t.stringLiteral(value)) : prop;
287
+ }), out.rulesToInsert) for (const {
288
+ identifier,
289
+ rules
290
+ } of out.rulesToInsert) onStyleRule?.(identifier, rules);
291
+ res.styled++, shouldPrintDebug && logger.info(`Extracted styled(${variableName})`);
292
+ },
293
+ JSXElement(traversePath) {
294
+ tm.mark("jsx-element", !!shouldPrintDebug);
295
+ const node = traversePath.node.openingElement,
296
+ ogAttributes = node.attributes.map(attr => ({
297
+ ...attr
298
+ })),
299
+ componentName = findComponentName(traversePath.scope),
300
+ closingElement = traversePath.node.closingElement;
301
+ if (shouldPrintDebug && logger.info(` start ${node.name}`), closingElement && t.isJSXMemberExpression(closingElement?.name) || !t.isJSXIdentifier(node.name)) {
302
+ shouldPrintDebug && logger.info(" skip non-identifier element");
303
+ return;
304
+ }
305
+ const binding = traversePath.scope.getBinding(node.name.name);
306
+ let moduleName = "";
307
+ if (binding && t.isImportDeclaration(binding.path.parent) && (moduleName = binding.path.parent.source.value, !isValidImport(propsWithFileInfo, moduleName, binding.identifier.name))) {
308
+ shouldPrintDebug && logger.info(` - Binding for ${componentName} not internal import or from components ${binding.identifier.name} in ${moduleName}`);
309
+ return;
310
+ }
311
+ const component = getValidComponent(propsWithFileInfo, moduleName, node.name.name);
312
+ if (!component || !component.staticConfig) {
313
+ shouldPrintDebug && logger.info(` - No Tamagui conf on this: ${node.name.name}`);
314
+ return;
315
+ }
316
+ const originalNodeName = node.name.name;
317
+ res.found++;
318
+ const filePath = `./${relative(process.cwd(), sourcePath)}`,
319
+ lineNumbers = node.loc ? node.loc.start.line + (node.loc.start.line !== node.loc.end.line ? `-${node.loc.end.line}` : "") : "",
320
+ codePosition = `${filePath}:${lineNumbers}`,
321
+ debugPropValue = node.attributes.filter(n => t.isJSXAttribute(n) && t.isJSXIdentifier(n.name) && n.name.name === "debug").map(n => n.value === null ? !0 : t.isStringLiteral(n.value) ? n.value.value : !1)[0];
322
+ if (debugPropValue && (shouldPrintDebug = debugPropValue), shouldPrintDebug && (logger.info(`
323
+ `), logger.info(`\x1B[33m%s\x1B[0m ${componentName} | ${codePosition} -------------------`), logger.info(["\x1B[1m", "\x1B[32m", `<${originalNodeName} />`, disableDebugAttr ? "" : "\u{1F41B}"].join(" "))), shouldAddDebugProp && !disableDebugAttr && (res.modified++, node.attributes.unshift(t.jsxAttribute(t.jsxIdentifier("data-is"), t.stringLiteral(node.name.name))), componentName && node.attributes.unshift(t.jsxAttribute(t.jsxIdentifier("data-in"), t.stringLiteral(componentName))), node.attributes.unshift(t.jsxAttribute(t.jsxIdentifier("data-at"), t.stringLiteral(`${basename(filePath)}:${lineNumbers}`)))), shouldDisableExtraction) {
324
+ shouldPrintDebug === "verbose" && console.info(" Extraction disabled");
325
+ return;
326
+ }
327
+ try {
328
+ let evaluateAttribute = function (path) {
329
+ const attribute = path.node,
330
+ attr = {
331
+ type: "attr",
332
+ value: attribute
333
+ };
334
+ if (t.isJSXSpreadAttribute(attribute)) {
335
+ const arg = attribute.argument,
336
+ conditional = t.isConditionalExpression(arg) ?
337
+ // <YStack {...isSmall ? { color: 'red } : { color: 'blue }}
338
+ [arg.test, arg.consequent, arg.alternate] : t.isLogicalExpression(arg) && arg.operator === "&&" ?
339
+ // <YStack {...isSmall && { color: 'red }}
340
+ [arg.left, arg.right, null] : null;
341
+ if (conditional) {
342
+ const [test, alt, cons] = conditional;
343
+ if (!test) throw new Error("no test");
344
+ return [alt, cons].some(side => side && !isStaticObject(side)) ? (shouldPrintDebug && logger.info(`not extractable ${alt} ${cons}`), attr) : [...(createTernariesFromObjectProperties(test, alt) || []), ...(cons && createTernariesFromObjectProperties(t.unaryExpression("!", test), cons) || [])].map(ternary => ({
345
+ type: "ternary",
346
+ value: ternary
347
+ }));
348
+ }
349
+ }
350
+ if (t.isJSXSpreadAttribute(attribute) || !attribute.name || typeof attribute.name.name != "string") return shouldPrintDebug && logger.info(" ! inlining, spread attr"), inlined.set(`${Math.random()}`, "spread"), attr;
351
+ const name = attribute.name.name;
352
+ if (excludeProps?.has(name)) return shouldPrintDebug && logger.info([" excluding prop", name].join(" ")), null;
353
+ if (inlineProps.has(name)) return inlined.set(name, name), shouldPrintDebug && logger.info([" ! inlining, inline prop", name].join(" ")), attr;
354
+ if (UNTOUCHED_PROPS[name]) return attr;
355
+ if (INLINE_EXTRACTABLE[name]) return inlined.set(name, INLINE_EXTRACTABLE[name]), attr;
356
+ if (name.startsWith("data-")) return attr;
357
+ if (name[0] === "$" && t.isJSXExpressionContainer(attribute?.value)) {
358
+ const shortname = name.slice(1);
359
+ if (mediaQueryConfig[shortname]) {
360
+ if (platform2 === "native" && (shouldDeopt = !0), disableExtractInlineMedia) return attr;
361
+ const expression = attribute.value.expression;
362
+ if (!t.isJSXEmptyExpression(expression)) {
363
+ const ternaries2 = createTernariesFromObjectProperties(t.stringLiteral(shortname), expression, {
364
+ inlineMediaQuery: shortname
365
+ });
366
+ if (ternaries2) return ternaries2.map(value2 => ({
367
+ type: "ternary",
368
+ value: value2
369
+ }));
370
+ }
371
+ }
372
+ }
373
+ const [value, valuePath] = t.isJSXExpressionContainer(attribute?.value) ? [attribute.value.expression, path.get("value")] : [attribute.value, path.get("value")],
374
+ remove = () => {
375
+ Array.isArray(valuePath) ? valuePath.map(p => p.remove()) : valuePath.remove();
376
+ };
377
+ if (name === "ref") return shouldPrintDebug && logger.info([" ! inlining, ref", name].join(" ")), inlined.set("ref", "ref"), attr;
378
+ if (name === "tag") return {
379
+ type: "attr",
380
+ value: path.node
381
+ };
382
+ if (disableExtractVariables === !0 && value && value.type === "StringLiteral" && value.value[0] === "$") return shouldPrintDebug && logger.info([` ! inlining, native disable extract: ${name} =`, value.value].join(" ")), inlined.set(name, !0), attr;
383
+ if (name === "theme") return inlined.set("theme", attr.value), attr;
384
+ const styleValue = attemptEvalSafe(value);
385
+ if (!variants[name] && !isValidStyleKey(name, staticConfig)) {
386
+ let keys = [name],
387
+ out = null;
388
+ out = propMapper(name, styleValue, propMapperStyleState), out && (Array.isArray(out) ? (out = Object.fromEntries(out), keys = Object.keys(out)) : (logger.warn("Error expected array but got", out), couldntParse = !0, shouldDeopt = !0)), out && (isTargetingHTML && (out = createDOMProps(isTextView ? "span" : "div", out), delete out.className), keys = Object.keys(out));
389
+ let didInline = !1;
390
+ const attributes = keys.map(key => {
391
+ const val = out[key];
392
+ return isValidStyleKey(key, staticConfig) ? {
393
+ type: "style",
394
+ value: {
395
+ [key]: styleValue
396
+ },
397
+ name: key,
398
+ attr: path.node
399
+ } : validHTMLAttributes[key] || key.startsWith("aria-") || key.startsWith("data-") ||
400
+ // this is debug stuff added by vite / new jsx transform
401
+ key === "__source" || key === "__self" ? attr : (shouldPrintDebug && logger.info(" ! inlining, non-static " + key), didInline = !0, inlined.set(key, val), val);
402
+ });
403
+ return didInline ? (shouldPrintDebug && logger.info(` bailing flattening due to attributes ${attributes}`), attr) : attributes;
404
+ }
405
+ if (styleValue !== FAILED_EVAL) return inlineWhenUnflattened.has(name) && (inlineWhenUnflattenedOGVals[name] = {
406
+ styleValue,
407
+ attr
408
+ }), isValidStyleKey(name, staticConfig) ? (shouldPrintDebug && logger.info(` style: ${name} = ${styleValue}`), name in defaultProps || hasSetOptimized || (res.optimized++, hasSetOptimized = !0), {
409
+ type: "style",
410
+ value: {
411
+ [name]: styleValue
412
+ },
413
+ name,
414
+ attr: path.node
415
+ }) : (variants[name] && variantValues.set(name, styleValue), inlined.set(name, !0), attr);
416
+ if (t.isBinaryExpression(value)) {
417
+ shouldPrintDebug && logger.info(` binary expression ${name} = ${value}`);
418
+ const {
419
+ operator,
420
+ left,
421
+ right
422
+ } = value,
423
+ lVal = attemptEvalSafe(left),
424
+ rVal = attemptEvalSafe(right);
425
+ if (shouldPrintDebug && logger.info(` evalBinaryExpression lVal ${String(lVal)}, rVal ${String(rVal)}`), lVal !== FAILED_EVAL && t.isConditionalExpression(right)) {
426
+ const ternary = addBinaryConditional(operator, left, right);
427
+ if (ternary) return ternary;
428
+ }
429
+ if (rVal !== FAILED_EVAL && t.isConditionalExpression(left)) {
430
+ const ternary = addBinaryConditional(operator, right, left);
431
+ if (ternary) return ternary;
432
+ }
433
+ return shouldPrintDebug && logger.info(" evalBinaryExpression cant extract"), inlined.set(name, !0), attr;
434
+ }
435
+ const staticConditional = getStaticConditional(value);
436
+ if (staticConditional) return shouldPrintDebug === "verbose" && logger.info(` static conditional ${name} ${value}`), {
437
+ type: "ternary",
438
+ value: staticConditional
439
+ };
440
+ const staticLogical = getStaticLogical(value);
441
+ if (staticLogical) return shouldPrintDebug === "verbose" && logger.info(` static ternary ${name} = ${value}`), {
442
+ type: "ternary",
443
+ value: staticLogical
444
+ };
445
+ if (options.experimentalFlattenThemesOnNative && isValidStyleKey(name, staticConfig)) return {
446
+ type: "dynamic-style",
447
+ value,
448
+ name
449
+ };
450
+ return inlined.set(name, !0), shouldPrintDebug && logger.info(` ! inline no match ${name} ${value}`), attr;
451
+ function addBinaryConditional(operator, staticExpr, cond) {
452
+ if (getStaticConditional(cond)) {
453
+ const alt = attemptEval(t.binaryExpression(operator, staticExpr, cond.alternate)),
454
+ cons = attemptEval(t.binaryExpression(operator, staticExpr, cond.consequent));
455
+ return shouldPrintDebug && logger.info([" binaryConditional", cond.test, cons, alt].join(" ")), {
456
+ type: "ternary",
457
+ value: {
458
+ test: cond.test,
459
+ remove,
460
+ alternate: {
461
+ [name]: alt
462
+ },
463
+ consequent: {
464
+ [name]: cons
465
+ }
466
+ }
467
+ };
468
+ }
469
+ return null;
470
+ }
471
+ function getStaticConditional(value2) {
472
+ if (t.isConditionalExpression(value2)) try {
473
+ const aVal = attemptEval(value2.alternate),
474
+ cVal = attemptEval(value2.consequent);
475
+ if (shouldPrintDebug) {
476
+ const type = value2.test.type;
477
+ logger.info([" static ternary", type, cVal, aVal].join(" "));
478
+ }
479
+ return {
480
+ test: value2.test,
481
+ remove,
482
+ consequent: {
483
+ [name]: cVal
484
+ },
485
+ alternate: {
486
+ [name]: aVal
487
+ }
488
+ };
489
+ } catch (err) {
490
+ shouldPrintDebug && logger.info([" cant eval ternary", err.message].join(" "));
491
+ }
492
+ return null;
493
+ }
494
+ function getStaticLogical(value2) {
495
+ if (t.isLogicalExpression(value2) && value2.operator === "&&") try {
496
+ const val = attemptEval(value2.right);
497
+ return shouldPrintDebug && logger.info([" staticLogical", value2.left, name, val].join(" ")), {
498
+ test: value2.left,
499
+ remove,
500
+ consequent: {
501
+ [name]: val
502
+ },
503
+ alternate: null
504
+ };
505
+ } catch (err) {
506
+ shouldPrintDebug && logger.info([" cant static eval logical", err].join(" "));
507
+ }
508
+ return null;
509
+ }
510
+ },
511
+ isStaticObject = function (obj) {
512
+ return t.isObjectExpression(obj) && obj.properties.every(prop => {
513
+ if (!t.isObjectProperty(prop)) return logger.info(["not object prop", prop].join(" ")), !1;
514
+ const propName = prop.key.name;
515
+ return !isValidStyleKey(propName, staticConfig) && propName !== "tag" ? (shouldPrintDebug && logger.info([" not a valid style prop!", propName].join(" ")), !1) : !0;
516
+ });
517
+ },
518
+ createTernariesFromObjectProperties = function (test, side, ternaryPartial = {}) {
519
+ if (!side) return null;
520
+ if (!isStaticObject(side)) throw new Error("not extractable");
521
+ return side.properties.flatMap(property => {
522
+ if (!t.isObjectProperty(property)) throw new Error("expected object property");
523
+ if (t.isIdentifier(property.key)) {
524
+ const key = property.key.name,
525
+ mediaQueryKey = key.slice(1);
526
+ if (key[0] === "$" && mediaQueryConfig[mediaQueryKey]) if (t.isExpression(property.value)) {
527
+ const ternaries2 = createTernariesFromObjectProperties(t.stringLiteral(mediaQueryKey), property.value, {
528
+ inlineMediaQuery: mediaQueryKey
529
+ });
530
+ if (ternaries2) return ternaries2.map(value => ({
531
+ ...ternaryPartial,
532
+ ...value,
533
+ // ensure media query test stays on left side (see getMediaQueryTernary)
534
+ test: t.logicalExpression("&&", value.test, test)
535
+ }));
536
+ logger.info(["\u26A0\uFE0F no ternaries?", property].join(" "));
537
+ } else logger.info(["\u26A0\uFE0F not expression", property].join(" "));
538
+ }
539
+ if (t.isConditionalExpression(property.value)) {
540
+ const [truthy, falsy] = [t.objectExpression([t.objectProperty(property.key, property.value.consequent)]), t.objectExpression([t.objectProperty(property.key, property.value.alternate)])].map(x => attemptEval(x));
541
+ return [createTernary({
542
+ remove() {},
543
+ ...ternaryPartial,
544
+ test: t.logicalExpression("&&", test, property.value.test),
545
+ consequent: truthy,
546
+ alternate: null
547
+ }), createTernary({
548
+ ...ternaryPartial,
549
+ test: t.logicalExpression("&&", test, t.unaryExpression("!", property.value.test)),
550
+ consequent: falsy,
551
+ alternate: null,
552
+ remove() {}
553
+ })];
554
+ }
555
+ const obj = t.objectExpression([t.objectProperty(property.key, property.value)]),
556
+ consequent = attemptEval(obj);
557
+ return createTernary({
558
+ remove() {},
559
+ ...ternaryPartial,
560
+ test,
561
+ consequent,
562
+ alternate: null
563
+ });
564
+ });
565
+ },
566
+ mergeToEnd = function (obj, key, val) {
567
+ key in obj && delete obj[key], obj[key] = val;
568
+ },
569
+ normalizeStyleWithoutVariants = function (style) {
570
+ let res2 = {};
571
+ for (const key in style) if (staticConfig.variants && key in staticConfig.variants) mergeToEnd(res2, key, style[key]);else {
572
+ const expanded = normalizeStyle({
573
+ [key]: style[key]
574
+ }, !0);
575
+ for (const key2 in expanded) mergeToEnd(res2, key2, expanded[key2]);
576
+ }
577
+ return res2;
578
+ },
579
+ mergeStyles = function (prev2, next) {
580
+ for (const key in next) pseudoDescriptors[key] ? (prev2[key] = prev2[key] || {}, Object.assign(prev2[key], next[key])) : mergeToEnd(prev2, key, next[key]);
581
+ };
582
+ const {
583
+ staticConfig
584
+ } = component,
585
+ defaultProps = {
586
+ ...(staticConfig.defaultProps || {})
587
+ },
588
+ variants = staticConfig.variants || {},
589
+ isTextView = staticConfig.isText || !1,
590
+ validStyles = staticConfig?.validStyles ?? {};
591
+ let tagName = defaultProps.tag ?? (isTextView ? "span" : "div");
592
+ traversePath.get("openingElement").get("attributes").forEach(path => {
593
+ const attr = path.node;
594
+ if (t.isJSXSpreadAttribute(attr) || attr.name.name !== "tag") return;
595
+ const val = attr.value;
596
+ t.isStringLiteral(val) && (tagName = val.value);
597
+ }), shouldPrintDebug === "verbose" && console.info(` Start tag ${tagName}`);
598
+ const flatNode = getFlattenedNode?.({
599
+ isTextView,
600
+ tag: tagName
601
+ }),
602
+ inlineProps = /* @__PURE__ */new Set([
603
+ // adding some always inline props
604
+ "dataSet", ...(restProps.inlineProps || []), ...(staticConfig.inlineProps || [])]),
605
+ deoptProps = /* @__PURE__ */new Set([
606
+ // always de-opt animation these
607
+ "animation", "disableOptimization", ...(isTargetingHTML ? [] : ["pressStyle", "focusStyle"]),
608
+ // when using a non-CSS driver, de-opt on enterStyle/exitStyle
609
+ ...(tamaguiConfig?.animations.isReactNative ? ["enterStyle", "exitStyle"] : [])]),
610
+ inlineWhenUnflattened = /* @__PURE__ */new Set([...(staticConfig.inlineWhenUnflattened || [])]),
611
+ staticNamespace = getStaticBindingsForScope(traversePath.scope, importsWhitelist, sourcePath, bindingCache, shouldPrintDebug),
612
+ attemptEval = evaluateVars ? createEvaluator({
613
+ props: propsWithFileInfo,
614
+ staticNamespace,
615
+ sourcePath,
616
+ traversePath,
617
+ shouldPrintDebug
618
+ }) : evaluateAstNode,
619
+ attemptEvalSafe = createSafeEvaluator(attemptEval);
620
+ if (shouldPrintDebug && logger.info(` staticNamespace ${Object.keys(staticNamespace).join(", ")}`), couldntParse) return;
621
+ tm.mark("jsx-element-flattened", !!shouldPrintDebug);
622
+ let attrs = [],
623
+ shouldDeopt = !1;
624
+ const inlined = /* @__PURE__ */new Map(),
625
+ variantValues = /* @__PURE__ */new Map();
626
+ let hasSetOptimized = !1;
627
+ const inlineWhenUnflattenedOGVals = {},
628
+ propMapperStyleState = {
629
+ staticConfig,
630
+ usedKeys: {},
631
+ classNames: {},
632
+ style: {},
633
+ theme: defaultTheme,
634
+ viewProps: defaultProps,
635
+ conf: tamaguiConfig,
636
+ curProps: defaultProps,
637
+ props: defaultProps,
638
+ componentState,
639
+ styleProps: {
640
+ ...styleProps,
641
+ resolveValues: "auto"
642
+ },
643
+ debug: shouldPrintDebug
644
+ };
645
+ if (attrs = traversePath.get("openingElement").get("attributes").flatMap(path => {
646
+ try {
647
+ const res2 = evaluateAttribute(path);
648
+ return tm.mark("jsx-element-evaluate-attr", !!shouldPrintDebug), res2 || path.remove(), res2;
649
+ } catch (err) {
650
+ return shouldPrintDebug && (logger.info(["Recoverable error extracting attribute", err.message, shouldPrintDebug === "verbose" ? err.stack : ""].join(" ")), shouldPrintDebug === "verbose" && logger.info(`node ${path.node?.type}`)), inlined.set(`${Math.random()}`, "spread"), {
651
+ type: "attr",
652
+ value: path.node
653
+ };
654
+ }
655
+ }).flat(4).filter(isPresent), shouldPrintDebug && logger.info([` - attrs (before):
656
+ `, logLines(attrs.map(attrStr).join(", "))].join(" ")), couldntParse || shouldDeopt) {
657
+ shouldPrintDebug && logger.info([" avoid optimizing:", {
658
+ couldntParse,
659
+ shouldDeopt
660
+ }].join(" ")), node.attributes = ogAttributes;
661
+ return;
662
+ }
663
+ const parentFn = findTopmostFunction(traversePath);
664
+ parentFn && modifiedComponents.add(parentFn);
665
+ const hasSpread = attrs.some(x => x.type === "attr" && t.isJSXSpreadAttribute(x.value)),
666
+ hasOnlyStringChildren = !hasSpread && (node.selfClosing || traversePath.node.children && traversePath.node.children.every(x => x.type === "JSXText"));
667
+ let themeVal = inlined.get("theme");
668
+ platform2 !== "native" && inlined.delete("theme");
669
+ for (const [key] of [...inlined]) {
670
+ const isStaticObjectVariant = staticConfig.variants?.[key] && variantValues.has(key);
671
+ (INLINE_EXTRACTABLE[key] || isStaticObjectVariant) && inlined.delete(key);
672
+ }
673
+ const canFlattenProps = inlined.size === 0;
674
+ let shouldFlatten = !!(flatNode && !shouldDeopt && canFlattenProps && !hasSpread && !staticConfig.isStyledHOC && !staticConfig.isHOC && !staticConfig.isReactNative && staticConfig.neverFlatten !== !0 && (staticConfig.neverFlatten !== "jsx" || hasOnlyStringChildren));
675
+ const usedThemeKeys = /* @__PURE__ */new Set();
676
+ if (themeAccessListeners.add(key => {
677
+ options.experimentalFlattenThemesOnNative && usedThemeKeys.add(key), disableExtractVariables && (usedThemeKeys.add(key), shouldFlatten = !1, shouldPrintDebug === "verbose" && logger.info([" ! accessing theme key, avoid flatten", key].join(" ")));
678
+ }), shouldFlatten) {
679
+ let skipMap = !1;
680
+ const defaultStyleAttrs = Object.keys(defaultProps).flatMap(key => {
681
+ if (skipMap) return [];
682
+ const value = defaultProps[key];
683
+ if (key === "theme" && !themeVal) return platform2 === "native" && (shouldFlatten = !1, skipMap = !0, inlined.set("theme", {
684
+ value: t.stringLiteral(value)
685
+ })), themeVal = {
686
+ value: t.stringLiteral(value)
687
+ }, [];
688
+ if (!isValidStyleKey(key, staticConfig)) return [];
689
+ const name = tamaguiConfig?.shorthands[key] || key;
690
+ if (value === void 0) {
691
+ logger.warn(`\u26A0\uFE0F Error evaluating default style for component, prop ${key} ${value}`), shouldDeopt = !0;
692
+ return;
693
+ }
694
+ return name[0] === "$" && mediaQueryConfig[name.slice(1)] ? (defaultProps[key] = void 0, evaluateAttribute({
695
+ node: t.jsxAttribute(t.jsxIdentifier(name), t.jsxExpressionContainer(t.objectExpression(Object.keys(value).filter(k => typeof value[k] < "u").map(k => t.objectProperty(t.identifier(k), literalToAst(value[k]))))))
696
+ })) : {
697
+ type: "style",
698
+ name,
699
+ value: {
700
+ [name]: value
701
+ }
702
+ };
703
+ });
704
+ skipMap || defaultStyleAttrs.length && (attrs = [...defaultStyleAttrs, ...attrs]);
705
+ }
706
+ let ternaries = [];
707
+ attrs = attrs.reduce((out, cur) => {
708
+ const next = attrs[attrs.indexOf(cur) + 1];
709
+ if (cur.type === "ternary" && ternaries.push(cur.value), (!next || next.type !== "ternary") && ternaries.length) {
710
+ const normalized = normalizeTernaries(ternaries).map(({
711
+ alternate,
712
+ consequent,
713
+ ...rest
714
+ }) => ({
715
+ type: "ternary",
716
+ value: {
717
+ ...rest,
718
+ alternate: alternate || null,
719
+ consequent: consequent || null
720
+ }
721
+ }));
722
+ try {
723
+ return [...out, ...normalized];
724
+ } finally {
725
+ shouldPrintDebug && logger.info(` normalizeTernaries (${ternaries.length} => ${normalized.length})`), ternaries = [];
726
+ }
727
+ }
728
+ return cur.type === "ternary" || out.push(cur), out;
729
+ }, []).flat();
730
+ const shouldWrapTheme = shouldFlatten && themeVal;
731
+ if (shouldWrapTheme && (programPath ? (shouldPrintDebug && logger.info([" - wrapping theme", themeVal].join(" ")), attrs = attrs.filter(x => !(x.type === "attr" && t.isJSXAttribute(x.value) && x.value.name.name === "theme")), hasImportedTheme || (hasImportedTheme = !0, programPath.node.body.push(t.importDeclaration([t.importSpecifier(t.identifier("_TamaguiTheme"), t.identifier("Theme"))], t.stringLiteral("@tamagui/web")))), traversePath.replaceWith(t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier("_TamaguiTheme"), [t.jsxAttribute(t.jsxIdentifier("name"), themeVal.value)]), t.jsxClosingElement(t.jsxIdentifier("_TamaguiTheme")), [traversePath.node]))) : console.warn(`No program path found, avoiding importing flattening / importing theme in ${sourcePath}`)), shouldPrintDebug) try {
732
+ logger.info([" flatten?", shouldFlatten, objToStr({
733
+ hasSpread,
734
+ shouldDeopt,
735
+ canFlattenProps,
736
+ shouldWrapTheme,
737
+ hasOnlyStringChildren
738
+ }), "inlined", inlined.size, [...inlined]].join(" "));
739
+ } catch {}
740
+ if (shouldDeopt || !shouldFlatten) {
741
+ shouldPrintDebug && logger.info(`Deopting ${shouldDeopt} ${shouldFlatten}`), node.attributes = ogAttributes;
742
+ return;
743
+ }
744
+ shouldPrintDebug && logger.info([` - attrs (flattened):
745
+ `, logLines(attrs.map(attrStr).join(", "))].join(" "));
746
+ let foundStaticProps = {};
747
+ for (const key in attrs) {
748
+ const cur = attrs[key];
749
+ if (cur.type === "style") {
750
+ const expanded = normalizeStyleWithoutVariants(cur.value);
751
+ for (const key2 in expanded) mergeToEnd(foundStaticProps, key2, expanded[key2]);
752
+ continue;
753
+ }
754
+ if (cur.type === "attr") {
755
+ if (t.isJSXSpreadAttribute(cur.value) || !t.isJSXIdentifier(cur.value.name)) continue;
756
+ const key2 = cur.value.name.name,
757
+ value = attemptEvalSafe(cur.value.value || t.booleanLiteral(!0));
758
+ value !== FAILED_EVAL && mergeToEnd(foundStaticProps, key2, value);
759
+ }
760
+ }
761
+ const completeProps = {};
762
+ for (const key in defaultProps) key in foundStaticProps || (completeProps[key] = defaultProps[key]);
763
+ for (const key in foundStaticProps) completeProps[key] = foundStaticProps[key];
764
+ attrs = attrs.reduce((acc, cur) => {
765
+ if (!cur) return acc;
766
+ if (cur.type === "attr" && !t.isJSXSpreadAttribute(cur.value) && shouldFlatten) {
767
+ const name = cur.value.name.name;
768
+ if (typeof name == "string") {
769
+ if (name === "tag") return acc;
770
+ if (variants[name] && variantValues.has(name)) {
771
+ const styleState = {
772
+ ...propMapperStyleState,
773
+ props: completeProps,
774
+ curProps: completeProps
775
+ };
776
+ let out = Object.fromEntries(propMapper(name, variantValues.get(name), styleState) || []);
777
+ if (out && isTargetingHTML) {
778
+ const cn = out.className;
779
+ out = createDOMProps(isTextView ? "span" : "div", out), out.className = cn;
780
+ }
781
+ shouldPrintDebug && logger.info([" - expanded variant", name, out].join(" "));
782
+ for (const key2 in out) {
783
+ const value2 = out[key2];
784
+ isValidStyleKey(key2, staticConfig) ? acc.push({
785
+ type: "style",
786
+ value: {
787
+ [key2]: value2
788
+ },
789
+ name: key2,
790
+ attr: cur.value
791
+ }) : acc.push({
792
+ type: "attr",
793
+ value: t.jsxAttribute(t.jsxIdentifier(key2), t.jsxExpressionContainer(typeof value2 == "string" ? t.stringLiteral(value2) : literalToAst(value2)))
794
+ });
795
+ }
796
+ }
797
+ }
798
+ }
799
+ if (cur.type !== "style") return acc.push(cur), acc;
800
+ let key = Object.keys(cur.value)[0];
801
+ const value = cur.value[key],
802
+ fullKey = tamaguiConfig?.shorthands[key];
803
+ return fullKey && (cur.value = {
804
+ [fullKey]: value
805
+ }, key = fullKey), disableExtractVariables && value[0] === "$" && (usedThemeKeys.has(key) || usedThemeKeys.has(fullKey)) ? (shouldPrintDebug && logger.info([` keeping variable inline: ${key} =`, value].join(" ")), acc.push({
806
+ type: "attr",
807
+ value: t.jsxAttribute(t.jsxIdentifier(key), t.jsxExpressionContainer(t.stringLiteral(value)))
808
+ }), acc) : (acc.push(cur), acc);
809
+ }, []), tm.mark("jsx-element-expanded", !!shouldPrintDebug), shouldPrintDebug && logger.info([` - attrs (expanded):
810
+ `, logLines(attrs.map(attrStr).join(", "))].join(" "));
811
+ let prev = null;
812
+ const getProps = (props, includeProps = !1, debugName = "") => {
813
+ if (!props) return shouldPrintDebug && logger.info([" getProps() no props"].join(" ")), {};
814
+ if (excludeProps?.size) for (const key in props) excludeProps.has(key) && (shouldPrintDebug && logger.info([" delete excluded", key].join(" ")), delete props[key]);
815
+ try {
816
+ const out = getSplitStyles(props, staticConfig, defaultTheme, "", componentState, {
817
+ ...styleProps,
818
+ noClassNames: !0,
819
+ fallbackProps: completeProps
820
+ }, void 0, void 0, void 0, debugPropValue || shouldPrintDebug);
821
+ let outProps = {
822
+ ...(includeProps ? out.viewProps : {}),
823
+ ...out.style,
824
+ ...out.pseudos
825
+ };
826
+ for (const key in outProps) deoptProps.has(key) && (shouldFlatten = !1);
827
+ return options.experimentalFlattenThemesOnNative && usedThemeKeys.size > 0 && Object.entries(props).forEach(([key, value]) => {
828
+ usedThemeKeys.has(value) && (outProps[key] = value);
829
+ }), shouldPrintDebug && (logger.info(`(${debugName})`), logger.info(`
830
+ getProps (props in): ${logLines(objToStr(props))}`), logger.info(`
831
+ getProps (outProps): ${logLines(objToStr(outProps))}`)), out.fontFamily && (setPropsToFontFamily(outProps, out.fontFamily), shouldPrintDebug && logger.info(`
832
+ \u{1F4AC} new font fam: ${out.fontFamily}`)), outProps;
833
+ } catch (err) {
834
+ return logger.info(["error", err.message, err.stack].join(" ")), {};
835
+ }
836
+ };
837
+ shouldFlatten && attrs.unshift({
838
+ type: "style",
839
+ value: defaultProps
840
+ }), attrs = attrs.reduce((acc, cur) => {
841
+ if (cur.type === "style") {
842
+ const key = Object.keys(cur.value)[0],
843
+ value = cur.value[key];
844
+ if (
845
+ // !isStyleAndAttr[key] &&
846
+ !shouldFlatten &&
847
+ // de-opt if non-style
848
+ !validStyles[key] && !pseudoDescriptors[key] && !(key.startsWith("data-") || key.startsWith("aria-"))) return shouldPrintDebug && logger.info([" - keeping as non-style", key].join(" ")), prev = cur, acc.push({
849
+ type: "attr",
850
+ value: t.jsxAttribute(t.jsxIdentifier(key), t.jsxExpressionContainer(typeof value == "string" ? t.stringLiteral(value) : literalToAst(value)))
851
+ }), acc.push(cur), acc;
852
+ if (prev?.type === "style") return mergeStyles(prev.value, cur.value), acc;
853
+ }
854
+ return prev = cur, acc.push(cur), acc;
855
+ }, []), shouldPrintDebug && logger.info([` - attrs (combined \u{1F500}):
856
+ `, logLines(attrs.map(attrStr).join(", "))].join(" "));
857
+ let getStyleError = null;
858
+ for (const attr of attrs) try {
859
+ switch (shouldPrintDebug && console.info(` Processing ${attr.type}:`), attr.type) {
860
+ case "ternary":
861
+ {
862
+ const a = getProps(attr.value.alternate, !1, "ternary.alternate"),
863
+ c = getProps(attr.value.consequent, !1, "ternary.consequent");
864
+ a && (attr.value.alternate = a), c && (attr.value.consequent = c), shouldPrintDebug && logger.info([" => tern ", attrStr(attr)].join(" "));
865
+ continue;
866
+ }
867
+ case "style":
868
+ {
869
+ const styles = getProps(attr.value, !1, "style");
870
+ styles && (attr.value = styles), shouldPrintDebug && logger.info([" * styles (in)", logLines(objToStr(attr.value))].join(" ")), shouldPrintDebug && logger.info([" * styles (out)", logLines(objToStr(styles))].join(" "));
871
+ continue;
872
+ }
873
+ case "attr":
874
+ if (shouldFlatten && t.isJSXAttribute(attr.value)) {
875
+ const key = attr.value.name.name;
876
+ if (key === "style" || key === "className" || key === "tag") continue;
877
+ const value = attemptEvalSafe(attr.value.value || t.booleanLiteral(!0));
878
+ if (value !== FAILED_EVAL) {
879
+ const outProps = getProps({
880
+ [key]: value
881
+ }, !0, `attr.${key}`),
882
+ outKey = Object.keys(outProps)[0];
883
+ if (outKey) {
884
+ const outVal = outProps[outKey];
885
+ attr.value = t.jsxAttribute(t.jsxIdentifier(outKey), t.jsxExpressionContainer(typeof outVal == "string" ? t.stringLiteral(outVal) : literalToAst(outVal)));
886
+ }
887
+ }
888
+ }
889
+ }
890
+ } catch (err) {
891
+ getStyleError = err;
892
+ }
893
+ if (shouldPrintDebug && logger.info([` - attrs (ternaries/combined):
894
+ `, logLines(attrs.map(attrStr).join(", "))].join(" ")), tm.mark("jsx-element-styles", !!shouldPrintDebug), getStyleError) return logger.info([" \u26A0\uFE0F postprocessing error, deopt", getStyleError].join(" ")), node.attributes = ogAttributes, null;
895
+ const existingStyleKeys = /* @__PURE__ */new Set();
896
+ for (let i = attrs.length - 1; i >= 0; i--) {
897
+ const attr = attrs[i];
898
+ if (shouldFlatten && attr.type === "attr" && t.isJSXAttribute(attr.value) && t.isJSXIdentifier(attr.value.name)) {
899
+ const name = attr.value.name.name;
900
+ INLINE_EXTRACTABLE[name] && (attr.value.name.name = INLINE_EXTRACTABLE[name]);
901
+ }
902
+ if (attr.type === "style") for (const key in attr.value) existingStyleKeys.has(key) ? (shouldPrintDebug && logger.info([` >> delete existing ${key}`].join(" ")), delete attr.value[key]) : existingStyleKeys.add(key);
903
+ attr.type === "dynamic-style" && (existingStyleKeys.has(attr.name) ? attrs[i] = void 0 : existingStyleKeys.add(attr.name));
904
+ }
905
+ if (options.experimentalFlattenThemesOnNative && (attrs = attrs.filter(Boolean)), !shouldFlatten && inlineWhenUnflattened.size) {
906
+ for (const [index, attr] of attrs.entries()) if (attr.type === "style") for (const key in attr.value) {
907
+ if (!inlineWhenUnflattened.has(key)) continue;
908
+ const val = inlineWhenUnflattenedOGVals[key];
909
+ val ? (delete attr.value[key], attrs.splice(index - 1, 0, val.attr)) : delete attr.value[key];
910
+ }
911
+ }
912
+ if (shouldFlatten && (shouldPrintDebug && logger.info([" [\u2705] flattening", originalNodeName, flatNode].join(" ")), node.name.name = flatNode, res.flattened++, closingElement && (closingElement.name.name = flatNode)), !shouldFlatten && platform2 === "native") return shouldPrintDebug && logger.info(`Disabled flattening except for simple cases on native for now: ${JSON.stringify({
913
+ flatNode,
914
+ shouldDeopt,
915
+ canFlattenProps,
916
+ hasSpread,
917
+ "staticConfig.isStyledHOC": staticConfig.isStyledHOC,
918
+ "!staticConfig.isHOC": !staticConfig.isHOC,
919
+ "staticConfig.isReactNative": staticConfig.isReactNative,
920
+ "staticConfig.neverFlatten": staticConfig.neverFlatten
921
+ }, null, 2)}`), node.attributes = ogAttributes, null;
922
+ shouldPrintDebug && (logger.info([` - inlined props (${inlined.size}):`, shouldDeopt ? " deopted" : "", hasSpread ? " has spread" : "", staticConfig.neverFlatten ? "neverFlatten" : ""].join(" ")), logger.info(` - shouldFlatten/isFlattened: ${shouldFlatten}`), logger.info(` - attrs (end):
923
+ ${logLines(attrs.map(attrStr).join(", "))}`)), onExtractTag({
924
+ parserProps: propsWithFileInfo,
925
+ attrs,
926
+ node,
927
+ lineNumbers,
928
+ filePath,
929
+ config: tamaguiConfig,
930
+ attemptEval,
931
+ jsxPath: traversePath,
932
+ originalNodeName,
933
+ isFlattened: shouldFlatten,
934
+ programPath,
935
+ completeProps,
936
+ staticConfig
937
+ });
938
+ } catch (err) {
939
+ node.attributes = ogAttributes, console.error(`@tamagui/static error, reverting optimization. In ${filePath} ${lineNumbers} on ${originalNodeName}: ${err.message}. For stack trace set environment TAMAGUI_DEBUG=1`), process.env.TAMAGUI_DEBUG === "1" && console.error(err.stack);
940
+ } finally {
941
+ debugPropValue && (shouldPrintDebug = ogDebug);
942
+ }
943
+ }
944
+ }), tm.mark("jsx-done", !!shouldPrintDebug), modifiedComponents.size) {
945
+ const all = Array.from(modifiedComponents);
946
+ shouldPrintDebug && logger.info(` [\u{1FA9D}] hook check ${all.length}`);
947
+ for (const comp of all) removeUnusedHooks(comp, shouldPrintDebug);
948
+ }
949
+ return tm.done(shouldPrintDebug === "verbose"), res;
950
+ }
951
+ }
952
+ export { createExtractor };