@homebound/truss 2.1.0-next.4 → 2.1.0-next.6
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/build/plugin/index.js +157 -19
- package/build/plugin/index.js.map +1 -1
- package/package.json +1 -1
package/build/plugin/index.js
CHANGED
|
@@ -163,7 +163,7 @@ function collectVariableRules(rules, seg, mapping) {
|
|
|
163
163
|
const prefix = conditionPrefix(seg.pseudoClass, seg.mediaQuery, seg.pseudoElement, mapping.breakpoints);
|
|
164
164
|
const segmentBaseKey = seg.key.split("__")[0];
|
|
165
165
|
for (const prop of seg.variableProps) {
|
|
166
|
-
const baseKey =
|
|
166
|
+
const baseKey = seg.key.split("__")[0];
|
|
167
167
|
const className = prefix ? `${prefix}${baseKey}_var` : `${baseKey}_var`;
|
|
168
168
|
const varName = toCssVariableName(className, baseKey, prop);
|
|
169
169
|
const declaration = { cssProperty: camelToKebab(prop), cssValue: `var(${varName})`, cssVarName: varName };
|
|
@@ -242,7 +242,7 @@ function collectWhenVariableRules(rules, seg, mapping) {
|
|
|
242
242
|
const segmentBaseKey = seg.key.split("__")[0];
|
|
243
243
|
const mClass = markerClassName(wp.markerNode);
|
|
244
244
|
for (const prop of seg.variableProps) {
|
|
245
|
-
const baseKey =
|
|
245
|
+
const baseKey = seg.key.split("__")[0];
|
|
246
246
|
const className = `${prefix}${baseKey}_var`;
|
|
247
247
|
const varName = toCssVariableName(className, baseKey, prop);
|
|
248
248
|
const declaration = { cssProperty: camelToKebab(prop), cssValue: `var(${varName})`, cssVarName: varName };
|
|
@@ -469,7 +469,7 @@ function buildStyleHashProperties(segments, mapping, maybeIncHelperName) {
|
|
|
469
469
|
const prefix = seg.whenPseudo ? whenPrefix(seg.whenPseudo) : conditionPrefix(seg.pseudoClass, seg.mediaQuery, seg.pseudoElement, mapping.breakpoints);
|
|
470
470
|
const segmentBaseKey = seg.key.split("__")[0];
|
|
471
471
|
for (const prop of seg.variableProps) {
|
|
472
|
-
const baseKey =
|
|
472
|
+
const baseKey = seg.key.split("__")[0];
|
|
473
473
|
const className = prefix ? `${prefix}${baseKey}_var` : `${baseKey}_var`;
|
|
474
474
|
const varName = toCssVariableName(className, baseKey, prop);
|
|
475
475
|
if (!propGroups.has(prop)) propGroups.set(prop, []);
|
|
@@ -530,12 +530,6 @@ function buildStyleHashProperties(segments, mapping, maybeIncHelperName) {
|
|
|
530
530
|
}
|
|
531
531
|
return properties;
|
|
532
532
|
}
|
|
533
|
-
function variableBaseKey(seg, cssProp) {
|
|
534
|
-
if (seg.key.startsWith("add_")) {
|
|
535
|
-
return cssProp;
|
|
536
|
-
}
|
|
537
|
-
return seg.key.split("__")[0];
|
|
538
|
-
}
|
|
539
533
|
function toCssVariableName(className, baseKey, cssProp) {
|
|
540
534
|
const baseClassName = `${baseKey}_var`;
|
|
541
535
|
const conditionPrefix2 = className.endsWith(baseClassName) ? className.slice(0, -baseClassName.length) : "";
|
|
@@ -1148,17 +1142,17 @@ function resolveAddCall(node, mapping, mediaQuery, pseudoClass, pseudoElement, w
|
|
|
1148
1142
|
const wpSuffix = whenPseudoKeyName(whenPseudo);
|
|
1149
1143
|
if (literalValue !== null) {
|
|
1150
1144
|
const keySuffix = literalValue.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
1151
|
-
const key =
|
|
1145
|
+
const key = `${propName}__${keySuffix}__${wpSuffix}`;
|
|
1152
1146
|
return { key, defs: { [propName]: literalValue }, whenPseudo, argResolved: literalValue };
|
|
1153
1147
|
} else {
|
|
1154
|
-
const key =
|
|
1148
|
+
const key = `${propName}__${wpSuffix}`;
|
|
1155
1149
|
return { key, defs: {}, whenPseudo, variableProps: [propName], incremented: false, argNode: valueArg };
|
|
1156
1150
|
}
|
|
1157
1151
|
}
|
|
1158
1152
|
const suffix = conditionKeySuffix(mediaQuery, pseudoClass, pseudoElement, mapping.breakpoints);
|
|
1159
1153
|
if (literalValue !== null) {
|
|
1160
1154
|
const keySuffix = literalValue.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
1161
|
-
const key = suffix ?
|
|
1155
|
+
const key = suffix ? `${propName}__${keySuffix}__${suffix}` : `${propName}__${keySuffix}`;
|
|
1162
1156
|
const defs = { [propName]: literalValue };
|
|
1163
1157
|
const wrappedDefs = wrapDefsWithConditions(defs, mediaQuery, pseudoClass);
|
|
1164
1158
|
return {
|
|
@@ -1170,7 +1164,7 @@ function resolveAddCall(node, mapping, mediaQuery, pseudoClass, pseudoElement, w
|
|
|
1170
1164
|
argResolved: literalValue
|
|
1171
1165
|
};
|
|
1172
1166
|
} else {
|
|
1173
|
-
const key = suffix ?
|
|
1167
|
+
const key = suffix ? `${propName}__${suffix}` : propName;
|
|
1174
1168
|
return {
|
|
1175
1169
|
key,
|
|
1176
1170
|
defs: {},
|
|
@@ -1623,6 +1617,29 @@ function findNamedImportBinding(ast, source, importedName) {
|
|
|
1623
1617
|
}
|
|
1624
1618
|
return null;
|
|
1625
1619
|
}
|
|
1620
|
+
function findImportDeclaration(ast, source) {
|
|
1621
|
+
for (const node of ast.program.body) {
|
|
1622
|
+
if (t2.isImportDeclaration(node) && node.source.value === source) {
|
|
1623
|
+
return node;
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
return null;
|
|
1627
|
+
}
|
|
1628
|
+
function replaceCssImportWithNamedImports(ast, cssBinding, source, imports) {
|
|
1629
|
+
for (const node of ast.program.body) {
|
|
1630
|
+
if (!t2.isImportDeclaration(node)) continue;
|
|
1631
|
+
const cssSpecIndex = node.specifiers.findIndex(function(spec) {
|
|
1632
|
+
return t2.isImportSpecifier(spec) && spec.local.name === cssBinding;
|
|
1633
|
+
});
|
|
1634
|
+
if (cssSpecIndex === -1 || node.specifiers.length !== 1) continue;
|
|
1635
|
+
node.source = t2.stringLiteral(source);
|
|
1636
|
+
node.specifiers = imports.map(function(entry) {
|
|
1637
|
+
return t2.importSpecifier(t2.identifier(entry.localName), t2.identifier(entry.importedName));
|
|
1638
|
+
});
|
|
1639
|
+
return true;
|
|
1640
|
+
}
|
|
1641
|
+
return false;
|
|
1642
|
+
}
|
|
1626
1643
|
function upsertNamedImports(ast, source, imports) {
|
|
1627
1644
|
if (imports.length === 0) return;
|
|
1628
1645
|
for (const node of ast.program.body) {
|
|
@@ -1718,6 +1735,7 @@ function getCssAttributePath(path) {
|
|
|
1718
1735
|
}
|
|
1719
1736
|
function buildStyleHashFromChain(chain, options) {
|
|
1720
1737
|
const members = [];
|
|
1738
|
+
const previousProperties = /* @__PURE__ */ new Map();
|
|
1721
1739
|
if (chain.markers.length > 0) {
|
|
1722
1740
|
const markerClasses = chain.markers.map(function(marker) {
|
|
1723
1741
|
return markerClassName(marker.markerNode);
|
|
@@ -1726,10 +1744,22 @@ function buildStyleHashFromChain(chain, options) {
|
|
|
1726
1744
|
}
|
|
1727
1745
|
for (const part of chain.parts) {
|
|
1728
1746
|
if (part.type === "unconditional") {
|
|
1729
|
-
|
|
1747
|
+
const partMembers = buildStyleHashMembers(part.segments, options);
|
|
1748
|
+
members.push(...partMembers);
|
|
1749
|
+
for (const member of partMembers) {
|
|
1750
|
+
if (t3.isObjectProperty(member)) {
|
|
1751
|
+
previousProperties.set(propertyName(member.key), member);
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1730
1754
|
} else {
|
|
1731
|
-
const thenMembers =
|
|
1732
|
-
|
|
1755
|
+
const thenMembers = mergeConditionalBranchMembers(
|
|
1756
|
+
buildStyleHashMembers(part.thenSegments, options),
|
|
1757
|
+
previousProperties
|
|
1758
|
+
);
|
|
1759
|
+
const elseMembers = mergeConditionalBranchMembers(
|
|
1760
|
+
buildStyleHashMembers(part.elseSegments, options),
|
|
1761
|
+
previousProperties
|
|
1762
|
+
);
|
|
1733
1763
|
members.push(
|
|
1734
1764
|
t3.spreadElement(
|
|
1735
1765
|
t3.conditionalExpression(part.conditionNode, t3.objectExpression(thenMembers), t3.objectExpression(elseMembers))
|
|
@@ -1773,6 +1803,82 @@ function buildStyleHashMembers(segments, options) {
|
|
|
1773
1803
|
flushNormal();
|
|
1774
1804
|
return members;
|
|
1775
1805
|
}
|
|
1806
|
+
function mergeConditionalBranchMembers(members, previousProperties) {
|
|
1807
|
+
return members.map(function(member) {
|
|
1808
|
+
if (!t3.isObjectProperty(member)) {
|
|
1809
|
+
return member;
|
|
1810
|
+
}
|
|
1811
|
+
const prior = previousProperties.get(propertyName(member.key));
|
|
1812
|
+
if (!prior) {
|
|
1813
|
+
return member;
|
|
1814
|
+
}
|
|
1815
|
+
return t3.objectProperty(
|
|
1816
|
+
clonePropertyKey(member.key),
|
|
1817
|
+
mergePropertyValues(prior.value, member.value)
|
|
1818
|
+
);
|
|
1819
|
+
});
|
|
1820
|
+
}
|
|
1821
|
+
function mergePropertyValues(previousValue, currentValue) {
|
|
1822
|
+
if (t3.isStringLiteral(previousValue) && t3.isStringLiteral(currentValue)) {
|
|
1823
|
+
return t3.stringLiteral(`${previousValue.value} ${currentValue.value}`);
|
|
1824
|
+
}
|
|
1825
|
+
if (t3.isStringLiteral(previousValue) && t3.isArrayExpression(currentValue)) {
|
|
1826
|
+
return mergeTupleValue(currentValue, previousValue.value, true);
|
|
1827
|
+
}
|
|
1828
|
+
if (t3.isArrayExpression(previousValue) && t3.isStringLiteral(currentValue)) {
|
|
1829
|
+
return mergeTupleValue(previousValue, currentValue.value, false);
|
|
1830
|
+
}
|
|
1831
|
+
if (t3.isArrayExpression(previousValue) && t3.isArrayExpression(currentValue)) {
|
|
1832
|
+
const previousClassNames = tupleClassNames(previousValue);
|
|
1833
|
+
return mergeTupleValue(currentValue, previousClassNames, true, arrayElementExpression(previousValue.elements[1]));
|
|
1834
|
+
}
|
|
1835
|
+
return t3.cloneNode(currentValue, true);
|
|
1836
|
+
}
|
|
1837
|
+
function mergeTupleValue(tuple, classNames, prependClassNames, previousVars) {
|
|
1838
|
+
const currentClassNames = tupleClassNames(tuple);
|
|
1839
|
+
const mergedClassNames = prependClassNames ? `${classNames} ${currentClassNames}` : `${currentClassNames} ${classNames}`;
|
|
1840
|
+
const varsExpr = tuple.elements[1];
|
|
1841
|
+
const mergedVars = previousVars && arrayElementExpression(varsExpr) ? mergeVarsObject(previousVars, arrayElementExpression(varsExpr)) : arrayElementExpression(varsExpr) ?? previousVars ?? null;
|
|
1842
|
+
return t3.arrayExpression([
|
|
1843
|
+
t3.stringLiteral(mergedClassNames),
|
|
1844
|
+
mergedVars ? t3.cloneNode(mergedVars, true) : t3.objectExpression([])
|
|
1845
|
+
]);
|
|
1846
|
+
}
|
|
1847
|
+
function tupleClassNames(tuple) {
|
|
1848
|
+
const classNames = tuple.elements[0];
|
|
1849
|
+
return t3.isStringLiteral(classNames) ? classNames.value : "";
|
|
1850
|
+
}
|
|
1851
|
+
function arrayElementExpression(element) {
|
|
1852
|
+
return element && !t3.isSpreadElement(element) ? element : null;
|
|
1853
|
+
}
|
|
1854
|
+
function mergeVarsObject(previousVars, currentVars) {
|
|
1855
|
+
if (t3.isObjectExpression(previousVars) && t3.isObjectExpression(currentVars)) {
|
|
1856
|
+
return t3.objectExpression([
|
|
1857
|
+
...previousVars.properties.map(function(property) {
|
|
1858
|
+
return t3.cloneNode(property, true);
|
|
1859
|
+
}),
|
|
1860
|
+
...currentVars.properties.map(function(property) {
|
|
1861
|
+
return t3.cloneNode(property, true);
|
|
1862
|
+
})
|
|
1863
|
+
]);
|
|
1864
|
+
}
|
|
1865
|
+
return t3.cloneNode(currentVars, true);
|
|
1866
|
+
}
|
|
1867
|
+
function propertyName(key) {
|
|
1868
|
+
if (t3.isIdentifier(key)) {
|
|
1869
|
+
return key.name;
|
|
1870
|
+
}
|
|
1871
|
+
if (t3.isStringLiteral(key)) {
|
|
1872
|
+
return key.value;
|
|
1873
|
+
}
|
|
1874
|
+
return generate(key).code;
|
|
1875
|
+
}
|
|
1876
|
+
function clonePropertyKey(key) {
|
|
1877
|
+
if (t3.isPrivateName(key)) {
|
|
1878
|
+
return t3.identifier(key.id.name);
|
|
1879
|
+
}
|
|
1880
|
+
return t3.cloneNode(key, true);
|
|
1881
|
+
}
|
|
1776
1882
|
function injectDebugInfo(expr, line, options) {
|
|
1777
1883
|
if (!options.debug) return;
|
|
1778
1884
|
const firstProp = expr.properties.find(function(p) {
|
|
@@ -1973,7 +2079,6 @@ function transformTruss(code, filename, mapping, options = {}) {
|
|
|
1973
2079
|
skippedCssPropMessages: errorMessages,
|
|
1974
2080
|
runtimeLookupNames
|
|
1975
2081
|
});
|
|
1976
|
-
removeCssImport(ast, cssBindingName);
|
|
1977
2082
|
const runtimeImports = [];
|
|
1978
2083
|
if (needsTrussPropsHelper.current) {
|
|
1979
2084
|
runtimeImports.push({ importedName: "trussProps", localName: trussPropsHelperName });
|
|
@@ -1987,8 +2092,14 @@ function transformTruss(code, filename, mapping, options = {}) {
|
|
|
1987
2092
|
if (options.injectCss) {
|
|
1988
2093
|
runtimeImports.push({ importedName: "__injectTrussCSS", localName: "__injectTrussCSS" });
|
|
1989
2094
|
}
|
|
2095
|
+
const reusedCssImportLine = runtimeImports.length > 0 && findImportDeclaration(ast, "@homebound/truss/runtime") === null && replaceCssImportWithNamedImports(ast, cssBindingName, "@homebound/truss/runtime", runtimeImports);
|
|
2096
|
+
if (!reusedCssImportLine) {
|
|
2097
|
+
removeCssImport(ast, cssBindingName);
|
|
2098
|
+
}
|
|
1990
2099
|
if (runtimeImports.length > 0) {
|
|
1991
|
-
|
|
2100
|
+
if (!reusedCssImportLine) {
|
|
2101
|
+
upsertNamedImports(ast, "@homebound/truss/runtime", runtimeImports);
|
|
2102
|
+
}
|
|
1992
2103
|
}
|
|
1993
2104
|
const declarationsToInsert = [];
|
|
1994
2105
|
if (maybeIncHelperName) {
|
|
@@ -2023,9 +2134,11 @@ function transformTruss(code, filename, mapping, options = {}) {
|
|
|
2023
2134
|
}
|
|
2024
2135
|
const output = generate2(ast, {
|
|
2025
2136
|
sourceFileName: filename,
|
|
2137
|
+
sourceMaps: true,
|
|
2026
2138
|
retainLines: false
|
|
2027
2139
|
});
|
|
2028
|
-
|
|
2140
|
+
const outputCode = preserveBlankLineAfterImports(code, output.code);
|
|
2141
|
+
return { code: outputCode, map: output.map, css: cssText, rules };
|
|
2029
2142
|
}
|
|
2030
2143
|
function collectRuntimeLookups(chains) {
|
|
2031
2144
|
const lookups = /* @__PURE__ */ new Map();
|
|
@@ -2043,6 +2156,31 @@ function collectRuntimeLookups(chains) {
|
|
|
2043
2156
|
}
|
|
2044
2157
|
return lookups;
|
|
2045
2158
|
}
|
|
2159
|
+
function preserveBlankLineAfterImports(input, output) {
|
|
2160
|
+
const inputLines = input.split("\n");
|
|
2161
|
+
const outputLines = output.split("\n");
|
|
2162
|
+
const lastInputImportLine = findLastImportLine(inputLines);
|
|
2163
|
+
const lastOutputImportLine = findLastImportLine(outputLines);
|
|
2164
|
+
if (lastInputImportLine === -1 || lastOutputImportLine === -1) {
|
|
2165
|
+
return output;
|
|
2166
|
+
}
|
|
2167
|
+
const inputHasBlankLineAfterImports = inputLines[lastInputImportLine + 1]?.trim() === "";
|
|
2168
|
+
const outputHasBlankLineAfterImports = outputLines[lastOutputImportLine + 1]?.trim() === "";
|
|
2169
|
+
if (!inputHasBlankLineAfterImports || outputHasBlankLineAfterImports) {
|
|
2170
|
+
return output;
|
|
2171
|
+
}
|
|
2172
|
+
outputLines.splice(lastOutputImportLine + 1, 0, "");
|
|
2173
|
+
return outputLines.join("\n");
|
|
2174
|
+
}
|
|
2175
|
+
function findLastImportLine(lines) {
|
|
2176
|
+
let lastImportLine = -1;
|
|
2177
|
+
for (let index = 0; index < lines.length; index++) {
|
|
2178
|
+
if (lines[index].trimStart().startsWith("import ")) {
|
|
2179
|
+
lastImportLine = index;
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
return lastImportLine;
|
|
2183
|
+
}
|
|
2046
2184
|
|
|
2047
2185
|
// src/plugin/transform-css.ts
|
|
2048
2186
|
import { parse as parse2 } from "@babel/parser";
|