@plumeria/unplugin 18.3.18 → 18.4.1
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/README.md +4 -0
- package/dist/core.d.ts +2 -1
- package/dist/core.js +96 -172
- package/dist/core.mjs +95 -171
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -156,6 +156,10 @@ plumeria.vite({
|
|
|
156
156
|
| `exclude` | — | Files to skip. |
|
|
157
157
|
| `devEmitToDisk` | `false` | Write CSS to disk in development so the bundler's watcher drives HMR. |
|
|
158
158
|
| `styleProp` | `'classStyle'` | The JSX prop that carries styles. |
|
|
159
|
+
| `withoutLogicalProperties` | `false` | Reject the logical name of a property that also has a physical name. Takes `true` or `{ sizes?: boolean }`. |
|
|
160
|
+
| `withoutPhysicalProperties` | `false` | Reject the physical name of a property that also has a logical name. Takes `true` or `{ sizes?: boolean }`. |
|
|
161
|
+
|
|
162
|
+
The two spelling options contradict each other, so enabling both is a configuration error. See [the docs](https://plumeria.dev/docs/api-reference/plugins/unplugin) for why the pair has to be settled and how it lines up with the lint rules.
|
|
159
163
|
|
|
160
164
|
### styleProp
|
|
161
165
|
|
package/dist/core.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { UnpluginFactory } from 'unplugin';
|
|
2
|
-
|
|
2
|
+
import type { PropertyPolicyOptions } from '@plumeria/utils';
|
|
3
|
+
export interface PluginOptions extends PropertyPolicyOptions {
|
|
3
4
|
include?: string | RegExp | Array<string | RegExp>;
|
|
4
5
|
exclude?: string | RegExp | Array<string | RegExp>;
|
|
5
6
|
devEmitToDisk?: boolean;
|
package/dist/core.js
CHANGED
|
@@ -71,81 +71,6 @@ const isStaticArgValue = (node) => node.type === 'StringLiteral' ||
|
|
|
71
71
|
(node.type === 'TemplateLiteral' && node.expressions.length === 0) ||
|
|
72
72
|
utils_1.t.isIdentifier(node) ||
|
|
73
73
|
utils_1.t.isMemberExpression(node);
|
|
74
|
-
const namedParamsOf = (params, defaults) => {
|
|
75
|
-
if (params.length !== 1)
|
|
76
|
-
return undefined;
|
|
77
|
-
const first = params[0];
|
|
78
|
-
const pattern = (first?.pat ?? first);
|
|
79
|
-
if (pattern?.type !== 'ObjectPattern')
|
|
80
|
-
return undefined;
|
|
81
|
-
const named = [];
|
|
82
|
-
for (const prop of pattern.properties ?? []) {
|
|
83
|
-
if (prop.type === 'AssignmentPatternProperty' && utils_1.t.isIdentifier(prop.key)) {
|
|
84
|
-
named.push({ key: prop.key.value, local: prop.key.value });
|
|
85
|
-
if (prop.value)
|
|
86
|
-
defaults[prop.key.value] = prop.value;
|
|
87
|
-
}
|
|
88
|
-
else if (prop.type === 'KeyValuePatternProperty' &&
|
|
89
|
-
utils_1.t.isIdentifier(prop.key) &&
|
|
90
|
-
utils_1.t.isIdentifier(prop.value)) {
|
|
91
|
-
named.push({ key: prop.key.value, local: prop.value.value });
|
|
92
|
-
}
|
|
93
|
-
else if (prop.type === 'KeyValuePatternProperty' &&
|
|
94
|
-
utils_1.t.isIdentifier(prop.key) &&
|
|
95
|
-
prop.value?.type === 'AssignmentPattern' &&
|
|
96
|
-
utils_1.t.isIdentifier(prop.value.left)) {
|
|
97
|
-
const pattern = prop.value;
|
|
98
|
-
named.push({ key: String(prop.key.value), local: pattern.left.value });
|
|
99
|
-
defaults[pattern.left.value] = pattern.right;
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
return undefined;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return named.length > 0 ? named : undefined;
|
|
106
|
-
};
|
|
107
|
-
const styleFunctionsOf = (objExpr) => {
|
|
108
|
-
const styleFunctions = {};
|
|
109
|
-
objExpr.properties.forEach((prop) => {
|
|
110
|
-
if (prop.type !== 'KeyValueProperty' || prop.key.type !== 'Identifier')
|
|
111
|
-
return;
|
|
112
|
-
const func = prop.value;
|
|
113
|
-
if (func.type !== 'ArrowFunctionExpression' &&
|
|
114
|
-
func.type !== 'FunctionExpression')
|
|
115
|
-
return;
|
|
116
|
-
const defaults = {};
|
|
117
|
-
const params = func.params.map((p) => {
|
|
118
|
-
const pattern = typeof p === 'object' && p !== null && 'pat' in p ? p.pat : p;
|
|
119
|
-
if (utils_1.t.isIdentifier(pattern))
|
|
120
|
-
return pattern.value;
|
|
121
|
-
if (pattern?.type === 'AssignmentPattern' &&
|
|
122
|
-
utils_1.t.isIdentifier(pattern.left)) {
|
|
123
|
-
defaults[pattern.left.value] = pattern.right;
|
|
124
|
-
return pattern.left.value;
|
|
125
|
-
}
|
|
126
|
-
return 'arg';
|
|
127
|
-
});
|
|
128
|
-
let actualBody = func.body;
|
|
129
|
-
if (actualBody?.type === 'ParenthesisExpression')
|
|
130
|
-
actualBody = actualBody.expression;
|
|
131
|
-
if (actualBody?.type === 'BlockStatement') {
|
|
132
|
-
const first = actualBody.stmts?.[0];
|
|
133
|
-
if (first?.type === 'ReturnStatement')
|
|
134
|
-
actualBody = first.argument;
|
|
135
|
-
if (actualBody?.type === 'ParenthesisExpression')
|
|
136
|
-
actualBody = actualBody.expression;
|
|
137
|
-
}
|
|
138
|
-
if (actualBody && actualBody.type === 'ObjectExpression') {
|
|
139
|
-
styleFunctions[prop.key.value] = {
|
|
140
|
-
params,
|
|
141
|
-
named: namedParamsOf(func.params, defaults),
|
|
142
|
-
defaults,
|
|
143
|
-
body: actualBody,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
return styleFunctions;
|
|
148
|
-
};
|
|
149
74
|
const foldDynamicVars = (vars) => {
|
|
150
75
|
const grouped = new Map();
|
|
151
76
|
[...vars]
|
|
@@ -167,61 +92,9 @@ const foldDynamicVars = (vars) => {
|
|
|
167
92
|
return `"${cssVar}": ${value}`;
|
|
168
93
|
});
|
|
169
94
|
};
|
|
170
|
-
const isUnitlessProp = (prop) => zss_engine_1.exceptionCamelCase.includes(prop) || prop.startsWith('--');
|
|
171
|
-
const collectVarProps = (style, cssVar, props) => {
|
|
172
|
-
const reference = `var(${cssVar})`;
|
|
173
|
-
for (const [prop, value] of Object.entries(style)) {
|
|
174
|
-
if (typeof value === 'string' && value.includes(reference))
|
|
175
|
-
props.push(prop);
|
|
176
|
-
else if (value !== null && typeof value === 'object')
|
|
177
|
-
collectVarProps(value, cssVar, props);
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
const retargetVar = (style, cssVar, next, unitless) => {
|
|
181
|
-
const reference = `var(${cssVar})`;
|
|
182
|
-
for (const [prop, value] of Object.entries(style)) {
|
|
183
|
-
if (typeof value === 'string' && value.includes(reference)) {
|
|
184
|
-
if (isUnitlessProp(prop) === unitless)
|
|
185
|
-
style[prop] = value
|
|
186
|
-
.split(reference)
|
|
187
|
-
.join(`var(${next})`);
|
|
188
|
-
}
|
|
189
|
-
else if (value !== null && typeof value === 'object') {
|
|
190
|
-
retargetVar(value, cssVar, next, unitless);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
const splitVarByUnit = (style, cssVar) => {
|
|
195
|
-
const props = [];
|
|
196
|
-
collectVarProps(style, cssVar, props);
|
|
197
|
-
if (props.length === 0)
|
|
198
|
-
return [];
|
|
199
|
-
const lead = props[0];
|
|
200
|
-
const split = props.find((prop) => isUnitlessProp(prop) !== isUnitlessProp(lead));
|
|
201
|
-
if (!split)
|
|
202
|
-
return [{ cssVar, prop: lead }];
|
|
203
|
-
const splitVar = `${cssVar}-${(0, zss_engine_1.camelToKebabCase)(split).replace(/^-+/, '')}`;
|
|
204
|
-
retargetVar(style, cssVar, splitVar, isUnitlessProp(split));
|
|
205
|
-
return [
|
|
206
|
-
{ cssVar, prop: lead },
|
|
207
|
-
{ cssVar: splitVar, prop: split },
|
|
208
|
-
];
|
|
209
|
-
};
|
|
210
|
-
const applyVarFallback = (style, cssVar, literal) => {
|
|
211
|
-
const reference = `var(${cssVar})`;
|
|
212
|
-
for (const [prop, value] of Object.entries(style)) {
|
|
213
|
-
if (typeof value === 'string' && value.includes(reference)) {
|
|
214
|
-
style[prop] = value
|
|
215
|
-
.split(reference)
|
|
216
|
-
.join(`var(${cssVar}, ${(0, zss_engine_1.applyCssValue)(literal, (0, zss_engine_1.camelToKebabCase)(prop))})`);
|
|
217
|
-
}
|
|
218
|
-
else if (value !== null && typeof value === 'object') {
|
|
219
|
-
applyVarFallback(value, cssVar, literal);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
95
|
const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
224
96
|
const filter = (0, pluginutils_1.createFilter)(options.include, options.exclude);
|
|
97
|
+
const propertyPolicy = (0, utils_1.resolvePropertyPolicy)(options);
|
|
225
98
|
const styleProp = options.styleProp ?? utils_1.DEFAULT_STYLE_PROP;
|
|
226
99
|
const cssLookup = new Map();
|
|
227
100
|
const cssFileLookup = new Map();
|
|
@@ -291,6 +164,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
291
164
|
tsx: true,
|
|
292
165
|
target: 'es2022',
|
|
293
166
|
});
|
|
167
|
+
(0, utils_1.assertPropertyPolicy)(ast, propertyPolicy, id);
|
|
294
168
|
const leadingLen = (0, utils_1.getLeadingCommentLength)(source);
|
|
295
169
|
const sourceBuffer = Buffer.from(source, 'utf-8');
|
|
296
170
|
const leadingBytes = Buffer.byteLength(source.slice(0, leadingLen), 'utf-8');
|
|
@@ -491,7 +365,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
491
365
|
scannedTables.createHashTable[uniqueKey];
|
|
492
366
|
}
|
|
493
367
|
if (scannedTables.createFunctionTable[uniqueKey]) {
|
|
494
|
-
createFunctionImportMap[localName] = styleFunctionsOf(scannedTables.createFunctionTable[uniqueKey]);
|
|
368
|
+
createFunctionImportMap[localName] = (0, utils_1.styleFunctionsOf)(scannedTables.createFunctionTable[uniqueKey]);
|
|
495
369
|
}
|
|
496
370
|
if (scannedTables.variantsHashTable[uniqueKey]) {
|
|
497
371
|
variantsImportMap[localName] =
|
|
@@ -592,6 +466,16 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
592
466
|
for (const key of Object.keys(createStaticImportMap)) {
|
|
593
467
|
mergedCreateStaticHashTable[key] = createStaticImportMap[key];
|
|
594
468
|
}
|
|
469
|
+
const dynamicStyleTables = {
|
|
470
|
+
keyframesHashTable: mergedKeyframesTable,
|
|
471
|
+
viewTransitionHashTable: mergedViewTransitionTable,
|
|
472
|
+
createThemeHashTable: mergedCreateThemeHashTable,
|
|
473
|
+
createThemeObjectTable: scannedTables.createThemeObjectTable,
|
|
474
|
+
createHashTable: mergedCreateTable,
|
|
475
|
+
createStaticHashTable: mergedCreateStaticHashTable,
|
|
476
|
+
createStaticObjectTable: scannedTables.createStaticObjectTable,
|
|
477
|
+
variantsHashTable: mergedVariantsTable,
|
|
478
|
+
};
|
|
595
479
|
const localCreateStyles = {};
|
|
596
480
|
const localStyleAliases = {};
|
|
597
481
|
const checkStyleAliasAssignment = (decl) => {
|
|
@@ -652,7 +536,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
652
536
|
records.forEach((r) => (atomMap[r.key] = r.hash));
|
|
653
537
|
hashMap[key] = atomMap;
|
|
654
538
|
});
|
|
655
|
-
const styleFunctions = styleFunctionsOf(init.arguments[0].expression);
|
|
539
|
+
const styleFunctions = (0, utils_1.styleFunctionsOf)(init.arguments[0].expression);
|
|
656
540
|
if (utils_1.t.isIdentifier(node.id)) {
|
|
657
541
|
idSpans.add(node.id.span.start);
|
|
658
542
|
}
|
|
@@ -993,7 +877,16 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
993
877
|
}
|
|
994
878
|
return null;
|
|
995
879
|
};
|
|
996
|
-
const
|
|
880
|
+
const isStyleFunctionCall = (expr) => {
|
|
881
|
+
if (!utils_1.t.isCallExpression(expr) || !utils_1.t.isMemberExpression(expr.callee))
|
|
882
|
+
return false;
|
|
883
|
+
const callee = expr.callee;
|
|
884
|
+
if (!utils_1.t.isIdentifier(callee.object) || !utils_1.t.isIdentifier(callee.property))
|
|
885
|
+
return false;
|
|
886
|
+
return Boolean(localCreateStyles[callee.object.value]?.functions?.[callee.property.value] ??
|
|
887
|
+
createFunctionImportMap[callee.object.value]?.[callee.property.value]);
|
|
888
|
+
};
|
|
889
|
+
const resolveDynamicCall = (expr, forceRuntime = false) => {
|
|
997
890
|
if (!utils_1.t.isCallExpression(expr) || !utils_1.t.isMemberExpression(expr.callee))
|
|
998
891
|
return null;
|
|
999
892
|
const callee = expr.callee;
|
|
@@ -1037,7 +930,9 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1037
930
|
throwCompilationError(`Plumeria: ${getSource(expr)} leaves "${key}" unset, and a dynamic style function has no value to fall back on.`, expr);
|
|
1038
931
|
return;
|
|
1039
932
|
}
|
|
1040
|
-
if (
|
|
933
|
+
if (!forceRuntime &&
|
|
934
|
+
isStaticArgValue(source) &&
|
|
935
|
+
argObj[key] !== undefined)
|
|
1041
936
|
tempStaticTable[local] = argObj[key];
|
|
1042
937
|
else
|
|
1043
938
|
runtime.push({ param: local, source });
|
|
@@ -1045,6 +940,8 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1045
940
|
}
|
|
1046
941
|
else if (callArgs.length === 1 &&
|
|
1047
942
|
callArgs[0].expression.type === 'ObjectExpression') {
|
|
943
|
+
if (forceRuntime)
|
|
944
|
+
return null;
|
|
1048
945
|
const argObj = resolveObjectArg(callArgs[0].expression) ?? {};
|
|
1049
946
|
func.params.forEach((p) => {
|
|
1050
947
|
if (argObj[p] !== undefined)
|
|
@@ -1059,39 +956,10 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1059
956
|
runtime.push({ param: p, source: callArg.expression });
|
|
1060
957
|
});
|
|
1061
958
|
}
|
|
1062
|
-
const
|
|
1063
|
-
|
|
1064
|
-
const varParams = Array.from(new Set([
|
|
1065
|
-
...runtime.map(({ param }) => param),
|
|
1066
|
-
...withDefault.map(([param]) => param),
|
|
1067
|
-
]));
|
|
1068
|
-
if (varParams.length > 0) {
|
|
1069
|
-
varParams.forEach((param) => (tempStaticTable[param] = param));
|
|
1070
|
-
const probe = (0, utils_1.objectExpressionToObject)(func.body, tempStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
|
|
1071
|
-
const hash = (0, zss_engine_1.genBase36Hash)(probe ?? {}, 1, 8);
|
|
1072
|
-
varParams.forEach((param) => {
|
|
1073
|
-
const cssVar = `--${hash}-${param}`;
|
|
1074
|
-
tempStaticTable[param] = `var(${cssVar})`;
|
|
1075
|
-
cssVars[param] = cssVar;
|
|
1076
|
-
});
|
|
1077
|
-
}
|
|
1078
|
-
const style = (0, utils_1.objectExpressionToObject)(func.body, tempStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
|
|
1079
|
-
if (!style)
|
|
959
|
+
const resolved = (0, utils_1.resolveDynamicStyle)(func, runtime.map(({ param }) => param), tempStaticTable, dynamicStyleTables);
|
|
960
|
+
if (!resolved)
|
|
1080
961
|
return null;
|
|
1081
|
-
const varGroups =
|
|
1082
|
-
varParams.forEach((param) => {
|
|
1083
|
-
const cssVar = cssVars[param];
|
|
1084
|
-
if (cssVar)
|
|
1085
|
-
varGroups.set(param, splitVarByUnit(style, cssVar));
|
|
1086
|
-
});
|
|
1087
|
-
withDefault.forEach(([param, expr]) => {
|
|
1088
|
-
const literal = expr.type === 'StringLiteral' || expr.type === 'NumericLiteral'
|
|
1089
|
-
? expr.value
|
|
1090
|
-
: undefined;
|
|
1091
|
-
if (literal === undefined)
|
|
1092
|
-
return;
|
|
1093
|
-
(varGroups.get(param) ?? []).forEach(({ cssVar }) => applyVarFallback(style, cssVar, literal));
|
|
1094
|
-
});
|
|
962
|
+
const { style, varGroups } = resolved;
|
|
1095
963
|
const vars = [];
|
|
1096
964
|
runtime.forEach(({ param, source }) => {
|
|
1097
965
|
const groups = varGroups.get(param);
|
|
@@ -1115,7 +983,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1115
983
|
valueExpr = JSON.stringify((0, zss_engine_1.applyCssValue)(argSource.slice(1, -1), kebabProp));
|
|
1116
984
|
}
|
|
1117
985
|
else {
|
|
1118
|
-
valueExpr = isUnitlessProp(prop)
|
|
986
|
+
valueExpr = (0, utils_1.isUnitlessProp)(prop)
|
|
1119
987
|
? argSource
|
|
1120
988
|
: `(typeof (${argSource}) === 'number' ? (${argSource}) + 'px' : (${argSource}))`;
|
|
1121
989
|
}
|
|
@@ -1133,6 +1001,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1133
1001
|
});
|
|
1134
1002
|
const conditionals = [];
|
|
1135
1003
|
const dynamicVars = [];
|
|
1004
|
+
const propVarSpreads = [];
|
|
1136
1005
|
let groupIdCounter = 0;
|
|
1137
1006
|
let sourceOrder = 0;
|
|
1138
1007
|
const baseChunks = [];
|
|
@@ -1351,9 +1220,23 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1351
1220
|
}
|
|
1352
1221
|
if (!possibilities || possibilities.length === 0)
|
|
1353
1222
|
return false;
|
|
1354
|
-
const
|
|
1355
|
-
|
|
1223
|
+
const carriesVars = possibilities.some((entry) => entry.hasVars);
|
|
1224
|
+
if (carriesVars && !isStyleProp) {
|
|
1225
|
+
throwCompilationError(`Plumeria: "${varName}" carries a dynamic function key, and css.use() returns only a class name. ` +
|
|
1226
|
+
`Apply it to ${styleProp} on the element instead.`, expr);
|
|
1227
|
+
}
|
|
1228
|
+
const gate = gates.length ? `(${gates.join(' && ')}) && ` : '';
|
|
1229
|
+
if (carriesVars) {
|
|
1230
|
+
const spread = `...(${gate}${source} && ${source}.vars)`;
|
|
1231
|
+
if (!propVarSpreads.includes(spread))
|
|
1232
|
+
propVarSpreads.push(spread);
|
|
1233
|
+
}
|
|
1234
|
+
const token = carriesVars
|
|
1235
|
+
? `((${source} && ${source}.key) || ${source})`
|
|
1356
1236
|
: source;
|
|
1237
|
+
const testLHS = gates.length
|
|
1238
|
+
? `((${gates.join(' && ')}) ? ${token} : "")`
|
|
1239
|
+
: token;
|
|
1357
1240
|
const currentGroupId = ++groupIdCounter;
|
|
1358
1241
|
const currentOrder = sourceOrder++;
|
|
1359
1242
|
const seen = new Set();
|
|
@@ -1592,6 +1475,7 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1592
1475
|
isOptimizable,
|
|
1593
1476
|
baseStyle,
|
|
1594
1477
|
dynamicVars,
|
|
1478
|
+
propVarSpreads,
|
|
1595
1479
|
};
|
|
1596
1480
|
}
|
|
1597
1481
|
const stateSources = baseChunks.map(({ order, style }) => ({ order, style: style }));
|
|
@@ -1847,7 +1731,13 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1847
1731
|
classParts.push(`(${JSON.stringify(results)}[${masterKeyExpr || '""'}] || ${baseConflictClass ? JSON.stringify(baseConflictClass) : '""'})`);
|
|
1848
1732
|
}
|
|
1849
1733
|
classParts.push(...dynamicClassParts);
|
|
1850
|
-
return {
|
|
1734
|
+
return {
|
|
1735
|
+
classParts,
|
|
1736
|
+
isOptimizable,
|
|
1737
|
+
baseStyle,
|
|
1738
|
+
dynamicVars,
|
|
1739
|
+
propVarSpreads,
|
|
1740
|
+
};
|
|
1851
1741
|
};
|
|
1852
1742
|
(0, utils_1.traverse)(ast, {
|
|
1853
1743
|
JSXOpeningElement({ node }) {
|
|
@@ -2048,14 +1938,40 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
2048
1938
|
node.value &&
|
|
2049
1939
|
node.value.type === 'JSXExpressionContainer') {
|
|
2050
1940
|
const expr = node.value.expression;
|
|
1941
|
+
const carrierFor = (subNode) => {
|
|
1942
|
+
const vars = [];
|
|
1943
|
+
let unresolved = false;
|
|
1944
|
+
(0, utils_1.traverse)(subNode, {
|
|
1945
|
+
CallExpression({ node: call }) {
|
|
1946
|
+
if (!isStyleFunctionCall(call))
|
|
1947
|
+
return;
|
|
1948
|
+
const resolved = resolveDynamicCall(call, true);
|
|
1949
|
+
if (!resolved) {
|
|
1950
|
+
unresolved = true;
|
|
1951
|
+
return;
|
|
1952
|
+
}
|
|
1953
|
+
vars.push(...resolved.vars);
|
|
1954
|
+
},
|
|
1955
|
+
});
|
|
1956
|
+
if (unresolved)
|
|
1957
|
+
return null;
|
|
1958
|
+
return `{ ${foldDynamicVars(vars).join(', ')} }`;
|
|
1959
|
+
};
|
|
2051
1960
|
const replaceWithKey = (subNode) => {
|
|
2052
1961
|
const entry = list.find((x) => x.spanStart === subNode.span.start &&
|
|
2053
1962
|
x.filePath === resourcePath);
|
|
2054
1963
|
if (entry) {
|
|
1964
|
+
let content = JSON.stringify(entry.key);
|
|
1965
|
+
if (entry.hasVars) {
|
|
1966
|
+
const carrier = carrierFor(subNode);
|
|
1967
|
+
if (!carrier)
|
|
1968
|
+
return false;
|
|
1969
|
+
content = `{ key: ${content}, vars: ${carrier} }`;
|
|
1970
|
+
}
|
|
2055
1971
|
replacements.push({
|
|
2056
1972
|
start: subNode.span.start - baseByteOffset,
|
|
2057
1973
|
end: subNode.span.end - baseByteOffset,
|
|
2058
|
-
content
|
|
1974
|
+
content,
|
|
2059
1975
|
});
|
|
2060
1976
|
processStyleRecords(entry.styleObj);
|
|
2061
1977
|
return true;
|
|
@@ -2073,6 +1989,11 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
2073
1989
|
excludeSubtreeSpans(subNode);
|
|
2074
1990
|
}
|
|
2075
1991
|
},
|
|
1992
|
+
CallExpression({ node: subNode }) {
|
|
1993
|
+
if (replaceWithKey(subNode)) {
|
|
1994
|
+
excludeSubtreeSpans(subNode);
|
|
1995
|
+
}
|
|
1996
|
+
},
|
|
2076
1997
|
});
|
|
2077
1998
|
}
|
|
2078
1999
|
}
|
|
@@ -2148,9 +2069,12 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
2148
2069
|
}
|
|
2149
2070
|
}
|
|
2150
2071
|
}
|
|
2151
|
-
const { classParts, isOptimizable, baseStyle, dynamicVars } = buildClassParts(args, dynamicClassParts, existingClassExpr, true);
|
|
2152
|
-
const
|
|
2153
|
-
|
|
2072
|
+
const { classParts, isOptimizable, baseStyle, dynamicVars, propVarSpreads, } = buildClassParts(args, dynamicClassParts, existingClassExpr, true);
|
|
2073
|
+
const styleParts = [
|
|
2074
|
+
...existingStyleParts,
|
|
2075
|
+
...foldDynamicVars(dynamicVars),
|
|
2076
|
+
...propVarSpreads,
|
|
2077
|
+
];
|
|
2154
2078
|
const styleAttr = styleParts.length > 0 || existingStyleExpr
|
|
2155
2079
|
? ` style={{ ${[existingStyleExpr, ...styleParts].filter(Boolean).join(', ')} }}`
|
|
2156
2080
|
: '';
|
package/dist/core.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createFilter } from '@rollup/pluginutils';
|
|
2
2
|
import { parseSync } from '@swc/core';
|
|
3
3
|
import * as path from 'path';
|
|
4
|
-
import { applyCssValue, genBase36Hash,
|
|
5
|
-
import { traverse, collectReferenceIdentifiers, getStyleRecords, getStateWeights, collectLocalConsts, objectExpressionToObject, t, getRootIdentifier, extractOndemandStyles, deepMerge, scanAll, resolveFileError, resolveImportPath, getLeadingCommentLength, optimizer, themeHashOf, getFileDependencies, resolveExport, resolveComponentKey, resolveThemeSelector, DEFAULT_STYLE_PROP, } from '@plumeria/utils';
|
|
4
|
+
import { applyCssValue, genBase36Hash, camelToKebabCase, isAtRule, } from 'zss-engine';
|
|
5
|
+
import { traverse, resolvePropertyPolicy, assertPropertyPolicy, collectReferenceIdentifiers, getStyleRecords, getStateWeights, collectLocalConsts, objectExpressionToObject, t, getRootIdentifier, extractOndemandStyles, deepMerge, scanAll, resolveFileError, resolveImportPath, getLeadingCommentLength, optimizer, styleFunctionsOf, isUnitlessProp, resolveDynamicStyle, themeHashOf, getFileDependencies, resolveExport, resolveComponentKey, resolveThemeSelector, DEFAULT_STYLE_PROP, } from '@plumeria/utils';
|
|
6
6
|
export const TARGET_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx'];
|
|
7
7
|
export const EXTENSION_PATTERN = /\.(ts|tsx|js|jsx)$/;
|
|
8
8
|
const unwrapExport = (node) => {
|
|
@@ -35,81 +35,6 @@ const isStaticArgValue = (node) => node.type === 'StringLiteral' ||
|
|
|
35
35
|
(node.type === 'TemplateLiteral' && node.expressions.length === 0) ||
|
|
36
36
|
t.isIdentifier(node) ||
|
|
37
37
|
t.isMemberExpression(node);
|
|
38
|
-
const namedParamsOf = (params, defaults) => {
|
|
39
|
-
if (params.length !== 1)
|
|
40
|
-
return undefined;
|
|
41
|
-
const first = params[0];
|
|
42
|
-
const pattern = (first?.pat ?? first);
|
|
43
|
-
if (pattern?.type !== 'ObjectPattern')
|
|
44
|
-
return undefined;
|
|
45
|
-
const named = [];
|
|
46
|
-
for (const prop of pattern.properties ?? []) {
|
|
47
|
-
if (prop.type === 'AssignmentPatternProperty' && t.isIdentifier(prop.key)) {
|
|
48
|
-
named.push({ key: prop.key.value, local: prop.key.value });
|
|
49
|
-
if (prop.value)
|
|
50
|
-
defaults[prop.key.value] = prop.value;
|
|
51
|
-
}
|
|
52
|
-
else if (prop.type === 'KeyValuePatternProperty' &&
|
|
53
|
-
t.isIdentifier(prop.key) &&
|
|
54
|
-
t.isIdentifier(prop.value)) {
|
|
55
|
-
named.push({ key: prop.key.value, local: prop.value.value });
|
|
56
|
-
}
|
|
57
|
-
else if (prop.type === 'KeyValuePatternProperty' &&
|
|
58
|
-
t.isIdentifier(prop.key) &&
|
|
59
|
-
prop.value?.type === 'AssignmentPattern' &&
|
|
60
|
-
t.isIdentifier(prop.value.left)) {
|
|
61
|
-
const pattern = prop.value;
|
|
62
|
-
named.push({ key: String(prop.key.value), local: pattern.left.value });
|
|
63
|
-
defaults[pattern.left.value] = pattern.right;
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
return undefined;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return named.length > 0 ? named : undefined;
|
|
70
|
-
};
|
|
71
|
-
const styleFunctionsOf = (objExpr) => {
|
|
72
|
-
const styleFunctions = {};
|
|
73
|
-
objExpr.properties.forEach((prop) => {
|
|
74
|
-
if (prop.type !== 'KeyValueProperty' || prop.key.type !== 'Identifier')
|
|
75
|
-
return;
|
|
76
|
-
const func = prop.value;
|
|
77
|
-
if (func.type !== 'ArrowFunctionExpression' &&
|
|
78
|
-
func.type !== 'FunctionExpression')
|
|
79
|
-
return;
|
|
80
|
-
const defaults = {};
|
|
81
|
-
const params = func.params.map((p) => {
|
|
82
|
-
const pattern = typeof p === 'object' && p !== null && 'pat' in p ? p.pat : p;
|
|
83
|
-
if (t.isIdentifier(pattern))
|
|
84
|
-
return pattern.value;
|
|
85
|
-
if (pattern?.type === 'AssignmentPattern' &&
|
|
86
|
-
t.isIdentifier(pattern.left)) {
|
|
87
|
-
defaults[pattern.left.value] = pattern.right;
|
|
88
|
-
return pattern.left.value;
|
|
89
|
-
}
|
|
90
|
-
return 'arg';
|
|
91
|
-
});
|
|
92
|
-
let actualBody = func.body;
|
|
93
|
-
if (actualBody?.type === 'ParenthesisExpression')
|
|
94
|
-
actualBody = actualBody.expression;
|
|
95
|
-
if (actualBody?.type === 'BlockStatement') {
|
|
96
|
-
const first = actualBody.stmts?.[0];
|
|
97
|
-
if (first?.type === 'ReturnStatement')
|
|
98
|
-
actualBody = first.argument;
|
|
99
|
-
if (actualBody?.type === 'ParenthesisExpression')
|
|
100
|
-
actualBody = actualBody.expression;
|
|
101
|
-
}
|
|
102
|
-
if (actualBody && actualBody.type === 'ObjectExpression') {
|
|
103
|
-
styleFunctions[prop.key.value] = {
|
|
104
|
-
params,
|
|
105
|
-
named: namedParamsOf(func.params, defaults),
|
|
106
|
-
defaults,
|
|
107
|
-
body: actualBody,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
return styleFunctions;
|
|
112
|
-
};
|
|
113
38
|
const foldDynamicVars = (vars) => {
|
|
114
39
|
const grouped = new Map();
|
|
115
40
|
[...vars]
|
|
@@ -131,61 +56,9 @@ const foldDynamicVars = (vars) => {
|
|
|
131
56
|
return `"${cssVar}": ${value}`;
|
|
132
57
|
});
|
|
133
58
|
};
|
|
134
|
-
const isUnitlessProp = (prop) => exceptionCamelCase.includes(prop) || prop.startsWith('--');
|
|
135
|
-
const collectVarProps = (style, cssVar, props) => {
|
|
136
|
-
const reference = `var(${cssVar})`;
|
|
137
|
-
for (const [prop, value] of Object.entries(style)) {
|
|
138
|
-
if (typeof value === 'string' && value.includes(reference))
|
|
139
|
-
props.push(prop);
|
|
140
|
-
else if (value !== null && typeof value === 'object')
|
|
141
|
-
collectVarProps(value, cssVar, props);
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
const retargetVar = (style, cssVar, next, unitless) => {
|
|
145
|
-
const reference = `var(${cssVar})`;
|
|
146
|
-
for (const [prop, value] of Object.entries(style)) {
|
|
147
|
-
if (typeof value === 'string' && value.includes(reference)) {
|
|
148
|
-
if (isUnitlessProp(prop) === unitless)
|
|
149
|
-
style[prop] = value
|
|
150
|
-
.split(reference)
|
|
151
|
-
.join(`var(${next})`);
|
|
152
|
-
}
|
|
153
|
-
else if (value !== null && typeof value === 'object') {
|
|
154
|
-
retargetVar(value, cssVar, next, unitless);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
const splitVarByUnit = (style, cssVar) => {
|
|
159
|
-
const props = [];
|
|
160
|
-
collectVarProps(style, cssVar, props);
|
|
161
|
-
if (props.length === 0)
|
|
162
|
-
return [];
|
|
163
|
-
const lead = props[0];
|
|
164
|
-
const split = props.find((prop) => isUnitlessProp(prop) !== isUnitlessProp(lead));
|
|
165
|
-
if (!split)
|
|
166
|
-
return [{ cssVar, prop: lead }];
|
|
167
|
-
const splitVar = `${cssVar}-${camelToKebabCase(split).replace(/^-+/, '')}`;
|
|
168
|
-
retargetVar(style, cssVar, splitVar, isUnitlessProp(split));
|
|
169
|
-
return [
|
|
170
|
-
{ cssVar, prop: lead },
|
|
171
|
-
{ cssVar: splitVar, prop: split },
|
|
172
|
-
];
|
|
173
|
-
};
|
|
174
|
-
const applyVarFallback = (style, cssVar, literal) => {
|
|
175
|
-
const reference = `var(${cssVar})`;
|
|
176
|
-
for (const [prop, value] of Object.entries(style)) {
|
|
177
|
-
if (typeof value === 'string' && value.includes(reference)) {
|
|
178
|
-
style[prop] = value
|
|
179
|
-
.split(reference)
|
|
180
|
-
.join(`var(${cssVar}, ${applyCssValue(literal, camelToKebabCase(prop))})`);
|
|
181
|
-
}
|
|
182
|
-
else if (value !== null && typeof value === 'object') {
|
|
183
|
-
applyVarFallback(value, cssVar, literal);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
59
|
export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
188
60
|
const filter = createFilter(options.include, options.exclude);
|
|
61
|
+
const propertyPolicy = resolvePropertyPolicy(options);
|
|
189
62
|
const styleProp = options.styleProp ?? DEFAULT_STYLE_PROP;
|
|
190
63
|
const cssLookup = new Map();
|
|
191
64
|
const cssFileLookup = new Map();
|
|
@@ -255,6 +128,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
255
128
|
tsx: true,
|
|
256
129
|
target: 'es2022',
|
|
257
130
|
});
|
|
131
|
+
assertPropertyPolicy(ast, propertyPolicy, id);
|
|
258
132
|
const leadingLen = getLeadingCommentLength(source);
|
|
259
133
|
const sourceBuffer = Buffer.from(source, 'utf-8');
|
|
260
134
|
const leadingBytes = Buffer.byteLength(source.slice(0, leadingLen), 'utf-8');
|
|
@@ -556,6 +430,16 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
556
430
|
for (const key of Object.keys(createStaticImportMap)) {
|
|
557
431
|
mergedCreateStaticHashTable[key] = createStaticImportMap[key];
|
|
558
432
|
}
|
|
433
|
+
const dynamicStyleTables = {
|
|
434
|
+
keyframesHashTable: mergedKeyframesTable,
|
|
435
|
+
viewTransitionHashTable: mergedViewTransitionTable,
|
|
436
|
+
createThemeHashTable: mergedCreateThemeHashTable,
|
|
437
|
+
createThemeObjectTable: scannedTables.createThemeObjectTable,
|
|
438
|
+
createHashTable: mergedCreateTable,
|
|
439
|
+
createStaticHashTable: mergedCreateStaticHashTable,
|
|
440
|
+
createStaticObjectTable: scannedTables.createStaticObjectTable,
|
|
441
|
+
variantsHashTable: mergedVariantsTable,
|
|
442
|
+
};
|
|
559
443
|
const localCreateStyles = {};
|
|
560
444
|
const localStyleAliases = {};
|
|
561
445
|
const checkStyleAliasAssignment = (decl) => {
|
|
@@ -957,7 +841,16 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
957
841
|
}
|
|
958
842
|
return null;
|
|
959
843
|
};
|
|
960
|
-
const
|
|
844
|
+
const isStyleFunctionCall = (expr) => {
|
|
845
|
+
if (!t.isCallExpression(expr) || !t.isMemberExpression(expr.callee))
|
|
846
|
+
return false;
|
|
847
|
+
const callee = expr.callee;
|
|
848
|
+
if (!t.isIdentifier(callee.object) || !t.isIdentifier(callee.property))
|
|
849
|
+
return false;
|
|
850
|
+
return Boolean(localCreateStyles[callee.object.value]?.functions?.[callee.property.value] ??
|
|
851
|
+
createFunctionImportMap[callee.object.value]?.[callee.property.value]);
|
|
852
|
+
};
|
|
853
|
+
const resolveDynamicCall = (expr, forceRuntime = false) => {
|
|
961
854
|
if (!t.isCallExpression(expr) || !t.isMemberExpression(expr.callee))
|
|
962
855
|
return null;
|
|
963
856
|
const callee = expr.callee;
|
|
@@ -1001,7 +894,9 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1001
894
|
throwCompilationError(`Plumeria: ${getSource(expr)} leaves "${key}" unset, and a dynamic style function has no value to fall back on.`, expr);
|
|
1002
895
|
return;
|
|
1003
896
|
}
|
|
1004
|
-
if (
|
|
897
|
+
if (!forceRuntime &&
|
|
898
|
+
isStaticArgValue(source) &&
|
|
899
|
+
argObj[key] !== undefined)
|
|
1005
900
|
tempStaticTable[local] = argObj[key];
|
|
1006
901
|
else
|
|
1007
902
|
runtime.push({ param: local, source });
|
|
@@ -1009,6 +904,8 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1009
904
|
}
|
|
1010
905
|
else if (callArgs.length === 1 &&
|
|
1011
906
|
callArgs[0].expression.type === 'ObjectExpression') {
|
|
907
|
+
if (forceRuntime)
|
|
908
|
+
return null;
|
|
1012
909
|
const argObj = resolveObjectArg(callArgs[0].expression) ?? {};
|
|
1013
910
|
func.params.forEach((p) => {
|
|
1014
911
|
if (argObj[p] !== undefined)
|
|
@@ -1023,39 +920,10 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1023
920
|
runtime.push({ param: p, source: callArg.expression });
|
|
1024
921
|
});
|
|
1025
922
|
}
|
|
1026
|
-
const
|
|
1027
|
-
|
|
1028
|
-
const varParams = Array.from(new Set([
|
|
1029
|
-
...runtime.map(({ param }) => param),
|
|
1030
|
-
...withDefault.map(([param]) => param),
|
|
1031
|
-
]));
|
|
1032
|
-
if (varParams.length > 0) {
|
|
1033
|
-
varParams.forEach((param) => (tempStaticTable[param] = param));
|
|
1034
|
-
const probe = objectExpressionToObject(func.body, tempStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
|
|
1035
|
-
const hash = genBase36Hash(probe ?? {}, 1, 8);
|
|
1036
|
-
varParams.forEach((param) => {
|
|
1037
|
-
const cssVar = `--${hash}-${param}`;
|
|
1038
|
-
tempStaticTable[param] = `var(${cssVar})`;
|
|
1039
|
-
cssVars[param] = cssVar;
|
|
1040
|
-
});
|
|
1041
|
-
}
|
|
1042
|
-
const style = objectExpressionToObject(func.body, tempStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
|
|
1043
|
-
if (!style)
|
|
923
|
+
const resolved = resolveDynamicStyle(func, runtime.map(({ param }) => param), tempStaticTable, dynamicStyleTables);
|
|
924
|
+
if (!resolved)
|
|
1044
925
|
return null;
|
|
1045
|
-
const varGroups =
|
|
1046
|
-
varParams.forEach((param) => {
|
|
1047
|
-
const cssVar = cssVars[param];
|
|
1048
|
-
if (cssVar)
|
|
1049
|
-
varGroups.set(param, splitVarByUnit(style, cssVar));
|
|
1050
|
-
});
|
|
1051
|
-
withDefault.forEach(([param, expr]) => {
|
|
1052
|
-
const literal = expr.type === 'StringLiteral' || expr.type === 'NumericLiteral'
|
|
1053
|
-
? expr.value
|
|
1054
|
-
: undefined;
|
|
1055
|
-
if (literal === undefined)
|
|
1056
|
-
return;
|
|
1057
|
-
(varGroups.get(param) ?? []).forEach(({ cssVar }) => applyVarFallback(style, cssVar, literal));
|
|
1058
|
-
});
|
|
926
|
+
const { style, varGroups } = resolved;
|
|
1059
927
|
const vars = [];
|
|
1060
928
|
runtime.forEach(({ param, source }) => {
|
|
1061
929
|
const groups = varGroups.get(param);
|
|
@@ -1097,6 +965,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1097
965
|
});
|
|
1098
966
|
const conditionals = [];
|
|
1099
967
|
const dynamicVars = [];
|
|
968
|
+
const propVarSpreads = [];
|
|
1100
969
|
let groupIdCounter = 0;
|
|
1101
970
|
let sourceOrder = 0;
|
|
1102
971
|
const baseChunks = [];
|
|
@@ -1315,9 +1184,23 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1315
1184
|
}
|
|
1316
1185
|
if (!possibilities || possibilities.length === 0)
|
|
1317
1186
|
return false;
|
|
1318
|
-
const
|
|
1319
|
-
|
|
1187
|
+
const carriesVars = possibilities.some((entry) => entry.hasVars);
|
|
1188
|
+
if (carriesVars && !isStyleProp) {
|
|
1189
|
+
throwCompilationError(`Plumeria: "${varName}" carries a dynamic function key, and css.use() returns only a class name. ` +
|
|
1190
|
+
`Apply it to ${styleProp} on the element instead.`, expr);
|
|
1191
|
+
}
|
|
1192
|
+
const gate = gates.length ? `(${gates.join(' && ')}) && ` : '';
|
|
1193
|
+
if (carriesVars) {
|
|
1194
|
+
const spread = `...(${gate}${source} && ${source}.vars)`;
|
|
1195
|
+
if (!propVarSpreads.includes(spread))
|
|
1196
|
+
propVarSpreads.push(spread);
|
|
1197
|
+
}
|
|
1198
|
+
const token = carriesVars
|
|
1199
|
+
? `((${source} && ${source}.key) || ${source})`
|
|
1320
1200
|
: source;
|
|
1201
|
+
const testLHS = gates.length
|
|
1202
|
+
? `((${gates.join(' && ')}) ? ${token} : "")`
|
|
1203
|
+
: token;
|
|
1321
1204
|
const currentGroupId = ++groupIdCounter;
|
|
1322
1205
|
const currentOrder = sourceOrder++;
|
|
1323
1206
|
const seen = new Set();
|
|
@@ -1556,6 +1439,7 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1556
1439
|
isOptimizable,
|
|
1557
1440
|
baseStyle,
|
|
1558
1441
|
dynamicVars,
|
|
1442
|
+
propVarSpreads,
|
|
1559
1443
|
};
|
|
1560
1444
|
}
|
|
1561
1445
|
const stateSources = baseChunks.map(({ order, style }) => ({ order, style: style }));
|
|
@@ -1811,7 +1695,13 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
1811
1695
|
classParts.push(`(${JSON.stringify(results)}[${masterKeyExpr || '""'}] || ${baseConflictClass ? JSON.stringify(baseConflictClass) : '""'})`);
|
|
1812
1696
|
}
|
|
1813
1697
|
classParts.push(...dynamicClassParts);
|
|
1814
|
-
return {
|
|
1698
|
+
return {
|
|
1699
|
+
classParts,
|
|
1700
|
+
isOptimizable,
|
|
1701
|
+
baseStyle,
|
|
1702
|
+
dynamicVars,
|
|
1703
|
+
propVarSpreads,
|
|
1704
|
+
};
|
|
1815
1705
|
};
|
|
1816
1706
|
traverse(ast, {
|
|
1817
1707
|
JSXOpeningElement({ node }) {
|
|
@@ -2012,14 +1902,40 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
2012
1902
|
node.value &&
|
|
2013
1903
|
node.value.type === 'JSXExpressionContainer') {
|
|
2014
1904
|
const expr = node.value.expression;
|
|
1905
|
+
const carrierFor = (subNode) => {
|
|
1906
|
+
const vars = [];
|
|
1907
|
+
let unresolved = false;
|
|
1908
|
+
traverse(subNode, {
|
|
1909
|
+
CallExpression({ node: call }) {
|
|
1910
|
+
if (!isStyleFunctionCall(call))
|
|
1911
|
+
return;
|
|
1912
|
+
const resolved = resolveDynamicCall(call, true);
|
|
1913
|
+
if (!resolved) {
|
|
1914
|
+
unresolved = true;
|
|
1915
|
+
return;
|
|
1916
|
+
}
|
|
1917
|
+
vars.push(...resolved.vars);
|
|
1918
|
+
},
|
|
1919
|
+
});
|
|
1920
|
+
if (unresolved)
|
|
1921
|
+
return null;
|
|
1922
|
+
return `{ ${foldDynamicVars(vars).join(', ')} }`;
|
|
1923
|
+
};
|
|
2015
1924
|
const replaceWithKey = (subNode) => {
|
|
2016
1925
|
const entry = list.find((x) => x.spanStart === subNode.span.start &&
|
|
2017
1926
|
x.filePath === resourcePath);
|
|
2018
1927
|
if (entry) {
|
|
1928
|
+
let content = JSON.stringify(entry.key);
|
|
1929
|
+
if (entry.hasVars) {
|
|
1930
|
+
const carrier = carrierFor(subNode);
|
|
1931
|
+
if (!carrier)
|
|
1932
|
+
return false;
|
|
1933
|
+
content = `{ key: ${content}, vars: ${carrier} }`;
|
|
1934
|
+
}
|
|
2019
1935
|
replacements.push({
|
|
2020
1936
|
start: subNode.span.start - baseByteOffset,
|
|
2021
1937
|
end: subNode.span.end - baseByteOffset,
|
|
2022
|
-
content
|
|
1938
|
+
content,
|
|
2023
1939
|
});
|
|
2024
1940
|
processStyleRecords(entry.styleObj);
|
|
2025
1941
|
return true;
|
|
@@ -2037,6 +1953,11 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
2037
1953
|
excludeSubtreeSpans(subNode);
|
|
2038
1954
|
}
|
|
2039
1955
|
},
|
|
1956
|
+
CallExpression({ node: subNode }) {
|
|
1957
|
+
if (replaceWithKey(subNode)) {
|
|
1958
|
+
excludeSubtreeSpans(subNode);
|
|
1959
|
+
}
|
|
1960
|
+
},
|
|
2040
1961
|
});
|
|
2041
1962
|
}
|
|
2042
1963
|
}
|
|
@@ -2112,9 +2033,12 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
|
|
|
2112
2033
|
}
|
|
2113
2034
|
}
|
|
2114
2035
|
}
|
|
2115
|
-
const { classParts, isOptimizable, baseStyle, dynamicVars } = buildClassParts(args, dynamicClassParts, existingClassExpr, true);
|
|
2116
|
-
const
|
|
2117
|
-
|
|
2036
|
+
const { classParts, isOptimizable, baseStyle, dynamicVars, propVarSpreads, } = buildClassParts(args, dynamicClassParts, existingClassExpr, true);
|
|
2037
|
+
const styleParts = [
|
|
2038
|
+
...existingStyleParts,
|
|
2039
|
+
...foldDynamicVars(dynamicVars),
|
|
2040
|
+
...propVarSpreads,
|
|
2041
|
+
];
|
|
2118
2042
|
const styleAttr = styleParts.length > 0 || existingStyleExpr
|
|
2119
2043
|
? ` style={{ ${[existingStyleExpr, ...styleParts].filter(Boolean).join(', ')} }}`
|
|
2120
2044
|
: '';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumeria/unplugin",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.4.1",
|
|
4
4
|
"description": "Universal Plumeria plugin for various build tools",
|
|
5
5
|
"author": "Refirst 11",
|
|
6
6
|
"license": "MIT",
|
|
@@ -94,12 +94,12 @@
|
|
|
94
94
|
"dependencies": {
|
|
95
95
|
"@rollup/pluginutils": "^5.4.0",
|
|
96
96
|
"unplugin": "^3.0.0",
|
|
97
|
-
"@plumeria/utils": "^18.
|
|
97
|
+
"@plumeria/utils": "^18.4.1"
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|
|
100
100
|
"@swc/core": "1.15.47",
|
|
101
101
|
"vite": "^8.0.13",
|
|
102
|
-
"zss-engine": "2.
|
|
102
|
+
"zss-engine": "2.8.0"
|
|
103
103
|
},
|
|
104
104
|
"publishConfig": {
|
|
105
105
|
"access": "public",
|