@tamagui/static 3.0.2 → 3.0.4
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/dist/cjs/compilerHost.cjs +170 -6
- package/dist/esm/compilerHost.mjs +171 -7
- package/dist/esm/compilerHost.mjs.map +1 -1
- package/package.json +19 -19
- package/src/compilerHost.ts +220 -10
- package/types/compilerHost.d.ts.map +1 -1
|
@@ -635,8 +635,155 @@ function unusedIdentifier(source, base) {
|
|
|
635
635
|
return candidate;
|
|
636
636
|
}
|
|
637
637
|
const VIEW_WRAPPER_PROPS = /^(aria-|accessibilityState$|accessibilityValue$|id$|tabIndex$|nativeID$)/;
|
|
638
|
-
function isBareHostView(element) {
|
|
639
|
-
return !element.entries.some((entry) => entry.kind === "child" || entry.kind === "spread" || entry.kind === "prop" && VIEW_WRAPPER_PROPS.test(entry.name));
|
|
638
|
+
function isBareHostView(element, resetsTextAncestor) {
|
|
639
|
+
return !element.entries.some((entry) => entry.kind === "child" && !resetsTextAncestor || entry.kind === "spread" || entry.kind === "prop" && VIEW_WRAPPER_PROPS.test(entry.name));
|
|
640
|
+
}
|
|
641
|
+
const TEXT_WRAPPER_PROPS = /^(aria-|accessib|on[A-Z]|disabled$|id$|nativeID$|numberOfLines$|ellipsizeMode$|selectable$|selectionColor$|suppressHighlighting$|pressRetentionOffset$|role$|allowFontScaling$)/;
|
|
642
|
+
function isBareHostText(element) {
|
|
643
|
+
return !element.entries.some((entry) => entry.kind === "spread" || entry.kind === "prop" && TEXT_WRAPPER_PROPS.test(entry.name));
|
|
644
|
+
}
|
|
645
|
+
const SCOPE_PRESERVING_PARENTS = {
|
|
646
|
+
react: ["Fragment"],
|
|
647
|
+
"react-native": [
|
|
648
|
+
"View",
|
|
649
|
+
"ScrollView",
|
|
650
|
+
"SafeAreaView"
|
|
651
|
+
],
|
|
652
|
+
"@tamagui/core": [
|
|
653
|
+
"View",
|
|
654
|
+
"Stack",
|
|
655
|
+
"XStack",
|
|
656
|
+
"YStack",
|
|
657
|
+
"ZStack"
|
|
658
|
+
],
|
|
659
|
+
tamagui: [
|
|
660
|
+
"View",
|
|
661
|
+
"Stack",
|
|
662
|
+
"XStack",
|
|
663
|
+
"YStack",
|
|
664
|
+
"ZStack"
|
|
665
|
+
]
|
|
666
|
+
};
|
|
667
|
+
const SCOPE_PROPS = /* @__PURE__ */ new Set([
|
|
668
|
+
"theme",
|
|
669
|
+
"themeInverse",
|
|
670
|
+
"themeShallow",
|
|
671
|
+
"componentName"
|
|
672
|
+
]);
|
|
673
|
+
let inlineModule = null;
|
|
674
|
+
function inlineModuleOf(input) {
|
|
675
|
+
if (inlineModule?.source === input.source) return inlineModule;
|
|
676
|
+
const program = (0, import_compiler_core.parseModuleAst)(input.source, input.id);
|
|
677
|
+
const imports = /* @__PURE__ */ new Map();
|
|
678
|
+
for (const statement of (0, import_compiler_core.childNodes)(program, "body")) {
|
|
679
|
+
if (statement.type !== "ImportDeclaration" || statement.importKind === "type") continue;
|
|
680
|
+
const from = (0, import_compiler_core.childNode)(statement, "source")?.value;
|
|
681
|
+
for (const specifier of (0, import_compiler_core.childNodes)(statement, "specifiers")) {
|
|
682
|
+
if (specifier.type !== "ImportSpecifier") continue;
|
|
683
|
+
const local = (0, import_compiler_core.identifierName)((0, import_compiler_core.childNode)(specifier, "local"));
|
|
684
|
+
const imported = (0, import_compiler_core.identifierName)((0, import_compiler_core.childNode)(specifier, "imported"));
|
|
685
|
+
if (local && imported) imports.set(local, `${from}#${imported}`);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
inlineModule = {
|
|
689
|
+
source: input.source,
|
|
690
|
+
program,
|
|
691
|
+
imports
|
|
692
|
+
};
|
|
693
|
+
return inlineModule;
|
|
694
|
+
}
|
|
695
|
+
function keepsThemeScope(element, imports) {
|
|
696
|
+
if (element.type === "JSXFragment") return true;
|
|
697
|
+
const opening = (0, import_compiler_core.childNode)(element, "openingElement");
|
|
698
|
+
if (!opening) return false;
|
|
699
|
+
for (const attribute of (0, import_compiler_core.childNodes)(opening, "attributes")) {
|
|
700
|
+
if (attribute.type !== "JSXAttribute") return false;
|
|
701
|
+
const name = (0, import_compiler_core.identifierName)((0, import_compiler_core.childNode)(attribute, "name"));
|
|
702
|
+
if (!name || SCOPE_PROPS.has(name)) return false;
|
|
703
|
+
}
|
|
704
|
+
const [from, imported] = (imports.get((0, import_compiler_core.identifierName)((0, import_compiler_core.childNode)(opening, "name")) ?? "") ?? "").split("#");
|
|
705
|
+
return !!SCOPE_PRESERVING_PARENTS[from]?.includes(imported);
|
|
706
|
+
}
|
|
707
|
+
function isComponentFunction(fn, parent) {
|
|
708
|
+
const pascal = (name) => !!name && /^[A-Z]/.test(name);
|
|
709
|
+
if (fn.type === "FunctionDeclaration") return pascal((0, import_compiler_core.identifierName)((0, import_compiler_core.childNode)(fn, "id")));
|
|
710
|
+
if (!parent) return false;
|
|
711
|
+
if (parent.type === "VariableDeclarator") {
|
|
712
|
+
return (0, import_compiler_core.childNode)(parent, "init") === fn && pascal((0, import_compiler_core.identifierName)((0, import_compiler_core.childNode)(parent, "id")));
|
|
713
|
+
}
|
|
714
|
+
if (parent.type === "CallExpression" && (0, import_compiler_core.childNodes)(parent, "arguments")[0] === fn) {
|
|
715
|
+
const callee = (0, import_compiler_core.childNode)(parent, "callee");
|
|
716
|
+
const name = callee?.type === "MemberExpression" ? (0, import_compiler_core.identifierName)((0, import_compiler_core.childNode)(callee, "property")) : (0, import_compiler_core.identifierName)(callee);
|
|
717
|
+
return name === "memo" || name === "forwardRef";
|
|
718
|
+
}
|
|
719
|
+
return false;
|
|
720
|
+
}
|
|
721
|
+
function isRenderCallback(fn, parent) {
|
|
722
|
+
if (parent?.type !== "CallExpression") return false;
|
|
723
|
+
const callee = (0, import_compiler_core.childNode)(parent, "callee");
|
|
724
|
+
if (callee?.type !== "MemberExpression") return false;
|
|
725
|
+
const args = (0, import_compiler_core.childNodes)(parent, "arguments");
|
|
726
|
+
const method = (0, import_compiler_core.identifierName)((0, import_compiler_core.childNode)(callee, "property"));
|
|
727
|
+
if (method === "map") return args[0] === fn;
|
|
728
|
+
return method === "from" && (0, import_compiler_core.identifierName)((0, import_compiler_core.childNode)(callee, "object")) === "Array" && args[1] === fn;
|
|
729
|
+
}
|
|
730
|
+
const FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
731
|
+
"FunctionDeclaration",
|
|
732
|
+
"FunctionExpression",
|
|
733
|
+
"ArrowFunctionExpression"
|
|
734
|
+
]);
|
|
735
|
+
function nativeInlinePlacement(input) {
|
|
736
|
+
if (input.element.form !== "jsx") return null;
|
|
737
|
+
const { program, imports } = inlineModuleOf(input);
|
|
738
|
+
const { start, end } = input.element.span;
|
|
739
|
+
const path = [];
|
|
740
|
+
const element = (0, import_compiler_core.findAstNode)(program, (node, _parent, key) => {
|
|
741
|
+
path.push({
|
|
742
|
+
node,
|
|
743
|
+
key
|
|
744
|
+
});
|
|
745
|
+
return node.type === "JSXElement" && node.start === start && node.end === end;
|
|
746
|
+
}, {
|
|
747
|
+
start,
|
|
748
|
+
end
|
|
749
|
+
});
|
|
750
|
+
if (!element) return null;
|
|
751
|
+
const parentType = path.at(-2)?.node.type;
|
|
752
|
+
const braces = parentType === "JSXElement" || parentType === "JSXFragment";
|
|
753
|
+
let index = path.length - 2;
|
|
754
|
+
while (index >= 0) {
|
|
755
|
+
const { node } = path[index];
|
|
756
|
+
const childKey = path[index + 1].key;
|
|
757
|
+
switch (node.type) {
|
|
758
|
+
case "JSXElement":
|
|
759
|
+
case "JSXFragment":
|
|
760
|
+
if (childKey !== "children" || !keepsThemeScope(node, imports)) return null;
|
|
761
|
+
break;
|
|
762
|
+
case "ConditionalExpression":
|
|
763
|
+
if (childKey === "test") return null;
|
|
764
|
+
break;
|
|
765
|
+
case "JSXExpressionContainer":
|
|
766
|
+
case "LogicalExpression":
|
|
767
|
+
case "ParenthesizedExpression":
|
|
768
|
+
case "ChainExpression": break;
|
|
769
|
+
case "ReturnStatement":
|
|
770
|
+
case "ArrowFunctionExpression": {
|
|
771
|
+
if (node.type === "ArrowFunctionExpression" && childKey !== "body") return null;
|
|
772
|
+
let fnIndex = index;
|
|
773
|
+
while (fnIndex >= 0 && !FUNCTION_TYPES.has(path[fnIndex].node.type)) fnIndex--;
|
|
774
|
+
if (fnIndex < 0) return null;
|
|
775
|
+
const fn = path[fnIndex].node;
|
|
776
|
+
const fnParent = path[fnIndex - 1]?.node;
|
|
777
|
+
if (isComponentFunction(fn, fnParent)) return { braces };
|
|
778
|
+
if (!isRenderCallback(fn, fnParent)) return null;
|
|
779
|
+
index = fnIndex - 1;
|
|
780
|
+
break;
|
|
781
|
+
}
|
|
782
|
+
default: return null;
|
|
783
|
+
}
|
|
784
|
+
index--;
|
|
785
|
+
}
|
|
786
|
+
return null;
|
|
640
787
|
}
|
|
641
788
|
function entrySource(input, entry) {
|
|
642
789
|
return entry.value.kind === "static" ? JSON.stringify(entry.value.value) : input.source.slice(entry.value.span.start, entry.value.span.end);
|
|
@@ -1761,7 +1908,7 @@ function createTamaguiCompilerHost(options) {
|
|
|
1761
1908
|
const usesNativeFastPath = !!themedStyleKeys && !!options.experimentalNativeFastPath && dynamicStyleEntries.length === 0 && !input.element.entries.some((entry) => entry.kind === "spread");
|
|
1762
1909
|
const nativeStyleImports = [{
|
|
1763
1910
|
content: `
|
|
1764
|
-
function ${nativeStyleLocal}() { return ${nativeStyleLocal}._ ?? (${nativeStyleLocal}._ = ${JSON.stringify(
|
|
1911
|
+
function ${nativeStyleLocal}() { return ${nativeStyleLocal}._ ?? (${nativeStyleLocal}._ = ${JSON.stringify(collapseNativeShorthands(nativeStyle) ?? {})}); } ${nativeStyleLocal}();`,
|
|
1765
1912
|
origin: input.element.component.span
|
|
1766
1913
|
}];
|
|
1767
1914
|
const nativeStyleSource = `${nativeStyleLocal}._ ?? ${nativeStyleLocal}()`;
|
|
@@ -1928,7 +2075,8 @@ import { createElement as ${createElementLocal} } from "react"
|
|
|
1928
2075
|
};
|
|
1929
2076
|
}
|
|
1930
2077
|
const nativeName = component.staticConfig.isText ? "Text" : "View";
|
|
1931
|
-
const useHostView = options.experimentalNativeFastPath && nativeName === "View" && isBareHostView(input.element);
|
|
2078
|
+
const useHostView = options.experimentalNativeFastPath && nativeName === "View" && isBareHostView(input.element, !!nativeFastPath);
|
|
2079
|
+
const useHostText = options.experimentalNativeFastPath && nativeName === "Text" && !!nativeFastPath && isBareHostText(input.element);
|
|
1932
2080
|
const nativeExport = useHostView ? "unstable_NativeView" : nativeName;
|
|
1933
2081
|
const nativeLocal = unusedIdentifier(input.source, `__TamaguiNative${useHostView ? "HostView" : nativeName}`);
|
|
1934
2082
|
if (themedStyleKeys && options.disablePartialExtraction) {
|
|
@@ -1958,9 +2106,25 @@ import { createElement as ${createElementLocal} } from "react"
|
|
|
1958
2106
|
if (!styleEdits) {
|
|
1959
2107
|
return bailout(input, "local/unsupported-target", `Compiled ${input.element.form} call has no editable props argument`);
|
|
1960
2108
|
}
|
|
2109
|
+
const inline = nativeInlinePlacement(input);
|
|
2110
|
+
const inlineEdits = inline ? [{
|
|
2111
|
+
start: input.element.span.start,
|
|
2112
|
+
end: input.element.span.start,
|
|
2113
|
+
content: `${inline.braces ? "{" : ""}${fastLocal}.inline(`,
|
|
2114
|
+
origin: input.element.span
|
|
2115
|
+
}, {
|
|
2116
|
+
start: input.element.span.end,
|
|
2117
|
+
end: input.element.span.end,
|
|
2118
|
+
content: `)${inline.braces ? "}" : ""}`,
|
|
2119
|
+
origin: input.element.span
|
|
2120
|
+
}] : [];
|
|
1961
2121
|
return {
|
|
1962
2122
|
ok: true,
|
|
1963
|
-
edits: [
|
|
2123
|
+
edits: [
|
|
2124
|
+
...inlineEdits,
|
|
2125
|
+
...tagEdits4,
|
|
2126
|
+
...styleEdits
|
|
2127
|
+
],
|
|
1964
2128
|
css: [],
|
|
1965
2129
|
imports: [
|
|
1966
2130
|
...nativeStyleImports,
|
|
@@ -1972,7 +2136,7 @@ const ${nativeLocal} = require('react-native').${nativeExport};`,
|
|
|
1972
2136
|
},
|
|
1973
2137
|
{
|
|
1974
2138
|
content: `
|
|
1975
|
-
const ${fastLocal} = require('@tamagui/core')._withNativeStyle(${nativeLocal}, ${nativeStyleSource}, ${nativeFastPath.mappingLocal});`,
|
|
2139
|
+
const ${fastLocal} = require('@tamagui/core')._withNativeStyle(${nativeLocal}, ${nativeStyleSource}, ${nativeFastPath.mappingLocal}${useHostView ? `, 'view'` : useHostText ? `, 'text'` : ""});`,
|
|
1976
2140
|
origin: input.element.component.span
|
|
1977
2141
|
}
|
|
1978
2142
|
],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { collectLeaves, zeroRuleMessage, zeroThemeBoundaryMessage } from "@tamagui/compiler-core";
|
|
1
|
+
import { childNode, childNodes, collectLeaves, findAstNode, identifierName, parseModuleAst, zeroRuleMessage, zeroThemeBoundaryMessage } from "@tamagui/compiler-core";
|
|
2
2
|
import { StyleObjectIdentifier, StyleObjectProperty, StyleObjectRules, StyleObjectValue, stylePropsAll, stylePropsInput, stylePropsText, validStyles } from "@tamagui/helpers";
|
|
3
3
|
import { ATTRIBUTES, EVENTS, NATIVE_BACKING, NATIVE_BLOCK_DEFAULTS, NATIVE_ELEMENT_DEFAULTS, NATIVE_FLEX_DEFAULTS, NATIVE_INPUT_TYPES, NATIVE_PRIMITIVE_MODULE, TAGS, TAG_WEB_DEFAULTS } from "@tamagui/dom";
|
|
4
4
|
import { resolveTransition, toCSSTransition } from "@tamagui/animation-helpers";
|
|
@@ -610,8 +610,155 @@ function unusedIdentifier(source, base) {
|
|
|
610
610
|
return candidate;
|
|
611
611
|
}
|
|
612
612
|
const VIEW_WRAPPER_PROPS = /^(aria-|accessibilityState$|accessibilityValue$|id$|tabIndex$|nativeID$)/;
|
|
613
|
-
function isBareHostView(element) {
|
|
614
|
-
return !element.entries.some((entry) => entry.kind === "child" || entry.kind === "spread" || entry.kind === "prop" && VIEW_WRAPPER_PROPS.test(entry.name));
|
|
613
|
+
function isBareHostView(element, resetsTextAncestor) {
|
|
614
|
+
return !element.entries.some((entry) => entry.kind === "child" && !resetsTextAncestor || entry.kind === "spread" || entry.kind === "prop" && VIEW_WRAPPER_PROPS.test(entry.name));
|
|
615
|
+
}
|
|
616
|
+
const TEXT_WRAPPER_PROPS = /^(aria-|accessib|on[A-Z]|disabled$|id$|nativeID$|numberOfLines$|ellipsizeMode$|selectable$|selectionColor$|suppressHighlighting$|pressRetentionOffset$|role$|allowFontScaling$)/;
|
|
617
|
+
function isBareHostText(element) {
|
|
618
|
+
return !element.entries.some((entry) => entry.kind === "spread" || entry.kind === "prop" && TEXT_WRAPPER_PROPS.test(entry.name));
|
|
619
|
+
}
|
|
620
|
+
const SCOPE_PRESERVING_PARENTS = {
|
|
621
|
+
react: ["Fragment"],
|
|
622
|
+
"react-native": [
|
|
623
|
+
"View",
|
|
624
|
+
"ScrollView",
|
|
625
|
+
"SafeAreaView"
|
|
626
|
+
],
|
|
627
|
+
"@tamagui/core": [
|
|
628
|
+
"View",
|
|
629
|
+
"Stack",
|
|
630
|
+
"XStack",
|
|
631
|
+
"YStack",
|
|
632
|
+
"ZStack"
|
|
633
|
+
],
|
|
634
|
+
tamagui: [
|
|
635
|
+
"View",
|
|
636
|
+
"Stack",
|
|
637
|
+
"XStack",
|
|
638
|
+
"YStack",
|
|
639
|
+
"ZStack"
|
|
640
|
+
]
|
|
641
|
+
};
|
|
642
|
+
const SCOPE_PROPS = /* @__PURE__ */ new Set([
|
|
643
|
+
"theme",
|
|
644
|
+
"themeInverse",
|
|
645
|
+
"themeShallow",
|
|
646
|
+
"componentName"
|
|
647
|
+
]);
|
|
648
|
+
let inlineModule = null;
|
|
649
|
+
function inlineModuleOf(input) {
|
|
650
|
+
if (inlineModule?.source === input.source) return inlineModule;
|
|
651
|
+
const program = parseModuleAst(input.source, input.id);
|
|
652
|
+
const imports = /* @__PURE__ */ new Map();
|
|
653
|
+
for (const statement of childNodes(program, "body")) {
|
|
654
|
+
if (statement.type !== "ImportDeclaration" || statement.importKind === "type") continue;
|
|
655
|
+
const from = childNode(statement, "source")?.value;
|
|
656
|
+
for (const specifier of childNodes(statement, "specifiers")) {
|
|
657
|
+
if (specifier.type !== "ImportSpecifier") continue;
|
|
658
|
+
const local = identifierName(childNode(specifier, "local"));
|
|
659
|
+
const imported = identifierName(childNode(specifier, "imported"));
|
|
660
|
+
if (local && imported) imports.set(local, `${from}#${imported}`);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
inlineModule = {
|
|
664
|
+
source: input.source,
|
|
665
|
+
program,
|
|
666
|
+
imports
|
|
667
|
+
};
|
|
668
|
+
return inlineModule;
|
|
669
|
+
}
|
|
670
|
+
function keepsThemeScope(element, imports) {
|
|
671
|
+
if (element.type === "JSXFragment") return true;
|
|
672
|
+
const opening = childNode(element, "openingElement");
|
|
673
|
+
if (!opening) return false;
|
|
674
|
+
for (const attribute of childNodes(opening, "attributes")) {
|
|
675
|
+
if (attribute.type !== "JSXAttribute") return false;
|
|
676
|
+
const name = identifierName(childNode(attribute, "name"));
|
|
677
|
+
if (!name || SCOPE_PROPS.has(name)) return false;
|
|
678
|
+
}
|
|
679
|
+
const [from, imported] = (imports.get(identifierName(childNode(opening, "name")) ?? "") ?? "").split("#");
|
|
680
|
+
return !!SCOPE_PRESERVING_PARENTS[from]?.includes(imported);
|
|
681
|
+
}
|
|
682
|
+
function isComponentFunction(fn, parent) {
|
|
683
|
+
const pascal = (name) => !!name && /^[A-Z]/.test(name);
|
|
684
|
+
if (fn.type === "FunctionDeclaration") return pascal(identifierName(childNode(fn, "id")));
|
|
685
|
+
if (!parent) return false;
|
|
686
|
+
if (parent.type === "VariableDeclarator") {
|
|
687
|
+
return childNode(parent, "init") === fn && pascal(identifierName(childNode(parent, "id")));
|
|
688
|
+
}
|
|
689
|
+
if (parent.type === "CallExpression" && childNodes(parent, "arguments")[0] === fn) {
|
|
690
|
+
const callee = childNode(parent, "callee");
|
|
691
|
+
const name = callee?.type === "MemberExpression" ? identifierName(childNode(callee, "property")) : identifierName(callee);
|
|
692
|
+
return name === "memo" || name === "forwardRef";
|
|
693
|
+
}
|
|
694
|
+
return false;
|
|
695
|
+
}
|
|
696
|
+
function isRenderCallback(fn, parent) {
|
|
697
|
+
if (parent?.type !== "CallExpression") return false;
|
|
698
|
+
const callee = childNode(parent, "callee");
|
|
699
|
+
if (callee?.type !== "MemberExpression") return false;
|
|
700
|
+
const args = childNodes(parent, "arguments");
|
|
701
|
+
const method = identifierName(childNode(callee, "property"));
|
|
702
|
+
if (method === "map") return args[0] === fn;
|
|
703
|
+
return method === "from" && identifierName(childNode(callee, "object")) === "Array" && args[1] === fn;
|
|
704
|
+
}
|
|
705
|
+
const FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
706
|
+
"FunctionDeclaration",
|
|
707
|
+
"FunctionExpression",
|
|
708
|
+
"ArrowFunctionExpression"
|
|
709
|
+
]);
|
|
710
|
+
function nativeInlinePlacement(input) {
|
|
711
|
+
if (input.element.form !== "jsx") return null;
|
|
712
|
+
const { program, imports } = inlineModuleOf(input);
|
|
713
|
+
const { start, end } = input.element.span;
|
|
714
|
+
const path = [];
|
|
715
|
+
const element = findAstNode(program, (node, _parent, key) => {
|
|
716
|
+
path.push({
|
|
717
|
+
node,
|
|
718
|
+
key
|
|
719
|
+
});
|
|
720
|
+
return node.type === "JSXElement" && node.start === start && node.end === end;
|
|
721
|
+
}, {
|
|
722
|
+
start,
|
|
723
|
+
end
|
|
724
|
+
});
|
|
725
|
+
if (!element) return null;
|
|
726
|
+
const parentType = path.at(-2)?.node.type;
|
|
727
|
+
const braces = parentType === "JSXElement" || parentType === "JSXFragment";
|
|
728
|
+
let index = path.length - 2;
|
|
729
|
+
while (index >= 0) {
|
|
730
|
+
const { node } = path[index];
|
|
731
|
+
const childKey = path[index + 1].key;
|
|
732
|
+
switch (node.type) {
|
|
733
|
+
case "JSXElement":
|
|
734
|
+
case "JSXFragment":
|
|
735
|
+
if (childKey !== "children" || !keepsThemeScope(node, imports)) return null;
|
|
736
|
+
break;
|
|
737
|
+
case "ConditionalExpression":
|
|
738
|
+
if (childKey === "test") return null;
|
|
739
|
+
break;
|
|
740
|
+
case "JSXExpressionContainer":
|
|
741
|
+
case "LogicalExpression":
|
|
742
|
+
case "ParenthesizedExpression":
|
|
743
|
+
case "ChainExpression": break;
|
|
744
|
+
case "ReturnStatement":
|
|
745
|
+
case "ArrowFunctionExpression": {
|
|
746
|
+
if (node.type === "ArrowFunctionExpression" && childKey !== "body") return null;
|
|
747
|
+
let fnIndex = index;
|
|
748
|
+
while (fnIndex >= 0 && !FUNCTION_TYPES.has(path[fnIndex].node.type)) fnIndex--;
|
|
749
|
+
if (fnIndex < 0) return null;
|
|
750
|
+
const fn = path[fnIndex].node;
|
|
751
|
+
const fnParent = path[fnIndex - 1]?.node;
|
|
752
|
+
if (isComponentFunction(fn, fnParent)) return { braces };
|
|
753
|
+
if (!isRenderCallback(fn, fnParent)) return null;
|
|
754
|
+
index = fnIndex - 1;
|
|
755
|
+
break;
|
|
756
|
+
}
|
|
757
|
+
default: return null;
|
|
758
|
+
}
|
|
759
|
+
index--;
|
|
760
|
+
}
|
|
761
|
+
return null;
|
|
615
762
|
}
|
|
616
763
|
function entrySource(input, entry) {
|
|
617
764
|
return entry.value.kind === "static" ? JSON.stringify(entry.value.value) : input.source.slice(entry.value.span.start, entry.value.span.end);
|
|
@@ -1736,7 +1883,7 @@ function createTamaguiCompilerHost(options) {
|
|
|
1736
1883
|
const usesNativeFastPath = !!themedStyleKeys && !!options.experimentalNativeFastPath && dynamicStyleEntries.length === 0 && !input.element.entries.some((entry) => entry.kind === "spread");
|
|
1737
1884
|
const nativeStyleImports = [{
|
|
1738
1885
|
content: `
|
|
1739
|
-
function ${nativeStyleLocal}() { return ${nativeStyleLocal}._ ?? (${nativeStyleLocal}._ = ${JSON.stringify(
|
|
1886
|
+
function ${nativeStyleLocal}() { return ${nativeStyleLocal}._ ?? (${nativeStyleLocal}._ = ${JSON.stringify(collapseNativeShorthands(nativeStyle) ?? {})}); } ${nativeStyleLocal}();`,
|
|
1740
1887
|
origin: input.element.component.span
|
|
1741
1888
|
}];
|
|
1742
1889
|
const nativeStyleSource = `${nativeStyleLocal}._ ?? ${nativeStyleLocal}()`;
|
|
@@ -1903,7 +2050,8 @@ import { createElement as ${createElementLocal} } from "react"
|
|
|
1903
2050
|
};
|
|
1904
2051
|
}
|
|
1905
2052
|
const nativeName = component.staticConfig.isText ? "Text" : "View";
|
|
1906
|
-
const useHostView = options.experimentalNativeFastPath && nativeName === "View" && isBareHostView(input.element);
|
|
2053
|
+
const useHostView = options.experimentalNativeFastPath && nativeName === "View" && isBareHostView(input.element, !!nativeFastPath);
|
|
2054
|
+
const useHostText = options.experimentalNativeFastPath && nativeName === "Text" && !!nativeFastPath && isBareHostText(input.element);
|
|
1907
2055
|
const nativeExport = useHostView ? "unstable_NativeView" : nativeName;
|
|
1908
2056
|
const nativeLocal = unusedIdentifier(input.source, `__TamaguiNative${useHostView ? "HostView" : nativeName}`);
|
|
1909
2057
|
if (themedStyleKeys && options.disablePartialExtraction) {
|
|
@@ -1933,9 +2081,25 @@ import { createElement as ${createElementLocal} } from "react"
|
|
|
1933
2081
|
if (!styleEdits) {
|
|
1934
2082
|
return bailout(input, "local/unsupported-target", `Compiled ${input.element.form} call has no editable props argument`);
|
|
1935
2083
|
}
|
|
2084
|
+
const inline = nativeInlinePlacement(input);
|
|
2085
|
+
const inlineEdits = inline ? [{
|
|
2086
|
+
start: input.element.span.start,
|
|
2087
|
+
end: input.element.span.start,
|
|
2088
|
+
content: `${inline.braces ? "{" : ""}${fastLocal}.inline(`,
|
|
2089
|
+
origin: input.element.span
|
|
2090
|
+
}, {
|
|
2091
|
+
start: input.element.span.end,
|
|
2092
|
+
end: input.element.span.end,
|
|
2093
|
+
content: `)${inline.braces ? "}" : ""}`,
|
|
2094
|
+
origin: input.element.span
|
|
2095
|
+
}] : [];
|
|
1936
2096
|
return {
|
|
1937
2097
|
ok: true,
|
|
1938
|
-
edits: [
|
|
2098
|
+
edits: [
|
|
2099
|
+
...inlineEdits,
|
|
2100
|
+
...tagEdits4,
|
|
2101
|
+
...styleEdits
|
|
2102
|
+
],
|
|
1939
2103
|
css: [],
|
|
1940
2104
|
imports: [
|
|
1941
2105
|
...nativeStyleImports,
|
|
@@ -1947,7 +2111,7 @@ const ${nativeLocal} = require('react-native').${nativeExport};`,
|
|
|
1947
2111
|
},
|
|
1948
2112
|
{
|
|
1949
2113
|
content: `
|
|
1950
|
-
const ${fastLocal} = require('@tamagui/core')._withNativeStyle(${nativeLocal}, ${nativeStyleSource}, ${nativeFastPath.mappingLocal});`,
|
|
2114
|
+
const ${fastLocal} = require('@tamagui/core')._withNativeStyle(${nativeLocal}, ${nativeStyleSource}, ${nativeFastPath.mappingLocal}${useHostView ? `, 'view'` : useHostText ? `, 'text'` : ""});`,
|
|
1951
2115
|
origin: input.element.component.span
|
|
1952
2116
|
}
|
|
1953
2117
|
],
|